summaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r--gcc/config/aarch64/aarch64-simd.md20
-rw-r--r--gcc/config/aarch64/aarch64.c47
-rw-r--r--gcc/config/aarch64/aarch64.md51
-rw-r--r--gcc/config/aarch64/driver-aarch64.c44
-rw-r--r--gcc/config/aarch64/t-aarch642
5 files changed, 114 insertions, 50 deletions
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 9ce7f000509..89bdcb3f7ed 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -5705,6 +5705,26 @@
[(set_attr "type" "crypto_sha1_fast")]
)
+(define_insn "aarch64_crypto_sha1hv4si"
+ [(set (match_operand:SI 0 "register_operand" "=w")
+ (unspec:SI [(vec_select:SI (match_operand:V4SI 1 "register_operand" "w")
+ (parallel [(const_int 0)]))]
+ UNSPEC_SHA1H))]
+ "TARGET_SIMD && TARGET_CRYPTO && !BYTES_BIG_ENDIAN"
+ "sha1h\\t%s0, %s1"
+ [(set_attr "type" "crypto_sha1_fast")]
+)
+
+(define_insn "aarch64_be_crypto_sha1hv4si"
+ [(set (match_operand:SI 0 "register_operand" "=w")
+ (unspec:SI [(vec_select:SI (match_operand:V4SI 1 "register_operand" "w")
+ (parallel [(const_int 3)]))]
+ UNSPEC_SHA1H))]
+ "TARGET_SIMD && TARGET_CRYPTO && BYTES_BIG_ENDIAN"
+ "sha1h\\t%s0, %s1"
+ [(set_attr "type" "crypto_sha1_fast")]
+)
+
(define_insn "aarch64_crypto_sha1su1v4si"
[(set (match_operand:V4SI 0 "register_operand" "=w")
(unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index df74ad96949..b7d4640826a 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2936,12 +2936,18 @@ aarch64_layout_frame (void)
cfun->machine->frame.laid_out = true;
}
+/* Return true if the register REGNO is saved on entry to
+ the current function. */
+
static bool
aarch64_register_saved_on_entry (int regno)
{
return cfun->machine->frame.reg_offset[regno] >= 0;
}
+/* Return the next register up from REGNO up to LIMIT for the callee
+ to save. */
+
static unsigned
aarch64_next_callee_save (unsigned regno, unsigned limit)
{
@@ -2950,6 +2956,9 @@ aarch64_next_callee_save (unsigned regno, unsigned limit)
return regno;
}
+/* Push the register number REGNO of mode MODE to the stack with write-back
+ adjusting the stack by ADJUSTMENT. */
+
static void
aarch64_pushwb_single_reg (machine_mode mode, unsigned regno,
HOST_WIDE_INT adjustment)
@@ -2966,6 +2975,10 @@ aarch64_pushwb_single_reg (machine_mode mode, unsigned regno,
RTX_FRAME_RELATED_P (insn) = 1;
}
+/* Generate and return an instruction to store the pair of registers
+ REG and REG2 of mode MODE to location BASE with write-back adjusting
+ the stack location BASE by ADJUSTMENT. */
+
static rtx
aarch64_gen_storewb_pair (machine_mode mode, rtx base, rtx reg, rtx reg2,
HOST_WIDE_INT adjustment)
@@ -2985,6 +2998,9 @@ aarch64_gen_storewb_pair (machine_mode mode, rtx base, rtx reg, rtx reg2,
}
}
+/* Push registers numbered REGNO1 and REGNO2 to the stack, adjusting the
+ stack pointer by ADJUSTMENT. */
+
static void
aarch64_push_regs (unsigned regno1, unsigned regno2, HOST_WIDE_INT adjustment)
{
@@ -3004,6 +3020,9 @@ aarch64_push_regs (unsigned regno1, unsigned regno2, HOST_WIDE_INT adjustment)
RTX_FRAME_RELATED_P (insn) = 1;
}
+/* Load the pair of register REG, REG2 of mode MODE from stack location BASE,
+ adjusting it by ADJUSTMENT afterwards. */
+
static rtx
aarch64_gen_loadwb_pair (machine_mode mode, rtx base, rtx reg, rtx reg2,
HOST_WIDE_INT adjustment)
@@ -3021,6 +3040,10 @@ aarch64_gen_loadwb_pair (machine_mode mode, rtx base, rtx reg, rtx reg2,
}
}
+/* Pop the two registers numbered REGNO1, REGNO2 from the stack, adjusting it
+ afterwards by ADJUSTMENT and writing the appropriate REG_CFA_RESTORE notes
+ into CFI_OPS. */
+
static void
aarch64_pop_regs (unsigned regno1, unsigned regno2, HOST_WIDE_INT adjustment,
rtx *cfi_ops)
@@ -3045,6 +3068,9 @@ aarch64_pop_regs (unsigned regno1, unsigned regno2, HOST_WIDE_INT adjustment,
}
}
+/* Generate and return a store pair instruction of mode MODE to store
+ register REG1 to MEM1 and register REG2 to MEM2. */
+
static rtx
aarch64_gen_store_pair (machine_mode mode, rtx mem1, rtx reg1, rtx mem2,
rtx reg2)
@@ -3062,6 +3088,9 @@ aarch64_gen_store_pair (machine_mode mode, rtx mem1, rtx reg1, rtx mem2,
}
}
+/* Generate and regurn a load pair isntruction of mode MODE to load register
+ REG1 from MEM1 and register REG2 from MEM2. */
+
static rtx
aarch64_gen_load_pair (machine_mode mode, rtx reg1, rtx mem1, rtx reg2,
rtx mem2)
@@ -3079,6 +3108,9 @@ aarch64_gen_load_pair (machine_mode mode, rtx reg1, rtx mem1, rtx reg2,
}
}
+/* Emit code to save the callee-saved registers from register number START
+ to LIMIT to the stack at the location starting at offset START_OFFSET,
+ skipping any write-back candidates if SKIP_WB is true. */
static void
aarch64_save_callee_saves (machine_mode mode, HOST_WIDE_INT start_offset,
@@ -3137,6 +3169,11 @@ aarch64_save_callee_saves (machine_mode mode, HOST_WIDE_INT start_offset,
}
}
+/* Emit code to restore the callee registers of mode MODE from register
+ number START up to and including LIMIT. Restore from the stack offset
+ START_OFFSET, skipping any write-back candidates if SKIP_WB is true.
+ Write the appropriate REG_CFA_RESTORE notes into CFI_OPS. */
+
static void
aarch64_restore_callee_saves (machine_mode mode,
HOST_WIDE_INT start_offset, unsigned start,
@@ -13197,7 +13234,7 @@ aarch64_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
}
static rtx
-aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
+aarch64_gen_ccmp_first (rtx_insn **prep_seq, rtx_insn **gen_seq,
int code, tree treeop0, tree treeop1)
{
machine_mode op_mode, cmp_mode, cc_mode = CCmode;
@@ -13271,8 +13308,8 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
}
static rtx
-aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
- tree treeop0, tree treeop1, int bit_code)
+aarch64_gen_ccmp_next (rtx_insn **prep_seq, rtx_insn **gen_seq, rtx prev,
+ int cmp_code, tree treeop0, tree treeop1, int bit_code)
{
rtx op0, op1, target;
machine_mode op_mode, cmp_mode, cc_mode = CCmode;
@@ -13281,7 +13318,7 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
struct expand_operand ops[6];
int aarch64_cond;
- push_to_sequence ((rtx_insn*) *prep_seq);
+ push_to_sequence (*prep_seq);
expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
op_mode = GET_MODE (op0);
@@ -13347,7 +13384,7 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
create_fixed_operand (&ops[4], prev);
create_fixed_operand (&ops[5], GEN_INT (aarch64_cond));
- push_to_sequence ((rtx_insn*) *gen_seq);
+ push_to_sequence (*gen_seq);
if (!maybe_expand_insn (icode, 6, ops))
{
end_sequence ();
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6afaf906915..46eaa30b159 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -639,7 +639,8 @@
[(set (pc) (if_then_else
(EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
(const_int 1)
- (match_operand 1 "const_int_operand" "n"))
+ (match_operand 1
+ "aarch64_simd_shift_imm_<mode>" "n"))
(const_int 0))
(label_ref (match_operand 2 "" ""))
(pc)))
@@ -1605,25 +1606,12 @@
(match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
""
{
- if (aarch64_pluslong_strict_immedate (operands[2], <MODE>mode))
- {
- /* Give CSE the opportunity to share this constant across additions. */
- if (!cse_not_expected && can_create_pseudo_p ())
- operands[2] = force_reg (<MODE>mode, operands[2]);
-
- /* Split will refuse to operate on a modification to the stack pointer.
- Aid the prologue and epilogue expanders by splitting this now. */
- else if (reload_completed && operands[0] == stack_pointer_rtx)
- {
- HOST_WIDE_INT i = INTVAL (operands[2]);
- HOST_WIDE_INT s = (i >= 0 ? i & 0xfff : -(-i & 0xfff));
- emit_insn (gen_rtx_SET (operands[0],
- gen_rtx_PLUS (<MODE>mode, operands[1],
- GEN_INT (i - s))));
- operands[1] = operands[0];
- operands[2] = GEN_INT (s);
- }
- }
+ /* If the constant is too large for a single instruction and isn't frame
+ based, split off the immediate so it is available for CSE. */
+ if (!aarch64_plus_immediate (operands[2], <MODE>mode)
+ && can_create_pseudo_p ()
+ && !REGNO_PTR_FRAME_P (REGNO (operands[1])))
+ operands[2] = force_reg (<MODE>mode, operands[2]);
})
(define_insn "*add<mode>3_aarch64"
@@ -4281,19 +4269,28 @@
(define_expand "<optab>"
[(set (match_operand:DI 0 "register_operand" "=r")
- (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "n")
- (match_operand 3 "const_int_operand" "n")))]
- ""
+ (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand")
+ (match_operand 2
+ "aarch64_simd_shift_imm_offset_di")
+ (match_operand 3 "aarch64_simd_shift_imm_di")))]
""
+ {
+ if (!IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]),
+ 1, GET_MODE_BITSIZE (DImode) - 1))
+ FAIL;
+ }
)
+
(define_insn "*<optab><mode>"
[(set (match_operand:GPI 0 "register_operand" "=r")
(ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "n")
- (match_operand 3 "const_int_operand" "n")))]
- ""
+ (match_operand 2
+ "aarch64_simd_shift_imm_offset_<mode>" "n")
+ (match_operand 3
+ "aarch64_simd_shift_imm_<mode>" "n")))]
+ "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]),
+ 1, GET_MODE_BITSIZE (<MODE>mode) - 1)"
"<su>bfx\\t%<w>0, %<w>1, %3, %2"
[(set_attr "type" "bfm")]
)
diff --git a/gcc/config/aarch64/driver-aarch64.c b/gcc/config/aarch64/driver-aarch64.c
index 658a4cd72e9..c21942c1aab 100644
--- a/gcc/config/aarch64/driver-aarch64.c
+++ b/gcc/config/aarch64/driver-aarch64.c
@@ -169,7 +169,6 @@ host_detect_local_cpu (int argc, const char **argv)
bool tune = false;
bool cpu = false;
unsigned int i = 0;
- unsigned int core_idx = 0;
unsigned char imp = INVALID_IMP;
unsigned int cores[2] = { INVALID_CORE, INVALID_CORE };
unsigned int n_cores = 0;
@@ -219,18 +218,13 @@ host_detect_local_cpu (int argc, const char **argv)
if (strstr (buf, "part") != NULL)
{
unsigned ccore = parse_field (buf);
- for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
- if (ccore == aarch64_cpu_data[i].part_no
- && !contains_core_p (cores, ccore))
- {
- if (n_cores == 2)
- goto not_found;
-
- cores[n_cores++] = ccore;
- core_idx = i;
- arch_id = aarch64_cpu_data[i].arch;
- break;
- }
+ if (!contains_core_p (cores, ccore))
+ {
+ if (n_cores == 2)
+ goto not_found;
+
+ cores[n_cores++] = ccore;
+ }
continue;
}
if (!tune && !processed_exts && strstr (buf, "Features") != NULL)
@@ -276,11 +270,19 @@ host_detect_local_cpu (int argc, const char **argv)
if (n_cores == 0 || n_cores > 2 || imp == INVALID_IMP)
goto not_found;
- if (arch && !arch_id)
- goto not_found;
-
if (arch)
{
+ /* Search for one of the cores in the list. */
+ for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+ if (aarch64_cpu_data[i].implementer_id == imp
+ && contains_core_p (cores, aarch64_cpu_data[i].part_no))
+ {
+ arch_id = aarch64_cpu_data[i].arch;
+ break;
+ }
+ if (!arch_id)
+ goto not_found;
+
struct aarch64_arch_driver_info* arch_info = get_arch_from_id (arch_id);
/* We got some arch indentifier that's not in aarch64-arches.def? */
@@ -312,7 +314,15 @@ host_detect_local_cpu (int argc, const char **argv)
/* The simple, non-big.LITTLE case. */
else
{
- if (aarch64_cpu_data[core_idx].implementer_id != imp)
+ int core_idx = -1;
+ for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+ if (cores[0] == aarch64_cpu_data[i].part_no
+ && aarch64_cpu_data[i].implementer_id == imp)
+ {
+ core_idx = i;
+ break;
+ }
+ if (core_idx == -1)
goto not_found;
res = concat ("-m", cpu ? "cpu" : "tune", "=",
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index 04eb63666e8..b461eb5bede 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -52,7 +52,7 @@ aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
$(srcdir)/config/arm/aarch-common.c
aarch64-c.o: $(srcdir)/config/aarch64/aarch64-c.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
+ coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/aarch64/aarch64-c.c