From d1e74401c1f2e86cbcdb7e013bba40fe6cc96b78 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 6 Sep 2010 08:43:54 +0200 Subject: [PATCH] i386.md (iptrsize): New mode attribute. * config/i386/i386.md (iptrsize): New mode attribute. (tp_seg): Ditto. (*load_tp_): Macroize insn from *load_tp_{si,di} using P mode iterator. (*add_tp_): Ditto from *add_tp_{si,di}. (stack_protect_set_): Ditto from stack_protect_set_{si,di}. (stack_protect_test_): Ditto from stack_protect_test_{si,di}. (stack_tls_protect_set_): Ditto from stack_tls_protect_set_{si,di}. Use %@ to output segment register of thread base pointer load. (stack_tls_protect_test_): 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 --- gcc/ChangeLog | 20 ++++ gcc/config/i386/i386.c | 17 +++- gcc/config/i386/i386.md | 198 +++++++++++++--------------------------- 3 files changed, 100 insertions(+), 135 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 141063e25ad..1b47551611e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2010-09-06 Uros Bizjak + + * config/i386/i386.md (iptrsize): New mode attribute. + (tp_seg): Ditto. + (*load_tp_): Macroize insn from *load_tp_{si,di} using P + mode iterator. + (*add_tp_): Ditto from *add_tp_{si,di}. + (stack_protect_set_): Ditto from stack_protect_set_{si,di}. + (stack_protect_test_): Ditto from stack_protect_test_{si,di}. + (stack_tls_protect_set_): Ditto from + stack_tls_protect_set_{si,di}. Use %@ to output segment register + of thread base pointer load. + (stack_tls_protect_test_): 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 * tree-tailcall.c (process_assignment): Handle NEGATE_EXPR and diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3a8484aeca4..fac660b632e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 726301cf0de..9780eef9047 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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))])] "") -;; Load and add the thread base pointer from %gs:0. +;; Segment register for the thread base ptr load +(define_mode_attr tp_seg [(SI "gs") (DI "fs")]) -(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}" - [(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"))) - (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}" +;; Load and add the thread base pointer from %gs:0. +(define_insn "*load_tp_" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(const_int 0)] UNSPEC_TP))] + "" + "mov{}\t{%%:0, %0|%0, PTR :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"))) +(define_insn "*add_tp_" + [(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{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}" + "" + "add{}\t{%%:0, %0|%0, PTR :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_" + [(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" - [(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" + "mov{}\t{%1, %2|%2, %1}\;mov{}\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_" + [(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{}\t{%@:%P1, %2|%2, PTR %@:%P1}\;mov{}\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_" [(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}" - [(set_attr "type" "multi")]) - -(define_insn "stack_protect_test_di" - [(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}" + "mov{}\t{%1, %3|%3, %1}\;xor{}\t{%2, %3|%3, %2}" [(set_attr "type" "multi")]) -(define_insn "stack_tls_protect_test_si" +(define_insn "stack_tls_protect_test_" [(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{}\t{%1, %3|%3, %1}\;xor{}\t{%@:%P2, %3|%3, PTR %@:%P2}" [(set_attr "type" "multi")]) (define_insn "sse4_2_crc32" -- 2.30.2