Commit 0d8e55d8 by Jeffrey A Law Committed by Jeff Law

combine.c (make_extraction): If no mode is specified for an operand of insv...

        * combine.c (make_extraction): If no mode is specified for
        an operand of insv, extv, or extzv, default it to word_mode.
        (simplify_comparison): Similarly.
        * expmed.c (store_bit_field): Similarly.
        (extract_bit_field): Similarly.
        * function.c (fixup_var_regs_1): Similarly.
        * recog.c (validate_replace_rtx_1): Similarly.
        * mips.md (extv, extzv, insv expanders): Default modes for most
        operands.  Handle TARGET_64BIT.
        (movdi_uld, movdi_usd): New patterns.

From-SVN: r22439
parent 54d65918
Tue Sep 15 22:59:52 1998 Jeffrey A Law (law@cygnus.com) Tue Sep 15 22:59:52 1998 Jeffrey A Law (law@cygnus.com)
* combine.c (make_extraction): If no mode is specified for
an operand of insv, extv, or extzv, default it to word_mode.
(simplify_comparison): Similarly.
* expmed.c (store_bit_field): Similarly.
(extract_bit_field): Similarly.
* function.c (fixup_var_regs_1): Similarly.
* recog.c (validate_replace_rtx_1): Similarly.
* mips.md (extv, extzv, insv expanders): Default modes for most
operands. Handle TARGET_64BIT.
(movdi_uld, movdi_usd): New patterns.
* pa.c (emit_move_sequence): Do not replace a pseudo with its * pa.c (emit_move_sequence): Do not replace a pseudo with its
equivalent memory location unless we have been provided a scratch equivalent memory location unless we have been provided a scratch
register. Similarly do not call find_replacement unless a register. Similarly do not call find_replacement unless a
......
...@@ -5605,27 +5605,45 @@ make_extraction (mode, inner, pos, pos_rtx, len, ...@@ -5605,27 +5605,45 @@ make_extraction (mode, inner, pos, pos_rtx, len,
#ifdef HAVE_insv #ifdef HAVE_insv
if (in_dest) if (in_dest)
{ {
wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_insv][0]; wanted_inner_reg_mode
pos_mode = insn_operand_mode[(int) CODE_FOR_insv][2]; = (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
extraction_mode = insn_operand_mode[(int) CODE_FOR_insv][3]; ? word_mode
: insn_operand_mode[(int) CODE_FOR_insv][0]);
pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode
? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]);
extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_insv][3]);
} }
#endif #endif
#ifdef HAVE_extzv #ifdef HAVE_extzv
if (! in_dest && unsignedp) if (! in_dest && unsignedp)
{ {
wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; wanted_inner_reg_mode
pos_mode = insn_operand_mode[(int) CODE_FOR_extzv][3]; = (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
extraction_mode = insn_operand_mode[(int) CODE_FOR_extzv][0]; ? word_mode
: insn_operand_mode[(int) CODE_FOR_extzv][1]);
pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode
? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]);
extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_extzv][0]);
} }
#endif #endif
#ifdef HAVE_extv #ifdef HAVE_extv
if (! in_dest && ! unsignedp) if (! in_dest && ! unsignedp)
{ {
wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extv][1]; wanted_inner_reg_mode
pos_mode = insn_operand_mode[(int) CODE_FOR_extv][3]; = (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
extraction_mode = insn_operand_mode[(int) CODE_FOR_extv][0]; ? word_mode
: insn_operand_mode[(int) CODE_FOR_extv][1]);
pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode
? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]);
extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode
? word_mode
: insn_operand_mode[(int) CODE_FOR_extv][0]);
} }
#endif #endif
...@@ -9762,12 +9780,16 @@ simplify_comparison (code, pop0, pop1) ...@@ -9762,12 +9780,16 @@ simplify_comparison (code, pop0, pop1)
&& (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0) && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
{ {
if (BITS_BIG_ENDIAN) if (BITS_BIG_ENDIAN)
{
#ifdef HAVE_extzv #ifdef HAVE_extzv
i = (GET_MODE_BITSIZE mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
(insn_operand_mode[(int) CODE_FOR_extzv][1]) - 1 - i); if (mode == VOIDmode)
mode = word_mode;
i = (GET_MODE_BITSIZE (mode) - 1 - i);
#else #else
i = BITS_PER_WORD - 1 - i; i = BITS_PER_WORD - 1 - i;
#endif #endif
}
op0 = XEXP (op0, 2); op0 = XEXP (op0, 2);
op1 = GEN_INT (i); op1 = GEN_INT (i);
......
...@@ -4224,24 +4224,30 @@ move\\t%0,%z4\\n\\ ...@@ -4224,24 +4224,30 @@ move\\t%0,%z4\\n\\
;; Bit field extract patterns which use lwl/lwr. ;; Bit field extract patterns which use lwl/lwr.
;; ??? There should be DImode variants for 64 bit code, but the current
;; bitfield scheme can't handle that. We would need to add new optabs
;; in order to make that work.
;; ??? There could be HImode variants for the ulh/ulhu/ush macros. ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
;; It isn't clear whether this will give better code. ;; It isn't clear whether this will give better code.
;; Only specify the mode operand 1, the rest are assumed to be word_mode.
(define_expand "extv" (define_expand "extv"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand 0 "register_operand" "")
(sign_extract:SI (match_operand:QI 1 "memory_operand" "") (sign_extract (match_operand:QI 1 "memory_operand" "")
(match_operand:SI 2 "immediate_operand" "") (match_operand 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")))] (match_operand 3 "immediate_operand" "")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
" "
{ {
/* If this isn't a 32 bit field, and it doesn't start on a byte boundary /* If the field does not start on a byte boundary, then fail. */
then fail. */ if (INTVAL (operands[3]) % 8 != 0)
if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0) FAIL;
/* MIPS I and MIPS II can only handle a 32bit field. */
if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
FAIL;
/* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
if (TARGET_64BIT
&& INTVAL (operands[2]) != 64
&& INTVAL (operands[2]) != 32)
FAIL; FAIL;
/* This can happen for a 64 bit target, when extracting a value from /* This can happen for a 64 bit target, when extracting a value from
...@@ -4253,22 +4259,43 @@ move\\t%0,%z4\\n\\ ...@@ -4253,22 +4259,43 @@ move\\t%0,%z4\\n\\
/* Change the mode to BLKmode for aliasing purposes. */ /* Change the mode to BLKmode for aliasing purposes. */
operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0)); operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
/* Otherwise, emit a lwl/lwr pair to load the value. */ /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
emit_insn (gen_movsi_ulw (operands[0], operands[1])); if (INTVAL (operands[2]) == 64)
emit_insn (gen_movdi_uld (operands[0], operands[1]));
else
{
if (TARGET_64BIT)
{
operands[0] = gen_lowpart (SImode, operands[0]);
if (operands[0] == NULL_RTX)
FAIL;
}
emit_insn (gen_movsi_ulw (operands[0], operands[1]));
}
DONE; DONE;
}") }")
;; Only specify the mode operand 1, the rest are assumed to be word_mode.
(define_expand "extzv" (define_expand "extzv"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand 0 "register_operand" "")
(zero_extract:SI (match_operand:QI 1 "memory_operand" "") (zero_extract (match_operand:QI 1 "memory_operand" "")
(match_operand:SI 2 "immediate_operand" "") (match_operand 2 "immediate_operand" "")
(match_operand:SI 3 "immediate_operand" "")))] (match_operand 3 "immediate_operand" "")))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
" "
{ {
/* If this isn't a 32 bit field, and it doesn't start on a byte boundary /* If the field does not start on a byte boundary, then fail. */
then fail. */ if (INTVAL (operands[3]) % 8 != 0)
if (INTVAL (operands[2]) != 32 || (INTVAL (operands[3]) % 8) != 0) FAIL;
/* MIPS I and MIPS II can only handle a 32bit field. */
if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
FAIL;
/* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
if (TARGET_64BIT
&& INTVAL (operands[2]) != 64
&& INTVAL (operands[2]) != 32)
FAIL; FAIL;
/* This can happen for a 64 bit target, when extracting a value from /* This can happen for a 64 bit target, when extracting a value from
...@@ -4281,21 +4308,42 @@ move\\t%0,%z4\\n\\ ...@@ -4281,21 +4308,42 @@ move\\t%0,%z4\\n\\
operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0)); operands[1] = change_address (operands[1], BLKmode, XEXP (operands[1], 0));
/* Otherwise, emit a lwl/lwr pair to load the value. */ /* Otherwise, emit a lwl/lwr pair to load the value. */
emit_insn (gen_movsi_ulw (operands[0], operands[1])); if (INTVAL (operands[2]) == 64)
emit_insn (gen_movdi_uld (operands[0], operands[1]));
else
{
if (TARGET_64BIT)
{
operands[0] = gen_lowpart (SImode, operands[0]);
if (operands[0] == NULL_RTX)
FAIL;
}
emit_insn (gen_movsi_ulw (operands[0], operands[1]));
}
DONE; DONE;
}") }")
;; Only specify the mode operands 0, the rest are assumed to be word_mode.
(define_expand "insv" (define_expand "insv"
[(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "") [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
(match_operand:SI 1 "immediate_operand" "") (match_operand 1 "immediate_operand" "")
(match_operand:SI 2 "immediate_operand" "")) (match_operand 2 "immediate_operand" ""))
(match_operand:SI 3 "register_operand" ""))] (match_operand 3 "register_operand" ""))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
" "
{ {
/* If this isn't a 32 bit field, and it doesn't start on a byte boundary /* If the field does not start on a byte boundary, then fail. */
then fail. */ if (INTVAL (operands[2]) % 8 != 0)
if (INTVAL (operands[1]) != 32 || (INTVAL (operands[2]) % 8) != 0) FAIL;
/* MIPS I and MIPS II can only handle a 32bit field. */
if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
FAIL;
/* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
if (TARGET_64BIT
&& INTVAL (operands[1]) != 64
&& INTVAL (operands[1]) != 32)
FAIL; FAIL;
/* This can happen for a 64 bit target, when storing into a 32 bit union /* This can happen for a 64 bit target, when storing into a 32 bit union
...@@ -4307,8 +4355,19 @@ move\\t%0,%z4\\n\\ ...@@ -4307,8 +4355,19 @@ move\\t%0,%z4\\n\\
/* Change the mode to BLKmode for aliasing purposes. */ /* Change the mode to BLKmode for aliasing purposes. */
operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0)); operands[0] = change_address (operands[0], BLKmode, XEXP (operands[0], 0));
/* Otherwise, emit a swl/swr pair to load the value. */ /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
emit_insn (gen_movsi_usw (operands[0], operands[3])); if (INTVAL (operands[1]) == 64)
emit_insn (gen_movdi_usd (operands[0], operands[3]));
else
{
if (TARGET_64BIT)
{
operands[3] = gen_lowpart (SImode, operands[3]);
if (operands[3] == NULL_RTX)
FAIL;
}
emit_insn (gen_movsi_usw (operands[0], operands[3]));
}
DONE; DONE;
}") }")
...@@ -4369,6 +4428,65 @@ move\\t%0,%z4\\n\\ ...@@ -4369,6 +4428,65 @@ move\\t%0,%z4\\n\\
(set_attr "mode" "SI") (set_attr "mode" "SI")
(set_attr "length" "2,4")]) (set_attr "length" "2,4")])
;; Bit field extract patterns which use ldl/ldr.
;; unaligned double word moves generated by the bit field patterns
(define_insn "movdi_uld"
[(set (match_operand:DI 0 "register_operand" "=&d,&d")
(unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] 0))]
""
"*
{
rtx offset = const0_rtx;
rtx addr = XEXP (operands[1], 0);
rtx mem_addr = eliminate_constant_term (addr, &offset);
char *ret;
if (TARGET_STATS)
mips_count_memory_refs (operands[1], 2);
/* The stack/frame pointers are always aligned, so we can convert
to the faster lw if we are referencing an aligned stack location. */
if ((INTVAL (offset) & 7) == 0
&& (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
ret = \"ld\\t%0,%1\";
else
ret = \"uld\\t%0,%1\";
return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
}"
[(set_attr "type" "load,load")
(set_attr "mode" "SI")
(set_attr "length" "2,4")])
(define_insn "movdi_usd"
[(set (match_operand:BLK 0 "memory_operand" "=R,o")
(unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] 1))]
""
"*
{
rtx offset = const0_rtx;
rtx addr = XEXP (operands[0], 0);
rtx mem_addr = eliminate_constant_term (addr, &offset);
if (TARGET_STATS)
mips_count_memory_refs (operands[0], 2);
/* The stack/frame pointers are always aligned, so we can convert
to the faster sw if we are referencing an aligned stack location. */
if ((INTVAL (offset) & 7) == 0
&& (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx))
return \"sd\\t%1,%0\";
return \"usd\\t%z1,%0\";
}"
[(set_attr "type" "store")
(set_attr "mode" "SI")
(set_attr "length" "2,4")])
;; These two patterns support loading addresses with two instructions instead ;; These two patterns support loading addresses with two instructions instead
;; of using the macro instruction la. ;; of using the macro instruction la.
......
...@@ -211,10 +211,10 @@ negate_rtx (mode, x) ...@@ -211,10 +211,10 @@ negate_rtx (mode, x)
/* ??? Note that there are two different ideas here for how /* ??? Note that there are two different ideas here for how
to determine the size to count bits within, for a register. to determine the size to count bits within, for a register.
One is BITS_PER_WORD, and the other is the size of operand 3 One is BITS_PER_WORD, and the other is the size of operand 3
of the insv pattern. (The latter assumes that an n-bit machine of the insv pattern.
will be able to insert bit fields up to n bits wide.)
It isn't certain that either of these is right. If operand 3 of the insv pattern is VOIDmode, then we will use BITS_PER_WORD
extract_bit_field has the same quandary. */ else, we use the mode of operand 3. */
rtx rtx
store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
...@@ -230,6 +230,14 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -230,6 +230,14 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
register int offset = bitnum / unit; register int offset = bitnum / unit;
register int bitpos = bitnum % unit; register int bitpos = bitnum % unit;
register rtx op0 = str_rtx; register rtx op0 = str_rtx;
#ifdef HAVE_insv
int insv_bitsize;
if (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode)
insv_bitsize = GET_MODE_BITSIZE (word_mode);
else
insv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]);
#endif
if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx)) if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
abort (); abort ();
...@@ -400,21 +408,22 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) ...@@ -400,21 +408,22 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
&& GET_MODE (value) != BLKmode && GET_MODE (value) != BLKmode
&& !(bitsize == 1 && GET_CODE (value) == CONST_INT) && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
/* Ensure insv's size is wide enough for this field. */ /* Ensure insv's size is wide enough for this field. */
&& (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]) && (insv_bitsize >= bitsize)
>= bitsize)
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
&& (bitsize + bitpos && (bitsize + bitpos > insv_bitsize)))
> GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]))))
{ {
int xbitpos = bitpos; int xbitpos = bitpos;
rtx value1; rtx value1;
rtx xop0 = op0; rtx xop0 = op0;
rtx last = get_last_insn (); rtx last = get_last_insn ();
rtx pat; rtx pat;
enum machine_mode maxmode enum machine_mode maxmode;
= insn_operand_mode[(int) CODE_FOR_insv][3];
int save_volatile_ok = volatile_ok; int save_volatile_ok = volatile_ok;
maxmode = insn_operand_mode[(int) CODE_FOR_insv][3];
if (maxmode == VOIDmode)
maxmode = word_mode;
volatile_ok = 1; volatile_ok = 1;
/* If this machine's insv can only insert into a register, copy OP0 /* If this machine's insv can only insert into a register, copy OP0
...@@ -894,6 +903,27 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -894,6 +903,27 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
register rtx op0 = str_rtx; register rtx op0 = str_rtx;
rtx spec_target = target; rtx spec_target = target;
rtx spec_target_subreg = 0; rtx spec_target_subreg = 0;
#ifdef HAVE_extv
int extv_bitsize;
#endif
#ifdef HAVE_extzv
int extzv_bitsize;
#endif
#ifdef HAVE_extv
if (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode)
extv_bitsize = GET_MODE_BITSIZE (word_mode);
else
extv_bitsize = GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]);
#endif
#ifdef HAVE_extzv
if (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode)
extzv_bitsize = GET_MODE_BITSIZE (word_mode);
else
extzv_bitsize
= GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]);
#endif
/* Discount the part of the structure before the desired byte. /* Discount the part of the structure before the desired byte.
We need to know how many bytes are safe to reference after it. */ We need to know how many bytes are safe to reference after it. */
...@@ -1073,11 +1103,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1073,11 +1103,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
{ {
#ifdef HAVE_extzv #ifdef HAVE_extzv
if (HAVE_extzv if (HAVE_extzv
&& (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]) && (extzv_bitsize >= bitsize)
>= bitsize)
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
&& (bitsize + bitpos && (bitsize + bitpos > extzv_bitsize)))
> GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]))))
{ {
int xbitpos = bitpos, xoffset = offset; int xbitpos = bitpos, xoffset = offset;
rtx bitsize_rtx, bitpos_rtx; rtx bitsize_rtx, bitpos_rtx;
...@@ -1087,8 +1115,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1087,8 +1115,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
rtx xspec_target = spec_target; rtx xspec_target = spec_target;
rtx xspec_target_subreg = spec_target_subreg; rtx xspec_target_subreg = spec_target_subreg;
rtx pat; rtx pat;
enum machine_mode maxmode enum machine_mode maxmode;
= insn_operand_mode[(int) CODE_FOR_extzv][0];
maxmode = insn_operand_mode[(int) CODE_FOR_extzv][0];
if (maxmode == VOIDmode)
maxmode = word_mode;
if (GET_CODE (xop0) == MEM) if (GET_CODE (xop0) == MEM)
{ {
...@@ -1213,11 +1244,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1213,11 +1244,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
{ {
#ifdef HAVE_extv #ifdef HAVE_extv
if (HAVE_extv if (HAVE_extv
&& (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]) && (extv_bitsize >= bitsize)
>= bitsize)
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG) && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
&& (bitsize + bitpos && (bitsize + bitpos > extv_bitsize)))
> GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]))))
{ {
int xbitpos = bitpos, xoffset = offset; int xbitpos = bitpos, xoffset = offset;
rtx bitsize_rtx, bitpos_rtx; rtx bitsize_rtx, bitpos_rtx;
...@@ -1226,8 +1255,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp, ...@@ -1226,8 +1255,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
rtx xspec_target = spec_target; rtx xspec_target = spec_target;
rtx xspec_target_subreg = spec_target_subreg; rtx xspec_target_subreg = spec_target_subreg;
rtx pat; rtx pat;
enum machine_mode maxmode enum machine_mode maxmode;
= insn_operand_mode[(int) CODE_FOR_extv][0];
maxmode = insn_operand_mode[(int) CODE_FOR_extv][0];
if (maxmode == VOIDmode)
maxmode = word_mode;
if (GET_CODE (xop0) == MEM) if (GET_CODE (xop0) == MEM)
{ {
......
...@@ -1975,11 +1975,19 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) ...@@ -1975,11 +1975,19 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
#ifdef HAVE_extzv #ifdef HAVE_extzv
if (GET_CODE (x) == ZERO_EXTRACT) if (GET_CODE (x) == ZERO_EXTRACT)
wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; {
wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
if (wanted_mode == VOIDmode)
wanted_mode = word_mode;
}
#endif #endif
#ifdef HAVE_extv #ifdef HAVE_extv
if (GET_CODE (x) == SIGN_EXTRACT) if (GET_CODE (x) == SIGN_EXTRACT)
wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1]; {
wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
if (wanted_mode == VOIDmode)
wanted_mode = word_mode;
}
#endif #endif
/* If we have a narrower mode, we can do something. */ /* If we have a narrower mode, we can do something. */
if (wanted_mode != VOIDmode if (wanted_mode != VOIDmode
...@@ -2168,11 +2176,14 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements) ...@@ -2168,11 +2176,14 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
&& ! mode_dependent_address_p (XEXP (tem, 0)) && ! mode_dependent_address_p (XEXP (tem, 0))
&& ! MEM_VOLATILE_P (tem)) && ! MEM_VOLATILE_P (tem))
{ {
enum machine_mode wanted_mode enum machine_mode wanted_mode;
= insn_operand_mode[(int) CODE_FOR_insv][0];
enum machine_mode is_mode = GET_MODE (tem); enum machine_mode is_mode = GET_MODE (tem);
HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2)); HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
wanted_mode = insn_operand_mode[(int) CODE_FOR_insv][0];
if (wanted_mode == VOIDmode)
wanted_mode = word_mode;
/* If we have a narrower mode, we can do something. */ /* If we have a narrower mode, we can do something. */
if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode)) if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
{ {
......
...@@ -484,11 +484,19 @@ validate_replace_rtx_1 (loc, from, to, object) ...@@ -484,11 +484,19 @@ validate_replace_rtx_1 (loc, from, to, object)
#ifdef HAVE_extzv #ifdef HAVE_extzv
if (code == ZERO_EXTRACT) if (code == ZERO_EXTRACT)
wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; {
wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
if (wanted_mode == VOIDmode)
wanted_mode = word_mode;
}
#endif #endif
#ifdef HAVE_extv #ifdef HAVE_extv
if (code == SIGN_EXTRACT) if (code == SIGN_EXTRACT)
wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1]; {
wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
if (wanted_mode == VOIDmode)
wanted_mode = word_mode;
}
#endif #endif
/* If we have a narrower mode, we can do something. */ /* If we have a narrower mode, we can do something. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment