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], PowerPC #12, Add instruction format enumeration


This is patch #12 which adds a new enumeration for instruction format.

As we discussed in patch #9, offset_format wasn't the best name.  This patch
adds the INSN_FORM enumeration that lists the 3 traditional offset instruction
formats (D/DS/DQ), indexed only instruction formats, and prefixed instruction
formats.  Its primary use is for deciding what instruction format to use for
offset instructions.

I have done a bootstrap on a little endian power8 system and there were no
regressions in the build or running make check.  Can I check this into the
trunk once patch #11 is checked in?

This is a series of separate patches to add functionality to the PowerPC
backend to support future processors.  Here is a high level summary of the
patches:

 * Patches 1-8, have already been applied
 * Patch 9 has been rewritten in patches 12-13
 * Patch 10 is withdrawn for now
 * Patch 11 adds DS offset mode to rs6000.c's reg_addr
 * Patch 12 adds a new enumeration for instruction format
 * Patch 13 adds support for matching prefixed insns
 * Patch 14 adds pc-relative support to load up addresses
 * Patch 15 renamed some functions to be smaller
 * Patch 16 updated a comment and moved a predicate
 * Patch 17 adds the prefixed RTL attribute & emitting 'p' before prefixed
 * Patch 18 adds prefixed support for scalar types
 * Patch 19 uses a separate 'future' cost structure
 * Patch 20 clones power9.md for initial scheduling on future.md.

The following patches have not yet been written, but I expect them to be:

 * Patch 21 finish prefixed insn support for vectors & 128-bit int/floats
 * Patch 22 enable pc-relative by default
 * Patch 23 add pcrel linker optimization
 * Patch 24 new tests

2019-07-24  Michael Meissner  <meissner@linux.ibm.com>

	* config/rs6000/rs6000.c (struct rs6000_reg_addr): Add default
	insn format field.
	(rs6000_debug_print_mode): If -mdebug=reg, print the default
	instruction format field.
	(addr_mask_to_insn_form): New function.
	(rs6000_setup_reg_addr_masks): Set up the default instruction
	format field.
	* config/rs6000/rs6000.md (INSN_FORM): New enumeration.

Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 273776)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -370,6 +370,7 @@ struct rs6000_reg_addr {
   enum insn_code reload_fpr_gpr;	/* INSN to move from FPR to GPR.  */
   enum insn_code reload_gpr_vsx;	/* INSN to move from GPR to VSX.  */
   enum insn_code reload_vsx_gpr;	/* INSN to move from VSX to GPR.  */
+  enum INSN_FORM default_insn_form;	/* Default format for offsets.  */
   addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks.  */
   bool scalar_in_vmx_p;			/* Scalar value can go in VMX.  */
 };
@@ -2118,6 +2119,38 @@ rs6000_debug_print_mode (ssize_t m)
     fprintf (stderr, " %s: %s", reload_reg_map[rc].name,
 	     rs6000_debug_addr_mask (reg_addr[m].addr_mask[rc], true));
 
+  switch (reg_addr[m].default_insn_form)
+    {
+    default:
+    case INSN_FORM_UNKNOWN:
+      fputs ("  form=?", stderr);
+      spaces++;
+      break;
+
+    case INSN_FORM_D:
+      fputs ("  form=d", stderr);
+      spaces++;
+      break;
+
+    case INSN_FORM_DS:
+      fputs ("  form=ds", stderr);
+      break;
+
+    case INSN_FORM_DQ:
+      fputs ("  form=dq", stderr);
+      break;
+
+    case INSN_FORM_X:
+      fputs ("  form=x", stderr);
+      spaces++;
+      break;
+
+    case INSN_FORM_PREFIXED:
+      fputs ("  form=p", stderr);
+      spaces++;
+      break;
+    }
+
   if ((reg_addr[m].reload_store != CODE_FOR_nothing)
       || (reg_addr[m].reload_load != CODE_FOR_nothing))
     {
@@ -2528,6 +2561,33 @@ rs6000_debug_reg_global (void)
 }
 
 
+/* Map an addr_mask into an instruction format.  The main use for INSN_FORM is
+   to determine if offsets are valid.  */
+
+static enum INSN_FORM
+addr_mask_to_insn_form (addr_mask_type mask)
+{
+  if ((mask & RELOAD_REG_VALID) == 0)
+    return INSN_FORM_UNKNOWN;
+
+  else if ((mask & RELOAD_REG_OFFSET) != 0)
+    {
+      if ((mask & RELOAD_REG_QUAD_OFFSET) != 0)
+	return INSN_FORM_DQ;
+
+      if ((mask & RELOAD_REG_DS_OFFSET) != 0)
+	return INSN_FORM_DS;
+
+      else
+	return INSN_FORM_D;
+    }
+
+  else if ((mask & RELOAD_REG_INDEXED) != 0)
+    return INSN_FORM_X;
+
+  return INSN_FORM_UNKNOWN;
+}
+
 /* Update the addr mask bits in reg_addr to help secondary reload and go if
    legitimate address support to figure out the appropriate addressing to
    use.  */
@@ -2536,7 +2596,7 @@ static void
 rs6000_setup_reg_addr_masks (void)
 {
   ssize_t rc, reg, m, nregs;
-  addr_mask_type any_addr_mask, addr_mask;
+  addr_mask_type any_addr_mask, addr_mask, default_mask;
 
   for (m = 0; m < NUM_MACHINE_MODES; ++m)
     {
@@ -2686,6 +2746,26 @@ rs6000_setup_reg_addr_masks (void)
 	}
 
       reg_addr[m].addr_mask[RELOAD_REG_ANY] = any_addr_mask;
+
+      /* Figure out the default insn format that is used for offsettable memory
+	 instructions.  For scalar floating point use the FPR addressing, for
+	 vector use either FPR or Altivec registers, and otherwise use
+	 GPRs.  */
+      if (ALTIVEC_OR_VSX_VECTOR_MODE (m2))
+	{
+	  if ((reg_addr[m].addr_mask[RELOAD_REG_FPR] & RELOAD_REG_VALID) != 0)
+	    default_mask = reg_addr[m].addr_mask[RELOAD_REG_FPR];
+	  else
+	    default_mask = reg_addr[m].addr_mask[RELOAD_REG_VMX];
+	}
+
+      else if ((SCALAR_FLOAT_MODE_P (m2) && msize <= 8) || float_2reg_p)
+	default_mask = reg_addr[m].addr_mask[RELOAD_REG_FPR];
+
+      else
+	default_mask = reg_addr[m].addr_mask[RELOAD_REG_GPR];
+
+      reg_addr[m].default_insn_form = addr_mask_to_insn_form (default_mask);
     }
 }
 
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 273771)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -177,6 +177,21 @@ (define_c_enum "unspecv"
 
 ; The three different kinds of epilogue.
 (define_enum "epilogue_type" [normal sibcall eh_return])
+
+
+;; Enumeration of the PowerPC instruction formats.  We only list the
+;; instruction formats that are used by the code, and not every possible
+;; instruction format that the machine supports.  The main use for this
+;; enumeration is to determine if a particular offsettable instruction has a
+;; valid offset field for a traditional instruction, or whether a prefixed
+;; instruction might be needed to hold the offset.
+(define_enum "INSN_FORM" [UNKNOWN	; Unknown format
+			  D		; Offset addressing uses 16 bits
+			  DS		; Offset addressing uses 14 bits
+			  DQ		; Offset addressing uses 12 bits
+			  X		; Indexed addressing
+			  PREFIXED])	; Prefixed instruction
+
 
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.ibm.com, phone: +1 (978) 899-4797


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