📄 pa.md
字号:
[(set_attr "type" "move,move,move,shift,load,store,move,fpalu") (set_attr "length" "4,4,4,4,4,4,4,4")])(define_insn "" [(set (match_operand:QI 3 "register_operand" "=r") (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "int5_operand" "L")))) (set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 1) (match_dup 2)))] "" "ldbs,mb %2(0,%0),%3" [(set_attr "type" "load") (set_attr "length" "4")])(define_insn "" [(set (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0") (match_operand:SI 2 "int5_operand" "L"))) (match_operand:QI 3 "reg_or_0_operand" "rM")) (set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 1) (match_dup 2)))] "" "stbs,mb %r3,%2(0,%0)" [(set_attr "type" "store") (set_attr "length" "4")]);; The definition of this insn does not really explain what it does,;; but it should suffice;; that anything generated as this insn will be recognized as one;; and that it will not successfully combine with anything.(define_expand "movstrsi" [(parallel [(set (mem:BLK (match_operand:BLK 0 "" "")) (mem:BLK (match_operand:BLK 1 "" ""))) (clobber (match_dup 0)) (clobber (match_dup 1)) (clobber (match_dup 4)) (clobber (match_dup 5)) (use (match_operand:SI 2 "arith_operand" "")) (use (match_operand:SI 3 "const_int_operand" ""))])] "" "{ /* If the blocks are not at least word-aligned and rather big (>16 items), or the size is indeterminate, don't inline the copy code. A procedure call is better since it can check the alignment at runtime and make the optimal decisions. */ if (INTVAL (operands[3]) < 4 && (GET_CODE (operands[2]) != CONST_INT || (INTVAL (operands[2]) / INTVAL (operands[3]) > 8))) FAIL; operands[0] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); operands[4] = gen_reg_rtx (SImode); operands[5] = gen_reg_rtx (SImode);}");; The operand constraints are written like this to support both compile-time;; and run-time determined byte count. If the count is run-time determined,;; the register with the byte count is clobbered by the copying code, and;; therefore it is forced to operand 2. If the count is compile-time;; determined, we need two scratch registers for the unrolled code.(define_insn "" [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r")) (mem:BLK (match_operand:SI 1 "register_operand" "+r,r"))) (clobber (match_dup 0)) (clobber (match_dup 1)) (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment "" "* return output_block_move (operands, !which_alternative);" [(set_attr "type" "multi,multi")]);; Floating point move insns;; This pattern forces (set (reg:DF ...) (const_double ...));; to be reloaded by putting the constant into memory when;; reg is a floating point register.;;;; For integer registers we use ldil;ldo to set the appropriate;; value.;;;; This must come before the movdf pattern, and it must be present;; to handle obscure reloading cases.(define_insn "" [(set (match_operand:DF 0 "general_operand" "=?r,f") (match_operand:DF 1 "" "?F,m"))] "GET_CODE (operands[1]) == CONST_DOUBLE && operands[1] != CONST0_RTX (DFmode) && ! TARGET_SOFT_FLOAT" "* return (which_alternative == 0 ? output_move_double (operands) : \" fldds%F1 %1,%0\");" [(set_attr "type" "move,fpload") (set_attr "length" "16,4")])(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, DFmode, 0)) DONE;}");; Reloading an SImode or DImode value requires a scratch register if;; going in to or out of float point registers.(define_expand "reload_indf" [(set (match_operand:DF 0 "register_operand" "=Z") (match_operand:DF 1 "non_hard_reg_operand" "")) (clobber (match_operand:DF 2 "register_operand" "=&r"))] "" "{ if (emit_move_sequence (operands, DFmode, operands[2])) DONE; /* We don't want the clobber emitted, so handle this ourselves. */ emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); DONE;}")(define_expand "reload_outdf" [(set (match_operand:DF 0 "non_hard_reg_operand" "") (match_operand:DF 1 "register_operand" "Z")) (clobber (match_operand:DF 2 "register_operand" "=&r"))] "" "{ if (emit_move_sequence (operands, DFmode, operands[2])) DONE; /* We don't want the clobber emitted, so handle this ourselves. */ emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); DONE;}")(define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,*r,Q,?o,?Q,f,*&r,*&r") (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" "fG,*rG,f,*r,*r,Q,o,Q"))] "(register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)) && ! TARGET_SOFT_FLOAT" "*{ if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) || operands[1] == CONST0_RTX (DFmode)) return output_fp_move_double (operands); return output_move_double (operands);}" [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load") (set_attr "length" "4,8,4,8,16,4,8,16")])(define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=r,?o,?Q,&r,&r") (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" "rG,r,r,o,Q"))] "(register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)) && TARGET_SOFT_FLOAT" "*{ return output_move_double (operands);}" [(set_attr "type" "move,store,store,load,load") (set_attr "length" "8,8,16,8,16")])(define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 8)) (match_operand:SI 2 "register_operand" "r"))))] "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT" "flddx,s %1(0,%2),%0" [(set_attr "type" "fpload") (set_attr "length" "4")]);; This variant of the above insn can occur if the second operand;; is the frame pointer. This is a kludge, but there doesn't;; seem to be a way around it. Only recognize it while reloading.;; Note how operand 3 uses a predicate of "const_int_operand", but ;; has constraints allowing a register. I don't know how this works,;; but it somehow makes sure that out-of-range constants are placed;; in a register which somehow magically is a "const_int_operand".;; (this was stolen from alpha.md, I'm not going to try and change it.;; Ugh. Output is a FP register; so we need to earlyclobber something;; else as a temporary.(define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (mem:DF (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "+&r") (const_int 8)) (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "const_int_operand" "rL"))))] "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress" "*{ if (GET_CODE (operands[3]) == CONST_INT) return \"sh3addl %1,%2,%1\;fldds %3(0,%1),%0\"; else return \"sh3addl %1,%2,%1\;flddx %3(0,%1),%0\";}" [(set_attr "type" "fpload") (set_attr "length" "8")])(define_insn "" [(set (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 8)) (match_operand:SI 2 "register_operand" "r"))) (match_operand:DF 0 "register_operand" "f"))] "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT" "fstdx,s %0,%1(0,%2)" [(set_attr "type" "fpstore") (set_attr "length" "4")]);; This variant of the above insn can occur if the second operand;; is the frame pointer. This is a kludge, but there doesn't;; seem to be a way around it. Only recognize it while reloading.;; Note how operand 3 uses a predicate of "const_int_operand", but ;; has constraints allowing a register. I don't know how this works,;; but it somehow makes sure that out-of-range constants are placed;; in a register which somehow magically is a "const_int_operand".;; (this was stolen from alpha.md, I'm not going to try and change it.;; Ugh. Output is a FP register; so we need to earlyclobber something;; else as a temporary.(define_insn "" [(set (mem:DF (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "+&r") (const_int 8)) (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "const_int_operand" "rL"))) (match_operand:DF 0 "register_operand" "f"))] "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress" "*{ if (GET_CODE (operands[3]) == CONST_INT) return \"sh3addl %1,%2,%1\;fstds %0,%3(0,%1)\"; else return \"sh3addl %1,%2,%1\;fstdx %0,%3(0,%1)\";}" [(set_attr "type" "fpstore") (set_attr "length" "8")])(define_expand "movdi" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") (match_operand:DI 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, DImode, 0)) DONE;}")(define_expand "reload_indi" [(set (match_operand:DI 0 "register_operand" "=f") (match_operand:DI 1 "non_hard_reg_operand" "")) (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" "{ if (emit_move_sequence (operands, DImode, operands[2])) DONE; /* We don't want the clobber emitted, so handle this ourselves. */ emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); DONE;}")(define_expand "reload_outdi" [(set (match_operand:DI 0 "general_operand" "") (match_operand:DI 1 "register_operand" "f")) (clobber (match_operand:SI 2 "register_operand" "=&r"))] "" "{ if (emit_move_sequence (operands, DImode, operands[2])) DONE; /* We don't want the clobber emitted, so handle this ourselves. */ emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1])); DONE;}")(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (high:DI (match_operand 1 "" "")))] "" "*{ rtx op0 = operands[0]; rtx op1 = operands[1]; if (GET_CODE (op1) == CONST_INT) { operands[0] = operand_subword (op0, 1, 0, DImode); output_asm_insn (\"ldil L'%1,%0\", operands); operands[0] = operand_subword (op0, 0, 0, DImode); if (INTVAL (op1) < 0) output_asm_insn (\"ldi -1,%0\", operands); else output_asm_insn (\"ldi 0,%0\", operands); return \"\"; } else if (GET_CODE (op1) == CONST_DOUBLE) { operands[0] = operand_subword (op0, 1, 0, DImode); operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1)); output_asm_insn (\"ldil L'%1,%0\", operands); operands[0] = operand_subword (op0, 0, 0, DImode); operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1)); output_asm_insn (singlemove_string (operands), operands); return \"\"; } else abort ();}" [(set_attr "type" "move") (set_attr "length" "8")]);;; Experimental(define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,o,Q,&r,&r,&r,f,f,*T") (match_operand:DI 1 "general_operand" "rM,r,r,o,Q,i,fM,*T,f"))] "(register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)) && ! TARGET_SOFT_FLOAT" "*{ if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]) || (operands[1] == CONST0_RTX (DImode))) return output_fp_move_double (operands); return output_move_double (operands);}" [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore") (set_attr "length" "8,8,16,8,16,16,4,4,4")])(define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,o,Q,&r,&r,&r") (match_operand:DI 1 "general_operand" "rM,r,r,o,Q,i"))] "(register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)) && TARGET_SOFT_FLOAT" "*{ return output_move_double (operands);}" [(set_attr "type" "move,store,store,load,load,multi") (set_attr "length" "8,8,16,8,16,16")])(define_insn "" [(set (match_operand:DI 0 "register_operand" "=r,&r") (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r") (match_operand:DI 2 "immediate_operand" "i,i")))] "" "*{ /* Don't output a 64 bit constant, since we can't trust the assembler to handle it correctly. */ if (GET_CODE (operands[2]) == CONST_DOUBLE) operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); if (which_alternative == 1) output_asm_insn (\"copy %1,%0\", operands); return \"ldo R'%G2(%R1),%R0\";}" [(set_attr "type" "move,move") (set_attr "length" "4,8")]);; This pattern forces (set (reg:SF ...) (const_double ...));; to be reloaded by putting the constant into memory when;; reg is a floating point register.;;;; For integer registers we use ldil;ldo to set the appropriate;; value.;;;; This must come before the movsf pattern, and it must be present;; to handle obscure reloading cases.(define_insn "" [(set (match_operand:SF 0 "general_operand" "=?r,f") (match_operand:SF 1 "" "?F,m"))] "GET_CODE (operands[1]) == CONST_DOUBLE && operands[1] != CONST0_RTX (SFmode) && ! TARGET_SOFT_FLOAT" "* return (which_alternative == 0 ? singlemove_string (operands) : \" fldws%F1 %1,%0\");" [(set_attr "type" "move,fpload") (set_attr "length" "8,4")])(define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, SFmode, 0)) DONE;}");; Reloading an SImode or DImode value requires a scratch register if;; going in to or out of float point registers.(define_expand "reload_insf" [(set (match_operand:SF 0 "register_operand" "=Z") (match_operand:SF 1 "non_hard_reg_operand" "")) (clobber (match_operand:SF 2 "register_operand" "=&r"))] "" "{ if (emit_move_sequence (operand
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -