Hey, check it out. I got correct code finally:
Input C code:
unsigned char Round;
#define VDPWD *((volatile char*)0x8C00)
void modulo()
{
VDPWD = '0' + Round % 10;
}
Output assembly:
modulo:
movb @Round, r1
srl r1, 8
mov r1, r2
clr r1
li r3, >A div r3, r1
mov r2, r1
swpb r1 # instruction is right where it's supposed to be
ai r1, >3000
movb r1, @>8C00
b *r11
OK, I'll admit it. At first that doesn't seem too exciting. The thing is that I've been looking for a way to cleanly handle this case for a long, long time. I walked away in frustration because I got stuck on this problem. I just need to test this a bit more and we can call this done.
I was looking through older development notes to see if there was anything else left semi-implemented. I found a note to see if there can be any way to remove two jumps in sequence like jlt/jmp
Here are all the conditional jumps and the logic they use:
Conditional flags:
L - Logical greater than
A - Arithmetic greater than
Q - equal
Arithmetic:
< ~A & ~Q jlt
> A & ~Q jgt
== Q jeq
>= A | Q jgt,jeq \__ Ick, go away.
<= ~A | Q jlt,jeq /
!= ~Q jne
Logical:
< ~L & ~Q jl
> L & ~Q jh
== Q jeq
>= L | Q jhe
<= ~L | Q jle
!= ~Q jne
Unfortunately, there is no way to completely implement >= and <= in one instruction for all valid imputs, but if the range of the test values were known, we could occasionally replace the jgt,jeq sequence with single jhe instruction.
EX: For byte compares, if A=[0..127] and B=[0..127], then these sequences are equivalent:
jlt ADDR --> jle ADDR
jeq ADDR
jgt ADDR --> jhe ADDR
jeq ADDR-->
Unfortunately, here is no way for the compiler to recognize this situation. If the user knows that their range matches this, they can take advantage of the slightly faster code by doing an unsigned compare. Something like this works:
int fast_lt_eq(int a, int b)
{
return ((unsigned int)a <= (unsigned int)b);
}
What else...
Way back in June, TheMole on Atariage reported that they were unable to compile a function whose return value was assigned in an asm block and implicitly typecast as the retun value. No problems now.
So at this point, I think I'm up to date on error reports. These are the last items before I move on to new stuff:
1) Test 32-bit shift by variable, I'm not sure I checked that
2) Test assembler for Editor/Assembler adherance for caps and digits for registers, comments, register defines, etc.
3) Check signed vs. unsigned division and multiplication
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment