📄 mcore.md
字号:
&& ! CONST_OK_FOR_I (INTVAL (operands[1])) && ! CONST_OK_FOR_M (INTVAL (operands[1])) && ! CONST_OK_FOR_N (INTVAL (operands[1])) && GET_CODE (operands[0]) == REG && REGNO (operands[0]) == LK_REG)" "* return mcore_output_inline_const_forced (insn, operands, SImode);" [(set_attr "type" "load")]);; (define_expand "reload_insi";; [(parallel [(match_operand:SI 0 "register_operand" "=r");; (match_operand:SI 1 "general_operand" "");; (match_operand:DI 2 "register_operand" "=&r")])];; "";; ";; {;; if (CONSTANT_P (operands[1]);; && GET_CODE (operands[1]) == CONST_INT;; && ! CONST_OK_FOR_I (INTVAL (operands[1]));; && ! CONST_OK_FOR_M (INTVAL (operands[1]));; && ! CONST_OK_FOR_N (INTVAL (operands[1]));; && GET_CODE (operands[0]) == REG;; && (REGNO (operands[0]) == STACK_POINTER_REGNUM;; || REGNO (operands[0]) == LK_REG));; {;; rtx tmp;;; ;; if ( REGNO (operands[2]) == REGNO (operands[0]);; || REGNO (operands[2]) == STACK_POINTER_REGNUM;; || REGNO (operands[2]) == LK_REG);; tmp = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);;; else;; tmp = gen_rtx_REG (SImode, REGNO (operands[2]));;; ;; emit_insn (gen_movsi (tmp, operands[1]));;; emit_insn (gen_movsi (operands[0], tmp));;; DONE;;; };; emit_insn (gen_movsi (operands[0], operands[1]));;; DONE;;; }";; ) ;;;; HImode;;;;; ??? This isn't guaranteed to work. It should be more like the SImode;;; patterns.(define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "") (match_operand:HI 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (HImode, operands[1]); else if (CONSTANT_P (operands[1]) && (GET_CODE (operands[1]) != CONST_INT || (! CONST_OK_FOR_I (INTVAL (operands[1])) && ! CONST_OK_FOR_M (INTVAL (operands[1])) && ! CONST_OK_FOR_N (INTVAL (operands[1])))) && ! reload_completed && ! reload_in_progress) { rtx reg = gen_reg_rtx (SImode); emit_insn (gen_movsi (reg, operands[1])); operands[1] = gen_rtx (SUBREG, HImode, reg, 0); }}") (define_insn "" [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,r,r,r,r,m") (match_operand:HI 1 "mcore_general_movsrc_operand" "r,I,M,N,c,m,r"))] "(register_operand (operands[0], HImode) || register_operand (operands[1], HImode)) && (GET_CODE (operands[1]) != CONST_INT || CONST_OK_FOR_M (INTVAL (operands[1])) || CONST_OK_FOR_N (INTVAL (operands[1])) || CONST_OK_FOR_I (INTVAL (operands[1])))" "@ mov %0,%1 movi %0,%1 bgeni %0,%P1 bmaski %0,%N1 mvc %0 ld.h %0,%1 st.h %1,%0" [(set_attr "type" "move,move,move,move,move,load,store")]);; Like movhi, but the const_int source can't be synthesized in;; a single-instruction. Fall back to the same things that ;; are done for movsi in such cases. Presumes that we can;; modify any parts of the register that we wish.(define_insn "" [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,a") (match_operand:HI 1 "const_int_operand" "P,i"))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) > 127 && INTVAL (operands[1]) < 65536" "*{ if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15 && !mcore_const_ok_for_inline (INTVAL (operands[1]))) { /* mcore_output_move would generate lrw r15 -- a forbidden combo */ return mcore_output_inline_const_forced (insn, operands, SImode); } else return mcore_output_move (insn, operands, SImode);}" [(set_attr "type" "move")]);; if we're still looking around for things to use, here's a last;; ditch effort that just calls the move. We only let this happen;; if we're in the reload pass.;;(define_insn "" [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,a") (match_operand:HI 1 "const_int_operand" "P,i"))] "reload_in_progress || reload_completed" "*{ if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15 && !mcore_const_ok_for_inline (INTVAL (operands[1]))) { /* mcore_output_move would generate lrw r15 -- a forbidden combo */ return mcore_output_inline_const_forced (insn, operands, SImode); } else return mcore_output_move (insn, operands, HImode);}" [(set_attr "type" "move")]);;;; QImode;;(define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (QImode, operands[1]); else if (CONSTANT_P (operands[1]) && (GET_CODE (operands[1]) != CONST_INT || (! CONST_OK_FOR_I (INTVAL (operands[1])) && ! CONST_OK_FOR_M (INTVAL (operands[1])) && ! CONST_OK_FOR_N (INTVAL (operands[1])))) && ! reload_completed && ! reload_in_progress) { rtx reg = gen_reg_rtx (SImode); emit_insn (gen_movsi (reg, operands[1])); operands[1] = gen_rtx (SUBREG, QImode, reg, 0); }}") (define_insn "" [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,r,r,r,r,m") (match_operand:QI 1 "mcore_general_movsrc_operand" "r,I,M,N,c,m,r"))] "(register_operand (operands[0], QImode) || register_operand (operands[1], QImode)) && (GET_CODE (operands[1]) != CONST_INT || CONST_OK_FOR_M (INTVAL (operands[1])) || CONST_OK_FOR_N (INTVAL (operands[1])) || CONST_OK_FOR_I (INTVAL (operands[1])))" "@ mov %0,%1 movi %0,%1 bgeni %0,%P1 bmaski %0,%N1 mvc %0 ld.b %0,%1 st.b %1,%0" [(set_attr "type" "move,move,move,move,move,load,store")]);; cover the case where the constant is 128..255; this isn't handled;; in the above case. We could if we wanted to mess with adding a ;; new constraint class like M,N,I.(define_insn "" [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r") (match_operand:QI 1 "const_int_operand" ""))] "GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) > 127 && INTVAL (operands[1]) < 256" "*{ /* have a constant in range 128..255; have to do 2 insns; we can * do this with a movi followed by a bseti */ operands[2] = GEN_INT (INTVAL (operands[1]) & 0x7f); return \"movi\\t%0,%2\;bseti\\t%0,7\";}" [(set_attr "type" "move")]);; if we're still looking around for things to use, here's a last;; ditch effort that just calls the move. We only let this happen;; if we're in the reload pass.;;(define_insn "" [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,a") (match_operand:QI 1 "const_int_operand" "P,i"))] "(reload_in_progress || reload_completed)" "*{ if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15 && ! mcore_const_ok_for_inline (INTVAL (operands[1]))) { /* mcore_output_move would generate lrw r15 -- a forbidden combo */ return mcore_output_inline_const_forced (insn, operands, SImode); } else return mcore_output_move (insn, operands, QImode);}" [(set_attr "type" "move")]);; DImode(define_expand "movdi" [(set (match_operand:DI 0 "general_operand" "") (match_operand:DI 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (DImode, operands[1]); else if (GET_CODE (operands[1]) == CONST_INT && ! CONST_OK_FOR_I (INTVAL (operands[1])) && ! CONST_OK_FOR_M (INTVAL (operands[1])) && ! CONST_OK_FOR_N (INTVAL (operands[1])) && ! reload_completed && ! reload_in_progress && GET_CODE (operands[0]) == REG) { emit_move_insn (operand_subword (operands[0], 0, 1, DImode), operand_subword_force (operands[1], 0, DImode)); emit_move_insn (operand_subword (operands[0], 1, 1, DImode), operand_subword_force (operands[1], 1, DImode)); DONE; }}")(define_insn "movdi_i" [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,a,r,m") (match_operand:DI 1 "mcore_general_movsrc_operand" "I,M,N,r,R,m,r"))] "" "* return mcore_output_movedouble (operands, DImode);" [(set_attr "length" "4") (set_attr "type" "move,move,move,move,load,load,store")]);; SFmode(define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (SFmode, operands[1]);}")(define_insn "movsf_i" [(set (match_operand:SF 0 "general_operand" "=r,r,m") (match_operand:SF 1 "general_operand" "r,m,r"))] "" "@ mov %0,%1 ld.w %0,%1 st.w %1,%0" [(set_attr "type" "move,load,store")]);; DFmode(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] "" "{ if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (DFmode, operands[1]);}")(define_insn "movdf_k" [(set (match_operand:DF 0 "general_operand" "=r,r,m") (match_operand:DF 1 "general_operand" "r,m,r"))] "" "* return mcore_output_movedouble (operands, DFmode);" [(set_attr "length" "4") (set_attr "type" "move,load,store")]);; Load/store multiple;; ??? This is not currently used.(define_insn "ldm" [(set (match_operand:TI 0 "mcore_arith_reg_operand" "=r") (mem:TI (match_operand:SI 1 "mcore_arith_reg_operand" "r")))] "" "ldq %U0,(%1)");; ??? This is not currently used.(define_insn "stm" [(set (mem:TI (match_operand:SI 0 "mcore_arith_reg_operand" "r")) (match_operand:TI 1 "mcore_arith_reg_operand" "r"))] "" "stq %U1,(%0)")(define_expand "load_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] "" "{ int regno, count, i; /* Support only loading a constant number of registers from memory and only if at least two registers. The last register must be r15. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 2 || GET_CODE (operands[1]) != MEM || XEXP (operands[1], 0) != stack_pointer_rtx || GET_CODE (operands[0]) != REG || REGNO (operands[0]) + INTVAL (operands[2]) != 16) FAIL; count = INTVAL (operands[2]); regno = REGNO (operands[0]); operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count)); for (i = 0; i < count; i++) XVECEXP (operands[3], 0, i) = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i), gen_rtx (MEM, SImode, plus_constant (stack_pointer_rtx, i * 4)));}")(define_insn "" [(match_parallel 0 "mcore_load_multiple_operation" [(set (match_operand:SI 1 "mcore_arith_reg_operand" "=r") (mem:SI (match_operand:SI 2 "register_operand" "r")))])] "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM" "ldm %1-r15,(%2)")(define_expand "store_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") (match_operand:SI 1 "" "")) (use (match_operand:SI 2 "" ""))])] "" "{ int regno, count, i; /* Support only storing a constant number of registers to memory and only if at least two registers. The last register must be r15. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 2 || GET_CODE (operands[0]) != MEM || XEXP (operands[0], 0) != stack_pointer_rtx || GET_CODE (operands[1]) != REG || REGNO (operands[1]) + INTVAL (operands[2]) != 16) FAIL; count = INTVAL (operands[2]); regno = REGNO (operands[1]); operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count)); for (i = 0; i < count; i++) XVECEXP (operands[3], 0, i) = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, plus_constant (stack_pointer_rtx, i * 4)), gen_rtx (REG, SImode, regno + i));}")(define_insn "" [(match_parallel 0 "mcore_store_multiple_operation" [(set (mem:SI (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 1 "mcore_arith_reg_operand" "r"))])] "GET_CODE (operands[2]) == REG && REGNO (operands[2]) == STACK_POINTER_REGNUM" "stm %1-r15,(%2)");; ------------------------------------------------------------------------;; Define the real conditional branch instructions.;; ------------------------------------------------------------------------(define_insn "branch_true" [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jbt %l0" [(set_attr "type" "brcond")])(define_insn "branch_false" [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jbf %l0" [(set_attr "type" "brcond")])(define_insn "inverse_branch_true" [(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jbf %l0" [(set_attr "type" "brcond")])(define_insn "inverse_branch_false" [(set (pc) (if_then_else (eq (reg:CC 17) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "jbt %l0" [(set_attr "type" "brcond")])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -