From 061cd933b9dfd34d7926aa47a9d46ac8121e6d01 Mon Sep 17 00:00:00 2001 From: mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Sun, 16 Apr 2000 21:47:17 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@33188 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 +++++ gcc/config/mips/mips-protos.h | 2 + gcc/config/mips/mips.c | 149 ++++++++++++++++++++++++++++++++-- gcc/config/mips/mips.h | 131 ++++-------------------------- 4 files changed, 178 insertions(+), 123 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0dc9205c150..9f8908778afa 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 598be36eba54..6f9f59b221f4 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 b7a7ffc80970..c19f35f57e6f 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 bc8c83e0732a..d455d9e3059e 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)', -- GitLab