On 09/21/11 19:33, Richard Henderson wrote: > Why, then, is this the only place in dwarf2cfi that needs to handle > registers via a loop over nregs? It seems to me that we should either > be handling multi-register spans everywhere or nowhere. > > Because alternately, this could be a bug in your backend that you > failed to add two RESTORE notes instead of just one...
Well, changing the backend works too. Patch below. Bernd
* mips.c (mips_restore_reg): Split multiword registers for REG_CFA_RESTORE notes. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (revision 178847) +++ gcc/config/mips/mips.c (working copy) @@ -10286,16 +10286,28 @@ mips_epilogue_set_cfa (rtx reg, HOST_WID static void mips_restore_reg (rtx reg, rtx mem) { + enum machine_mode mode = GET_MODE (reg); + unsigned regno = REGNO (reg); + /* There's no MIPS16 instruction to load $31 directly. Load into $7 instead and adjust the return insn appropriately. */ - if (TARGET_MIPS16 && REGNO (reg) == RETURN_ADDR_REGNUM) - reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7); + if (TARGET_MIPS16 && regno == RETURN_ADDR_REGNUM) + reg = gen_rtx_REG (mode, GP_REG_FIRST + 7); + else if (GET_MODE_SIZE (mode) != 8 || !mips_split_64bit_move_p (reg, mem)) + mips_epilogue.cfa_restores + = alloc_reg_note (REG_CFA_RESTORE, reg, mips_epilogue.cfa_restores); else - mips_epilogue.cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, - mips_epilogue.cfa_restores); + { + rtx word1 = mips_subword (reg, true); + rtx word2 = mips_subword (reg, false); + mips_epilogue.cfa_restores + = alloc_reg_note (REG_CFA_RESTORE, word1, mips_epilogue.cfa_restores); + mips_epilogue.cfa_restores + = alloc_reg_note (REG_CFA_RESTORE, word2, mips_epilogue.cfa_restores); + } - mips_emit_save_slot_move (reg, mem, MIPS_EPILOGUE_TEMP (GET_MODE (reg))); - if (REGNO (reg) == REGNO (mips_epilogue.cfa_reg)) + mips_emit_save_slot_move (reg, mem, MIPS_EPILOGUE_TEMP (mode)); + if (regno == REGNO (mips_epilogue.cfa_reg)) /* The CFA is currently defined in terms of the register whose value we have just restored. Redefine the CFA in terms of the stack pointer. */