{
Testing for an overflow condition
{
V: D15 • M15 • R15 + D15 • M15 • R15
If both args are negative but result positive or if both args are positive but result negative... 15th bit is sign bit, isn't it? This directly translates to something like this
if( (a<0 && b<0 && (a+b)>=0) || (a>=0 && b>=0 && (a+b)<0) ) {
}
I tried compiling it in CW4.5 and it looks much lighter than "if( ((long)a +b) > 32767 || ((long)a+b)<-32768)"
here's the disassembled code
5: if( (a<0 && b<0 && (a+b)>=0) || (a>=0 && b>=0 && (a+b)<0) ) {
0002 fc0000 [3] LDD a
0005 2c0d [3/1] BGE *+15 ;abs = 0014
0007 fe0000 [3] LDX b
000a 2c08 [3/1] BGE *+10 ;abs = 0014
000c f30000 [3] ADDD b
000f 8c0000 [2] CPD #0
0012 2c12 [3/1] BGE *+20 ;abs = 0026
0014 fc0000 [3] LDD a
0017 2d10 [3/1] BLT *+18 ;abs = 0029
0019 fe0000 [3] LDX b
001c 2d0b [3/1] BLT *+13 ;abs = 0029
001e f30000 [3] ADDD b
0021 8c0000 [2] CPD #0
0024 2c03 [3/1] BGE *+5 ;abs = 0029
Actually "if(a<0)" and "if(a>=0) could be compiled using BMI/BPL branches. BLT/BGT after LDD is the same as BMI/BGT. But BMI/BGT could eliminate the need to CPD #0 :
if ((a+b) < 0)
LDD a
ADDD b
BPL sumispositive ; branch to >=0 caseBMI sumisnegative ; branch to <0 case
__asm{ LDD temp2 // put temp2 into the D accumulator ADDD temp1 // add temp1 to temp2 BVC noOverFlow // did the addition cause an overflow— CLRB // yes, so defer this addition until temp2 gets smaller RTS // the calling routine checks the B accumulatornoOverFlow: // Therefore CLRB followed by RTS is the same as a return(0) C instruction STD temp2 // no, so store the result into temp2}
V: D15 • M15 • R15 + D15 • M15 • R15
If both args are negative but result positive or if both args are positive but result negative... 15th bit is sign bit, isn't it? This directly translates to something like this
if( (a<0 && b<0 && (a+b)>=0) || (a>=0 && b>=0 && (a+b)<0) ) {
}
I tried compiling it in CW4.5 and it looks much lighter than "if( ((long)a +b) > 32767 || ((long)a+b)<-32768)"
here's the disassembled code
5: if( (a<0 && b<0 && (a+b)>=0) || (a>=0 && b>=0 && (a+b)<0) ) {
0002 fc0000 [3] LDD a
0005 2c0d [3/1] BGE *+15 ;abs = 0014
0007 fe0000 [3] LDX b
000a 2c08 [3/1] BGE *+10 ;abs = 0014
000c f30000 [3] ADDD b
000f 8c0000 [2] CPD #0
0012 2c12 [3/1] BGE *+20 ;abs = 0026
0014 fc0000 [3] LDD a
0017 2d10 [3/1] BLT *+18 ;abs = 0029
0019 fe0000 [3] LDX b
001c 2d0b [3/1] BLT *+13 ;abs = 0029
001e f30000 [3] ADDD b
0021 8c0000 [2] CPD #0
0024 2c03 [3/1] BGE *+5 ;abs = 0029
Actually "if(a<0)" and "if(a>=0) could be compiled using BMI/BPL branches. BLT/BGT after LDD is the same as BMI/BGT. But BMI/BGT could eliminate the need to CPD #0 :
if ((a+b) < 0)
LDD a
ADDD b
BPL sumispositive ; branch to >=0 caseBMI sumisnegative ; branch to <0 case