aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-12-10 03:08:17 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-12-10 03:08:17 -0800
commit89c09c61d35a01e8f922da04aff0164b12bb2f0b (patch)
tree646103bbed114356dac510a45a54c98c0eddca3a /gcc
parent99d308218f152f0a454ee2fc2eec42a7dd371ba9 (diff)
downloadriscv-gnu-toolchain-89c09c61d35a01e8f922da04aff0164b12bb2f0b.zip
riscv-gnu-toolchain-89c09c61d35a01e8f922da04aff0164b12bb2f0b.tar.gz
riscv-gnu-toolchain-89c09c61d35a01e8f922da04aff0164b12bb2f0b.tar.bz2
gcc: miscellaneous simplifications and improvements
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/config/riscv/predicates.md2
-rw-r--r--gcc/gcc/config/riscv/riscv-protos.h2
-rw-r--r--gcc/gcc/config/riscv/riscv.c181
-rw-r--r--gcc/gcc/config/riscv/riscv.h42
4 files changed, 44 insertions, 183 deletions
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)