diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8351c3723a3..2e46e4d0e93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ Wed Sep 23 16:22:01 1998 Nick Clifton + * config/arm/thumb.h: The following patches were made by Jim Wilson: + (enum reg_class): Add NONARG_LO_REGS support. + (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS, + PREFERRED_RELOAD_CLASS, SECONDARY_RELOAD_CLASS): Likewise. + (GO_IF_LEGITIMATE_ADDRESS): Disable REG+REG addresses before reload + completes. Re-enable HImode REG+OFFSET addresses. + (LEGITIMIZE_RELOAD_ADDRESS): Define. + * expmed.c (extract_bit_field): Add comment from Jim Wilson. Wed Sep 23 13:26:02 1998 Richard Henderson diff --git a/gcc/config/arm/thumb.h b/gcc/config/arm/thumb.h index 4030e37e406..0f6c60c6390 100644 --- a/gcc/config/arm/thumb.h +++ b/gcc/config/arm/thumb.h @@ -472,9 +472,15 @@ extern char * structure_size_string; #define MODES_TIEABLE_P(MODE1,MODE2) 1 +/* The NOARG_LO_REGS class is the set of LO_REGS that are not used for passing + arguments to functions. These are the registers that are available for + spilling during reload. The code in reload1.c:init_reload() will detect this + class and place it into 'reload_address_base_reg_class'. */ + enum reg_class { NO_REGS, + NONARG_LO_REGS, LO_REGS, STACK_REG, BASE_REGS, @@ -490,6 +496,7 @@ enum reg_class #define REG_CLASS_NAMES \ { \ "NO_REGS", \ + "NONARG_LO_REGS", \ "LO_REGS", \ "STACK_REG", \ "BASE_REGS", \ @@ -500,6 +507,7 @@ enum reg_class #define REG_CLASS_CONTENTS \ { \ 0x00000, \ + 0x000f0, \ 0x000ff, \ 0x02000, \ 0x020ff, \ @@ -509,7 +517,8 @@ enum reg_class #define REGNO_REG_CLASS(REGNO) \ ((REGNO) == STACK_POINTER_REGNUM ? STACK_REG \ - : (REGNO) < 8 ? LO_REGS \ + : (REGNO) < 8 ? ((REGNO) < 4 ? LO_REGS \ + : NONARG_LO_REGS) \ : HI_REGS) #define BASE_REG_CLASS BASE_REGS @@ -555,8 +564,15 @@ enum reg_class abort. Alternatively, this could be fixed by modifying BASE_REG_CLASS to be LO_REGS instead of BASE_REGS. It is not clear what affect this change would have. */ +/* ??? This looks even more suspiciously wrong. PREFERRED_RELOAD_CLASS + must always return a strict subset of the input class. Just blindly + returning LO_REGS is safe only if the input class is a superset of LO_REGS, + but there is no check for this. Added another exception for NONARG_LO_REGS + because it is not a superset of LO_REGS. */ +/* ??? We now use NONARG_LO_REGS for caller_save_spill_class, so the + comments about BASE_REGS are now obsolete. */ #define PREFERRED_RELOAD_CLASS(X,CLASS) \ - ((CLASS) == BASE_REGS ? (CLASS) \ + ((CLASS) == BASE_REGS || (CLASS) == NONARG_LO_REGS ? (CLASS) \ : LO_REGS) /* ((CONSTANT_P ((X)) && GET_CODE ((X)) != CONST_INT \ @@ -565,9 +581,10 @@ enum reg_class && (unsigned HOST_WIDE_INT) INTVAL ((X)) > 255) ? NO_REGS \ : LO_REGS) */ -/* Must leave BASE_REGS reloads alone, see comment above. */ +/* Must leave BASE_REGS and NONARG_LO_REGS reloads alone, see comment + above. */ #define SECONDARY_RELOAD_CLASS(CLASS,MODE,X) \ - ((CLASS) != LO_REGS && (CLASS) != BASE_REGS \ + ((CLASS) != LO_REGS && (CLASS) != BASE_REGS && (CLASS) != NONARG_LO_REGS \ ? ((true_regnum (X) == -1 ? LO_REGS \ : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \ : NO_REGS)) \ @@ -885,6 +902,16 @@ int thumb_shiftable_const (); else if (GET_CODE (X) == PLUS) \ { \ /* REG+REG address can be any two index registers. */ \ + /* ??? REG+REG addresses have been completely disabled before \ + reload completes, because we do not have enough available \ + reload registers. We only have 3 guaranteed reload registers \ + (NONARG_LO_REGS - the frame pointer), but we need at least 4 \ + to support REG+REG addresses. We have left them enabled after \ + reload completes, in the hope that reload_cse_regs and related \ + routines will be able to create them after the fact. It is \ + probably possible to support REG+REG addresses with additional \ + reload work, but I do not not have enough time to attempt such \ + a change at this time. */ \ /* ??? Normally checking the mode here is wrong, since it isn't \ impossible to use REG+REG with DFmode. However, the movdf \ pattern requires offsettable addresses, and REG+REG is not \ @@ -898,14 +925,14 @@ int thumb_shiftable_const (); will be replaced with STACK, and SP relative addressing only \ permits SP+OFFSET. */ \ if (GET_MODE_SIZE (MODE) <= 4 \ + /* ??? See comment above. */ \ + && reload_completed \ && GET_CODE (XEXP (X, 0)) == REG \ && GET_CODE (XEXP (X, 1)) == REG \ && XEXP (X, 0) != frame_pointer_rtx \ && XEXP (X, 1) != frame_pointer_rtx \ - /* CYGNUS LOCAL nickc */ \ && XEXP (X, 0) != virtual_stack_vars_rtx \ && XEXP (X, 1) != virtual_stack_vars_rtx \ - /* END CYGNUS LOCAL */ \ && REG_OK_FOR_INDEX_P (XEXP (X, 0)) \ && REG_OK_FOR_INDEX_P (XEXP (X, 1))) \ goto WIN; \ @@ -913,9 +940,6 @@ int thumb_shiftable_const (); else if (GET_CODE (XEXP (X, 0)) == REG \ && (REG_OK_FOR_INDEX_P (XEXP (X, 0)) \ || XEXP (X, 0) == arg_pointer_rtx) \ - /* CYGNUS LOCAL nickc */ \ - && GET_MODE_SIZE (MODE) != 2 \ - /* END CYGNUS LOCAL */ \ && GET_CODE (XEXP (X, 1)) == CONST_INT \ && LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \ goto WIN; \ @@ -933,6 +957,32 @@ int thumb_shiftable_const (); } \ } +/* ??? If an HImode FP+large_offset address is converted to an HImode + SP+large_offset address, then reload won't know how to fix it. It sees + only that SP isn't valid for HImode, and so reloads the SP into an index + register, but the resulting address is still invalid because the offset + is too big. We fix it here instead by reloading the entire address. */ +/* We could probably achieve better results by defining PROMOTE_MODE to help + cope with the variances between the Thumb's signed and unsigned byte and + halfword load instructions. */ +#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ +{ \ + if (GET_CODE (X) == PLUS \ + && GET_MODE_SIZE (MODE) < 4 \ + && GET_CODE (XEXP (X, 0)) == REG \ + && XEXP (X, 0) == stack_pointer_rtx \ + && GET_CODE (XEXP (X, 1)) == CONST_INT \ + && ! LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \ + { \ + rtx orig_X = X; \ + X = copy_rtx (X); \ + push_reload (orig_X, NULL_RTX, &X, NULL_PTR, \ + reload_address_base_reg_class, \ + Pmode, VOIDmode, 0, 0, OPNUM, TYPE); \ + goto WIN; \ + } \ +} + #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)