diff mbox

[04/12] vax: Emit prologue as rtl.

Message ID 1309384152-25027-5-git-send-email-rth@redhat.com
State New
Headers show

Commit Message

Richard Henderson June 29, 2011, 9:49 p.m. UTC
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.
---
 gcc/config/vax/vax-protos.h |    1 +
 gcc/config/vax/vax.c        |   86 +++++++++++++++++++++++++++++++------------
 gcc/config/vax/vax.md       |   25 ++++++++++--
 3 files changed, 84 insertions(+), 28 deletions(-)

Comments

Steven Bosscher June 29, 2011, 11:01 p.m. UTC | #1
On Wed, Jun 29, 2011 at 11:49 PM, Richard Henderson <rth@redhat.com> wrote:
> --- a/gcc/config/vax/vax.c
> +++ b/gcc/config/vax/vax.c
> @@ -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

Can you please also update http://gcc.gnu.org/backends.html? I think
VAX should have a 'g' after you commit this patch.

How many TARGET_ASM_FUNCTION_{PRO,EPI}LOGUE targets are left anyway?

Ciao!
Steven
Richard Henderson June 29, 2011, 11:09 p.m. UTC | #2
On 06/29/2011 04:01 PM, Steven Bosscher wrote:
> Can you please also update http://gcc.gnu.org/backends.html? I think
> VAX should have a 'g' after you commit this patch.

Sure.

> How many TARGET_ASM_FUNCTION_{PRO,EPI}LOGUE targets are left anyway?

It's difficult to tell at a glance, because quite a few use
the hook for Other Things.  Such as ARM printing debug info
about the stack frame, or Sparc outputting the scratch register
elf info, or IA-64 and Alpha using it to output some portion
of the unwind info.


r~
Richard Henderson June 30, 2011, 5:21 p.m. UTC | #3
On 06/29/2011 04:01 PM, Steven Bosscher wrote:
> How many TARGET_ASM_FUNCTION_{PRO,EPI}LOGUE targets are left anyway?

Answering the question that it sounds like you actually asked: 2 or 3.
Not that it does us that much good because of the other uses.

FWIW, Alpha appears to be the only target that (ab)uses 
ASM_DECLARE_FUNCTION_NAME to output unwind info.  That might have been
a mistake, considering the interference that causes with using elfos.h.

I'm not sure what all the zeroing of backend variables that several 
targets are doing is for.  Better GC at the end of the function maybe?


r~

----------------------


Users of TARGET_ASM_FUNCTION_PROLOGUE

   Outputs the real prologue
	pdp11
	rs6000		if !TARGET_SCHED_PROLOG

   Outputs assembly comments
	arm
	m32r
	mep
	picochip
	rx

   Outputs unwind info
	ia64		(.regstk, .prologue)
	microblaze	(.ent, .frame, .mask)
	mips		(.ent, .frame, .mask)
	pa		(.PROC and .CALLINFO)
	score		(.ent, .frame, .mask)

   Other
	frv		renaming of gr3?, frv_pack_insns
	mips		mips16 function stub, gp load at function start
	microblaze	add _interrupt_handler alias?
	mmix		init register renaming?
	rs6000		emit .extern as needed before uses?
	sparc		emit .register as needed

Users of TARGET_ASM_FUNCTION_EPILOGUE

   Outputs the real epilogue
	arm		thumb1 only
	pdp11
	rs6000		if !TARGET_SCHED_PROLOG

   Outputs assembly comments
	picochip
	mmix		actually just a newline?

   Outputs unwind info
	microblaze	(.end)
	mips		(.end)
	pa		(.PROCEND and stuff)
	rs6000		aix traceback table
	score		(.end)

   Other
	arm		validate some frame offsets?
	frv		reset variables
	i386		undo pic register renaming, darwin nop hack
	ia64		undo register renaming
	m32r		reset variables
	microblaze	finish _interrupt_handler alias, reset variables
	mips		undo pic register renaming
	rs6000		darwin branch islands
	sh		reset variables
	sparc		unwind nop, deferred case vectors
	xtensa		reset variables
Paul Koning June 30, 2011, 5:30 p.m. UTC | #4
On Jun 30, 2011, at 1:21 PM, Richard Henderson wrote:

> On 06/29/2011 04:01 PM, Steven Bosscher wrote:
>> How many TARGET_ASM_FUNCTION_{PRO,EPI}LOGUE targets are left anyway?
> 
> Answering the question that it sounds like you actually asked: 2 or 3.
> Not that it does us that much good because of the other uses.
> ...
> Users of TARGET_ASM_FUNCTION_PROLOGUE
> 
>   Outputs the real prologue
> 	pdp11
> 	rs6000		if !TARGET_SCHED_PROLOG
> ...

I intend to change pdp11 over to RTL based pro/epilogue in the not too distant future.

	paul
diff mbox

Patch

diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index a8f88bf..3f24794 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 7c7070c..13a4515 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 8c3ef00..32f50fd 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)]
   ""