📄 mn10300.md
字号:
if (GET_CODE (operands[1]) == MEM && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) { rtx temp = operands[0]; while (GET_CODE (temp) == SUBREG) temp = SUBREG_REG (temp); if (GET_CODE (temp) != REG) abort (); if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)), XEXP (operands[1], 0))) return \"mov %H1,%H0\;mov %L1,%L0\"; else return \"mov %L1,%L0\;mov %H1,%H0\"; } else if (GET_CODE (operands[1]) == MEM && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS) { rtx xoperands[2]; xoperands[0] = operands[0]; xoperands[1] = XEXP (operands[1], 0); output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\", xoperands); return \"\"; } else { if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && val[0] == 0) { if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) output_asm_insn (\"clr %L0\", operands); else output_asm_insn (\"mov %L1,%L0\", operands); } else if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS) && (((val[0] & 0x80) && ! (val[0] & 0xffffff00)) || ((val[0] & 0x800000) && ! (val[0] & 0xff000000)))) output_asm_insn (\"movu %1,%0\", operands); else output_asm_insn (\"mov %L1,%L0\", operands); if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && val[1] == 0) { if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) output_asm_insn (\"clr %H0\", operands); else output_asm_insn (\"mov %H1,%H0\", operands); } else if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && val[0] == val[1]) output_asm_insn (\"mov %L0,%H0\", operands); else if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS) && (((val[1] & 0x80) && ! (val[1] & 0xffffff00)) || ((val[1] & 0x800000) && ! (val[1] & 0xff000000)))) output_asm_insn (\"movu %1,%0\", operands); else output_asm_insn (\"mov %H1,%H0\", operands); return \"\"; } default: abort (); }}" [(set (attr "cc") (cond [ (lt (symbol_ref "which_alternative") (const_int 2) ) (const_string "none") (eq (symbol_ref "which_alternative") (const_int 2) ) (const_string "clobber") (eq (symbol_ref "which_alternative") (const_int 3) ) (if_then_else (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])") (const_int 0)) (const_string "clobber") (const_string "none_0hit")) (ior (eq (symbol_ref "which_alternative") (const_int 8)) (eq (symbol_ref "which_alternative") (const_int 9)) ) (if_then_else (ne (symbol_ref "mn10300_wide_const_load_uses_clr (operands)") (const_int 0)) (const_string "clobber") (const_string "none_0hit")) ] (const_string "none_0hit")))])(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] "" "{ /* One of the ops has to be in a register */ if (!register_operand (operand1, DFmode) && !register_operand (operand0, DFmode)) operands[1] = copy_to_mode_reg (DFmode, operand1);}")(define_insn "" [(set (match_operand:DF 0 "nonimmediate_operand" "=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax") (match_operand:DF 1 "general_operand" "0,0,G,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))] "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" "*{ long val[2]; REAL_VALUE_TYPE rv; switch (which_alternative) { case 0: case 1: return \"nop\"; case 2: return \"clr %L0\;clr %H0\"; case 3: if (rtx_equal_p (operands[0], operands[1])) return \"sub %L1,%L0\;mov %L0,%H0\"; else return \"mov %1,%L0\;mov %L0,%H0\"; case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: if (GET_CODE (operands[1]) == CONST_INT) { rtx low, high; split_double (operands[1], &low, &high); val[0] = INTVAL (low); val[1] = INTVAL (high); } if (GET_CODE (operands[1]) == CONST_DOUBLE) { if (GET_MODE (operands[1]) == DFmode) { REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); REAL_VALUE_TO_TARGET_DOUBLE (rv, val); } else if (GET_MODE (operands[1]) == VOIDmode || GET_MODE (operands[1]) == DImode) { val[0] = CONST_DOUBLE_LOW (operands[1]); val[1] = CONST_DOUBLE_HIGH (operands[1]); } } if (GET_CODE (operands[1]) == MEM && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0))) { rtx temp = operands[0]; while (GET_CODE (temp) == SUBREG) temp = SUBREG_REG (temp); if (GET_CODE (temp) != REG) abort (); if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)), XEXP (operands[1], 0))) return \"mov %H1,%H0\;mov %L1,%L0\"; else return \"mov %L1,%L0\;mov %H1,%H0\"; } else if (GET_CODE (operands[1]) == MEM && CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) && REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS) { rtx xoperands[2]; xoperands[0] = operands[0]; xoperands[1] = XEXP (operands[1], 0); output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\", xoperands); return \"\"; } else { if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && val[0] == 0) { if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) output_asm_insn (\"clr %L0\", operands); else output_asm_insn (\"mov %L1,%L0\", operands); } else if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS) && (((val[0] & 0x80) && ! (val[0] & 0xffffff00)) || ((val[0] & 0x800000) && ! (val[0] & 0xff000000)))) output_asm_insn (\"movu %1,%0\", operands); else output_asm_insn (\"mov %L1,%L0\", operands); if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && val[1] == 0) { if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS) output_asm_insn (\"clr %H0\", operands); else output_asm_insn (\"mov %H1,%H0\", operands); } else if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && val[0] == val[1]) output_asm_insn (\"mov %L0,%H0\", operands); else if ((GET_CODE (operands[1]) == CONST_INT || GET_CODE (operands[1]) == CONST_DOUBLE) && (REGNO_REG_CLASS (true_regnum (operands[0])) == EXTENDED_REGS) && (((val[1] & 0x80) && ! (val[1] & 0xffffff00)) || ((val[1] & 0x800000) && ! (val[1] & 0xff000000)))) output_asm_insn (\"movu %1,%0\", operands); else output_asm_insn (\"mov %H1,%H0\", operands); return \"\"; } default: abort (); }}" [(set (attr "cc") (cond [ (lt (symbol_ref "which_alternative") (const_int 2) ) (const_string "none") (eq (symbol_ref "which_alternative") (const_int 2) ) (const_string "clobber") (eq (symbol_ref "which_alternative") (const_int 3) ) (if_then_else (ne (symbol_ref "rtx_equal_p (operands[0], operands[1])") (const_int 0)) (const_string "clobber") (const_string "none_0hit")) (ior (eq (symbol_ref "which_alternative") (const_int 8)) (eq (symbol_ref "which_alternative") (const_int 9)) ) (if_then_else (ne (symbol_ref "mn10300_wide_const_load_uses_clr (operands)") (const_int 0)) (const_string "clobber") (const_string "none_0hit")) ] (const_string "none_0hit")))]);; ----------------------------------------------------------------------;; TEST INSTRUCTIONS;; ----------------------------------------------------------------------;; Go ahead and define tstsi so we can eliminate redundant tst insns;; when we start trying to optimize this port.(define_insn "tstsi" [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))] "" "* return output_tst (operands[0], insn);" [(set_attr "cc" "set_znv")])(define_insn "" [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))] "TARGET_AM33" "* return output_tst (operands[0], insn);" [(set_attr "cc" "set_znv")])(define_insn "" [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))] "" "* return output_tst (operands[0], insn);" [(set_attr "cc" "set_znv")])(define_insn "" [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))] "TARGET_AM33" "* return output_tst (operands[0], insn);" [(set_attr "cc" "set_znv")])(define_insn "" [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))] "" "* return output_tst (operands[0], insn);" [(set_attr "cc" "set_znv")]);; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if;; its operands hold equal values, but the operands of a cmp;; instruction must be distinct registers. In the case where we'd;; like to compare a register to itself, we can achieve this effect;; with a btst 0,d0 instead. (This will not alter the contents of d0;; but will have the proper effect on cc0. Using d0 is arbitrary; any;; data register would work.);; Even though the first alternative would be preferrable if it can;; possibly match, reload must not be given the opportunity to attempt;; to use it. It assumes that such matches can only occur when one of;; the operands is used for input and the other for output. Since;; this is not the case, it abort()s. Indeed, such a reload cannot be;; possibly satisfied, so just mark the alternative with a `!', so;; that it is not considered by reload.(define_insn "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax") (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))] "" "@ btst 0,d0 cmp %1,%0" [(set_attr "cc" "compare,compare")]);; ----------------------------------------------------------------------;; ADD INSTRUCTIONS;; ----------------------------------------------------------------------(define_expand "addsi3" [(set (match_operand:SI 0 "register_operand" "") (plus:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "nonmemory_operand" "")))] "" "")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax") (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax") (match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))] "TARGET_AM33" "*{ switch (which_alternative) { case 0: case 1: return \"inc %0\"; case 2: case 3: return \"inc4 %0\"; case 4: case 5: return \"add %2,%0\"; case 6: { enum reg_class src1_class, src2_class, dst_class; src1_class = REGNO_REG_CLASS (true_regnum (operands[1])); src2_class = REGNO_REG_CLASS (true_regnum (operands[2])); dst_class = REGNO_REG_CLASS (true_regnum (operands[0])); /* I'm not sure if this can happen or not. Might as well be prepared and generate the best possible code if it does happen. */ if (true_regnum (operands[0]) == true_regnum (operands[1])) return \"add %2,%0\"; if (true_regnum (operands[0]) == true_regnum (operands[2])) return \"add %1,%0\"; /* Catch cases where no extended register was used. These should be handled just like the mn10300. */ if (src1_class != EXTENDED_REGS && src2_class != EXTENDED_REGS && dst_class != EXTENDED_REGS) { /* We have to copy one of the sources into the destination, then add the other source to the destination. Carefully select which source to copy to the destination; a naive implementation will waste a byte when the source classes are different and the destination is an address register. Selecting the lowest cost register copy will optimize this sequence. */ if (REGNO_REG_CLASS (true_regnum (operands[1])) == REGNO_REG_CLASS (true_regnum (operands[0]))) return \"mov %1,%0\;add %2,%0\"; return \"mov %2,%0\;add %1,%0\"; } /* At least one register is an extended register. */ /* The three operand add instruction on the am33 is a win iff the output register is an extended register, or if both source registers are extended registers. */ if (dst_class == EXTENDED_REGS || src1_class == src2_class) return \"add %2,%1,%0\"; /* It is better to copy one of the sources to the destination, then perform a 2 address add. The destination in this case must be an address or data register and one of the sources must be an extended register and the remaining source must not be an extended register. The best code for this case is to copy the extended reg to the destination, then emit a two address add. */ if (src1_class == EXTENDED_REGS) return \"mov %1,%0\;add %2,%0\"; return \"mov %2,%0\;add %1,%0\"; } default: abort (); }}" [(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])(define_insn "" [(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax") (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax") (match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))] "" "*{ switch (which_alternative) { case 0: case 1: return \"inc %0\"; case 2: return \"inc4 %0\"; case 3: case 4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -