From 9ad5e54f9548cfdd2fbed30d11fc82fd9f4bdd6e Mon Sep 17 00:00:00 2001 From: Rask Ingemann Lambertsen Date: Mon, 22 Oct 2007 13:50:56 +0200 Subject: [PATCH] re PR target/29473 (-masm=intel combined with -march=athlon64 has some issues.) PR target/29473 PR target/29493 * config/i386/i386.c (output_pic_addr_const): Support Intel asm syntax. (print_reg): Print register prefix only with AT&T asm syntax. Support pc_rtx for RIP register. (print_operand_address): Use print_reg()'s pc_rtx support for RIP relative addressing. Always print segment register prefix with AT&T asm syntax and never with Intel asm syntax. (print_operand): Suppress 'XXX PTR' prefix for BLKmode operands. Fix prefix for 16-byte XFmode operands. (output_addr_const_extra): Support Intel asm syntax. (x86_file_start): Don't use register prefix with Intel asm syntax. * config/i386/i386.md ("*zero_extendqihi2_movzbl"): Fix typo. ("return_internal_long"): Fix Intel asm syntax output. ("set_got_rex64"): Support Intel asm syntax. ("set_rip_rex64"): Likewise. ("set_got_offset_rex64"): Likewise. ("*sibcall_1_rex64_v"): Print register prefix only with AT&T asm syntax. ("*tls_global_dynamic_64"): Likewise. ("*tls_local_dynamic_base_64"): Likewise. ("*load_tp_si")("*load_tp_di"): Likewise. ("*add_tp_si")("*add_tp_di"): Likewise. ("*tls_dynamic_lea_64"): Likewise. ("*sibcall_value_1_rex64_v"): Likewise. ("stack_tls_protect_set_si"): Likewise. ("stack_tls_protect_set_di"): Likewise. ("stack_tls_protect_test_si"): Likewise. ("stack_tls_protect_test_di"): Likewise. * config/i386/mmx.md ("*mov_internal_rex64"): Fix Intel asm syntax output. ("*movv2sf_internal_rex64"): Likewise. * config/i386/cpuid.h (__cpuid): Support Intel asm syntax. (__get_cpuid_max): Likewise. From-SVN: r129548 --- gcc/ChangeLog | 37 +++++++++++++++++++ gcc/config/i386/cpuid.h | 24 ++++++------- gcc/config/i386/i386.c | 79 ++++++++++++++++++++++++----------------- gcc/config/i386/i386.md | 40 ++++++++++----------- gcc/config/i386/mmx.md | 8 ++--- 5 files changed, 120 insertions(+), 68 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ea58775e69e..620d7877ad6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,40 @@ +2007-10-22 Rask Ingemann Lambertsen + + PR target/29473 + PR target/29493 + * config/i386/i386.c (output_pic_addr_const): Support Intel asm syntax. + (print_reg): Print register prefix only with AT&T asm syntax. + Support pc_rtx for RIP register. + (print_operand_address): Use print_reg()'s pc_rtx support for RIP + relative addressing. Always print segment register prefix with AT&T + asm syntax and never with Intel asm syntax. + (print_operand): Suppress 'XXX PTR' prefix for BLKmode operands. + Fix prefix for 16-byte XFmode operands. + (output_addr_const_extra): Support Intel asm syntax. + (x86_file_start): Don't use register prefix with Intel asm syntax. + * config/i386/i386.md ("*zero_extendqihi2_movzbl"): Fix typo. + ("return_internal_long"): Fix Intel asm syntax output. + ("set_got_rex64"): Support Intel asm syntax. + ("set_rip_rex64"): Likewise. + ("set_got_offset_rex64"): Likewise. + ("*sibcall_1_rex64_v"): Print register prefix only with AT&T asm + syntax. + ("*tls_global_dynamic_64"): Likewise. + ("*tls_local_dynamic_base_64"): Likewise. + ("*load_tp_si")("*load_tp_di"): Likewise. + ("*add_tp_si")("*add_tp_di"): Likewise. + ("*tls_dynamic_lea_64"): Likewise. + ("*sibcall_value_1_rex64_v"): Likewise. + ("stack_tls_protect_set_si"): Likewise. + ("stack_tls_protect_set_di"): Likewise. + ("stack_tls_protect_test_si"): Likewise. + ("stack_tls_protect_test_di"): Likewise. + * config/i386/mmx.md ("*mov_internal_rex64"): Fix Intel asm + syntax output. + ("*movv2sf_internal_rex64"): Likewise. + * config/i386/cpuid.h (__cpuid): Support Intel asm syntax. + (__get_cpuid_max): Likewise. + 2007-10-21 Richard Sandiford * config/mips/mips-protos.h (mips_regno_mode_ok_for_base_p): Give diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index f272b67e6d2..7fa4f681547 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -62,9 +62,9 @@ #if defined(__i386__) && defined(__PIC__) /* %ebx may be the PIC register. */ #define __cpuid(level, a, b, c, d) \ - __asm__ ("xchgl\t%%ebx, %1\n\t" \ + __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ "cpuid\n\t" \ - "xchgl\t%%ebx, %1\n\t" \ + "xchg{l}\t{%%}ebx, %1\n\t" \ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ : "0" (level)) #else @@ -88,16 +88,16 @@ __get_cpuid_max (unsigned int __ext, unsigned int *__sig) #ifndef __x86_64__ /* See if we can use cpuid. On AMD64 we always can. */ - __asm__ ("pushfl\n\t" - "pushfl\n\t" - "popl\t%0\n\t" - "movl\t%0, %1\n\t" - "xorl\t%2, %0\n\t" - "pushl\t%0\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl\t%0\n\t" - "popfl\n\t" + __asm__ ("pushf{l|d}\n\t" + "pushf{l|d}\n\t" + "pop{l}\t%0\n\t" + "mov{l}\t{%0, %1|%1, %0}\n\t" + "xor{l}\t{%2, %0|%0, %2}\n\t" + "push{l}\t%0\n\t" + "popf{l|d}\n\t" + "pushf{l|d}\n\t" + "pop{l}\t%0\n\t" + "popf{l|d}\n\t" : "=&r" (__eax), "=&r" (__ebx) : "i" (0x00200000)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5ed8e2d372e..0429d239efa 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -8185,7 +8185,8 @@ output_pic_addr_const (FILE *file, rtx x, int code) fputs ("@PLTOFF", file); break; case UNSPEC_GOTPCREL: - fputs ("@GOTPCREL(%rip)", file); + fputs (ASSEMBLER_DIALECT == ASM_ATT ? + "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file); break; case UNSPEC_GOTTPOFF: /* FIXME: This might be @TPOFF in Sun ld too. */ @@ -8205,7 +8206,8 @@ output_pic_addr_const (FILE *file, rtx x, int code) break; case UNSPEC_GOTNTPOFF: if (TARGET_64BIT) - fputs ("@GOTTPOFF(%rip)", file); + fputs (ASSEMBLER_DIALECT == ASM_ATT ? + "@GOTTPOFF(%rip)": "@GOTTPOFF[rip]", file); else fputs ("@GOTNTPOFF", file); break; @@ -8531,15 +8533,23 @@ put_condition_code (enum rtx_code code, enum machine_mode mode, int reverse, void print_reg (rtx x, int code, FILE *file) { - gcc_assert (REGNO (x) != ARG_POINTER_REGNUM - && REGNO (x) != FRAME_POINTER_REGNUM - && REGNO (x) != FLAGS_REG - && REGNO (x) != FPSR_REG - && REGNO (x) != FPCR_REG); + gcc_assert (x == pc_rtx + || (REGNO (x) != ARG_POINTER_REGNUM + && REGNO (x) != FRAME_POINTER_REGNUM + && REGNO (x) != FLAGS_REG + && REGNO (x) != FPSR_REG + && REGNO (x) != FPCR_REG)); - if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0) + if (ASSEMBLER_DIALECT == ASM_ATT) putc ('%', file); + if (x == pc_rtx) + { + gcc_assert (TARGET_64BIT); + fputs ("rip", file); + return; + } + if (code == 'w' || MMX_REG_P (x)) code = 2; else if (code == 'b') @@ -9036,8 +9046,9 @@ print_operand (FILE *file, rtx x, int code) else if (MEM_P (x)) { - /* No `byte ptr' prefix for call instructions. */ - if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P') + /* No `byte ptr' prefix for call instructions or BLKmode operands. */ + if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P' + && GET_MODE (x) != BLKmode) { const char * size; switch (GET_MODE_SIZE (GET_MODE (x))) @@ -9047,7 +9058,12 @@ print_operand (FILE *file, rtx x, int code) case 4: size = "DWORD"; break; case 8: size = "QWORD"; break; case 12: size = "XWORD"; break; - case 16: size = "XMMWORD"; break; + case 16: + if (GET_MODE (x) == XFmode) + size = "XWORD"; + else + size = "XMMWORD"; + break; default: gcc_unreachable (); } @@ -9165,7 +9181,7 @@ print_operand_address (FILE *file, rtx addr) break; case SEG_FS: case SEG_GS: - if (USER_LABEL_PREFIX[0] == 0) + if (ASSEMBLER_DIALECT == ASM_ATT) putc ('%', file); fputs ((parts.seg == SEG_FS ? "fs:" : "gs:"), file); break; @@ -9173,6 +9189,21 @@ print_operand_address (FILE *file, rtx addr) gcc_unreachable (); } + /* Use one byte shorter RIP relative addressing for 64bit mode. */ + if (TARGET_64BIT && !base && !index) + { + rtx symbol = disp; + + if (GET_CODE (disp) == CONST + && GET_CODE (XEXP (disp, 0)) == PLUS + && CONST_INT_P (XEXP (XEXP (disp, 0), 1))) + symbol = XEXP (XEXP (disp, 0), 0); + + if (GET_CODE (symbol) == LABEL_REF + || (GET_CODE (symbol) == SYMBOL_REF + && SYMBOL_REF_TLS_MODEL (symbol) == 0)) + base = pc_rtx; + } if (!base && !index) { /* Displacement only requires special attention. */ @@ -9180,30 +9211,13 @@ print_operand_address (FILE *file, rtx addr) if (CONST_INT_P (disp)) { if (ASSEMBLER_DIALECT == ASM_INTEL && parts.seg == SEG_DEFAULT) - { - if (USER_LABEL_PREFIX[0] == 0) - putc ('%', file); - fputs ("ds:", file); - } + fputs ("ds:", file); fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp)); } else if (flag_pic) output_pic_addr_const (file, disp, 0); else output_addr_const (file, disp); - - /* Use one byte shorter RIP relative addressing for 64bit mode. */ - if (TARGET_64BIT) - { - if (GET_CODE (disp) == CONST - && GET_CODE (XEXP (disp, 0)) == PLUS - && CONST_INT_P (XEXP (XEXP (disp, 0), 1))) - disp = XEXP (XEXP (disp, 0), 0); - if (GET_CODE (disp) == LABEL_REF - || (GET_CODE (disp) == SYMBOL_REF - && SYMBOL_REF_TLS_MODEL (disp) == 0)) - fputs ("(%rip)", file); - } } else { @@ -9319,7 +9333,8 @@ output_addr_const_extra (FILE *file, rtx x) case UNSPEC_GOTNTPOFF: output_addr_const (file, op); if (TARGET_64BIT) - fputs ("@GOTTPOFF(%rip)", file); + fputs (ASSEMBLER_DIALECT == ASM_ATT ? + "@GOTTPOFF(%rip)" : "@GOTTPOFF[rip]", file); else fputs ("@GOTNTPOFF", file); break; @@ -22736,7 +22751,7 @@ x86_file_start (void) if (X86_FILE_START_FLTUSED) fputs ("\t.global\t__fltused\n", asm_out_file); if (ix86_asm_dialect == ASM_INTEL) - fputs ("\t.intel_syntax\n", asm_out_file); + fputs ("\t.intel_syntax noprefix\n", asm_out_file); } int diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ec2787f096c..c13fcbcb7c1 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3439,7 +3439,7 @@ [(set (match_operand:HI 0 "register_operand" "=r") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" - "movz{bl|x}\t{%1, %k0|%k0, %k1}" + "movz{bl|x}\t{%1, %k0|%k0, %1}" [(set_attr "type" "imovx") (set_attr "mode" "SI")]) @@ -14907,7 +14907,7 @@ [(call (mem:QI (reg:DI R11_REG)) (match_operand 0 "" ""))] "SIBLING_CALL_P (insn) && TARGET_64BIT" - "jmp\t*%%r11" + "jmp\t{*%%}r11" [(set_attr "type" "call")]) @@ -15037,7 +15037,7 @@ [(return) (unspec [(const_int 0)] UNSPEC_REP)] "reload_completed" - "rep{\;| }ret" + "rep\;ret" [(set_attr "length" "1") (set_attr "length_immediate" "0") (set_attr "prefix_rep" "1") @@ -15116,7 +15116,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] "TARGET_64BIT" - "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0" + "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" [(set_attr "type" "lea") (set_attr "length" "6")]) @@ -15124,7 +15124,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))] "TARGET_64BIT" - "lea{q}\t%l1(%%rip), %0" + "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" [(set_attr "type" "lea") (set_attr "length" "6")]) @@ -15132,7 +15132,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))] "TARGET_64BIT" - "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0" + "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" [(set_attr "type" "imov") (set_attr "length" "11")]) @@ -15753,7 +15753,7 @@ (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] UNSPEC_TLS_GD)] "TARGET_64BIT" - ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2" + ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2" [(set_attr "type" "multi") (set_attr "length" "16")]) @@ -15831,7 +15831,7 @@ (match_operand:DI 2 "" ""))) (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] "TARGET_64BIT" - "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1" + "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1" [(set_attr "type" "multi") (set_attr "length" "12")]) @@ -15881,7 +15881,7 @@ [(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}" + "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}" [(set_attr "type" "imov") (set_attr "modrm" "0") (set_attr "length" "7") @@ -15894,7 +15894,7 @@ (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}" + "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}" [(set_attr "type" "alu") (set_attr "modrm" "0") (set_attr "length" "7") @@ -15905,7 +15905,7 @@ [(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}" + "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}" [(set_attr "type" "imov") (set_attr "modrm" "0") (set_attr "length" "7") @@ -15918,7 +15918,7 @@ (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{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}" [(set_attr "type" "alu") (set_attr "modrm" "0") (set_attr "length" "7") @@ -16014,7 +16014,7 @@ (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] UNSPEC_TLSDESC))] "TARGET_64BIT && TARGET_GNU2_TLS" - "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}" + "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}" [(set_attr "type" "lea") (set_attr "mode" "DI") (set_attr "length" "7") @@ -21262,7 +21262,7 @@ (call (mem:QI (reg:DI R11_REG)) (match_operand:DI 1 "" "")))] "SIBLING_CALL_P (insn) && TARGET_64BIT" - "jmp\t*%%r11" + "jmp\t{*%%}r11" [(set_attr "type" "callv")]) ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. @@ -21470,7 +21470,7 @@ (set (match_scratch:SI 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" + "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" @@ -21484,9 +21484,9 @@ 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"; + 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"; + return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; } [(set_attr "type" "multi")]) @@ -21545,7 +21545,7 @@ UNSPEC_SP_TLS_TEST)) (clobber (match_scratch:SI 3 "=r"))] "" - "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}" + "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" @@ -21560,9 +21560,9 @@ 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}"; + 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}"; + return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}"; } [(set_attr "type" "multi")]) diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 20c4fb05b57..72780155d2b 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -69,8 +69,8 @@ "TARGET_64BIT && TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ - movq\t{%1, %0|%0, %1} - movq\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} pxor\t%0, %0 movq\t{%1, %0|%0, %1} movq\t{%1, %0|%0, %1} @@ -128,8 +128,8 @@ "TARGET_64BIT && TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ - movq\t{%1, %0|%0, %1} - movq\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} pxor\t%0, %0 movq\t{%1, %0|%0, %1} movq\t{%1, %0|%0, %1}