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 3rd April 2009 at http://forums.arm.com

    > Just a follow-up question here, shouldn't the negative flag be set in the SUBS? I mean we do subtract a positive number from a negative number.
    The ARM core generally has no notion of signed and unsigned instructions (for general data processing anyway - signed and unsigned multiply and saturating DSP instructions exist) - that's a compiler issue to generate appropriate instructions which fit 2's complement maths, the 'N'egative bit is simply bit 31 of the result register.

    > MUL temp2, a, b => negative flag, no overflow flag (but shouldn't overflow be set since it's a signed multiply?)
    Also - you mention flag setting in your multiplication instructions - on ARM the flags are only set for instructions with the 'S' postfix (there are notable exceptions such as CMP and CMPN which implicitly set flags). So SUBS sets the flags, SUB doesn't. In your case the MUL will not set any flags at all because it isn't a MULS.
Reply
  • Note: This was originally posted on 3rd April 2009 at http://forums.arm.com

    > Just a follow-up question here, shouldn't the negative flag be set in the SUBS? I mean we do subtract a positive number from a negative number.
    The ARM core generally has no notion of signed and unsigned instructions (for general data processing anyway - signed and unsigned multiply and saturating DSP instructions exist) - that's a compiler issue to generate appropriate instructions which fit 2's complement maths, the 'N'egative bit is simply bit 31 of the result register.

    > MUL temp2, a, b => negative flag, no overflow flag (but shouldn't overflow be set since it's a signed multiply?)
    Also - you mention flag setting in your multiplication instructions - on ARM the flags are only set for instructions with the 'S' postfix (there are notable exceptions such as CMP and CMPN which implicitly set flags). So SUBS sets the flags, SUB doesn't. In your case the MUL will not set any flags at all because it isn't a MULS.
Children
No data