📄 i960.md
字号:
"" "clrbit %1,%2,%0");; The above pattern canonicalizes to this when both the input and output;; are the same pseudo-register.(define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") (const_int 1) (match_operand:SI 1 "register_operand" "d")) (const_int 0))] "" "clrbit %1,%0,%0")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") (xor:SI (ashift:SI (const_int 1) (match_operand:SI 1 "register_operand" "d")) (match_operand:SI 2 "arith_operand" "dI")))] "" "notbit %1,%2,%0")(define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=d") (neg:SI (match_operand:SI 1 "arith_operand" "dI")))] "" "subo %1,0,%0" [(set_attr "length" "1")])(define_insn "one_cmplsi2" [(set (match_operand:SI 0 "register_operand" "=d") (not:SI (match_operand:SI 1 "arith_operand" "dI")))] "" "not %1,%0" [(set_attr "length" "1")]);; Floating point arithmetic instructions.(define_insn "adddf3" [(set (match_operand:DF 0 "register_operand" "=d*f") (plus:DF (match_operand:DF 1 "fp_arith_operand" "%rGH") (match_operand:DF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "addrl %1,%2,%0" [(set_attr "type" "fpadd")])(define_insn "addsf3" [(set (match_operand:SF 0 "register_operand" "=d*f") (plus:SF (match_operand:SF 1 "fp_arith_operand" "%rGH") (match_operand:SF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "addr %1,%2,%0" [(set_attr "type" "fpadd")])(define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=d*f") (minus:DF (match_operand:DF 1 "fp_arith_operand" "rGH") (match_operand:DF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "subrl %2,%1,%0" [(set_attr "type" "fpadd")])(define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=d*f") (minus:SF (match_operand:SF 1 "fp_arith_operand" "rGH") (match_operand:SF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "subr %2,%1,%0" [(set_attr "type" "fpadd")])(define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=d*f") (mult:DF (match_operand:DF 1 "fp_arith_operand" "%rGH") (match_operand:DF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "mulrl %1,%2,%0" [(set_attr "type" "fpmul")])(define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=d*f") (mult:SF (match_operand:SF 1 "fp_arith_operand" "%rGH") (match_operand:SF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "mulr %1,%2,%0" [(set_attr "type" "fpmul")])(define_insn "divdf3" [(set (match_operand:DF 0 "register_operand" "=d*f") (div:DF (match_operand:DF 1 "fp_arith_operand" "rGH") (match_operand:DF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "divrl %2,%1,%0" [(set_attr "type" "fpdiv")])(define_insn "divsf3" [(set (match_operand:SF 0 "register_operand" "=d*f") (div:SF (match_operand:SF 1 "fp_arith_operand" "rGH") (match_operand:SF 2 "fp_arith_operand" "rGH")))] "TARGET_NUMERICS" "divr %2,%1,%0" [(set_attr "type" "fpdiv")])(define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=d,d*f") (neg:DF (match_operand:DF 1 "register_operand" "d,r")))] "" "*{ if (which_alternative == 0) { if (REGNO (operands[0]) == REGNO (operands[1])) return \"notbit 31,%D1,%D0\"; return \"mov %1,%0\;notbit 31,%D1,%D0\"; } return \"subrl %1,0f0.0,%0\";}" [(set_attr "type" "fpadd")])(define_insn "negsf2" [(set (match_operand:SF 0 "register_operand" "=d,d*f") (neg:SF (match_operand:SF 1 "register_operand" "d,r")))] "" "@ notbit 31,%1,%0 subr %1,0f0.0,%0" [(set_attr "type" "fpadd")]);;; The abs patterns also work even if the target machine doesn't have;;; floating point, because in that case dstreg and srcreg will always be;;; less than 32.(define_insn "absdf2" [(set (match_operand:DF 0 "register_operand" "=d*f") (abs:DF (match_operand:DF 1 "register_operand" "df")))] "" "*{ int dstreg = REGNO (operands[0]); int srcreg = REGNO (operands[1]); if (dstreg < 32) { if (srcreg < 32) { if (dstreg != srcreg) output_asm_insn (\"mov %1,%0\", operands); return \"clrbit 31,%D1,%D0\"; } /* Src is an fp reg. */ return \"movrl %1,%0\;clrbit 31,%D1,%D0\"; } if (srcreg >= 32) return \"cpysre %1,0f0.0,%0\"; return \"movrl %1,%0\;cpysre %0,0f0.0,%0\";}" [(set_attr "type" "multi")])(define_insn "abssf2" [(set (match_operand:SF 0 "register_operand" "=d*f") (abs:SF (match_operand:SF 1 "register_operand" "df")))] "" "*{ int dstreg = REGNO (operands[0]); int srcreg = REGNO (operands[1]); if (dstreg < 32 && srcreg < 32) return \"clrbit 31,%1,%0\"; if (dstreg >= 32 && srcreg >= 32) return \"cpysre %1,0f0.0,%0\"; if (dstreg < 32) return \"movr %1,%0\;clrbit 31,%0,%0\"; return \"movr %1,%0\;cpysre %0,0f0.0,%0\";}" [(set_attr "type" "multi")]);; Tetra (16 byte) float support.(define_expand "cmptf" [(set (reg:CC 36) (compare:CC (match_operand:TF 0 "register_operand" "") (match_operand:TF 1 "nonmemory_operand" "")))] "TARGET_NUMERICS" "{ i960_compare_op0 = operands[0]; i960_compare_op1 = operands[1]; DONE;}")(define_insn "" [(set (reg:CC 36) (compare:CC (match_operand:TF 0 "register_operand" "f") (match_operand:TF 1 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "cmpr %0,%1" [(set_attr "type" "fpcc")])(define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") (match_operand:TF 1 "fpmove_src_operand" ""))] "" "{ if (emit_move_sequence (operands, TFmode)) DONE;}")(define_insn "" [(set (match_operand:TF 0 "general_operand" "=r,f,d,d,m") (match_operand:TF 1 "fpmove_src_operand" "r,GH,F,m,d"))] "register_operand (operands[0], TFmode) || register_operand (operands[1], TFmode)" "*{ switch (which_alternative) { case 0: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return \"movre %1,%0\"; else return \"movq %1,%0\"; case 1: return \"movre %1,%0\"; case 2: return i960_output_ldconst (operands[0], operands[1]); case 3: return \"ldt %1,%0\"; case 4: return \"stt %1,%0\"; default: abort(); }}" [(set_attr "type" "move,move,load,fpload,fpstore")])(define_insn "extendsftf2" [(set (match_operand:TF 0 "register_operand" "=f,d") (float_extend:TF (match_operand:SF 1 "register_operand" "d,f")))] "TARGET_NUMERICS" "@ movr %1,%0 movre %1,%0" [(set_attr "type" "fpmove")])(define_insn "extenddftf2" [(set (match_operand:TF 0 "register_operand" "=f,d") (float_extend:TF (match_operand:DF 1 "register_operand" "d,f")))] "TARGET_NUMERICS" "@ movrl %1,%0 movre %1,%0" [(set_attr "type" "fpmove")])(define_insn "trunctfdf2" [(set (match_operand:DF 0 "register_operand" "=d") (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))] "TARGET_NUMERICS" "movrl %1,%0" [(set_attr "type" "fpmove")])(define_insn "trunctfsf2" [(set (match_operand:SF 0 "register_operand" "=d") (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))] "TARGET_NUMERICS" "movr %1,%0" [(set_attr "type" "fpmove")])(define_insn "floatsitf2" [(set (match_operand:TF 0 "register_operand" "=f") (float:TF (match_operand:SI 1 "register_operand" "d")))] "TARGET_NUMERICS" "cvtir %1,%0" [(set_attr "type" "fpcvt")])(define_insn "fix_trunctfsi2" [(set (match_operand:SI 0 "register_operand" "=d") (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] "TARGET_NUMERICS" "cvtzri %1,%0" [(set_attr "type" "fpcvt")])(define_insn "fixuns_trunctfsi2" [(set (match_operand:SI 0 "register_operand" "=d") (unsigned_fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))] "TARGET_NUMERICS" "cvtzri %1,%0" [(set_attr "type" "fpcvt")])(define_insn "addtf3" [(set (match_operand:TF 0 "register_operand" "=f") (plus:TF (match_operand:TF 1 "nonmemory_operand" "%fGH") (match_operand:TF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "addr %1,%2,%0" [(set_attr "type" "fpadd")])(define_insn "subtf3" [(set (match_operand:TF 0 "register_operand" "=f") (minus:TF (match_operand:TF 1 "nonmemory_operand" "fGH") (match_operand:TF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "subr %2,%1,%0" [(set_attr "type" "fpadd")])(define_insn "multf3" [(set (match_operand:TF 0 "register_operand" "=f") (mult:TF (match_operand:TF 1 "nonmemory_operand" "%fGH") (match_operand:TF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "mulr %1,%2,%0" [(set_attr "type" "fpmul")])(define_insn "divtf3" [(set (match_operand:TF 0 "register_operand" "=f") (div:TF (match_operand:TF 1 "nonmemory_operand" "fGH") (match_operand:TF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "divr %2,%1,%0" [(set_attr "type" "fpdiv")])(define_insn "negtf2" [(set (match_operand:TF 0 "register_operand" "=f") (neg:TF (match_operand:TF 1 "register_operand" "f")))] "TARGET_NUMERICS" "subr %1,0f0.0,%0" [(set_attr "type" "fpadd")])(define_insn "abstf2" [(set (match_operand:TF 0 "register_operand" "=f") (abs:TF (match_operand:TF 1 "register_operand" "f")))] "(TARGET_NUMERICS)" "cpysre %1,0f0.0,%0" [(set_attr "type" "fpmove")]);; Arithmetic shift instructions.;; The shli instruction generates an overflow fault if the sign changes.;; In the case of overflow, it does not give the natural result, it instead;; gives the last shift value before the overflow. We can not use this;; instruction because gcc thinks that arithmetic left shift and logical;; left shift are identical, and sometimes canonicalizes the logical left;; shift to an arithmetic left shift. Therefore we must always use the;; logical left shift instruction.(define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=d") (ashift:SI (match_operand:SI 1 "arith_operand" "dI") (match_operand:SI 2 "arith_operand" "dI")))] "" "shlo %2,%1,%0" [(set_attr "type" "alu2")])(define_insn "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=d") (ashiftrt:SI (match_operand:SI 1 "arith_operand" "dI") (match_operand:SI 2 "arith_operand" "dI")))] "" "shri %2,%1,%0" [(set_attr "type" "alu2")])(define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=d") (lshiftrt:SI (match_operand:SI 1 "arith_operand" "dI") (match_operand:SI 2 "arith_operand" "dI")))] "" "shro %2,%1,%0" [(set_attr "type" "alu2")]);; Unconditional and other jump instructions.(define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "b %l0" [(set_attr "type" "branch")])(define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "address_operand" "p"))] "" "bx %a0" [(set_attr "type" "branch")])(define_insn "tablejump" [(set (pc) (match_operand:SI 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] "" "*{ if (flag_pic) return \"bx %l1(%0)\"; else return \"bx (%0)\";}" [(set_attr "type" "branch")]);;- jump to subroutine(define_expand "call" [(call (match_operand:SI 0 "memory_operand" "m") (match_operand:SI 1 "immediate_operand" "i"))] "" "{ emit_call_insn (gen_call_internal (operands[0], operands[1], virtual_outgoing_args_rtx)); DONE;}");; We need a call saved register allocated for the match_scratch, so we use;; 'l' because all local registers are call saved.;; ??? I would prefer to use a match_scratch here, but match_scratch allocated;; registers can't be used for spills. In a function with lots of calls,;; local-alloc may allocate all local registers to a match_scratch, leaving;; no local registers available for spills.(define_insn "call_internal" [(call (match_operand:SI 0 "memory_operand" "m") (match_operand:SI 1 "immediate_operand" "i")) (use (match_operand:SI 2 "address_operand" "p")) (clobber (reg:SI 19))] "" "* return i960_output_call_insn (operands[0], operands[1], operands[2], insn);" [(set_attr "type" "call")])(define_expand "call_value" [(set (match_operand 0 "register_operand" "=d") (call (match_operand:SI 1 "memory_operand" "m") (match_operand:SI 2 "immediate_operand" "i")))] "" "{ emit_call_insn (gen_call_value_internal (operands[0], operands[1], operands[2], virtual_outgoing_args_rtx)); DONE;}");; We need a call saved register allocated for the match_scratch, so we use;; 'l' because all local registers are call saved.(define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=d") (call (match_operand:SI 1 "memory_operand" "m") (match_operand:SI 2 "immediate_operand" "i"))) (use (match_operand:SI 3 "address_operand" "p")) (clobber (reg:SI 19))] "" "* return i960_output_call_insn (operands[1], operands[2], operands[3], insn);" [(set_attr "type" "call")])(define_insn "return" [(return)] "" "* return i960_output_ret_insn (insn);"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -