From 89c09c61d35a01e8f922da04aff0164b12bb2f0b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 10 Dec 2015 03:08:17 -0800 Subject: gcc: miscellaneous simplifications and improvements --- gcc/gcc/config/riscv/predicates.md | 2 +- gcc/gcc/config/riscv/riscv-protos.h | 2 - gcc/gcc/config/riscv/riscv.c | 181 ++++++++---------------------------- gcc/gcc/config/riscv/riscv.h | 42 ++------- 4 files changed, 44 insertions(+), 183 deletions(-) (limited to 'gcc') diff --git a/gcc/gcc/config/riscv/predicates.md b/gcc/gcc/config/riscv/predicates.md index 688c15c..b8a5d66 100644 --- a/gcc/gcc/config/riscv/predicates.md +++ b/gcc/gcc/config/riscv/predicates.md @@ -77,7 +77,7 @@ /* Otherwise check whether the constant can be loaded in a single instruction. */ - return !LUI_INT (op) && !SMALL_INT (op); + return !LUI_OPERAND (INTVAL (op)) && !SMALL_OPERAND (INTVAL (op)); }) (define_predicate "move_operand" diff --git a/gcc/gcc/config/riscv/riscv-protos.h b/gcc/gcc/config/riscv/riscv-protos.h index 8cc6a56..c84f2de 100644 --- a/gcc/gcc/config/riscv/riscv-protos.h +++ b/gcc/gcc/config/riscv/riscv-protos.h @@ -83,8 +83,6 @@ extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode); extern enum reg_class riscv_secondary_reload_class (enum reg_class, enum machine_mode, rtx, bool); -extern int riscv_class_max_nregs (enum reg_class, enum machine_mode); - extern unsigned int riscv_hard_regno_nregs (int, enum machine_mode); extern void irix_asm_output_align (FILE *, unsigned); diff --git a/gcc/gcc/config/riscv/riscv.c b/gcc/gcc/config/riscv/riscv.c index d8587fc..5c801c9 100644 --- a/gcc/gcc/config/riscv/riscv.c +++ b/gcc/gcc/config/riscv/riscv.c @@ -623,13 +623,13 @@ riscv_symbolic_constant_p (rtx x, enum riscv_symbol_type *symbol_type) static int riscv_symbol_insns (enum riscv_symbol_type type) { switch (type) - { + { case SYMBOL_TLS: return 0; /* Depends on the TLS model. */ case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference itself */ case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference itself */ case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference itself */ default: gcc_unreachable(); - } + } } /* Implement TARGET_LEGITIMATE_CONSTANT_P. */ @@ -658,7 +658,7 @@ riscv_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x) { /* As an optimization, don't spill symbolic constants that are as cheap to rematerialize as to access in the constant pool. */ - if (SMALL_INT (offset) && riscv_symbol_insns (type) > 0) + if (SMALL_OPERAND (INTVAL (offset)) && riscv_symbol_insns (type) > 0) return true; /* As an optimization, avoid needlessly generate dynamic relocations. */ @@ -800,7 +800,7 @@ riscv_classify_address (struct riscv_address_info *info, rtx x, /* Small-integer addresses don't occur very often, but they are legitimate if $0 is a valid base register. */ info->type = ADDRESS_CONST_INT; - return SMALL_INT (x); + return SMALL_OPERAND (INTVAL (x)); default: return false; @@ -879,25 +879,13 @@ riscv_const_insns (rtx x) if (riscv_symbolic_constant_p (x, &symbol_type)) return riscv_symbol_insns (symbol_type); - /* Otherwise try splitting the constant into a base and offset. - If the offset is a 16-bit value, we can load the base address - into a register and then use (D)ADDIU to add in the offset. - If the offset is larger, we can load the base and offset - into separate registers and add them together with (D)ADDU. - However, the latter is only possible before reload; during - and after reload, we must have the option of forcing the - constant into the pool instead. */ + /* Otherwise try splitting the constant into a base and offset. */ split_const (x, &x, &offset); if (offset != 0) { int n = riscv_const_insns (x); if (n != 0) - { - if (SMALL_INT (offset)) - return n + 1; - else if (!targetm.cannot_force_const_mem (GET_MODE (x), x)) - return n + 1 + riscv_integer_cost (INTVAL (offset)); - } + return n + riscv_integer_cost (INTVAL (offset)); } return 0; @@ -2604,7 +2592,7 @@ riscv_expand_call (bool sibcall_p, rtx result, rtx addr, rtx args_size) if (!call_insn_operand (addr, VOIDmode)) { - rtx reg = RISCV_EPILOGUE_TEMP (Pmode); + rtx reg = RISCV_PROLOGUE_TEMP (Pmode); riscv_emit_move (reg, addr); addr = reg; } @@ -3148,7 +3136,7 @@ riscv_compute_frame_info (void) frame->mask |= 1 << (regno - GP_REG_FIRST), num_x_saved++; /* Find out which FPRs we need to save. This loop must iterate over - the same space as its companion in riscv_for_each_saved_gpr_and_fpr. */ + the same space as its companion in riscv_for_each_saved_reg. */ if (TARGET_HARD_FLOAT) for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) if (riscv_save_reg_p (regno)) @@ -3281,8 +3269,7 @@ riscv_save_restore_reg (enum machine_mode mode, int regno, of the frame. */ static void -riscv_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset, - riscv_save_restore_fn fn) +riscv_for_each_saved_reg (HOST_WIDE_INT sp_offset, riscv_save_restore_fn fn) { HOST_WIDE_INT offset; int regno; @@ -3307,49 +3294,21 @@ riscv_for_each_saved_gpr_and_fpr (HOST_WIDE_INT sp_offset, } } -/* Emit a move from SRC to DEST, given that one of them is a register - save slot and that the other is a register. TEMP is a temporary - GPR of the same mode that is available if need be. */ +/* Save register REG to MEM. Make the instruction frame-related. */ static void -riscv_emit_save_slot_move (rtx dest, rtx src, rtx temp) +riscv_save_reg (rtx reg, rtx mem) { - unsigned int regno; - rtx mem; - enum reg_class rclass; - - if (REG_P (src)) - { - regno = REGNO (src); - mem = dest; - } - else - { - regno = REGNO (dest); - mem = src; - } - - rclass = riscv_secondary_reload_class (REGNO_REG_CLASS (regno), - GET_MODE (mem), mem, mem == src); - - if (rclass == NO_REGS) - riscv_emit_move (dest, src); - else - { - gcc_assert (!reg_overlap_mentioned_p (dest, temp)); - riscv_emit_move (temp, src); - riscv_emit_move (dest, temp); - } - if (MEM_P (dest)) - riscv_set_frame_expr (riscv_frame_set (dest, src)); + riscv_emit_move (mem, reg); + riscv_set_frame_expr (riscv_frame_set (mem, reg)); } -/* Save register REG to MEM. Make the instruction frame-related. */ +/* Restore register REG from MEM. */ static void -riscv_save_reg (rtx reg, rtx mem) +riscv_restore_reg (rtx reg, rtx mem) { - riscv_emit_save_slot_move (mem, reg, RISCV_PROLOGUE_TEMP (GET_MODE (reg))); + riscv_emit_move (reg, mem); } /* Return the code to invoke the GPR save routine. */ @@ -3414,7 +3373,7 @@ riscv_expand_prologue (void) GEN_INT (-step1)); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; size -= step1; - riscv_for_each_saved_gpr_and_fpr (size, riscv_save_reg); + riscv_for_each_saved_reg (size, riscv_save_reg); } frame->mask = mask; /* Undo the above fib. */ @@ -3450,14 +3409,6 @@ riscv_expand_prologue (void) } } } - -/* Emit instructions to restore register REG from slot MEM. */ - -static void -riscv_restore_reg (rtx reg, rtx mem) -{ - riscv_emit_save_slot_move (reg, mem, RISCV_EPILOGUE_TEMP (GET_MODE (reg))); -} /* Expand an "epilogue" or "sibcall_epilogue" pattern; SIBCALL_P says which. */ @@ -3487,13 +3438,14 @@ riscv_expand_epilogue (bool sibcall_p) if (cfun->calls_alloca) { rtx adjust = GEN_INT (-frame->hard_frame_pointer_offset); - if (!SMALL_INT (adjust)) + if (!SMALL_OPERAND (INTVAL (adjust))) { - riscv_emit_move (RISCV_EPILOGUE_TEMP (Pmode), adjust); - adjust = RISCV_EPILOGUE_TEMP (Pmode); + riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust); + adjust = RISCV_PROLOGUE_TEMP (Pmode); } - emit_insn (gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, adjust)); + emit_insn (gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, + adjust)); } /* If we need to restore registers, deallocate as much stack as @@ -3511,8 +3463,8 @@ riscv_expand_epilogue (bool sibcall_p) rtx adjust = GEN_INT (step1); if (!SMALL_OPERAND (step1)) { - riscv_emit_move (RISCV_EPILOGUE_TEMP (Pmode), adjust); - adjust = RISCV_EPILOGUE_TEMP (Pmode); + riscv_emit_move (RISCV_PROLOGUE_TEMP (Pmode), adjust); + adjust = RISCV_PROLOGUE_TEMP (Pmode); } emit_insn (gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, adjust)); @@ -3522,8 +3474,7 @@ riscv_expand_epilogue (bool sibcall_p) frame->mask = 0; /* Temporarily fib that we need not save GPRs. */ /* Restore the registers. */ - riscv_for_each_saved_gpr_and_fpr (frame->total_size - step2, - riscv_restore_reg); + riscv_for_each_saved_reg (frame->total_size - step2, riscv_restore_reg); if (use_restore_libcall) { @@ -3618,25 +3569,18 @@ riscv_hard_regno_nregs (int regno, enum machine_mode mode) return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; } -/* Implement CLASS_MAX_NREGS, taking the maximum of the cases - in riscv_hard_regno_nregs. */ +/* Implement CLASS_MAX_NREGS. */ -int -riscv_class_max_nregs (enum reg_class rclass, enum machine_mode mode) +static unsigned char +riscv_class_max_nregs (reg_class_t rclass, enum machine_mode mode) { - int size; - HARD_REG_SET left; + if (reg_class_subset_p (FP_REGS, rclass)) + return riscv_hard_regno_nregs (FP_REG_FIRST, mode); - size = 0x8000; - COPY_HARD_REG_SET (left, reg_class_contents[(int) rclass]); - if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS])) - { - size = MIN (size, UNITS_PER_FPREG); - AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) FP_REGS]); - } - if (!hard_reg_set_empty_p (left)) - size = MIN (size, UNITS_PER_WORD); - return (GET_MODE_SIZE (mode) + size - 1) / size; + if (reg_class_subset_p (GR_REGS, rclass)) + return riscv_hard_regno_nregs (GP_REG_FIRST, mode); + + return 0; } /* Implement TARGET_PREFERRED_RELOAD_CLASS. */ @@ -3649,18 +3593,6 @@ riscv_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass) rclass; } -/* RCLASS is a class involved in a REGISTER_MOVE_COST calculation. - Return a "canonical" class to represent it in later calculations. */ - -static reg_class_t -riscv_canonicalize_move_class (reg_class_t rclass) -{ - if (reg_class_subset_p (rclass, GENERAL_REGS)) - rclass = GENERAL_REGS; - - return rclass; -} - /* Implement TARGET_MEMORY_MOVE_COST. */ static int @@ -3670,48 +3602,6 @@ riscv_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in) + memory_move_secondary_cost (mode, rclass, in)); } -/* Return the register class required for a secondary register when - copying between one of the registers in RCLASS and value X, which - has mode MODE. X is the source of the move if IN_P, otherwise it - is the destination. Return NO_REGS if no secondary register is - needed. */ - -enum reg_class -riscv_secondary_reload_class (enum reg_class rclass, - enum machine_mode mode, rtx x, - bool in_p ATTRIBUTE_UNUSED) -{ - int regno; - - regno = true_regnum (x); - - if (reg_class_subset_p (rclass, FP_REGS)) - { - if (MEM_P (x) && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)) - /* We can use flw/fld/fsw/fsd. */ - return NO_REGS; - - if (GP_REG_P (regno) || x == CONST0_RTX (mode)) - /* We can use fmv or go through memory when mode > Pmode. */ - return NO_REGS; - - if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (mode, x)) - /* We can force the constant to memory and use flw/fld. */ - return NO_REGS; - - if (FP_REG_P (regno)) - /* We can use fmv.fmt. */ - return NO_REGS; - - /* Otherwise, we need to reload through an integer register. */ - return GR_REGS; - } - if (FP_REG_P (regno)) - return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS; - - return NO_REGS; -} - /* Implement TARGET_MODE_REP_EXTENDED. */ static int @@ -4393,6 +4283,9 @@ riscv_lra_p (void) #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE riscv_conditional_register_usage +#undef TARGET_CLASS_MAX_NREGS +#define TARGET_CLASS_MAX_NREGS riscv_class_max_nregs + #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT riscv_trampoline_init diff --git a/gcc/gcc/config/riscv/riscv.h b/gcc/gcc/config/riscv/riscv.h index 34e0a5a..8557cbf 100644 --- a/gcc/gcc/config/riscv/riscv.h +++ b/gcc/gcc/config/riscv/riscv.h @@ -254,10 +254,6 @@ along with GCC; see the file COPYING3. If not see /* We currently require both or neither of the `F' and `D' extensions. */ #define UNITS_PER_FPREG 8 -/* If FP regs aren't wide enough for a given FP argument, it is passed in - integer registers. */ -#define MIN_FPRS_PER_FMT 1 - /* The largest size of value that can be held in floating-point registers and moved with a single instruction. */ #define UNITS_PER_HWFPVALUE \ @@ -390,11 +386,11 @@ along with GCC; see the file COPYING3. If not see Extensions of pointers to word_mode must be signed. */ #define POINTERS_EXTEND_UNSIGNED false -/* RV32 double-precision FP <-> integer moves go through memory */ -#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - (!TARGET_64BIT && GET_MODE_SIZE (MODE) == 8 && \ - (((CLASS1) == FP_REGS && (CLASS2) != FP_REGS) \ - || ((CLASS2) == FP_REGS && (CLASS1) != FP_REGS))) +/* When floating-point registers are wider than integer ones, moves between + them must go through memory. */ +#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ + (GET_MODE_SIZE (MODE) > UNITS_PER_WORD \ + && ((CLASS1) == FP_REGS) != ((CLASS2) == FP_REGS)) /* Define if loading short immediate values into registers sign extends. */ #define SHORT_IMMEDIATES_SIGN_EXTEND @@ -515,10 +511,7 @@ along with GCC; see the file COPYING3. If not see the frame pointer, the EH stack adjustment, or the EH data registers. */ #define RISCV_PROLOGUE_TEMP_REGNUM (GP_TEMP_FIRST + 1) -#define RISCV_EPILOGUE_TEMP_REGNUM RISCV_PROLOGUE_TEMP_REGNUM - #define RISCV_PROLOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_PROLOGUE_TEMP_REGNUM) -#define RISCV_EPILOGUE_TEMP(MODE) gen_rtx_REG (MODE, RISCV_EPILOGUE_TEMP_REGNUM) #define FUNCTION_PROFILER(STREAM, LABELNO) \ { \ @@ -644,7 +637,7 @@ enum reg_class 64, 65 \ } -/* True if VALUE is a signed 16-bit number. */ +/* True if VALUE is a signed 12-bit number. */ #define SMALL_OPERAND(VALUE) \ ((unsigned HOST_WIDE_INT) (VALUE) + IMM_REACH/2 < IMM_REACH) @@ -655,29 +648,6 @@ enum reg_class (((VALUE) | ((1UL<<31) - IMM_REACH)) == ((1UL<<31) - IMM_REACH) \ || ((VALUE) | ((1UL<<31) - IMM_REACH)) + IMM_REACH == 0) -/* Return a value X with the low 16 bits clear, and such that - VALUE - X is a signed 16-bit value. */ - -#define SMALL_INT(X) SMALL_OPERAND (INTVAL (X)) -#define LUI_INT(X) LUI_OPERAND (INTVAL (X)) - -/* The HI and LO registers can only be reloaded via the general - registers. Condition code registers can only be loaded to the - general registers, and from the floating point registers. */ - -#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ - riscv_secondary_reload_class (CLASS, MODE, X, true) -#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ - riscv_secondary_reload_class (CLASS, MODE, X, false) - -/* Return the maximum number of consecutive registers - needed to represent mode MODE in a register of class CLASS. */ - -#define CLASS_MAX_NREGS(CLASS, MODE) riscv_class_max_nregs (CLASS, MODE) - -/* It is undefined to interpret an FP register in a different format than - that which it was created to be. */ - #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ reg_classes_intersect_p (FP_REGS, CLASS) -- cgit v1.1