diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/mips/mips.c | 34 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 49 |
3 files changed, 83 insertions, 5 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 9ddcf4d..76f681f 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4158,7 +4158,39 @@ mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos) } return true; } - + +/* Return true if (zero_extract OP SIZE POSITION) can be used as the + source of an "ext" instruction or the destination of an "ins" + instruction. OP must be a register operand and the following + conditions must hold: + + 0 <= POSITION < GET_MODE_BITSIZE (GET_MODE (op)) + 0 < SIZE <= GET_MODE_BITSIZE (GET_MODE (op)) + 0 < POSITION + SIZE <= GET_MODE_BITSIZE (GET_MODE (op)) + + Also reject lengths equal to a word as they are better handled + by the move patterns. */ + +bool +mips_use_ins_ext_p (rtx op, rtx size, rtx position) +{ + HOST_WIDE_INT len, pos; + + if (!ISA_HAS_EXT_INS + || !register_operand (op, VOIDmode) + || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD) + return false; + + len = INTVAL (size); + pos = INTVAL (position); + + if (len <= 0 || len >= GET_MODE_BITSIZE (GET_MODE (op)) + || pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (op))) + return false; + + return true; +} + /* Set up globals to generate code for the ISA or processor described by INFO. */ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 9de422d..ef293be 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -670,6 +670,11 @@ extern const struct mips_cpu_info *mips_tune_info; && (ISA_MIPS32R2 \ )) +/* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */ +#define ISA_HAS_EXT_INS (!TARGET_MIPS16 \ + && (ISA_MIPS32R2 \ + )) + /* True if the result of a load is not available to the next instruction. A nop will then be needed between instructions like "lw $4,..." and "addiu $4,$4,1". */ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 5d58b73..804d50a 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -2818,7 +2818,7 @@ beq\t%2,%.,1b\;\ (define_expand "extzv" [(set (match_operand 0 "register_operand") - (zero_extract (match_operand:QI 1 "memory_operand") + (zero_extract (match_operand 1 "nonimmediate_operand") (match_operand 2 "immediate_operand") (match_operand 3 "immediate_operand")))] "!TARGET_MIPS16" @@ -2827,12 +2827,33 @@ beq\t%2,%.,1b\;\ INTVAL (operands[2]), INTVAL (operands[3]))) DONE; + else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3])) + { + if (GET_MODE (operands[0]) == DImode) + emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], + operands[3])); + else + emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } else FAIL; }) +(define_insn "extzv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:SI 2 "immediate_operand" "I") + (match_operand:SI 3 "immediate_operand" "I")))] + "mips_use_ins_ext_p (operands[1], operands[2], operands[3])" + "<d>ext\t%0,%1,%3,%2" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + + (define_expand "insv" - [(set (zero_extract (match_operand:QI 0 "memory_operand") + [(set (zero_extract (match_operand 0 "nonimmediate_operand") (match_operand 1 "immediate_operand") (match_operand 2 "immediate_operand")) (match_operand 3 "reg_or_0_operand"))] @@ -2842,10 +2863,30 @@ beq\t%2,%.,1b\;\ INTVAL (operands[1]), INTVAL (operands[2]))) DONE; - else - FAIL; + else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2])) + { + if (GET_MODE (operands[0]) == DImode) + emit_insn (gen_insvdi (operands[0], operands[1], operands[2], + operands[3])); + else + emit_insn (gen_insvsi (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } + else + FAIL; }) +(define_insn "insv<mode>" + [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d") + (match_operand:SI 1 "immediate_operand" "I") + (match_operand:SI 2 "immediate_operand" "I")) + (match_operand:GPR 3 "reg_or_0_operand" "dJ"))] + "mips_use_ins_ext_p (operands[0], operands[1], operands[2])" + "<d>ins\t%0,%z3,%2,%1" + [(set_attr "type" "arith") + (set_attr "mode" "<MODE>")]) + ;; Unaligned word moves generated by the bit field patterns. ;; ;; As far as the rtl is concerned, both the left-part and right-part |