Use ADD/SUB instructions on x86 and x86-64 atomics instead of INC/DEC
According to the Intel Optimization Manual section 3.5.1.1 Use of INC and DEC Instructions, those instructions modify only part of the flags register, so they mey introduce unnecessary data dependencies on previous flag-setting operations so that the resulting flags are computed. Preferring ADD and SUB (rule 33) is recommended. However, we don't do it for 16-bit integers. The reason is that the presence of the 0x66 prefix may trigger a slower decoding codepath in the processor (up to 6 cycles, as opposed to 1). The same Intel manual talks about Length-Changing Prefix, which applies in particular to instructions with 16-bit immediates. The assembler generally produces uses the 8-bit immediate variant of the ADD and SUB instructions, but to be on the safe side, we prefer to use INC and DEC here. Change-Id: Ic03236ac600a5b4e087614d21df5d3c666ae064e Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>bb10
parent
99802f0c14
commit
7db5f0dd6a
|
|
@ -137,7 +137,7 @@ bool QBasicAtomicOps<1>::ref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incb %0\n"
|
||||
"addb $1, %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
|
|
@ -163,7 +163,7 @@ bool QBasicAtomicOps<4>::ref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incl %0\n"
|
||||
"addl $1, %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
|
|
@ -176,7 +176,7 @@ bool QBasicAtomicOps<1>::deref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decb %0\n"
|
||||
"subb $1, %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
|
|
@ -202,7 +202,7 @@ bool QBasicAtomicOps<4>::deref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decl %0\n"
|
||||
"subl $1, %0\n"
|
||||
"setne %1"
|
||||
: "+m" (_q_value), "=qm" (ret)
|
||||
:
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ bool QBasicAtomicOps<1>::ref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incb %0\n"
|
||||
"addb $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
|
|
@ -164,7 +164,7 @@ bool QBasicAtomicOps<4>::ref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incl %0\n"
|
||||
"addl $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
|
|
@ -177,7 +177,7 @@ bool QBasicAtomicOps<8>::ref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"incq %0\n"
|
||||
"addq $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
|
|
@ -190,7 +190,7 @@ bool QBasicAtomicOps<1>::deref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decb %0\n"
|
||||
"subb $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
|
|
@ -215,7 +215,7 @@ bool QBasicAtomicOps<4>::deref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decl %0\n"
|
||||
"subl $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
|
|
@ -228,7 +228,7 @@ bool QBasicAtomicOps<8>::deref(T &_q_value)
|
|||
{
|
||||
unsigned char ret;
|
||||
asm volatile("lock\n"
|
||||
"decq %0\n"
|
||||
"subq $1, %0\n"
|
||||
"setne %1"
|
||||
: "=m" (_q_value), "=qm" (ret)
|
||||
: "m" (_q_value)
|
||||
|
|
|
|||
Loading…
Reference in New Issue