Commit e19da24c by Chao-ying Fu Committed by Chao-ying Fu

mips.c (mips_frame_info): Add acc_mask...

2009-04-02  Chao-ying Fu  <fu@mips.com>
	    James Grosbach <james.grosbach@microchip.com>

	* config/mips/mips.c (mips_frame_info): Add acc_mask, num_acc,
	num_cop0_regs, acc_save_offset, cop0_save_offset, acc_sp_offset,
	cop0_sp_offset.
	(machine_function): Add interrupt_handler_p, use_shadow_register_set_p,
	keep_interrupts_masked_p, use_debug_exception_return_p.
	(mips_attribute_table): Add interrupt, use_shadow_register_set,
	keep_interrupts_masked, use_debug_exception_return.
	(mips_interrupt_type_p, mips_use_shadow_register_set_p,
	mips_keep_interrupts_masked_p, mips_use_debug_exception_return_p):
	New functions.
	(mips_function_ok_for_sibcall): Return false for interrupt handlers.
	(mips_print_operand): Process COP0 registers to print $0 .. $31
	correctly for GAS to process.
	(mips_interrupt_extra_call_saved_reg_p): New function.
	(mips_cfun_call_saved_reg_p): For interrupt handlers, we need to check
	extra registers.
	(mips_cfun_might_clobber_call_saved_reg_p): Likewise.
	(mips_compute_frame_info): Add supports for interrupt context that
	includes doubleword accumulators and COP0 registers.
	(mips_for_each_saved_acc): New function.
	(mips_for_each_saved_gpr_and_fpr): Change the function name from
	mips_for_each_saved_reg.
	(mips_save_reg): Save accumulators.
	(mips_kernel_reg_p): A new for_each_rtx callback.
	(mips_expand_prologue): Support interrupt handlers.
	(mips_restore_reg): Restore accumulators.
	(mips_expand_epilogue): Support interrupt handlers.
	(mips_can_use_return_insn): Return false for interrupt handlers.
	(mips_epilogue_uses): New function.
	* config/mips/mips.md (UNSPEC_ERET, UNSPEC_DERET, UNSPEC_DI,
	UNSPEC_EHB, UNSPEC_RDPGPR, UNSPEC_COP0): New UNSPEC.
	(mips_eret, mips_deret, mips_di, mips_ehb, mips_rdpgpr,
	cop0_move): New instructions.
	* config/mips/mips-protos.h (mips_epilogue_uses): Declare.
	* config/mips/mips.h (K0_REG_NUM, K1_REG_NUM, KERNEL_REG_P): New
	defines.
	(COP0_STATUS_REG_NUM, COP0_CAUSE_REG_NUM, COP0_EPC_REG_NUM):
	New defines.
	(CAUSE_IPL, SR_IPL, SR_EXL, SR_IE): New defines.
	(MIPS_PROLOGUE_TEMP_REGNUM, MIPS_EPILOGUE_TEMP_REGNUM): For
	interrupt handlers, we use K0 as the temporary register.
	(EPILOGUE_USES): Change to a function call.
	* config/mips/sde.h (MIPS_EPILOGUE_TEMP_REGNUM): For interrupt
	handlers, we use K0 as the temporary register.

	* doc/extend.texi (Function Attributes): Document interrupt,
	use_shadow_register_set, keep_interrupts_masked,
	use_debug_exception_return for MIPS attributes.

Co-Authored-By: James Grosbach <james.grosbach@microchip.com>

From-SVN: r145481
parent 608f7b2e
2009-04-02 Chao-ying Fu <fu@mips.com>
James Grosbach <james.grosbach@microchip.com>
* config/mips/mips.c (mips_frame_info): Add acc_mask, num_acc,
num_cop0_regs, acc_save_offset, cop0_save_offset, acc_sp_offset,
cop0_sp_offset.
(machine_function): Add interrupt_handler_p, use_shadow_register_set_p,
keep_interrupts_masked_p, use_debug_exception_return_p.
(mips_attribute_table): Add interrupt, use_shadow_register_set,
keep_interrupts_masked, use_debug_exception_return.
(mips_interrupt_type_p, mips_use_shadow_register_set_p,
mips_keep_interrupts_masked_p, mips_use_debug_exception_return_p):
New functions.
(mips_function_ok_for_sibcall): Return false for interrupt handlers.
(mips_print_operand): Process COP0 registers to print $0 .. $31
correctly for GAS to process.
(mips_interrupt_extra_call_saved_reg_p): New function.
(mips_cfun_call_saved_reg_p): For interrupt handlers, we need to check
extra registers.
(mips_cfun_might_clobber_call_saved_reg_p): Likewise.
(mips_compute_frame_info): Add supports for interrupt context that
includes doubleword accumulators and COP0 registers.
(mips_for_each_saved_acc): New function.
(mips_for_each_saved_gpr_and_fpr): Change the function name from
mips_for_each_saved_reg.
(mips_save_reg): Save accumulators.
(mips_kernel_reg_p): A new for_each_rtx callback.
(mips_expand_prologue): Support interrupt handlers.
(mips_restore_reg): Restore accumulators.
(mips_expand_epilogue): Support interrupt handlers.
(mips_can_use_return_insn): Return false for interrupt handlers.
(mips_epilogue_uses): New function.
* config/mips/mips.md (UNSPEC_ERET, UNSPEC_DERET, UNSPEC_DI,
UNSPEC_EHB, UNSPEC_RDPGPR, UNSPEC_COP0): New UNSPEC.
(mips_eret, mips_deret, mips_di, mips_ehb, mips_rdpgpr,
cop0_move): New instructions.
* config/mips/mips-protos.h (mips_epilogue_uses): Declare.
* config/mips/mips.h (K0_REG_NUM, K1_REG_NUM, KERNEL_REG_P): New
defines.
(COP0_STATUS_REG_NUM, COP0_CAUSE_REG_NUM, COP0_EPC_REG_NUM):
New defines.
(CAUSE_IPL, SR_IPL, SR_EXL, SR_IE): New defines.
(MIPS_PROLOGUE_TEMP_REGNUM, MIPS_EPILOGUE_TEMP_REGNUM): For
interrupt handlers, we use K0 as the temporary register.
(EPILOGUE_USES): Change to a function call.
* config/mips/sde.h (MIPS_EPILOGUE_TEMP_REGNUM): For interrupt
handlers, we use K0 as the temporary register.
* doc/extend.texi (Function Attributes): Document interrupt,
use_shadow_register_set, keep_interrupts_masked,
use_debug_exception_return for MIPS attributes.
2009-04-03 Alan Modra <amodra@bigpond.net.au> 2009-04-03 Alan Modra <amodra@bigpond.net.au>
* config.gcc (powerpc64-*-gnu*): Add rs6000/default64.h to tm_file. * config.gcc (powerpc64-*-gnu*): Add rs6000/default64.h to tm_file.
......
...@@ -332,4 +332,6 @@ extern void mips_expand_atomic_qihi (union mips_gen_fn_ptrs, ...@@ -332,4 +332,6 @@ extern void mips_expand_atomic_qihi (union mips_gen_fn_ptrs,
extern void mips_expand_vector_init (rtx, rtx); extern void mips_expand_vector_init (rtx, rtx);
extern bool mips_epilogue_uses (unsigned int);
#endif /* ! GCC_MIPS_PROTOS_H */ #endif /* ! GCC_MIPS_PROTOS_H */
...@@ -1622,6 +1622,9 @@ enum mips_code_readable_setting { ...@@ -1622,6 +1622,9 @@ enum mips_code_readable_setting {
#define GP_REG_LAST 31 #define GP_REG_LAST 31
#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1) #define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1)
#define GP_DBX_FIRST 0 #define GP_DBX_FIRST 0
#define K0_REG_NUM (GP_REG_FIRST + 26)
#define K1_REG_NUM (GP_REG_FIRST + 27)
#define KERNEL_REG_P(REGNO) (IN_RANGE (REGNO, K0_REG_NUM, K1_REG_NUM))
#define FP_REG_FIRST 32 #define FP_REG_FIRST 32
#define FP_REG_LAST 63 #define FP_REG_LAST 63
...@@ -1649,6 +1652,10 @@ enum mips_code_readable_setting { ...@@ -1649,6 +1652,10 @@ enum mips_code_readable_setting {
#define COP0_REG_LAST 111 #define COP0_REG_LAST 111
#define COP0_REG_NUM (COP0_REG_LAST - COP0_REG_FIRST + 1) #define COP0_REG_NUM (COP0_REG_LAST - COP0_REG_FIRST + 1)
#define COP0_STATUS_REG_NUM (COP0_REG_FIRST + 12)
#define COP0_CAUSE_REG_NUM (COP0_REG_FIRST + 13)
#define COP0_EPC_REG_NUM (COP0_REG_FIRST + 14)
#define COP2_REG_FIRST 112 #define COP2_REG_FIRST 112
#define COP2_REG_LAST 143 #define COP2_REG_LAST 143
#define COP2_REG_NUM (COP2_REG_LAST - COP2_REG_FIRST + 1) #define COP2_REG_NUM (COP2_REG_LAST - COP2_REG_FIRST + 1)
...@@ -1667,6 +1674,17 @@ enum mips_code_readable_setting { ...@@ -1667,6 +1674,17 @@ enum mips_code_readable_setting {
#define HI_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1) #define HI_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1)
#define LO_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST) #define LO_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST)
/* A few bitfield locations for the coprocessor registers. */
/* Request Interrupt Priority Level is from bit 10 to bit 15 of
the cause register for the EIC interrupt mode. */
#define CAUSE_IPL 10
/* Interrupt Priority Level is from bit 10 to bit 15 of the status register. */
#define SR_IPL 10
/* Exception Level is at bit 1 of the status register. */
#define SR_EXL 1
/* Interrupt Enable is at bit 0 of the status register. */
#define SR_IE 0
/* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC. /* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC.
If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG
should be used instead. */ should be used instead. */
...@@ -1754,11 +1772,18 @@ enum mips_code_readable_setting { ...@@ -1754,11 +1772,18 @@ enum mips_code_readable_setting {
incoming arguments, the static chain pointer, or the frame pointer. incoming arguments, the static chain pointer, or the frame pointer.
The epilogue temporary mustn't conflict with the return registers, The epilogue temporary mustn't conflict with the return registers,
the PIC call register ($25), the frame pointer, the EH stack adjustment, the PIC call register ($25), the frame pointer, the EH stack adjustment,
or the EH data registers. */ or the EH data registers.
If we're generating interrupt handlers, we use K0 as a temporary register
in prologue/epilogue code. */
#define MIPS16_PIC_TEMP_REGNUM (GP_REG_FIRST + 2) #define MIPS16_PIC_TEMP_REGNUM (GP_REG_FIRST + 2)
#define MIPS_PROLOGUE_TEMP_REGNUM (GP_REG_FIRST + 3) #define MIPS_PROLOGUE_TEMP_REGNUM \
#define MIPS_EPILOGUE_TEMP_REGNUM (GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8)) (cfun->machine->interrupt_handler_p ? K0_REG_NUM : GP_REG_FIRST + 3)
#define MIPS_EPILOGUE_TEMP_REGNUM \
(cfun->machine->interrupt_handler_p \
? K0_REG_NUM \
: GP_REG_FIRST + (TARGET_MIPS16 ? 6 : 8))
#define MIPS16_PIC_TEMP gen_rtx_REG (Pmode, MIPS16_PIC_TEMP_REGNUM) #define MIPS16_PIC_TEMP gen_rtx_REG (Pmode, MIPS16_PIC_TEMP_REGNUM)
#define MIPS_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, MIPS_PROLOGUE_TEMP_REGNUM) #define MIPS_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, MIPS_PROLOGUE_TEMP_REGNUM)
...@@ -2284,14 +2309,7 @@ typedef struct mips_args { ...@@ -2284,14 +2309,7 @@ typedef struct mips_args {
(mips_abi == ABI_EABI && UNITS_PER_FPVALUE >= UNITS_PER_DOUBLE) (mips_abi == ABI_EABI && UNITS_PER_FPVALUE >= UNITS_PER_DOUBLE)
/* Say that the epilogue uses the return address register. Note that #define EPILOGUE_USES(REGNO) mips_epilogue_uses (REGNO)
in the case of sibcalls, the values "used by the epilogue" are
considered live at the start of the called function.
If using a GOT, say that the epilogue also uses GOT_VERSION_REGNUM.
See the comment above load_call<mode> for details. */
#define EPILOGUE_USES(REGNO) \
((REGNO) == 31 || (TARGET_USE_GOT && (REGNO) == GOT_VERSION_REGNUM))
/* Treat LOC as a byte offset from the stack pointer and round it up /* Treat LOC as a byte offset from the stack pointer and round it up
to the next fully-aligned offset. */ to the next fully-aligned offset. */
......
...@@ -67,6 +67,12 @@ ...@@ -67,6 +67,12 @@
(UNSPEC_SET_GOT_VERSION 46) (UNSPEC_SET_GOT_VERSION 46)
(UNSPEC_UPDATE_GOT_VERSION 47) (UNSPEC_UPDATE_GOT_VERSION 47)
(UNSPEC_COPYGP 48) (UNSPEC_COPYGP 48)
(UNSPEC_ERET 49)
(UNSPEC_DERET 50)
(UNSPEC_DI 51)
(UNSPEC_EHB 52)
(UNSPEC_RDPGPR 53)
(UNSPEC_COP0 54)
(UNSPEC_ADDRESS_FIRST 100) (UNSPEC_ADDRESS_FIRST 100)
...@@ -5679,6 +5685,60 @@ ...@@ -5679,6 +5685,60 @@
[(set_attr "type" "jump") [(set_attr "type" "jump")
(set_attr "mode" "none")]) (set_attr "mode" "none")])
;; Exception return.
(define_insn "mips_eret"
[(return)
(unspec_volatile [(const_int 0)] UNSPEC_ERET)]
""
"eret"
[(set_attr "type" "trap")
(set_attr "mode" "none")])
;; Debug exception return.
(define_insn "mips_deret"
[(return)
(unspec_volatile [(const_int 0)] UNSPEC_DERET)]
""
"deret"
[(set_attr "type" "trap")
(set_attr "mode" "none")])
;; Disable interrupts.
(define_insn "mips_di"
[(unspec_volatile [(const_int 0)] UNSPEC_DI)]
""
"di"
[(set_attr "type" "trap")
(set_attr "mode" "none")])
;; Execution hazard barrier.
(define_insn "mips_ehb"
[(unspec_volatile [(const_int 0)] UNSPEC_EHB)]
""
"ehb"
[(set_attr "type" "trap")
(set_attr "mode" "none")])
;; Read GPR from previous shadow register set.
(define_insn "mips_rdpgpr"
[(set (match_operand:SI 0 "register_operand" "=d")
(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")]
UNSPEC_RDPGPR))]
""
"rdpgpr\t%0,%1"
[(set_attr "type" "move")
(set_attr "mode" "SI")])
;; Move involving COP0 registers.
(define_insn "cop0_move"
[(set (match_operand:SI 0 "register_operand" "=B,d")
(unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")]
UNSPEC_COP0))]
""
{ return mips_output_move (operands[0], operands[1]); }
[(set_attr "type" "mtc,mfc")
(set_attr "mode" "SI")])
;; This is used in compiling the unwind routines. ;; This is used in compiling the unwind routines.
(define_expand "eh_return" (define_expand "eh_return"
[(use (match_operand 0 "general_operand"))] [(use (match_operand 0 "general_operand"))]
......
...@@ -90,7 +90,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -90,7 +90,8 @@ along with GCC; see the file COPYING3. If not see
/* Use $5 as a temporary for both MIPS16 and non-MIPS16. */ /* Use $5 as a temporary for both MIPS16 and non-MIPS16. */
#undef MIPS_EPILOGUE_TEMP_REGNUM #undef MIPS_EPILOGUE_TEMP_REGNUM
#define MIPS_EPILOGUE_TEMP_REGNUM (GP_REG_FIRST + 5) #define MIPS_EPILOGUE_TEMP_REGNUM \
(cfun->machine->interrupt_handler_p ? K0_REG_NUM : GP_REG_FIRST + 5)
/* Using long will always be right for size_t and ptrdiff_t, since /* Using long will always be right for size_t and ptrdiff_t, since
sizeof(long) must equal sizeof(void *), following from the setting sizeof(long) must equal sizeof(void *), following from the setting
......
...@@ -2402,7 +2402,7 @@ This attribute is ignored for R8C target. ...@@ -2402,7 +2402,7 @@ This attribute is ignored for R8C target.
@item interrupt @item interrupt
@cindex interrupt handler functions @cindex interrupt handler functions
Use this attribute on the ARM, AVR, CRX, M32C, M32R/D, m68k, Use this attribute on the ARM, AVR, CRX, M32C, M32R/D, m68k, MIPS
and Xstormy16 ports to indicate that the specified function is an and Xstormy16 ports to indicate that the specified function is an
interrupt handler. The compiler will generate function entry and exit interrupt handler. The compiler will generate function entry and exit
sequences suitable for use in an interrupt handler when this attribute sequences suitable for use in an interrupt handler when this attribute
...@@ -2425,6 +2425,42 @@ Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@. ...@@ -2425,6 +2425,42 @@ Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@.
On ARMv7-M the interrupt type is ignored, and the attribute means the function On ARMv7-M the interrupt type is ignored, and the attribute means the function
may be called with a word aligned stack pointer. may be called with a word aligned stack pointer.
On MIPS targets, you can use the following attributes to modify the behavior
of an interrupt handler:
@table @code
@item use_shadow_register_set
@cindex @code{use_shadow_register_set} attribute
Assume that the handler uses a shadow register set, instead of
the main general-purpose registers.
@item keep_interrupts_masked
@cindex @code{keep_interrupts_masked} attribute
Keep interrupts masked for the whole function. Without this attribute,
GCC tries to reenable interrupts for as much of the function as it can.
@item use_debug_exception_return
@cindex @code{use_debug_exception_return} attribute
Return using the @code{deret} instruction. Interrupt handlers that don't
have this attribute return using @code{eret} instead.
@end table
You can use any combination of these attributes, as shown below:
@smallexample
void __attribute__ ((interrupt)) v0 ();
void __attribute__ ((interrupt, use_shadow_register_set)) v1 ();
void __attribute__ ((interrupt, keep_interrupts_masked)) v2 ();
void __attribute__ ((interrupt, use_debug_exception_return)) v3 ();
void __attribute__ ((interrupt, use_shadow_register_set,
keep_interrupts_masked)) v4 ();
void __attribute__ ((interrupt, use_shadow_register_set,
use_debug_exception_return)) v5 ();
void __attribute__ ((interrupt, keep_interrupts_masked,
use_debug_exception_return)) v6 ();
void __attribute__ ((interrupt, use_shadow_register_set,
keep_interrupts_masked,
use_debug_exception_return)) v7 ();
@end smallexample
@item interrupt_handler @item interrupt_handler
@cindex interrupt handler functions on the Blackfin, m68k, H8/300 and SH processors @cindex interrupt handler functions on the Blackfin, m68k, H8/300 and SH processors
Use this attribute on the Blackfin, m68k, H8/300, H8/300H, H8S, and SH to Use this attribute on the Blackfin, m68k, H8/300, H8/300H, H8S, and SH to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment