📄 iq2000.md
字号:
DONE;}")(define_expand "slt" [(set (match_operand:SI 0 "register_operand" "=d") (lt:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "slt_si" [(set (match_operand:SI 0 "register_operand" "=d,=d") (lt:SI (match_operand:SI 1 "register_operand" "d,d") (match_operand:SI 2 "arith_operand" "d,I")))] "" "@ slt\\t%0,%1,%2 slti\\t%0,%1,%2" [(set_attr "type" "arith,arith") (set_attr "mode" "SI,SI")])(define_expand "sle" [(set (match_operand:SI 0 "register_operand" "=d") (le:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "sle_si_const" [(set (match_operand:SI 0 "register_operand" "=d") (le:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "small_int" "I")))] "INTVAL (operands[2]) < 32767" "*{ operands[2] = GEN_INT (INTVAL (operands[2])+1); return \"slti\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_expand "sgtu" [(set (match_operand:SI 0 "register_operand" "=d") (gtu:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "sgtu_si" [(set (match_operand:SI 0 "register_operand" "=d") (gtu:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "reg_or_0_operand" "dJ")))] "" "sltu\\t%0,%z2,%1" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=t") (gtu:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d")))] "" "sltu\\t%2,%1" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_expand "sgeu" [(set (match_operand:SI 0 "register_operand" "=d") (geu:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_expand "sltu" [(set (match_operand:SI 0 "register_operand" "=d") (ltu:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "sltu_si" [(set (match_operand:SI 0 "register_operand" "=d,=d") (ltu:SI (match_operand:SI 1 "register_operand" "d,d") (match_operand:SI 2 "arith_operand" "d,I")))] "" "@ sltu\\t%0,%1,%2 sltiu\\t%0,%1,%2" [(set_attr "type" "arith,arith") (set_attr "mode" "SI,SI")])(define_expand "sleu" [(set (match_operand:SI 0 "register_operand" "=d") (leu:SI (match_dup 1) (match_dup 2)))] "" "{ if (branch_type != CMP_SI && (branch_type != CMP_DI)) FAIL; /* Set up operands from compare. */ operands[1] = branch_cmp[0]; operands[2] = branch_cmp[1]; gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0); DONE;}")(define_insn "sleu_si_const" [(set (match_operand:SI 0 "register_operand" "=d") (leu:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "small_int" "I")))] "INTVAL (operands[2]) < 32767" "*{ operands[2] = GEN_INT (INTVAL (operands[2]) + 1); return \"sltiu\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI")]);;;; ....................;;;; UNCONDITIONAL BRANCHES;;;; ....................;; Unconditional branches.(define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "*{ if (GET_CODE (operands[0]) == REG) return \"j\\t%0\"; return \"j\\t%l0\"; /* return \"b\\t%l0\";*/}" [(set_attr "type" "jump") (set_attr "mode" "none")])(define_expand "indirect_jump" [(set (pc) (match_operand 0 "register_operand" "d"))] "" "{ rtx dest; if (operands[0]) /* eliminate unused code warnings */ { dest = operands[0]; if (GET_CODE (dest) != REG || GET_MODE (dest) != Pmode) operands[0] = copy_to_mode_reg (Pmode, dest); if (!(Pmode == DImode)) emit_jump_insn (gen_indirect_jump_internal1 (operands[0])); else emit_jump_insn (gen_indirect_jump_internal2 (operands[0])); DONE; }}")(define_insn "indirect_jump_internal1" [(set (pc) (match_operand:SI 0 "register_operand" "d"))] "!(Pmode == DImode)" "j\\t%0" [(set_attr "type" "jump") (set_attr "mode" "none")])(define_expand "tablejump" [(set (pc) (match_operand 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] "" "{ if (operands[0]) /* eliminate unused code warnings */ { if (GET_MODE (operands[0]) != Pmode) abort (); if (!(Pmode == DImode)) emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1])); else emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1])); DONE; }}")(define_insn "tablejump_internal1" [(set (pc) (match_operand:SI 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] "!(Pmode == DImode)" "j\\t%0" [(set_attr "type" "jump") (set_attr "mode" "none")])(define_expand "tablejump_internal3" [(parallel [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "d") (label_ref:SI (match_operand 1 "" "")))) (use (label_ref:SI (match_dup 1)))])] "" "");;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise;;; it is not valid. ??? With the USE, the condition tests may not be required;;; any longer.;;; ??? The length depends on the ABI. It is two for o32, and one for n32.;;; We just use the conservative number here.(define_insn "" [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "d") (label_ref:SI (match_operand 1 "" "")))) (use (label_ref:SI (match_dup 1)))] "!(Pmode == DImode) && next_active_insn (insn) != 0 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC && PREV_INSN (next_active_insn (insn)) == operands[1]" "*{ return \"j\\t%0\";}" [(set_attr "type" "jump") (set_attr "mode" "none") (set_attr "length" "8")]);;;; ....................;;;; Function prologue/epilogue;;;; ....................;;(define_expand "prologue" [(const_int 1)] "" "{ if (iq2000_isa >= 0) /* avoid unused code warnings */ { iq2000_expand_prologue (); DONE; }}");; Block any insns from being moved before this point, since the;; profiling call to mcount can use various registers that aren't;; saved or used to pass arguments.(define_insn "blockage" [(unspec_volatile [(const_int 0)] 0)] "" "" [(set_attr "type" "unknown") (set_attr "mode" "none") (set_attr "length" "0")])(define_expand "epilogue" [(const_int 2)] "" "{ if (iq2000_isa >= 0) /* avoid unused code warnings */ { iq2000_expand_epilogue (); DONE; }}");; Trivial return. Make it look like a normal return insn as that;; allows jump optimizations to work better .(define_insn "return" [(return)] "iq2000_can_use_return_insn ()" "j\\t%%31" [(set_attr "type" "jump") (set_attr "mode" "none")]);; Normal return.(define_insn "return_internal" [(use (match_operand 0 "pmode_register_operand" "")) (return)] "" "*{ return \"j\\t%0\";}" [(set_attr "type" "jump") (set_attr "mode" "none")])(define_insn "eh_return_internal" [(const_int 4) (return) (use (reg:SI 26)) (use (reg:SI 31))] "" "j\\t%%26" [(set_attr "type" "jump") (set_attr "mode" "none")])(define_expand "eh_return" [(use (match_operand:SI 0 "register_operand" "r"))] "" "{ iq2000_expand_eh_return (operands[0]); DONE;}");;;; ....................;;;; FUNCTION CALLS;;;; ....................;; calls.c now passes a third argument, make saber happy(define_expand "call" [(parallel [(call (match_operand 0 "memory_operand" "m") (match_operand 1 "" "i")) (clobber (reg:SI 31)) (use (match_operand 2 "" "")) ;; next_arg_reg (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx "" "{ rtx addr; if (operands[0]) /* eliminate unused code warnings */ { addr = XEXP (operands[0], 0); if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr))) || ! call_insn_operand (addr, VOIDmode)) XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr); /* In order to pass small structures by value in registers compatibly with the IQ2000 compiler, we need to shift the value into the high part of the register. Function_arg has encoded a PARALLEL rtx, holding a vector of adjustments to be made as the next_arg_reg variable, so we split up the insns, and emit them separately. */ if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL) { rtvec adjust = XVEC (operands[2], 0); int num = GET_NUM_ELEM (adjust); int i; for (i = 0; i < num; i++) emit_insn (RTVEC_ELT (adjust, i)); } emit_call_insn (gen_call_internal0 (operands[0], operands[1], gen_rtx_REG (SImode, GP_REG_FIRST + 31))); DONE; }}")(define_expand "call_internal0" [(parallel [(call (match_operand 0 "" "") (match_operand 1 "" "")) (clobber (match_operand:SI 2 "" ""))])] "" "")(define_insn "call_internal1" [(call (mem (match_operand 0 "call_insn_operand" "ri")) (match_operand 1 "" "i")) (clobber (match_operand:SI 2 "register_operand" "=d"))] "" "*{ register rtx target = operands[0]; if (GET_CODE (target) == CONST_INT) return \"li\\t%@,%0\\n\\tjalr\\t%2,%@\"; else if (CONSTANT_ADDRESS_P (target)) return \"jal\\t%0\"; else return \"jalr\\t%2,%0\";}" [(set_attr "type" "call") (set_attr "mode" "none")]);; calls.c now passes a fourth argument, make saber happy(define_expand "call_value" [(parallel [(set (match_operand 0 "register_operand" "=df") (call (match_operand 1 "memory_operand" "m") (match_operand 2 "" "i"))) (clobber (reg:SI 31)) (use (match_operand 3 "" ""))])] ;; next_arg_reg "" "{ rtx addr; if (operands[0]) /* eliminate unused code warning */ { addr = XEXP (operands[1], 0); if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr))) || ! call_insn_operand (addr, VOIDmode)) XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr); /* In order to pass small structures by value in registers compatibly with the IQ2000 compiler, we need to shift the value into the high part of the register. Function_arg has encoded a PARALLEL rtx, holding a vector of adjustments to be made as the next_arg_reg variable, so we split up the insns, and emit them separately. */ if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL) { rtvec adjust = XVEC (operands[3], 0); int num = GET_NUM_ELEM (adjust); int i; for (i = 0; i < num; i++) emit_insn (RTVEC_ELT (adjust, i)); } if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1) { emit_call_insn (gen_call_value_multiple_internal0 (XEXP (XVECEXP (operands[0], 0, 0), 0), operands[1], operands[2], XEXP (XVECEXP (operands[0], 0, 1), 0),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -