This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] mips.md macroisation (18/n)
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 25 Aug 2004 20:19:01 +0100
- Subject: [committed] mips.md macroisation (18/n)
Part 18 of the mips.md macroisation process. This patch handles the
shift instructions, combining by both mode and code. Unfortunately,
the DImode MIPS16 shifts are a bit irregular, so I ended up keeping
them as separate patterns.
I took the opportunity to extend the SI->DI extension patterns
from ashift to the other two. There should be no behavioural
changes otherwise.
Bootstrapped & regression tested on mips-sgi-irix6.5. Also tested
by comparing the before and after output of gcc.c-torture and gcc.dg
for "-O2 -mips64" and "-O2 -mips16", with no changes. Applied to head.
Richard
* config/mips/mips.md (any_shift): New code macro.
(optab, insn): New code attributes.
({ashl,ashr,lshr}[sd]i3): Redefine using :GPR and any_shift.
Use the standard rather than internal patterns for the MIPS16
double-shift optimization.
(*{ashl,ashr,lshr}[sd]i3): New names for the non-mips16 shift patterns.
Redefine using :GPR and any_shift.
(*{ashl,ashr,lshr}si3_extend): Generalize ashlsi3_internal1_extend
to cover all three shifts.
(*{ashl,ashr,lshr}si3_mips16): New names for the mips16 SImode shifts.
Redefine using any_shift. Use :GPR and any_shift to combine splitters.
(*{ashl,ashr,lshr}di3_mips16): New names for the mips16 DImode shifts.
Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.288
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.288 mips.md
*** config/mips/mips.md 24 Aug 2004 20:43:57 -0000 1.288
--- config/mips/mips.md 25 Aug 2004 19:02:20 -0000
*************** (define_code_macro any_cond [unordered o
*** 323,334 ****
--- 323,348 ----
;; to use the same template.
(define_code_macro any_extend [sign_extend zero_extend])
+ ;; This code macro allows the three shift instructions to be generated
+ ;; from the same template.
+ (define_code_macro any_shift [ashift ashiftrt lshiftrt])
+
;; <u> expands to an empty string when doing a signed operation and
;; "u" when doing an unsigned operation.
(define_code_attr u [(sign_extend "") (zero_extend "u")])
;; <su> is like <u>, but the signed form expands to "s" rather than "".
(define_code_attr su [(sign_extend "s") (zero_extend "u")])
+
+ ;; <optab> expands to the name of the optab for a particular code.
+ (define_code_attr optab [(ashift "ashl")
+ (ashiftrt "ashr")
+ (lshiftrt "lshr")])
+
+ ;; <insn> expands to the name of the insn that implements a particular code.
+ (define_code_attr insn [(ashift "sll")
+ (ashiftrt "sra")
+ (lshiftrt "srl")])
;; .........................
;;
*************** (define_expand "movmemsi"
*** 4217,4229 ****
;;
;; ....................
! ;; Many of these instructions use trivial define_expands, because we
! ;; want to use a different set of constraints when TARGET_MIPS16.
!
! (define_expand "ashlsi3"
! [(set (match_operand:SI 0 "register_operand")
! (ashift:SI (match_operand:SI 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
""
{
/* On the mips16, a shift of more than 8 is a four byte instruction,
--- 4231,4240 ----
;;
;; ....................
! (define_expand "<optab><mode>3"
! [(set (match_operand:GPR 0 "register_operand")
! (any_shift:GPR (match_operand:GPR 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
""
{
/* On the mips16, a shift of more than 8 is a four byte instruction,
*************** (define_expand "ashlsi3"
*** 4238,4366 ****
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16
! && ! reload_in_progress
! && ! reload_completed)
{
! rtx temp = gen_reg_rtx (SImode);
! emit_insn (gen_ashlsi3_internal2 (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_ashlsi3_internal2 (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
DONE;
}
})
! (define_insn "ashlsi3_internal1"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (ashift:SI (match_operand:SI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
"!TARGET_MIPS16"
{
if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
! return "sll\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")])
! (define_insn "ashlsi3_internal1_extend"
[(set (match_operand:DI 0 "register_operand" "=d")
! (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI"))))]
"TARGET_64BIT && !TARGET_MIPS16"
{
if (GET_CODE (operands[2]) == CONST_INT)
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
! return "sll\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")])
!
! (define_insn "ashlsi3_internal2"
[(set (match_operand:SI 0 "register_operand" "=d,d")
! (ashift:SI (match_operand:SI 1 "register_operand" "0,d")
! (match_operand:SI 2 "arith_operand" "d,I")))]
"TARGET_MIPS16"
{
if (which_alternative == 0)
! return "sll\t%0,%2";
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
!
! return "sll\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
! ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
!
! (define_split
! [(set (match_operand:SI 0 "register_operand")
! (ashift:SI (match_operand:SI 1 "register_operand")
! (match_operand:SI 2 "const_int_operand")))]
! "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (ashift:SI (match_dup 1) (const_int 8)))
! (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
! { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
!
! (define_expand "ashldi3"
! [(set (match_operand:DI 0 "register_operand")
! (ashift:DI (match_operand:DI 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
! "TARGET_64BIT"
! {
! /* On the mips16, a shift of more than 8 is a four byte
! instruction, so, for a shift between 8 and 16, it is just as
! fast to do two shifts of 8 or less. If there is a lot of
! shifting going on, we may win in CSE. Otherwise combine will
! put the shifts back together again. This can be called by
! function_arg, so we must be careful not to allocate a new
! register if we've reached the reload pass. */
! if (TARGET_MIPS16
! && optimize
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16
! && ! reload_in_progress
! && ! reload_completed)
! {
! rtx temp = gen_reg_rtx (DImode);
!
! emit_insn (gen_ashldi3_internal (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_ashldi3_internal (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
! DONE;
! }
! })
!
!
! (define_insn "ashldi3_internal"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (ashift:DI (match_operand:DI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
! "TARGET_64BIT && !TARGET_MIPS16"
! {
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
!
! return "dsll\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")])
!
! (define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d,d")
(ashift:DI (match_operand:DI 1 "register_operand" "0,d")
(match_operand:SI 2 "arith_operand" "d,I")))]
--- 4249,4319 ----
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16
! && !reload_in_progress
! && !reload_completed)
{
! rtx temp = gen_reg_rtx (<MODE>mode);
! emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_<optab><mode>3 (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
DONE;
}
})
! (define_insn "*<optab><mode>3"
! [(set (match_operand:GPR 0 "register_operand" "=d")
! (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
"!TARGET_MIPS16"
{
if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2])
! & (GET_MODE_BITSIZE (<MODE>mode) - 1));
! return "<d><insn>\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "<MODE>")])
! (define_insn "*<optab>si3_extend"
[(set (match_operand:DI 0 "register_operand" "=d")
! (sign_extend:DI
! (any_shift:SI (match_operand:SI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI"))))]
"TARGET_64BIT && !TARGET_MIPS16"
{
if (GET_CODE (operands[2]) == CONST_INT)
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
! return "<insn>\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")])
! (define_insn "*<optab>si3_mips16"
[(set (match_operand:SI 0 "register_operand" "=d,d")
! (any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
! (match_operand:SI 2 "arith_operand" "d,I")))]
"TARGET_MIPS16"
{
if (which_alternative == 0)
! return "<insn>\t%0,%2";
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
! return "<insn>\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
! ;; We need separate DImode MIPS16 patterns because of the irregularity
! ;; of right shifts.
! (define_insn "*ashldi3_mips16"
[(set (match_operand:DI 0 "register_operand" "=d,d")
(ashift:DI (match_operand:DI 1 "register_operand" "0,d")
(match_operand:SI 2 "arith_operand" "d,I")))]
*************** (define_insn ""
*** 4369,4522 ****
if (which_alternative == 0)
return "dsll\t%0,%2";
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
!
return "dsll\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")
! (set_attr_alternative "length"
! [(const_int 4)
! (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
! (const_int 4)
! (const_int 8))])])
!
!
! ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
!
! (define_split
! [(set (match_operand:DI 0 "register_operand")
! (ashift:DI (match_operand:DI 1 "register_operand")
! (match_operand:SI 2 "const_int_operand")))]
! "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
! && reload_completed
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (ashift:DI (match_dup 1) (const_int 8)))
! (set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))]
! { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
!
! (define_expand "ashrsi3"
! [(set (match_operand:SI 0 "register_operand")
! (ashiftrt:SI (match_operand:SI 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
! ""
! {
! /* On the mips16, a shift of more than 8 is a four byte instruction,
! so, for a shift between 8 and 16, it is just as fast to do two
! shifts of 8 or less. If there is a lot of shifting going on, we
! may win in CSE. Otherwise combine will put the shifts back
! together again. */
! if (TARGET_MIPS16
! && optimize
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16)
! {
! rtx temp = gen_reg_rtx (SImode);
!
! emit_insn (gen_ashrsi3_internal2 (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_ashrsi3_internal2 (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
! DONE;
! }
! })
!
! (define_insn "ashrsi3_internal1"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (ashiftrt:SI (match_operand:SI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
! "!TARGET_MIPS16"
! {
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
!
! return "sra\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")])
!
! (define_insn "ashrsi3_internal2"
! [(set (match_operand:SI 0 "register_operand" "=d,d")
! (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
! (match_operand:SI 2 "arith_operand" "d,I")))]
! "TARGET_MIPS16"
! {
! if (which_alternative == 0)
! return "sra\t%0,%2";
!
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
!
! return "sra\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
!
! ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
!
! (define_split
! [(set (match_operand:SI 0 "register_operand")
! (ashiftrt:SI (match_operand:SI 1 "register_operand")
! (match_operand:SI 2 "const_int_operand")))]
! "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 8)))
! (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))]
! { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
!
! (define_expand "ashrdi3"
! [(set (match_operand:DI 0 "register_operand")
! (ashiftrt:DI (match_operand:DI 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
! "TARGET_64BIT"
! {
! /* On the mips16, a shift of more than 8 is a four byte
! instruction, so, for a shift between 8 and 16, it is just as
! fast to do two shifts of 8 or less. If there is a lot of
! shifting going on, we may win in CSE. Otherwise combine will
! put the shifts back together again. */
! if (TARGET_MIPS16
! && optimize
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16)
! {
! rtx temp = gen_reg_rtx (DImode);
!
! emit_insn (gen_ashrdi3_internal (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_ashrdi3_internal (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
! DONE;
! }
! })
!
!
! (define_insn "ashrdi3_internal"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
! "TARGET_64BIT && !TARGET_MIPS16"
! {
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
!
! return "dsra\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")])
!
! (define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d,d")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:SI 2 "arith_operand" "d,I")))]
--- 4322,4339 ----
if (which_alternative == 0)
return "dsll\t%0,%2";
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
return "dsll\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
! (define_insn "*ashrdi3_mips16"
[(set (match_operand:DI 0 "register_operand" "=d,d")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:SI 2 "arith_operand" "d,I")))]
*************** (define_insn ""
*** 4527,4630 ****
return "dsra\t%0,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
! ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
!
! (define_split
! [(set (match_operand:DI 0 "register_operand")
! (ashiftrt:DI (match_operand:DI 1 "register_operand")
! (match_operand:SI 2 "const_int_operand")))]
! "TARGET_MIPS16 && TARGET_64BIT && !TARGET_DEBUG_D_MODE
! && reload_completed
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (ashiftrt:DI (match_dup 1) (const_int 8)))
! (set (match_dup 0) (ashiftrt:DI (match_dup 0) (match_dup 2)))]
! { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
!
! (define_expand "lshrsi3"
! [(set (match_operand:SI 0 "register_operand")
! (lshiftrt:SI (match_operand:SI 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
! ""
! {
! /* On the mips16, a shift of more than 8 is a four byte instruction,
! so, for a shift between 8 and 16, it is just as fast to do two
! shifts of 8 or less. If there is a lot of shifting going on, we
! may win in CSE. Otherwise combine will put the shifts back
! together again. */
! if (TARGET_MIPS16
! && optimize
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16)
! {
! rtx temp = gen_reg_rtx (SImode);
!
! emit_insn (gen_lshrsi3_internal2 (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_lshrsi3_internal2 (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
! DONE;
! }
! })
!
! (define_insn "lshrsi3_internal1"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (lshiftrt:SI (match_operand:SI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
! "!TARGET_MIPS16"
! {
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
!
! return "srl\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")])
!
! (define_insn "lshrsi3_internal2"
! [(set (match_operand:SI 0 "register_operand" "=d,d")
! (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,d")
(match_operand:SI 2 "arith_operand" "d,I")))]
! "TARGET_MIPS16"
{
- if (which_alternative == 0)
- return "srl\t%0,%2";
-
if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
! return "srl\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
-
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
! [(set (match_operand:SI 0 "register_operand")
! (lshiftrt:SI (match_operand:SI 1 "register_operand")
! (match_operand:SI 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 8)))
! (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
{ operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
;; If we load a byte on the mips16 as a bitfield, the resulting
--- 4344,4388 ----
return "dsra\t%0,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
! (define_insn "*lshrdi3_mips16"
! [(set (match_operand:DI 0 "register_operand" "=d,d")
! (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:SI 2 "arith_operand" "d,I")))]
! "TARGET_64BIT && TARGET_MIPS16"
{
if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
! return "dsrl\t%0,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
! (if_then_else (match_operand 2 "m16_uimm3_b")
(const_int 4)
(const_int 8))])])
;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
(define_split
! [(set (match_operand:GPR 0 "register_operand")
! (any_shift:GPR (match_operand:GPR 1 "register_operand")
! (match_operand:GPR 2 "const_int_operand")))]
"TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8)))
! (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))]
{ operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
;; If we load a byte on the mips16 as a bitfield, the resulting
*************** (define_insn_and_split ""
*** 4650,4771 ****
(set_attr "mode" "SI")
(set_attr "length" "16")])
! (define_expand "lshrdi3"
! [(set (match_operand:DI 0 "register_operand")
! (lshiftrt:DI (match_operand:DI 1 "register_operand")
! (match_operand:SI 2 "arith_operand")))]
! "TARGET_64BIT"
! {
! /* On the mips16, a shift of more than 8 is a four byte
! instruction, so, for a shift between 8 and 16, it is just as
! fast to do two shifts of 8 or less. If there is a lot of
! shifting going on, we may win in CSE. Otherwise combine will
! put the shifts back together again. */
! if (TARGET_MIPS16
! && optimize
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16)
! {
! rtx temp = gen_reg_rtx (DImode);
!
! emit_insn (gen_lshrdi3_internal (temp, operands[1], GEN_INT (8)));
! emit_insn (gen_lshrdi3_internal (operands[0], temp,
! GEN_INT (INTVAL (operands[2]) - 8)));
! DONE;
! }
! })
!
!
! (define_insn "lshrdi3_internal"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
! "TARGET_64BIT && !TARGET_MIPS16"
! {
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
!
! return "dsrl\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")])
!
! (define_insn ""
! [(set (match_operand:DI 0 "register_operand" "=d,d")
! (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
! (match_operand:SI 2 "arith_operand" "d,I")))]
! "TARGET_64BIT && TARGET_MIPS16"
! {
! if (GET_CODE (operands[2]) == CONST_INT)
! operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
!
! return "dsrl\t%0,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")
! (set_attr_alternative "length"
! [(const_int 4)
! (if_then_else (match_operand:VOID 2 "m16_uimm3_b")
! (const_int 4)
! (const_int 8))])])
!
! (define_insn "rotrsi3"
! [(set (match_operand:SI 0 "register_operand" "=d")
! (rotatert:SI (match_operand:SI 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dn")))]
! "ISA_HAS_ROTR_SI"
! {
! if (TARGET_SR71K && GET_CODE (operands[2]) != CONST_INT)
! return "rorv\t%0,%1,%2";
!
! if ((GET_CODE (operands[2]) == CONST_INT)
! && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 32))
! abort ();
!
! return "ror\t%0,%1,%2";
! }
! [(set_attr "type" "shift")
! (set_attr "mode" "SI")])
!
! (define_insn "rotrdi3"
! [(set (match_operand:DI 0 "register_operand" "=d")
! (rotatert:DI (match_operand:DI 1 "register_operand" "d")
! (match_operand:DI 2 "arith_operand" "dn")))]
! "ISA_HAS_ROTR_DI"
{
- if (TARGET_SR71K)
- {
- if (GET_CODE (operands[2]) != CONST_INT)
- return "drorv\t%0,%1,%2";
-
- if (INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) <= 63)
- return "dror32\t%0,%1,%2";
- }
-
if ((GET_CODE (operands[2]) == CONST_INT)
! && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) >= 64))
abort ();
! return "dror\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "DI")])
!
!
! ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
!
! (define_split
! [(set (match_operand:DI 0 "register_operand")
! (lshiftrt:DI (match_operand:DI 1 "register_operand")
! (match_operand:SI 2 "const_int_operand")))]
! "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
! && GET_CODE (operands[2]) == CONST_INT
! && INTVAL (operands[2]) > 8
! && INTVAL (operands[2]) <= 16"
! [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 8)))
! (set (match_dup 0) (lshiftrt:DI (match_dup 0) (match_dup 2)))]
! { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); })
;;
;; ....................
--- 4408,4428 ----
(set_attr "mode" "SI")
(set_attr "length" "16")])
! (define_insn "rotr<mode>3"
! [(set (match_operand:GPR 0 "register_operand" "=d")
! (rotatert:GPR (match_operand:GPR 1 "register_operand" "d")
! (match_operand:SI 2 "arith_operand" "dI")))]
! "ISA_HAS_ROTR_<MODE>"
{
if ((GET_CODE (operands[2]) == CONST_INT)
! && (INTVAL (operands[2]) < 0
! || INTVAL (operands[2]) >= GET_MODE_BITSIZE (<MODE>mode)))
abort ();
! return "<d>ror\t%0,%1,%2";
}
! [(set_attr "type" "shift")
! (set_attr "mode" "<MODE>")])
;;
;; ....................