Hello everyone,
I am trying to fix a bug in a custom port of gcc 3.2 (port done by
someone else). The bug is:
"The compiler generates the wrong instructions for unsigned-integer
comparision, and also inverts the comparision". The processor in
question has two different instructions for each comparision operation
(<, >, <=, >=), one for signed and other for unsigned numbers. The
following are the instruction to be used in each case:
SIGNED:
Less-Than : BLT <address>
Less-Than-Or-Equal : BLE <address>
Greater-Than : BGT <address>
Greater-Than-Or-Equal: BGE <address>
UNSIGNED:
Less-Than : BCS <address>
Less-Than-Or-Equal : BLS <address>
Greater-Than : BHI <address>
Greater-Than-Or-Equal: BCC <address>
The compiler is reversing the sequence of comparision and then inverting
the comparision:
i.e. If my C statement has if (a<b), the compiler is trying to evaluate;
if(b>=a). Is this the normal behaviour for gcc?
Also, as can be seen below, it is generating the correct insn's for
signed values, but is generating incorrect insns for Unsigned comparisions.
Now, where do I change this? My .md file has entries corresponding to
these comparisions. Is it enough if I change them here? or should I be
changing somewhere else also?
The following is a sample code and its gcc-generated assembly. The
comparision insns have been surrounded by <<<<< >>>>>>
-------------------------
int foo(void)
{
int res;
int a,b;
unsigned int x;
unsigned int y;
a=10;
b=-5;
x=20;
y=15;
if(a<b)
res=-1;
else
res=1;
if(a<=b)
res=-1;
else
res=1;
if(a>b)
res=1;
else
res=-1;
if(a>=b)
res=1;
else
res=-1;
if(x<y)
res=-1;
else
res=1;
if(x<=y)
res=-1;
else
res=1;
if(x>y)
res=1;
else
res=-1;
if(x>=y)
res=1;
else
res=-1;
return res;
}
----------------------------
00000000 <_foo>:
sti r4+,r7
sti r4+,r5
tfr r4,r5
leaa #0x5,r4
movek16 #0xa,d0
sta r5,#0x1,d0
movek16 #0xfffb,d0
sta r5,#0x2,d0
movek16 #0x14,d0
sta r5,#0x3,d0
movek16 #0xf,d0
sta r5,#0x4,d0
lda r5,#0x1,d0
lda r5,#0x2,d2
cmp d2,d0
<<<<< bge 21 <_foo+0x21> >>>>>
movek16 #0xffff,d0
st r5,d0
bra 24 <_foo+0x24>
movek16 #0x1,d0
st r5,d0
lda r5,#0x1,d0
lda r5,#0x2,d2
cmp d2,d0
<<<<< bgt 30 <_foo+0x30> >>>>>
movek16 #0xffff,d0
st r5,d0
bra 33 <_foo+0x33>
movek16 #0x1,d0
st r5,d0
lda r5,#0x1,d0
lda r5,#0x2,d2
cmp d2,d0
<<<<< ble 3f <_foo+0x3f> >>>>>
movek16 #0x1,d0
st r5,d0
bra 42 <_foo+0x42>
movek16 #0xffff,d0
st r5,d0
lda r5,#0x1,d0
lda r5,#0x2,d2
cmp d2,d0
movek16 #0x1,d0
st r5,d0
bra 51 <_foo+0x51>
<<<<< blt 4e <_foo+0x4e> >>>>>
movek16 #0xffff,d0
st r5,d0
lda r5,#0x3,d0
lda r5,#0x4,d2
cmp d2,d0
<<<<< bcs 5d <_foo+0x5d> >>>>>
movek16 #0xffff,d0
st r5,d0
bra 60 <_foo+0x60>
movek16 #0x1,d0
st r5,d0
lda r5,#0x3,d0
lda r5,#0x4,d2
cmp d2,d0
<<<<< bhi 6c <_foo+0x6c> >>>>>
movek16 #0xffff,d0
st r5,d0
bra 6f <_foo+0x6f>
movek16 #0x1,d0
st r5,d0
lda r5,#0x3,d0
lda r5,#0x4,d2
cmp d2,d0
<<<<< bls 7b <_foo+0x7b> >>>>>
movek16 #0x1,d0
st r5,d0
bra 7e <_foo+0x7e>
movek16 #0xffff,d0
st r5,d0
lda r5,#0x3,d0
lda r5,#0x4,d2
cmp d2,d0
<<<<< bcc 8a <_foo+0x8a> >>>>>
movek16 #0x1,d0
st r5,d0
bra 8d <_foo+0x8d>
movek16 #0xffff,d0
st r5,d0
ld r5,d0
leas #0x5,r4
ldd -r4,r5
ldd -r4,r7
rts
----------------------------
Kind regards,
Sriharsha Vedurmudi.