[Bug target/52848] New: [x32] *load_tp_x32 in i386.md isn't necessary
hjl.tools at gmail dot com
gcc-bugzilla@gcc.gnu.org
Tue Apr 3 18:13:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52848
Bug #: 52848
Summary: [x32] *load_tp_x32 in i386.md isn't necessary
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: hjl.tools@gmail.com
Target: x32
Segment register %fs is used as thread pointer for x32 in 64bit hardware mode.
For a memory operand "%fs:address", its effective address is the base address
of %fs + address. The base address of %fs are hidden and "mov %fs, %ax" only
accesses the visible part of %fs, which is the 16bit segment selector.
In x32, UNSPEC_TP refers to the base address of %fs. To access the
base address of %fs, a system call is provided:
int arch_prctl(int code, unsigned long long addr);
int arch_prctl(int code, unsigned long long *addr);
ARCH_SET_FS
Set the 64-bit base for the FS register to addr.
ARCH_GET_FS
Return the 64-bit base value for the FS register of the
current thread in the unsigned long pointed to by addr.
We must use arch_prctl to update the base address of %fs, To read
the base address of %fs, OS arranges that the base address of %fs points
to a struct:
typedef struct
{
void *tcb; /* Pointer to the TCB. Not necessarily the
thread descriptor used by libpthread. */
...
}
and sets up "tcb" == the base address of %fs so that the address of "%fs:0"
is the address of the tcb field. For x32, the base address of %fs is
between 0 and 0xffffffff. We can use
"mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
to move the base address of %fs into %r32 and %r64 directly. In case
of %r32, we are loading "tcb", which is a 32bit memory. For %r64, we
are loading "tcb" and zero-extend it to 64bit. We can use
;; Load and add the thread base pointer from %<tp_seg>:0.
(define_insn "*load_tp_x32_<mode>"
[(set (match_operand:SWI48x 0 "register_operand" "=r")
(unspec:SWI48x [(const_int 0)] UNSPEC_TP))]
"TARGET_X32"
"mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
[(set_attr "type" "imov")
(set_attr "modrm" "0")
(set_attr "length" "7")
(set_attr "memory" "load")
(set_attr "imm_disp" "false")])
instead of
;; Load and add the thread base pointer from %<tp_seg>:0.
(define_insn "*load_tp_x32"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"TARGET_X32"
"mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
[(set_attr "type" "imov")
(set_attr "modrm" "0")
(set_attr "length" "7")
(set_attr "memory" "load")
(set_attr "imm_disp" "false")])
(define_insn "*load_tp_x32_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
"TARGET_X32"
"mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
[(set_attr "type" "imov")
(set_attr "modrm" "0")
(set_attr "length" "7")
(set_attr "memory" "load")
(set_attr "imm_disp" "false")])
More information about the Gcc-bugs
mailing list