i386.md (iptrsize): New mode attribute.
* config/i386/i386.md (iptrsize): New mode attribute. (tp_seg): Ditto. (*load_tp_<mode>): Macroize insn from *load_tp_{si,di} using P mode iterator. (*add_tp_<mode>): Ditto from *add_tp_{si,di}. (stack_protect_set_<mode>): Ditto from stack_protect_set_{si,di}. (stack_protect_test_<mode>): Ditto from stack_protect_test_{si,di}. (stack_tls_protect_set_<mode>): Ditto from stack_tls_protect_set_{si,di}. Use %@ to output segment register of thread base pointer load. (stack_tls_protect_test_<mode>): Ditto from stack_tls_protect_test_{si,di}. Use %@ to output segment register of thread base pointer load. (stack_protect_set): Rewrite using indirect functions. (stack_protect_test): Ditto. * config/i386/i386.c (ix86_print_operand_punct_valid): Add '@'. (ix86_print_operand): Handle '@'. From-SVN: r163900
This commit is contained in:
parent
195a95c430
commit
d1e74401c1
3 changed files with 100 additions and 135 deletions
|
@ -1,3 +1,23 @@
|
|||
2010-09-06 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
* config/i386/i386.md (iptrsize): New mode attribute.
|
||||
(tp_seg): Ditto.
|
||||
(*load_tp_<mode>): Macroize insn from *load_tp_{si,di} using P
|
||||
mode iterator.
|
||||
(*add_tp_<mode>): Ditto from *add_tp_{si,di}.
|
||||
(stack_protect_set_<mode>): Ditto from stack_protect_set_{si,di}.
|
||||
(stack_protect_test_<mode>): Ditto from stack_protect_test_{si,di}.
|
||||
(stack_tls_protect_set_<mode>): Ditto from
|
||||
stack_tls_protect_set_{si,di}. Use %@ to output segment register
|
||||
of thread base pointer load.
|
||||
(stack_tls_protect_test_<mode>): Ditto from
|
||||
stack_tls_protect_test_{si,di}. Use %@ to output segment register
|
||||
of thread base pointer load.
|
||||
(stack_protect_set): Rewrite using indirect functions.
|
||||
(stack_protect_test): Ditto.
|
||||
* config/i386/i386.c (ix86_print_operand_punct_valid): Add '@'.
|
||||
(ix86_print_operand): Handle '@'.
|
||||
|
||||
2010-09-05 Giuseppe Scrivano <gscrivano@gnu.org>
|
||||
|
||||
* tree-tailcall.c (process_assignment): Handle NEGATE_EXPR and
|
||||
|
|
|
@ -12404,6 +12404,7 @@ get_some_local_dynamic_name (void)
|
|||
Y -- print condition for XOP pcom* instruction.
|
||||
+ -- print a branch hint as 'cs' or 'ds' prefix
|
||||
; -- print a semicolon (after prefixes due to bug in older gas).
|
||||
@ -- print a segment register of thread base pointer load
|
||||
*/
|
||||
|
||||
void
|
||||
|
@ -12882,6 +12883,19 @@ ix86_print_operand (FILE *file, rtx x, int code)
|
|||
#endif
|
||||
return;
|
||||
|
||||
case '@':
|
||||
if (ASSEMBLER_DIALECT == ASM_ATT)
|
||||
putc ('%', file);
|
||||
|
||||
/* The kernel uses a different segment register for performance
|
||||
reasons; a system call would not have to trash the userspace
|
||||
segment register, which would be expensive. */
|
||||
if (TARGET_64BIT && ix86_cmodel != CM_KERNEL)
|
||||
fputs ("fs", file);
|
||||
else
|
||||
fputs ("gs", file);
|
||||
return;
|
||||
|
||||
default:
|
||||
output_operand_lossage ("invalid operand code '%c'", code);
|
||||
}
|
||||
|
@ -13012,7 +13026,8 @@ ix86_print_operand (FILE *file, rtx x, int code)
|
|||
static bool
|
||||
ix86_print_operand_punct_valid_p (unsigned char code)
|
||||
{
|
||||
return (code == '*' || code == '+' || code == '&' || code == ';');
|
||||
return (code == '@' || code == '*' || code == '+'
|
||||
|| code == '&' || code == ';');
|
||||
}
|
||||
|
||||
/* Print a memory operand whose address is ADDR. */
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
;; Y -- print condition for XOP pcom* instruction.
|
||||
;; + -- print a branch hint as 'cs' or 'ds' prefix
|
||||
;; ; -- print a semicolon (after prefixes due to bug in older gas).
|
||||
;; @ -- print a segment register of thread base pointer load
|
||||
|
||||
;; UNSPEC usage:
|
||||
|
||||
|
@ -821,6 +822,12 @@
|
|||
;; Instruction suffix for integer modes.
|
||||
(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
|
||||
|
||||
;; Pointer size prefix for integer modes (Intel asm dialect)
|
||||
(define_mode_attr iptrsize [(QI "BYTE")
|
||||
(HI "WORD")
|
||||
(SI "DWORD")
|
||||
(DI "QWORD")])
|
||||
|
||||
;; Register class for integer modes.
|
||||
(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
|
||||
|
||||
|
@ -12042,50 +12049,28 @@
|
|||
(clobber (reg:CC FLAGS_REG))])]
|
||||
"")
|
||||
|
||||
;; Segment register for the thread base ptr load
|
||||
(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
|
||||
|
||||
;; Load and add the thread base pointer from %gs:0.
|
||||
|
||||
(define_insn "*load_tp_si"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec:SI [(const_int 0)] UNSPEC_TP))]
|
||||
"!TARGET_64BIT"
|
||||
"mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
|
||||
(define_insn "*load_tp_<mode>"
|
||||
[(set (match_operand:P 0 "register_operand" "=r")
|
||||
(unspec:P [(const_int 0)] UNSPEC_TP))]
|
||||
""
|
||||
"mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
|
||||
[(set_attr "type" "imov")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "length" "7")
|
||||
(set_attr "memory" "load")
|
||||
(set_attr "imm_disp" "false")])
|
||||
|
||||
(define_insn "*add_tp_si"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
|
||||
(match_operand:SI 1 "register_operand" "0")))
|
||||
(define_insn "*add_tp_<mode>"
|
||||
[(set (match_operand:P 0 "register_operand" "=r")
|
||||
(plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
|
||||
(match_operand:P 1 "register_operand" "0")))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"!TARGET_64BIT"
|
||||
"add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "length" "7")
|
||||
(set_attr "memory" "load")
|
||||
(set_attr "imm_disp" "false")])
|
||||
|
||||
(define_insn "*load_tp_di"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(unspec:DI [(const_int 0)] UNSPEC_TP))]
|
||||
"TARGET_64BIT"
|
||||
"mov{q}\t{%%fs:0, %0|%0, QWORD 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 "*add_tp_di"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
|
||||
(match_operand:DI 1 "register_operand" "0")))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"TARGET_64BIT"
|
||||
"add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
|
||||
""
|
||||
"add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "modrm" "0")
|
||||
(set_attr "length" "7")
|
||||
|
@ -12219,8 +12204,6 @@
|
|||
operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
|
||||
emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
|
||||
})
|
||||
|
||||
;;
|
||||
|
||||
;; These patterns match the binary 387 instructions for addM3, subM3,
|
||||
;; mulM3 and divM3. There are three patterns for each of DFmode and
|
||||
|
@ -17344,66 +17327,40 @@
|
|||
(match_operand 1 "memory_operand" "")]
|
||||
""
|
||||
{
|
||||
rtx (*insn)(rtx, rtx);
|
||||
|
||||
#ifdef TARGET_THREAD_SSP_OFFSET
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_stack_tls_protect_set_di (operands[0],
|
||||
GEN_INT (TARGET_THREAD_SSP_OFFSET)));
|
||||
else
|
||||
emit_insn (gen_stack_tls_protect_set_si (operands[0],
|
||||
GEN_INT (TARGET_THREAD_SSP_OFFSET)));
|
||||
operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
|
||||
insn = (TARGET_64BIT
|
||||
? gen_stack_tls_protect_set_di
|
||||
: gen_stack_tls_protect_set_si);
|
||||
#else
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
|
||||
insn = (TARGET_64BIT
|
||||
? gen_stack_protect_set_di
|
||||
: gen_stack_protect_set_si);
|
||||
#endif
|
||||
|
||||
emit_insn (insn (operands[0], operands[1]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "stack_protect_set_si"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=m")
|
||||
(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
|
||||
(set (match_scratch:SI 2 "=&r") (const_int 0))
|
||||
(define_insn "stack_protect_set_<mode>"
|
||||
[(set (match_operand:P 0 "memory_operand" "=m")
|
||||
(unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
|
||||
(set (match_scratch:P 2 "=&r") (const_int 0))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
""
|
||||
"mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
|
||||
"mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "stack_protect_set_di"
|
||||
[(set (match_operand:DI 0 "memory_operand" "=m")
|
||||
(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
|
||||
(set (match_scratch:DI 2 "=&r") (const_int 0))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"TARGET_64BIT"
|
||||
"mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "stack_tls_protect_set_si"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=m")
|
||||
(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
|
||||
UNSPEC_SP_TLS_SET))
|
||||
(set (match_scratch:SI 2 "=&r") (const_int 0))
|
||||
(define_insn "stack_tls_protect_set_<mode>"
|
||||
[(set (match_operand:P 0 "memory_operand" "=m")
|
||||
(unspec:P [(match_operand:P 1 "const_int_operand" "i")]
|
||||
UNSPEC_SP_TLS_SET))
|
||||
(set (match_scratch:P 2 "=&r") (const_int 0))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
""
|
||||
"mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "stack_tls_protect_set_di"
|
||||
[(set (match_operand:DI 0 "memory_operand" "=m")
|
||||
(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
|
||||
UNSPEC_SP_TLS_SET))
|
||||
(set (match_scratch:DI 2 "=&r") (const_int 0))
|
||||
(clobber (reg:CC FLAGS_REG))]
|
||||
"TARGET_64BIT"
|
||||
{
|
||||
/* The kernel uses a different segment register for performance reasons; a
|
||||
system call would not have to trash the userspace segment register,
|
||||
which would be expensive */
|
||||
if (ix86_cmodel != CM_KERNEL)
|
||||
return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
|
||||
else
|
||||
return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
|
||||
}
|
||||
"mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "stack_protect_test"
|
||||
|
@ -17414,71 +17371,44 @@
|
|||
{
|
||||
rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
|
||||
|
||||
rtx (*insn)(rtx, rtx, rtx);
|
||||
|
||||
#ifdef TARGET_THREAD_SSP_OFFSET
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
|
||||
GEN_INT (TARGET_THREAD_SSP_OFFSET)));
|
||||
else
|
||||
emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
|
||||
GEN_INT (TARGET_THREAD_SSP_OFFSET)));
|
||||
operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
|
||||
insn = (TARGET_64BIT
|
||||
? gen_stack_tls_protect_test_di
|
||||
: gen_stack_tls_protect_test_si);
|
||||
#else
|
||||
if (TARGET_64BIT)
|
||||
emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
|
||||
insn = (TARGET_64BIT
|
||||
? gen_stack_protect_test_di
|
||||
: gen_stack_protect_test_si);
|
||||
#endif
|
||||
|
||||
emit_insn (insn (flags, operands[0], operands[1]));
|
||||
|
||||
emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
|
||||
flags, const0_rtx, operands[2]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "stack_protect_test_si"
|
||||
(define_insn "stack_protect_test_<mode>"
|
||||
[(set (match_operand:CCZ 0 "flags_reg_operand" "")
|
||||
(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
|
||||
(match_operand:SI 2 "memory_operand" "m")]
|
||||
(unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
|
||||
(match_operand:P 2 "memory_operand" "m")]
|
||||
UNSPEC_SP_TEST))
|
||||
(clobber (match_scratch:SI 3 "=&r"))]
|
||||
(clobber (match_scratch:P 3 "=&r"))]
|
||||
""
|
||||
"mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
|
||||
"mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "stack_protect_test_di"
|
||||
(define_insn "stack_tls_protect_test_<mode>"
|
||||
[(set (match_operand:CCZ 0 "flags_reg_operand" "")
|
||||
(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
|
||||
(match_operand:DI 2 "memory_operand" "m")]
|
||||
UNSPEC_SP_TEST))
|
||||
(clobber (match_scratch:DI 3 "=&r"))]
|
||||
"TARGET_64BIT"
|
||||
"mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "stack_tls_protect_test_si"
|
||||
[(set (match_operand:CCZ 0 "flags_reg_operand" "")
|
||||
(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
|
||||
(match_operand:SI 2 "const_int_operand" "i")]
|
||||
(unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
|
||||
(match_operand:P 2 "const_int_operand" "i")]
|
||||
UNSPEC_SP_TLS_TEST))
|
||||
(clobber (match_scratch:SI 3 "=r"))]
|
||||
(clobber (match_scratch:P 3 "=r"))]
|
||||
""
|
||||
"mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "stack_tls_protect_test_di"
|
||||
[(set (match_operand:CCZ 0 "flags_reg_operand" "")
|
||||
(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
|
||||
(match_operand:DI 2 "const_int_operand" "i")]
|
||||
UNSPEC_SP_TLS_TEST))
|
||||
(clobber (match_scratch:DI 3 "=r"))]
|
||||
"TARGET_64BIT"
|
||||
{
|
||||
/* The kernel uses a different segment register for performance reasons; a
|
||||
system call would not have to trash the userspace segment register,
|
||||
which would be expensive */
|
||||
if (ix86_cmodel != CM_KERNEL)
|
||||
return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
|
||||
else
|
||||
return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
|
||||
}
|
||||
"mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
|
||||
[(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "sse4_2_crc32<mode>"
|
||||
|
|
Loading…
Add table
Reference in a new issue