From: Borja F. <bor...@gm...> - 2010-09-28 20:56:26
|
I've just finished fixing the register calling convention. I had a huge TODO in my code to handle passing chars in even registers and returning a char in R24. I couldnt use the typical approach of using the Tablegen code to define the calling convention because wide arguments are splitted into i8 pieces making LLVM treat all args as chars so there was no easy way of knowing the real size of each arg. I had to write it down in C++ code to check the real argument size and allocate the regs using AVR's ABI spec. A piece of code to show it: typedef int t; t foo(t a, t b, char c, int d) { return a+b+d; } foo: # @foo .ent foo # BB#0: # %entry add r22, r18 adc r23, r19 adc r24, r20 adc r25, r21 add r22, r12 adc r23, r13 adc r24, r14 adc r25, r15 ret GCC generated this: 120: cf 92 push r12 122: df 92 push r13 124: ef 92 push r14 126: ff 92 push r15 return (a + b +d); 128: 26 0f add r18, r22 12a: 37 1f adc r19, r23 12c: 48 1f adc r20, r24 12e: 59 1f adc r21, r25 130: 2c 0d add r18, r12 132: 3d 1d adc r19, r13 134: 4e 1d adc r20, r14 136: 5f 1d adc r21, r15 138: b9 01 movw r22, r18 13a: ca 01 movw r24, r20 13c: ff 90 pop r15 13e: ef 90 pop r14 140: df 90 pop r13 142: cf 90 pop r12 144: 08 95 ret Forget the fact that our code isnt saving regs into the stack, that's currently unimplemented, but notice those two movws are totally redundant, pretty funny. LLVM's site states that the new version will get released tomorrow, so i'll start porting my code once that is done. |