Commit c94c9817 by Mark Mitchell Committed by Mark Mitchell

mips-protos.h (mips_legitimate_address_p): New function.

	* config/mips/mips-protos.h (mips_legitimate_address_p): New
	function.
	(mips_reg_mode_ok_for_base_p): Likewise.
	* config/mips/mips.h (REG_OK_STRICT_P): Don't define.
	(REG_OK_FOR_INDEX_P): Define unconditionally.
	(REG_MODE_OK_FOR_BASE_P): Use mips_reg_mode_ok_for_base_p.
	(GO_IF_LEGITIMATE_ADDRESS): Use mips_legitimate_address_p.
	* config/mips/mips.c (mips16_simple_memory_operand): Adjust now
	that GET_MODE_SIZE is unsigned.
	(mips_reg_mode_ok_for_base_p): Define.
	(mips_legitimate_address_p): Likewise.  Adjust now
	that GET_MODE_SIZE is unsigned.
	(block_move_loop): Make the number of bytes unsigned.
	(expand_block_move): Likewise.
	(function_arg): Make the loop counter unsigned to match the
	boundary condition.

From-SVN: r33188
parent d636c18c
2000-04-16 Mark Mitchell <mark@codesourcery.com>
* config/mips/mips-protos.h (mips_legitimate_address_p): New
function.
(mips_reg_mode_ok_for_base_p): Likewise.
* config/mips/mips.h (REG_OK_STRICT_P): Don't define.
(REG_OK_FOR_INDEX_P): Define unconditionally.
(REG_MODE_OK_FOR_BASE_P): Use mips_reg_mode_ok_for_base_p.
(GO_IF_LEGITIMATE_ADDRESS): Use mips_legitimate_address_p.
* config/mips/mips.c (mips16_simple_memory_operand): Adjust now
that GET_MODE_SIZE is unsigned.
(mips_reg_mode_ok_for_base_p): Define.
(mips_legitimate_address_p): Likewise. Adjust now
that GET_MODE_SIZE is unsigned.
(block_move_loop): Make the number of bytes unsigned.
(expand_block_move): Likewise.
(function_arg): Make the loop counter unsigned to match the
boundary condition.
2000-04-16 Richard Henderson <rth@cygnus.com>
* rtl.h (enum insn_note): New enumeration. Subsume
......
......@@ -130,6 +130,8 @@ extern int se_uns_arith_operand PARAMS ((rtx, enum machine_mode));
extern int se_arith_operand PARAMS ((rtx, enum machine_mode));
extern int se_nonmemory_operand PARAMS ((rtx, enum machine_mode));
extern int se_nonimmediate_operand PARAMS ((rtx, enum machine_mode));
extern int mips_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
extern int mips_reg_mode_ok_for_base_p PARAMS ((rtx, enum machine_mode, int));
extern int extend_operator PARAMS ((rtx, enum machine_mode));
extern int highpart_shift_operator PARAMS ((rtx, enum machine_mode));
extern int m16_uimm3_b PARAMS ((rtx, enum machine_mode));
......
......@@ -91,7 +91,9 @@ static enum internal_test map_test_to_internal_test PARAMS ((enum rtx_code));
static int mips16_simple_memory_operand PARAMS ((rtx, rtx,
enum machine_mode));
static int m16_check_op PARAMS ((rtx, int, int, int));
static void block_move_loop PARAMS ((rtx, rtx, int, int,
static void block_move_loop PARAMS ((rtx, rtx,
unsigned int,
int,
rtx, rtx));
static void block_move_call PARAMS ((rtx, rtx, rtx));
static FILE *mips_make_temp_file PARAMS ((void));
......@@ -671,7 +673,8 @@ mips16_simple_memory_operand (reg, offset, mode)
rtx offset;
enum machine_mode mode;
{
int size, off;
unsigned int size;
int off;
if (mode == BLKmode)
{
......@@ -1209,6 +1212,136 @@ mips_check_split (address, mode)
return 0;
}
/* This function is used to implement REG_MODE_OK_FOR_BASE_P. */
int
mips_reg_mode_ok_for_base_p (reg, mode, strict)
rtx reg;
enum machine_mode mode;
int strict;
{
return (strict
? REGNO_MODE_OK_FOR_BASE_P (REGNO (reg), mode)
: GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (reg), mode));
}
/* This function is used to implement GO_IF_LEGITIMATE_ADDRESS. It
returns a nonzero value if XINSN is a legitimate address for a
memory operand of the indicated MODE. STRICT is non-zero if this
function is called during reload. */
int
mips_legitimate_address_p (mode, xinsn, strict)
enum machine_mode mode;
rtx xinsn;
int strict;
{
if (TARGET_DEBUG_B_MODE)
{
GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
strict ? "" : "not ");
GO_DEBUG_RTX (xinsn);
}
/* Check for constant before stripping off SUBREG, so that we don't
accept (subreg (const_int)) which will fail to reload. */
if (CONSTANT_ADDRESS_P (xinsn)
&& ! (mips_split_addresses && mips_check_split (xinsn, mode))
&& (! TARGET_MIPS16 || mips16_constant (xinsn, mode, 1, 0)))
return 1;
while (GET_CODE (xinsn) == SUBREG)
xinsn = SUBREG_REG (xinsn);
/* The mips16 can only use the stack pointer as a base register when
loading SImode or DImode values. */
if (GET_CODE (xinsn) == REG
&& mips_reg_mode_ok_for_base_p (xinsn, mode, strict))
return 1;
if (GET_CODE (xinsn) == LO_SUM && mips_split_addresses)
{
register rtx xlow0 = XEXP (xinsn, 0);
register rtx xlow1 = XEXP (xinsn, 1);
while (GET_CODE (xlow0) == SUBREG)
xlow0 = SUBREG_REG (xlow0);
if (GET_CODE (xlow0) == REG
&& mips_reg_mode_ok_for_base_p (xlow0, mode, strict)
&& mips_check_split (xlow1, mode))
return 1;
}
if (GET_CODE (xinsn) == PLUS)
{
register rtx xplus0 = XEXP (xinsn, 0);
register rtx xplus1 = XEXP (xinsn, 1);
register enum rtx_code code0;
register enum rtx_code code1;
while (GET_CODE (xplus0) == SUBREG)
xplus0 = SUBREG_REG (xplus0);
code0 = GET_CODE (xplus0);
while (GET_CODE (xplus1) == SUBREG)
xplus1 = SUBREG_REG (xplus1);
code1 = GET_CODE (xplus1);
/* The mips16 can only use the stack pointer as a base register
when loading SImode or DImode values. */
if (code0 == REG
&& mips_reg_mode_ok_for_base_p (xplus0, mode, strict))
{
if (code1 == CONST_INT && SMALL_INT (xplus1))
return 1;
/* On the mips16, we represent GP relative offsets in RTL.
These are 16 bit signed values, and can serve as register
offsets. */
if (TARGET_MIPS16
&& mips16_gp_offset_p (xplus1))
return 1;
/* For some code sequences, you actually get better code by
pretending that the MIPS supports an address mode of a
constant address + a register, even though the real
machine doesn't support it. This is because the
assembler can use $r1 to load just the high 16 bits, add
in the register, and fold the low 16 bits into the memory
reference, whereas the compiler generates a 4 instruction
sequence. On the other hand, CSE is not as effective.
It would be a win to generate the lui directly, but the
MIPS assembler does not have syntax to generate the
appropriate relocation. */
/* Also accept CONST_INT addresses here, so no else. */
/* Reject combining an embedded PIC text segment reference
with a register. That requires an additional
instruction. */
/* ??? Reject combining an address with a register for the MIPS
64 bit ABI, because the SGI assembler can not handle this. */
if (!TARGET_DEBUG_A_MODE
&& (mips_abi == ABI_32
|| mips_abi == ABI_O64
|| mips_abi == ABI_EABI)
&& CONSTANT_ADDRESS_P (xplus1)
&& ! mips_split_addresses
&& (!TARGET_EMBEDDED_PIC
|| code1 != CONST
|| GET_CODE (XEXP (xplus1, 0)) != MINUS)
&& !TARGET_MIPS16)
return 1;
}
}
if (TARGET_DEBUG_B_MODE)
GO_PRINTF ("Not a legitimate address\n");
/* The address was not legitimate. */
return 0;
}
/* We need a lot of little routines to check constant values on the
mips16. These are used to figure out how long the instruction will
be. It would be much better to do this using constraints, but
......@@ -3033,7 +3166,7 @@ static void
block_move_loop (dest_reg, src_reg, bytes, align, orig_dest, orig_src)
rtx dest_reg; /* register holding destination address */
rtx src_reg; /* register holding source address */
int bytes; /* # bytes to move */
unsigned int bytes; /* # bytes to move */
int align; /* alignment */
rtx orig_dest; /* original dest for change_address */
rtx orig_src; /* original source for making a reg note */
......@@ -3145,14 +3278,14 @@ expand_block_move (operands)
rtx bytes_rtx = operands[2];
rtx align_rtx = operands[3];
int constp = GET_CODE (bytes_rtx) == CONST_INT;
HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
int align = INTVAL (align_rtx);
unsigned HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
unsigned int align = INTVAL (align_rtx);
rtx orig_src = operands[1];
rtx orig_dest = operands[0];
rtx src_reg;
rtx dest_reg;
if (constp && bytes <= 0)
if (constp && bytes == 0)
return;
if (align > UNITS_PER_WORD)
......@@ -3863,7 +3996,7 @@ function_arg (cum, mode, type, named)
unsigned int chunks;
HOST_WIDE_INT bitpos;
unsigned int regno;
int i;
unsigned int i;
/* ??? If this is a packed structure, then the last hunk won't
be 64 bits. */
......
......@@ -2725,21 +2725,15 @@ typedef struct mips_args {
need to be strict. */
#ifndef REG_OK_STRICT
#define REG_OK_STRICT_P 0
#define REG_OK_FOR_INDEX_P(X) 0
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
GP_REG_OR_PSEUDO_NONSTRICT_P (REGNO (X), (MODE))
mips_reg_mode_ok_for_base_p (X, MODE, 0)
#else
#define REG_OK_STRICT_P 1
#define REG_OK_FOR_INDEX_P(X) 0
#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
REGNO_MODE_OK_FOR_BASE_P (REGNO (X), (MODE))
mips_reg_mode_ok_for_base_p (X, MODE, 1)
#endif
#define REG_OK_FOR_INDEX_P(X) 0
/* Maximum number of registers that can appear in a valid memory address. */
......@@ -2806,112 +2800,19 @@ typedef struct mips_args {
#define GO_DEBUG_RTX(x)
#endif
#ifdef REG_OK_STRICT
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
register rtx xinsn = (X); \
\
if (TARGET_DEBUG_B_MODE) \
{ \
GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n", \
(REG_OK_STRICT_P) ? "" : "not "); \
GO_DEBUG_RTX (xinsn); \
} \
\
/* Check for constant before stripping off SUBREG, so that we don't \
accept (subreg (const_int)) which will fail to reload. */ \
if (CONSTANT_ADDRESS_P (xinsn) \
&& ! (mips_split_addresses && mips_check_split (xinsn, MODE)) \
&& (! TARGET_MIPS16 || mips16_constant (xinsn, MODE, 1, 0))) \
if (mips_legitimate_address_p (MODE, X, 1)) \
goto ADDR; \
\
while (GET_CODE (xinsn) == SUBREG) \
xinsn = SUBREG_REG (xinsn); \
\
/* The mips16 can only use the stack pointer as a base register when \
loading SImode or DImode values. */ \
if (GET_CODE (xinsn) == REG && REG_MODE_OK_FOR_BASE_P (xinsn, MODE)) \
goto ADDR; \
\
if (GET_CODE (xinsn) == LO_SUM && mips_split_addresses) \
{ \
register rtx xlow0 = XEXP (xinsn, 0); \
register rtx xlow1 = XEXP (xinsn, 1); \
\
while (GET_CODE (xlow0) == SUBREG) \
xlow0 = SUBREG_REG (xlow0); \
if (GET_CODE (xlow0) == REG \
&& REG_MODE_OK_FOR_BASE_P (xlow0, MODE) \
&& mips_check_split (xlow1, MODE)) \
goto ADDR; \
} \
\
if (GET_CODE (xinsn) == PLUS) \
{ \
register rtx xplus0 = XEXP (xinsn, 0); \
register rtx xplus1 = XEXP (xinsn, 1); \
register enum rtx_code code0; \
register enum rtx_code code1; \
\
while (GET_CODE (xplus0) == SUBREG) \
xplus0 = SUBREG_REG (xplus0); \
code0 = GET_CODE (xplus0); \
\
while (GET_CODE (xplus1) == SUBREG) \
xplus1 = SUBREG_REG (xplus1); \
code1 = GET_CODE (xplus1); \
\
/* The mips16 can only use the stack pointer as a base register \
when loading SImode or DImode values. */ \
if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, MODE)) \
{ \
if (code1 == CONST_INT \
&& INTVAL (xplus1) >= -32768 \
&& INTVAL (xplus1) + GET_MODE_SIZE (MODE) - 1 <= 32767) \
goto ADDR; \
\
/* On the mips16, we represent GP relative offsets in RTL. \
These are 16 bit signed values, and can serve as register \
offsets. */ \
if (TARGET_MIPS16 \
&& mips16_gp_offset_p (xplus1)) \
goto ADDR; \
\
/* For some code sequences, you actually get better code by \
pretending that the MIPS supports an address mode of a \
constant address + a register, even though the real \
machine doesn't support it. This is because the \
assembler can use $r1 to load just the high 16 bits, add \
in the register, and fold the low 16 bits into the memory \
reference, whereas the compiler generates a 4 instruction \
sequence. On the other hand, CSE is not as effective. \
It would be a win to generate the lui directly, but the \
MIPS assembler does not have syntax to generate the \
appropriate relocation. */ \
\
/* Also accept CONST_INT addresses here, so no else. */ \
/* Reject combining an embedded PIC text segment reference \
with a register. That requires an additional \
instruction. */ \
/* ??? Reject combining an address with a register for the MIPS \
64 bit ABI, because the SGI assembler can not handle this. */ \
if (!TARGET_DEBUG_A_MODE \
&& (mips_abi == ABI_32 \
|| mips_abi == ABI_O64 \
|| mips_abi == ABI_EABI) \
&& CONSTANT_ADDRESS_P (xplus1) \
&& ! mips_split_addresses \
&& (!TARGET_EMBEDDED_PIC \
|| code1 != CONST \
|| GET_CODE (XEXP (xplus1, 0)) != MINUS) \
&& !TARGET_MIPS16) \
}
#else
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
if (mips_legitimate_address_p (MODE, X, 0)) \
goto ADDR; \
} \
} \
\
if (TARGET_DEBUG_B_MODE) \
GO_PRINTF ("Not a legitimate address\n"); \
}
#endif
/* A C expression that is 1 if the RTX X is a constant which is a
valid address. This is defined to be the same as `CONSTANT_P (X)',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment