diff --git a/gcc/config/riscv/arcv-rmx500.md b/gcc/config/riscv/arcv-rmx500.md index dd470a52c281..0c9df3e23da8 100644 --- a/gcc/config/riscv/arcv-rmx500.md +++ b/gcc/config/riscv/arcv-rmx500.md @@ -20,70 +20,86 @@ (define_automaton "arcv_rmx500") -(define_cpu_unit "arcv_rmx500_ALU" "arcv_rmx500") -;(define_cpu_unit "arcv_rmx500_CSR" "arcv_rmx500") -(define_cpu_unit "arcv_rmx500_FPU" "arcv_rmx500") -(define_cpu_unit "arcv_rmx500_MPY" "arcv_rmx500") -(define_cpu_unit "arcv_rmx500_DIV" "arcv_rmx500") -(define_cpu_unit "arcv_rmx500_DMP" "arcv_rmx500") - -;; Instruction reservation for arithmetic instructions. -(define_insn_reservation "arcv_rmx500_alu_arith" 3 +(define_cpu_unit "arcv_rmx500_ALU_A_fuse0_early" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_ALU_A_fuse1_early" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_ALU_B_fuse0_early" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_ALU_B_fuse1_early" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_MPY32" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_DIV" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_DMP_fuse0" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_DMP_fuse1" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_fdivsqrt" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_issueA_fuse0" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_issueA_fuse1" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_issueB_fuse0" "arcv_rmx500") +(define_cpu_unit "arcv_rmx500_issueB_fuse1" "arcv_rmx500") + +;; Instruction reservation for arithmetic instructions (pipe A, pipe B). +(define_insn_reservation "arcv_rmx500_alu_early_arith" 1 (and (eq_attr "tune" "arcv_rmx500") - (eq_attr "type" "unknown, const, arith, shift, slt, multi, auipc, nop, - logical, move, atomic, mvpair, bitmanip, clz, ctz, cpop, - zicond, condmove, clmul, min, max, minu, maxu")) - "arcv_rmx500_ALU, nothing*2") + (eq_attr "type" "unknown,move,const,arith,shift,slt,multi,auipc,nop,logical,\ + bitmanip,min,max,minu,maxu,clz,ctz,atomic,\ + condmove,mvpair,zicond,cpop,clmul")) + "((arcv_rmx500_issueA_fuse0 + arcv_rmx500_ALU_A_fuse0_early) | (arcv_rmx500_issueA_fuse1 + arcv_rmx500_ALU_A_fuse1_early)) | ((arcv_rmx500_issueB_fuse0 + arcv_rmx500_ALU_B_fuse0_early) | (arcv_rmx500_issueB_fuse1 + arcv_rmx500_ALU_B_fuse1_early))") + +(define_insn_reservation "arcv_rmx500_imul_fused" 1 + (and (eq_attr "tune" "arcv_rmx500") + (eq_attr "type" "imul_fused")) + "(arcv_rmx500_issueA_fuse0 + arcv_rmx500_issueA_fuse1 + arcv_rmx500_ALU_A_fuse0_early + arcv_rmx500_ALU_A_fuse1_early + arcv_rmx500_MPY32)") + +(define_insn_reservation "arcv_rmx500_alu_fused" 1 + (and (eq_attr "tune" "arcv_rmx500") + (eq_attr "type" "alu_fused")) + "(arcv_rmx500_issueA_fuse0 + arcv_rmx500_issueA_fuse1 + arcv_rmx500_ALU_A_fuse0_early + arcv_rmx500_ALU_A_fuse1_early) | (arcv_rmx500_issueB_fuse0 + arcv_rmx500_issueB_fuse1 + arcv_rmx500_ALU_B_fuse0_early + arcv_rmx500_ALU_B_fuse1_early)") + (define_insn_reservation "arcv_rmx500_jmp_insn" 1 (and (eq_attr "tune" "arcv_rmx500") - (eq_attr "type" "branch, jump, call, jalr, ret, trap")) - "arcv_rmx500_ALU") + (eq_attr "type" "branch,jump,call,jalr,ret,trap")) + "arcv_rmx500_issueA_fuse0 | arcv_rmx500_issueA_fuse1") (define_insn_reservation "arcv_rmx500_div_insn" 22 (and (eq_attr "tune" "arcv_rmx500") (eq_attr "type" "idiv")) - "arcv_rmx500_DIV*22") + "arcv_rmx500_issueA_fuse0 + arcv_rmx500_DIV, nothing*21") (define_insn_reservation "arcv_rmx500_mpy32_insn" 10 (and (eq_attr "tune" "arcv_rmx500") (eq_attr "type" "imul")) - "arcv_rmx500_MPY*10") + "arcv_rmx500_issueA_fuse0 + arcv_rmx500_MPY32, nothing*9") (define_insn_reservation "arcv_rmx500_load_insn" 1 (and (eq_attr "tune" "arcv_rmx500") (eq_attr "type" "load,fpload")) - "arcv_rmx500_DMP") + "(arcv_rmx500_issueB_fuse0 + arcv_rmx500_DMP_fuse0) | (arcv_rmx500_issueB_fuse1 + arcv_rmx500_DMP_fuse1)") (define_insn_reservation "arcv_rmx500_store_insn" 1 (and (eq_attr "tune" "arcv_rmx500") (eq_attr "type" "store,fpstore")) - "arcv_rmx500_DMP") + "(arcv_rmx500_issueB_fuse0 + arcv_rmx500_DMP_fuse0) | (arcv_rmx500_issueB_fuse1 + arcv_rmx500_DMP_fuse1)") -(define_insn_reservation "arcv_rmx500_farith_insn" 2 +;; (soft) floating points +(define_insn_reservation "arcv_rmx500_xfer" 2 (and (eq_attr "tune" "arcv_rmx500") - (eq_attr "type" "fadd,fmul,fmadd,fcmp")) - "arcv_rmx500_FPU*2") + (eq_attr "type" "mfc,mtc,fcvt,fcvt_i2f,fcvt_f2i,fmove,fcmp")) + "(arcv_rmx500_ALU_A_fuse0_early | arcv_rmx500_ALU_B_fuse0_early), nothing") -(define_insn_reservation "arcv_rmx500_fdiv_insn" 17 +(define_insn_reservation "arcv_rmx500_fmul" 2 (and (eq_attr "tune" "arcv_rmx500") - (eq_attr "type" "fdiv,fsqrt")) - "arcv_rmx500_FPU*17") + (eq_attr "type" "fadd,fmul,fmadd")) + "(arcv_rmx500_ALU_A_fuse0_early | arcv_rmx500_ALU_B_fuse0_early,nothing)") -(define_insn_reservation "arcv_rmx500_xfer" 2 +(define_insn_reservation "arcv_rmx500_fdiv" 17 (and (eq_attr "tune" "arcv_rmx500") - (eq_attr "type" "fmove,mtc,mfc,fcvt,fcvt_f2i,fcvt_i2f")) - "arcv_rmx500_FPU*2") - -;;(define_insn_reservation "core" 1 -;; (eq_attr "type" "block, brk, dmb, flag, lr, sr, sync") -;; "arcv_rmx500_ALU0 + arcv_rmx500_ALU1 + arcv_rmx500_DMP + arcv_rmx500_MPY + arcv_rmx500_MPY64 + arcv_rmx500_DIV") + (eq_attr "type" "fdiv,fsqrt")) + "arcv_rmx500_fdivsqrt*17") ;; Bypasses -(define_bypass 9 "arcv_rmx500_mpy32_insn" "arcv_rmx500_mpy32_insn,arcv_rmx500_div_insn") - -;;(define_bypass 1 "arcv_rmx500_alu_arith" "arcv_rmx500_mpy32_insn" "!accumulator_bypass_p") -(define_bypass 1 "arcv_rmx500_alu_arith,arcv_rmx500_load_insn" - "arcv_rmx500_alu_arith,arcv_rmx500_mpy32_insn,arcv_rmx500_div_insn,arcv_rmx500_load_insn") -(define_bypass 1 "arcv_rmx500_alu_arith,arcv_rmx500_load_insn" - "arcv_rmx500_store_insn" "riscv_store_data_bypass_p") +(define_bypass 1 "arcv_rmx500_alu_early_arith" "arcv_rmx500_store_insn" "riscv_store_data_bypass_p") +(define_bypass 1 "arcv_rmx500_load_insn" "arcv_rmx500_store_insn" "riscv_store_data_bypass_p") +(define_bypass 1 "arcv_rmx500_load_insn" "arcv_rmx500_alu_early_arith") +(define_bypass 1 "arcv_rmx500_load_insn" "arcv_rmx500_mpy*_insn") +(define_bypass 1 "arcv_rmx500_load_insn" "arcv_rmx500_load_insn") +(define_bypass 1 "arcv_rmx500_load_insn" "arcv_rmx500_div_insn") +(define_bypass 9 "arcv_rmx500_mpy32_insn" "arcv_rmx500_mpy*_insn") +(define_bypass 9 "arcv_rmx500_mpy32_insn" "arcv_rmx500_div_insn") diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 04046af90f5f..327220662c43 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -861,6 +861,7 @@ bool arcv_micro_arch_supports_fusion_p (void) { return (riscv_is_micro_arch (arcv_rhx100) + || riscv_is_micro_arch (arcv_rmx500) || riscv_is_micro_arch (arcv_rpx100)); } @@ -10841,7 +10842,8 @@ riscv_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, int *n_readyp, int clock ATTRIBUTE_UNUSED) { - if (sched_fusion) + + if (sched_fusion) return cached_can_issue_more; if (!cached_can_issue_more) @@ -10855,11 +10857,12 @@ riscv_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, { for (int i = 1; i <= *n_readyp; i++) { - if (NONDEBUG_INSN_P (ready[*n_readyp - i]) - && !SCHED_GROUP_P (ready[*n_readyp - i]) - && (!next_insn (ready[*n_readyp - i]) - || !NONDEBUG_INSN_P (next_insn (ready[*n_readyp - i])) - || !SCHED_GROUP_P (next_insn (ready[*n_readyp - i]))) + /*try to fuse the last_scheduled_insn with */ + if (NONDEBUG_INSN_P (ready[*n_readyp - i]) /*fuse only with nondebug insn*/ + && !SCHED_GROUP_P (ready[*n_readyp - i]) /*which have not been already fused*/ + && (!next_nonnote_nondebug_insn (ready[*n_readyp - i]) /* no real insn comes after*/ + /*dont fuse at the expense of breaking another fuse*/ + || !SCHED_GROUP_P (next_nonnote_nondebug_insn (ready[*n_readyp - i]))) && arcv_macro_fusion_pair_p (last_scheduled_insn, ready[*n_readyp - i])) { std::swap (ready[*n_readyp - 1], ready[*n_readyp - i]); @@ -10872,8 +10875,7 @@ riscv_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, } /* Try to fuse a non-memory last_scheduled_insn. */ - if ((!alu_pipe_scheduled_p || !pipeB_scheduled_p) - && last_scheduled_insn && ready && *n_readyp > 0 + if ((!alu_pipe_scheduled_p || !pipeB_scheduled_p) && last_scheduled_insn && ready && *n_readyp > 0 && !SCHED_GROUP_P (last_scheduled_insn) && (get_attr_type (last_scheduled_insn) != TYPE_LOAD && get_attr_type (last_scheduled_insn) != TYPE_STORE)) @@ -10882,10 +10884,9 @@ riscv_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, { if (NONDEBUG_INSN_P (ready[*n_readyp - i]) && !SCHED_GROUP_P (ready[*n_readyp - i]) - && (!next_insn (ready[*n_readyp - i]) - || !NONDEBUG_INSN_P (next_insn (ready[*n_readyp - i])) - || !SCHED_GROUP_P (next_insn (ready[*n_readyp - i]))) - && arcv_macro_fusion_pair_p (last_scheduled_insn, ready[*n_readyp - i])) + && (!next_nonnote_nondebug_insn (ready[*n_readyp - i]) + || !SCHED_GROUP_P (next_nonnote_nondebug_insn (ready[*n_readyp - i]))) + && arcv_macro_fusion_pair_p (last_scheduled_insn, ready[*n_readyp - i])) { if (get_attr_type (ready[*n_readyp - i]) == TYPE_LOAD || get_attr_type (ready[*n_readyp - i]) == TYPE_STORE) @@ -10924,11 +10925,11 @@ riscv_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, && get_attr_type (ready[*n_readyp - i]) != TYPE_LOAD && get_attr_type (ready[*n_readyp - i]) != TYPE_STORE && !SCHED_GROUP_P (ready[*n_readyp - i]) - && ((!next_insn (ready[*n_readyp - i]) - || !NONDEBUG_INSN_P (next_insn (ready[*n_readyp - i])) - || !SCHED_GROUP_P (next_insn (ready[*n_readyp - i]))))) + && (!next_nonnote_nondebug_insn (ready[*n_readyp - i]) + || !SCHED_GROUP_P (next_nonnote_nondebug_insn (ready[*n_readyp - i]))) + ) || ((next_insn (ready[*n_readyp - i]) - && NONDEBUG_INSN_P (next_insn (ready[*n_readyp - i])) + /* && NONDEBUG_INSN_P (next_insn (ready[*n_readyp - i])) */ && recog_memoized (next_insn (ready[*n_readyp - i])) >= 0 && get_attr_type (next_insn (ready[*n_readyp - i])) != TYPE_LOAD && get_attr_type (next_insn (ready[*n_readyp - i])) != TYPE_STORE))) @@ -11475,7 +11476,8 @@ riscv_override_options_internal (struct gcc_options *opts) /* Enable advanced fusion for the ARC-V cores that support it unless explicitly disabled. - TODO Add arcv_rmx500 once it supports fusion. */ + advanced fusion for rmx500 is turned on by an option. + */ if ((riscv_microarchitecture == arcv_rhx100 || riscv_microarchitecture == arcv_rpx100) && (target_flags_explicit & MASK_ARCV_ADVANCED_FUSION) == 0) diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index d68b15684337..0b2317dc18e0 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4435,8 +4435,8 @@ (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand")) (sign_extend:SI (match_operand:HI 2 "register_operand"))) (match_operand:SI 3 "register_operand")))] - "TARGET_XTHEADMAC || (TARGET_ARCV_ADVANCED_FUSION - && (TARGET_ZMMUL || TARGET_MUL))" + "(TARGET_XTHEADMAC || (TARGET_ARCV_ADVANCED_FUSION + && (TARGET_ZMMUL || TARGET_MUL)))" { if (TARGET_ARCV_ADVANCED_FUSION) {