This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 6/9] Adds class xlouge_layout to i386.c


This C++ class adds the basic support for foutline-msabi-xlogues by
manging the layout (where registers are stored based upon and other
facets of the optimization) and providing the proper symbol rtx for the
required stub.

xlouge_layout should not be used until a call to
ix86_compute_frame_layout as it's behavior is dependent upon data in
ctrl and cfun->machine. Once ix86_compute_frame_layout has been called,
the static member function xlouge_layout::get_instance can be used to
retrieve the appropriate (constant) instance of xlouge_layout.
---
 gcc/config/i386/i386.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 218 insertions(+)

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4cc3c8f..f39b847 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2429,6 +2429,224 @@ unsigned const x86_64_ms_sysv_extra_clobbered_registers[12] =
   XMM12_REG, XMM13_REG, XMM14_REG, XMM15_REG
 };
 
+enum xlogue_stub {
+  XLOGUE_STUB_SAVE,
+  XLOGUE_STUB_RESTORE,
+  XLOGUE_STUB_RESTORE_TAIL,
+  XLOGUE_STUB_SAVE_HFP,
+  XLOGUE_STUB_RESTORE_HFP,
+  XLOGUE_STUB_RESTORE_HFP_TAIL,
+
+  XLOGUE_STUB_COUNT
+};
+
+enum xlogue_stub_sets {
+  XLOGUE_SET_ALIGNED,
+  XLOGUE_SET_ALIGNED_PLUS_8,
+  XLOGUE_SET_UNALIGNED,
+
+  XLOGUE_SET_COUNT
+};
+
+/* Register save/restore layout used by an out-of-line stubs.  */
+class xlogue_layout {
+public:
+  struct reginfo {
+    unsigned regno;
+    HOST_WIDE_INT offset;	/* Offset used by stub base pointer (rax or
+				   rsi) to where each register is stored.  */
+  };
+
+  unsigned get_nregs () const			{return m_nregs;}
+  HOST_WIDE_INT get_stack_align_off_in () const	{return m_stack_align_off_in;}
+
+  const reginfo &get_reginfo (unsigned reg) const
+    {
+      gcc_assert (reg < m_nregs);
+      return m_regs[reg];
+    }
+
+  /* Returns an rtx for the stub's symbol based upon
+       1.) the specified stub (save, restore or restore_ret) and
+       2.) the value of cfun->machine->outline_ms_sysv_extra_regs and
+       3.) rather or not stack alignment is being performed.  */
+  rtx get_stub_rtx (enum xlogue_stub stub) const;
+
+  /* Returns the amount of stack space (including padding) that the stub
+     needs to store registers based upon data in the machine_function.  */
+  HOST_WIDE_INT get_stack_space_used () const
+    {
+      const struct machine_function &m = *cfun->machine;
+      unsigned last_reg = m.outline_ms_sysv_extra_regs + MIN_REGS;
+
+      gcc_assert (m.outline_ms_sysv_extra_regs <= MAX_EXTRA_REGS);
+      return m_regs[last_reg - 1].offset
+	     + (m.outline_ms_sysv_pad_out ? 8 : 0)
+	     + STUB_INDEX_OFFSET;
+    }
+
+  /* Returns the offset for the base pointer used by the stub.  */
+  HOST_WIDE_INT get_stub_ptr_offset () const
+    {
+      return STUB_INDEX_OFFSET + m_stack_align_off_in;
+    }
+
+  static const struct xlogue_layout &get_instance ();
+
+  static const HOST_WIDE_INT STUB_INDEX_OFFSET = 0x70;
+  static const unsigned MIN_REGS = 12;
+  static const unsigned MAX_REGS = 18;
+  static const unsigned MAX_EXTRA_REGS = MAX_REGS - MIN_REGS;
+  static const unsigned VARIANT_COUNT = MAX_EXTRA_REGS + 1;
+  static const unsigned STUB_NAME_MAX_LEN = 16;
+  static const char * const STUB_BASE_NAMES[XLOGUE_STUB_COUNT];
+  static const unsigned REG_ORDER[MAX_REGS];
+  static const unsigned REG_ORDER_REALIGN[MAX_REGS];
+
+private:
+  xlogue_layout ();
+  xlogue_layout (HOST_WIDE_INT stack_align_off_in, bool hfp);
+  xlogue_layout (const xlogue_layout &);
+  ~xlogue_layout ();
+
+  /* True if hard frame pointer is used.  */
+  bool m_hfp;
+
+  /* Max number of register this layout manages.  */
+  unsigned m_nregs;
+
+  /* Incoming offset from 16-byte alignment.  */
+  HOST_WIDE_INT m_stack_align_off_in;
+  struct reginfo m_regs[MAX_REGS];
+  rtx m_syms[XLOGUE_STUB_COUNT][VARIANT_COUNT];
+  char m_stub_names[XLOGUE_STUB_COUNT][VARIANT_COUNT][STUB_NAME_MAX_LEN];
+
+  static const struct xlogue_layout GTY(()) s_instances[XLOGUE_SET_COUNT];
+};
+
+const char * const xlogue_layout::STUB_BASE_NAMES[XLOGUE_STUB_COUNT] = {
+  "savms64",
+  "resms64",
+  "resms64x",
+  "savms64f",
+  "resms64f",
+  "resms64fx"
+};
+
+const unsigned xlogue_layout::REG_ORDER[xlogue_layout::MAX_REGS] = {
+/* The below offset values are where each register is stored for the layout
+   relative to incoming stack pointer.  The value of each m_regs[].offset will
+   be relative to the incoming base pointer (rax or rsi) used by the stub.
+
+			  FP offset	FP offset
+    Register		   aligned	aligned + 8	realigned*/
+    XMM15_REG,		/* 0x10		0x18		0x10	*/
+    XMM14_REG,		/* 0x20		0x28		0x20	*/
+    XMM13_REG,		/* 0x30		0x38		0x30	*/
+    XMM12_REG,		/* 0x40		0x48		0x40	*/
+    XMM11_REG,		/* 0x50		0x58		0x50	*/
+    XMM10_REG,		/* 0x60		0x68		0x60	*/
+    XMM9_REG,		/* 0x70		0x78		0x70	*/
+    XMM8_REG,		/* 0x80		0x88		0x80	*/
+    XMM7_REG,		/* 0x90		0x98		0x90	*/
+    XMM6_REG,		/* 0xa0		0xa8		0xa0	*/
+    SI_REG,		/* 0xa8		0xb0		0xa8	*/
+    DI_REG,		/* 0xb0		0xb8		0xb0	*/
+    BX_REG,		/* 0xb8		0xc0		0xb8	*/
+    BP_REG,		/* 0xc0		0xc8		N/A	*/
+    R12_REG,		/* 0xc8		0xd0		0xc0	*/
+    R13_REG,		/* 0xd0		0xd8		0xc8	*/
+    R14_REG,		/* 0xd8		0xe0		0xd0	*/
+    R15_REG,		/* 0xe0		0xe8		0xd8	*/
+};
+
+const struct xlogue_layout GTY(())
+xlogue_layout::s_instances[XLOGUE_SET_COUNT] = {
+  xlogue_layout (0, false),
+  xlogue_layout (8, false),
+  xlogue_layout (0, true)
+};
+
+const struct xlogue_layout &xlogue_layout::get_instance ()
+{
+  enum xlogue_stub_sets stub_set;
+
+  if (crtl->stack_realign_needed)
+    stub_set = XLOGUE_SET_UNALIGNED;
+  else if (cfun->machine->outline_ms_sysv_pad_in)
+    stub_set = XLOGUE_SET_ALIGNED_PLUS_8;
+  else
+    stub_set = XLOGUE_SET_ALIGNED;
+
+  return s_instances[stub_set];
+}
+
+xlogue_layout::xlogue_layout (HOST_WIDE_INT stack_align_off_in, bool hfp)
+  : m_hfp (hfp) , m_nregs (hfp ? 17 : 18),
+    m_stack_align_off_in (stack_align_off_in)
+{
+  memset (m_regs, 0, sizeof (m_regs));
+  memset (m_syms, 0, sizeof (m_syms));
+  memset (m_stub_names, 0, sizeof (m_stub_names));
+
+  gcc_assert (!hfp || !stack_align_off_in);
+  gcc_assert (!(stack_align_off_in & (~8)));
+
+  HOST_WIDE_INT offset = stack_align_off_in;
+  unsigned i, j;
+  for (i = j = 0; i < MAX_REGS; ++i)
+    {
+      unsigned regno = REG_ORDER[i];
+
+      if (regno == BP_REG && hfp)
+	continue;
+      if (SSE_REGNO_P (regno))
+	{
+	  offset += 16;
+	  /* Verify that SSE regs are always aligned.  */
+	  gcc_assert (!((stack_align_off_in + offset) & 15));
+	}
+      else
+	offset += 8;
+
+      m_regs[j].regno    = regno;
+      m_regs[j++].offset = offset - STUB_INDEX_OFFSET;
+    }
+    gcc_assert (j == m_nregs);
+}
+
+xlogue_layout::~xlogue_layout ()
+{
+}
+
+rtx xlogue_layout::get_stub_rtx (enum xlogue_stub stub) const
+{
+  const unsigned n_extra_regs = cfun->machine->outline_ms_sysv_extra_regs;
+  gcc_assert (n_extra_regs <= MAX_EXTRA_REGS);
+  gcc_assert (stub < XLOGUE_STUB_COUNT);
+
+  /* FIXME: For some reason, cached symbols go bad, so disable it for now.
+     Should we just remove the rtx cache or do we need to reset it at some
+     point? */
+  if (true || !m_syms[stub][n_extra_regs])
+    {
+      xlogue_layout *writey_this = const_cast<xlogue_layout*>(this);
+      char *stub_name = writey_this->m_stub_names[stub][n_extra_regs];
+      rtx sym;
+      int res;
+
+      res = snprintf (stub_name, STUB_NAME_MAX_LEN - 1, "__%s_%u",
+		      STUB_BASE_NAMES[stub], 12 + n_extra_regs);
+      gcc_assert (res <= (int)STUB_NAME_MAX_LEN);
+
+      sym = gen_rtx_SYMBOL_REF (Pmode, stub_name);
+      writey_this->m_syms[stub][n_extra_regs] = sym;
+    }
+
+    gcc_assert (m_syms[stub][n_extra_regs]);
+    return m_syms[stub][n_extra_regs];
+}
+
 /* Define the structure for the machine field in struct function.  */
 
 struct GTY(()) stack_local_entry {
-- 
2.9.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]