📄 i960.md
字号:
(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 "cmpxf" [(set (reg:CC 36) (compare:CC (match_operand:XF 0 "register_operand" "") (match_operand:XF 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:XF 0 "register_operand" "f") (match_operand:XF 1 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "cmpr %0,%1" [(set_attr "type" "fpcc")])(define_expand "movxf" [(set (match_operand:XF 0 "general_operand" "") (match_operand:XF 1 "fpmove_src_operand" ""))] "" "{ if (emit_move_sequence (operands, XFmode)) DONE;}")(define_insn "" [(set (match_operand:XF 0 "general_operand" "=r,f,d,d,m") (match_operand:XF 1 "fpmove_src_operand" "r,GH,F,m,d"))] "register_operand (operands[0], XFmode) || register_operand (operands[1], XFmode)" "*{ 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\"; }}" [(set_attr "type" "move,move,load,fpload,fpstore")])(define_insn "extendsfxf2" [(set (match_operand:XF 0 "register_operand" "=f,d") (float_extend:XF (match_operand:SF 1 "register_operand" "d,f")))] "TARGET_NUMERICS" "@ movr %1,%0 movre %1,%0" [(set_attr "type" "fpmove")])(define_insn "extenddfxf2" [(set (match_operand:XF 0 "register_operand" "=f,d") (float_extend:XF (match_operand:DF 1 "register_operand" "d,f")))] "TARGET_NUMERICS" "@ movrl %1,%0 movre %1,%0" [(set_attr "type" "fpmove")])(define_insn "truncxfdf2" [(set (match_operand:DF 0 "register_operand" "=d") (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] "TARGET_NUMERICS" "movrl %1,%0" [(set_attr "type" "fpmove")])(define_insn "truncxfsf2" [(set (match_operand:SF 0 "register_operand" "=d") (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] "TARGET_NUMERICS" "movr %1,%0" [(set_attr "type" "fpmove")])(define_insn "floatsixf2" [(set (match_operand:XF 0 "register_operand" "=f") (float:XF (match_operand:SI 1 "register_operand" "d")))] "TARGET_NUMERICS" "cvtir %1,%0" [(set_attr "type" "fpcvt")])(define_insn "fix_truncxfsi2" [(set (match_operand:SI 0 "register_operand" "=d") (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))] "TARGET_NUMERICS" "cvtzri %1,%0" [(set_attr "type" "fpcvt")])(define_insn "fixuns_truncxfsi2" [(set (match_operand:SI 0 "register_operand" "=d") (unsigned_fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))] "TARGET_NUMERICS" "cvtzri %1,%0" [(set_attr "type" "fpcvt")])(define_insn "addxf3" [(set (match_operand:XF 0 "register_operand" "=f") (plus:XF (match_operand:XF 1 "nonmemory_operand" "%fGH") (match_operand:XF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "addr %1,%2,%0" [(set_attr "type" "fpadd")])(define_insn "subxf3" [(set (match_operand:XF 0 "register_operand" "=f") (minus:XF (match_operand:XF 1 "nonmemory_operand" "fGH") (match_operand:XF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "subr %2,%1,%0" [(set_attr "type" "fpadd")])(define_insn "mulxf3" [(set (match_operand:XF 0 "register_operand" "=f") (mult:XF (match_operand:XF 1 "nonmemory_operand" "%fGH") (match_operand:XF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "mulr %1,%2,%0" [(set_attr "type" "fpmul")])(define_insn "divxf3" [(set (match_operand:XF 0 "register_operand" "=f") (div:XF (match_operand:XF 1 "nonmemory_operand" "fGH") (match_operand:XF 2 "nonmemory_operand" "fGH")))] "TARGET_NUMERICS" "divr %2,%1,%0" [(set_attr "type" "fpdiv")])(define_insn "negxf2" [(set (match_operand:XF 0 "register_operand" "=f") (neg:XF (match_operand:XF 1 "register_operand" "f")))] "TARGET_NUMERICS" "subr %1,0f0.0,%0" [(set_attr "type" "fpadd")])(define_insn "absxf2" [(set (match_operand:XF 0 "register_operand" "=f") (abs:XF (match_operand:XF 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_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_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);" [(set_attr "type" "branch")]);; A return instruction. Used only by nonlocal_goto to change the;; stack pointer, frame pointer, previous frame pointer and the return;; instruction pointer.(define_insn "ret" [(use (reg:SI 16)) (unspec_volatile [(const_int 0)] 3)] "" "ret" [(set_attr "type" "branch") (set_attr "length" "1")])(define_expand "nonlocal_goto" [(match_operand:SI 0 "" "") (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "") (match_operand:SI 3 "general_operand" "")] "" "{ rtx chain = operands[0]; rtx handler = operands[1]; rtx stack = operands[2]; rtx label = operands[3]; /* We must restore the stack pointer, frame pointer, previous frame pointer and the return instruction pointer. Since the ret instruction does all this for us with one instruction, we arrange everything so that ret will do everything we need done. */ /* First, we must flush the register windows, so that we can modify the saved local registers on the stack directly and because we are going to change the previous frame pointer. */ emit_insn (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -