Sunday, August 7, 2011

I was just about to devliver some patches, but remembered that I wanted to confirm that R11 and the fake PC register were working as expected. The PC works just fine, but R11 was not being saved properly if it was used as a temp register in a leaf function.

I found this out by making a function with 16 volatile ints stored on that stack, and returned the sum of all of them. That prevented the optimizer from removing one of these values, ensuring that all registers would be used. Well, all except the stack pointer, that's off-limits for obvious reasons. The C code and assembly output are shown below.

So, with that fixed and out of the way, I can finish the release.

int regtest(int a1, int a2, int a3, int a4, int a5, int a6)
{
volatile a7, a8, a9, a10, a11, a12, a13, a14, a15, a16;
return (a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15+a16);
}


regtest
# R1 - R6 are used by the function arguments,
# making this test slightly smaller

# Allocate 30 bytes on the stack
ai r10, >FFE2

# Save non-volatile registers to the stack
mov r10, r0
mov r11, *r0+
mov r9, *r0+
mov r13, *r0+
mov r14, *r0+
mov r15, *r0

# Copy our junk data from the stack to registers
mov *r10, r15
mov @>2(r10), r6
mov @>4(r10), r14
mov @>6(r10), r13
mov @>8(r10), r9
mov @>A(r10), r11
mov @>C(r10), r0
mov @>E(r10), r12
mov @>10(r10), r8
mov @>12(r10), r7

# Add everything up
a r15, r6
a r14, r6
a r13, r6
a r9, r6
a r11, r6
a r0, r6
a r12, r6
a r8, r6
a r7, r6
a r1, r6
a r2, r6
a r3, r6
a r4, r6
a r5, r6
mov r6, r1

# As expected, the 16th value didn't make it into a register
a @>1C(r10), r1

# Restore non-volatile registers from the stack
# This also frees 8 bytes of stack space
mov *r10+, r11
mov *r10+, r9
mov *r10+, r13
mov *r10+, r14
mov *r10, r15

# Free the rest of the allocated stack space (22 + 8 = 30)
ai r10, >16
b *r11

No comments:

Post a Comment