diff options
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 20 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 47 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 51 | ||||
-rw-r--r-- | gcc/config/aarch64/driver-aarch64.c | 44 | ||||
-rw-r--r-- | gcc/config/aarch64/t-aarch64 | 2 |
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 |