Arm Community
Site
Search
User
Site
Search
User
Support forums
Architectures and Processors forum
ARM7TDMI: SUBS vs SUB + CMP
Jump...
Cancel
State
Accepted Answer
+1
person also asked this
people also asked this
Locked
Locked
Replies
7 replies
Subscribers
350 subscribers
Views
20028 views
Users
0 members are here
Arm7
Options
Share
More actions
Cancel
Related
How was your experience today?
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
Greger Greger
over 12 years ago
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
Top replies
Peter Harris
over 12 years ago
+1
verified
Note: This was originally posted on 6th April 2009 at http://forums.arm.com I'd highly recommend the ARM System Developer's Guide ( http://www.arm.com/documentation/books/4975.html ) - it covers lots of...
Parents
0
Greger Greger
over 12 years ago
Note: This was originally posted on 3rd April 2009 at
http://forums.arm.com
Thank you for your answers!
I realize I gave the wrong numbers. The calculation in question (indeed, the root cause is poor algorithm design) is
t = 0x80 * 0x106DCD9 - 0x8D7F * 0x8D7F
=> t = 0x836E6C80 - 0x4E352501 (=0x3539477F)
(a = 0x80, b = 0x106DCD9, c = 0x8DF, a*b = 0x836E6C80, c*c = 0x4E352501)
So, if I understand you right we should have
MUL temp1, c, c => no overflow flag, no negative flag (this is in bounds)
MUL temp2, a, b => negative flag, no overflow flag (but shouldn't overflow be set since it's a signed multiply?)
SUBS t, temp2, temp1 => no negative flag, overflow flag (underflow)
MOVGT d, t => MOV is not executed
and
MUL temp1, c, c => no overflow flag, no negative flag (this is in bounds)
MUL temp2, a, b => negative flag, no overflow flag (but shouldn't overflow be set since it's a signed multiply?)
SUB t, temp2, temp1
CMP t, #0 => 0x3539477F - 0 => no negative flag, no overflow overflow flag
MOVGT d, t => MOV is executed
OK. Then it is really not a problem with the simulator but that the optimizer takes a legal short cut due to a poorly designed algorithm (which overflows). "Good."
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.
Thanks again!
Greger
Cancel
Vote up
0
Vote down
Cancel
Reply
0
Greger Greger
over 12 years ago
Note: This was originally posted on 3rd April 2009 at
http://forums.arm.com
Thank you for your answers!
I realize I gave the wrong numbers. The calculation in question (indeed, the root cause is poor algorithm design) is
t = 0x80 * 0x106DCD9 - 0x8D7F * 0x8D7F
=> t = 0x836E6C80 - 0x4E352501 (=0x3539477F)
(a = 0x80, b = 0x106DCD9, c = 0x8DF, a*b = 0x836E6C80, c*c = 0x4E352501)
So, if I understand you right we should have
MUL temp1, c, c => no overflow flag, no negative flag (this is in bounds)
MUL temp2, a, b => negative flag, no overflow flag (but shouldn't overflow be set since it's a signed multiply?)
SUBS t, temp2, temp1 => no negative flag, overflow flag (underflow)
MOVGT d, t => MOV is not executed
and
MUL temp1, c, c => no overflow flag, no negative flag (this is in bounds)
MUL temp2, a, b => negative flag, no overflow flag (but shouldn't overflow be set since it's a signed multiply?)
SUB t, temp2, temp1
CMP t, #0 => 0x3539477F - 0 => no negative flag, no overflow overflow flag
MOVGT d, t => MOV is executed
OK. Then it is really not a problem with the simulator but that the optimizer takes a legal short cut due to a poorly designed algorithm (which overflows). "Good."
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.
Thanks again!
Greger
Cancel
Vote up
0
Vote down
Cancel
Children
No data