mirror of
https://github.com/pret/agbcc.git
synced 2026-04-25 15:35:13 -05:00
remove big-endian target support
This commit is contained in:
parent
0823458650
commit
7444c4f6f7
|
|
@ -1972,10 +1972,7 @@ yylex ()
|
|||
value = 0;
|
||||
else
|
||||
value = (c >> (byte * width)) & bytemask;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
p[WCHAR_BYTES - byte - 1] = value;
|
||||
else
|
||||
p[byte] = value;
|
||||
p[byte] = value;
|
||||
}
|
||||
p += WCHAR_BYTES;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -774,13 +774,6 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
|
|||
args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
|
||||
* args[i].n_aligned_regs);
|
||||
|
||||
/* Structures smaller than a word are aligned to the least
|
||||
significant byte (to the right). On a BYTES_BIG_ENDIAN machine,
|
||||
this means we must skip the empty high order bytes when
|
||||
calculating the bit offset. */
|
||||
if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
|
||||
big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
|
||||
|
||||
for (j = 0; j < args[i].n_aligned_regs; j++)
|
||||
{
|
||||
rtx reg = gen_reg_rtx (word_mode);
|
||||
|
|
|
|||
184
gcc/combine.c
184
gcc/combine.c
|
|
@ -2821,9 +2821,6 @@ find_split_point (loc, insn)
|
|||
enum machine_mode mode = GET_MODE (dest);
|
||||
HOST_WIDE_UINT mask = ((HOST_WIDE_INT) 1 << len) - 1;
|
||||
|
||||
if (BITS_BIG_ENDIAN)
|
||||
pos = GET_MODE_BITSIZE (mode) - len - pos;
|
||||
|
||||
if ((HOST_WIDE_UINT) src == mask)
|
||||
SUBST (SET_SRC (x),
|
||||
gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
|
||||
|
|
@ -2917,8 +2914,6 @@ find_split_point (loc, insn)
|
|||
len = INTVAL (XEXP (SET_SRC (x), 1));
|
||||
pos = INTVAL (XEXP (SET_SRC (x), 2));
|
||||
|
||||
if (BITS_BIG_ENDIAN)
|
||||
pos = GET_MODE_BITSIZE (GET_MODE (inner)) - len - pos;
|
||||
unsignedp = (code == ZERO_EXTRACT);
|
||||
}
|
||||
break;
|
||||
|
|
@ -3569,14 +3564,6 @@ simplify_rtx (x, op0_mode, last, in_dest)
|
|||
|| mode_dependent_address_p (XEXP (inner, 0)))
|
||||
return gen_rtx_CLOBBER (mode, const0_rtx);
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
|
||||
endian_offset += UNITS_PER_WORD - GET_MODE_SIZE (mode);
|
||||
if (GET_MODE_SIZE (GET_MODE (inner)) < UNITS_PER_WORD)
|
||||
endian_offset -= (UNITS_PER_WORD
|
||||
- GET_MODE_SIZE (GET_MODE (inner)));
|
||||
}
|
||||
/* Note if the plus_constant doesn't make a valid address
|
||||
then this combination won't be accepted. */
|
||||
x = gen_rtx_MEM (mode,
|
||||
|
|
@ -3646,16 +3633,8 @@ simplify_rtx (x, op0_mode, last, in_dest)
|
|||
only if the constant's mode fits in one word. Note that we
|
||||
cannot use subreg_lowpart_p since SUBREG_REG may be VOIDmode. */
|
||||
if (CONSTANT_P (SUBREG_REG (x))
|
||||
&& ((GET_MODE_SIZE (op0_mode) <= UNITS_PER_WORD
|
||||
|| ! WORDS_BIG_ENDIAN)
|
||||
? SUBREG_WORD (x) == 0
|
||||
: (SUBREG_WORD (x)
|
||||
== ((GET_MODE_SIZE (op0_mode)
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
|
||||
/ UNITS_PER_WORD)))
|
||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (op0_mode)
|
||||
&& (! WORDS_BIG_ENDIAN
|
||||
|| GET_MODE_BITSIZE (op0_mode) <= BITS_PER_WORD))
|
||||
&& (SUBREG_WORD (x) == 0)
|
||||
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (op0_mode))
|
||||
return gen_lowpart_for_combine (mode, SUBREG_REG (x));
|
||||
|
||||
/* A paradoxical SUBREG of a VOIDmode constant is the same constant,
|
||||
|
|
@ -5281,9 +5260,6 @@ expand_compound_operation (x)
|
|||
if (len + pos > GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))
|
||||
SUBST (XEXP (x, 0), gen_rtx_USE (GET_MODE (x), XEXP (x, 0)));
|
||||
|
||||
if (BITS_BIG_ENDIAN)
|
||||
pos = GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - len - pos;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -5446,24 +5422,6 @@ expand_field_assignment (x)
|
|||
if (GET_CODE (pos) == CONST_INT
|
||||
&& INTVAL (pos) + len > GET_MODE_BITSIZE (GET_MODE (inner)))
|
||||
inner = gen_rtx_USE (GET_MODE (SET_DEST (x)), inner);
|
||||
|
||||
if (BITS_BIG_ENDIAN)
|
||||
{
|
||||
if (GET_CODE (pos) == CONST_INT)
|
||||
pos = GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner)) - len
|
||||
- INTVAL (pos));
|
||||
else if (GET_CODE (pos) == MINUS
|
||||
&& GET_CODE (XEXP (pos, 1)) == CONST_INT
|
||||
&& (INTVAL (XEXP (pos, 1))
|
||||
== GET_MODE_BITSIZE (GET_MODE (inner)) - len))
|
||||
/* If position is ADJUST - X, new position is X. */
|
||||
pos = XEXP (pos, 0);
|
||||
else
|
||||
pos = gen_binary (MINUS, GET_MODE (pos),
|
||||
GEN_INT (GET_MODE_BITSIZE (GET_MODE (inner))
|
||||
- len),
|
||||
pos);
|
||||
}
|
||||
}
|
||||
|
||||
/* A SUBREG between two modes that occupy the same numbers of words
|
||||
|
|
@ -5652,12 +5610,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
|||
|
||||
if (GET_CODE (inner) == MEM)
|
||||
{
|
||||
int offset;
|
||||
/* POS counts from lsb, but make OFFSET count in memory order. */
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset = (GET_MODE_BITSIZE (is_mode) - len - pos) / BITS_PER_UNIT;
|
||||
else
|
||||
offset = pos / BITS_PER_UNIT;
|
||||
int offset = pos / BITS_PER_UNIT;
|
||||
|
||||
new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset));
|
||||
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (inner);
|
||||
|
|
@ -5668,14 +5621,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
|||
/* We can't call gen_lowpart_for_combine here since we always want
|
||||
a SUBREG and it would sometimes return a new hard register. */
|
||||
if (tmode != inner_mode)
|
||||
new = gen_rtx_SUBREG (tmode, inner,
|
||||
(WORDS_BIG_ENDIAN
|
||||
&& GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD
|
||||
? (((GET_MODE_SIZE (inner_mode)
|
||||
- GET_MODE_SIZE (tmode))
|
||||
/ UNITS_PER_WORD)
|
||||
- pos / BITS_PER_WORD)
|
||||
: pos / BITS_PER_WORD));
|
||||
new = gen_rtx_SUBREG (tmode, inner, pos / BITS_PER_WORD);
|
||||
else
|
||||
new = inner;
|
||||
}
|
||||
|
|
@ -5722,50 +5668,8 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
|||
|
||||
/* Get the mode to use should INNER not be a MEM, the mode for the position,
|
||||
and the mode for the result. */
|
||||
#ifdef HAVE_insv
|
||||
if (in_dest)
|
||||
{
|
||||
wanted_inner_reg_mode
|
||||
= (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode
|
||||
? 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
|
||||
|
||||
#ifdef HAVE_extzv
|
||||
if (! in_dest && unsignedp)
|
||||
{
|
||||
wanted_inner_reg_mode
|
||||
= (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode
|
||||
? 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
|
||||
|
||||
#ifdef HAVE_extv
|
||||
if (! in_dest && ! unsignedp)
|
||||
{
|
||||
wanted_inner_reg_mode
|
||||
= (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode
|
||||
? 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
|
||||
|
||||
/* Never narrow an object, since that might not be safe. */
|
||||
|
||||
|
|
@ -5789,29 +5693,6 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
|||
|
||||
orig_pos = pos;
|
||||
|
||||
if (BITS_BIG_ENDIAN)
|
||||
{
|
||||
/* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to
|
||||
BITS_BIG_ENDIAN style. If position is constant, compute new
|
||||
position. Otherwise, build subtraction.
|
||||
Note that POS is relative to the mode of the original argument.
|
||||
If it's a MEM we need to recompute POS relative to that.
|
||||
However, if we're extracting from (or inserting into) a register,
|
||||
we want to recompute POS relative to wanted_inner_mode. */
|
||||
int width = (GET_CODE (inner) == MEM
|
||||
? GET_MODE_BITSIZE (is_mode)
|
||||
: GET_MODE_BITSIZE (wanted_inner_mode));
|
||||
|
||||
if (pos_rtx == 0)
|
||||
pos = width - len - pos;
|
||||
else
|
||||
pos_rtx
|
||||
= gen_rtx_combine (MINUS, GET_MODE (pos_rtx),
|
||||
GEN_INT (width - len), pos_rtx);
|
||||
/* POS may be less than 0 now, but we check for that below.
|
||||
Note that it can only be less than 0 if GET_CODE (inner) != MEM. */
|
||||
}
|
||||
|
||||
/* If INNER has a wider mode, make it smaller. If this is a constant
|
||||
extract, try to adjust the byte to point to the byte containing
|
||||
the value. */
|
||||
|
|
@ -5824,17 +5705,6 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
|||
{
|
||||
int offset = 0;
|
||||
|
||||
/* The computations below will be correct if the machine is big
|
||||
endian in both bits and bytes or little endian in bits and bytes.
|
||||
If it is mixed, we must adjust. */
|
||||
|
||||
/* If bytes are big endian and we had a paradoxical SUBREG, we must
|
||||
adjust OFFSET to compensate. */
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& ! spans_byte
|
||||
&& GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (is_mode))
|
||||
offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);
|
||||
|
||||
/* If this is a constant position, we can move to the desired byte. */
|
||||
if (pos_rtx == 0)
|
||||
{
|
||||
|
|
@ -5842,12 +5712,6 @@ make_extraction (mode, inner, pos, pos_rtx, len,
|
|||
pos %= GET_MODE_BITSIZE (wanted_inner_mode);
|
||||
}
|
||||
|
||||
if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
|
||||
&& ! spans_byte
|
||||
&& is_mode != wanted_inner_mode)
|
||||
offset = (GET_MODE_SIZE (is_mode)
|
||||
- GET_MODE_SIZE (wanted_inner_mode) - offset);
|
||||
|
||||
if (offset != 0 || inner_mode != wanted_inner_mode)
|
||||
{
|
||||
rtx newmem = gen_rtx_MEM (wanted_inner_mode,
|
||||
|
|
@ -6369,8 +6233,7 @@ force_to_mode (x, mode, mask, reg, just_select)
|
|||
/* X is a (use (mem ..)) that was made from a bit-field extraction that
|
||||
spanned the boundary of the MEM. If we are now masking so it is
|
||||
within that boundary, we don't need the USE any more. */
|
||||
if (! BITS_BIG_ENDIAN
|
||||
&& (mask & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
|
||||
if ((mask & ~ GET_MODE_MASK (GET_MODE (XEXP (x, 0)))) == 0)
|
||||
return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
|
||||
break;
|
||||
|
||||
|
|
@ -8526,10 +8389,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
|
|||
&& (tmode = mode_for_size (GET_MODE_BITSIZE (mode) - count,
|
||||
MODE_INT, 1)) != BLKmode)
|
||||
{
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
new = gen_rtx_MEM (tmode, XEXP (varop, 0));
|
||||
else
|
||||
new = gen_rtx_MEM (tmode,
|
||||
new = gen_rtx_MEM (tmode,
|
||||
plus_constant (XEXP (varop, 0),
|
||||
count / BITS_PER_UNIT));
|
||||
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (varop);
|
||||
|
|
@ -8551,15 +8411,11 @@ simplify_shift_const (x, code, result_mode, varop, count)
|
|||
MODE_INT, 1)) != BLKmode
|
||||
&& tmode == GET_MODE (XEXP (varop, 0)))
|
||||
{
|
||||
if (BITS_BIG_ENDIAN)
|
||||
new = XEXP (varop, 0);
|
||||
else
|
||||
{
|
||||
|
||||
new = copy_rtx (XEXP (varop, 0));
|
||||
SUBST (XEXP (new, 0),
|
||||
plus_constant (XEXP (new, 0),
|
||||
count / BITS_PER_UNIT));
|
||||
}
|
||||
|
||||
varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND
|
||||
: ZERO_EXTEND, mode, new);
|
||||
|
|
@ -9280,16 +9136,6 @@ gen_lowpart_for_combine (mode, x)
|
|||
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
|
||||
return gen_rtx_SUBREG (mode, x, 0);
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
/* Adjust the address so that the address-after-the-data is
|
||||
unchanged. */
|
||||
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
|
||||
}
|
||||
new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
|
||||
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
|
||||
MEM_COPY_ATTRIBUTES (new, x);
|
||||
|
|
@ -9308,10 +9154,6 @@ gen_lowpart_for_combine (mode, x)
|
|||
{
|
||||
int word = 0;
|
||||
|
||||
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
|
||||
word = ((GET_MODE_SIZE (GET_MODE (x))
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
|
||||
/ UNITS_PER_WORD);
|
||||
return gen_rtx_SUBREG (mode, x, word);
|
||||
}
|
||||
}
|
||||
|
|
@ -9832,18 +9674,6 @@ simplify_comparison (code, pop0, pop1)
|
|||
&& equality_comparison_p && const_op == 0
|
||||
&& (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
|
||||
{
|
||||
if (BITS_BIG_ENDIAN)
|
||||
{
|
||||
#ifdef HAVE_extzv
|
||||
mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
|
||||
if (mode == VOIDmode)
|
||||
mode = word_mode;
|
||||
i = (GET_MODE_BITSIZE (mode) - 1 - i);
|
||||
#else
|
||||
i = BITS_PER_WORD - 1 - i;
|
||||
#endif
|
||||
}
|
||||
|
||||
op0 = XEXP (op0, 2);
|
||||
op1 = GEN_INT (i);
|
||||
const_op = i;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
|
|||
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
|
||||
|
||||
# Avoid building a duplicate set of libraries for the default endian-ness.
|
||||
MULTILIB_OPTIONS = mlittle-endian/mbig-endian mno-thumb-interwork/mthumb-interwork
|
||||
MULTILIB_DIRNAMES = le be normal interwork
|
||||
MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
|
||||
MULTILIB_OPTIONS = mno-thumb-interwork/mthumb-interwork
|
||||
MULTILIB_DIRNAMES = normal interwork
|
||||
MULTILIB_MATCHES =
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
|
|
|||
|
|
@ -1365,13 +1365,13 @@ thumb_print_operand(FILE *f, rtx x, int code)
|
|||
case 'Q':
|
||||
if (REGNO(x) > 15)
|
||||
abort();
|
||||
fputs(reg_names[REGNO(x) + (WORDS_BIG_ENDIAN ? 1 : 0)], f);
|
||||
fputs(reg_names[REGNO(x)], f);
|
||||
return;
|
||||
|
||||
case 'R':
|
||||
if (REGNO(x) > 15)
|
||||
abort();
|
||||
fputs(reg_names[REGNO(x) + (WORDS_BIG_ENDIAN ? 0 : 1)], f);
|
||||
fputs(reg_names[REGNO(x) + 1], f);
|
||||
return;
|
||||
|
||||
case 'H':
|
||||
|
|
|
|||
|
|
@ -41,23 +41,13 @@ Boston, MA 02111-1307, USA. */
|
|||
#define CPP_PREDEFINES "-Dthumb -D__thumb -Acpu(arm) -Amachine(arm)"
|
||||
#endif
|
||||
|
||||
#ifndef CPP_SPEC
|
||||
#define CPP_SPEC "\
|
||||
%{mbig-endian:-D__ARMEB__ -D__THUMBEB__} \
|
||||
%{mbe:-D__ARMEB__ -D__THUMBEB__} \
|
||||
%{!mbe: %{!mbig-endian:-D__ARMEL__ -D__THUMBEL__}} \
|
||||
"
|
||||
#endif
|
||||
|
||||
#ifndef ASM_SPEC
|
||||
#define ASM_SPEC "-marm7tdmi %{mthumb-interwork:-mthumb-interwork} %{mbig-endian:-EB}"
|
||||
#define ASM_SPEC "-marm7tdmi %{mthumb-interwork:-mthumb-interwork}"
|
||||
#endif
|
||||
#define LINK_SPEC "%{mbig-endian:-EB} -X"
|
||||
#define LINK_SPEC "-X"
|
||||
|
||||
#define TARGET_VERSION fputs (" (ARM/THUMB:generic)", stderr);
|
||||
|
||||
/* Nonzero if we should compile with BYTES_BIG_ENDIAN set to 1. */
|
||||
#define THUMB_FLAG_BIG_END 0x0001
|
||||
#define ARM_FLAG_THUMB 0x1000 /* same as in arm.h */
|
||||
#define THUMB_FLAG_CALLER_SUPER_INTERWORKING 0x80000
|
||||
|
||||
|
|
@ -68,7 +58,6 @@ Boston, MA 02111-1307, USA. */
|
|||
/* Run-time compilation parameters selecting different hardware/software subsets. */
|
||||
extern int target_flags;
|
||||
#define TARGET_DEFAULT 0 /* ARM_FLAG_THUMB */
|
||||
#define TARGET_BIG_END (target_flags & THUMB_FLAG_BIG_END)
|
||||
#define TARGET_THUMB_INTERWORK (target_flags & ARM_FLAG_THUMB)
|
||||
|
||||
/* Set if calls via function pointers should assume that their
|
||||
|
|
@ -85,8 +74,6 @@ extern int target_flags;
|
|||
|
||||
#define TARGET_SWITCHES \
|
||||
{ \
|
||||
{"big-endian", THUMB_FLAG_BIG_END}, \
|
||||
{"little-endian", -THUMB_FLAG_BIG_END}, \
|
||||
{"thumb-interwork", ARM_FLAG_THUMB}, \
|
||||
{"no-thumb-interwork", -ARM_FLAG_THUMB}, \
|
||||
{"caller-super-interworking", THUMB_FLAG_CALLER_SUPER_INTERWORKING}, \
|
||||
|
|
@ -350,16 +337,6 @@ do { \
|
|||
|
||||
/* Storage Layout */
|
||||
|
||||
/* Define this is most significant bit is lowest numbered in
|
||||
instructions that operate on numbered bit-fields. */
|
||||
#define BITS_BIG_ENDIAN 0
|
||||
|
||||
/* Define this if most significant byte of a word is the lowest
|
||||
numbered. */
|
||||
#define BYTES_BIG_ENDIAN (TARGET_BIG_END != 0)
|
||||
|
||||
#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
|
||||
|
||||
#define FLOAT_WORDS_BIG_ENDIAN 1
|
||||
|
||||
#define BITS_PER_UNIT 8
|
||||
|
|
|
|||
16
gcc/cse.c
16
gcc/cse.c
|
|
@ -4804,10 +4804,6 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
|
|||
/* Extracting a bit-field from a constant */
|
||||
HOST_WIDE_INT val = INTVAL (op0);
|
||||
|
||||
if (BITS_BIG_ENDIAN)
|
||||
val >>= (GET_MODE_BITSIZE (op0_mode)
|
||||
- INTVAL (op2) - INTVAL (op1));
|
||||
else
|
||||
val >>= INTVAL (op2);
|
||||
|
||||
if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
|
||||
|
|
@ -5226,9 +5222,7 @@ fold_rtx (x, insn)
|
|||
0, const_mode)) != 0)
|
||||
return new;
|
||||
|
||||
if (((BYTES_BIG_ENDIAN
|
||||
&& offset == GET_MODE_SIZE (GET_MODE (constant)) - 1)
|
||||
|| (! BYTES_BIG_ENDIAN && offset == 0))
|
||||
if (offset == 0
|
||||
&& (new = gen_lowpart_if_possible (mode, constant)) != 0)
|
||||
return new;
|
||||
}
|
||||
|
|
@ -5917,14 +5911,6 @@ gen_lowpart_if_possible (mode, x)
|
|||
register int offset = 0;
|
||||
rtx new;
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
/* Adjust the address so that the address-after-the-data is
|
||||
unchanged. */
|
||||
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
|
||||
new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset));
|
||||
if (! memory_address_p (mode, XEXP (new, 0)))
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -393,16 +393,8 @@ static void dwarf2out_stack_adjust (rtx);
|
|||
#ifndef ASM_OUTPUT_DWARF_DATA8
|
||||
#define ASM_OUTPUT_DWARF_DATA8(FILE,HIGH_VALUE,LOW_VALUE) \
|
||||
do { \
|
||||
if (WORDS_BIG_ENDIAN) \
|
||||
{ \
|
||||
fprintf ((FILE), "\t%s\t0x%lx\n", UNALIGNED_INT_ASM_OP, (HIGH_VALUE));\
|
||||
fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (LOW_VALUE));\
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf ((FILE), "\t%s\t0x%lx\n", UNALIGNED_INT_ASM_OP, (LOW_VALUE)); \
|
||||
fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (HIGH_VALUE)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
|
@ -7064,8 +7056,7 @@ add_location_or_const_value_attribute (die, decl)
|
|||
all* cases where (rtl == NULL_RTX) just below. */
|
||||
if (declared_type == passed_type)
|
||||
rtl = DECL_INCOMING_RTL (decl);
|
||||
else if (! BYTES_BIG_ENDIAN
|
||||
&& TREE_CODE (declared_type) == INTEGER_TYPE
|
||||
else if (TREE_CODE (declared_type) == INTEGER_TYPE
|
||||
&& TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
|
||||
rtl = DECL_INCOMING_RTL (decl);
|
||||
}
|
||||
|
|
@ -7390,18 +7381,15 @@ add_bit_offset_attribute (die, decl)
|
|||
highest_order_object_bit_offset = object_offset_in_bytes * BITS_PER_UNIT;
|
||||
highest_order_field_bit_offset = bitpos_int;
|
||||
|
||||
if (! BYTES_BIG_ENDIAN)
|
||||
{
|
||||
|
||||
highest_order_field_bit_offset
|
||||
+= (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl));
|
||||
|
||||
highest_order_object_bit_offset += simple_type_size_in_bits (type);
|
||||
}
|
||||
|
||||
|
||||
bit_offset
|
||||
= (! BYTES_BIG_ENDIAN
|
||||
? highest_order_object_bit_offset - highest_order_field_bit_offset
|
||||
: highest_order_field_bit_offset - highest_order_object_bit_offset);
|
||||
= highest_order_object_bit_offset - highest_order_field_bit_offset;
|
||||
|
||||
add_AT_unsigned (die, DW_AT_bit_offset, bit_offset);
|
||||
}
|
||||
|
|
|
|||
156
gcc/emit-rtl.c
156
gcc/emit-rtl.c
|
|
@ -620,11 +620,6 @@ gen_lowpart_common (mode, x)
|
|||
/ UNITS_PER_WORD)))
|
||||
return 0;
|
||||
|
||||
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
|
||||
word = ((GET_MODE_SIZE (GET_MODE (x))
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
|
||||
/ UNITS_PER_WORD);
|
||||
|
||||
if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
|
||||
&& GET_MODE_CLASS (mode) == MODE_INT)
|
||||
{
|
||||
|
|
@ -658,10 +653,6 @@ gen_lowpart_common (mode, x)
|
|||
regs are sized by the underlying register size. Better would be
|
||||
to always interpret the subreg offset parameter as bytes or bits. */
|
||||
|
||||
if (WORDS_BIG_ENDIAN && REGNO (x) < FIRST_PSEUDO_REGISTER)
|
||||
word = (HARD_REGNO_NREGS (REGNO (x), GET_MODE (x))
|
||||
- HARD_REGNO_NREGS (REGNO (x), mode));
|
||||
|
||||
/* If the register is not valid for MODE, return 0. If we don't
|
||||
do this, there is no way to fix up the resulting REG later.
|
||||
But we do do this if the current REG is not valid for its
|
||||
|
|
@ -770,7 +761,6 @@ gen_lowpart_common (mode, x)
|
|||
&& GET_MODE (x) == VOIDmode
|
||||
&& (sizeof (double) * HOST_BITS_PER_CHAR
|
||||
== 2 * HOST_BITS_PER_WIDE_INT))
|
||||
#ifdef REAL_ARITHMETIC
|
||||
{
|
||||
REAL_VALUE_TYPE r;
|
||||
HOST_WIDE_INT i[2];
|
||||
|
|
@ -783,33 +773,11 @@ gen_lowpart_common (mode, x)
|
|||
|
||||
/* REAL_VALUE_TARGET_DOUBLE takes the addressing order of the
|
||||
target machine. */
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
i[0] = high, i[1] = low;
|
||||
else
|
||||
i[0] = low, i[1] = high;
|
||||
|
||||
r = REAL_VALUE_FROM_TARGET_DOUBLE (i);
|
||||
return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
|
||||
}
|
||||
#else
|
||||
{
|
||||
union {HOST_WIDE_INT i[2]; double d; } u;
|
||||
HOST_WIDE_INT low, high;
|
||||
|
||||
if (GET_CODE (x) == CONST_INT)
|
||||
low = INTVAL (x), high = low >> (HOST_BITS_PER_WIDE_INT -1);
|
||||
else
|
||||
low = CONST_DOUBLE_LOW (x), high = CONST_DOUBLE_HIGH (x);
|
||||
|
||||
#ifdef HOST_WORDS_BIG_ENDIAN
|
||||
u.i[0] = high, u.i[1] = low;
|
||||
#else
|
||||
u.i[0] = low, u.i[1] = high;
|
||||
#endif
|
||||
|
||||
return CONST_DOUBLE_FROM_REAL_VALUE (u.d, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We need an extra case for machines where HOST_BITS_PER_WIDE_INT is the
|
||||
same as sizeof (double) or when sizeof (float) is larger than the
|
||||
|
|
@ -853,9 +821,9 @@ gen_lowpart_common (mode, x)
|
|||
&& GET_MODE_BITSIZE (mode) == 2 * BITS_PER_WORD)
|
||||
{
|
||||
rtx lowpart
|
||||
= operand_subword (x, word + WORDS_BIG_ENDIAN, 0, GET_MODE (x));
|
||||
= operand_subword (x, word, 0, GET_MODE (x));
|
||||
rtx highpart
|
||||
= operand_subword (x, word + ! WORDS_BIG_ENDIAN, 0, GET_MODE (x));
|
||||
= operand_subword (x, word + 1, 0, GET_MODE (x));
|
||||
|
||||
if (lowpart && GET_CODE (lowpart) == CONST_INT
|
||||
&& highpart && GET_CODE (highpart) == CONST_INT)
|
||||
|
|
@ -876,8 +844,6 @@ gen_realpart (mode, x)
|
|||
{
|
||||
if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
|
||||
return XEXP (x, 0);
|
||||
else if (WORDS_BIG_ENDIAN)
|
||||
return gen_highpart (mode, x);
|
||||
else
|
||||
return gen_lowpart (mode, x);
|
||||
}
|
||||
|
|
@ -892,8 +858,6 @@ gen_imagpart (mode, x)
|
|||
{
|
||||
if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
|
||||
return XEXP (x, 1);
|
||||
else if (WORDS_BIG_ENDIAN)
|
||||
return gen_lowpart (mode, x);
|
||||
else
|
||||
return gen_highpart (mode, x);
|
||||
}
|
||||
|
|
@ -941,15 +905,6 @@ gen_lowpart (mode, x)
|
|||
{
|
||||
/* The only additional case we can do is MEM. */
|
||||
register int offset = 0;
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
/* Adjust the address so that the address-after-the-data
|
||||
is unchanged. */
|
||||
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
|
||||
|
||||
return change_address (x, mode, plus_constant (XEXP (x, 0), offset));
|
||||
}
|
||||
|
|
@ -987,12 +942,11 @@ gen_highpart (mode, x)
|
|||
else if (GET_CODE (x) == MEM)
|
||||
{
|
||||
register int offset = 0;
|
||||
if (! WORDS_BIG_ENDIAN)
|
||||
|
||||
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
|
||||
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
|
||||
|
||||
if (! BYTES_BIG_ENDIAN
|
||||
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD)
|
||||
if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
|
||||
offset -= (GET_MODE_SIZE (mode)
|
||||
- MIN (UNITS_PER_WORD,
|
||||
GET_MODE_SIZE (GET_MODE (x))));
|
||||
|
|
@ -1019,9 +973,7 @@ gen_highpart (mode, x)
|
|||
regs are sized by the underlying register size. Better would be
|
||||
to always interpret the subreg offset parameter as bytes or bits. */
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
word = 0;
|
||||
else if (REGNO (x) < FIRST_PSEUDO_REGISTER)
|
||||
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
|
||||
word = (HARD_REGNO_NREGS (REGNO (x), GET_MODE (x))
|
||||
- HARD_REGNO_NREGS (REGNO (x), mode));
|
||||
else
|
||||
|
|
@ -1060,13 +1012,6 @@ subreg_lowpart_p (x)
|
|||
else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
|
||||
return 0;
|
||||
|
||||
if (WORDS_BIG_ENDIAN
|
||||
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) > UNITS_PER_WORD)
|
||||
return (SUBREG_WORD (x)
|
||||
== ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
|
||||
- MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD))
|
||||
/ UNITS_PER_WORD));
|
||||
|
||||
return SUBREG_WORD (x) == 0;
|
||||
}
|
||||
|
||||
|
|
@ -1185,7 +1130,7 @@ operand_subword (op, i, validate_address, mode)
|
|||
constants are easy. Note that REAL_VALUE_TO_TARGET_{SINGLE,DOUBLE}
|
||||
are defined as returning one or two 32 bit values, respectively,
|
||||
and not values of BITS_PER_WORD bits. */
|
||||
#ifdef REAL_ARITHMETIC
|
||||
|
||||
/* The output is some bits, the width of the target machine's word.
|
||||
A wider-word host can surely hold them in a CONST_INT. A narrower-word
|
||||
host can't. */
|
||||
|
|
@ -1200,56 +1145,12 @@ operand_subword (op, i, validate_address, mode)
|
|||
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
|
||||
REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
|
||||
|
||||
/* We handle 32-bit and >= 64-bit words here. Note that the order in
|
||||
which the words are written depends on the word endianness.
|
||||
|
||||
??? This is a potential portability problem and should
|
||||
be fixed at some point. */
|
||||
if (BITS_PER_WORD == 32)
|
||||
return GEN_INT ((HOST_WIDE_INT) k[i]);
|
||||
#if HOST_BITS_PER_WIDE_INT > 32
|
||||
else if (BITS_PER_WORD >= 64 && i == 0)
|
||||
return GEN_INT ((((HOST_WIDE_INT) k[! WORDS_BIG_ENDIAN]) << 32)
|
||||
| (HOST_WIDE_INT) k[WORDS_BIG_ENDIAN]);
|
||||
#endif
|
||||
else if (BITS_PER_WORD == 16)
|
||||
{
|
||||
long value;
|
||||
value = k[i >> 1];
|
||||
if ((i & 0x1) == !WORDS_BIG_ENDIAN)
|
||||
value >>= 16;
|
||||
value &= 0xffff;
|
||||
return GEN_INT ((HOST_WIDE_INT) value);
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
return GEN_INT ((HOST_WIDE_INT) k[i]);
|
||||
}
|
||||
#else /* no REAL_ARITHMETIC */
|
||||
if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
|
||||
&& HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
|
||||
|| flag_pretend_float)
|
||||
&& GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
|
||||
&& GET_CODE (op) == CONST_DOUBLE)
|
||||
{
|
||||
/* The constant is stored in the host's word-ordering,
|
||||
but we want to access it in the target's word-ordering. Some
|
||||
compilers don't like a conditional inside macro args, so we have two
|
||||
copies of the return. */
|
||||
#ifdef HOST_WORDS_BIG_ENDIAN
|
||||
return GEN_INT (i == WORDS_BIG_ENDIAN
|
||||
? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op));
|
||||
#else
|
||||
return GEN_INT (i != WORDS_BIG_ENDIAN
|
||||
? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op));
|
||||
#endif
|
||||
}
|
||||
#endif /* no REAL_ARITHMETIC */
|
||||
|
||||
/* Single word float is a little harder, since single- and double-word
|
||||
values often do not have the same high-order bits. We have already
|
||||
verified that we want the only defined word of the single-word value. */
|
||||
#ifdef REAL_ARITHMETIC
|
||||
if (GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_BITSIZE (mode) == 32
|
||||
&& GET_CODE (op) == CONST_DOUBLE)
|
||||
|
|
@ -1260,48 +1161,8 @@ operand_subword (op, i, validate_address, mode)
|
|||
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
|
||||
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
|
||||
|
||||
if (BITS_PER_WORD == 16)
|
||||
{
|
||||
if ((i & 0x1) == !WORDS_BIG_ENDIAN)
|
||||
l >>= 16;
|
||||
l &= 0xffff;
|
||||
}
|
||||
return GEN_INT ((HOST_WIDE_INT) l);
|
||||
}
|
||||
#else
|
||||
if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
|
||||
&& HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
|
||||
|| flag_pretend_float)
|
||||
&& sizeof (float) * 8 == HOST_BITS_PER_WIDE_INT
|
||||
&& GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (mode) == UNITS_PER_WORD
|
||||
&& GET_CODE (op) == CONST_DOUBLE)
|
||||
{
|
||||
double d;
|
||||
union {float f; HOST_WIDE_INT i; } u;
|
||||
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (d, op);
|
||||
|
||||
u.f = d;
|
||||
return GEN_INT (u.i);
|
||||
}
|
||||
if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
|
||||
&& HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
|
||||
|| flag_pretend_float)
|
||||
&& sizeof (double) * 8 == HOST_BITS_PER_WIDE_INT
|
||||
&& GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (mode) == UNITS_PER_WORD
|
||||
&& GET_CODE (op) == CONST_DOUBLE)
|
||||
{
|
||||
double d;
|
||||
union {double d; HOST_WIDE_INT i; } u;
|
||||
|
||||
REAL_VALUE_FROM_CONST_DOUBLE (d, op);
|
||||
|
||||
u.d = d;
|
||||
return GEN_INT (u.i);
|
||||
}
|
||||
#endif /* no REAL_ARITHMETIC */
|
||||
|
||||
/* The only remaining cases that we can handle are integers.
|
||||
Convert to proper endianness now since these cases need it.
|
||||
|
|
@ -1319,9 +1180,6 @@ operand_subword (op, i, validate_address, mode)
|
|||
|| BITS_PER_WORD > HOST_BITS_PER_WIDE_INT)
|
||||
return 0;
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
i = GET_MODE_SIZE (mode) / UNITS_PER_WORD - 1 - i;
|
||||
|
||||
/* Find out which word on the host machine this value is in and get
|
||||
it from the constant. */
|
||||
val = (i / size_ratio == 0
|
||||
|
|
|
|||
548
gcc/expmed.c
548
gcc/expmed.c
|
|
@ -230,14 +230,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
|||
register int offset = bitnum / unit;
|
||||
register int bitpos = bitnum % unit;
|
||||
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))
|
||||
abort ();
|
||||
|
|
@ -276,14 +268,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
|||
}
|
||||
}
|
||||
|
||||
/* If OP0 is a register, BITPOS must count within a word.
|
||||
But as we have it, it counts within whatever size OP0 now has.
|
||||
On a bigendian machine, these are not the same, so convert. */
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& GET_CODE (op0) != MEM
|
||||
&& unit > GET_MODE_BITSIZE (GET_MODE (op0)))
|
||||
bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
|
||||
|
||||
value = protect_from_queue (value, 0);
|
||||
|
||||
if (flag_force_mem)
|
||||
|
|
@ -327,7 +311,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
|||
can be done with a movestrict instruction. */
|
||||
|
||||
if (GET_CODE (op0) != MEM
|
||||
&& (BYTES_BIG_ENDIAN ? bitpos + bitsize == unit : bitpos == 0)
|
||||
&& (bitpos == 0)
|
||||
&& bitsize == GET_MODE_BITSIZE (fieldmode)
|
||||
&& (GET_MODE (op0) == fieldmode
|
||||
|| (movstrict_optab->handlers[(int) fieldmode].insn_code
|
||||
|
|
@ -374,10 +358,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
|||
/* Here we transfer the words of the field
|
||||
in the order least significant first.
|
||||
This is because the most significant word is the one which may
|
||||
be less than full.
|
||||
However, only do that if the value is not BLKmode. */
|
||||
|
||||
int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
|
||||
be less than full. */
|
||||
|
||||
int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
|
||||
int i;
|
||||
|
|
@ -393,10 +374,8 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
|||
{
|
||||
/* If I is 0, use the low-order word in both field and target;
|
||||
if I is 1, use the next to lowest word; and so on. */
|
||||
int wordnum = (backwards ? nwords - i - 1 : i);
|
||||
int bit_offset = (backwards
|
||||
? MAX (bitsize - (i + 1) * BITS_PER_WORD, 0)
|
||||
: i * BITS_PER_WORD);
|
||||
int wordnum = i;
|
||||
int bit_offset = i * BITS_PER_WORD;
|
||||
store_bit_field (op0, MIN (BITS_PER_WORD,
|
||||
bitsize - i * BITS_PER_WORD),
|
||||
bitnum + bit_offset, word_mode,
|
||||
|
|
@ -457,147 +436,6 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
|
|||
/* Now OFFSET is nonzero only if OP0 is memory
|
||||
and is therefore always measured in bytes. */
|
||||
|
||||
#ifdef HAVE_insv
|
||||
if (HAVE_insv
|
||||
&& GET_MODE (value) != BLKmode
|
||||
&& !(bitsize == 1 && GET_CODE (value) == CONST_INT)
|
||||
/* Ensure insv's size is wide enough for this field. */
|
||||
&& (insv_bitsize >= bitsize)
|
||||
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
|
||||
&& (bitsize + bitpos > insv_bitsize)))
|
||||
{
|
||||
int xbitpos = bitpos;
|
||||
rtx value1;
|
||||
rtx xop0 = op0;
|
||||
rtx last = get_last_insn ();
|
||||
rtx pat;
|
||||
enum machine_mode maxmode;
|
||||
int save_volatile_ok = volatile_ok;
|
||||
|
||||
maxmode = insn_operand_mode[(int) CODE_FOR_insv][3];
|
||||
if (maxmode == VOIDmode)
|
||||
maxmode = word_mode;
|
||||
|
||||
volatile_ok = 1;
|
||||
|
||||
/* If this machine's insv can only insert into a register, copy OP0
|
||||
into a register and save it back later. */
|
||||
/* This used to check flag_force_mem, but that was a serious
|
||||
de-optimization now that flag_force_mem is enabled by -O2. */
|
||||
if (GET_CODE (op0) == MEM
|
||||
&& ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
|
||||
(op0, VOIDmode)))
|
||||
{
|
||||
rtx tempreg;
|
||||
enum machine_mode bestmode;
|
||||
|
||||
/* Get the mode to use for inserting into this field. If OP0 is
|
||||
BLKmode, get the smallest mode consistent with the alignment. If
|
||||
OP0 is a non-BLKmode object that is no wider than MAXMODE, use its
|
||||
mode. Otherwise, use the smallest mode containing the field. */
|
||||
|
||||
if (GET_MODE (op0) == BLKmode
|
||||
|| GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode))
|
||||
bestmode
|
||||
= get_best_mode (bitsize, bitnum, align * BITS_PER_UNIT, maxmode,
|
||||
MEM_VOLATILE_P (op0));
|
||||
else
|
||||
bestmode = GET_MODE (op0);
|
||||
|
||||
if (bestmode == VOIDmode
|
||||
|| (SLOW_UNALIGNED_ACCESS && GET_MODE_SIZE (bestmode) > align))
|
||||
goto insv_loses;
|
||||
|
||||
/* Adjust address to point to the containing unit of that mode. */
|
||||
unit = GET_MODE_BITSIZE (bestmode);
|
||||
/* Compute offset as multiple of this unit, counting in bytes. */
|
||||
offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
|
||||
bitpos = bitnum % unit;
|
||||
op0 = change_address (op0, bestmode,
|
||||
plus_constant (XEXP (op0, 0), offset));
|
||||
|
||||
/* Fetch that unit, store the bitfield in it, then store the unit. */
|
||||
tempreg = copy_to_reg (op0);
|
||||
store_bit_field (tempreg, bitsize, bitpos, fieldmode, value,
|
||||
align, total_size);
|
||||
emit_move_insn (op0, tempreg);
|
||||
return value;
|
||||
}
|
||||
volatile_ok = save_volatile_ok;
|
||||
|
||||
/* Add OFFSET into OP0's address. */
|
||||
if (GET_CODE (xop0) == MEM)
|
||||
xop0 = change_address (xop0, byte_mode,
|
||||
plus_constant (XEXP (xop0, 0), offset));
|
||||
|
||||
/* If xop0 is a register, we need it in MAXMODE
|
||||
to make it acceptable to the format of insv. */
|
||||
if (GET_CODE (xop0) == SUBREG)
|
||||
/* We can't just change the mode, because this might clobber op0,
|
||||
and we will need the original value of op0 if insv fails. */
|
||||
xop0 = gen_rtx_SUBREG (maxmode, SUBREG_REG (xop0), SUBREG_WORD (xop0));
|
||||
if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
|
||||
xop0 = gen_rtx_SUBREG (maxmode, xop0, 0);
|
||||
|
||||
/* On big-endian machines, we count bits from the most significant.
|
||||
If the bit field insn does not, we must invert. */
|
||||
|
||||
if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
|
||||
xbitpos = unit - bitsize - xbitpos;
|
||||
|
||||
/* We have been counting XBITPOS within UNIT.
|
||||
Count instead within the size of the register. */
|
||||
if (BITS_BIG_ENDIAN && GET_CODE (xop0) != MEM)
|
||||
xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
|
||||
|
||||
unit = GET_MODE_BITSIZE (maxmode);
|
||||
|
||||
/* Convert VALUE to maxmode (which insv insn wants) in VALUE1. */
|
||||
value1 = value;
|
||||
if (GET_MODE (value) != maxmode)
|
||||
{
|
||||
if (GET_MODE_BITSIZE (GET_MODE (value)) >= bitsize)
|
||||
{
|
||||
/* Optimization: Don't bother really extending VALUE
|
||||
if it has all the bits we will actually use. However,
|
||||
if we must narrow it, be sure we do it correctly. */
|
||||
|
||||
if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode))
|
||||
{
|
||||
/* Avoid making subreg of a subreg, or of a mem. */
|
||||
if (GET_CODE (value1) != REG)
|
||||
value1 = copy_to_reg (value1);
|
||||
value1 = gen_rtx_SUBREG (maxmode, value1, 0);
|
||||
}
|
||||
else
|
||||
value1 = gen_lowpart (maxmode, value1);
|
||||
}
|
||||
else if (!CONSTANT_P (value))
|
||||
/* Parse phase is supposed to make VALUE's data type
|
||||
match that of the component reference, which is a type
|
||||
at least as wide as the field; so VALUE should have
|
||||
a mode that corresponds to that type. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* If this machine's insv insists on a register,
|
||||
get VALUE1 into a register. */
|
||||
if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3])
|
||||
(value1, maxmode)))
|
||||
value1 = force_reg (maxmode, value1);
|
||||
|
||||
pat = gen_insv (xop0, GEN_INT (bitsize), GEN_INT (xbitpos), value1);
|
||||
if (pat)
|
||||
emit_insn (pat);
|
||||
else
|
||||
{
|
||||
delete_insns_since (last);
|
||||
store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
|
||||
}
|
||||
}
|
||||
else
|
||||
insv_loses:
|
||||
#endif
|
||||
/* Insv is not available; store using shifts and boolean ops. */
|
||||
store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
|
||||
return value;
|
||||
|
|
@ -700,12 +538,6 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
|
|||
BITPOS is the starting bit number within OP0.
|
||||
(OP0's mode may actually be narrower than MODE.) */
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
/* BITPOS is the distance between our msb
|
||||
and that of the containing datum.
|
||||
Convert it to the distance from the lsb. */
|
||||
bitpos = total_bits - bitsize - bitpos;
|
||||
|
||||
/* Now BITPOS is always the distance between our lsb
|
||||
and that of OP0. */
|
||||
|
||||
|
|
@ -839,42 +671,6 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
|
|||
thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
|
||||
thissize = MIN (thissize, unit - thispos);
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
int total_bits;
|
||||
|
||||
/* We must do an endian conversion exactly the same way as it is
|
||||
done in extract_bit_field, so that the two calls to
|
||||
extract_fixed_bit_field will have comparable arguments. */
|
||||
if (GET_CODE (value) != MEM || GET_MODE (value) == BLKmode)
|
||||
total_bits = BITS_PER_WORD;
|
||||
else
|
||||
total_bits = GET_MODE_BITSIZE (GET_MODE (value));
|
||||
|
||||
/* Fetch successively less significant portions. */
|
||||
if (GET_CODE (value) == CONST_INT)
|
||||
part = GEN_INT (((HOST_WIDE_UINT) (INTVAL (value))
|
||||
>> (bitsize - bitsdone - thissize))
|
||||
& (((HOST_WIDE_INT) 1 << thissize) - 1));
|
||||
else
|
||||
/* The args are chosen so that the last part includes the
|
||||
lsb. Give extract_bit_field the value it needs (with
|
||||
endianness compensation) to fetch the piece we want.
|
||||
|
||||
??? We have no idea what the alignment of VALUE is, so
|
||||
we have to use a guess. */
|
||||
part
|
||||
= extract_fixed_bit_field
|
||||
(word_mode, value, 0, thissize,
|
||||
total_bits - bitsize + bitsdone, NULL_RTX, 1,
|
||||
GET_MODE (value) == VOIDmode
|
||||
? UNITS_PER_WORD
|
||||
: (GET_MODE (value) == BLKmode
|
||||
? 1
|
||||
: GET_MODE_ALIGNMENT (GET_MODE (value)) / BITS_PER_UNIT));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fetch successively more significant portions. */
|
||||
if (GET_CODE (value) == CONST_INT)
|
||||
part = GEN_INT (((HOST_WIDE_UINT) (INTVAL (value))
|
||||
|
|
@ -889,7 +685,6 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
|
|||
: (GET_MODE (value) == BLKmode
|
||||
? 1
|
||||
: GET_MODE_ALIGNMENT (GET_MODE (value)) / BITS_PER_UNIT));
|
||||
}
|
||||
|
||||
/* If OP0 is a register, then handle OFFSET here.
|
||||
|
||||
|
|
@ -959,27 +754,8 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
register rtx op0 = str_rtx;
|
||||
rtx spec_target = target;
|
||||
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.
|
||||
We need to know how many bytes are safe to reference after it. */
|
||||
|
|
@ -998,16 +774,6 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
|
||||
inner_size = MIN (inner_size, BITS_PER_WORD);
|
||||
|
||||
if (BYTES_BIG_ENDIAN && (outer_size < inner_size))
|
||||
{
|
||||
bitpos += inner_size - outer_size;
|
||||
if (bitpos > unit)
|
||||
{
|
||||
offset += (bitpos / unit);
|
||||
bitpos %= unit;
|
||||
}
|
||||
}
|
||||
|
||||
op0 = SUBREG_REG (op0);
|
||||
}
|
||||
|
||||
|
|
@ -1029,14 +795,6 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
/* ??? We currently assume TARGET is at least as big as BITSIZE.
|
||||
If that's wrong, the solution is to test for it and set TARGET to 0
|
||||
if needed. */
|
||||
|
||||
/* If OP0 is a register, BITPOS must count within a word.
|
||||
But as we have it, it counts within whatever size OP0 now has.
|
||||
On a bigendian machine, these are not the same, so convert. */
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& GET_CODE (op0) != MEM
|
||||
&& unit > GET_MODE_BITSIZE (GET_MODE (op0)))
|
||||
bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
|
||||
|
||||
/* Extracting a full-word or multi-word value
|
||||
from a structure in a register or aligned memory.
|
||||
|
|
@ -1058,9 +816,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
if the value is in a register, and if mode_for_size is not
|
||||
the same mode as op0. This causes us to get unnecessarily
|
||||
inefficient code from the Thumb port when -mbig-endian. */
|
||||
&& (BYTES_BIG_ENDIAN
|
||||
? bitpos + bitsize == BITS_PER_WORD
|
||||
: bitpos == 0))))
|
||||
&& (bitpos == 0))))
|
||||
{
|
||||
enum machine_mode mode1
|
||||
= mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0);
|
||||
|
|
@ -1112,13 +868,9 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
/* If I is 0, use the low-order word in both field and target;
|
||||
if I is 1, use the next to lowest word; and so on. */
|
||||
/* Word number in TARGET to use. */
|
||||
int wordnum = (WORDS_BIG_ENDIAN
|
||||
? GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD - i - 1
|
||||
: i);
|
||||
int wordnum = i;
|
||||
/* Offset from start of field in OP0. */
|
||||
int bit_offset = (WORDS_BIG_ENDIAN
|
||||
? MAX (0, bitsize - (i + 1) * BITS_PER_WORD)
|
||||
: i * BITS_PER_WORD);
|
||||
int bit_offset = i * BITS_PER_WORD;
|
||||
rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
|
||||
rtx result_part
|
||||
= extract_bit_field (op0, MIN (BITS_PER_WORD,
|
||||
|
|
@ -1145,7 +897,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
total_words = GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD;
|
||||
for (i = nwords; i < total_words; i++)
|
||||
{
|
||||
int wordnum = WORDS_BIG_ENDIAN ? total_words - i - 1 : i;
|
||||
int wordnum = i;
|
||||
rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
|
||||
emit_move_insn (target_part, const0_rtx);
|
||||
}
|
||||
|
|
@ -1194,279 +946,12 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|
|||
machine with word length more 32 bits. */
|
||||
enum machine_mode itmode = int_mode_for_mode (tmode);
|
||||
|
||||
#ifdef HAVE_extzv
|
||||
if (HAVE_extzv
|
||||
&& (extzv_bitsize >= bitsize)
|
||||
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
|
||||
&& (bitsize + bitpos > extzv_bitsize)))
|
||||
{
|
||||
int xbitpos = bitpos, xoffset = offset;
|
||||
rtx bitsize_rtx, bitpos_rtx;
|
||||
rtx last = get_last_insn ();
|
||||
rtx xop0 = op0;
|
||||
rtx xtarget = target;
|
||||
rtx xspec_target = spec_target;
|
||||
rtx xspec_target_subreg = spec_target_subreg;
|
||||
rtx pat;
|
||||
enum machine_mode maxmode;
|
||||
|
||||
maxmode = insn_operand_mode[(int) CODE_FOR_extzv][0];
|
||||
if (maxmode == VOIDmode)
|
||||
maxmode = word_mode;
|
||||
|
||||
if (GET_CODE (xop0) == MEM)
|
||||
{
|
||||
int save_volatile_ok = volatile_ok;
|
||||
volatile_ok = 1;
|
||||
|
||||
/* Is the memory operand acceptable? */
|
||||
if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1])
|
||||
(xop0, GET_MODE (xop0))))
|
||||
{
|
||||
/* No, load into a reg and extract from there. */
|
||||
enum machine_mode bestmode;
|
||||
|
||||
/* Get the mode to use for inserting into this field. If
|
||||
OP0 is BLKmode, get the smallest mode consistent with the
|
||||
alignment. If OP0 is a non-BLKmode object that is no
|
||||
wider than MAXMODE, use its mode. Otherwise, use the
|
||||
smallest mode containing the field. */
|
||||
|
||||
if (GET_MODE (xop0) == BLKmode
|
||||
|| (GET_MODE_SIZE (GET_MODE (op0))
|
||||
> GET_MODE_SIZE (maxmode)))
|
||||
bestmode = get_best_mode (bitsize, bitnum,
|
||||
align * BITS_PER_UNIT, maxmode,
|
||||
MEM_VOLATILE_P (xop0));
|
||||
else
|
||||
bestmode = GET_MODE (xop0);
|
||||
|
||||
if (bestmode == VOIDmode
|
||||
|| (SLOW_UNALIGNED_ACCESS && GET_MODE_SIZE (bestmode) > align))
|
||||
goto extzv_loses;
|
||||
|
||||
/* Compute offset as multiple of this unit,
|
||||
counting in bytes. */
|
||||
unit = GET_MODE_BITSIZE (bestmode);
|
||||
xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
|
||||
xbitpos = bitnum % unit;
|
||||
xop0 = change_address (xop0, bestmode,
|
||||
plus_constant (XEXP (xop0, 0),
|
||||
xoffset));
|
||||
/* Fetch it to a register in that size. */
|
||||
xop0 = force_reg (bestmode, xop0);
|
||||
|
||||
/* XBITPOS counts within UNIT, which is what is expected. */
|
||||
}
|
||||
else
|
||||
/* Get ref to first byte containing part of the field. */
|
||||
xop0 = change_address (xop0, byte_mode,
|
||||
plus_constant (XEXP (xop0, 0), xoffset));
|
||||
|
||||
volatile_ok = save_volatile_ok;
|
||||
}
|
||||
|
||||
/* If op0 is a register, we need it in MAXMODE (which is usually
|
||||
SImode). to make it acceptable to the format of extzv. */
|
||||
if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
|
||||
goto extzv_loses;
|
||||
if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
|
||||
xop0 = gen_rtx_SUBREG (maxmode, xop0, 0);
|
||||
|
||||
/* On big-endian machines, we count bits from the most significant.
|
||||
If the bit field insn does not, we must invert. */
|
||||
if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
|
||||
xbitpos = unit - bitsize - xbitpos;
|
||||
|
||||
/* Now convert from counting within UNIT to counting in MAXMODE. */
|
||||
if (BITS_BIG_ENDIAN && GET_CODE (xop0) != MEM)
|
||||
xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
|
||||
|
||||
unit = GET_MODE_BITSIZE (maxmode);
|
||||
|
||||
if (xtarget == 0
|
||||
|| (flag_force_mem && GET_CODE (xtarget) == MEM))
|
||||
xtarget = xspec_target = gen_reg_rtx (itmode);
|
||||
|
||||
if (GET_MODE (xtarget) != maxmode)
|
||||
{
|
||||
if (GET_CODE (xtarget) == REG)
|
||||
{
|
||||
int wider = (GET_MODE_SIZE (maxmode)
|
||||
> GET_MODE_SIZE (GET_MODE (xtarget)));
|
||||
xtarget = gen_lowpart (maxmode, xtarget);
|
||||
if (wider)
|
||||
xspec_target_subreg = xtarget;
|
||||
}
|
||||
else
|
||||
xtarget = gen_reg_rtx (maxmode);
|
||||
}
|
||||
|
||||
/* If this machine's extzv insists on a register target,
|
||||
make sure we have one. */
|
||||
if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
|
||||
(xtarget, maxmode)))
|
||||
xtarget = gen_reg_rtx (maxmode);
|
||||
|
||||
bitsize_rtx = GEN_INT (bitsize);
|
||||
bitpos_rtx = GEN_INT (xbitpos);
|
||||
|
||||
pat = gen_extzv (protect_from_queue (xtarget, 1),
|
||||
xop0, bitsize_rtx, bitpos_rtx);
|
||||
if (pat)
|
||||
{
|
||||
emit_insn (pat);
|
||||
target = xtarget;
|
||||
spec_target = xspec_target;
|
||||
spec_target_subreg = xspec_target_subreg;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_insns_since (last);
|
||||
target = extract_fixed_bit_field (itmode, op0, offset, bitsize,
|
||||
bitpos, target, 1, align);
|
||||
}
|
||||
}
|
||||
else
|
||||
extzv_loses:
|
||||
#endif
|
||||
target = extract_fixed_bit_field (itmode, op0, offset, bitsize, bitpos,
|
||||
target, 1, align);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Here we can assume that the desired field is and integer. */
|
||||
#ifdef HAVE_extv
|
||||
if (HAVE_extv
|
||||
&& (extv_bitsize >= bitsize)
|
||||
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
|
||||
&& (bitsize + bitpos > extv_bitsize)))
|
||||
{
|
||||
int xbitpos = bitpos, xoffset = offset;
|
||||
rtx bitsize_rtx, bitpos_rtx;
|
||||
rtx last = get_last_insn ();
|
||||
rtx xop0 = op0, xtarget = target;
|
||||
rtx xspec_target = spec_target;
|
||||
rtx xspec_target_subreg = spec_target_subreg;
|
||||
rtx pat;
|
||||
enum machine_mode maxmode;
|
||||
|
||||
maxmode = insn_operand_mode[(int) CODE_FOR_extv][0];
|
||||
if (maxmode == VOIDmode)
|
||||
maxmode = word_mode;
|
||||
|
||||
if (GET_CODE (xop0) == MEM)
|
||||
{
|
||||
/* Is the memory operand acceptable? */
|
||||
if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1])
|
||||
(xop0, GET_MODE (xop0))))
|
||||
{
|
||||
/* No, load into a reg and extract from there. */
|
||||
enum machine_mode bestmode;
|
||||
|
||||
/* Get the mode to use for inserting into this field. If
|
||||
OP0 is BLKmode, get the smallest mode consistent with the
|
||||
alignment. If OP0 is a non-BLKmode object that is no
|
||||
wider than MAXMODE, use its mode. Otherwise, use the
|
||||
smallest mode containing the field. */
|
||||
|
||||
if (GET_MODE (xop0) == BLKmode
|
||||
|| (GET_MODE_SIZE (GET_MODE (op0))
|
||||
> GET_MODE_SIZE (maxmode)))
|
||||
bestmode = get_best_mode (bitsize, bitnum,
|
||||
align * BITS_PER_UNIT, maxmode,
|
||||
MEM_VOLATILE_P (xop0));
|
||||
else
|
||||
bestmode = GET_MODE (xop0);
|
||||
|
||||
if (bestmode == VOIDmode
|
||||
|| (SLOW_UNALIGNED_ACCESS && GET_MODE_SIZE (bestmode) > align))
|
||||
goto extv_loses;
|
||||
|
||||
/* Compute offset as multiple of this unit,
|
||||
counting in bytes. */
|
||||
unit = GET_MODE_BITSIZE (bestmode);
|
||||
xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
|
||||
xbitpos = bitnum % unit;
|
||||
xop0 = change_address (xop0, bestmode,
|
||||
plus_constant (XEXP (xop0, 0),
|
||||
xoffset));
|
||||
/* Fetch it to a register in that size. */
|
||||
xop0 = force_reg (bestmode, xop0);
|
||||
|
||||
/* XBITPOS counts within UNIT, which is what is expected. */
|
||||
}
|
||||
else
|
||||
/* Get ref to first byte containing part of the field. */
|
||||
xop0 = change_address (xop0, byte_mode,
|
||||
plus_constant (XEXP (xop0, 0), xoffset));
|
||||
}
|
||||
|
||||
/* If op0 is a register, we need it in MAXMODE (which is usually
|
||||
SImode) to make it acceptable to the format of extv. */
|
||||
if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
|
||||
goto extv_loses;
|
||||
if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
|
||||
xop0 = gen_rtx_SUBREG (maxmode, xop0, 0);
|
||||
|
||||
/* On big-endian machines, we count bits from the most significant.
|
||||
If the bit field insn does not, we must invert. */
|
||||
if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
|
||||
xbitpos = unit - bitsize - xbitpos;
|
||||
|
||||
/* XBITPOS counts within a size of UNIT.
|
||||
Adjust to count within a size of MAXMODE. */
|
||||
if (BITS_BIG_ENDIAN && GET_CODE (xop0) != MEM)
|
||||
xbitpos += (GET_MODE_BITSIZE (maxmode) - unit);
|
||||
|
||||
unit = GET_MODE_BITSIZE (maxmode);
|
||||
|
||||
if (xtarget == 0
|
||||
|| (flag_force_mem && GET_CODE (xtarget) == MEM))
|
||||
xtarget = xspec_target = gen_reg_rtx (tmode);
|
||||
|
||||
if (GET_MODE (xtarget) != maxmode)
|
||||
{
|
||||
if (GET_CODE (xtarget) == REG)
|
||||
{
|
||||
int wider = (GET_MODE_SIZE (maxmode)
|
||||
> GET_MODE_SIZE (GET_MODE (xtarget)));
|
||||
xtarget = gen_lowpart (maxmode, xtarget);
|
||||
if (wider)
|
||||
xspec_target_subreg = xtarget;
|
||||
}
|
||||
else
|
||||
xtarget = gen_reg_rtx (maxmode);
|
||||
}
|
||||
|
||||
/* If this machine's extv insists on a register target,
|
||||
make sure we have one. */
|
||||
if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
|
||||
(xtarget, maxmode)))
|
||||
xtarget = gen_reg_rtx (maxmode);
|
||||
|
||||
bitsize_rtx = GEN_INT (bitsize);
|
||||
bitpos_rtx = GEN_INT (xbitpos);
|
||||
|
||||
pat = gen_extv (protect_from_queue (xtarget, 1),
|
||||
xop0, bitsize_rtx, bitpos_rtx);
|
||||
if (pat)
|
||||
{
|
||||
emit_insn (pat);
|
||||
target = xtarget;
|
||||
spec_target = xspec_target;
|
||||
spec_target_subreg = xspec_target_subreg;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_insns_since (last);
|
||||
target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
|
||||
bitpos, target, 0, align);
|
||||
}
|
||||
}
|
||||
else
|
||||
extv_loses:
|
||||
#endif
|
||||
target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
|
||||
target, 0, align);
|
||||
}
|
||||
|
|
@ -1570,14 +1055,6 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
|
|||
|
||||
mode = GET_MODE (op0);
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
/* BITPOS is the distance between our msb and that of OP0.
|
||||
Convert it to the distance from the lsb. */
|
||||
|
||||
bitpos = total_bits - bitsize - bitpos;
|
||||
}
|
||||
|
||||
/* Now BITPOS is always the distance between the field's lsb and that of OP0.
|
||||
We have reduced the big-endian case to the little-endian case. */
|
||||
|
||||
|
|
@ -1796,18 +1273,9 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
|
|||
bitsdone += thissize;
|
||||
|
||||
/* Shift this part into place for the result. */
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
if (bitsize != bitsdone)
|
||||
part = expand_shift (LSHIFT_EXPR, word_mode, part,
|
||||
build_int_2 (bitsize - bitsdone, 0), 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bitsdone != thissize)
|
||||
part = expand_shift (LSHIFT_EXPR, word_mode, part,
|
||||
build_int_2 (bitsdone - thissize, 0), 0, 1);
|
||||
}
|
||||
|
||||
if (first)
|
||||
result = part;
|
||||
|
|
|
|||
143
gcc/expr.c
143
gcc/expr.c
|
|
@ -698,31 +698,17 @@ convert_move (to, from, unsignedp)
|
|||
fill_value = const0_rtx;
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_slt
|
||||
if (HAVE_slt
|
||||
&& insn_operand_mode[(int) CODE_FOR_slt][0] == word_mode
|
||||
&& STORE_FLAG_VALUE == -1)
|
||||
{
|
||||
emit_cmp_insn (lowfrom, const0_rtx, NE, NULL_RTX,
|
||||
lowpart_mode, 0, 0);
|
||||
fill_value = gen_reg_rtx (word_mode);
|
||||
emit_insn (gen_slt (fill_value));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fill_value
|
||||
= expand_shift (RSHIFT_EXPR, lowpart_mode, lowfrom,
|
||||
size_int (GET_MODE_BITSIZE (lowpart_mode) - 1),
|
||||
NULL_RTX, 0);
|
||||
fill_value = convert_to_mode (word_mode, fill_value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the remaining words. */
|
||||
for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
|
||||
{
|
||||
int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
|
||||
int index = i;
|
||||
rtx subword = operand_subword (to, index, 1, to_mode);
|
||||
|
||||
if (subword == 0)
|
||||
|
|
@ -827,78 +813,36 @@ convert_move (to, from, unsignedp)
|
|||
|
||||
if (from_mode == DImode && to_mode == SImode)
|
||||
{
|
||||
#ifdef HAVE_truncdisi2
|
||||
if (HAVE_truncdisi2)
|
||||
{
|
||||
emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
convert_move (to, force_reg (from_mode, from), unsignedp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_mode == DImode && to_mode == HImode)
|
||||
{
|
||||
#ifdef HAVE_truncdihi2
|
||||
if (HAVE_truncdihi2)
|
||||
{
|
||||
emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
convert_move (to, force_reg (from_mode, from), unsignedp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_mode == DImode && to_mode == QImode)
|
||||
{
|
||||
#ifdef HAVE_truncdiqi2
|
||||
if (HAVE_truncdiqi2)
|
||||
{
|
||||
emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
convert_move (to, force_reg (from_mode, from), unsignedp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_mode == SImode && to_mode == HImode)
|
||||
{
|
||||
#ifdef HAVE_truncsihi2
|
||||
if (HAVE_truncsihi2)
|
||||
{
|
||||
emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
convert_move (to, force_reg (from_mode, from), unsignedp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_mode == SImode && to_mode == QImode)
|
||||
{
|
||||
#ifdef HAVE_truncsiqi2
|
||||
if (HAVE_truncsiqi2)
|
||||
{
|
||||
emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
convert_move (to, force_reg (from_mode, from), unsignedp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_mode == HImode && to_mode == QImode)
|
||||
{
|
||||
#ifdef HAVE_trunchiqi2
|
||||
if (HAVE_trunchiqi2)
|
||||
{
|
||||
emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
convert_move (to, force_reg (from_mode, from), unsignedp);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1497,25 +1441,6 @@ move_block_from_reg (regno, x, nregs, size)
|
|||
gen_rtx_REG (mode, regno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
|
||||
to the left before storing to memory. Note that the previous test
|
||||
doesn't handle all cases (e.g. SIZE == 3). */
|
||||
if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN)
|
||||
{
|
||||
rtx tem = operand_subword (x, 0, 1, BLKmode);
|
||||
rtx shift;
|
||||
|
||||
if (tem == 0)
|
||||
abort ();
|
||||
|
||||
shift = expand_shift (LSHIFT_EXPR, word_mode,
|
||||
gen_rtx_REG (word_mode, regno),
|
||||
build_int_2 ((UNITS_PER_WORD - size)
|
||||
* BITS_PER_UNIT, 0), NULL_RTX, 0);
|
||||
emit_move_insn (tem, shift);
|
||||
return;
|
||||
}
|
||||
|
||||
/* See if the machine can do this with a store multiple insn. */
|
||||
#ifdef HAVE_store_multiple
|
||||
|
|
@ -1620,12 +1545,6 @@ emit_group_load (dst, orig_src, ssize, align)
|
|||
bytepos*BITS_PER_UNIT, 1, NULL_RTX,
|
||||
mode, mode, align, ssize);
|
||||
}
|
||||
|
||||
if (BYTES_BIG_ENDIAN && shift)
|
||||
{
|
||||
expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
|
||||
tmps[i], 0, OPTAB_WIDEN);
|
||||
}
|
||||
}
|
||||
emit_queue();
|
||||
|
||||
|
|
@ -1714,12 +1633,6 @@ emit_group_store (orig_dst, src, ssize, align)
|
|||
/* Handle trailing fragments that run over the size of the struct. */
|
||||
if (ssize >= 0 && bytepos + bytelen > ssize)
|
||||
{
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
|
||||
expand_binop (mode, ashr_optab, tmps[i], GEN_INT (shift),
|
||||
tmps[i], 0, OPTAB_WIDEN);
|
||||
}
|
||||
bytelen = ssize - bytepos;
|
||||
}
|
||||
|
||||
|
|
@ -1782,14 +1695,6 @@ copy_blkmode_from_reg(tgtblk,srcreg,type)
|
|||
srcreg = convert_to_mode (word_mode, srcreg,
|
||||
TREE_UNSIGNED (type));
|
||||
|
||||
/* Structures whose size is not a multiple of a word are aligned
|
||||
to the least significant byte (to the right). On a BYTES_BIG_ENDIAN
|
||||
machine, this means we must skip the empty high order bytes when
|
||||
calculating the bit offset. */
|
||||
if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
|
||||
big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
|
||||
* BITS_PER_UNIT));
|
||||
|
||||
/* Copy the structure BITSIZE bites at a time.
|
||||
|
||||
We could probably emit more efficient code for machines
|
||||
|
|
@ -3687,10 +3592,6 @@ store_constructor (exp, target, cleared)
|
|||
type = type_for_size (BITS_PER_WORD, TREE_UNSIGNED (type));
|
||||
value = convert (type, value);
|
||||
}
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
value
|
||||
= fold (build (LSHIFT_EXPR, type, value,
|
||||
build_int_2 (BITS_PER_WORD - bitsize, 0)));
|
||||
bitsize = BITS_PER_WORD;
|
||||
mode = word_mode;
|
||||
}
|
||||
|
|
@ -3956,9 +3857,6 @@ store_constructor (exp, target, cleared)
|
|||
{
|
||||
if (bit_buffer[ibit])
|
||||
{
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
word |= (1 << (set_word_size - 1 - bit_pos));
|
||||
else
|
||||
word |= 1 << bit_pos;
|
||||
}
|
||||
bit_pos++; ibit++;
|
||||
|
|
@ -4175,18 +4073,6 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
|
|||
{
|
||||
rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
|
||||
|
||||
/* If BITSIZE is narrower than the size of the type of EXP
|
||||
we will be narrowing TEMP. Normally, what's wanted are the
|
||||
low-order bits. However, if EXP's type is a record and this is
|
||||
big-endian machine, we want the upper BITSIZE bits. */
|
||||
if (BYTES_BIG_ENDIAN && GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
|
||||
&& bitsize < GET_MODE_BITSIZE (GET_MODE (temp))
|
||||
&& TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
|
||||
temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
|
||||
size_int (GET_MODE_BITSIZE (GET_MODE (temp))
|
||||
- bitsize),
|
||||
temp, 1);
|
||||
|
||||
/* Unless MODE is VOIDmode or BLKmode, convert TEMP to
|
||||
MODE. */
|
||||
if (mode != VOIDmode && mode != BLKmode
|
||||
|
|
@ -6078,17 +5964,6 @@ expand_expr (exp, target, tmode, modifier)
|
|||
alignment,
|
||||
int_size_in_bytes (TREE_TYPE (tem)));
|
||||
|
||||
/* If the result is a record type and BITSIZE is narrower than
|
||||
the mode of OP0, an integral mode, and this is a big endian
|
||||
machine, we must put the field into the high-order bits. */
|
||||
if (TREE_CODE (type) == RECORD_TYPE && BYTES_BIG_ENDIAN
|
||||
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
|
||||
&& bitsize < GET_MODE_BITSIZE (GET_MODE (op0)))
|
||||
op0 = expand_shift (LSHIFT_EXPR, GET_MODE (op0), op0,
|
||||
size_int (GET_MODE_BITSIZE (GET_MODE (op0))
|
||||
- bitsize),
|
||||
op0, 1);
|
||||
|
||||
if (mode == BLKmode)
|
||||
{
|
||||
rtx new = assign_stack_temp (ext_mode,
|
||||
|
|
@ -10423,16 +10298,8 @@ do_jump_by_parts_greater (exp, swap, if_false_label, if_true_label)
|
|||
rtx comp;
|
||||
rtx op0_word, op1_word;
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
{
|
||||
op0_word = operand_subword_force (op0, i, mode);
|
||||
op1_word = operand_subword_force (op1, i, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
|
||||
op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
|
||||
}
|
||||
|
||||
/* All but high-order word must be compared as unsigned. */
|
||||
comp = compare_from_rtx (op0_word, op1_word,
|
||||
|
|
@ -10486,16 +10353,8 @@ do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true
|
|||
rtx comp;
|
||||
rtx op0_word, op1_word;
|
||||
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
{
|
||||
op0_word = operand_subword_force (op0, i, mode);
|
||||
op1_word = operand_subword_force (op1, i, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
|
||||
op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
|
||||
}
|
||||
|
||||
/* All but high-order word must be compared as unsigned. */
|
||||
comp = compare_from_rtx (op0_word, op1_word,
|
||||
|
|
|
|||
10
gcc/expr.h
10
gcc/expr.h
|
|
@ -209,13 +209,7 @@ enum direction {none, upward, downward}; /* Value has this type. */
|
|||
|
||||
#ifndef FUNCTION_ARG_PADDING
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(! BYTES_BIG_ENDIAN \
|
||||
? upward \
|
||||
: (((MODE) == BLKmode \
|
||||
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
|
||||
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
|
||||
: GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
|
||||
? downward : upward))
|
||||
(upward)
|
||||
#endif
|
||||
|
||||
/* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let
|
||||
|
|
@ -257,7 +251,7 @@ enum direction {none, upward, downward}; /* Value has this type. */
|
|||
&& 0 == (int_size_in_bytes (TYPE) \
|
||||
% (PARM_BOUNDARY / BITS_PER_UNIT))) \
|
||||
&& (FUNCTION_ARG_PADDING (MODE, TYPE) \
|
||||
== (BYTES_BIG_ENDIAN ? upward : downward)))))
|
||||
== (downward)))))
|
||||
#endif
|
||||
|
||||
/* Nonzero if type TYPE should be returned in memory.
|
||||
|
|
|
|||
37
gcc/final.c
37
gcc/final.c
|
|
@ -2174,9 +2174,6 @@ alter_subreg (x)
|
|||
else if (GET_CODE (y) == MEM)
|
||||
{
|
||||
register int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (y))));
|
||||
PUT_CODE (x, MEM);
|
||||
MEM_COPY_ATTRIBUTES (x, y);
|
||||
MEM_ALIAS_SET (x) = MEM_ALIAS_SET (y);
|
||||
|
|
@ -2849,16 +2846,9 @@ split_double (value, first, second)
|
|||
|
||||
low = GEN_INT ((INTVAL (value) << rshift) >> rshift);
|
||||
high = GEN_INT ((INTVAL (value) << lshift) >> rshift);
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
{
|
||||
*first = high;
|
||||
*second = low;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
*first = low;
|
||||
*second = high;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2866,30 +2856,15 @@ split_double (value, first, second)
|
|||
is that we regard the value as signed.
|
||||
So sign-extend it. */
|
||||
rtx high = (INTVAL (value) < 0 ? constm1_rtx : const0_rtx);
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
{
|
||||
*first = high;
|
||||
*second = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
*first = value;
|
||||
*second = high;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GET_CODE (value) != CONST_DOUBLE)
|
||||
{
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
{
|
||||
*first = const0_rtx;
|
||||
*second = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
*first = value;
|
||||
*second = const0_rtx;
|
||||
}
|
||||
}
|
||||
else if (GET_MODE (value) == VOIDmode
|
||||
/* This is the old way we did CONST_DOUBLE integers. */
|
||||
|
|
@ -2897,16 +2872,8 @@ split_double (value, first, second)
|
|||
{
|
||||
/* In an integer, the words are defined as most and least significant.
|
||||
So order them by the target's convention. */
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
{
|
||||
*first = GEN_INT (CONST_DOUBLE_HIGH (value));
|
||||
*second = GEN_INT (CONST_DOUBLE_LOW (value));
|
||||
}
|
||||
else
|
||||
{
|
||||
*first = GEN_INT (CONST_DOUBLE_LOW (value));
|
||||
*second = GEN_INT (CONST_DOUBLE_HIGH (value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2723,9 +2723,6 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
lbitpos = lnbitsize - lbitsize - lbitpos;
|
||||
|
||||
/* Make the mask to be used against the extracted field. */
|
||||
mask = build_int_2 (~0, ~0);
|
||||
TREE_TYPE (mask) = unsigned_type;
|
||||
|
|
@ -4082,12 +4079,6 @@ fold_truthop (code, truth_type, lhs, rhs)
|
|||
type = type_for_size (lnbitsize, 1);
|
||||
xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
|
||||
xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
|
||||
}
|
||||
|
||||
ll_mask = const_binop (LSHIFT_EXPR, convert (type, ll_mask),
|
||||
size_int (xll_bitpos), 0);
|
||||
rl_mask = const_binop (LSHIFT_EXPR, convert (type, rl_mask),
|
||||
|
|
@ -4154,12 +4145,6 @@ fold_truthop (code, truth_type, lhs, rhs)
|
|||
rnbitpos = first_bit & ~ (rnbitsize - 1);
|
||||
xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
|
||||
xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
|
||||
}
|
||||
|
||||
lr_mask = const_binop (LSHIFT_EXPR, convert (type, lr_mask),
|
||||
size_int (xlr_bitpos), 0);
|
||||
rr_mask = const_binop (LSHIFT_EXPR, convert (type, rr_mask),
|
||||
|
|
|
|||
160
gcc/function.c
160
gcc/function.c
|
|
@ -736,11 +736,6 @@ assign_stack_local (mode, size, align)
|
|||
frame_offset = CEIL_ROUND (frame_offset, alignment);
|
||||
#endif
|
||||
|
||||
/* On a big-endian machine, if we are allocating more space than we will use,
|
||||
use the least significant bytes of those that are allocated. */
|
||||
if (BYTES_BIG_ENDIAN && mode != BLKmode)
|
||||
bigend_correction = size - GET_MODE_SIZE (mode);
|
||||
|
||||
#ifdef FRAME_GROWS_DOWNWARD
|
||||
frame_offset -= size;
|
||||
#endif
|
||||
|
|
@ -807,11 +802,6 @@ assign_outer_stack_local (mode, size, align, function)
|
|||
function->frame_offset = CEIL_ROUND (function->frame_offset, alignment);
|
||||
#endif
|
||||
|
||||
/* On a big-endian machine, if we are allocating more space than we will use,
|
||||
use the least significant bytes of those that are allocated. */
|
||||
if (BYTES_BIG_ENDIAN && mode != BLKmode)
|
||||
bigend_correction = size - GET_MODE_SIZE (mode);
|
||||
|
||||
#ifdef FRAME_GROWS_DOWNWARD
|
||||
function->frame_offset -= size;
|
||||
#endif
|
||||
|
|
@ -2001,22 +1991,6 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
|
|||
enum machine_mode is_mode = GET_MODE (tem);
|
||||
HOST_WIDE_INT pos = INTVAL (XEXP (x, 2));
|
||||
|
||||
#ifdef HAVE_extzv
|
||||
if (GET_CODE (x) == ZERO_EXTRACT)
|
||||
{
|
||||
wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
|
||||
if (wanted_mode == VOIDmode)
|
||||
wanted_mode = word_mode;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_extv
|
||||
if (GET_CODE (x) == SIGN_EXTRACT)
|
||||
{
|
||||
wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
|
||||
if (wanted_mode == VOIDmode)
|
||||
wanted_mode = word_mode;
|
||||
}
|
||||
#endif
|
||||
/* If we have a narrower mode, we can do something. */
|
||||
if (wanted_mode != VOIDmode
|
||||
&& GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
|
||||
|
|
@ -2025,12 +1999,6 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
|
|||
rtx old_pos = XEXP (x, 2);
|
||||
rtx newmem;
|
||||
|
||||
/* If the bytes and bits are counted differently, we
|
||||
must adjust the offset. */
|
||||
if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
|
||||
offset = (GET_MODE_SIZE (is_mode)
|
||||
- GET_MODE_SIZE (wanted_mode) - offset);
|
||||
|
||||
pos %= GET_MODE_BITSIZE (wanted_mode);
|
||||
|
||||
newmem = gen_rtx_MEM (wanted_mode,
|
||||
|
|
@ -2154,9 +2122,6 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
|
|||
{
|
||||
rtx dest = SET_DEST (x);
|
||||
rtx src = SET_SRC (x);
|
||||
#ifdef HAVE_insv
|
||||
rtx outerdest = dest;
|
||||
#endif
|
||||
|
||||
while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
|
||||
|| GET_CODE (dest) == SIGN_EXTRACT
|
||||
|
|
@ -2175,85 +2140,6 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
|
|||
/* We will need to rerecognize this insn. */
|
||||
INSN_CODE (insn) = -1;
|
||||
|
||||
#ifdef HAVE_insv
|
||||
if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var)
|
||||
{
|
||||
/* Since this case will return, ensure we fixup all the
|
||||
operands here. */
|
||||
fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 1),
|
||||
insn, replacements);
|
||||
fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 2),
|
||||
insn, replacements);
|
||||
fixup_var_refs_1 (var, promoted_mode, &SET_SRC (x),
|
||||
insn, replacements);
|
||||
|
||||
tem = XEXP (outerdest, 0);
|
||||
|
||||
/* Clean up (SUBREG:SI (MEM:mode ...) 0)
|
||||
that may appear inside a ZERO_EXTRACT.
|
||||
This was legitimate when the MEM was a REG. */
|
||||
if (GET_CODE (tem) == SUBREG
|
||||
&& SUBREG_REG (tem) == var)
|
||||
tem = fixup_memory_subreg (tem, insn, 0);
|
||||
else
|
||||
tem = fixup_stack_1 (tem, insn);
|
||||
|
||||
if (GET_CODE (XEXP (outerdest, 1)) == CONST_INT
|
||||
&& GET_CODE (XEXP (outerdest, 2)) == CONST_INT
|
||||
&& ! mode_dependent_address_p (XEXP (tem, 0))
|
||||
&& ! MEM_VOLATILE_P (tem))
|
||||
{
|
||||
enum machine_mode wanted_mode;
|
||||
enum machine_mode is_mode = GET_MODE (tem);
|
||||
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 (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
|
||||
{
|
||||
HOST_WIDE_INT offset = pos / BITS_PER_UNIT;
|
||||
rtx old_pos = XEXP (outerdest, 2);
|
||||
rtx newmem;
|
||||
|
||||
if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
|
||||
offset = (GET_MODE_SIZE (is_mode)
|
||||
- GET_MODE_SIZE (wanted_mode) - offset);
|
||||
|
||||
pos %= GET_MODE_BITSIZE (wanted_mode);
|
||||
|
||||
newmem = gen_rtx_MEM (wanted_mode,
|
||||
plus_constant (XEXP (tem, 0), offset));
|
||||
RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
|
||||
MEM_COPY_ATTRIBUTES (newmem, tem);
|
||||
|
||||
/* Make the change and see if the insn remains valid. */
|
||||
INSN_CODE (insn) = -1;
|
||||
XEXP (outerdest, 0) = newmem;
|
||||
XEXP (outerdest, 2) = GEN_INT (pos);
|
||||
|
||||
if (recog_memoized (insn) >= 0)
|
||||
return;
|
||||
|
||||
/* Otherwise, restore old position. XEXP (x, 0) will be
|
||||
restored later. */
|
||||
XEXP (outerdest, 2) = old_pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get here, the bit-field store doesn't allow memory
|
||||
or isn't located at a constant position. Load the value into
|
||||
a register, do the store, and put it back into memory. */
|
||||
|
||||
tem1 = gen_reg_rtx (GET_MODE (tem));
|
||||
emit_insn_before (gen_move_insn (tem1, tem), insn);
|
||||
emit_insn_after (gen_move_insn (tem, tem1), insn);
|
||||
XEXP (outerdest, 0) = tem1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* STRICT_LOW_PART is a no-op on memory references
|
||||
and it can cause combinations to be unrecognizable,
|
||||
|
|
@ -2434,9 +2320,6 @@ fixup_memory_subreg (x, insn, uncritical)
|
|||
&& ! uncritical)
|
||||
abort ();
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset += (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
|
||||
addr = plus_constant (addr, offset);
|
||||
if (!flag_force_addr && memory_address_p (mode, addr))
|
||||
/* Shortcut if no insns need be emitted. */
|
||||
|
|
@ -2618,21 +2501,11 @@ optimize_bit_field (body, insn, equiv_mem)
|
|||
HOST_WIDE_INT offset = INTVAL (XEXP (bitfield, 2));
|
||||
rtx insns;
|
||||
|
||||
/* Adjust OFFSET to count bits from low-address byte. */
|
||||
if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
|
||||
offset = (GET_MODE_BITSIZE (GET_MODE (XEXP (bitfield, 0)))
|
||||
- offset - INTVAL (XEXP (bitfield, 1)));
|
||||
|
||||
/* Adjust OFFSET to count bytes from low-address byte. */
|
||||
offset /= BITS_PER_UNIT;
|
||||
if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
|
||||
{
|
||||
offset += SUBREG_WORD (XEXP (bitfield, 0)) * UNITS_PER_WORD;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset -= (MIN (UNITS_PER_WORD,
|
||||
GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
|
||||
- MIN (UNITS_PER_WORD,
|
||||
GET_MODE_SIZE (GET_MODE (memref))));
|
||||
}
|
||||
|
||||
start_sequence ();
|
||||
|
|
@ -4241,39 +4114,6 @@ assign_parms (fndecl, second_time)
|
|||
&& nominal_mode != BLKmode && nominal_mode != passed_mode)
|
||||
stack_parm = 0;
|
||||
|
||||
#if 0
|
||||
/* Now adjust STACK_PARM to the mode and precise location
|
||||
where this parameter should live during execution,
|
||||
if we discover that it must live in the stack during execution.
|
||||
To make debuggers happier on big-endian machines, we store
|
||||
the value in the last bytes of the space available. */
|
||||
|
||||
if (nominal_mode != BLKmode && nominal_mode != passed_mode
|
||||
&& stack_parm != 0)
|
||||
{
|
||||
rtx offset_rtx;
|
||||
|
||||
if (BYTES_BIG_ENDIAN
|
||||
&& GET_MODE_SIZE (nominal_mode) < UNITS_PER_WORD)
|
||||
stack_offset.constant += (GET_MODE_SIZE (passed_mode)
|
||||
- GET_MODE_SIZE (nominal_mode));
|
||||
|
||||
offset_rtx = ARGS_SIZE_RTX (stack_offset);
|
||||
if (offset_rtx == const0_rtx)
|
||||
stack_parm = gen_rtx_MEM (nominal_mode, internal_arg_pointer);
|
||||
else
|
||||
stack_parm = gen_rtx_MEM (nominal_mode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
internal_arg_pointer,
|
||||
offset_rtx));
|
||||
|
||||
/* If this is a memory ref that contains aggregate components,
|
||||
mark it as such for cse and loop optimize. */
|
||||
MEM_SET_IN_STRUCT_P (stack_parm, aggregate);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
/* ENTRY_PARM is an RTX for the parameter as it arrives,
|
||||
in the mode in which it arrives.
|
||||
STACK_PARM is an RTX for a stack slot where the parameter can live
|
||||
|
|
|
|||
|
|
@ -2334,9 +2334,7 @@ delete_noop_moves (f)
|
|||
delete_insn (insn);
|
||||
}
|
||||
/* Also delete insns to store bit fields if they are no-ops. */
|
||||
/* Not worth the hair to detect this in the big-endian case. */
|
||||
else if (! BYTES_BIG_ENDIAN
|
||||
&& GET_CODE (body) == SET
|
||||
else if (GET_CODE (body) == SET
|
||||
&& GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
|
||||
&& XEXP (SET_DEST (body), 2) == const0_rtx
|
||||
&& XEXP (SET_DEST (body), 0) == SET_SRC (body)
|
||||
|
|
|
|||
10
gcc/optabs.c
10
gcc/optabs.c
|
|
@ -676,7 +676,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
|
|||
WORDS_BIG_ENDIAN. */
|
||||
|
||||
left_shift = binoptab == ashl_optab;
|
||||
outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
|
||||
outof_word = left_shift ^ 1;
|
||||
|
||||
outof_target = operand_subword (target, outof_word, 1, mode);
|
||||
into_target = operand_subword (target, 1 - outof_word, 1, mode);
|
||||
|
|
@ -794,7 +794,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
|
|||
WORDS_BIG_ENDIAN. */
|
||||
|
||||
left_shift = (binoptab == rotl_optab);
|
||||
outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
|
||||
outof_word = left_shift ^ 1;
|
||||
|
||||
outof_target = operand_subword (target, outof_word, 1, mode);
|
||||
into_target = operand_subword (target, 1 - outof_word, 1, mode);
|
||||
|
|
@ -924,7 +924,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
|
|||
/* Do the actual arithmetic. */
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
|
||||
int index = i;
|
||||
rtx target_piece = operand_subword (target, index, 1, mode);
|
||||
rtx op0_piece = operand_subword_force (xop0, index, mode);
|
||||
rtx op1_piece = operand_subword_force (xop1, index, mode);
|
||||
|
|
@ -1061,8 +1061,8 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
|
|||
|| (smul_widen_optab->handlers[(int) mode].insn_code
|
||||
!= CODE_FOR_nothing)))
|
||||
{
|
||||
int low = (WORDS_BIG_ENDIAN ? 1 : 0);
|
||||
int high = (WORDS_BIG_ENDIAN ? 0 : 1);
|
||||
int low = 0;
|
||||
int high = 1;
|
||||
rtx op0_high = operand_subword_force (op0, high, mode);
|
||||
rtx op0_low = operand_subword_force (op0, low, mode);
|
||||
rtx op1_high = operand_subword_force (op1, high, mode);
|
||||
|
|
|
|||
31
gcc/recog.c
31
gcc/recog.c
|
|
@ -523,11 +523,6 @@ validate_replace_rtx_1 (loc, from, to, object)
|
|||
enum machine_mode mode = GET_MODE (x);
|
||||
rtx new;
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset += (MIN (UNITS_PER_WORD,
|
||||
GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
|
||||
|
||||
new = gen_rtx_MEM (mode, plus_constant (XEXP (to, 0), offset));
|
||||
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (to);
|
||||
MEM_COPY_ATTRIBUTES (new, to);
|
||||
|
|
@ -553,22 +548,6 @@ validate_replace_rtx_1 (loc, from, to, object)
|
|||
enum machine_mode is_mode = GET_MODE (to);
|
||||
int pos = INTVAL (XEXP (x, 2));
|
||||
|
||||
#ifdef HAVE_extzv
|
||||
if (code == ZERO_EXTRACT)
|
||||
{
|
||||
wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
|
||||
if (wanted_mode == VOIDmode)
|
||||
wanted_mode = word_mode;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_extv
|
||||
if (code == SIGN_EXTRACT)
|
||||
{
|
||||
wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
|
||||
if (wanted_mode == VOIDmode)
|
||||
wanted_mode = word_mode;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we have a narrower mode, we can do something. */
|
||||
if (wanted_mode != VOIDmode
|
||||
|
|
@ -577,12 +556,6 @@ validate_replace_rtx_1 (loc, from, to, object)
|
|||
int offset = pos / BITS_PER_UNIT;
|
||||
rtx newmem;
|
||||
|
||||
/* If the bytes and bits are counted differently, we
|
||||
must adjust the offset. */
|
||||
if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
|
||||
offset = (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode)
|
||||
- offset);
|
||||
|
||||
pos %= GET_MODE_BITSIZE (wanted_mode);
|
||||
|
||||
newmem = gen_rtx_MEM (wanted_mode,
|
||||
|
|
@ -1254,10 +1227,6 @@ indirect_operand (op, mode)
|
|||
register int offset = SUBREG_WORD (op) * UNITS_PER_WORD;
|
||||
rtx inner = SUBREG_REG (op);
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (op)))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (inner))));
|
||||
|
||||
if (mode != VOIDmode && GET_MODE (op) != mode)
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
23
gcc/reload.c
23
gcc/reload.c
|
|
@ -1909,16 +1909,6 @@ operands_match_p (x, y)
|
|||
else
|
||||
j = REGNO (y);
|
||||
|
||||
/* On a WORDS_BIG_ENDIAN machine, point to the last register of a
|
||||
multiple hard register group, so that for example (reg:DI 0) and
|
||||
(reg:SI 1) will be considered the same register. */
|
||||
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
|
||||
&& i < FIRST_PSEUDO_REGISTER)
|
||||
i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
|
||||
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
|
||||
&& j < FIRST_PSEUDO_REGISTER)
|
||||
j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
|
||||
|
||||
return i == j;
|
||||
}
|
||||
/* If two operands must match, because they are really a single
|
||||
|
|
@ -4231,10 +4221,6 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn)
|
|||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
|
||||
{
|
||||
int shift = SUBREG_WORD (x) * BITS_PER_WORD;
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
|
||||
- GET_MODE_BITSIZE (GET_MODE (x))
|
||||
- shift);
|
||||
/* Here we use the knowledge that CONST_INTs have a
|
||||
HOST_WIDE_INT field. */
|
||||
if (shift >= HOST_BITS_PER_WIDE_INT)
|
||||
|
|
@ -5412,15 +5398,6 @@ find_reloads_subreg_address (x, force_replace, opnum, type,
|
|||
{
|
||||
int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
|
||||
offset += MIN (size, UNITS_PER_WORD);
|
||||
size = GET_MODE_SIZE (GET_MODE (x));
|
||||
offset -= MIN (size, UNITS_PER_WORD);
|
||||
}
|
||||
XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
|
||||
PUT_MODE (tem, GET_MODE (x));
|
||||
find_reloads_address (GET_MODE (tem), &tem, XEXP (tem, 0),
|
||||
|
|
|
|||
|
|
@ -2273,12 +2273,6 @@ alter_reg (i, from_reg)
|
|||
/* No known place to spill from => no slot to reuse. */
|
||||
x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size,
|
||||
inherent_size == total_size ? 0 : -1);
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
/* Cancel the big-endian correction done in assign_stack_local.
|
||||
Get the address of the beginning of the slot.
|
||||
This is so we can do a big-endian correction unconditionally
|
||||
below. */
|
||||
adjust = inherent_size - total_size;
|
||||
|
||||
RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
|
||||
}
|
||||
|
|
@ -2307,28 +2301,10 @@ alter_reg (i, from_reg)
|
|||
x = assign_stack_local (mode, total_size,
|
||||
inherent_size == total_size ? 0 : -1);
|
||||
stack_slot = x;
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
/* Cancel the big-endian correction done in assign_stack_local.
|
||||
Get the address of the beginning of the slot.
|
||||
This is so we can do a big-endian correction unconditionally
|
||||
below. */
|
||||
adjust = GET_MODE_SIZE (mode) - total_size;
|
||||
if (adjust)
|
||||
stack_slot = gen_rtx_MEM (mode_for_size (total_size
|
||||
* BITS_PER_UNIT,
|
||||
MODE_INT, 1),
|
||||
plus_constant (XEXP (x, 0), adjust));
|
||||
}
|
||||
spill_stack_slot[from_reg] = stack_slot;
|
||||
spill_stack_slot_width[from_reg] = total_size;
|
||||
}
|
||||
|
||||
/* On a big endian machine, the "address" of the slot
|
||||
is the address of the low part that fits its inherent mode. */
|
||||
if (BYTES_BIG_ENDIAN && inherent_size < total_size)
|
||||
adjust += (total_size - inherent_size);
|
||||
|
||||
/* If we have any adjustment to make, or if the stack slot is the
|
||||
wrong mode, make a new stack slot. */
|
||||
if (adjust != 0 || GET_MODE (x) != GET_MODE (regno_reg_rtx[i]))
|
||||
|
|
@ -2845,11 +2821,6 @@ eliminate_regs (x, mem_mode, insn)
|
|||
int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
offset += (MIN (UNITS_PER_WORD,
|
||||
GET_MODE_SIZE (GET_MODE (new)))
|
||||
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
|
||||
|
||||
PUT_MODE (new, mode);
|
||||
XEXP (new, 0) = plus_constant (XEXP (new, 0), offset);
|
||||
return new;
|
||||
|
|
@ -8541,14 +8512,6 @@ reload_cse_regno_equal_p (regno, val, mode)
|
|||
&& (GET_CODE (val) != CONST_INT
|
||||
|| mode == GET_MODE (x)
|
||||
|| (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x))
|
||||
/* On a big endian machine if the value spans more than
|
||||
one register then this register holds the high part of
|
||||
it and we can't use it.
|
||||
|
||||
??? We should also compare with the high part of the
|
||||
value. */
|
||||
&& !(WORDS_BIG_ENDIAN
|
||||
&& HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1)
|
||||
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
|
||||
GET_MODE_BITSIZE (GET_MODE (x))))))
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -2589,14 +2589,6 @@ expand_return (retval)
|
|||
rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
|
||||
enum machine_mode tmpmode, result_reg_mode;
|
||||
|
||||
/* Structures whose size is not a multiple of a word are aligned
|
||||
to the least significant byte (to the right). On a BYTES_BIG_ENDIAN
|
||||
machine, this means we must skip the empty high order bytes when
|
||||
calculating the bit offset. */
|
||||
if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
|
||||
big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
|
||||
* BITS_PER_UNIT));
|
||||
|
||||
/* Copy the structure BITSIZE bits at a time. */
|
||||
for (bitpos = 0, xbitpos = big_endian_correction;
|
||||
bitpos < bytes * BITS_PER_UNIT;
|
||||
|
|
|
|||
|
|
@ -4991,9 +4991,6 @@ get_set_constructor_bytes (init, buffer, wd_size)
|
|||
{
|
||||
if (bit_buffer[i])
|
||||
{
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
*bytep |= (1 << (set_word_size - 1 - bit_pos));
|
||||
else
|
||||
*bytep |= 1 << bit_pos;
|
||||
}
|
||||
bit_pos++;
|
||||
|
|
|
|||
34
gcc/varasm.c
34
gcc/varasm.c
|
|
@ -4027,39 +4027,7 @@ output_constructor (exp, size)
|
|||
(all part of the same byte). */
|
||||
this_time = MIN (end_offset - next_offset,
|
||||
BITS_PER_UNIT - next_bit);
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
{
|
||||
/* On big-endian machine, take the most significant bits
|
||||
first (of the bits that are significant)
|
||||
and put them into bytes from the most significant end. */
|
||||
shift = end_offset - next_offset - this_time;
|
||||
/* Don't try to take a bunch of bits that cross
|
||||
the word boundary in the INTEGER_CST. */
|
||||
if (shift < HOST_BITS_PER_WIDE_INT
|
||||
&& shift + this_time > HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
this_time -= (HOST_BITS_PER_WIDE_INT - shift);
|
||||
shift = HOST_BITS_PER_WIDE_INT;
|
||||
}
|
||||
|
||||
/* Now get the bits from the appropriate constant word. */
|
||||
if (shift < HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
value = TREE_INT_CST_LOW (val);
|
||||
}
|
||||
else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
value = TREE_INT_CST_HIGH (val);
|
||||
shift -= HOST_BITS_PER_WIDE_INT;
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
byte |= (((value >> shift)
|
||||
& (((HOST_WIDE_INT) 1 << this_time) - 1))
|
||||
<< (BITS_PER_UNIT - this_time - next_bit));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* On little-endian machines,
|
||||
take first the least significant bits of the value
|
||||
and pack them starting at the least significant
|
||||
|
|
@ -4088,7 +4056,7 @@ output_constructor (exp, size)
|
|||
byte |= (((value >> shift)
|
||||
& (((HOST_WIDE_INT) 1 << this_time) - 1))
|
||||
<< next_bit);
|
||||
}
|
||||
|
||||
next_offset += this_time;
|
||||
byte_buffer_in_use = 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user