wrong insn sequence generation for condition verification

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux