Commit a3515605 by Richard Henderson Committed by Richard Henderson

vax: Emit prologue as rtl.

Not that there's much rtl to emit, since the CALL instruction
interpreting the procedure entry mask does almost all the work.
However, it means we're no longer emitting dwarf2 via the
text-based entry points.

        * config/vax/vax.md (define_c_enum unspecv): New.  Define the
        VUNSPEC_* constants here instead of via define_constants.
        (VUNSPEC_PEM): New constant.
        (procedure_entry_mask): New insn.
        (prologue): New expander.
        * config/vax/vax.c (vax_add_reg_cfa_offset): New.
        (vax_expand_prologue): Rename from vax_output_function_prologue;
        emit rtl instead of text.
        (TARGET_ASM_FUNCTION_PROLOGUE): Remove.
        (print_operand): Add 'x' prefix.

From-SVN: r175869
parent 96241349
2011-07-05 Richard Henderson <rth@redhat.com>
* config/vax/vax.md (define_c_enum unspecv): New. Define the
VUNSPEC_* constants here instead of via define_constants.
(VUNSPEC_PEM): New constant.
(procedure_entry_mask): New insn.
(prologue): New expander.
* config/vax/vax.c (vax_add_reg_cfa_offset): New.
(vax_expand_prologue): Rename from vax_output_function_prologue;
emit rtl instead of text.
(TARGET_ASM_FUNCTION_PROLOGUE): Remove.
(print_operand): Add 'x' prefix.
2011-07-05 H.J. Lu <hongjiu.lu@intel.com> 2011-07-05 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/47715 PR middle-end/47715
......
...@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
extern bool legitimate_constant_address_p (rtx); extern bool legitimate_constant_address_p (rtx);
extern bool vax_mode_dependent_address_p (rtx); extern bool vax_mode_dependent_address_p (rtx);
extern void vax_expand_prologue (void);
#ifdef RTX_CODE #ifdef RTX_CODE
extern const char *cond_name (rtx); extern const char *cond_name (rtx);
......
...@@ -48,7 +48,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -48,7 +48,6 @@ along with GCC; see the file COPYING3. If not see
static void vax_option_override (void); static void vax_option_override (void);
static bool vax_legitimate_address_p (enum machine_mode, rtx, bool); static bool vax_legitimate_address_p (enum machine_mode, rtx, bool);
static void vax_output_function_prologue (FILE *, HOST_WIDE_INT);
static void vax_file_start (void); static void vax_file_start (void);
static void vax_init_libfuncs (void); static void vax_init_libfuncs (void);
static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
...@@ -70,9 +69,6 @@ static int vax_return_pops_args (tree, tree, int); ...@@ -70,9 +69,6 @@ static int vax_return_pops_args (tree, tree, int);
#undef TARGET_ASM_ALIGNED_HI_OP #undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t" #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
#undef TARGET_ASM_FILE_START #undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START vax_file_start #define TARGET_ASM_FILE_START vax_file_start
#undef TARGET_ASM_FILE_START_APP_OFF #undef TARGET_ASM_FILE_START_APP_OFF
...@@ -137,6 +133,17 @@ vax_option_override (void) ...@@ -137,6 +133,17 @@ vax_option_override (void)
#endif #endif
} }
static void
vax_add_reg_cfa_offset (rtx insn, int offset, rtx src)
{
rtx x;
x = plus_constant (frame_pointer_rtx, offset);
x = gen_rtx_MEM (SImode, x);
x = gen_rtx_SET (VOIDmode, x, src);
add_reg_note (insn, REG_CFA_OFFSET, x);
}
/* Generate the assembly code for function entry. FILE is a stdio /* Generate the assembly code for function entry. FILE is a stdio
stream to output the code to. SIZE is an int: how many units of stream to output the code to. SIZE is an int: how many units of
temporary storage to allocate. temporary storage to allocate.
...@@ -146,38 +153,67 @@ vax_option_override (void) ...@@ -146,38 +153,67 @@ vax_option_override (void)
used in the function. This function is responsible for knowing used in the function. This function is responsible for knowing
which registers should not be saved even if used. */ which registers should not be saved even if used. */
static void void
vax_output_function_prologue (FILE * file, HOST_WIDE_INT size) vax_expand_prologue (void)
{ {
int regno; int regno, offset;
int mask = 0; int mask = 0;
HOST_WIDE_INT size;
rtx insn;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
mask |= 1 << regno; mask |= 1 << regno;
fprintf (file, "\t.word 0x%x\n", mask); insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask)));
RTX_FRAME_RELATED_P (insn) = 1;
if (dwarf2out_do_frame ()) /* The layout of the CALLG/S stack frame is follows:
{
const char *label = dwarf2out_cfi_label (false);
int offset = 0;
for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno) <- CFA, AP
if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) r11
dwarf2out_reg_save (label, regno, offset -= 4); r10
... Registers saved as specified by MASK
r3
r2
return-addr
old fp
old ap
old psw
zero
<- FP, SP
dwarf2out_reg_save (label, PC_REGNUM, offset -= 4); The rest of the prologue will adjust the SP for the local frame. */
dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4);
dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4); vax_add_reg_cfa_offset (insn, 4, arg_pointer_rtx);
dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4)); vax_add_reg_cfa_offset (insn, 8, frame_pointer_rtx);
} vax_add_reg_cfa_offset (insn, 12, pc_rtx);
offset = 16;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (mask & (1 << regno))
{
vax_add_reg_cfa_offset (insn, offset, gen_rtx_REG (SImode, regno));
offset += 4;
}
/* Because add_reg_note pushes the notes, adding this last means that
it will be processed first. This is required to allow the other
notes be interpreted properly. */
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (frame_pointer_rtx, offset));
/* Allocate the local stack frame. */
size = get_frame_size ();
size -= STARTING_FRAME_OFFSET; size -= STARTING_FRAME_OFFSET;
if (size >= 64) emit_insn (gen_addsi3 (stack_pointer_rtx,
asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size); stack_pointer_rtx, GEN_INT (-size)));
else if (size)
asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size); /* Do not allow instructions referencing local stack memory to be
scheduled before the frame is allocated. This is more pedantic
than anything else, given that VAX does not currently have a
scheduling description. */
emit_insn (gen_blockage ());
} }
/* When debugging with stabs, we want to output an extra dummy label /* When debugging with stabs, we want to output an extra dummy label
...@@ -485,6 +521,8 @@ print_operand (FILE *file, rtx x, int code) ...@@ -485,6 +521,8 @@ print_operand (FILE *file, rtx x, int code)
fprintf (file, "$%d", (int) (0xff & - INTVAL (x))); fprintf (file, "$%d", (int) (0xff & - INTVAL (x)));
else if (code == 'M' && CONST_INT_P (x)) else if (code == 'M' && CONST_INT_P (x))
fprintf (file, "$%d", ~((1 << INTVAL (x)) - 1)); fprintf (file, "$%d", ~((1 << INTVAL (x)) - 1));
else if (code == 'x' && CONST_INT_P (x))
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
else if (REG_P (x)) else if (REG_P (x))
fprintf (file, "%s", reg_names[REGNO (x)]); fprintf (file, "%s", reg_names[REGNO (x)]);
else if (MEM_P (x)) else if (MEM_P (x))
......
...@@ -29,11 +29,15 @@ ...@@ -29,11 +29,15 @@
;; UNSPEC_VOLATILE usage: ;; UNSPEC_VOLATILE usage:
(define_constants (define_c_enum "unspecv" [
[(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an VUNSPEC_BLOCKAGE ; 'blockage' insn to prevent scheduling across an
; insn in the code. ; insn in the code.
(VUNSPEC_SYNC_ISTREAM 1) ; sequence of insns to sync the I-stream VUNSPEC_SYNC_ISTREAM ; sequence of insns to sync the I-stream
(VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer VUNSPEC_PEM ; 'procedure_entry_mask' insn.
])
(define_constants
[(VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer
(VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer (VAX_FP_REGNUM 13) ; Register 13 contains the frame pointer
(VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer (VAX_SP_REGNUM 14) ; Register 14 contains the stack pointer
(VAX_PC_REGNUM 15) ; Register 15 contains the program counter (VAX_PC_REGNUM 15) ; Register 15 contains the program counter
...@@ -1409,11 +1413,24 @@ ...@@ -1409,11 +1413,24 @@
"" ""
"") "")
(define_insn "procedure_entry_mask"
[(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)]
""
".word %x0")
(define_insn "return" (define_insn "return"
[(return)] [(return)]
"" ""
"ret") "ret")
(define_expand "prologue"
[(const_int 0)]
""
{
vax_expand_prologue ();
DONE;
})
(define_expand "epilogue" (define_expand "epilogue"
[(return)] [(return)]
"" ""
......
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