why two separate instructions instead of one instruction? Practically in what kind of situations we need to use CMP and TEQ instructions.
I know how both the instruction works.
why two separate instructions instead of one instruction? Practically in what kind of situations we need to use CMP and TEQ instructions.
I know how both the instruction works.
short: Both serve different purposes each, cmp
is subs
without a destination while teq
is eors
without a destination.
cmp
is very straightforward: you compare two numbers A and B
signed:
gt
: A > B
ge
: A >= B
eq
: A == B
le
: A <= B
lt
: A < B
unsigned:
hi
: A > B
hs
: A >= B
eq
: A == B
ls
: A <= B
lo
: A < B
Let's assume the problem below though:
int32_t foo(int32_t A)
{
if (((A < 0) && ((A & 1) == 1)) || ((A >= 0) && ((A & 1) == 0)))
{
A += 1;
}
else
{
A -= 1;
}
return A;
}
In human language, the if statement is true if A is either an (odd negative number) or an (even positive number), and Linaro GCC 7.4.1 @ O3
will generate that mess below:
foo
0x00000000: CMP r0,#0
0x00000004: AND r3,r0,#1
0x00000008: BLT {pc}+0x14 ; 0x1c
0x0000000C: CMP r3,#0
0x00000010: BEQ {pc}+0x14 ; 0x24
0x00000014: SUB r0,r0,#1
0x00000018: BX lr
0x0000001C: CMP r3,#0
0x00000020: BEQ {pc}-0xc ; 0x14
0x00000024: ADD r0,r0,#1
0x00000028: BX lr
People knowledgeable in the field of bit hacking would alter the if statement like below:
int32_t bar(int32_t A)
{
if ((A ^ (A<<31)) >= 0)
{
A += 1;
}
else
{
A -= 1;
}
return A;
}
And the results are:
bar
0x0000002C: EORS r3,r0,r0,LSL #31
0x00000030: ADDPL r0,r0,#1
0x00000034: SUBMI r0,r0,#1
0x00000038: BX lr
And finally, assembly programmers will replace EORS
with teq r0, r0, lsl #31
.
It won't make the code any faster, but it doesn't need R3
as the scratch register.
Note that the code above is just a show case, being a separate function where you have excess of available registers.
In real life however, registers are by far the most scarce resource, especially inside a loop, and even compilers will make use of the teq
instruction in similar situations.
Summing it up, there are fields such as error correction, decryption/encryption, etc where tons of xor
operations are done, and people dealing with those problems just know to appreciate instructions such as teq
and when to us them.
And always remember: never trust compilers
TEQ
. –
Anorthite xor
operations since I had the feeling that the OP knows them only from textbooks. –
Caledonian tst
. So you have an equivalent of subs
, ands
and eors
with cmp
, tst
, and teq
. ldr
is sort of similar with pld
. All are instructions that don't update registers, but do get the side effects of what the other operation would do. But basically if you don't put restriction on register use, they don't make much sense (which goes back to my first point). –
Anorthite © 2022 - 2024 — McMap. All rights reserved.
TEQ
is used to test if two values are equal, without affecting the V flag (asCMP
does). The C flag is also unaffected in many cases.TEQ
is also useful for testing whether the two values have the same sign. After the comparison, the N flag is the logical Exclusive OR of the sign bits of the two operands." – Royroyalarm-none-eabi-gcc
and the generated instruction for bothif ( a != b)
andif(a > b)
always consists of aCMP
instruction. Indeed it's not easy to understand the need to have 2 separate instructions – HerlindahermCMP
sets the flag based onop1 - op2
, whileTEQ
sets the flags based onop1 XOR op2
. SoCMP
can check for the ordering of two values (==, >, <, etc).TEQ
on the other hand can check for equality and whether the signs are the same. – RoyroyalTEQ
do with aCMP
, right ? PerhapsTEQ
is faster on some MCUs ? Or is there another reason to have both instructions ? – HerlindahermCMP
? – Royroyalsubs
, etc which does destructive testing as opposed tocmp
. – Anorthite