Re: Help with reloading
On 20 December 2010 10:56, Jeff Law wrote: > On 12/15/10 07:14, Mohamed Shafi wrote: >> >> Hi, >> >> I am doing a port in GCC 4.5.1. >> The target supports storing immediate values into memory location >> represented by a symbolic address. So in the move pattern i have given >> constraints to represent this. > > Presumably the target does not support storing an immediate value into other > MEMs? ie, the only store-immediate is to a symbolic memory operand, right? > yes you are right. > I think this is a case where you're going to need a secondary reload to > force the immediate into a register if the destination is a non-symbolic MEM > or a pseudo without a hard reg and its equivalent address is non-symbolic. > I am not sure how i should be implementing this. Currently in define_expand for move i have code to force the immediate value into a register if the destination is not a symbolic address. If i understand correctly this is the only place where i can decide what to do with the source depending on the destination. right? Moreover for the pattern (insn 27 25 33 4 pr23848-3.c:12 (set (mem/s/j:QI (reg/f:PQI 12 as0 [69]) [0 S1 A32]) (reg:QI 93)) 7 {movqi_op} (expr_list:REG_DEAD (reg/f:PQI 12 as0 [69]) (expr_list:REG_EQUAL (const_int 0 [0x0]) (nil destination is the src operand gets converted by /* This is equivalent to calling find_reloads_toplev. The code is duplicated for speed. When we find a pseudo always equivalent to a constant, we replace it by the constant. We must be sure, however, that we don't try to replace it in the insn in which it is being set. */ int regno = REGNO (recog_data.operand[i]); if (reg_equiv_constant[regno] != 0 && (set == 0 || &SET_DEST (set) != recog_data.operand_loc[i])) { /* Record the existing mode so that the check if constants are allowed will work when operand_mode isn't specified. */ if (operand_mode[i] == VOIDmode) operand_mode[i] = GET_MODE (recog_data.operand[i]); substed_operand[i] = recog_data.operand[i] = reg_equiv_constant[regno]; } and since the destination is already selected for reload /* If the address was already reloaded, we win as well. */ else if (MEM_P (operand) && address_reloaded[i] == 1) win = 1; the reload phase never reaches secondary reload. So i do not understand your answer. Could you explain it briefly. Regards, Shafi
RE: Is eliminate_regs_in_insn allowed to generate invalid instruction?
> -Original Message- > From: Ulrich Weigand [mailto:uweig...@de.ibm.com] > Sent: 17 December 2010 18:48 > To: Bingfeng Mei > Cc: i...@google.com; gcc@gcc.gnu.org; gcc-patc...@gcc.gnu.org > Subject: Re: Is eliminate_regs_in_insn allowed to generate invalid > instruction? > > Bingfeng Mei wrote: > > > I think I found the cause. find_reloads_address returns 0 even > > it reloads both parts of address (see the patch). Therefore, > > corresponding address_reloaded[i] is not set and in > > the following code of find_reloads, > > > >if (EXTRA_CONSTRAINT_STR (operand, c, p)) > > win = 1; > > /* If the address was already reloaded, > >we win as well. */ > >else if (MEM_P (operand) > > && address_reloaded[i] == 1) <-- address_reloaded[i] still > 0 > > win = 1; > > ... > > > > Extra reload is thus generated even it is unnecessary > > and causes ICE. > > As Ian said, since the address wasn't *completely* reloaded (so that > after reload we'll have just a plain base register), it is correct > that address_reloaded must be 0. > > However, if you're running into problems in this part of the code, you > may probably hit another of the long-standing warts in reload: at this > point, you have an address that reload has already decided to reload > certain parts of, and the result has to match one of your port's > extra memory constraints. However, reload at this point has not > actually made any modifications to the address in its RTL form, it > has just recorded in its own tables that *later*, it *will* replace > some subexpressions of that RTL with registers. > > This means that the RTL that is passed to your EXTRA_CONSTRAINT_STR > implementation will still be the *original* un-reloaded address. > And most likely, your back-end will then reject this address as > not valid for your machine. > Thanks, that is exactly what I see. But is only EXTRA_CONSTRAINT_STR that suffers this issue? It sounds that normal memory constraint should have this problem too. > The way some ports take around this issue is to recognize, in your > EXTRA_CONSTRAINT_STR implementation, certain forms of complex > addresses as those which you *know* reload will already have marked > for reloading, and therefore *accept* them (if they'd otherwise > match the constraint). > > Bye, > Ulrich > > -- > Dr. Ulrich Weigand > GNU Toolchain for Linux on System z and Cell BE > ulrich.weig...@de.ibm.com Bingfeng
Re: BImode is treated as normal byte-wide mode and causes bug.
Hi, Why don't you use a define_insn "zero_extendbisi2" which generates your conversion instruction. You can also use a define_insn_and_split if you have multiple instructions to generate. The define_insn_and_split should take place after reload is completed. Hence, you will avoid working on subregs. Best, Claudiu On Fri, Dec 10, 2010 at 10:58 AM, Bingfeng Mei wrote: > > Hi, > I am investigating a bug in our target port. It is > due to following optimization done by combine pass. > > (zero_extend:SI (reg:BI 120)) > > is transformed to > > (and:SI (subreg:SI (reg:BI 120) 0) > (const_int 255 [0xff])) > > in expand_compound_operation (combine.c), where BImode is > just treated as a byte-wide mode. > > In machmode.def, BImode is defined as FRACTIONAL_INT_MODE (BI, 1, 1). > But the precision field is not used at all here. > > Even after I hacked the code to bypass the transformation. > > (subreg:QI (zero_extend:SI (reg:BI 120)) 0) > > is still transformed to > (subreg:QI (reg:BI 120) 0)) > > in simplify_subreg. This is wrong because the higher bits > of paradoxical subreg is undefined here, not zeros. > > Grep GET_MODE_PRECISION returns not many results. It seems > that many rtx optimization functions don't consider > FRACTIONAL_INT_MODE at all. If that is the case, we should > document that limitations (or maybe I missed it). > > We need zero_extend BImode to model behaviour of moving > lowest bit of predicate register into general register. > > Cheers, > Bingfeng >
Re: Is eliminate_regs_in_insn allowed to generate invalid instruction?
Bingfeng Mei wrote: > > -Original Message- > > This means that the RTL that is passed to your EXTRA_CONSTRAINT_STR > > implementation will still be the *original* un-reloaded address. > > And most likely, your back-end will then reject this address as > > not valid for your machine. > > Thanks, that is exactly what I see. But is only EXTRA_CONSTRAINT_STR > that suffers this issue? It sounds that normal memory constraint should > have this problem too. Actually, it doesn't. If you look at the corresponding code: case TARGET_MEM_CONSTRAINT: if (force_reload) break; if (MEM_P (operand) || (REG_P (operand) && REGNO (operand) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (operand)] < 0)) win = 1; if (CONST_POOL_OK_P (operand)) badop = 0; constmemok = 1; break; you'll notice that *every* MEM is accepted for the normal memory constraint here; there is no checking whatsoever that the address is legitimate. (If there were, we'd run into exactly the same problem.) The reasoning behind this approach is: Before reload, we know the address must have been valid. During find_reloads_address, the code is careful to either leave the address valid, or else create reloads that are known to be sufficient to make the address valid again. Therefore, we can simply assume that the final address after all reloads are applied will be legitimate, without having to explicitly check for that ... Bye, Ulrich -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com
Re: Help with reloading
On 12/20/10 01:47, Mohamed Shafi wrote: I think this is a case where you're going to need a secondary reload to force the immediate into a register if the destination is a non-symbolic MEM or a pseudo without a hard reg and its equivalent address is non-symbolic. I am not sure how i should be implementing this. Currently in define_expand for move i have code to force the immediate value into a register if the destination is not a symbolic address. If i understand correctly this is the only place where i can decide what to do with the source depending on the destination. right? Just changing the movxx expander is not sufficient since for this case you do not know until reload time whether or not a particular insn needs an extra register to implement the move. That's the whole point of the secondary reload mechanism -- to allow you to allocate a scratch register during reloading to handle oddball cases like this. In your secondary reload code you'll need to check for the case where the destination is a MEM and the source is an unallocated pseudo with a constant equivalent and return a suitable register class for that case. Jeff
Re: Help with reloading
On 20 December 2010 19:30, Jeff Law wrote: > On 12/20/10 01:47, Mohamed Shafi wrote: >> >> >>> I think this is a case where you're going to need a secondary reload to >>> force the immediate into a register if the destination is a non-symbolic >>> MEM >>> or a pseudo without a hard reg and its equivalent address is >>> non-symbolic. >>> >> I am not sure how i should be implementing this. >> Currently in define_expand for move i have code to force the >> immediate value into a register if the destination is not a symbolic >> address. If i understand correctly this is the only place where i can >> decide what to do with the source depending on the destination. right? > > Just changing the movxx expander is not sufficient since for this case you > do not know until reload time whether or not a particular insn needs an > extra register to implement the move. That's the whole point of the > secondary reload mechanism -- to allow you to allocate a scratch register > during reloading to handle oddball cases like this. > > > In your secondary reload code you'll need to check for the case where the > destination is a MEM and the source is an unallocated pseudo with a constant > equivalent and return a suitable register class for that case. > Jeff, thanks for the reply. I didn't know that you could do that in TARGET_SECONDARY_RELOAD hook. Can you point me to some target that does this - figuring out what the destination is based on the source or vice versa. In my case only the address operand comes into TARGET_SECONDARY_RELOAD hook during the reload pass. I am not sure how to find out the source for the pattern which has this particular address as the destination. Sorry for the trouble. Shafi
Re: Help with reloading
On 12/20/10 07:33, Mohamed Shafi wrote: I didn't know that you could do that in TARGET_SECONDARY_RELOAD hook. Can you point me to some target that does this - figuring out what the destination is based on the source or vice versa. In my case only the address operand comes into TARGET_SECONDARY_RELOAD hook during the reload pass. I am not sure how to find out the source for the pattern which has this particular address as the destination. The vast majority of targets define secondary reloads. You'd have to scan through them to see if one does precisely what you want -- I don't know if one will do precisely what you want, but there should be enough examples that you can learn from to implement what your target needs. The mn103 port is pretty simple and defines a few well understood secondary reloads. The other, less desirable alternative would be to disallow constant stores to memory completely in the insn predicate, then have a peephole2 to catch cases where you have a constant load into a reg followed by a store of that reg to a symbolic memory location and the reg dies. jeff
Re: cscope replacement
Perry Smith writes: > Is there a way to have gcc produce some type of intermediate file that > could be used to generate a cscope like database. (Perhaps a better > way to phrase the question is 'which intermediate file, if any, could > be used') I have a few issues with cscope that I keep hoping to solve > somehow someday. Here is a short list of them: If you mean: is there an option to do that today, then, no, there isn't. If you mean: could it be done in some way, then, yes. This sounds like a natural application for a compiler plugin. Ian
[gimplefe] Mainline merge @168092
Bootstrapped and tested on x86_64. ChangeLog.gimplefe Merge with mainline rev 168092. * BASE-VER: Add -gimplefe suffix to version string. * DATESTAMP: Indicate latest trunk revision merged. gimple/ChangeLog * parser.h (gimple_parser): Remove field debug_p. * parser.c (gimple_main): Remove argument debug_p. Update all users. Diego.
How can I add 256bits register file to a MIPS port?
Hi all I need add 256bits-register support for our MIPS-based processor, so I add some codes. When I build gcc and test it, get a error "unable to find a register to spill in class 'XX_REGS'" can you tell me how to add 256bits register file to a MIPS port? Thanks! codes: gcc/config/mips/constraints.md : (define_register_constraint 'Z' 'XX_REGS' '@internal') gcc/config/mips/mips-ftypes.def : DEF_MIPS_FTYPE (2, (UV32QI, UV32QI, UV32QI)) DEF_MIPS_FTYPE (2, (V32QI, V32QI, V32QI)) gcc/config/mips/mips.h : #define FIXED_REGISTERS /* XX regusters */ \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\ #define CALL_USED_REGISTERS /* XX regusters */ \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\ #define CALL_REALLY_USED_REGISTERS /* XX regusters */ \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\ #define XX_REG_FIRST 188 #define XX_REG_LAST 251 #define XX_REG_NUM (XX_REG_LAST - XX_REG_FIRST + 1) #define XX_REG_P(REGNO) \ ((unsigned int) ((int) (REGNO) - XX_REG_FIRST) < XX_REG_NUM) enum reg_class XX_REGS, #define REG_CLASS_NAMES XX_REGS, #define REG_CLASS_CONTENTS add bits into it. #define REG_ALLOC_ORDER 188,189,190,191,192,193,194,195,196,197,\ 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213, \ 214,215,216,217,218,219,229,221,222,223,224,225,226,227,228,229, \ 230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245, \ 246,247,248,249,250,251 #define REGISTER_NAMES '$z0', '$z1', '$z2', '$z3', '$z4', '$z5', '$z6', '$z7', '$z8', '$z9',\ '$z10', '$z11', '$z12', '$z13', '$z14', '$z15', '$z16', '$z17', '$z18', '$z19', \ '$z20', '$z21', '$z22', '$z23', '$z24', '$z25', '$z26', '$z27', '$z28', '$z29', \ '$z30', '$z31', '$z32', '$z33', '$z34', '$z35', '$z36', '$z37', '$z38', '$z39', \ '$z40', '$z41', '$z42', '$z43', '$z44', '$z45', '$z46', '$z47', '$z48', '$z49', \ '$z50', '$z51', '$z52', '$z53', '$z54', '$z55', '$z56', '$z57', '$z58', '$z59', \ '$z60', '$z61', '$z62', '$z63' } gcc/config/mips/mips-modes.def : /* XX Vec modes */ VECTOR_MODES (INT, 32);/* V32QI V16HI V8SI V4DI */ gcc/config/mips/xx.h : vpaddb_u (uint8x32_t s, uint8x32_t t) { return __builtin_xx_vpaddb_u (s, t); } __extension__ static __inline int8x32_t __attribute__ ((__always_inline__)) vpaddb_s (int8x32_t s, int8x32_t t) { return __builtin_xx_vpaddb_s (s, t); } gcc/config/mips/xx.md : (define_mode_iterator ZB [V32QI]) (define_mode_iterator ZH [V16HI]) (define_mode_iterator ZW [V8SI]) (define_mode_iterator ZD [V4DI]) (define_mode_iterator ZHB [V16HI V32QI]) (define_mode_iterator ZWH [V8SI V16HI]) (define_mode_iterator ZDW [V4DI V8SI]) (define_mode_iterator ZWHB [V8SI V16HI V32QI]) (define_mode_iterator ZDWH [V4DI V8SI V16HI]) (define_mode_iterator ZDWHB [V4DI V8SI V16HI V32QI]) (define_mode_attr Z_suffix [(V4DI 'd')(V8SI 'w') (V16HI 'h') (V32QI 'b')]) (define_insn 'xx_vpadd' [(set (match_operand:ZDWHB 0 'register_operand' '=Z') (plus:ZDWHB (match_operand:ZDWHB 1 'register_operand' 'Z') (match_operand:ZDWHB 2 'register_operand' 'Z')))] 'TARGET_HARD_FLOAT && TARGET_XX_VECTORS' 'vpadd\t%0,%1,%2' [(set_attr 'type' 'fadd')]) gcc/config/mips/mips.c : if (TARGET_XX_VECTORS && (mode == V32QImode || mode == V16HImode || mode == V8SImode || mode == V4DImode)) return true; case V32QImode: case V16HImode: case V8SImode: case V4DImode: return TARGET_XX_VECTORS; #define CODE_FOR_xx_vpaddb CODE_FOR_xx_vpaddv32qi XX_BUILTIN_SUFFIX (vpaddb, u, MIPS_UV32QI_FTYPE_UV32QI_UV32QI), XX_BUILTIN_SUFFIX (vpaddb, s, MIPS_V32QI_FTYPE_V32QI_V32QI), #define MIPS_ATYPE_V32QI mips_builtin_vector_type (intQI_type_node, V32QImode) #define MIPS_ATYPE_V16HI mips_builtin_vector_type (intHI_type_node, V16HImode) #define MIPS_ATYPE_V8SI mips_builtin_vector_type (intSI_type_node, V8SImode) #define MIPS_ATYPE_V4DI mips_builtin_vector_type (intDI_type_node, V4DImode) #define MIPS_ATYPE_UV32QI
Re: cscope replacement
Hi, On Mon, Dec 20, 2010 at 2:44 PM, Ian Lance Taylor wrote: > Perry Smith writes: > >> Is there a way to have gcc produce some type of intermediate file that >> could be used to generate a cscope like database. (Perhaps a better >> way to phrase the question is 'which intermediate file, if any, could >> be used') I have a few issues with cscope that I keep hoping to solve >> somehow someday. Here is a short list of them: > > If you mean: is there an option to do that today, then, no, there > isn't. If you mean: could it be done in some way, then, yes. This > sounds like a natural application for a compiler plugin. > Speaking about plugins, last time (a few month ago) I played with them, I had to move the PLUGIN_FINISH_TYPE invocation location to be able to handle other type that struct or unions. That said, there is certainly something I did wrong to catch enum declaration or other type. Why has it not been place in a more central place, like declspecs_add_type() ? Thanks, - Arnaud > Ian >
soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type
On x86_64-apple-darwin10, we see the warnings... /Users/howarth/darwin_objdir/./gcc/xgcc -B/Users/howarth/darwin_objdir/./gcc/ -B/Users/howarth/dist/x86_64-apple-darwin10.5.0/bin/ -B/Users/howarth/dist/x86_64-apple-darwin10.5.0/lib/ -isystem /Users/howarth/dist/x86_64-apple-darwin10.5.0/include -isystem /Users/howarth/dist/x86_64-apple-darwin10.5.0/sys-include-g -O2 -m32 -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fPIC -pipe -g -DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -fno-stack-protector -I. -I. -I../../.././gcc -I../../../../gcc/libgcc -I../../../../gcc/libgcc/. -I../../../../gcc/libgcc/../gcc -I../../../../gcc/libgcc/../include -DHAVE_CC_TLS -DUSE_EMUTLS -Wno-missing-prototypes -Wno-type-limits -o fixtfsi.o -MT fixtfsi.o -MD -MP -MF fixtfsi.dep -fexceptions -c ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c -fvisibility=hidden -DHIDE_EXPORTS ../../../../gcc/libgcc/../gcc/config/soft-fp/unordtf2.c: In function '__unordtf2': ../../../../gcc/libgcc/../gcc/config/soft-fp/unordtf2.c:39:1: warning: variable 'B_s' set but not used [-Wunused-but-set-variable] ../../../../gcc/libgcc/../gcc/config/soft-fp/unordtf2.c:38:1: warning: variable 'A_s' set but not used [-Wunused-but-set-variable] ../../../../gcc/libgcc/../gcc/config/soft-fp/multf3.c: In function '__multf3': ../../../../gcc/libgcc/../gcc/config/soft-fp/multf3.c:47:3: warning: 'R_e' may be used uninitialized in this function [-Wuninitialized] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c: In function '__fixtfsi': ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixtfsi.c:44:3: warning: left shift count >= width of type [enabled by default] as well as /libgcc/../gcc/config/soft-fp/fixunstfsi.c -fvisibility=hidden -DHIDE_EXPORTS /Users/howarth/darwin_objdir/./gcc/xgcc -B/Users/howarth/darwin_objdir/./gcc/ -B/Users/howarth/dist/x86_64-apple-darwin10.5.0/bin/ -B/Users/howarth/dist/x86_64-apple-darwin10.5.0/lib/ -isystem /Users/howarth/dist/x86_64-apple-darwin10.5.0/include -isystem /Users/howarth/dist/x86_64-apple-darwin10.5.0/sys-include-g -O2 -m32 -O2 -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fPIC -pipe -g -DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -fno-stack-protector -I. -I. -I../../.././gcc -I../../../../gcc/libgcc -I../../../../gcc/libgcc/. -I../../../../gcc/libgcc/../gcc -I../../../../gcc/libgcc/../include -DHAVE_CC_TLS -DUSE_EMUTLS -Wno-missing-prototypes -Wno-type-limits -o floatsitf.o -MT floatsitf.o -MD -MP -MF floatsitf.dep -fexceptions -c ../../../../gcc/libgcc/../gcc/config/soft-fp/floatsitf.c -fvisibility=hidden -DHIDE_EXPORTS ../../../gcc/libgcc/../gcc/config/soft-fp/floatunsitf.c: In function '__floatunsitf': ../../../gcc/libgcc/../gcc/config/soft-fp/floatunsitf.c:45:3: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c: In function '__fixunstfsi': ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: warning: left shift count >= width of type [enabled by default] ../../../../gcc/libgcc/../gcc/config/soft-fp/fixunstfsi.c:44:3: war
Question on ARM legitimate address for DImode
Hi, While working on a bug, I found some code in ARM port that I don't understand. In ARM_LEGITIMIZE_RELOAD_ADDRESS and arm_legitimize_address, we allow a very small offset for DImode addressing. In ARM_LEGITIMIZE_RELOAD_ADDRESS: if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT)) \ low = ((val & 0xf) ^ 0x8) - 0x8; \ In arm_legitimize_address /* VFP addressing modes actually allow greater offsets, but for now we just stick with the lowest common denominator. */ if (mode == DImode || ((TARGET_SOFT_FLOAT || TARGET_VFP) && mode == DFmode)) { low_n = n & 0x0f; n &= ~0x0f; if (low_n > 4) { n += 16; low_n -= 16; } } AFAIK, we could use two LDRs, or one LDRD, or one VLDR to access DImode in memory when the address is in the form of (REG + CONST_INT). The offset ranges for these three cases are: LDR -4095,4091 LDRD -255,255 VLDR -1020,1020 && (ADDR & 3) == 0 so the lowest common denominator is -1020,1020 && (ADDR & 3) == 0 if ! TARGET_LDRD -255,255 && (ADDR & 3) == 0 if TARGET_LDRD Both are much larger than what we have now in the ARM port. Did I miss some other cases? That two pieces of code are rather old (more than 15 years). The main code was added by svn: revision 7536 by erich, Thu Jun 23 16:02:41 1994 UTC in arm.h git: fac435147512513c1b8fa55bee061c8e3a767ba9 log: (LEGITIMIZE_ADDRESS): Push constants that will never be legitimate -- symbols and labels -- into registers. Handle DImode better. I checked out that revision to take a look but didn't find an obvious reason for such small index range. Did I miss something tricky? If there is nothing I missed, I'd like to propose the attached patch. Regards, -- Jie Zhang Index: config/arm/arm.c === --- config/arm/arm.c (revision 168085) +++ config/arm/arm.c (working copy) @@ -6221,13 +6221,9 @@ arm_legitimize_address (rtx x, rtx orig_ if (mode == DImode || ((TARGET_SOFT_FLOAT || TARGET_VFP) && mode == DFmode)) { - low_n = n & 0x0f; - n &= ~0x0f; - if (low_n > 4) - { - n += 16; - low_n -= 16; - } + HOST_WIDE_INT mask = (TARGET_LDRD ? 0xfc : 0x3fc); + low_n = (n >= 0 ? (n & mask) : -((-n) & mask)); + n -= low_n; } else { Index: config/arm/arm.h === --- config/arm/arm.h (revision 168085) +++ config/arm/arm.h (working copy) @@ -1283,7 +1283,12 @@ enum reg_class HOST_WIDE_INT low, high; \ \ if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT)) \ - low = ((val & 0xf) ^ 0x8) - 0x8; \ + { \ + /* VFP addressing modes actually allow greater offsets, but for \ + now we just stick with the lowest common denominator. */ \ + HOST_WIDE_INT mask = (TARGET_LDRD ? 0xfc : 0x3fc); \ + low = (val >= 0 ? (val & mask) : -((-val) & mask)); \ + } \ else if (TARGET_MAVERICK && TARGET_HARD_FLOAT) \ /* Need to be careful, -256 is not a valid offset. */ \ low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
Re: How can I add 256bits register file to a MIPS port?
Liu writes: > I need add 256bits-register support for our MIPS-based > processor, so I add some codes. > When I build gcc and test it, get a error "unable to find a > register to spill in class 'XX_REGS'" > can you tell me how to add 256bits register file to a MIPS port? > > Thanks! > > codes: > gcc/config/mips/constraints.md : > (define_register_constraint 'Z' 'XX_REGS' > '@internal') > > gcc/config/mips/mips-ftypes.def : > DEF_MIPS_FTYPE (2, (UV32QI, UV32QI, UV32QI)) > DEF_MIPS_FTYPE (2, (V32QI, V32QI, V32QI)) > > gcc/config/mips/mips.h : > #define FIXED_REGISTERS > /* XX regusters */ \ > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ > 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \ Setting them all as 1 in FIXED_REGISTERS means that gcc can't use them. Ian