arm.h (target_fp_name, [...]): Const-ify.

* arm.h (target_fp_name, structure_size_string, arm_cpu_select):
Const-ify.
* arm.c (target_fp_name, structure_size_string): Const-ify.
* arm.md (reload_inhi, reload_outhi): Make the scratch DImode.
* arm.c (arm_reload_in_hi): Handle cases when the input is still
a pseudo, make use of scratch registers for reloading the address
as appropriate.
(arm_reload_outhi): Similarly for when the output is still a pseudo.
* riscix.h (SUBTARGET_SWITCHES): Document.

From-SVN: r26368
This commit is contained in:
Richard Earnshaw 1999-04-12 09:43:37 +00:00 committed by Richard Earnshaw
parent c3c55f8632
commit f9cc092ab4
5 changed files with 264 additions and 33 deletions

View File

@ -1,3 +1,17 @@
Mon Apr 12 09:30:03 1999 Richard Earnshaw (rearnsha@arm.com)
* arm.h (target_fp_name, structure_size_string, arm_cpu_select):
Const-ify.
* arm.c (target_fp_name, structure_size_string): Const-ify.
* arm.md (reload_inhi, reload_outhi): Make the scratch DImode.
* arm.c (arm_reload_in_hi): Handle cases when the input is still
a pseudo, make use of scratch registers for reloading the address
as appropriate.
(arm_reload_outhi): Similarly for when the output is still a pseudo.
* riscix.h (SUBTARGET_SWITCHES): Document.
1999-04-12 Bruce Korb <ddsinc09@ix.netcom.com>
* fixincludes:

View File

@ -84,10 +84,10 @@ enum floating_point_type arm_fpu_arch;
enum prog_mode_type arm_prgmode;
/* Set by the -mfp=... option */
char * target_fp_name = NULL;
const char * target_fp_name = NULL;
/* Used to parse -mstructure_size_boundary command line option. */
char * structure_size_string = NULL;
const char * structure_size_string = NULL;
int arm_structure_size_boundary = 32; /* Used to be 8 */
/* Bit values used to identify processor capabilities. */
@ -3609,22 +3609,95 @@ void
arm_reload_in_hi (operands)
rtx *operands;
{
rtx base = find_replacement (&XEXP (operands[1], 0));
rtx ref = operands[1];
rtx base, scratch;
HOST_WIDE_INT offset = 0;
if (GET_CODE (ref) == SUBREG)
{
offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
if (BYTES_BIG_ENDIAN)
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
- MIN (UNITS_PER_WORD,
GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
ref = SUBREG_REG (ref);
}
if (GET_CODE (ref) == REG)
{
/* We have a pseudo which has been spilt onto the stack; there
are two cases here: the first where there is a simple
stack-slot replacement and a second where the stack-slot is
out of range, or is used as a subreg. */
if (reg_equiv_mem[REGNO (ref)])
{
ref = reg_equiv_mem[REGNO (ref)];
base = find_replacement (&XEXP (ref, 0));
}
else
/* The slot is out of range, or was dressed up in a SUBREG */
base = reg_equiv_address[REGNO (ref)];
}
else
base = find_replacement (&XEXP (ref, 0));
emit_insn (gen_zero_extendqisi2 (operands[2], gen_rtx_MEM (QImode, base)));
/* Handle the case where the address is too complex to be offset by 1. */
if (GET_CODE (base) == MINUS
|| (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
{
rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[0]));
rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
base = base_plus;
}
else if (GET_CODE (base) == PLUS)
{
/* The addend must be CONST_INT, or we would have dealt with it above */
HOST_WIDE_INT hi, lo;
offset += INTVAL (XEXP (base, 1));
base = XEXP (base, 0);
/* Rework the address into a legal sequence of insns */
/* Valid range for lo is -4095 -> 4095 */
lo = (offset >= 0
? (offset & 0xfff)
: -((-offset) & 0xfff));
/* Corner case, if lo is the max offset then we would be out of range
once we have added the additional 1 below, so bump the msb into the
pre-loading insn(s). */
if (lo == 4095)
lo &= 0x7ff;
hi = ((((offset - lo) & (HOST_WIDE_INT) 0xFFFFFFFF)
^ (HOST_WIDE_INT) 0x80000000)
- (HOST_WIDE_INT) 0x80000000);
if (hi + lo != offset)
abort ();
if (hi != 0)
{
rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
/* Get the base address; addsi3 knows how to handle constants
that require more than one insn */
emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
base = base_plus;
offset = lo;
}
}
scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
emit_insn (gen_zero_extendqisi2 (scratch,
gen_rtx_MEM (QImode,
plus_constant (base,
offset))));
emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
gen_rtx_MEM (QImode,
plus_constant (base, 1))));
plus_constant (base,
offset + 1))));
if (BYTES_BIG_ENDIAN)
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
gen_rtx_IOR (SImode,
@ -3632,41 +3705,183 @@ arm_reload_in_hi (operands)
(SImode,
gen_rtx_SUBREG (SImode, operands[0], 0),
GEN_INT (8)),
operands[2])));
scratch)));
else
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
gen_rtx_IOR (SImode,
gen_rtx_ASHIFT (SImode, operands[2],
gen_rtx_ASHIFT (SImode, scratch,
GEN_INT (8)),
gen_rtx_SUBREG (SImode, operands[0],
0))));
}
/* Handle storing a half-word to memory during reload by synthesising as two
byte stores. Take care not to clobber the input values until after we
have moved them somewhere safe. This code assumes that if the DImode
scratch in operands[2] overlaps either the input value or output address
in some way, then that value must die in this insn (we absolutely need
two scratch registers for some corner cases). */
void
arm_reload_out_hi (operands)
rtx *operands;
{
rtx base = find_replacement (&XEXP (operands[0], 0));
rtx ref = operands[0];
rtx outval = operands[1];
rtx base, scratch;
HOST_WIDE_INT offset = 0;
if (GET_CODE (ref) == SUBREG)
{
offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
if (BYTES_BIG_ENDIAN)
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
- MIN (UNITS_PER_WORD,
GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
ref = SUBREG_REG (ref);
}
if (GET_CODE (ref) == REG)
{
/* We have a pseudo which has been spilt onto the stack; there
are two cases here: the first where there is a simple
stack-slot replacement and a second where the stack-slot is
out of range, or is used as a subreg. */
if (reg_equiv_mem[REGNO (ref)])
{
ref = reg_equiv_mem[REGNO (ref)];
base = find_replacement (&XEXP (ref, 0));
}
else
/* The slot is out of range, or was dressed up in a SUBREG */
base = reg_equiv_address[REGNO (ref)];
}
else
base = find_replacement (&XEXP (ref, 0));
scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
/* Handle the case where the address is too complex to be offset by 1. */
if (GET_CODE (base) == MINUS
|| (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
{
rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
/* Be careful not to destroy OUTVAL. */
if (reg_overlap_mentioned_p (base_plus, outval))
{
/* Updating base_plus might destroy outval, see if we can
swap the scratch and base_plus. */
if (! reg_overlap_mentioned_p (scratch, outval))
{
rtx tmp = scratch;
scratch = base_plus;
base_plus = tmp;
}
else
{
rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
/* Be conservative and copy OUTVAL into the scratch now,
this should only be necessary if outval is a subreg
of something larger than a word. */
/* XXX Might this clobber base? I can't see how it can,
since scratch is known to overlap with OUTVAL, and
must be wider than a word. */
emit_insn (gen_movhi (scratch_hi, outval));
outval = scratch_hi;
}
}
emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
base = base_plus;
}
else if (GET_CODE (base) == PLUS)
{
/* The addend must be CONST_INT, or we would have dealt with it above */
HOST_WIDE_INT hi, lo;
offset += INTVAL (XEXP (base, 1));
base = XEXP (base, 0);
/* Rework the address into a legal sequence of insns */
/* Valid range for lo is -4095 -> 4095 */
lo = (offset >= 0
? (offset & 0xfff)
: -((-offset) & 0xfff));
/* Corner case, if lo is the max offset then we would be out of range
once we have added the additional 1 below, so bump the msb into the
pre-loading insn(s). */
if (lo == 4095)
lo &= 0x7ff;
hi = ((((offset - lo) & (HOST_WIDE_INT) 0xFFFFFFFF)
^ (HOST_WIDE_INT) 0x80000000)
- (HOST_WIDE_INT) 0x80000000);
if (hi + lo != offset)
abort ();
if (hi != 0)
{
rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
/* Be careful not to destroy OUTVAL. */
if (reg_overlap_mentioned_p (base_plus, outval))
{
/* Updating base_plus might destroy outval, see if we
can swap the scratch and base_plus. */
if (! reg_overlap_mentioned_p (scratch, outval))
{
rtx tmp = scratch;
scratch = base_plus;
base_plus = tmp;
}
else
{
rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
/* Be conservative and copy outval into scratch now,
this should only be necessary if outval is a
subreg of something larger than a word. */
/* XXX Might this clobber base? I can't see how it
can, since scratch is known to overlap with
outval. */
emit_insn (gen_movhi (scratch_hi, outval));
outval = scratch_hi;
}
}
/* Get the base address; addsi3 knows how to handle constants
that require more than one insn */
emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
base = base_plus;
offset = lo;
}
}
if (BYTES_BIG_ENDIAN)
{
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, 1)),
gen_rtx_SUBREG (QImode, operands[1], 0)));
emit_insn (gen_lshrsi3 (operands[2],
gen_rtx_SUBREG (SImode, operands[1], 0),
emit_insn (gen_movqi (gen_rtx_MEM (QImode,
plus_constant (base, offset + 1)),
gen_rtx_SUBREG (QImode, outval, 0)));
emit_insn (gen_lshrsi3 (scratch,
gen_rtx_SUBREG (SImode, outval, 0),
GEN_INT (8)));
emit_insn (gen_movqi (gen_rtx_MEM (QImode, base),
gen_rtx_SUBREG (QImode, operands[2], 0)));
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
gen_rtx_SUBREG (QImode, scratch, 0)));
}
else
{
emit_insn (gen_movqi (gen_rtx_MEM (QImode, base),
gen_rtx_SUBREG (QImode, operands[1], 0)));
emit_insn (gen_lshrsi3 (operands[2],
gen_rtx_SUBREG (SImode, operands[1], 0),
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
gen_rtx_SUBREG (QImode, outval, 0)));
emit_insn (gen_lshrsi3 (scratch,
gen_rtx_SUBREG (SImode, outval, 0),
GEN_INT (8)));
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, 1)),
gen_rtx_SUBREG (QImode, operands[2], 0)));
emit_insn (gen_movqi (gen_rtx_MEM (QImode,
plus_constant (base, offset + 1)),
gen_rtx_SUBREG (QImode, scratch, 0)));
}
}

View File

@ -248,7 +248,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
extern int target_flags;
/* The floating point instruction architecture, can be 2 or 3 */
extern char * target_fp_name;
extern const char * target_fp_name;
/* Nonzero if the function prologue (and epilogue) should obey
the ARM Procedure Call Standard. */
@ -404,9 +404,9 @@ function tries to return. */
struct arm_cpu_select
{
char * string;
char * name;
struct processors * processors;
const char * string;
const char * name;
const struct processors * processors;
};
/* This is a magic array. If the user specifies a command line switch
@ -585,7 +585,7 @@ extern int arm_is_6_or_7;
#endif
/* Used when parsing command line option -mstructure_size_boundary. */
extern char * structure_size_string;
extern const char * structure_size_string;
/* Non-zero if move instructions will actually fail to work
when given unaligned data. */

View File

@ -3128,11 +3128,13 @@
mov%?\\t%0, %1\\t%@ movhi
mvn%?\\t%0, #%B1\\t%@ movhi")
;; We use a DImode scratch because we may occasionally need an additional
;; temporary if the address isn't offsettable -- push_reload doesn't seem
;; to take any notice of the "o" constraints on reload_memory_operand operand.
(define_expand "reload_outhi"
[(parallel [(match_operand:HI 0 "reload_memory_operand" "=o")
(match_operand:HI 1 "s_register_operand" "r")
(match_operand:SI 2 "s_register_operand" "=&r")])]
(match_operand:DI 2 "s_register_operand" "=&r")])]
""
"
arm_reload_out_hi (operands);
@ -3142,7 +3144,7 @@
(define_expand "reload_inhi"
[(parallel [(match_operand:HI 0 "s_register_operand" "=r")
(match_operand:HI 1 "reload_memory_operand" "o")
(match_operand:SI 2 "s_register_operand" "=&r")])]
(match_operand:DI 2 "s_register_operand" "=&r")])]
"TARGET_SHORT_BY_BYTES"
"
arm_reload_in_hi (operands);

View File

@ -79,10 +79,10 @@ Boston, MA 02111-1307, USA. */
/* None of these is actually used in cc1. If we don't define them in target
switches cc1 complains about them. For the sake of argument lets allocate
bit 31 of target flags for such options. */
#define SUBTARGET_SWITCHES \
{"bsd", 0x80000000, ""}, \
{"xopen", 0x80000000, ""}, \
{"no-symrename", 0x80000000, ""},
#define SUBTARGET_SWITCHES \
{"bsd", 0x80000000, "Do symbol renaming for BSD"}, \
{"xopen", 0x80000000, "Do symbol renaming for X/OPEN"}, \
{"no-symrename", 0x80000000, "Don't do symbol renaming"},
/* Run-time Target Specification. */