aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/m32c/m32c.c85
-rw-r--r--gcc/config/m32c/m32c.md2
-rw-r--r--gcc/config/m32c/prologue.md17
-rw-r--r--gcc/doc/extend.texi13
5 files changed, 122 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 953397e..94e20b3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2009-08-17 DJ Delorie <dj@redhat.com>
+
+ * config/m32c/m32c.md (UNS_FSETB, UNS_FREIT): New.
+ * config/m32c/prologue.md (epilogue_freit): New.
+ (fset_b): New.
+ * config/m32c/m32c.c (m32c_function_needs_enter): Add prototype.
+ (bank_switch_p): Likewise.
+ (fast_interrupt_p): Likewise.
+ (interrupt_p): Likewise.
+ (m32c_conditional_register_usage): Round memregs size up.
+ (need_to_save): We only need to save $a0 when we use ENTER.
+ (interrupt_p): Check for fast_interrupt too.
+ (bank_switch_p): New.
+ (fast_interrupt_p): New.
+ (m32c_attribute_table): Add bank_switch and fast_interrupt.
+ (m32c_emit_prolog): Support bank switching and fast interrupts.
+ * doc/extend.texi (Function Attributes): Add bank_switch and
+ fast_interrupt.
+
2009-08-17 Douglas B Rupp <rupp@gnat.com>
* config/alpha/alpha.c (vms_valid_pointer_mode): New function.
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 46dc4dc..ae4c897 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -60,9 +60,13 @@ typedef enum
PP_justcount
} Push_Pop_Type;
+static bool m32c_function_needs_enter (void);
static tree interrupt_handler (tree *, tree, tree, int, bool *);
static tree function_vector_handler (tree *, tree, tree, int, bool *);
static int interrupt_p (tree node);
+static int bank_switch_p (tree node);
+static int fast_interrupt_p (tree node);
+static int interrupt_p (tree node);
static bool m32c_asm_integer (rtx, unsigned int, int);
static int m32c_comp_type_attributes (const_tree, const_tree);
static bool m32c_fixed_condition_code_regs (unsigned int *, unsigned int *);
@@ -493,7 +497,7 @@ m32c_conditional_register_usage (void)
{
/* The command line option is bytes, but our "registers" are
16-bit words. */
- for (i = target_memregs/2; i < 8; i++)
+ for (i = (target_memregs+1)/2; i < 8; i++)
{
fixed_regs[MEM0_REGNO + i] = 1;
CLEAR_HARD_REG_BIT (reg_class_contents[MEM_REGS], MEM0_REGNO + i);
@@ -1255,7 +1259,10 @@ need_to_save (int regno)
if (regno == FP_REGNO)
return 0;
if (cfun->machine->is_interrupt
- && (!cfun->machine->is_leaf || regno == A0_REGNO))
+ && (!cfun->machine->is_leaf
+ || (regno == A0_REGNO
+ && m32c_function_needs_enter ())
+ ))
return 1;
if (df_regs_ever_live_p (regno)
&& (!call_used_regs[regno] || cfun->machine->is_interrupt))
@@ -2733,6 +2740,34 @@ interrupt_p (tree node ATTRIBUTE_UNUSED)
return 1;
list = TREE_CHAIN (list);
}
+ return fast_interrupt_p (node);
+}
+
+/* Returns TRUE if the given tree has the "bank_switch" attribute. */
+static int
+bank_switch_p (tree node ATTRIBUTE_UNUSED)
+{
+ tree list = M32C_ATTRIBUTES (node);
+ while (list)
+ {
+ if (is_attribute_p ("bank_switch", TREE_PURPOSE (list)))
+ return 1;
+ list = TREE_CHAIN (list);
+ }
+ return 0;
+}
+
+/* Returns TRUE if the given tree has the "fast_interrupt" attribute. */
+static int
+fast_interrupt_p (tree node ATTRIBUTE_UNUSED)
+{
+ tree list = M32C_ATTRIBUTES (node);
+ while (list)
+ {
+ if (is_attribute_p ("fast_interrupt", TREE_PURPOSE (list)))
+ return 1;
+ list = TREE_CHAIN (list);
+ }
return 0;
}
@@ -2846,6 +2881,8 @@ current_function_special_page_vector (rtx x)
#define TARGET_ATTRIBUTE_TABLE m32c_attribute_table
static const struct attribute_spec m32c_attribute_table[] = {
{"interrupt", 0, 0, false, false, false, interrupt_handler},
+ {"bank_switch", 0, 0, false, false, false, interrupt_handler},
+ {"fast_interrupt", 0, 0, false, false, false, interrupt_handler},
{"function_vector", 1, 1, true, false, false, function_vector_handler},
{0, 0, 0, 0, 0, 0, 0}
};
@@ -3928,16 +3965,23 @@ m32c_emit_prologue (void)
cfun->machine->is_interrupt = 1;
complex_prologue = 1;
}
+ else if (bank_switch_p (cfun->decl))
+ warning (OPT_Wattributes,
+ "%<bank_switch%> has no effect on non-interrupt functions");
reg_save_size = m32c_pushm_popm (PP_justcount);
if (interrupt_p (cfun->decl))
- emit_insn (gen_pushm (GEN_INT (cfun->machine->intr_pushm)));
+ {
+ if (bank_switch_p (cfun->decl))
+ emit_insn (gen_fset_b ());
+ else if (cfun->machine->intr_pushm)
+ emit_insn (gen_pushm (GEN_INT (cfun->machine->intr_pushm)));
+ }
frame_size =
m32c_initial_elimination_offset (FB_REGNO, SP_REGNO) - reg_save_size;
if (frame_size == 0
- && !cfun->machine->is_interrupt
&& !m32c_function_needs_enter ())
cfun->machine->use_rts = 1;
@@ -3988,16 +4032,29 @@ m32c_emit_epilogue (void)
{
enum machine_mode spmode = TARGET_A16 ? HImode : PSImode;
- emit_move_insn (gen_rtx_REG (spmode, A0_REGNO),
- gen_rtx_REG (spmode, FP_REGNO));
- emit_move_insn (gen_rtx_REG (spmode, SP_REGNO),
- gen_rtx_REG (spmode, A0_REGNO));
- if (TARGET_A16)
- emit_insn (gen_pophi_16 (gen_rtx_REG (HImode, FP_REGNO)));
- else
- emit_insn (gen_poppsi (gen_rtx_REG (PSImode, FP_REGNO)));
- emit_insn (gen_popm (GEN_INT (cfun->machine->intr_pushm)));
- if (TARGET_A16)
+ /* REIT clears B flag and restores $fp for us, but we still
+ have to fix up the stack. USE_RTS just means we didn't
+ emit ENTER. */
+ if (!cfun->machine->use_rts)
+ {
+ emit_move_insn (gen_rtx_REG (spmode, A0_REGNO),
+ gen_rtx_REG (spmode, FP_REGNO));
+ emit_move_insn (gen_rtx_REG (spmode, SP_REGNO),
+ gen_rtx_REG (spmode, A0_REGNO));
+ /* We can't just add this to the POPM because it would be in
+ the wrong order, and wouldn't fix the stack if we're bank
+ switching. */
+ if (TARGET_A16)
+ emit_insn (gen_pophi_16 (gen_rtx_REG (HImode, FP_REGNO)));
+ else
+ emit_insn (gen_poppsi (gen_rtx_REG (PSImode, FP_REGNO)));
+ }
+ if (!bank_switch_p (cfun->decl) && cfun->machine->intr_pushm)
+ emit_insn (gen_popm (GEN_INT (cfun->machine->intr_pushm)));
+
+ if (fast_interrupt_p (cfun->decl))
+ emit_jump_insn (gen_epilogue_freit ());
+ else if (TARGET_A16)
emit_jump_insn (gen_epilogue_reit_16 ());
else
emit_jump_insn (gen_epilogue_reit_24 ());
diff --git a/gcc/config/m32c/m32c.md b/gcc/config/m32c/m32c.md
index da0f8dd..739f24c 100644
--- a/gcc/config/m32c/m32c.md
+++ b/gcc/config/m32c/m32c.md
@@ -47,6 +47,8 @@
(UNS_SSTR 7)
(UNS_SCMPU 8)
(UNS_SMOVU 9)
+ (UNS_FSETB 10)
+ (UNS_FREIT 11)
])
;; n = no change, x = clobbered. The first 16 values are chosen such
diff --git a/gcc/config/m32c/prologue.md b/gcc/config/m32c/prologue.md
index 9db4920..175b2b0 100644
--- a/gcc/config/m32c/prologue.md
+++ b/gcc/config/m32c/prologue.md
@@ -149,6 +149,15 @@
[(set_attr "flags" "x")]
)
+(define_insn "epilogue_freit"
+ [(unspec [(const_int 0)] UNS_FREIT)
+ (return)
+ ]
+ ""
+ "freit"
+ [(set_attr "flags" "x")]
+ )
+
(define_insn "epilogue_rts"
[(return)
]
@@ -180,3 +189,11 @@
"popm\t%p0"
[(set_attr "flags" "n")]
)
+
+(define_insn "fset_b"
+ [(unspec [(const_int 0)] UNS_FSETB)]
+ ""
+ "fset\tB"
+ [(set_attr "flags" "n")]
+ )
+
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 827198e..4e9f189 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2019,6 +2019,12 @@ info format it will either mean marking the function as artificial
or using the caller location for all instructions within the inlined
body.
+@item bank_switch
+@cindex interrupt handler functions
+When added to an interrupt handler with the M32C port, causes the
+prologue and epilogue to use bank switching to preserve the registers
+rather than saving them on the stack.
+
@item flatten
@cindex @code{flatten} function attribute
Generally, inlining into a function is limited. For a function marked with
@@ -2272,6 +2278,13 @@ On MeP targets this causes the compiler to use a calling convention
which assumes the called function is too far away for the built-in
addressing modes.
+@item fast_interrupt
+@cindex interrupt handler functions
+Use this attribute on the M32C port to indicate that the specified
+function is a fast interrupt handler. This is just like the
+@code{interrupt} attribute, except that @code{freit} is used to return
+instead of @code{reit}.
+
@item fastcall
@cindex functions that pop the argument stack on the 386
On the Intel 386, the @code{fastcall} attribute causes the compiler to