+2018-12-11 Dimitar Dimitrov <dimitar@dinux.eu>
+
+ * cfgexpand.c (asm_clobber_reg_is_valid): Also produce
+ error when stack pointer is clobbered.
+ (expand_asm_stmt): Refactor clobber check in separate function.
+
2018-12-11 Eric Botcazou <botcazou@adacore.com>
* config/rs6000/vxworks.h (RS6000_STARTING_FRAME_OFFSET): Define,
return false;
}
+/* Check that the given REGNO spanning NREGS is a valid
+ asm clobber operand. Some HW registers cannot be
+ saved/restored, hence they should not be clobbered by
+ asm statements. */
+static bool
+asm_clobber_reg_is_valid (int regno, int nregs, const char *regname)
+{
+ bool is_valid = true;
+ HARD_REG_SET regset;
+
+ CLEAR_HARD_REG_SET (regset);
+
+ add_range_to_hard_reg_set (®set, regno, nregs);
+
+ /* Clobbering the PIC register is an error. */
+ if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+ && overlaps_hard_reg_set_p (regset, Pmode, PIC_OFFSET_TABLE_REGNUM))
+ {
+ /* ??? Diagnose during gimplification? */
+ error ("PIC register clobbered by %qs in %<asm%>", regname);
+ is_valid = false;
+ }
+ /* Clobbering the STACK POINTER register is an error. */
+ if (overlaps_hard_reg_set_p (regset, Pmode, STACK_POINTER_REGNUM))
+ {
+ error ("Stack Pointer register clobbered by %qs in %<asm%>", regname);
+ is_valid = false;
+ }
+
+ return is_valid;
+}
+
/* Generate RTL for an asm statement with arguments.
STRING is the instruction template.
OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
else
for (int reg = j; reg < j + nregs; reg++)
{
- /* Clobbering the PIC register is an error. */
- if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
- {
- /* ??? Diagnose during gimplification? */
- error ("PIC register clobbered by %qs in %<asm%>",
- regname);
- return;
- }
+ if (!asm_clobber_reg_is_valid (reg, nregs, regname))
+ return;
SET_HARD_REG_BIT (clobbered_regs, reg);
rtx x = gen_rtx_REG (reg_raw_mode[reg], reg);