📄 i386.md
字号:
[(set (match_operand:DF 0 "push_operand" "=<,<") (match_operand:DF 1 "general_operand" "gF,f"))] "!TARGET_MOVE" "*{ if (STACK_REG_P (operands[1])) { rtx xops[3]; xops[0] = AT_SP (SFmode); xops[1] = GEN_INT (8); xops[2] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L2,%1,%2), xops); if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) output_asm_insn (AS1 (fstp%Q0,%0), xops); else output_asm_insn (AS1 (fst%Q0,%0), xops); RET; } else return output_move_double (operands);}")(define_insn "movdf_push" [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<") (match_operand:DF 1 "general_operand" "rF,f,o,o,o")) (clobber (match_scratch:SI 2 "=X,X,&r,&r,X")) (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))] "" "*{ if (STACK_REG_P (operands[1])) { rtx xops[3]; xops[0] = AT_SP (SFmode); xops[1] = GEN_INT (8); xops[2] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L2,%1,%2), xops); if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) output_asm_insn (AS1 (fstp%Q0,%0), xops); else output_asm_insn (AS1 (fst%Q0,%0), xops); RET; } else if (GET_CODE (operands[1]) != MEM) return output_move_double (operands); else return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);}")(define_insn "movdf_mem" [(set (match_operand:DF 0 "memory_operand" "=o,o") (match_operand:DF 1 "memory_operand" "o,o")) (clobber (match_scratch:SI 2 "=&r,&r")) (clobber (match_scratch:SI 3 "=&r,X"))] "" "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);");; For the purposes of regclass, prefer FLOAT_REGS.(define_insn "" [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "*{ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; /* First handle a `pop' insn or a `fld %st(0)' */ if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) { if (stack_top_dies) return AS1 (fstp,%y0); else return AS1 (fld,%y0); } /* Handle a transfer between the 387 and a 386 register */ if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); RET; } if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) { output_to_reg (operands[0], stack_top_dies, 0); RET; } /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) { if (stack_top_dies) return AS1 (fstp%z0,%y0); else return AS1 (fst%z0,%y0); } /* Handle other kinds of reads to the 387 */ if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) return output_move_const_single (operands); if (STACK_TOP_P (operands[0])) return AS1 (fld%z1,%y1); /* Handle all DFmode moves not involving the 387 */ return output_move_double (operands);}" [(set_attr "type" "fld")])(define_insn "swapdf" [(set (match_operand:DF 0 "register_operand" "f") (match_operand:DF 1 "register_operand" "f")) (set (match_dup 1) (match_dup 0))] "" "*{ if (STACK_TOP_P (operands[0])) return AS1 (fxch,%1); else return AS1 (fxch,%0);}")(define_expand "movxf" [(set (match_operand:XF 0 "general_operand" "") (match_operand:XF 1 "general_operand" ""))] "" "{ /* Special case memory->memory moves and pushes */ if (TARGET_MOVE && (reload_in_progress | reload_completed) == 0 && GET_CODE (operands[0]) == MEM && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode))) { rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode)) ? gen_movxf_push : gen_movxf_mem; emit_insn ((*genfunc) (operands[0], operands[1])); DONE; } /* If we are loading a floating point constant that isn't 0 or 1 into a register, indicate we need the pic register loaded. This could be optimized into stores of constants if the target eventually moves to memory, but better safe than sorry. */ if ((reload_in_progress | reload_completed) == 0 && GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) == CONST_DOUBLE && !standard_80387_constant_p (operands[1])) { rtx insn, note, fp_const; fp_const = force_const_mem (XFmode, operands[1]); if (flag_pic) current_function_uses_pic_offset_table = 1; insn = emit_insn (gen_rtx (SET, XFmode, operands[0], fp_const)); note = find_reg_note (insn, REG_EQUAL, NULL_RTX); if (note) XEXP (note, 0) = operands[1]; else REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands[1], REG_NOTES (insn)); }}")(define_insn "movxf_push_nomove" [(set (match_operand:XF 0 "push_operand" "=<,<") (match_operand:XF 1 "general_operand" "gF,f"))] "!TARGET_MOVE" "*{ if (STACK_REG_P (operands[1])) { rtx xops[3]; xops[0] = AT_SP (SFmode); xops[1] = GEN_INT (12); xops[2] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L2,%1,%2), xops); output_asm_insn (AS1 (fstp%T0,%0), xops); if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) output_asm_insn (AS1 (fld%T0,%0), xops); RET; } else return output_move_double (operands); }")(define_insn "movxf_push" [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<") (match_operand:XF 1 "general_operand" "rF,f,o,o,o")) (clobber (match_scratch:SI 2 "=X,X,&r,&r,X")) (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))] "" "*{ if (STACK_REG_P (operands[1])) { rtx xops[3]; xops[0] = AT_SP (SFmode); xops[1] = GEN_INT (12); xops[2] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L2,%1,%2), xops); output_asm_insn (AS1 (fstp%T0,%0), xops); if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) output_asm_insn (AS1 (fld%T0,%0), xops); RET; } else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG) return output_move_double (operands); else return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);}")(define_insn "movxf_mem" [(set (match_operand:XF 0 "memory_operand" "=o,o") (match_operand:XF 1 "memory_operand" "o,o")) (clobber (match_scratch:SI 2 "=&r,&r")) (clobber (match_scratch:SI 3 "=&r,X"))] "" "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")(define_insn "" [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "*{ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; /* First handle a `pop' insn or a `fld %st(0)' */ if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) { if (stack_top_dies) return AS1 (fstp,%y0); else return AS1 (fld,%y0); } /* Handle a transfer between the 387 and a 386 register */ if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); RET; } if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) { output_to_reg (operands[0], stack_top_dies, 0); RET; } /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) { output_asm_insn (AS1 (fstp%z0,%y0), operands); if (! stack_top_dies) return AS1 (fld%z0,%y0); RET; } /* Handle other kinds of reads to the 387 */ if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) return output_move_const_single (operands); if (STACK_TOP_P (operands[0])) return AS1 (fld%z1,%y1); /* Handle all XFmode moves not involving the 387 */ return output_move_double (operands);}")(define_insn "swapxf" [(set (match_operand:XF 0 "register_operand" "f") (match_operand:XF 1 "register_operand" "f")) (set (match_dup 1) (match_dup 0))] "" "*{ if (STACK_TOP_P (operands[0])) return AS1 (fxch,%1); else return AS1 (fxch,%0);}")(define_insn "" [(set (match_operand:DI 0 "push_operand" "=<,<,<,<") (match_operand:DI 1 "general_operand" "riF,o,o,o")) (clobber (match_scratch:SI 2 "=X,&r,&r,X")) (clobber (match_scratch:SI 3 "=X,&r,X,X"))] "" "*{ if (GET_CODE (operands[1]) != MEM) return output_move_double (operands); else return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);}")(define_insn "movdi" [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm") (match_operand:DI 1 "general_operand" "o,o,m,riF")) (clobber (match_scratch:SI 2 "=&r,&r,X,X")) (clobber (match_scratch:SI 3 "=&r,X,X,X"))] "" "*{ rtx low[2], high[2], xop[6]; if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) return output_move_double (operands); else return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);}");;- conversion instructions;;- NONE;;- zero extension instructions;; See comments by `andsi' for when andl is faster than movzx.(define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r,&r,?r") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))] "" "* { rtx xops[2]; if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) { xops[0] = operands[0]; xops[1] = GEN_INT (0xffff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])) { output_asm_insn (AS2 (xor%L0,%0,%0),operands); output_asm_insn (AS2 (mov%W0,%1,%w0),operands); RET; } if (TARGET_ZERO_EXTEND_WITH_AND) { xops[0] = operands[0]; xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff); if (i386_aligned_p (operands[1])) output_asm_insn (AS2 (mov%L0,%k1,%k0),operands); else output_asm_insn (AS2 (mov%W0,%1,%w0),operands); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; }#ifdef INTEL_SYNTAX return AS2 (movzx,%1,%0);#else return AS2 (movz%W0%L0,%1,%0);#endif}")(define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])" [(set (match_dup 0) (const_int 0)) (set (strict_low_part (match_dup 2)) (match_dup 1))] "operands[2] = gen_rtx (REG, HImode, true_regnum (operands[0]));")(define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))] "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])" [(set (strict_low_part (match_dup 2)) (match_dup 1)) (set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))] "operands[2] = gen_rtx (REG, HImode, true_regnum (operands[0]));")(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "=q,&q,?r") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] "" "* { rtx xops[2]; if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) { xops[0] = operands[0]; xops[1] = GEN_INT (0xff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) { if(!reg_overlap_mentioned_p(operands[0],operands[1])) { output_asm_insn (AS2 (xor%L0,%k0,%k0), operands); output_asm_insn (AS2 (mov%B0,%1,%b0), operands); } else { xops[0] = operands[0]; xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); output_asm_insn (AS2 (mov%B0,%1,%b0),operands); output_asm_insn (AS2 (and%L0,%1,%k0), xops); } RET; } #ifdef INTEL_SYNTAX return AS2 (movzx,%1,%0);#else return AS2 (movz%B0%W0,%1,%0);#endif}")(define_split [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -