aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2000-04-16 21:47:17 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2000-04-16 21:47:17 +0000
commitc94c981720869f68bb1e2b2c48e615849c338e7e (patch)
tree8102cb69f67414484bfae05a563bafc66216daa4 /gcc
parentd636c18c54181f8bf09f5c75bb9b517bba3efb69 (diff)
downloadgcc-c94c981720869f68bb1e2b2c48e615849c338e7e.zip
gcc-c94c981720869f68bb1e2b2c48e615849c338e7e.tar.gz
gcc-c94c981720869f68bb1e2b2c48e615849c338e7e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c149
-rw-r--r--gcc/config/mips/mips.h131
4 files changed, 178 insertions, 123 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c0dc920..9f89087 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+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
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 598be36..6f9f59b 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -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));
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b7a7ffc..c19f35f 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -91,8 +91,10 @@ 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,
- rtx, rtx));
+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));
static void save_restore_insns PARAMS ((int, rtx,
@@ -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)
{
@@ -1208,6 +1211,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
@@ -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. */
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index bc8c83e..d455d9e 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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
-#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))) \
- 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) \
- goto ADDR; \
- } \
- } \
- \
- if (TARGET_DEBUG_B_MODE) \
- GO_PRINTF ("Not a legitimate address\n"); \
+#ifdef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (mips_legitimate_address_p (MODE, X, 1)) \
+ goto ADDR; \
}
-
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
+{ \
+ if (mips_legitimate_address_p (MODE, X, 0)) \
+ goto ADDR; \
+}
+#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)',