📄 pa.md
字号:
xoperands[0] = operands[0]; compute_xdepi_operands_from_integer (INTVAL (operands[1]), xoperands); output_asm_insn (\"zdepi %1,%2,%3,%0\", xoperands); return \"\";}" [(set_attr "type" "move") (set_attr "length" "1")])(define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") (lo_sum:HI (match_operand:HI 1 "register_operand" "r") (match_operand 2 "immediate_operand" "i")))] "" "ldo R'%G2(%1),%0" [(set_attr "length" "1")])(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, QImode, 0)) DONE;}")(define_insn "" [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!r,!*fx,!*fx") (match_operand:QI 1 "move_operand" "rM,Q,rM,*fx,r,*fx"))] "" "@ copy %r1,%0 ldb%M1 %1,%0 stb%M0 %r1,%0 fstws %1,-16(30)\;ldw -16(30),%0 stw %1,-16(30)\;fldws -16(30),%0 fcpy,sgl %1,%0" [(set_attr "type" "move,load,store,move,move,fpalu") (set_attr "length" "1,1,1,2,2,1")])(define_insn "" [(set (match_operand:QI 0 "register_operand" "=r") (match_operand:QI 1 "immediate_operand" "J"))] "" "ldo %1(0),%0" [(set_attr "type" "move") (set_attr "length" "1")])(define_insn "" [(set (match_operand:QI 0 "register_operand" "=r") (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") (match_operand 2 "immediate_operand" "i")) 0))] "" "ldo R'%G2(%1),%0" [(set_attr "length" "1")]);; Sneaky ways of using index modes;; We don't use unscaled modes since they can't be used unless we can tell;; which of the registers is the base and which is the index, due to PA's;; idea of segment selection using the top bits of the base register.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r") (const_int 4)) (match_operand:SI 2 "register_operand" "r"))))] "" "ldwx,s %1(0,%2),%0" [(set_attr "type" "move") (set_attr "length" "1")]); this will never match;(define_insn ""; [(set (match_operand:SI 0 "register_operand" "=r"); (mem:SI (match_operand:SI 1 "register_operand" "+r"))); (set (match_dup 1); (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r"); (const_int 4)); (match_dup 1)))]; ""; "ldwx,sm %2(0,%1),%0"; [(set_attr "type" "move"); (set_attr "length" "1")])(define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") (mem:HI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r") (const_int 2)) (match_operand:SI 1 "register_operand" "r"))))] "" "ldhx,s %2(0,%1),%0" [(set_attr "type" "move") (set_attr "length" "1")]); this will never match;(define_insn ""; [(set (match_operand:HI 0 "register_operand" "=r"); (mem:HI (match_operand:SI 1 "register_operand" "+r"))); (set (match_dup 1); (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r"); (const_int 2)); (match_dup 1)))]; ""; "ldhx,sm %2(0,%1),%0"; [(set_attr "type" "move"); (set_attr "length" "1")]);; 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 "general_operand" "")) (mem:BLK (match_operand:BLK 1 "general_operand" ""))) (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]) > 16))) 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.;; It must come before the more general movdf pattern.(define_insn "" [(set (match_operand:DF 0 "general_operand" "=?r,r,fx") (match_operand:DF 1 "" "?E,G,m"))] "GET_CODE (operands[1]) == CONST_DOUBLE" "*{ switch (which_alternative) { case 0: return output_move_double (operands); case 1: return \"copy 0,%0\;copy 0,%R0\"; case 2: return output_fp_move_double (operands); }}" [(set_attr "type" "load,move,fpload") (set_attr "length" "3,2,3")])(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, DFmode, 0)) DONE;}")(define_insn "" [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=fx,*r,Q,?Q,fx,*&r,?fx,?r") (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "fx,*r,fx,*r,Q,Q,*r,fx"))] "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" "*{ if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return output_fp_move_double (operands); return output_move_double (operands);}" [(set_attr "type" "fpalu,move,fpstore,store,fpload,load,multi,multi") (set_attr "length" "1,2,1,2,1,2,3,3")])(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" "=z") (match_operand:DI 1 "general_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" "z")) (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 "" "")))] "check_pic (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 (\"ldo -1(0),%0\", operands); else output_asm_insn (\"ldo 0(0),%0\", operands); return \"\"; } else if (GET_CODE (op1) == CONST_DOUBLE) { operands[0] = operand_subword (op0, 1, 0, DImode); operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (op1)); output_asm_insn (\"ldil L'%1,%0\", operands); operands[0] = operand_subword (op0, 0, 0, DImode); operands[1] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (op1)); output_asm_insn (singlemove_string (operands), operands); return \"\"; } else abort ();}" [(set_attr "type" "move") (set_attr "length" "2")]);;; Experimental(define_insn "" [(set (match_operand:DI 0 "fp_reg_operand" "=fx") (match_operand:DI 1 "short_memory_operand" "T"))] "" "fldds%F1 %1,%0" [(set_attr "type" "fpload") (set_attr "length" "1")])(define_insn "" [(set (match_operand:DI 0 "short_memory_operand" "=T") (match_operand:DI 1 "fp_reg_operand" "fx"))] "" "fstds%F0 %1,%0" [(set_attr "type" "fpstore") (set_attr "length" "1")])(define_insn "" [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r,&r,fx,fx,r") (match_operand:DI 1 "general_operand" "r,r,Q,i,r,fx,fx"))] "" "*{ if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return output_fp_move_double (operands); return output_move_double (operands);}" [(set_attr "type" "move,store,load,misc,multi,fpalu,multi") (set_attr "length" "2,3,3,3,3,2,3")])(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_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[2])); if (which_alternative == 1) output_asm_insn (\"copy %1,%0\", operands); return \"ldo R'%G2(%R1),%R0\";}" ;; Need to set length for this arith insn because operand2 ;; is not an "arith_operand". [(set_attr "length" "1,2")])(define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "general_operand" ""))] "" "{ if (emit_move_sequence (operands, SFmode, 0)) DONE;}")(define_insn "" [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=fx,r,r,fx,fx,r,Q,Q") (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "fx,r,!fx,!r,Q,Q,fx,r"))] "" "@ fcpy,sgl %1,%0 copy %1,%0 fstws %1,-16(0,30)\;ldw -16(0,30),%0 stw %r1,-16(0,30)\;fldws -16(0,30),%0 fldws%F1 %1,%0 ldw%M1 %1,%0 fstws%F0 %r1,%0 stw%M0 %r1,%0" [(set_attr "type" "fpalu,move,multi,multi,fpload,load,fpstore,store") (set_attr "length" "1,1,2,2,1,1,1,1")]);;- zero extension instructions;; Note that the one starting from HImode comes before those for QImode;; so that a constant operand will match HImode, not QImode.(define_expand "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:HI 1 "general_operand" "")))] "" "{ if (GET_CODE (operand1) == MEM && symbolic_operand (XEXP (operand1, 0), Pmode)) { rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, XEXP (operand1, 0))); operands[1] = gen_rtx (MEM, HImode, gen_rtx (LO_SUM, Pmode, temp, XEXP (operand1, 0))); }}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") (zero_extend:SI (match_operand:HI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] "" "@ extru %1,31,16,%0 ldh%M1 %1,%0" [(set_attr "type" "unary,load")])(define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "general_operand" "")))] "" "{ if (GET_CODE (operand1) == MEM && symbolic_operand (XEXP (operand1, 0), Pmode)) { rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, XEXP (operand1, 0))); operands[1] = gen_rtx (MEM, QImode, gen_rtx (LO_SUM, Pmode, temp, XEXP (operand1, 0))); }}")(define_insn "" [(set (match_operand:HI 0 "register_operand" "=r,r") (zero_extend:HI (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] "" "@ extru %1,31,8,%0 ldb%M1 %1,%0" [(set_attr "type" "unary,load") (set_attr "length" "1,1")])(define_expand "zero_extendqisi2" [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "general_operand" "")))] "" "{ if (GET_CODE (operand1) == MEM && symbolic_operand (XEXP (operand1, 0), Pmode)) { rtx temp = copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, XEXP (operand1, 0))); operand1 = gen_rtx (MEM, QImode, gen_rtx (LO_SUM, Pmode, temp, XEXP (operand1, 0))); emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (ZERO_EXTEND, SImode, operand1))); DONE; }}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") (zero_extend:SI (match_operand:QI 1 "reg_or_nonsymb_mem_operand" "r,Q")))] "" "@ extru %1,31,8,%0 ldb%M1 %1,%0" [(set_attr "type" "unary,load") (set_attr "length" "1,1")]);;- sign extension instructions;; Note that the one starting from HImode comes before those for QImode;; so that a constant operand will match HImode, not QImode.(define_insn "extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -