📄 dsp16xx.c
字号:
case Y_ADDR_OR_YBASE_REGS: if (IS_YBASE_ELIGIBLE_REG (REGNO (x))) return YBASE_VIRT_REGS; else return (!reload_in_progress ? NO_REGS : class); case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS: if (IS_YBASE_ELIGIBLE_REG (REGNO (x))) return ACCUM_LOW_OR_YBASE_REGS; else return ACCUM_LOW_REGS; case YBASE_OR_YBASE_ELIGIBLE_REGS: if (IS_YBASE_ELIGIBLE_REG (REGNO (x))) return ACCUM_OR_YBASE_REGS; else return ACCUM_REGS; case NO_HIGH_ALL_REGS: if (IS_YBASE_ELIGIBLE_REG (REGNO (x))) return ACCUM_LOW_OR_YBASE_REGS; else return ACCUM_LOW_REGS; case ALL_REGS: if (IS_YBASE_ELIGIBLE_REG (REGNO (x))) return ACCUM_OR_YBASE_REGS; else return ACCUM_REGS; case NOHIGH_NON_ADDR_REGS: return ACCUM_LOW_REGS; case NON_ADDR_REGS: case SLOW_MEM_LOAD_REGS: return ACCUM_REGS; case NOHIGH_NON_YBASE_REGS: return ACCUM_LOW_REGS; case NO_ACCUM_NON_YBASE_REGS: return (!reload_in_progress ? NO_REGS : class); case NON_YBASE_REGS: return ACCUM_REGS; default: return class; } } /* If x (the input) is a ybase register, restrict the class of registers we can copy the register into. */ if (REG_P (x) && !TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW (REGNO(x))) { switch ((int) class) { case NO_REGS: case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG: case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS: case A1_REG: case ACCUM_REGS: case X_REG: case X_OR_ACCUM_LOW_REGS: case X_OR_ACCUM_REGS: case YH_REG: case YH_OR_ACCUM_HIGH_REGS: case X_OR_YH_REGS: case YL_REG: case YL_OR_ACCUM_LOW_REGS: case X_OR_YL_REGS: case X_OR_Y_REGS: case Y_REG: case ACCUM_OR_Y_REGS: case PH_REG: case X_OR_PH_REGS: case PL_REG: case PL_OR_ACCUM_LOW_REGS: case X_OR_PL_REGS: case YL_OR_PL_OR_ACCUM_LOW_REGS: case P_REG: case ACCUM_OR_P_REGS: case YL_OR_P_REGS: case ACCUM_LOW_OR_YL_OR_P_REGS: case Y_OR_P_REGS: case ACCUM_Y_OR_P_REGS: case NO_FRAME_Y_ADDR_REGS: case Y_ADDR_REGS: case ACCUM_LOW_OR_Y_ADDR_REGS: case ACCUM_OR_Y_ADDR_REGS: case X_OR_Y_ADDR_REGS: case Y_OR_Y_ADDR_REGS: case P_OR_Y_ADDR_REGS: case NON_HIGH_YBASE_ELIGIBLE_REGS: case YBASE_ELIGIBLE_REGS: default: return class; case J_REG: return (!reload_in_progress ? NO_REGS : class); case J_OR_DAU_16_BIT_REGS: return ACCUM_HIGH_REGS; case BMU_REGS: case YBASE_VIRT_REGS: return (!reload_in_progress ? NO_REGS : class); case ACCUM_LOW_OR_YBASE_REGS: return ACCUM_LOW_REGS; case ACCUM_OR_YBASE_REGS: return ACCUM_REGS; case X_OR_YBASE_REGS: return X_REG; case Y_OR_YBASE_REGS: return Y_REG; case ACCUM_LOW_YL_PL_OR_YBASE_REGS: return YL_OR_PL_OR_ACCUM_LOW_REGS; case P_OR_YBASE_REGS: return P_REG; case ACCUM_Y_P_OR_YBASE_REGS: return ACCUM_Y_OR_P_REGS; case Y_ADDR_OR_YBASE_REGS: return Y_ADDR_REGS; case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS: return NON_HIGH_YBASE_ELIGIBLE_REGS; case YBASE_OR_YBASE_ELIGIBLE_REGS: return YBASE_ELIGIBLE_REGS; case NO_HIGH_ALL_REGS: return NON_HIGH_YBASE_ELIGIBLE_REGS; case ALL_REGS: return YBASE_ELIGIBLE_REGS; case NOHIGH_NON_ADDR_REGS: return ACCUM_LOW_OR_YL_OR_P_REGS; case NON_ADDR_REGS: return ACCUM_Y_OR_P_REGS; case SLOW_MEM_LOAD_REGS: return ACCUM_OR_Y_ADDR_REGS; case NOHIGH_NON_YBASE_REGS: return NON_HIGH_YBASE_ELIGIBLE_REGS; case NO_ACCUM_NON_YBASE_REGS: return Y_ADDR_REGS; case NON_YBASE_REGS: return YBASE_ELIGIBLE_REGS; } } if (GET_CODE (x) == PLUS) { if (GET_MODE (x) == QImode && REG_P (XEXP (x,0)) && (XEXP (x,0) == frame_pointer_rtx || XEXP (x,0) == stack_pointer_rtx) && (GET_CODE (XEXP (x,1)) == CONST_INT)) { if (class == ACCUM_HIGH_REGS) return class; /* If the accumulators are not part of the class being reloaded into, return NO_REGS. */#if 0 if (!reg_class_subset_p (ACCUM_REGS, class)) return (!reload_in_progress ? NO_REGS : class);#endif if (reg_class_subset_p (ACCUM_HIGH_REGS, class)) return ACCUM_HIGH_REGS; /* We will use accumulator 'a1l' for reloading a PLUS. We can only use one accumulator because 'reload_inqi' only allows one alternative to be used. */ else if (class == ACCUM_LOW_REGS) return A1L_REG; else if (class == A0L_REG) return NO_REGS; else return class; } if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS) return Y_ADDR_REGS; else return class; } else if (GET_CODE (x) == MEM) { /* We can't copy from a memory location into a ybase register. */ if (reg_class_subset_p(YBASE_VIRT_REGS, class)) { switch ((int) class) { case YBASE_VIRT_REGS: return (!reload_in_progress ? NO_REGS : class); case ACCUM_LOW_OR_YBASE_REGS: return ACCUM_LOW_REGS; case ACCUM_OR_YBASE_REGS: return ACCUM_REGS; case X_OR_YBASE_REGS: return X_REG; case Y_OR_YBASE_REGS: return Y_REG; case ACCUM_LOW_YL_PL_OR_YBASE_REGS: return YL_OR_PL_OR_ACCUM_LOW_REGS; case P_OR_YBASE_REGS: return P_REG; case ACCUM_Y_P_OR_YBASE_REGS: return ACCUM_Y_OR_P_REGS; case Y_ADDR_OR_YBASE_REGS: return Y_ADDR_REGS; case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS: return NON_HIGH_YBASE_ELIGIBLE_REGS; case YBASE_OR_YBASE_ELIGIBLE_REGS: return YBASE_ELIGIBLE_REGS; case NO_HIGH_ALL_REGS: return NOHIGH_NON_YBASE_REGS; case ALL_REGS: return NON_YBASE_REGS; default: return class; } } else return class; } else return class;} /* Return the register class of a scratch register needed to copy IN into or out of a register in CLASS in MODE. If it can be done directly, NO_REGS is returned. */enum reg_classsecondary_reload_class (class, mode, in) enum reg_class class; enum machine_mode mode; rtx in;{ int regno = -1; if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG) regno = true_regnum (in); /* If we are reloading a plus into a high accumulator register, we need a scratch low accumulator, because the low half gets clobbered. */ if (class == ACCUM_HIGH_REGS || class == A1H_REG || class == A0H_REG) { if (GET_CODE (in) == PLUS && mode == QImode) return ACCUM_LOW_REGS; } if (class == ACCUM_HIGH_REGS || class == ACCUM_LOW_REGS || class == A1L_REG || class == A0L_REG || class == A1H_REG || class == A0H_REG) { if (GET_CODE (in) == PLUS && mode == QImode) { rtx addr0 = XEXP (in, 0); rtx addr1 = XEXP (in, 1); /* If we are reloading a plus (reg:QI) (reg:QI) we need an additional register. */ if (REG_P (addr0) && REG_P (addr1)) return NO_REGS; } } /* We can place anything into ACCUM_REGS and can put ACCUM_REGS into anything. */ if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS || class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG || class == A1H_REG || class == A1_REG) || (regno >= REG_A0 && regno < REG_A1L + 1)) return NO_REGS; if (class == ACCUM_OR_YBASE_REGS && REG_P(in) && IS_YBASE_ELIGIBLE_REG(regno)) { return NO_REGS; } /* We can copy the ybase registers into: r0-r3, a0-a1, y, p, & x or the union of any of these. */ if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno)) { switch ((int) class) { case (int) X_REG: case (int) X_OR_ACCUM_LOW_REGS: case (int) X_OR_ACCUM_REGS: case (int) YH_REG: case (int) YH_OR_ACCUM_HIGH_REGS: case (int) X_OR_YH_REGS: case (int) YL_REG: case (int) YL_OR_ACCUM_LOW_REGS: case (int) X_OR_Y_REGS: case (int) X_OR_YL_REGS: case (int) Y_REG: case (int) ACCUM_OR_Y_REGS: case (int) PH_REG: case (int) X_OR_PH_REGS: case (int) PL_REG: case (int) PL_OR_ACCUM_LOW_REGS: case (int) X_OR_PL_REGS: case (int) YL_OR_PL_OR_ACCUM_LOW_REGS: case (int) P_REG: case (int) ACCUM_OR_P_REGS: case (int) YL_OR_P_REGS: case (int) ACCUM_LOW_OR_YL_OR_P_REGS: case (int) Y_OR_P_REGS: case (int) ACCUM_Y_OR_P_REGS: case (int) Y_ADDR_REGS: case (int) ACCUM_LOW_OR_Y_ADDR_REGS: case (int) ACCUM_OR_Y_ADDR_REGS: case (int) X_OR_Y_ADDR_REGS: case (int) Y_OR_Y_ADDR_REGS: case (int) P_OR_Y_ADDR_REGS: case (int) YBASE_ELIGIBLE_REGS: return NO_REGS; default: return ACCUM_HIGH_REGS; } } /* We can copy r0-r3, a0-a1, y, & p directly to the ybase registers. In addition we can use any of the ybase virtual registers as the secondary reload registers when copying between any of these registers. */ if (!TARGET_RESERVE_YBASE && regno != -1) { switch (regno) { case REG_A0: case REG_A0L: case REG_A1: case REG_A1L: case REG_X: case REG_Y: case REG_YL: case REG_PROD: case REG_PRODL: case REG_R0: case REG_R1: case REG_R2: case REG_R3: if (class == YBASE_VIRT_REGS) return NO_REGS; else { switch ((int) class) { case (int) X_REG: case (int) X_OR_ACCUM_LOW_REGS: case (int) X_OR_ACCUM_REGS: case (int) YH_REG: case (int) YH_OR_ACCUM_HIGH_REGS: case (int) X_OR_YH_REGS: case (int) YL_REG: case (int) YL_OR_ACCUM_LOW_REGS: case (int) X_OR_Y_REGS: case (int) X_OR_YL_REGS: case (int) Y_REG: case (int) ACCUM_OR_Y_REGS: case (int) PH_REG: case (int) X_OR_PH_REGS: case (int) PL_REG: case (int) PL_OR_ACCUM_LOW_REGS: case (int) X_OR_PL_REGS: case (int) YL_OR_PL_OR_ACCUM_LOW_REGS: case (int) P_REG: case (int) ACCUM_OR_P_REGS: case (int) YL_OR_P_REGS: case (int) ACCUM_LOW_OR_YL_OR_P_REGS: case (int) Y_OR_P_REGS: case (int) ACCUM_Y_OR_P_REGS: case (int) Y_ADDR_REGS: case (int) ACCUM_LOW_OR_Y_ADDR_REGS: case (int) ACCUM_OR_Y_ADDR_REGS: case (int) X_OR_Y_ADDR_REGS: case (int) Y_OR_Y_ADDR_REGS: case (int) P_OR_Y_ADDR_REGS: case (int) YBASE_ELIGIBLE_REGS: return YBASE_VIRT_REGS; default: break; } } } } /* Memory or constants can be moved from or to any register except the ybase virtual registers. */ if (regno == -1 && GET_CODE(in) != PLUS) { if (class == YBASE_VIRT_REGS) return NON_YBASE_REGS; else return NO_REGS; } if (GET_CODE (in) == PLUS && mode == QImode) { rtx addr0 = XEXP (in, 0); rtx addr1 = XEXP (in, 1); /* If we are reloading a plus (reg:QI) (reg:QI) we need a low accumulator, not a high one. */ if (REG_P (addr0) && REG_P (addr1)) return ACCUM_LOW_REGS; }#if 0 if (REG_P(in)) return ACCUM_REGS;#endif /* Otherwise, we need a high accumulator(s). */ return ACCUM_HIGH_REGS;}intsymbolic_address_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (symbolic_address_p (op));}intsymbolic_address_p (op) rtx op;{ switch (GET_CODE (op)) { case SYMBOL_REF: case LABEL_REF: return 1; case CONST: op = XEXP (op, 0); return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF || GET_CODE (XEXP (op, 0)) == LABEL_REF) && GET_CODE (XEXP (op, 1)) == CONST_INT && INTVAL (XEXP (op,1)) < 0x20); default: return 0; }}/* For a Y address space operand we allow only *rn, *rn++, *rn--. This routine only recognizes *rn, the '<>' constraints recognize (*rn++), and (*rn--). */intY_address_operand (op, mode) rtx op; enum machine_mode mode;{ return (memory_address_p (mode, op) && !symbolic_address_p (op));} intsp_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == PLUS && (XEXP (op, 0) == stack_pointer_rtx || XEXP (op, 0) == frame_pointer_rtx) && GET_CODE (XEXP (op,1)) == CONST_INT);}intsp_operand2 (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if ((GET_CODE (op) == PLUS && (XEXP (op, 0) == stack_pointer_rtx || XEXP (op, 0) == frame_pointer_rtx) && (REG_P (XEXP (op,1)) && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1)))))) return 1; else if ((GET_CODE (op) == PLUS && (XEXP (op, 1) == stack_pointer_rtx || XEXP (op, 1) == frame_pointer_rtx) && (REG_P (XEXP (op,0)) && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1)))))) return 1; else return 0;}intnonmemory_arith_operand (op, mode) rtx op; enum machine_mode mode;{ return (immediate_operand (op, mode) || arith_reg_operand (op, mode));}intarith_reg_operand (op, mode) rtx op; enum machine_mode mode;{ return (register_operand (op, mode) && (GET_CODE (op) != REG || REGNO (op) >= FIRST_PSEUDO_REGISTER || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op))) && REGNO (op) != FRAME_POINTER_REGNUM)));}intcall_address_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ if (symbolic_address_p (op) || REG_P(op)) { return 1; } return 0;}intdsp16xx_comparison_operator (op, mode) register rtx op; enum machine_mode mode;{ return ((mode == VOIDmode || GET_MODE (op) == mode) && GET_RTX_CLASS (GET_CODE (op)) == '<' && (GET_CODE(op) != GE && GET_CODE (op) != LT && GET_CODE (op) != GEU && GET_CODE (op) != LTU));}voidnotice_update_cc(exp) rtx exp;{ if (GET_CODE (exp) == SET) { /* Jumps do not alter the cc's. */ if (SET_DEST (exp) == pc_rtx) return; /* Moving register or memory into a register: it doesn't alter the cc's, but it might invalidate the RTX's which we remember the cc's came from. (Note that moving a constant 0 or 1 MAY set the cc's). */ if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM)) { if (cc_status.value1 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)) cc_status.value1 = 0; if (cc_status.value2 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2)) cc_status.value2 = 0; return; } /* Moving register into memory doesn't alter the cc's. It may invalidate the RTX's which we remember the cc's came from. */ if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp))) { if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM) cc_status.value1 = 0; if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM) cc_status.value2 = 0; return; } /* Function calls clobber the cc's. */ else if (GET_CODE (SET_SRC (exp)) == CALL) { CC_STATUS_INIT; return; } /* Tests and compares set the cc's in predictable ways. */ else if (SET_DEST (exp) == cc0_rtx) { CC_STATUS_INIT; cc_status.value1 = SET_SRC (exp); return; } /* Certain instructions effect the condition codes. */ else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT) switch (GET_CODE (SET_SRC (exp))) { case PLUS: case MINUS: if (REG_P (SET_DEST (exp))) { /* Address registers don't set the condition codes. */ if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp)))) { CC_STATUS_INIT; break; } } case ASHIFTRT: case LSHIFTRT: case ASHIFT: case AND: case IOR: case XOR: case MULT: case NEG: case NOT: cc_status.value1 = SET_SRC (exp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -