diff options
Diffstat (limited to 'gcc-4.4.3/gcc/config/i386/i386.md')
-rw-r--r-- | gcc-4.4.3/gcc/config/i386/i386.md | 219 |
1 files changed, 197 insertions, 22 deletions
diff --git a/gcc-4.4.3/gcc/config/i386/i386.md b/gcc-4.4.3/gcc/config/i386/i386.md index 22c891c49..bbe915112 100644 --- a/gcc-4.4.3/gcc/config/i386/i386.md +++ b/gcc-4.4.3/gcc/config/i386/i386.md @@ -227,6 +227,11 @@ (UNSPECV_CLD 15) (UNSPECV_VZEROALL 16) (UNSPECV_VZEROUPPER 17) + (UNSPECV_VSWAPMOV 18) + (UNSPECV_LLWP_INTRINSIC 19) + (UNSPECV_SLWP_INTRINSIC 20) + (UNSPECV_LWPVAL_INTRINSIC 21) + (UNSPECV_LWPINS_INTRINSIC 22) ]) ;; Constants to represent pcomtrue/pcomfalse variants @@ -315,7 +320,7 @@ ;; Processor type. -(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2, +(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom, generic64,amdfam10" (const (symbol_ref "ix86_schedule"))) @@ -329,9 +334,9 @@ push,pop,call,callv,leave, str,bitmanip, fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, - sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul, + sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul, sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins, - ssemuladd,sse4arg, + ssemuladd,sse4arg,lwp, mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" (const_string "other")) @@ -344,7 +349,7 @@ (define_attr "unit" "integer,i387,sse,mmx,unknown" (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") (const_string "i387") - (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul, + (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul, sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt, ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg") (const_string "sse") @@ -524,7 +529,7 @@ ;; if the instruction is complex. (define_attr "memory" "none,load,store,both,unknown" - (cond [(eq_attr "type" "other,multi,str") + (cond [(eq_attr "type" "other,multi,str,lwp") (const_string "unknown") (eq_attr "type" "lea,fcmov,fpspc") (const_string "none") @@ -611,6 +616,12 @@ (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" (const_string "any")) +;; Define attribute to classify add/sub insns that consumes carry flag (CF) +(define_attr "use_carry" "0,1" (const_string "0")) + +;; Define attribute to indicate unaligned ssemov insns +(define_attr "movu" "0,1" (const_string "0")) + ;; Describe a user's asm statement. (define_asm_attributes [(set_attr "length" "128") @@ -673,6 +684,9 @@ ;; Single word integer modes without QImode. (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) +;; Single word integer modes without QImode and HImode. +(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) + ;; Instruction suffix for integer modes. (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) @@ -726,6 +740,7 @@ (include "k6.md") (include "athlon.md") (include "geode.md") +(include "atom.md") ;; Operand and operator predicates and constraints @@ -5789,6 +5804,7 @@ "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" "adc{q}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "DI")]) @@ -5863,6 +5879,7 @@ "ix86_binary_operator_ok (PLUS, QImode, operands)" "adc{b}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "QI")]) @@ -5875,6 +5892,7 @@ "ix86_binary_operator_ok (PLUS, HImode, operands)" "adc{w}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "HI")]) @@ -5887,6 +5905,7 @@ "ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) @@ -5900,6 +5919,7 @@ "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %k0|%k0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) @@ -6129,9 +6149,9 @@ (set_attr "mode" "SI")]) (define_insn "*adddi_1_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") - (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r") - (match_operand:DI 2 "x86_64_general_operand" "rme,re,le"))) + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r") + (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" { @@ -6152,6 +6172,10 @@ } default: + /* Use add as much as possible to replace lea for AGU optimization. */ + if (which_alternative == 2 && TARGET_OPT_AGU) + return "add{q}\t{%1, %0|%0, %1}"; + gcc_assert (rtx_equal_p (operands[0], operands[1])); /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. @@ -6170,8 +6194,11 @@ } } [(set (attr "type") - (cond [(eq_attr "alternative" "2") + (cond [(and (eq_attr "alternative" "2") + (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) (const_string "lea") + (eq_attr "alternative" "3") + (const_string "lea") ; Current assemblers are broken and do not allow @GOTOFF in ; ought but a memory context. (match_operand:DI 2 "pic_symbolic_operand" "") @@ -6188,8 +6215,8 @@ (plus:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1])" + "TARGET_64BIT && reload_completed + && ix86_lea_for_add_ok (PLUS, insn, operands)" [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] @@ -6393,9 +6420,9 @@ (define_insn "*addsi_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") - (match_operand:SI 2 "general_operand" "g,ri,li"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r") + (match_operand:SI 2 "general_operand" "g,ri,0,li"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -6416,6 +6443,10 @@ } default: + /* Use add as much as possible to replace lea for AGU optimization. */ + if (which_alternative == 2 && TARGET_OPT_AGU) + return "add{l}\t{%1, %0|%0, %1}"; + gcc_assert (rtx_equal_p (operands[0], operands[1])); /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. @@ -6432,7 +6463,10 @@ } } [(set (attr "type") - (cond [(eq_attr "alternative" "2") + (cond [(and (eq_attr "alternative" "2") + (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) + (const_string "lea") + (eq_attr "alternative" "3") (const_string "lea") ; Current assemblers are broken and do not allow @GOTOFF in ; ought but a memory context. @@ -6450,8 +6484,7 @@ (plus (match_operand 1 "register_operand" "") (match_operand 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1])" + "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" [(const_int 0)] { rtx pat; @@ -7552,6 +7585,7 @@ "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" "sbb{q}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "DI")]) @@ -7600,6 +7634,7 @@ "ix86_binary_operator_ok (MINUS, QImode, operands)" "sbb{b}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "QI")]) @@ -7612,6 +7647,7 @@ "ix86_binary_operator_ok (MINUS, HImode, operands)" "sbb{w}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "HI")]) @@ -7624,6 +7660,7 @@ "ix86_binary_operator_ok (MINUS, SImode, operands)" "sbb{l}\t{%2, %0|%0, %2}" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "mode" "SI")]) @@ -15162,7 +15199,7 @@ ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), operands[0], const0_rtx, GEN_INT ((TARGET_64BIT - ? (DEFAULT_ABI == SYSV_ABI + ? (ix86_abi == SYSV_ABI ? X86_64_SSE_REGPARM_MAX : X64_SSE_REGPARM_MAX) : X86_32_SSE_REGPARM_MAX) @@ -15242,6 +15279,7 @@ "reload_completed" "ret" [(set_attr "length" "1") + (set_attr "atom_unit" "jeu") (set_attr "length_immediate" "0") (set_attr "modrm" "0")]) @@ -15254,6 +15292,7 @@ "reload_completed" "rep\;ret" [(set_attr "length" "1") + (set_attr "atom_unit" "jeu") (set_attr "length_immediate" "0") (set_attr "prefix_rep" "1") (set_attr "modrm" "0")]) @@ -15264,6 +15303,7 @@ "reload_completed" "ret\t%0" [(set_attr "length" "3") + (set_attr "atom_unit" "jeu") (set_attr "length_immediate" "2") (set_attr "modrm" "0")]) @@ -15612,7 +15652,7 @@ (bswap:SI (match_operand:SI 1 "register_operand" "")))] "" { - if (!TARGET_BSWAP) + if (!(TARGET_BSWAP || TARGET_MOVBE)) { rtx x = operands[0]; @@ -15624,6 +15664,21 @@ } }) +(define_insn "*bswapsi_movbe" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m") + (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))] + "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + bswap\t%0 + movbe\t{%1, %0|%0, %1} + movbe\t{%1, %0|%0, %1}" + [(set_attr "type" "*,imov,imov") + (set_attr "modrm" "*,1,1") + (set_attr "prefix_0f" "1") + (set_attr "prefix_extra" "*,1,1") + (set_attr "length" "2,*,*") + (set_attr "mode" "SI")]) + (define_insn "*bswapsi_1" [(set (match_operand:SI 0 "register_operand" "=r") (bswap:SI (match_operand:SI 1 "register_operand" "0")))] @@ -15652,7 +15707,29 @@ [(set_attr "length" "4") (set_attr "mode" "HI")]) -(define_insn "bswapdi2" +(define_expand "bswapdi2" + [(set (match_operand:DI 0 "register_operand" "") + (bswap:DI (match_operand:DI 1 "register_operand" "")))] + "TARGET_64BIT" + "") + +(define_insn "*bswapdi_movbe" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m") + (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))] + "TARGET_64BIT && TARGET_MOVBE + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + bswap\t%0 + movbe\t{%1, %0|%0, %1} + movbe\t{%1, %0|%0, %1}" + [(set_attr "type" "*,imov,imov") + (set_attr "modrm" "*,1,1") + (set_attr "prefix_0f" "1") + (set_attr "prefix_extra" "*,1,1") + (set_attr "length" "3,*,*") + (set_attr "mode" "DI")]) + +(define_insn "*bswapdi_1" [(set (match_operand:DI 0 "register_operand" "=r") (bswap:DI (match_operand:DI 1 "register_operand" "0")))] "TARGET_64BIT" @@ -16380,6 +16457,7 @@ "TARGET_SSE_MATH" "%vrcpss\t{%1, %d0|%d0, %1}" [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "rcp") (set_attr "prefix" "maybe_vex") (set_attr "mode" "SF")]) @@ -16731,6 +16809,7 @@ "TARGET_SSE_MATH" "%vrsqrtss\t{%1, %d0|%d0, %1}" [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "rcp") (set_attr "prefix" "maybe_vex") (set_attr "mode" "SF")]) @@ -16751,6 +16830,7 @@ "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}" [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "sqrt") (set_attr "prefix" "maybe_vex") (set_attr "mode" "<MODE>") (set_attr "athlon_decode" "*") @@ -19807,6 +19887,7 @@ ; Since we don't have the proper number of operands for an alu insn, ; fill in all the blanks. [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "memory" "none") (set_attr "imm_disp" "false") @@ -19822,6 +19903,7 @@ "" "sbb{q}\t%0, %0" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "memory" "none") (set_attr "imm_disp" "false") @@ -19865,6 +19947,7 @@ ; Since we don't have the proper number of operands for an alu insn, ; fill in all the blanks. [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "memory" "none") (set_attr "imm_disp" "false") @@ -19880,6 +19963,7 @@ "" "sbb{l}\t%0, %0" [(set_attr "type" "alu") + (set_attr "use_carry" "1") (set_attr "pent_pair" "pu") (set_attr "memory" "none") (set_attr "imm_disp" "false") @@ -20212,7 +20296,8 @@ } } [(set (attr "type") - (cond [(eq_attr "alternative" "0") + (cond [(and (eq_attr "alternative" "0") + (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) (const_string "alu") (match_operand:SI 2 "const0_operand" "") (const_string "imov") @@ -20255,7 +20340,8 @@ } } [(set (attr "type") - (cond [(eq_attr "alternative" "0") + (cond [(and (eq_attr "alternative" "0") + (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0))) (const_string "alu") (match_operand:DI 2 "const0_operand" "") (const_string "imov") @@ -21753,6 +21839,7 @@ return patterns[locality]; } [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "prefetch") (set_attr "memory" "none")]) (define_insn "*prefetch_sse_rex" @@ -21771,6 +21858,7 @@ return patterns[locality]; } [(set_attr "type" "sse") + (set_attr "atom_sse_attr" "prefetch") (set_attr "memory" "none")]) (define_insn "*prefetch_3dnow" @@ -21972,6 +22060,93 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; LWP instructions +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_expand "lwp_llwpcb" + [(unspec_volatile [(match_operand 0 "register_operand" "r")] + UNSPECV_LLWP_INTRINSIC)] + "TARGET_LWP" + "") + +(define_insn "*lwp_llwpcb<mode>1" + [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] + UNSPECV_LLWP_INTRINSIC)] + "TARGET_LWP" + "llwpcb\t%0" + [(set_attr "type" "lwp") + (set_attr "mode" "<MODE>") + (set_attr "length" "5")]) + +(define_expand "lwp_slwpcb" + [(set (match_operand 0 "register_operand" "=r") + (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] + "TARGET_LWP" + { + if (TARGET_64BIT) + emit_insn (gen_lwp_slwpcbdi (operands[0])); + else + emit_insn (gen_lwp_slwpcbsi (operands[0])); + DONE; + }) + +(define_insn "lwp_slwpcb<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] + "TARGET_LWP" + "slwpcb\t%0" + [(set_attr "type" "lwp") + (set_attr "mode" "<MODE>") + (set_attr "length" "5")]) + +(define_expand "lwp_lwpval<mode>3" + [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r") + (match_operand:SI 2 "nonimmediate_operand" "rm") + (match_operand:SI 3 "const_int_operand" "i")] + UNSPECV_LWPVAL_INTRINSIC)] + "TARGET_LWP" + "/* Avoid unused variable warning. */ + (void) operand0;") + +(define_insn "*lwp_lwpval<mode>3_1" + [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") + (match_operand:SI 1 "nonimmediate_operand" "rm") + (match_operand:SI 2 "const_int_operand" "i")] + UNSPECV_LWPVAL_INTRINSIC)] + "TARGET_LWP" + "lwpval\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "lwp") + (set_attr "mode" "<MODE>") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) + +(define_expand "lwp_lwpins<mode>3" + [(set (reg:CCC FLAGS_REG) + (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r") + (match_operand:SI 2 "nonimmediate_operand" "rm") + (match_operand:SI 3 "const_int_operand" "i")] + UNSPECV_LWPINS_INTRINSIC)) + (set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] + "TARGET_LWP" + "") + +(define_insn "*lwp_lwpins<mode>3_1" + [(set (reg:CCC FLAGS_REG) + (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") + (match_operand:SI 1 "nonimmediate_operand" "rm") + (match_operand:SI 2 "const_int_operand" "i")] + UNSPECV_LWPINS_INTRINSIC))] + "TARGET_LWP" + "lwpins\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "type" "lwp") + (set_attr "mode" "<MODE>") + (set (attr "length") + (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) + (include "mmx.md") (include "sse.md") (include "sync.md") |