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
347 subscribers
Views
21113 views
Users
0 members are here
Arm7
Options
Share
More actions
Cancel
Related
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