📄 m68hc11.c
字号:
{ printf ("Class = %s for: ", reg_class_names[class]); fflush (stdout); debug_rtx (operand); } } if (debug_m6811) { printf (" => class=%s\n", reg_class_names[class]); fflush (stdout); debug_rtx (operand); } return class;}/* Return 1 if the operand is a valid indexed addressing mode. For 68hc11: n,r with n in [0..255] and r in A_REGS class For 68hc12: n,r no constraint on the constant, r in A_REGS class. */static intregister_indirect_p (operand, mode, strict) rtx operand; enum machine_mode mode; int strict;{ rtx base, offset; switch (GET_CODE (operand)) { case POST_INC: case PRE_INC: case POST_DEC: case PRE_DEC: if (TARGET_M6812 && TARGET_AUTO_INC_DEC) return register_indirect_p (XEXP (operand, 0), mode, strict); return 0; case PLUS: base = XEXP (operand, 0); if (GET_CODE (base) == MEM) return 0; offset = XEXP (operand, 1); if (GET_CODE (offset) == MEM) return 0; if (GET_CODE (base) == REG) { if (!VALID_CONSTANT_OFFSET_P (offset, mode)) return 0; if (strict == 0) return 1; return REGNO_OK_FOR_BASE_P2 (REGNO (base), strict); } if (GET_CODE (offset) == REG) { if (!VALID_CONSTANT_OFFSET_P (base, mode)) return 0; if (strict == 0) return 1; return REGNO_OK_FOR_BASE_P2 (REGNO (offset), strict); } return 0; case REG: return REGNO_OK_FOR_BASE_P2 (REGNO (operand), strict); case CONST_INT: if (TARGET_M6811) return 0; return VALID_CONSTANT_OFFSET_P (operand, mode); default: return 0; }}/* Returns 1 if the operand fits in a 68HC11 indirect mode or in a 68HC12 1-byte index addressing mode. */intm68hc11_small_indexed_indirect_p (operand, mode) rtx operand; enum machine_mode mode;{ rtx base, offset; if (GET_CODE (operand) == REG && reload_in_progress && REGNO (operand) >= FIRST_PSEUDO_REGISTER && reg_equiv_memory_loc[REGNO (operand)]) { operand = reg_equiv_memory_loc[REGNO (operand)]; operand = eliminate_regs (operand, 0, NULL_RTX); } if (GET_CODE (operand) != MEM) return 0; operand = XEXP (operand, 0); if (CONSTANT_ADDRESS_P (operand)) return 1; if (PUSH_POP_ADDRESS_P (operand)) return 1; if (!register_indirect_p (operand, mode, reload_completed)) return 0; if (TARGET_M6812 && GET_CODE (operand) == PLUS && (reload_completed | reload_in_progress)) { base = XEXP (operand, 0); offset = XEXP (operand, 1); /* The offset can be a symbol address and this is too big for the operand constraint. */ if (GET_CODE (base) != CONST_INT && GET_CODE (offset) != CONST_INT) return 0; if (GET_CODE (base) == CONST_INT) offset = base; switch (GET_MODE_SIZE (mode)) { case 8: if (INTVAL (offset) < -16 + 6 || INTVAL (offset) > 15 - 6) return 0; break; case 4: if (INTVAL (offset) < -16 + 2 || INTVAL (offset) > 15 - 2) return 0; break; default: if (INTVAL (offset) < -16 || INTVAL (offset) > 15) return 0; break; } } return 1;}intm68hc11_register_indirect_p (operand, mode) rtx operand; enum machine_mode mode;{ if (GET_CODE (operand) != MEM) return 0; operand = XEXP (operand, 0); return register_indirect_p (operand, mode, (reload_completed | reload_in_progress));}static intgo_if_legitimate_address_internal (operand, mode, strict) rtx operand; enum machine_mode mode; int strict;{ if (CONSTANT_ADDRESS_P (operand) && TARGET_M6812) { /* Reject the global variables if they are too wide. This forces a load of their address in a register and generates smaller code. */ if (GET_MODE_SIZE (mode) == 8) return 0; return 1; } if (register_indirect_p (operand, mode, strict)) { return 1; } if (PUSH_POP_ADDRESS_P (operand)) { return 1; } if (symbolic_memory_operand (operand, mode)) { return 1; } return 0;}intm68hc11_go_if_legitimate_address (operand, mode, strict) rtx operand; enum machine_mode mode; int strict;{ int result; if (debug_m6811) { printf ("Checking: "); fflush (stdout); debug_rtx (operand); } result = go_if_legitimate_address_internal (operand, mode, strict); if (debug_m6811) { printf (" -> %s\n", result == 0 ? "NO" : "YES"); } if (result == 0) { if (debug_m6811) { printf ("go_if_legitimate%s, ret 0: %d:", (strict ? "_strict" : ""), mode); fflush (stdout); debug_rtx (operand); } } return result;}intm68hc11_legitimize_address (operand, old_operand, mode) rtx *operand ATTRIBUTE_UNUSED; rtx old_operand ATTRIBUTE_UNUSED; enum machine_mode mode ATTRIBUTE_UNUSED;{ return 0;}intm68hc11_reload_operands (operands) rtx operands[];{ enum machine_mode mode; if (regs_inited == 0) create_regs_rtx (); mode = GET_MODE (operands[1]); /* Input reload of indirect addressing (MEM (PLUS (REG) (CONST))). */ if (A_REG_P (operands[0]) && memory_reload_operand (operands[1], mode)) { rtx big_offset = XEXP (XEXP (operands[1], 0), 1); rtx base = XEXP (XEXP (operands[1], 0), 0); if (GET_CODE (base) != REG) { rtx tmp = base; base = big_offset; big_offset = tmp; } /* If the offset is out of range, we have to compute the address with a separate add instruction. We try to do with with an 8-bit add on the A register. This is possible only if the lowest part of the offset (ie, big_offset % 256) is a valid constant offset with respect to the mode. If it's not, we have to generate a 16-bit add on the D register. From: (SET (REG X (MEM (PLUS (REG X) (CONST_INT 1000))))) we generate: [(SET (REG D) (REG X)) (SET (REG X) (REG D))] (SET (REG A) (PLUS (REG A) (CONST_INT 1000 / 256))) [(SET (REG D) (REG X)) (SET (REG X) (REG D))] (SET (REG X) (MEM (PLUS (REG X) (CONST_INT 1000 % 256))) (SET (REG X) (PLUS (REG X) (CONST_INT 1000 / 256 * 256))) (SET (REG X) (MEM (PLUS (REG X) (CONST_INT 1000 % 256)))) */ if (!VALID_CONSTANT_OFFSET_P (big_offset, mode)) { int vh, vl; rtx reg = operands[0]; rtx offset; int val = INTVAL (big_offset); /* We use the 'operands[0]' as a scratch register to compute the address. Make sure 'base' is in that register. */ if (!rtx_equal_p (base, operands[0])) { emit_move_insn (reg, base); } if (val > 0) { vh = val >> 8; vl = val & 0x0FF; } else { vh = (val >> 8) & 0x0FF; vl = val & 0x0FF; } /* Create the lowest part offset that still remains to be added. If it's not a valid offset, do a 16-bit add. */ offset = GEN_INT (vl); if (!VALID_CONSTANT_OFFSET_P (offset, mode)) { emit_insn (gen_rtx (SET, VOIDmode, reg, gen_rtx (PLUS, HImode, reg, big_offset))); offset = const0_rtx; } else { emit_insn (gen_rtx (SET, VOIDmode, reg, gen_rtx (PLUS, HImode, reg, GEN_INT (vh << 8)))); } emit_move_insn (operands[0], gen_rtx (MEM, GET_MODE (operands[1]), gen_rtx (PLUS, Pmode, reg, offset))); return 1; } } /* Use the normal gen_movhi pattern. */ return 0;}voidm68hc11_emit_libcall (name, code, dmode, smode, noperands, operands) const char *name; enum rtx_code code; enum machine_mode dmode; enum machine_mode smode; int noperands; rtx *operands;{ rtx ret; rtx insns; rtx libcall; rtx equiv; start_sequence (); libcall = gen_rtx_SYMBOL_REF (Pmode, name); switch (noperands) { case 2: ret = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, dmode, 1, operands[1], smode); equiv = gen_rtx (code, dmode, operands[1]); break; case 3: ret = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, dmode, 2, operands[1], smode, operands[2], smode); equiv = gen_rtx (code, dmode, operands[1], operands[2]); break; default: abort (); } insns = get_insns (); end_sequence (); emit_libcall_block (insns, operands[0], ret, equiv);}/* Returns true if X is a PRE/POST increment decrement (same as auto_inc_p() in rtlanal.c but do not take into account the stack). */static intm68hc11_auto_inc_p (x) rtx x;{ return GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC || GET_CODE (x) == PRE_INC;}/* Predicates for machine description. */intmemory_reload_operand (operand, mode) rtx operand; enum machine_mode mode ATTRIBUTE_UNUSED;{ return GET_CODE (operand) == MEM && GET_CODE (XEXP (operand, 0)) == PLUS && ((GET_CODE (XEXP (XEXP (operand, 0), 0)) == REG && GET_CODE (XEXP (XEXP (operand, 0), 1)) == CONST_INT) || (GET_CODE (XEXP (XEXP (operand, 0), 1)) == REG && GET_CODE (XEXP (XEXP (operand, 0), 0)) == CONST_INT));}inttst_operand (operand, mode) rtx operand; enum machine_mode mode;{ if (GET_CODE (operand) == MEM && reload_completed == 0) { rtx addr = XEXP (operand, 0); if (m68hc11_auto_inc_p (addr)) return 0; } return nonimmediate_operand (operand, mode);}intcmp_operand (operand, mode) rtx operand; enum machine_mode mode;{ if (GET_CODE (operand) == MEM) { rtx addr = XEXP (operand, 0); if (m68hc11_auto_inc_p (addr)) return 0; } return general_operand (operand, mode);}intnon_push_operand (operand, mode) rtx operand; enum machine_mode mode;{ if (general_operand (operand, mode) == 0) return 0; if (push_operand (operand, mode) == 1) return 0; return 1;}intreg_or_some_mem_operand (operand, mode) rtx operand; enum machine_mode mode;{ if (GET_CODE (operand) == MEM) { rtx op = XEXP (operand, 0); if (symbolic_memory_operand (op, mode)) return 1; if (IS_STACK_PUSH (operand)) return 1; if (m68hc11_register_indirect_p (operand, mode)) return 1; return 0; } return register_operand (operand, mode);}intm68hc11_symbolic_p (operand, mode) rtx operand; enum machine_mode mode;{ if (GET_CODE (operand) == MEM) { rtx op = XEXP (operand, 0); if (symbolic_memory_operand (op, mode)) return 1; } return 0;}intm68hc11_indirect_p (operand, mode) rtx operand; enum machine_mode mode;{ if (GET_CODE (operand) == MEM) { rtx op = XEXP (operand, 0); if (symbolic_memory_operand (op, mode)) return 0; if (reload_in_progress) return 1; operand = XEXP (operand, 0); return register_indirect_p (operand, mode, reload_completed); } return 0;}int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -