Reputation: 137
Can anyone help me convert following x86 inline asm code to arm format?
bool N_FLAG = 0;
bool C_FLAG = 0;
bool Z_FLAG = 0;
bool V_FLAG = 0;
asm ("sub %1, %%ebx;"\
"setsb N_FLAG;"\
"setzb Z_FLAG;"\
"setncb C_FLAG;"\
"setob V_FLAG;"\
: "=b" (reg[dest].I)\
: "r" (reg[base].I), "b" (value));
Upvotes: 2
Views: 1506
Reputation: 8401
How about converting this into C?
It looks like the code subtracts two numbers (value - reg[base].I)
, stores the result into reg[dest].I
and then checks the various flags.
So something (roughly, not tested) like:
reg[dest].I = value - reg[base].I;
Z_FLAG = (reg[dest].I == 0);
N_FLAG = (reg[dest].I < 0);
/* repeat for: carry, overflow */
And then let the compiler do its magic? The ARM gcc compiler is not bad in mapping this sort of stuff to the right ARM instructions.
If you want to go ARM assembly you're probably looking at using conditional move instructions, something like (wrote quickly - untested):
__asm__ (
"subs %[out], %[in2], %[in1]\n\t"
"movmi %[N_FLAG], #1\n\t"
"moveq %[Z_FLAG], #1\n\t"
"movcs %[C_FLAG], #1\n\t"
"movvs %[V_FLAG], #1\n\t"
: [N_FLAG]"+r"(N_FLAG), [Z_FLAG]"+r"(Z_FLAG), [C_FLAG]"+r"(C_FLAG), [V_FLAG]"+r"(V_FLAG), [out]"=r" (reg[dest].I)
: [in1]"r" (reg[base].I), [in2]"r"(value))
: "cc"
);
Upvotes: 2
Reputation: 8116
This code works for me using clang:
int sub(int a, int b)
{
int c;
asm ("sub %0, %2, %1" : "=r" (c) : "r" (b), "r" (a));
return c;
}
Notice the commas between the register arguments.
Upvotes: 1