This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM7TDMI: SUBS vs SUB + CMP

Note: This was originally posted on 2nd April 2009 at http://forums.arm.com

Hi,

I have a question regarding the SUBS instruction and how it compares to SUB and CMP (due to unexpected behavior in a C-program).

The original C-code goes like this (all variables are 32 bit signed integers):

    t = a*b - c*c;
    if (t > 0) d = t;

In a particular case (a = 0x80, b = 0x106DCD9, c = 0x4E352501) I get an overflow in a*b as well as in the subtraction. What is puzzling to me is that there's a difference between the the following two assembler versions in a certain simulated environment - and I'm trying to figure out if this is expected or a bug in the simulator:

MUL temp1, c, c
MUL temp2, a, b
SUBS t, temp2, temp1
MOVGT d, t

and

MUL temp1, c, c
MUL temp2, a, b
SUB t, temp2, temp1
CMP t, #0
MOVGT d, t

(These are genereated depending on different compiler settings.)

Any help is greatly appreciated!

Greger
Parents
  • Note: This was originally posted on 2nd April 2009 at http://forums.arm.com

    To merge the comparison into the SUBS flag setting would require the ability to perform a condition check for N clear and Z clear, i.e a positive non-zero value; however, no such condition check exists.
    The closest is GT, with V clear, i.e. Z clear and N==V.

    Whether or not this is a compiler bug is a different question; the compiler choosing GT rathen than NE, indicates that "t" is a "signed int", and this may be why this apparently erroneous behaviour is legal -- the C standard has a number of caveats with respect to arithmetic operations exceeding the precision of "signed" integer types and allowing implemenation defined results.

    hth
    s.
Reply
  • Note: This was originally posted on 2nd April 2009 at http://forums.arm.com

    To merge the comparison into the SUBS flag setting would require the ability to perform a condition check for N clear and Z clear, i.e a positive non-zero value; however, no such condition check exists.
    The closest is GT, with V clear, i.e. Z clear and N==V.

    Whether or not this is a compiler bug is a different question; the compiler choosing GT rathen than NE, indicates that "t" is a "signed int", and this may be why this apparently erroneous behaviour is legal -- the C standard has a number of caveats with respect to arithmetic operations exceeding the precision of "signed" integer types and allowing implemenation defined results.

    hth
    s.
Children
No data