From 7db5f0dd6a3a876279a32cf060dfbc929c615de4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 25 Dec 2011 19:30:15 -0200 Subject: 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 --- src/corelib/arch/qatomic_i386.h | 8 ++++---- src/corelib/arch/qatomic_x86_64.h | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/corelib/arch') diff --git a/src/corelib/arch/qatomic_i386.h b/src/corelib/arch/qatomic_i386.h index 61d835a7d4..a81376108c 100644 --- a/src/corelib/arch/qatomic_i386.h +++ b/src/corelib/arch/qatomic_i386.h @@ -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) : diff --git a/src/corelib/arch/qatomic_x86_64.h b/src/corelib/arch/qatomic_x86_64.h index 33427ebf33..58505e2aa9 100644 --- a/src/corelib/arch/qatomic_x86_64.h +++ b/src/corelib/arch/qatomic_x86_64.h @@ -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) -- cgit v1.2.3