diff options
Diffstat (limited to 'gcc/config/vax')
-rw-r--r-- | gcc/config/vax/vax-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/vax/vax.c | 86 | ||||
-rw-r--r-- | gcc/config/vax/vax.md | 25 |
3 files changed, 84 insertions, 28 deletions
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h index a8f88bfa126..3f247943314 100644 --- a/gcc/config/vax/vax-protos.h +++ b/gcc/config/vax/vax-protos.h @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see extern bool legitimate_constant_address_p (rtx); extern bool vax_mode_dependent_address_p (rtx); +extern void vax_expand_prologue (void); #ifdef RTX_CODE extern const char *cond_name (rtx); diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c index 7c7070c9016..13a45158f94 100644 --- a/gcc/config/vax/vax.c +++ b/gcc/config/vax/vax.c @@ -48,7 +48,6 @@ along with GCC; see the file COPYING3. If not see static void vax_option_override (void); 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_init_libfuncs (void); static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, @@ -70,9 +69,6 @@ static int vax_return_pops_args (tree, tree, int); #undef TARGET_ASM_ALIGNED_HI_OP #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 #define TARGET_ASM_FILE_START vax_file_start #undef TARGET_ASM_FILE_START_APP_OFF @@ -137,6 +133,17 @@ vax_option_override (void) #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 stream to output the code to. SIZE is an int: how many units of temporary storage to allocate. @@ -146,38 +153,67 @@ vax_option_override (void) used in the function. This function is responsible for knowing which registers should not be saved even if used. */ -static void -vax_output_function_prologue (FILE * file, HOST_WIDE_INT size) +void +vax_expand_prologue (void) { - int regno; + int regno, offset; int mask = 0; + HOST_WIDE_INT size; + rtx insn; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) if (df_regs_ever_live_p (regno) && !call_used_regs[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 ()) - { - const char *label = dwarf2out_cfi_label (false); - int offset = 0; + /* The layout of the CALLG/S stack frame is follows: - for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno) - if (df_regs_ever_live_p (regno) && !call_used_regs[regno]) - dwarf2out_reg_save (label, regno, offset -= 4); + <- CFA, AP + r11 + 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); - dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4); - dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4); - dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4)); - } + The rest of the prologue will adjust the SP for the local frame. */ + + vax_add_reg_cfa_offset (insn, 4, arg_pointer_rtx); + 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; - if (size >= 64) - asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size); - else if (size) - asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size); + emit_insn (gen_addsi3 (stack_pointer_rtx, + stack_pointer_rtx, GEN_INT (-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 @@ -485,6 +521,8 @@ print_operand (FILE *file, rtx x, int code) fprintf (file, "$%d", (int) (0xff & - INTVAL (x))); else if (code == 'M' && CONST_INT_P (x)) 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)) fprintf (file, "%s", reg_names[REGNO (x)]); else if (MEM_P (x)) diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md index 8c3ef0042ff..32f50fd3367 100644 --- a/gcc/config/vax/vax.md +++ b/gcc/config/vax/vax.md @@ -29,11 +29,15 @@ ;; UNSPEC_VOLATILE usage: -(define_constants - [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an +(define_c_enum "unspecv" [ + VUNSPEC_BLOCKAGE ; 'blockage' insn to prevent scheduling across an ; insn in the code. - (VUNSPEC_SYNC_ISTREAM 1) ; sequence of insns to sync the I-stream - (VAX_AP_REGNUM 12) ; Register 12 contains the argument pointer + VUNSPEC_SYNC_ISTREAM ; sequence of insns to sync the I-stream + 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_SP_REGNUM 14) ; Register 14 contains the stack pointer (VAX_PC_REGNUM 15) ; Register 15 contains the program counter @@ -1409,11 +1413,24 @@ "" "") +(define_insn "procedure_entry_mask" + [(unspec_volatile [(match_operand 0 "const_int_operand")] VUNSPEC_PEM)] + "" + ".word %x0") + (define_insn "return" [(return)] "" "ret") +(define_expand "prologue" + [(const_int 0)] + "" +{ + vax_expand_prologue (); + DONE; +}) + (define_expand "epilogue" [(return)] "" |