📄 i386.md
字号:
(const_string "imov") (and (eq_attr "alternative" "1,2") (match_operand:HI 1 "aligned_operand" "")) (const_string "imov") (and (ne (symbol_ref "TARGET_MOVX") (const_int 0)) (eq_attr "alternative" "0,2")) (const_string "imovx") ] (const_string "imov"))) (set (attr "mode") (cond [(eq_attr "type" "imovx") (const_string "SI") (and (eq_attr "alternative" "1,2") (match_operand:HI 1 "aligned_operand" "")) (const_string "SI") (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)))) (const_string "SI") ] (const_string "HI")))]);; 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 "*movabshi_1_rex64" [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) (match_operand:HI 1 "nonmemory_operand" "a,er"))] "TARGET_64BIT && ix86_check_movabs (insn, 0)" "@ movabs{w}\t{%1, %P0|%P0, %1} mov{w}\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" "HI")])(define_insn "*movabshi_2_rex64" [(set (match_operand:HI 0 "register_operand" "=a,r") (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] "TARGET_64BIT && ix86_check_movabs (insn, 1)" "@ movabs{w}\t{%P1, %0|%0, %P1} mov{w}\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" "HI")])(define_insn "*swaphi_1" [(set (match_operand:HI 0 "register_operand" "+r") (match_operand:HI 1 "register_operand" "+r")) (set (match_dup 1) (match_dup 0))] "TARGET_PARTIAL_REG_STALL" "xchg{w}\t%1, %0" [(set_attr "type" "imov") (set_attr "pent_pair" "np") (set_attr "mode" "HI") (set_attr "modrm" "0") (set_attr "ppro_uops" "few")])(define_insn "*swaphi_2" [(set (match_operand:HI 0 "register_operand" "+r") (match_operand:HI 1 "register_operand" "+r")) (set (match_dup 1) (match_dup 0))] "! TARGET_PARTIAL_REG_STALL" "xchg{l}\t%k1, %k0" [(set_attr "type" "imov") (set_attr "pent_pair" "np") (set_attr "mode" "SI") (set_attr "modrm" "0") (set_attr "ppro_uops" "few")])(define_expand "movstricthi" [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) (match_operand:HI 1 "general_operand" ""))] "! TARGET_PARTIAL_REG_STALL || optimize_size"{ /* Don't generate memory->memory moves, go through a register */ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) operands[1] = force_reg (HImode, operands[1]);})(define_insn "*movstricthi_1" [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) (match_operand:HI 1 "general_operand" "rn,m"))] "(! TARGET_PARTIAL_REG_STALL || optimize_size) && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" "mov{w}\t{%1, %0|%0, %1}" [(set_attr "type" "imov") (set_attr "mode" "HI")])(define_insn "*movstricthi_xor" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) (match_operand:HI 1 "const0_operand" "i")) (clobber (reg:CC 17))] "reload_completed && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" "xor{w}\t{%0, %0|%0, %0}" [(set_attr "type" "alu1") (set_attr "mode" "HI") (set_attr "length_immediate" "0")])(define_expand "movqi" [(set (match_operand:QI 0 "nonimmediate_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "ix86_expand_move (QImode, operands); DONE;");; emit_push_insn when it calls move_by_pieces requires an insn to;; "push a byte". But actually we use pushw, which has the effect;; of rounding the amount pushed up to a halfword.(define_insn "*pushqi2" [(set (match_operand:QI 0 "push_operand" "=X,X") (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))] "!TARGET_64BIT" "@ push{w}\t{|word ptr }%1 push{w}\t%w1" [(set_attr "type" "push") (set_attr "mode" "HI")]);; For 64BIT abi we always round up to 8 bytes.(define_insn "*pushqi2_rex64" [(set (match_operand:QI 0 "push_operand" "=X") (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] "TARGET_64BIT" "push{q}\t%q1" [(set_attr "type" "push") (set_attr "mode" "QI")]);; Situation is quite tricky about when to choose full sized (SImode) move;; over QImode moves. For Q_REG -> Q_REG move we use full size only for;; partial register dependency machines (such as AMD Athlon), where QImode;; moves issue extra dependency and for partial register stalls machines;; that don't use QImode patterns (and QImode move cause stall on the next;; instruction).;;;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial;; register stall machines with, where we use QImode instructions, since;; partial register stall can be caused there. Then we use movzx.(define_insn "*movqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"{ switch (get_attr_type (insn)) { case TYPE_IMOVX: if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM) abort (); return "movz{bl|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{b}\t{%1, %0|%0, %1}"; }} [(set (attr "type") (cond [(and (eq_attr "alternative" "3") (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") (const_int 0)) (eq (symbol_ref "TARGET_QIMODE_MATH") (const_int 0)))) (const_string "imov") (eq_attr "alternative" "3,5") (const_string "imovx") (and (ne (symbol_ref "TARGET_MOVX") (const_int 0)) (eq_attr "alternative" "2")) (const_string "imovx") ] (const_string "imov"))) (set (attr "mode") (cond [(eq_attr "alternative" "3,4,5") (const_string "SI") (eq_attr "alternative" "6") (const_string "QI") (eq_attr "type" "imovx") (const_string "SI") (and (eq_attr "type" "imov") (and (eq_attr "alternative" "0,1,2") (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") (const_int 0)))) (const_string "SI") ;; Avoid partial register stalls when not using QImode arithmetic (and (eq_attr "type" "imov") (and (eq_attr "alternative" "0,1,2") (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") (const_int 0)) (eq (symbol_ref "TARGET_QIMODE_MATH") (const_int 0))))) (const_string "SI") ] (const_string "QI")))])(define_expand "reload_outqi" [(parallel [(match_operand:QI 0 "" "=m") (match_operand:QI 1 "register_operand" "r") (match_operand:QI 2 "register_operand" "=&q")])] ""{ rtx op0, op1, op2; op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; if (reg_overlap_mentioned_p (op2, op0)) abort (); if (! q_regs_operand (op1, QImode)) { emit_insn (gen_movqi (op2, op1)); op1 = op2; } emit_insn (gen_movqi (op0, op1)); DONE;})(define_insn "*swapqi" [(set (match_operand:QI 0 "register_operand" "+r") (match_operand:QI 1 "register_operand" "+r")) (set (match_dup 1) (match_dup 0))] "" "xchg{b}\t%1, %0" [(set_attr "type" "imov") (set_attr "pent_pair" "np") (set_attr "mode" "QI") (set_attr "modrm" "0") (set_attr "ppro_uops" "few")])(define_expand "movstrictqi" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) (match_operand:QI 1 "general_operand" ""))] "! TARGET_PARTIAL_REG_STALL || optimize_size"{ /* Don't generate memory->memory moves, go through a register. */ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) operands[1] = force_reg (QImode, operands[1]);})(define_insn "*movstrictqi_1" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) (match_operand:QI 1 "general_operand" "*qn,m"))] "(! TARGET_PARTIAL_REG_STALL || optimize_size) && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" "mov{b}\t{%1, %0|%0, %1}" [(set_attr "type" "imov") (set_attr "mode" "QI")])(define_insn "*movstrictqi_xor" [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) (match_operand:QI 1 "const0_operand" "i")) (clobber (reg:CC 17))] "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" "xor{b}\t{%0, %0|%0, %0}" [(set_attr "type" "alu1") (set_attr "mode" "QI") (set_attr "length_immediate" "0")])(define_insn "*movsi_extv_1" [(set (match_operand:SI 0 "register_operand" "=R") (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") (const_int 8) (const_int 8)))] "" "movs{bl|x}\t{%h1, %0|%0, %h1}" [(set_attr "type" "imovx") (set_attr "mode" "SI")])(define_insn "*movhi_extv_1" [(set (match_operand:HI 0 "register_operand" "=R") (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") (const_int 8) (const_int 8)))] "" "movs{bl|x}\t{%h1, %k0|%k0, %h1}" [(set_attr "type" "imovx") (set_attr "mode" "SI")])(define_insn "*movqi_extv_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") (const_int 8) (const_int 8)))] "!TARGET_64BIT"{ switch (get_attr_type (insn)) { case TYPE_IMOVX: return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; default: return "mov{b}\t{%h1, %0|%0, %h1}"; }} [(set (attr "type") (if_then_else (and (match_operand:QI 0 "register_operand" "") (ior (not (match_operand:QI 0 "q_regs_operand" "")) (ne (symbol_ref "TARGET_MOVX") (const_int 0)))) (const_string "imovx") (const_string "imov"))) (set (attr "mode") (if_then_else (eq_attr "type" "imovx") (const_string "SI") (const_string "QI")))])(define_insn "*movqi_extv_1_rex64" [(set (match_operand:QI 0 "register_operand" "=Q,?R") (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") (const_int 8) (const_int 8)))] "TARGET_64BIT"{ switch (get_attr_type (insn)) { case TYPE_IMOVX: return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; default: return "mov{b}\t{%h1, %0|%0, %h1}"; }} [(set (attr "type") (if_then_else (and (match_operand:QI 0 "register_operand" "") (ior (not (match_operand:QI 0 "q_regs_operand" "")) (ne (symbol_ref "TARGET_MOVX") (const_int 0)))) (const_string "imovx") (const_string "imov"))) (set (attr "mode") (if_then_else (eq_attr "type" "imovx") (const_string "SI") (const_string "QI")))]);; 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 "*movabsqi_1_rex64" [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) (match_operand:QI 1 "nonmemory_operand" "a,er"))] "TARGET_64BIT && ix86_check_movabs (insn, 0)" "@ movabs{b}\t{%1, %P0|%P0, %1} mov{b}\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" "QI")])(define_insn "*movabsqi_2_rex64" [(set (match_operand:QI 0 "register_operand" "=a,r") (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] "TARGET_64BIT && ix86_check_movabs (insn, 1)" "@ movabs{b}\t{%P1, %0|%0, %P1} mov{b}\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" "QI")])(define_insn "*movsi_extzv_1" [(set (match_operand:SI 0 "register_operand" "=R") (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") (const_int 8) (const_int 8)))] "" "movz{bl|x}\t{%h1, %0|%0, %h1}" [(set_attr "type" "imovx") (set_attr "mode" "SI")])(define_insn "*movqi_extzv_2" [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") (const_int 8) (const_int 8)) 0))] "!TARGET_64BIT"{ switch (get_attr_type (insn)) { case TYPE_IMOVX: return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; default: return "mov{b}\t{%h1, %0|%0, %h1}"; }} [(set (attr "type") (if_then_else (and (match_operand:QI 0 "register_operand" "") (ior (not (match_operand:QI 0 "q_regs_operand" "")) (ne (symbol_ref "TARGET_MOVX") (const_int 0)))) (const_string "imovx") (const_string "imov"))) (set (attr "mode") (if_then_else (eq_attr "type" "imovx") (const_string "SI") (const_string "QI")))])(define_insn "*movqi_extzv_2_rex64"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -