📄 i386.md
字号:
&& !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, QImode, REGNO (operands[0]));")(define_split [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))] "reload_completed && QI_REG_P (operands[0]) && 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:HI (match_dup 0) (const_int 255)))] "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));")(define_split [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] "reload_completed && TARGET_ZERO_EXTEND_WITH_AND" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))] "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0) operands[1] = SUBREG_REG (operands[1]); if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG || REGNO (operands[0]) == REGNO (operands[1])) FAIL; operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));")(define_insn "zero_extendqisi2" [(set (match_operand:SI 0 "register_operand" "=q,&q,?r") (zero_extend:SI (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,%0,%0),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; } if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG) { xops[0] = operands[0]; xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); operands[1] = gen_rtx (REG, SImode, REGNO (operands[1])); output_asm_insn (AS2 (mov%L0,%1,%0), operands); 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}")(define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] "reload_completed && QI_REG_P (operands[0]) && 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, QImode, REGNO (operands[0]));")(define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))] "reload_completed && QI_REG_P (operands[0]) && 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 255)))] "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));")(define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && ! reg_overlap_mentioned_p (operands[0], operands[1])" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))] "operands[2] = gen_rtx (REG, SImode, true_regnum (operands[1]));")(define_insn "zero_extendsidi2" [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m") (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))] "" "* { rtx high[2], low[2], xops[4]; if (REG_P (operands[0]) && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) { operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); return AS2 (xor%L0,%0,%0); } split_di (operands, 1, low, high); xops[0] = low[0]; xops[1] = operands[1]; xops[2] = high[0]; xops[3] = const0_rtx; output_asm_insn (AS2 (mov%L0,%1,%0), xops); if (GET_CODE (low[0]) == MEM) output_asm_insn (AS2 (mov%L2,%3,%2), xops); else output_asm_insn (AS2 (xor%L2,%2,%2), xops); RET;}");;- sign extension instructions(define_insn "extendsidi2" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))] "" "*{ if (REGNO (operands[0]) == 0) { /* This used to be cwtl, but that extends HI to SI somehow. */#ifdef INTEL_SYNTAX return \"cdq\";#else return \"cltd\";#endif } operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); output_asm_insn (AS2 (mov%L0,%0,%1), operands); operands[0] = GEN_INT (31); return AS2 (sar%L1,%0,%1);}");; 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 "register_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 "register_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 "register_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}");; Truncation of long long -> 32 bit(define_expand "truncdisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] "" "{ /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE && (reload_in_progress | reload_completed) == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { rtx target = gen_reg_rtx (SImode); emit_insn (gen_truncdisi2 (target, operands[1])); emit_move_insn (operands[0], target); DONE; }}")(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "*{ rtx low[2], high[2], xops[2]; split_di (&operands[1], 1, low, high); xops[0] = operands[0]; xops[1] = low[0]; if (!rtx_equal_p (xops[0], xops[1])) output_asm_insn (AS2 (mov%L0,%1,%0), xops); RET;}")(define_insn "" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") (const_int 32))))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "*{ rtx low[2], high[2], xops[2]; split_di (&operands[1], 1, low, high); xops[0] = operands[0]; xops[1] = high[0]; if (!rtx_equal_p (xops[0], xops[1])) output_asm_insn (AS2 (mov%L0,%1,%0), xops); RET;}");; Conversions between float and double.(define_insn "extendsfdf2" [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f") (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,fm")))] "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, 0); 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 ();}")(define_insn "extenddfxf2" [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") (float_extend:XF (match_operand:DF 1 "nonimmediate_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, 0); RET; } if (STACK_TOP_P (operands[0])) return AS1 (fld%z1,%y1); if (GET_CODE (operands[0]) == MEM) { output_asm_insn (AS1 (fstp%z0,%y0), operands); if (! stack_top_dies) return AS1 (fld%z0,%y0); RET; } abort ();}")(define_insn "extendsfxf2" [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") (float_extend:XF (match_operand:SF 1 "nonimmediate_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, 0); RET; } if (STACK_TOP_P (operands[0])) return AS1 (fld%z1,%y1); if (GET_CODE (operands[0]) == MEM) { output_asm_insn (AS1 (fstp%z0,%y0), operands); if (! stack_top_dies) return AS1 (fld%z0,%y0); RET; } abort ();}")(define_expand "truncdfsf2" [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) (clobber (match_dup 2))])] "TARGET_80387" "{ operands[2] = (rtx) assign_386_stack_local (SFmode, 0);}");; 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. So we pretend we can output to a reg in order to get better;; register preferencing, but we really use a stack slot.(define_insn "" [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m") (float_truncate:SF (match_operand:DF 1 "register_operand" "0,f"))) (clobber (match_operand:SF 2 "memory_operand" "m,m"))] "TARGET_80387" "*{ int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; if (GET_CODE (operands[0]) == MEM) { if (stack_top_dies) return AS1 (fstp%z0,%0); else return AS1 (fst%z0,%0); } else if (STACK_TOP_P (operands[0])) { output_asm_insn (AS1 (fstp%z2,%y2), operands); return AS1 (fld%z2,%y2); } else abort ();}")(define_insn "truncxfsf2" [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r") (float_truncate:SF (match_operand:XF 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])) { if (stack_top_dies == 0) { output_asm_insn (AS1 (fld,%y1), operands); stack_top_dies = 1; } output_to_reg (operands[0], stack_top_dies, 0); RET; } else if (GET_CODE (operands[0]) == MEM) { if (stack_top_dies) return AS1 (fstp%z0,%0); else { output_asm_insn (AS1 (fld,%y1), operands); return AS1 (fstp%z0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -