diff options
Diffstat (limited to 'gcc/config/xtensa')
-rw-r--r-- | gcc/config/xtensa/constraints.md | 2 | ||||
-rw-r--r-- | gcc/config/xtensa/predicates.md | 3 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.cc | 134 | ||||
-rw-r--r-- | gcc/config/xtensa/xtensa.md | 429 |
5 files changed, 332 insertions, 237 deletions
diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md index 77c9571..727ec1e 100644 --- a/gcc/config/xtensa/constraints.md +++ b/gcc/config/xtensa/constraints.md @@ -130,7 +130,7 @@ (and (match_code "mem") (match_test "smalloffset_mem_p (op)"))) -(define_memory_constraint "T" +(define_special_memory_constraint "T" "Memory in a literal pool (addressable with an L32R instruction)." (and (match_code "mem") (match_test "!TARGET_CONST16 && constantpool_mem_p (op)"))) diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md index 9aeaba6..20160a4 100644 --- a/gcc/config/xtensa/predicates.md +++ b/gcc/config/xtensa/predicates.md @@ -189,6 +189,9 @@ (define_predicate "ubranch_operator" (match_code "ltu,geu")) +(define_predicate "alt_ubranch_operator" + (match_code "gtu,leu")) + (define_predicate "boolean_operator" (match_code "eq,ne")) diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index 1f5dcf5..98e75c6 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -60,6 +60,7 @@ extern bool xtensa_tls_referenced_p (rtx); extern enum rtx_code xtensa_shlrd_which_direction (rtx, rtx); extern bool xtensa_split1_finished_p (void); extern void xtensa_split_DI_reg_imm (rtx *); +extern char *xtensa_bswapsi2_output (rtx_insn *, const char *); #ifdef TREE_CODE extern void init_cumulative_args (CUMULATIVE_ARGS *, int); diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index 02554c5..f3b89de 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -2645,6 +2645,94 @@ xtensa_split_DI_reg_imm (rtx *operands) } +/* Return the asm output string of bswapsi2_internal insn pattern. + It does this by scanning backwards for the BB from the specified insn, + and if an another bswapsi2_internal is found, it omits the instruction + to set SAR to 8. If not found, or if a CALL, JUMP, ASM, or other insn + that clobbers SAR is found first, prepend an instruction to set SAR to + 8 as usual. */ + +static int +xtensa_bswapsi2_output_1 (rtx_insn *insn) +{ + int icode; + rtx pat; + const char *iname; + + /* CALL insn do not preserve SAR. + JUMP insn only appear at the end of BB, so they do not need to be + considered when scanning backwards. */ + if (CALL_P (insn)) + return -1; + + switch (icode = INSN_CODE (insn)) + { + /* rotate insns clobber SAR. */ + case CODE_FOR_rotlsi3: + case CODE_FOR_rotrsi3: + return -1; + /* simple shift insns clobber SAR if non-immediate shift amounts. */ + case CODE_FOR_ashlsi3_internal: + case CODE_FOR_ashrsi3: + case CODE_FOR_lshrsi3: + if (! CONST_INT_P (XEXP (SET_SRC (PATTERN (insn)), 1))) + return -1; + break; + /* this insn always set SAR to 8. */ + case CODE_FOR_bswapsi2_internal: + return 1; + default: + break; + } + + /* "*shift_per_byte" and "*shlrd_*" complex shift insns clobber SAR. */ + if (icode >= CODE_FOR_nothing + && (! strcmp (iname = insn_data[icode].name, "*shift_per_byte") + || ! strncmp (iname, "*shlrd_", 7))) + return -1; + + /* asm statements may also clobber SAR, so they are anything goes. */ + if (NONJUMP_INSN_P (insn)) + switch (GET_CODE (pat = PATTERN (insn))) + { + case SET: + return GET_CODE (SET_SRC (pat)) == ASM_OPERANDS ? -1 : 0; + case PARALLEL: + return (GET_CODE (pat = XVECEXP (pat, 0, 0)) == SET + && GET_CODE (SET_SRC (pat)) == ASM_OPERANDS) + || GET_CODE (pat) == ASM_OPERANDS + || GET_CODE (pat) == ASM_INPUT ? -1 : 0; + case ASM_OPERANDS: + return -1; + default: + break; + } + + /* All other insns are not interested in SAR. */ + return 0; +} + +char * +xtensa_bswapsi2_output (rtx_insn *insn, const char *output) +{ + static char result[128]; + int i; + + strcpy (result, "ssai\t8\n\t"); + while ((insn = prev_nonnote_nondebug_insn_bb (insn))) + if ((i = xtensa_bswapsi2_output_1 (insn)) < 0) + break; + else if (i > 0) + { + result[0] = '\0'; + break; + } + strcat (result, output); + + return result; +} + + /* Try to split an integer value into what are suitable for two consecutive immediate addition instructions, ADDI or ADDMI. */ @@ -4702,25 +4790,49 @@ static bool xtensa_is_insn_L32R_p (const rtx_insn *insn) { rtx pat, dest, src; + machine_mode mode; - /* "PATTERN (insn)" can be used without checking, see insn_cost() - in gcc/rtlanal.cc. */ + /* RTX insns that are not "(set (reg) ...)" cannot become L32R instructions: + - it is permitted to apply PATTERN() to the insn without validation. + See insn_cost() in gcc/rtlanal.cc. + - it is used register_operand() instead of REG() to identify things that + don't look like REGs but will eventually become so as well. */ if (GET_CODE (pat = PATTERN (insn)) != SET || ! register_operand (dest = SET_DEST (pat), VOIDmode)) return false; + /* If the source is a reference to a literal pool entry, then the insn + obviously corresponds to an L32R instruction. */ if (constantpool_mem_p (src = SET_SRC (pat))) return true; - /* Return true if: - - CONST16 instruction is not configured, and - - the source is some constant, and also - - negation of "the source is integer and fits into the immediate - field". */ - return (!TARGET_CONST16 - && CONSTANT_P (src) - && ! ((GET_MODE (dest) == SImode || GET_MODE (dest) == HImode) - && CONST_INT_P (src) && xtensa_simm12b (INTVAL (src)))); + /* Similarly, an insn whose source is not a constant obviously does not + correspond to L32R. */ + if (! CONSTANT_P (src)) + return false; + + /* If the source is a CONST_INT whose value fits into signed 12 bits, then + the insn corresponds to a MOVI instruction (rather than an L32R one), + regardless of the configuration of TARGET_CONST16 or + TARGET_AUTOLITPOOLS. Note that the destination register can be non- + SImode. */ + if (((mode = GET_MODE (dest)) == SImode + || mode == HImode || mode == SFmode) + && CONST_INT_P (src) && xtensa_simm12b (INTVAL (src))) + return false; + + /* If TARGET_CONST16 is configured, constants of the remaining forms + correspond to pairs of CONST16 instructions, not L32R. */ + if (TARGET_CONST16) + return false; + + /* The last remaining form of constant is one of the following: + - CONST_INTs with large values + - floating-point constants + - symbolic constants + and is all handled by a relaxed MOVI instruction, which is later + converted to an L32R instruction by the assembler. */ + return true; } /* Compute a relative costs of RTL insns. This is necessary in order to diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 629dfdd..52ffb16 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -88,6 +88,7 @@ ;; This mode iterator allows the HI and QI patterns to be defined from ;; the same template. (define_mode_iterator HQI [HI QI]) +(define_mode_attr mode_bits [(HI "16") (QI "8")]) ;; This mode iterator allows the SI and HI patterns to be defined from ;; the same template. @@ -176,19 +177,18 @@ ;; Addition. (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=D,D,a,a,a") - (plus:SI (match_operand:SI 1 "register_operand" "%d,d,r,r,r") - (match_operand:SI 2 "add_operand" "d,O,r,J,N")))] - "" - "@ - add.n\t%0, %1, %2 - addi.n\t%0, %1, %d2 - add\t%0, %1, %2 - addi\t%0, %1, %d2 - addmi\t%0, %1, %x2" - [(set_attr "type" "arith,arith,arith,arith,arith") - (set_attr "mode" "SI") - (set_attr "length" "2,2,3,3,3")]) + [(set (match_operand:SI 0 "register_operand") + (plus:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "add_operand")))] + "" + {@ [cons: =0, %1, 2; attrs: type, length] + [D, d, d; arith, 2] add.n\t%0, %1, %2 + [D, d, O; arith, 2] addi.n\t%0, %1, %d2 + [a, r, r; arith, 3] add\t%0, %1, %2 + [a, r, J; arith, 3] addi\t%0, %1, %d2 + [a, r, N; arith, 3] addmi\t%0, %1, %x2 + } + [(set_attr "mode" "SI")]) (define_insn "*addsubx" [(set (match_operand:SI 0 "register_operand" "=a") @@ -392,18 +392,15 @@ (set_attr "length" "3")]) (define_insn "<u>mulhisi3" - [(set (match_operand:SI 0 "register_operand" "=C,A") - (mult:SI (any_extend:SI - (match_operand:HI 1 "register_operand" "%r,r")) - (any_extend:SI - (match_operand:HI 2 "register_operand" "r,r"))))] + [(set (match_operand:SI 0 "register_operand") + (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand")) + (any_extend:SI (match_operand:HI 2 "register_operand"))))] "TARGET_MUL16 || TARGET_MAC16" - "@ - mul16<su>\t%0, %1, %2 - <u>mul.aa.ll\t%1, %2" - [(set_attr "type" "mul16,mac16") - (set_attr "mode" "SI") - (set_attr "length" "3,3")]) + {@ [cons: =0, %1, 2; attrs: type, length] + [C, r, r; mul16, 3] mul16<su>\t%0, %1, %2 + [A, r, r; mac16, 3] <u>mul.aa.ll\t%1, %2 + } + [(set_attr "mode" "SI")]) (define_insn "muladdhisi" [(set (match_operand:SI 0 "register_operand" "=A") @@ -652,36 +649,15 @@ }) (define_insn "bswapsi2_internal" - [(set (match_operand:SI 0 "register_operand" "=a,&a") - (bswap:SI (match_operand:SI 1 "register_operand" "0,r"))) - (clobber (match_scratch:SI 2 "=&a,X"))] + [(set (match_operand:SI 0 "register_operand") + (bswap:SI (match_operand:SI 1 "register_operand"))) + (clobber (match_scratch:SI 2))] "!optimize_debug && optimize > 1 && !optimize_size" -{ - rtx_insn *prev_insn = prev_nonnote_nondebug_insn (insn); - const char *init = "ssai\t8\;"; - static char result[128]; - if (prev_insn && NONJUMP_INSN_P (prev_insn)) - { - rtx x = PATTERN (prev_insn); - if (GET_CODE (x) == PARALLEL && XVECLEN (x, 0) == 2 - && GET_CODE (XVECEXP (x, 0, 0)) == SET - && GET_CODE (XVECEXP (x, 0, 1)) == CLOBBER) - { - x = XEXP (XVECEXP (x, 0, 0), 1); - if (GET_CODE (x) == BSWAP && GET_MODE (x) == SImode) - init = ""; - } - } - sprintf (result, - (which_alternative == 0) - ? "%s" "srli\t%%2, %%1, 16\;src\t%%2, %%2, %%1\;src\t%%2, %%2, %%2\;src\t%%0, %%1, %%2" - : "%s" "srli\t%%0, %%1, 16\;src\t%%0, %%0, %%1\;src\t%%0, %%0, %%0\;src\t%%0, %%1, %%0", - init); - return result; -} - [(set_attr "type" "arith,arith") - (set_attr "mode" "SI") - (set_attr "length" "15,15")]) + {@ [cons: =0, 1, =2; attrs: type, length] + [ a, 0, &a; arith, 15] << xtensa_bswapsi2_output (insn, "srli\t%2, %1, 16\;src\t%2, %2, %1\;src\t%2, %2, %2\;src\t%0, %1, %2"); + [&a, r, X; arith, 15] << xtensa_bswapsi2_output (insn, "srli\t%0, %1, 16\;src\t%0, %0, %1\;src\t%0, %0, %0\;src\t%0, %1, %0"); + } + [(set_attr "mode" "SI")]) (define_expand "bswapdi2" [(set (match_operand:DI 0 "register_operand" "") @@ -742,16 +718,15 @@ ;; Logical instructions. (define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (and:SI (match_operand:SI 1 "register_operand" "%r,r") - (match_operand:SI 2 "mask_operand" "P,r")))] + [(set (match_operand:SI 0 "register_operand") + (and:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "mask_operand")))] "" - "@ - extui\t%0, %1, 0, %K2 - and\t%0, %1, %2" - [(set_attr "type" "arith,arith") - (set_attr "mode" "SI") - (set_attr "length" "3,3")]) + {@ [cons: =0, %1, 2; attrs: type, length] + [a, r, P; arith, 3] extui\t%0, %1, 0, %K2 + [a, r, r; arith, 3] and\t%0, %1, %2 + } + [(set_attr "mode" "SI")]) (define_insn_and_split "*andsi3_bitcmpl" [(set (match_operand:SI 0 "register_operand" "=a") @@ -944,27 +919,15 @@ ;; Zero-extend instructions. -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (zero_extend:SI (match_operand:HI 1 "nonimmed_operand" "r,U")))] - "" - "@ - extui\t%0, %1, 0, 16 - %v1l16ui\t%0, %1" - [(set_attr "type" "arith,load") - (set_attr "mode" "SI") - (set_attr "length" "3,3")]) - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (zero_extend:SI (match_operand:QI 1 "nonimmed_operand" "r,U")))] +(define_insn "zero_extend<mode>si2" + [(set (match_operand:SI 0 "register_operand") + (zero_extend:SI (match_operand:HQI 1 "nonimmed_operand")))] "" - "@ - extui\t%0, %1, 0, 8 - %v1l8ui\t%0, %1" - [(set_attr "type" "arith,load") - (set_attr "mode" "SI") - (set_attr "length" "3,3")]) + {@ [cons: =0, 1; attrs: type, length] + [a, r; arith, 3] extui\t%0, %1, 0, <mode_bits> + [a, U; load , 3] %v1l<mode_bits>ui\t%0, %1 + } + [(set_attr "mode" "SI")]) ;; Sign-extend instructions. @@ -982,15 +945,14 @@ }) (define_insn "extendhisi2_internal" - [(set (match_operand:SI 0 "register_operand" "=B,a") - (sign_extend:SI (match_operand:HI 1 "sext_operand" "r,U")))] + [(set (match_operand:SI 0 "register_operand") + (sign_extend:SI (match_operand:HI 1 "sext_operand")))] "" - "@ - sext\t%0, %1, 15 - %v1l16si\t%0, %1" - [(set_attr "type" "arith,load") - (set_attr "mode" "SI") - (set_attr "length" "3,3")]) + {@ [cons: =0, 1; attrs: type, length] + [B, r; arith, 3] sext\t%0, %1, 15 + [a, U; load , 3] %v1l16si\t%0, %1 + } + [(set_attr "mode" "SI")]) (define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") @@ -1327,29 +1289,28 @@ }) (define_insn "movsi_internal" - [(set (match_operand:SI 0 "nonimmed_operand" "=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A") - (match_operand:SI 1 "move_operand" "M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))] + [(set (match_operand:SI 0 "nonimmed_operand") + (match_operand:SI 1 "move_operand"))] "xtensa_valid_move (SImode, operands)" - "@ - movi.n\t%0, %x1 - mov.n\t%0, %1 - mov.n\t%0, %1 - %v1l32i.n\t%0, %1 - %v0s32i.n\t%1, %0 - %v0s32i.n\t%1, %0 - mov\t%0, %1 - movsp\t%0, %1 - movi\t%0, %x1 - movi\t%0, %1 - const16\t%0, %t1\;const16\t%0, %b1 - %v1l32r\t%0, %1 - %v1l32i\t%0, %1 - %v0s32i\t%1, %0 - rsr\t%0, ACCLO - wsr\t%1, ACCLO" - [(set_attr "type" "move,move,move,load,store,store,move,move,move,load,move,load,load,store,rsr,wsr") - (set_attr "mode" "SI") - (set_attr "length" "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")]) + {@ [cons: =0, 1; attrs: type, length] + [ D, M; move , 2] movi.n\t%0, %x1 + [ D, D; move , 2] mov.n\t%0, %1 + [ D, d; move , 2] ^ + [ D, R; load , 2] %v1l32i.n\t%0, %1 + [ R, D; store, 2] %v0s32i.n\t%1, %0 + [ R, d; store, 2] ^ + [ a, r; move , 3] mov\t%0, %1 + [ q, r; move , 3] movsp\t%0, %1 + [ a, I; move , 3] movi\t%0, %x1 + [ a, Y; load , 3] movi\t%0, %1 + [ W, i; move , 6] const16\t%0, %t1\;const16\t%0, %b1 + [ a, T; load , 3] %v1l32r\t%0, %1 + [ a, U; load , 3] %v1l32i\t%0, %1 + [ U, r; store, 3] %v0s32i\t%1, %0 + [*a, *A; rsr , 3] rsr\t%0, ACCLO + [*A, *r; wsr , 3] wsr\t%1, ACCLO + } + [(set_attr "mode" "SI")]) (define_split [(set (match_operand:SHI 0 "register_operand") @@ -1399,23 +1360,22 @@ }) (define_insn "movhi_internal" - [(set (match_operand:HI 0 "nonimmed_operand" "=D,D,a,a,a,a,a,U,*a,*A") - (match_operand:HI 1 "move_operand" "M,d,r,I,Y,T,U,r,*A,*r"))] + [(set (match_operand:HI 0 "nonimmed_operand") + (match_operand:HI 1 "move_operand"))] "xtensa_valid_move (HImode, operands)" - "@ - movi.n\t%0, %x1 - mov.n\t%0, %1 - mov\t%0, %1 - movi\t%0, %x1 - movi\t%0, %1 - %v1l32r\t%0, %1 - %v1l16ui\t%0, %1 - %v0s16i\t%1, %0 - rsr\t%0, ACCLO - wsr\t%1, ACCLO" - [(set_attr "type" "move,move,move,move,load,load,load,store,rsr,wsr") - (set_attr "mode" "HI") - (set_attr "length" "2,2,3,3,3,3,3,3,3,3")]) + {@ [cons: =0, 1; attrs: type, length] + [ D, M; move , 2] movi.n\t%0, %x1 + [ D, d; move , 2] mov.n\t%0, %1 + [ a, r; move , 3] mov\t%0, %1 + [ a, I; move , 3] movi\t%0, %x1 + [ a, Y; load , 3] movi\t%0, %1 + [ a, T; load , 3] %v1l32r\t%0, %1 + [ a, U; load , 3] %v1l16ui\t%0, %1 + [ U, r; store, 3] %v0s16i\t%1, %0 + [*a, *A; rsr , 3] rsr\t%0, ACCLO + [*A, *r; wsr , 3] wsr\t%1, ACCLO + } + [(set_attr "mode" "HI")]) ;; 8-bit Integer moves @@ -1429,21 +1389,20 @@ }) (define_insn "movqi_internal" - [(set (match_operand:QI 0 "nonimmed_operand" "=D,D,a,a,a,U,*a,*A") - (match_operand:QI 1 "move_operand" "M,d,r,I,U,r,*A,*r"))] + [(set (match_operand:QI 0 "nonimmed_operand") + (match_operand:QI 1 "move_operand"))] "xtensa_valid_move (QImode, operands)" - "@ - movi.n\t%0, %x1 - mov.n\t%0, %1 - mov\t%0, %1 - movi\t%0, %x1 - %v1l8ui\t%0, %1 - %v0s8i\t%1, %0 - rsr\t%0, ACCLO - wsr\t%1, ACCLO" - [(set_attr "type" "move,move,move,move,load,store,rsr,wsr") - (set_attr "mode" "QI") - (set_attr "length" "2,2,3,3,3,3,3,3")]) + {@ [cons: =0, 1; attrs: type, length] + [ D, M; move , 2] movi.n\t%0, %x1 + [ D, d; move , 2] mov.n\t%0, %1 + [ a, r; move , 3] mov\t%0, %1 + [ a, I; move , 3] movi\t%0, %x1 + [ a, U; load , 3] %v1l8ui\t%0, %1 + [ U, r; store, 3] %v0s8i\t%1, %0 + [*a, *A; rsr , 3] rsr\t%0, ACCLO + [*A, *r; wsr , 3] wsr\t%1, ACCLO + } + [(set_attr "mode" "QI")]) ;; Sub-word reloads from the constant pool. @@ -1501,30 +1460,29 @@ }) (define_insn "movsf_internal" - [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,a,D,R,a,f,a,a,W,a,U") - (match_operand:SF 1 "move_operand" "f,^U,f,d,T,R,d,r,r,f,Y,iF,U,r"))] + [(set (match_operand:SF 0 "nonimmed_operand") + (match_operand:SF 1 "move_operand"))] "((register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)) && !(FP_REG_P (xt_true_regnum (operands[0])) && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))" - "@ - mov.s\t%0, %1 - %v1lsi\t%0, %1 - %v0ssi\t%1, %0 - mov.n\t%0, %1 - %v1l32r\t%0, %1 - %v1l32i.n\t%0, %1 - %v0s32i.n\t%1, %0 - mov\t%0, %1 - wfr\t%0, %1 - rfr\t%0, %1 - movi\t%0, %y1 - const16\t%0, %t1\;const16\t%0, %b1 - %v1l32i\t%0, %1 - %v0s32i\t%1, %0" - [(set_attr "type" "farith,fload,fstore,move,load,load,store,move,farith,farith,load,move,load,store") - (set_attr "mode" "SF") - (set_attr "length" "3,3,3,2,3,2,2,3,3,3,3,6,3,3")]) + {@ [cons: =0, 1; attrs: type, length] + [f, f; farith, 3] mov.s\t%0, %1 + [f, ^U; fload , 3] %v1lsi\t%0, %1 + [U, f; fstore, 3] %v0ssi\t%1, %0 + [D, d; move , 2] mov.n\t%0, %1 + [a, T; load , 3] %v1l32r\t%0, %1 + [D, R; load , 2] %v1l32i.n\t%0, %1 + [R, d; store , 2] %v0s32i.n\t%1, %0 + [a, r; move , 3] mov\t%0, %1 + [f, r; farith, 3] wfr\t%0, %1 + [a, f; farith, 3] rfr\t%0, %1 + [a, Y; load , 3] movi\t%0, %y1 + [W, iF; move , 6] const16\t%0, %t1\;const16\t%0, %b1 + [a, U; load , 3] %v1l32i\t%0, %1 + [U, r; store , 3] %v0s32i\t%1, %0 + } + [(set_attr "mode" "SF")]) (define_insn "*lsiu" [(set (match_operand:SF 0 "register_operand" "=f") @@ -1692,16 +1650,15 @@ }) (define_insn "ashlsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (ashift:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "arith_operand" "J,r")))] + [(set (match_operand:SI 0 "register_operand") + (ashift:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "arith_operand")))] "" - "@ - slli\t%0, %1, %R2 - ssl\t%2\;sll\t%0, %1" - [(set_attr "type" "arith,arith") - (set_attr "mode" "SI") - (set_attr "length" "3,6")]) + {@ [cons: =0, 1, 2; attrs: type, length] + [a, r, J; arith, 3] slli\t%0, %1, %R2 + [a, r, r; arith, 6] ssl\t%2\;sll\t%0, %1 + } + [(set_attr "mode" "SI")]) (define_split [(set (match_operand:SI 0 "register_operand") @@ -1713,35 +1670,26 @@ (match_dup 1)))]) (define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "arith_operand" "J,r")))] + [(set (match_operand:SI 0 "register_operand") + (ashiftrt:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "arith_operand")))] "" - "@ - srai\t%0, %1, %R2 - ssr\t%2\;sra\t%0, %1" - [(set_attr "type" "arith,arith") - (set_attr "mode" "SI") - (set_attr "length" "3,6")]) + {@ [cons: =0, 1, 2; attrs: type, length] + [a, r, J; arith, 3] srai\t%0, %1, %R2 + [a, r, r; arith, 6] ssr\t%2\;sra\t%0, %1 + } + [(set_attr "mode" "SI")]) (define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "arith_operand" "J,r")))] + [(set (match_operand:SI 0 "register_operand") + (lshiftrt:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "arith_operand")))] "" -{ - if (which_alternative == 0) - { - if ((INTVAL (operands[2]) & 0x1f) < 16) - return "srli\t%0, %1, %R2"; - else - return "extui\t%0, %1, %R2, %L2"; - } - return "ssr\t%2\;srl\t%0, %1"; -} - [(set_attr "type" "arith,arith") - (set_attr "mode" "SI") - (set_attr "length" "3,6")]) + {@ [cons: =0, 1, 2; attrs: type, length] + [a, r, J; arith, 3] << (INTVAL (operands[2]) & 0x1f) < 16 ? \"srli\t%0, %1, %R2\" : \"extui\t%0, %1, %R2, %L2\"; + [a, r, r; arith, 6] ssr\t%2\;srl\t%0, %1 + } + [(set_attr "mode" "SI")]) (define_insn "*shift_per_byte" [(set (match_operand:SI 0 "register_operand" "=a") @@ -1944,28 +1892,26 @@ (set_attr "length" "6")]) (define_insn "rotlsi3" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (rotate:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "arith_operand" "J,r")))] + [(set (match_operand:SI 0 "register_operand") + (rotate:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "arith_operand")))] "" - "@ - ssai\t%L2\;src\t%0, %1, %1 - ssl\t%2\;src\t%0, %1, %1" - [(set_attr "type" "multi,multi") - (set_attr "mode" "SI") - (set_attr "length" "6,6")]) + {@ [cons: =0, 1, 2; attrs: type, length] + [a, r, J; multi, 6] ssai\t%L2\;src\t%0, %1, %1 + [a, r, r; multi, 6] ssl\t%2\;src\t%0, %1, %1 + } + [(set_attr "mode" "SI")]) (define_insn "rotrsi3" - [(set (match_operand:SI 0 "register_operand" "=a,a") - (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "arith_operand" "J,r")))] + [(set (match_operand:SI 0 "register_operand") + (rotatert:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "arith_operand")))] "" - "@ - ssai\t%R2\;src\t%0, %1, %1 - ssr\t%2\;src\t%0, %1, %1" - [(set_attr "type" "multi,multi") - (set_attr "mode" "SI") - (set_attr "length" "6,6")]) + {@ [cons: =0, 1, 2; attrs: type, length] + [a, r, J; multi, 6] ssai\t%R2\;src\t%0, %1, %1 + [a, r, r; multi, 6] ssr\t%2\;src\t%0, %1, %1 + } + [(set_attr "mode" "SI")]) ;; Comparisons. @@ -2024,26 +1970,23 @@ [(match_operand:SI 0 "register_operand" "r") (const_int -2147483648)]) (label_ref (match_operand 1 "")) - (pc)))] + (pc))) + (clobber (match_scratch:SI 3 "=a"))] "TARGET_ABS" "#" - "&& can_create_pseudo_p ()" + "&& 1" [(set (match_dup 3) (abs:SI (match_dup 0))) (set (pc) (if_then_else (match_op_dup 2 - [(zero_extract:SI (match_dup 3) - (const_int 1) - (match_dup 4)) + [(match_dup 3) (const_int 0)]) (label_ref (match_dup 1)) (pc)))] { - operands[3] = gen_reg_rtx (SImode); - operands[4] = GEN_INT (BITS_BIG_ENDIAN ? 0 : 31); - operands[2] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[2])), - VOIDmode, XEXP (operands[2], 0), - const0_rtx); + if (GET_CODE (operands[3]) == SCRATCH) + operands[3] = gen_reg_rtx (SImode); + PUT_CODE (operands[2], GET_CODE (operands[2]) == EQ ? LT : GE); } [(set_attr "type" "jump") (set_attr "mode" "none") @@ -2190,7 +2133,7 @@ (label_ref (match_dup 1)) (pc)))] { - operands[3] = GEN_INT ((1 << GET_MODE_BITSIZE (GET_MODE (operands[3]))) - 1); + operands[3] = GEN_INT (GET_MODE_MASK (GET_MODE (operands[3]))); }) (define_insn_and_split "*masktrue_const_pow2_minus_one" @@ -3370,6 +3313,42 @@ (const_int 8) (const_int 9))))]) +(define_insn_and_split "*eqne_in_range" + [(set (pc) + (if_then_else (match_operator 4 "alt_ubranch_operator" + [(plus:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "const_int_operand" "i")) + (match_operand:SI 2 "const_int_operand" "i")]) + (label_ref (match_operand 3 "")) + (pc))) + (clobber (match_scratch:SI 5 "=&a"))] + "TARGET_MINMAX && TARGET_CLAMPS + && INTVAL (operands[1]) * 2 - INTVAL (operands[2]) == 1 + && IN_RANGE (exact_log2 (INTVAL (operands[1])), 7, 22)" + "#" + "&& 1" + [(set (match_dup 5) + (smin:SI (smax:SI (match_dup 0) + (match_dup 1)) + (match_dup 2))) + (set (pc) + (if_then_else (match_op_dup 4 + [(match_dup 0) + (match_dup 5)]) + (label_ref (match_dup 3)) + (pc)))] +{ + HOST_WIDE_INT v = INTVAL (operands[1]); + operands[1] = GEN_INT (-v); + operands[2] = GEN_INT (v - 1); + PUT_CODE (operands[4], GET_CODE (operands[4]) == GTU ? NE : EQ); + if (GET_CODE (operands[5]) == SCRATCH) + operands[5] = gen_reg_rtx (SImode); +} + [(set_attr "type" "jump") + (set_attr "mode" "none") + (set_attr "length" "6")]) + (define_split [(clobber (match_operand 0 "register_operand"))] "HARD_REGISTER_P (operands[0]) |