📄 i386.md
字号:
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "" "*{ if ((TARGET_486 || REGNO (operands[0]) == 0) && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) { rtx xops[2]; xops[0] = operands[0]; xops[1] = GEN_INT (0xff); 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_insn "zero_extendqisi2" [(set (match_operand:SI 0 "general_operand" "=r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "" "*{ if ((TARGET_486 || REGNO (operands[0]) == 0) && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) { rtx xops[2]; xops[0] = operands[0]; xops[1] = GEN_INT (0xff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; }#ifdef INTEL_SYNTAX return AS2 (movzx,%1,%0);#else return AS2 (movz%B0%L0,%1,%0);#endif}");;- sign extension instructions/*(define_insn "extendsidi2" [(set (match_operand:DI 0 "general_operand" "=a") (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "a")))] "" "clq")*/;; Note that the i386 programmers' manual says that the opcodes;; are named movsx..., but the assembler on Unix does not accept that.;; We use what the Unix assembler expects.(define_insn "extendhisi2" [(set (match_operand:SI 0 "general_operand" "=r") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] "" "*{ if (REGNO (operands[0]) == 0 && REG_P (operands[1]) && REGNO (operands[1]) == 0)#ifdef INTEL_SYNTAX return \"cwde\";#else return \"cwtl\";#endif#ifdef INTEL_SYNTAX return AS2 (movsx,%1,%0);#else return AS2 (movs%W0%L0,%1,%0);#endif}")(define_insn "extendqihi2" [(set (match_operand:HI 0 "general_operand" "=r") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "" "*{ if (REGNO (operands[0]) == 0 && REG_P (operands[1]) && REGNO (operands[1]) == 0) return \"cbtw\";#ifdef INTEL_SYNTAX return AS2 (movsx,%1,%0);#else return AS2 (movs%B0%W0,%1,%0);#endif}")(define_insn "extendqisi2" [(set (match_operand:SI 0 "general_operand" "=r") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "" "*{#ifdef INTEL_SYNTAX return AS2 (movsx,%1,%0);#else return AS2 (movs%B0%L0,%1,%0);#endif}");; Conversions between float and double.(define_insn "extendsfdf2" [(set (match_operand:DF 0 "general_operand" "=fm,f,f,!*r") (float_extend:DF (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))] "TARGET_80387" "*{ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; if (NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); RET; } if (NON_STACK_REG_P (operands[0])) { output_to_reg (operands[0], stack_top_dies); RET; } if (STACK_TOP_P (operands[0])) return AS1 (fld%z1,%y1); if (GET_CODE (operands[0]) == MEM) { if (stack_top_dies) return AS1 (fstp%z0,%y0); else return AS1 (fst%z0,%y0); } abort ();}");; This cannot output into an f-reg because there is no way to be sure;; of truncating in that case. Otherwise this is just like a simple move;; insn.(define_insn "truncdfsf2" [(set (match_operand:SF 0 "general_operand" "=m,!*r") (float_truncate:SF (match_operand:DF 1 "register_operand" "f,f")))] "TARGET_80387" "*{ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; if (NON_STACK_REG_P (operands[0])) { output_to_reg (operands[0], stack_top_dies); RET; } else if (GET_CODE (operands[0]) == MEM) { if (stack_top_dies) return AS1 (fstp%z0,%0); else return AS1 (fst%z0,%0); } else abort ();}");; The 387 requires that the stack top dies after converting to DImode.;; Represent an unsigned conversion from SImode to MODE_FLOAT by first;; doing a signed conversion to DImode, and then taking just the low;; part.(define_expand "fixuns_truncdfsi2" [(set (match_dup 5) (match_operand:DF 1 "register_operand" "")) (parallel [(set (match_dup 3) (fix:DI (fix:DF (match_dup 5)))) (clobber (match_scratch:HI 2 "")) (clobber (match_dup 5))]) (set (match_operand:SI 0 "general_operand" "") (match_dup 4))] "TARGET_80387" "{ operands[3] = gen_reg_rtx (DImode); operands[4] = gen_lowpart (SImode, operands[3]); operands[5] = gen_reg_rtx (DFmode);}")(define_expand "fixuns_truncsfsi2" [(set (match_dup 5) (match_operand:SF 1 "register_operand" "")) (parallel [(set (match_dup 3) (fix:DI (fix:SF (match_dup 5)))) (clobber (match_scratch:HI 2 "")) (clobber (match_dup 5))]) (set (match_operand:SI 0 "general_operand" "") (match_dup 4))] "TARGET_80387" "{ operands[3] = gen_reg_rtx (DImode); operands[4] = gen_lowpart (SImode, operands[3]); operands[5] = gen_reg_rtx (SFmode);}");; Signed conversion to DImode.(define_expand "fix_truncdfdi2" [(set (match_dup 3) (match_operand:DF 1 "register_operand" "")) (parallel [(set (match_operand:DI 0 "general_operand" "") (fix:DI (fix:DF (match_dup 3)))) (clobber (match_scratch:HI 2 "")) (clobber (match_dup 3))])] "TARGET_80387" "{ operands[1] = copy_to_mode_reg (DFmode, operands[1]); operands[3] = gen_reg_rtx (DFmode);}")(define_expand "fix_truncsfdi2" [(set (match_dup 3) (match_operand:SF 1 "register_operand" "")) (parallel [(set (match_operand:DI 0 "general_operand" "") (fix:DI (fix:SF (match_dup 3)))) (clobber (match_scratch:HI 2 "")) (clobber (match_dup 3))])] "TARGET_80387" "{ operands[1] = copy_to_mode_reg (SFmode, operands[1]); operands[3] = gen_reg_rtx (SFmode);}");; These match a signed conversion of either DFmode or SFmode to DImode.(define_insn "" [(set (match_operand:DI 0 "general_operand" "=m,!*r") (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) (clobber (match_scratch:HI 2 "=&r,&r")) (clobber (match_dup 1))] "TARGET_80387" "* return (char *) output_fix_trunc (insn, operands);")(define_insn "" [(set (match_operand:DI 0 "general_operand" "=m,!*r") (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) (clobber (match_scratch:HI 2 "=&r,&r")) (clobber (match_dup 1))] "TARGET_80387" "* return (char *) output_fix_trunc (insn, operands);");; Signed MODE_FLOAT conversion to SImode.(define_expand "fix_truncdfsi2" [(parallel [(set (match_operand:SI 0 "general_operand" "") (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "")))) (clobber (match_scratch:HI 2 ""))])] "TARGET_80387" "")(define_expand "fix_truncsfsi2" [(parallel [(set (match_operand:SI 0 "general_operand" "") (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "")))) (clobber (match_scratch:HI 2 ""))])] "TARGET_80387" "")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=m,!*r") (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) (clobber (match_scratch:HI 2 "=&r,&r"))] "TARGET_80387" "* return (char *) output_fix_trunc (insn, operands);")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=m,!*r") (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) (clobber (match_scratch:HI 2 "=&r,&r"))] "TARGET_80387" "* return (char *) output_fix_trunc (insn, operands);");; Conversion between fixed point and floating point.;; The actual pattern that matches these is at the end of this file.;; ??? Possibly represent floatunssidf2 here in gcc2.(define_expand "floatsisf2" [(set (match_operand:SF 0 "register_operand" "") (float:SF (match_operand:SI 1 "general_operand" "")))] "TARGET_80387" "")(define_expand "floatdisf2" [(set (match_operand:SF 0 "register_operand" "") (float:SF (match_operand:DI 1 "general_operand" "")))] "TARGET_80387" "")(define_expand "floatsidf2" [(set (match_operand:DF 0 "register_operand" "") (float:DF (match_operand:SI 1 "general_operand" "")))] "TARGET_80387" "")(define_expand "floatdidf2" [(set (match_operand:DF 0 "register_operand" "") (float:DF (match_operand:DI 1 "general_operand" "")))] "TARGET_80387" "");; This will convert from SImode or DImode to MODE_FLOAT.(define_insn "" [(set (match_operand:DF 0 "register_operand" "=f,f") (float:DF (match_operand:DI 1 "general_operand" "m,!*r")))] "TARGET_80387" "*{ if (NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fild%z0,%1)); RET; } else if (GET_CODE (operands[1]) == MEM) return AS1 (fild%z1,%1); else abort ();}")(define_insn "" [(set (match_operand:SF 0 "register_operand" "=f,f") (float:SF (match_operand:DI 1 "general_operand" "m,!*r")))] "TARGET_80387" "*{ if (NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fild%z0,%1)); RET; } else if (GET_CODE (operands[1]) == MEM) return AS1 (fild%z1,%1); else abort ();}")(define_insn "" [(set (match_operand:DF 0 "register_operand" "=f,f") (float:DF (match_operand:SI 1 "general_operand" "m,!*r")))] "TARGET_80387" "*{ if (NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fild%z0,%1)); RET; } else if (GET_CODE (operands[1]) == MEM) return AS1 (fild%z1,%1); else abort ();}")(define_insn "" [(set (match_operand:SF 0 "register_operand" "=f,f") (float:SF (match_operand:SI 1 "general_operand" "m,!*r")))] "TARGET_80387" "*{ if (NON_STACK_REG_P (operands[1])) { output_op_from_reg (operands[1], AS1 (fild%z0,%1)); RET; } else if (GET_CODE (operands[1]) == MEM) return AS1 (fild%z1,%1); else abort ();}");;- add instructions(define_insn "adddi3" [(set (match_operand:DI 0 "general_operand" "=&r,ro") (plus:DI (match_operand:DI 1 "general_operand" "%0,0") (match_operand:DI 2 "general_operand" "o,riF")))] "" "*{ rtx low[3], high[3]; CC_STATUS_INIT; split_di (operands, 3, low, high); output_asm_insn (AS2 (add%L0,%2,%0), low); output_asm_insn (AS2 (adc%L0,%2,%0), high); RET;}");; On a 486, it is faster to do movl/addl than to do a single leal if;; operands[1] and operands[2] are both registers.(define_insn "addsi3" [(set (match_operand:SI 0 "general_operand" "=?r,rm,r") (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0") (match_operand:SI 2 "general_operand" "ri,ri,rm")))] "" "*{ if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) { if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) return AS2 (add%L0,%1,%0); if (! TARGET_486 || ! REG_P (operands[2])) { CC_STATUS_INIT; if (operands[2] == stack_pointer_rtx) { rtx temp; temp = operands[1]; operands[1] = operands[2]; operands[2] = temp; } if (operands[2] != stack_pointer_rtx) { operands[1] = SET_SRC (PATTERN (insn)); return AS2 (lea%L0,%a1,%0); } } output_asm_insn (AS2 (mov%L0,%1,%0), operands); } if (operands[2] == const1_rtx) return AS1 (inc%L0,%0); if (operands[2] == constm1_rtx) return AS1 (dec%L0,%0); return AS2 (add%L0,%2,%0);}");; ??? `lea' here, for three operand add? If leaw is used, only %bx,;; %si and %di can appear in SET_SRC, and output_asm_insn might not be;; able to handle the operand. But leal always works?(define_insn "addhi3" [(set (match_operand:HI 0 "general_operand" "=rm,r") (plus:HI (match_operand:HI 1 "general_operand" "%0,0") (match_operand:HI 2 "general_operand" "ri,rm")))] "" "*{ if (operands[2] == const1_rtx) return AS1 (inc%W0,%0); if (operands[2] == constm1_rtx) return AS1 (dec%W0,%0); return AS2 (add%W0,%2,%0);}")(define_insn "addqi3"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -