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 <meiss...@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: meiss...@linux.ibm.com, phone: +1 (978) 899-4797