📄 mcore.md
字号:
&& ! 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_lowpart (QImode, reg); }}") (define_insn "" [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m") (match_operand:QI 1 "mcore_general_movsrc_operand" "r,P,i,c,m,r"))] "(register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" "* return mcore_output_move (insn, operands, QImode);" [(set_attr "type" "move,move,move,move,load,store")]);; 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]))) { int i; for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD) emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i), simplify_gen_subreg (SImode, operands[1], DImode, i)); 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")]);; Conditional branch insns;; At top-level, condition test are eq/ne, because we;; are comparing against the condition register (which;; has the result of the true relational test; There is no beq compare, so we reverse the branch arms.(define_expand "beq" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "{ operands[1] = mcore_gen_compare_reg (EQ);}")(define_expand "bne" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = mcore_gen_compare_reg (NE);}"); check whether (GT A imm) can become (LE A imm) with the branch reversed. ; if so, emit a (LT A imm + 1) in place of the (LE A imm). BRC(define_expand "bgt" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (mcore_modify_comparison (LE)) { emit_jump_insn (gen_reverse_blt (operands[0])); DONE; } operands[1] = mcore_gen_compare_reg (GT);}"); There is no ble compare, so we reverse the branch arms.; reversed the condition and branch arms for ble -- the check_dbra_loop(); transformation assumes that ble uses a branch-true with the label as; as the target. BRC; check whether (LE A imm) can become (LT A imm + 1).(define_expand "ble" [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ if (mcore_modify_comparison (LE)) { emit_jump_insn (gen_blt (operands[0])); DONE; } operands[1] = mcore_gen_compare_reg (LE);}"); make generating a reversed blt simple(define_expand "reverse_blt" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "{ operands[1] = mcore_gen_compare_reg (LT);}")(define_expand "blt" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = mcore_gen_compare_reg (LT);}"); There is no bge compare, so we reverse the branch arms.(define_expand "bge" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "{ operands[1] = mcore_gen_compare_reg (GE);}"); There is no gtu compare, so we reverse the branch arms;(define_expand "bgtu"; [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)); (pc); (label_ref (match_operand 0 "" ""))))]; ""; ";{; if (GET_CODE (arch_compare_op1) == CONST_INT; && INTVAL (arch_compare_op1) == 0); operands[1] = mcore_gen_compare_reg (NE);; else ; { if (mcore_modify_comparison (GTU)); {; emit_jump_insn (gen_bgeu (operands[0]));; DONE;; }; operands[1] = mcore_gen_compare_reg (LEU);; };}")(define_expand "bgtu" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "{ if (GET_CODE (arch_compare_op1) == CONST_INT && INTVAL (arch_compare_op1) == 0) { /* The inverse of '> 0' for an unsigned test is '== 0' but we do not have such an instruction available. Instead we must reverse the branch (back to the normal ordering) and test '!= 0'. */ operands[1] = mcore_gen_compare_reg (NE); emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, gen_rtx_NE (VOIDmode, operands[1], const0_rtx), gen_rtx_LABEL_REF (VOIDmode,operands[0]), pc_rtx))); DONE; } operands[1] = mcore_gen_compare_reg (GTU);}")(define_expand "bleu" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = mcore_gen_compare_reg (LEU);}"); There is no bltu compare, so we reverse the branch arms(define_expand "bltu" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "{ operands[1] = mcore_gen_compare_reg (LTU);}")(define_expand "bgeu" [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "{ operands[1] = mcore_gen_compare_reg (GEU);}");; ------------------------------------------------------------------------;; Jump and linkage insns;; ------------------------------------------------------------------------(define_insn "jump_real" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "jbr %l0" [(set_attr "type" "branch")])(define_expand "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "{ emit_jump_insn (gen_jump_real (operand0)); DONE;}")(define_insn "indirect_jump" [(set (pc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -