📄 i386.md
字号:
"* return output_fp_compare (insn, operands, 0, 0);" [(set_attr "type" "fcmp") (set_attr "mode" "XF")])(define_insn "*cmpfp_2_xf_1" [(set (match_operand:HI 0 "register_operand" "=a") (unspec:HI [(compare:CCFP (match_operand:XF 1 "register_operand" "f") (match_operand:XF 2 "register_operand" "f"))] UNSPEC_FNSTSW))] "!TARGET_64BIT && TARGET_80387" "* return output_fp_compare (insn, operands, 2, 0);" [(set_attr "type" "multi") (set_attr "mode" "XF")])(define_insn "*cmpfp_2_tf_1" [(set (match_operand:HI 0 "register_operand" "=a") (unspec:HI [(compare:CCFP (match_operand:TF 1 "register_operand" "f") (match_operand:TF 2 "register_operand" "f"))] UNSPEC_FNSTSW))] "TARGET_80387" "* return output_fp_compare (insn, operands, 2, 0);" [(set_attr "type" "multi") (set_attr "mode" "XF")])(define_insn "*cmpfp_2u" [(set (reg:CCFPU 18) (compare:CCFPU (match_operand 0 "register_operand" "f") (match_operand 1 "register_operand" "f")))] "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" "* return output_fp_compare (insn, operands, 0, 1);" [(set_attr "type" "fcmp") (set_attr "mode" "unknownfp")])(define_insn "*cmpfp_2u_1" [(set (match_operand:HI 0 "register_operand" "=a") (unspec:HI [(compare:CCFPU (match_operand 1 "register_operand" "f") (match_operand 2 "register_operand" "f"))] UNSPEC_FNSTSW))] "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1])) && GET_MODE (operands[1]) == GET_MODE (operands[2])" "* return output_fp_compare (insn, operands, 2, 1);" [(set_attr "type" "multi") (set_attr "mode" "unknownfp")]);; Patterns to match the SImode-in-memory ficom instructions.;;;; %%% Play games with accepting gp registers, as otherwise we have to;; force them to memory during rtl generation, which is no good. We;; can get rid of this once we teach reload to do memory input reloads ;; via pushes.(define_insn "*ficom_1" [(set (reg:CCFP 18) (compare:CCFP (match_operand 0 "register_operand" "f,f") (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))] "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])" "#");; Split the not-really-implemented gp register case into a;; push-op-pop sequence.;;;; %%% This is most efficient, but am I gonna get in trouble;; for separating cc0_setter and cc0_user?(define_split [(set (reg:CCFP 18) (compare:CCFP (match_operand:SF 0 "register_operand" "") (float (match_operand:SI 1 "register_operand" ""))))] "0 && TARGET_80387 && reload_completed" [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1)) (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2))) (parallel [(set (match_dup 1) (mem:SI (reg:SI 7))) (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])] "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx); operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);");; FP compares, step 2;; Move the fpsw to ax.(define_insn "x86_fnstsw_1" [(set (match_operand:HI 0 "register_operand" "=a") (unspec:HI [(reg 18)] UNSPEC_FNSTSW))] "TARGET_80387" "fnstsw\t%0" [(set_attr "length" "2") (set_attr "mode" "SI") (set_attr "unit" "i387") (set_attr "ppro_uops" "few")]);; FP compares, step 3;; Get ax into flags, general case.(define_insn "x86_sahf_1" [(set (reg:CC 17) (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))] "!TARGET_64BIT" "sahf" [(set_attr "length" "1") (set_attr "athlon_decode" "vector") (set_attr "mode" "SI") (set_attr "ppro_uops" "one")]);; Pentium Pro can do steps 1 through 3 in one go.(define_insn "*cmpfp_i" [(set (reg:CCFP 17) (compare:CCFP (match_operand 0 "register_operand" "f") (match_operand 1 "register_operand" "f")))] "TARGET_80387 && TARGET_CMOVE && !SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[0])" "* return output_fp_compare (insn, operands, 1, 0);" [(set_attr "type" "fcmp") (set_attr "mode" "unknownfp") (set_attr "athlon_decode" "vector")])(define_insn "*cmpfp_i_sse" [(set (reg:CCFP 17) (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f") (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] "TARGET_80387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[0])" "* return output_fp_compare (insn, operands, 1, 0);" [(set_attr "type" "fcmp,ssecmp") (set_attr "mode" "unknownfp") (set_attr "athlon_decode" "vector")])(define_insn "*cmpfp_i_sse_only" [(set (reg:CCFP 17) (compare:CCFP (match_operand 0 "register_operand" "x") (match_operand 1 "nonimmediate_operand" "xm")))] "SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[0])" "* return output_fp_compare (insn, operands, 1, 0);" [(set_attr "type" "ssecmp") (set_attr "mode" "unknownfp") (set_attr "athlon_decode" "vector")])(define_insn "*cmpfp_iu" [(set (reg:CCFPU 17) (compare:CCFPU (match_operand 0 "register_operand" "f") (match_operand 1 "register_operand" "f")))] "TARGET_80387 && TARGET_CMOVE && !SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" "* return output_fp_compare (insn, operands, 1, 1);" [(set_attr "type" "fcmp") (set_attr "mode" "unknownfp") (set_attr "athlon_decode" "vector")])(define_insn "*cmpfp_iu_sse" [(set (reg:CCFPU 17) (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f") (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] "TARGET_80387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" "* return output_fp_compare (insn, operands, 1, 1);" [(set_attr "type" "fcmp,ssecmp") (set_attr "mode" "unknownfp") (set_attr "athlon_decode" "vector")])(define_insn "*cmpfp_iu_sse_only" [(set (reg:CCFPU 17) (compare:CCFPU (match_operand 0 "register_operand" "x") (match_operand 1 "nonimmediate_operand" "xm")))] "SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" "* return output_fp_compare (insn, operands, 1, 1);" [(set_attr "type" "ssecmp") (set_attr "mode" "unknownfp") (set_attr "athlon_decode" "vector")]);; Move instructions.;; General case of fullword move.(define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "") (match_operand:SI 1 "general_operand" ""))] "" "ix86_expand_move (SImode, operands); DONE;");; Push/pop instructions. They are separate since autoinc/dec is not a;; general_operand.;;;; %%% We don't use a post-inc memory reference because x86 is not a ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.;; Changing this impacts compiler performance on other non-AUTO_INC_DEC;; targets without our curiosities, and it is just as easy to represent;; this differently.(define_insn "*pushsi2" [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] "!TARGET_64BIT" "push{l}\t%1" [(set_attr "type" "push") (set_attr "mode" "SI")]);; For 64BIT abi we always round up to 8 bytes.(define_insn "*pushsi2_rex64" [(set (match_operand:SI 0 "push_operand" "=X") (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] "TARGET_64BIT" "push{q}\t%q1" [(set_attr "type" "push") (set_attr "mode" "SI")])(define_insn "*pushsi2_prologue" [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "general_no_elim_operand" "ri*m")) (clobber (mem:BLK (scratch)))] "!TARGET_64BIT" "push{l}\t%1" [(set_attr "type" "push") (set_attr "mode" "SI")])(define_insn "*popsi1_epilogue" [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") (mem:SI (reg:SI 7))) (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4))) (clobber (mem:BLK (scratch)))] "!TARGET_64BIT" "pop{l}\t%0" [(set_attr "type" "pop") (set_attr "mode" "SI")])(define_insn "popsi1" [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") (mem:SI (reg:SI 7))) (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))] "!TARGET_64BIT" "pop{l}\t%0" [(set_attr "type" "pop") (set_attr "mode" "SI")])(define_insn "*movsi_xor" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "const0_operand" "i")) (clobber (reg:CC 17))] "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" "xor{l}\t{%0, %0|%0, %0}" [(set_attr "type" "alu1") (set_attr "mode" "SI") (set_attr "length_immediate" "0")])(define_insn "*movsi_or" [(set (match_operand:SI 0 "register_operand" "=r") (match_operand:SI 1 "immediate_operand" "i")) (clobber (reg:CC 17))] "reload_completed && GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == -1 && (TARGET_PENTIUM || optimize_size)"{ operands[1] = constm1_rtx; return "or{l}\t{%1, %0|%0, %1}";} [(set_attr "type" "alu1") (set_attr "mode" "SI") (set_attr "length_immediate" "1")])(define_insn "*movsi_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!*Y,!rm") (match_operand:SI 1 "general_operand" "rinm,rin,rm,*y,*y,*Y,rm,*Y"))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"{ switch (get_attr_type (insn)) { case TYPE_SSEMOV: if (get_attr_mode (insn) == MODE_TI) return "movdqa\t{%1, %0|%0, %1}"; return "movd\t{%1, %0|%0, %1}"; case TYPE_MMXMOV: if (get_attr_mode (insn) == MODE_DI) return "movq\t{%1, %0|%0, %1}"; return "movd\t{%1, %0|%0, %1}"; case TYPE_LEA: return "lea{l}\t{%1, %0|%0, %1}"; default: if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1])) abort(); return "mov{l}\t{%1, %0|%0, %1}"; }} [(set (attr "type") (cond [(eq_attr "alternative" "2,3,4") (const_string "mmxmov") (eq_attr "alternative" "5,6,7") (const_string "ssemov") (and (ne (symbol_ref "flag_pic") (const_int 0)) (match_operand:SI 1 "symbolic_operand" "")) (const_string "lea") ] (const_string "imov"))) (set_attr "mode" "SI,SI,SI,SI,DI,TI,SI,SI")]);; Stores and loads of ax to arbitary constant address.;; We fake an second form of instruction to force reload to load address;; into register when rax is not available(define_insn "*movabssi_1_rex64" [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) (match_operand:SI 1 "nonmemory_operand" "a,er"))] "TARGET_64BIT && ix86_check_movabs (insn, 0)" "@ movabs{l}\t{%1, %P0|%P0, %1} mov{l}\t{%1, %a0|%a0, %1}" [(set_attr "type" "imov") (set_attr "modrm" "0,*") (set_attr "length_address" "8,0") (set_attr "length_immediate" "0,*") (set_attr "memory" "store") (set_attr "mode" "SI")])(define_insn "*movabssi_2_rex64" [(set (match_operand:SI 0 "register_operand" "=a,r") (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] "TARGET_64BIT && ix86_check_movabs (insn, 1)" "@ movabs{l}\t{%P1, %0|%0, %P1} mov{l}\t{%a1, %0|%0, %a1}" [(set_attr "type" "imov") (set_attr "modrm" "0,*") (set_attr "length_address" "8,0") (set_attr "length_immediate" "0") (set_attr "memory" "load") (set_attr "mode" "SI")])(define_insn "*swapsi" [(set (match_operand:SI 0 "register_operand" "+r") (match_operand:SI 1 "register_operand" "+r")) (set (match_dup 1) (match_dup 0))] "" "xchg{l}\t%1, %0" [(set_attr "type" "imov") (set_attr "pent_pair" "np") (set_attr "athlon_decode" "vector") (set_attr "mode" "SI") (set_attr "modrm" "0") (set_attr "ppro_uops" "few")])(define_expand "movhi" [(set (match_operand:HI 0 "nonimmediate_operand" "") (match_operand:HI 1 "general_operand" ""))] "" "ix86_expand_move (HImode, operands); DONE;")(define_insn "*pushhi2" [(set (match_operand:HI 0 "push_operand" "=<,<") (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))] "!TARGET_64BIT" "@ push{w}\t{|WORD PTR }%1 push{w}\t%1" [(set_attr "type" "push") (set_attr "mode" "HI")]);; For 64BIT abi we always round up to 8 bytes.(define_insn "*pushhi2_rex64" [(set (match_operand:HI 0 "push_operand" "=X") (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] "TARGET_64BIT" "push{q}\t%q1" [(set_attr "type" "push") (set_attr "mode" "QI")])(define_insn "*movhi_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"{ switch (get_attr_type (insn)) { case TYPE_IMOVX: /* movzwl is faster than movw on p2 due to partial word stalls, though not as fast as an aligned movl. */ return "movz{wl|x}\t{%1, %k0|%k0, %1}"; default: if (get_attr_mode (insn) == MODE_SI) return "mov{l}\t{%k1, %k0|%k0, %k1}"; else return "mov{w}\t{%1, %0|%0, %1}"; }} [(set (attr "type") (cond [(and (eq_attr "alternative" "0") (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") (const_int 0)) (eq (symbol_ref "TARGET_HIMODE_MATH") (const_int 0))))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -