2008/5/29 <[EMAIL PROTECTED]>: > Again thank you and Denis for your comment. > > Here is what I deduce from code and Denis comments - I am sure he (and > others) will correct me if wrong :-) > > > The main issue is that we have one pointer register that cannot take offset > and two base pointers with limited offset (0-63).
Yes. Oops I'm sorry. I wrote -63 to +63 in my last mail it's wrong. The right offset 0 to 63. > > Reload provides no means to pick the right pointer register. To do so would > require a "preffered base pointer" mechanism. Yes. > > AVR L_R_A sole purpose is substituting POINTER class where there are > oppertunities to do so. > > BUT as L_R_A is in middle of find_reloads_address, we have a problem in > that some normal reload solutions have already been applied and some have > not. Yes. > This may mean that 1) We never get here - so miss POINTER oppertunity or 2) > Miss even better solutions that are applied latter. > 3)Have code vulnerable to reload changes. Yes. > I have added comment below to explain the parts. > I'll probably need to add some debug hooks to check what parts still > contribute. > > best regards > > Andy > > > > #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) > \ > do { \ > if (1&&(GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)) \ > { \ > push_reload (XEXP (X,0), XEXP (X,0), &XEXP (X,0), &XEXP (X,0), \ > POINTER_REGS, GET_MODE (X),GET_MODE (X) , 0, 0, \ > OPNUM, RELOAD_OTHER); \ > goto WIN; \ > } \ > > > The intent is to use POINTER class registers for INC/DEC so we have one more > register available than BASE_POINTER > > Has INC/DEC been handled already making this part redundant? > Are there any other solutions that this code skips? Really, I forgot why this part of L_R_A exists. Look at strange 'if (1&&'. I remember that once I have disabled it (add 0&&), but after some testing I have enablet it again. > if (GET_CODE (X) == PLUS \ > && REG_P (XEXP (X, 0)) \ > && GET_CODE (XEXP (X, 1)) == CONST_INT \ > && INTVAL (XEXP (X, 1)) >= 1) \ > { \ > int fit = INTVAL (XEXP (X, 1)) <= (64 - GET_MODE_SIZE (MODE)); \ > if (fit) \ > { \ > if (reg_equiv_address[REGNO (XEXP (X, 0))] != 0) \ > { \ > int regno = REGNO (XEXP (X, 0)); \ > rtx mem = make_memloc (X, regno); \ > push_reload (XEXP (mem,0), NULL, &XEXP (mem,0), NULL, \ > POINTER_REGS, Pmode, VOIDmode, 0, 0, \ > 1, ADDR_TYPE (TYPE)); \ > push_reload (mem, NULL_RTX, &XEXP (X, 0), NULL, \ > BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \ > OPNUM, TYPE); \ > goto WIN; \ > } > > Im struggling with this part. however, the POINTER class is an advantageous > in the first reloading the address from memory > - where we would not want to waste BASE POINTER and also create overlap > problem. Yes. > The implication of using this code is that without it we cannot catch the > inner reload POINTER oppertunity if we leave reload to decompose > BASE+offset. I think this is correct :-( > > > \ > push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \ > BASE_POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \ > OPNUM, TYPE); \ > goto WIN; > > This part is duplicating reload and should not be here (I have patch pending > with maintainer that removes this - for different bug) > > \ > } \ > else if (! (frame_pointer_needed && XEXP (X,0) == frame_pointer_rtx)) \ > { \ > push_reload (X, NULL_RTX, &X, NULL, \ > POINTER_REGS, GET_MODE (X), VOIDmode, 0, 0, \ > OPNUM, TYPE); \ > goto WIN; \ > } \ > } \ > > This case is where offset is out of range and we must reload not-the-frame_pointer. The frame_pointer can be handled by reload more optimal because we have Z register (Z+offset). > - so we allow POINTER class on the > basis that this is no worse than BASE POINTER. However, we leave > frame_pointer to reload. Because reload-pass can reload frame_pointer+big_offset because we have anower one pointer+offser register (Z+offset). Denis.