static void h8300_emit_stack_adjustment (int, HOST_WIDE_INT, bool);
static HOST_WIDE_INT round_frame_size (HOST_WIDE_INT);
static unsigned int compute_saved_regs (void);
-static void push (int);
-static void pop (int);
static const char *cond_string (enum rtx_code);
static unsigned int h8300_asm_insn_count (const char *);
static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
/* Emit an insn to push register RN. */
-static void
+static rtx
push (int rn)
{
rtx reg = gen_rtx_REG (word_mode, rn);
x = gen_push_h8300hs_normal (reg);
x = F (emit_insn (x), true);
add_reg_note (x, REG_INC, stack_pointer_rtx);
+ return x;
}
/* Emit an insn to pop register RN. */
-static void
+static rtx
pop (int rn)
{
rtx reg = gen_rtx_REG (word_mode, rn);
x = gen_pop_h8300hs_normal (reg);
x = emit_insn (x);
add_reg_note (x, REG_INC, stack_pointer_rtx);
+ return x;
}
/* Emit an instruction to push or pop NREGS consecutive registers
void
h8300_swap_into_er6 (rtx addr)
{
- push (HARD_FRAME_POINTER_REGNUM);
+ rtx insn = push (HARD_FRAME_POINTER_REGNUM);
+ if (frame_pointer_needed)
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (gen_rtx_MEM (Pmode, stack_pointer_rtx),
+ 2 * UNITS_PER_WORD));
+ else
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx, 4)));
+
emit_move_insn (hard_frame_pointer_rtx, addr);
if (REGNO (addr) == SP_REG)
emit_move_insn (hard_frame_pointer_rtx,
void
h8300_swap_out_of_er6 (rtx addr)
{
+ rtx insn;
+
if (REGNO (addr) != SP_REG)
emit_move_insn (addr, hard_frame_pointer_rtx);
- pop (HARD_FRAME_POINTER_REGNUM);
+
+ insn = pop (HARD_FRAME_POINTER_REGNUM);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ if (frame_pointer_needed)
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (hard_frame_pointer_rtx, 2 * UNITS_PER_WORD));
+ else
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx, -4)));
}
\f
/* Return the length of mov instruction. */
if (cfi)
{
cur_row->cfa = *new_cfa;
- if (cfi->dw_cfi_opc == DW_CFA_def_cfa_expression)
- cur_row->cfa_cfi = cfi;
+ cur_row->cfa_cfi = (cfi->dw_cfi_opc == DW_CFA_def_cfa_expression
+ ? cfi : NULL);
add_cfi (cfi);
}
memset (&loc, 0, sizeof (loc));
- switch (GET_CODE (pat))
+ if (GET_CODE (pat) == PLUS)
{
- case PLUS:
- loc.reg = dwf_regno (XEXP (pat, 0));
loc.offset = INTVAL (XEXP (pat, 1));
- break;
-
- case REG:
- loc.reg = dwf_regno (pat);
- break;
-
- case MEM:
+ pat = XEXP (pat, 0);
+ }
+ if (MEM_P (pat))
+ {
loc.indirect = 1;
pat = XEXP (pat, 0);
if (GET_CODE (pat) == PLUS)
loc.base_offset = INTVAL (XEXP (pat, 1));
pat = XEXP (pat, 0);
}
- loc.reg = dwf_regno (pat);
- break;
-
- default:
- /* Recurse and define an expression. */
- gcc_unreachable ();
}
+ /* ??? If this fails, we could be calling into the _loc functions to
+ define a full expression. So far no port does that. */
+ gcc_assert (REG_P (pat));
+ loc.reg = dwf_regno (pat);
def_cfa_1 (&loc);
}