From: Jeff Law Date: Fri, 2 Jul 2021 15:07:37 +0000 (-0400) Subject: Preparing to use shifts to eliminate redundant test/compare insns on H8 X-Git-Tag: basepoints/gcc-13~6329 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b60761baa6fd6acf3200e732283d133f4ce0f0e9;p=thirdparty%2Fgcc.git Preparing to use shifts to eliminate redundant test/compare insns on H8 * config/h8300/h8300-protos.h (output_a_shift): Make first argument an array of rtx rather than a pointer to rtx. Add code argument. (compute_a_shift_length): Similarly. * config/h8300/h8300.c (h8300_shift_costs): Adjust now that the shift itself isn't an operand. Create dummy operand[0] to carry a mode and pass a suitable rtx code to compute_a_shift_length. (get_shift_alg): Adjust operand number of clobber in output templates. (output_a_shift): Make first argument an array of rtx rather than a pointer to rtx. Add code argument for the type of shift. Adjust now that the shift itself is no longer an operand. (compute_a_shift_length): Similarly. * config/h8300/shiftrotate.md (shiftqi, shifthi, shiftsi): Use an iterator rather than nshift_operator. (shiftqi_noscratch, shifthi_noscratch, shiftsi_noscratch): Likewise. (shiftqi_clobber_flags): Adjust to API changes in output_a_shift and compute_a_shift_length. (shiftqi_noscratch_clobber_flags): Likewise. (shifthi_noscratch_clobber_flags): Likewise. (shiftsi_noscratch_clobber_flags): Likewise. --- diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index d7efa978aa01..86bcc3fd3248 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -28,8 +28,8 @@ along with GCC; see the file COPYING3. If not see extern unsigned int compute_mov_length (rtx *); extern const char *output_plussi (rtx *, bool); extern unsigned int compute_plussi_length (rtx *, bool); -extern const char *output_a_shift (rtx *); -extern unsigned int compute_a_shift_length (rtx *); +extern const char *output_a_shift (rtx[4], rtx_code); +extern unsigned int compute_a_shift_length (rtx[4], rtx_code); extern const char *output_a_rotate (enum rtx_code, rtx *); extern unsigned int compute_a_rotate_length (rtx *); extern const char *output_simode_bld (int, rtx[]); diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index d8b4bfcbdbe7..0fdc68bf65be 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1108,18 +1108,17 @@ h8300_and_costs (rtx x) static int h8300_shift_costs (rtx x) { - rtx operands[4]; + rtx operands[3]; if (GET_MODE (x) != QImode && GET_MODE (x) != HImode && GET_MODE (x) != SImode) return 100; - operands[0] = NULL; + operands[0] = gen_rtx_REG (GET_MODE (x), 0); operands[1] = NULL; operands[2] = XEXP (x, 1); - operands[3] = x; - return compute_a_shift_length (operands) / 2; + return compute_a_shift_length (operands, GET_CODE (x)) / 2; } /* Worker function for TARGET_RTX_COSTS. */ @@ -3759,13 +3758,13 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode, switch (shift_type) { case SHIFT_ASHIFT: - info->special = "mov.w\t%e0,%f4\n\tmov.b\t%s4,%t4\n\tmov.b\t%t0,%s4\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f4,%e0"; + info->special = "mov.w\t%e0,%f3\n\tmov.b\t%s3,%t3\n\tmov.b\t%t0,%s3\n\tmov.b\t%s0,%t0\n\tsub.b\t%s0,%s0\n\tmov.w\t%f3,%e0"; goto end; case SHIFT_LSHIFTRT: - info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\textu.w\t%f4\n\tmov.w\t%f4,%e0"; + info->special = "mov.w\t%e0,%f3\n\tmov.b\t%t0,%s0\n\tmov.b\t%s3,%t0\n\tmov.b\t%t3,%s3\n\textu.w\t%f3\n\tmov.w\t%f3,%e0"; goto end; case SHIFT_ASHIFTRT: - info->special = "mov.w\t%e0,%f4\n\tmov.b\t%t0,%s0\n\tmov.b\t%s4,%t0\n\tmov.b\t%t4,%s4\n\texts.w\t%f4\n\tmov.w\t%f4,%e0"; + info->special = "mov.w\t%e0,%f3\n\tmov.b\t%t0,%s0\n\tmov.b\t%s3,%t0\n\tmov.b\t%t3,%s3\n\texts.w\t%f3\n\tmov.w\t%f3,%e0"; goto end; } } @@ -3985,12 +3984,10 @@ h8300_shift_needs_scratch_p (int count, machine_mode mode, enum rtx_code type) /* Output the assembler code for doing shifts. */ const char * -output_a_shift (rtx *operands) +output_a_shift (rtx operands[4], rtx_code code) { static int loopend_lab; - rtx shift = operands[3]; - machine_mode mode = GET_MODE (shift); - enum rtx_code code = GET_CODE (shift); + machine_mode mode = GET_MODE (operands[0]); enum shift_type shift_type; enum shift_mode shift_mode; struct shift_info info; @@ -4114,10 +4111,10 @@ output_a_shift (rtx *operands) if (info.shift2 != NULL) { fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n / 2, - names_big[REGNO (operands[4])]); + names_big[REGNO (operands[3])]); fprintf (asm_out_file, ".Llt%d:\n", loopend_lab); output_asm_insn (info.shift2, operands); - output_asm_insn ("add #0xff,%X4", operands); + output_asm_insn ("add #0xff,%X3", operands); fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab); if (n % 2) output_asm_insn (info.shift1, operands); @@ -4125,10 +4122,10 @@ output_a_shift (rtx *operands) else { fprintf (asm_out_file, "\tmov.b #%d,%sl\n", n, - names_big[REGNO (operands[4])]); + names_big[REGNO (operands[3])]); fprintf (asm_out_file, ".Llt%d:\n", loopend_lab); output_asm_insn (info.shift1, operands); - output_asm_insn ("add #0xff,%X4", operands); + output_asm_insn ("add #0xff,%X3", operands); fprintf (asm_out_file, "\tbne .Llt%d\n", loopend_lab); } return ""; @@ -4155,11 +4152,9 @@ h8300_asm_insn_count (const char *templ) /* Compute the length of a shift insn. */ unsigned int -compute_a_shift_length (rtx *operands) +compute_a_shift_length (rtx operands[3], rtx_code code) { - rtx shift = operands[3]; - machine_mode mode = GET_MODE (shift); - enum rtx_code code = GET_CODE (shift); + enum machine_mode mode = GET_MODE (operands[0]); enum shift_type shift_type; enum shift_mode shift_mode; struct shift_info info; diff --git a/gcc/config/h8300/shiftrotate.md b/gcc/config/h8300/shiftrotate.md index 23140d9ade85..c5d32cd6271d 100644 --- a/gcc/config/h8300/shiftrotate.md +++ b/gcc/config/h8300/shiftrotate.md @@ -152,168 +152,163 @@ (define_insn_and_split "*shiftqi" [(set (match_operand:QI 0 "register_operand" "=r,r") - (match_operator:QI 3 "nshift_operator" - [(match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "R,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn"))) + (clobber (match_scratch:QI 3 "=X,&r"))] "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) - (clobber (match_dup 4)) + [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3)) (clobber (reg:CC CC_REG))])]) (define_insn "*shiftqi_clobber_flags" [(set (match_operand:QI 0 "register_operand" "=r,r") - (match_operator:QI 3 "nshift_operator" - [(match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "R,rn")])) - (clobber (match_scratch:QI 4 "=X,&r")) + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn"))) + (clobber (match_scratch:QI 3 "=X,&r")) (clobber (reg:CC CC_REG))] "" { - return output_a_shift (operands); + return output_a_shift (operands, ); } [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands)"))]) + (symbol_ref "compute_a_shift_length (operands, )"))]) (define_insn_and_split "*shiftqi_noscratch" [(set (match_operand:QI 0 "register_operand" "=r,r") - (match_operator:QI 3 "nshift_operator" - [(match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "R,rn")]))] + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn")))] "(GET_CODE (operands[2]) == CONST_INT && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, - GET_CODE (operands[3])))" + ))" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) + [(parallel [(set (match_dup 0) (shifts:QI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])]) (define_insn "*shiftqi_noscratch_clobber_flags" [(set (match_operand:QI 0 "register_operand" "=r,r") - (match_operator:QI 3 "nshift_operator" - [(match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "R,rn")])) + (shifts:QI + (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "R,rn"))) (clobber (reg:CC CC_REG))] "(GET_CODE (operands[2]) == CONST_INT - && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, - GET_CODE (operands[3])))" + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode, ))" { - return output_a_shift (operands); + return output_a_shift (operands, ); } [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands)"))]) + (symbol_ref "compute_a_shift_length (operands, )"))]) (define_insn_and_split "*shifthi" [(set (match_operand:HI 0 "register_operand" "=r,r") - (match_operator:HI 3 "nshift_operator" - [(match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "S,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] + (shifts:HI + (match_operand:HI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "S,rn"))) + (clobber (match_scratch:QI 3 "=X,&r"))] "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) - (clobber (match_dup 4)) + [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3)) (clobber (reg:CC CC_REG))])]) (define_insn "*shifthi_clobber_flags" [(set (match_operand:HI 0 "register_operand" "=r,r") - (match_operator:HI 3 "nshift_operator" - [(match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "S,rn")])) - (clobber (match_scratch:QI 4 "=X,&r")) + (shifts:HI + (match_operand:HI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "S,rn"))) + (clobber (match_scratch:QI 3 "=X,&r")) (clobber (reg:CC CC_REG))] "" { - return output_a_shift (operands); + return output_a_shift (operands, ); } [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands)"))]) + (symbol_ref "compute_a_shift_length (operands, )"))]) (define_insn_and_split "*shifthi_noscratch" [(set (match_operand:HI 0 "register_operand" "=r,r") - (match_operator:HI 3 "nshift_operator" - [(match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "nonmemory_operand" "S,rn")]))] + (shifts:HI + (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "nonmemory_operand" "S,rn")))] "(GET_CODE (operands[2]) == CONST_INT - && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, - GET_CODE (operands[3])))" + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, ))" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) + [(parallel [(set (match_dup 0) (shifts:HI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])]) (define_insn "*shifthi_noscratch_clobber_flags" [(set (match_operand:HI 0 "register_operand" "=r,r") - (match_operator:HI 3 "nshift_operator" - [(match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "nonmemory_operand" "S,rn")])) + (shifts:HI + (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "nonmemory_operand" "S,rn"))) (clobber (reg:CC CC_REG))] "(GET_CODE (operands[2]) == CONST_INT - && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, - GET_CODE (operands[3])))" + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode, ))" { - return output_a_shift (operands); + return output_a_shift (operands, ); } [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands)"))]) + (symbol_ref "compute_a_shift_length (operands, )"))]) (define_insn_and_split "*shiftsi" [(set (match_operand:SI 0 "register_operand" "=r,r") - (match_operator:SI 3 "nshift_operator" - [(match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "T,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "T,rn"))) + (clobber (match_scratch:QI 3 "=X,&r"))] "" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) - (clobber (match_dup 4)) + [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2))) + (clobber (match_dup 3)) (clobber (reg:CC CC_REG))])]) (define_insn "*shiftsi_clobber_flags" [(set (match_operand:SI 0 "register_operand" "=r,r") - (match_operator:SI 3 "nshift_operator" - [(match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "T,rn")])) - (clobber (match_scratch:QI 4 "=X,&r")) + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "T,rn"))) + (clobber (match_scratch:QI 3 "=X,&r")) (clobber (reg:CC CC_REG))] "" { - return output_a_shift (operands); + return output_a_shift (operands, ); } [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands)"))]) + (symbol_ref "compute_a_shift_length (operands, )"))]) (define_insn_and_split "*shiftsi_noscratch" [(set (match_operand:SI 0 "register_operand" "=r,r") - (match_operator:SI 3 "nshift_operator" - [(match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "T,rn")]))] + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "T,rn")))] "(GET_CODE (operands[2]) == CONST_INT - && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, - GET_CODE (operands[3])))" + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, ))" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)])) + [(parallel [(set (match_dup 0) (shifts:SI (match_dup 1) (match_dup 2))) (clobber (reg:CC CC_REG))])]) (define_insn "*shiftsi_noscratch_clobber_flags" [(set (match_operand:SI 0 "register_operand" "=r,r") - (match_operator:SI 3 "nshift_operator" - [(match_operand:SI 1 "register_operand" "0,0") - (match_operand:SI 2 "nonmemory_operand" "T,rn")])) + (shifts:SI + (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "nonmemory_operand" "T,rn"))) (clobber (reg:CC CC_REG))] "(GET_CODE (operands[2]) == CONST_INT - && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, - GET_CODE (operands[3])))" + && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode, ))" { - return output_a_shift (operands); + return output_a_shift (operands, ); } [(set (attr "length") - (symbol_ref "compute_a_shift_length (operands)"))]) + (symbol_ref "compute_a_shift_length (operands, )"))]) ;; Split a variable shift into a loop. If the register containing ;; the shift count dies, then we just use that register.