D on lm32-CPU: string argument on stack instead of register

Michael Reese michaelate at gmail.com
Fri Jul 31 10:22:20 UTC 2020


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




More information about the Digitalmars-d-learn mailing list