Hi all,

at work we put embedded lm32 soft-core CPUs in FPGAs and write the firmware in C. At home I enjoy writing small projects in D from time to time, but I don't consider myself a D expert.

Now, I'm trying to run some toy examples in D on the lm32 cpu. I'm using a recent gcc-elf-lm32. I succeeded in compiling and running some code and it works fine.

But I noticed, when calling a function with a string argument, the string is not stored in registers, but on the stack. Consider a simple function (below) that writes bytes to a peripheral (that forwards the data to the host computer via USB). I've two versions, an ideomatic D one, and another version where pointer and length are two distinct function parameters. I also show the generated assembly code. The string version is 4 instructions longer, just because of the stack manipulation. In addition, it is also slower because it need to access the ram, and it needs more stack space.

My question: Is there a way I can tell the D compiler to use registers instead of stack for string arguments, or any other trick to reduce code size while maintaining an ideomatic D codestyle?

Best regards
Michael


// ideomatic D version
void write_to_host(in string msg) {
        // a fixed address to get bytes to the host via usb
        char *usb_slave = cast(char*)BaseAdr.ft232_slave;
        foreach(ch; msg) {
                *usb_slave = ch;
        }
}
// resulting assembly code (compiled with -Os) 12 instructions
_D10firmware_d13write_to_hostFxAyaZv:
        addi     sp, sp, -8
        addi     r3, r0, 4096
        sw       (sp+4), r1
        sw       (sp+8), r2
        add      r1, r2, r1
.L3:
        be     r2,r1,.L1
        lbu      r4, (r2+0)
        addi     r2, r2, 1
        sb       (r3+0), r4
        bi       .L3
.L1:
        addi     sp, sp, 8
        b        ra

// C-like version
void write_to_hostC(const char *msg, int len) {
        char *ptr = cast(char*)msg;
        char *usb_slave = cast(char*)BaseAdr.ft232_slave;
        while (len--) {
                *usb_slave = *ptr++;
        }
}
// resulting assembly code (compiled with -Os) 8 instructions
_D10firmware_d14write_to_hostCFxPaiZv:
        add      r2, r1, r2
        addi     r3, r0, 4096
.L7:
        be     r1,r2,.L5
        lbu      r4, (r1+0)
        addi     r1, r1, 1
        sb       (r3+0), r4
        bi       .L7
.L5:
        b        ra


Reply via email to