Re: Help with reloading

2010-12-20 Thread Mohamed Shafi
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?

2010-12-20 Thread Bingfeng Mei

> -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.

2010-12-20 Thread Claudiu Zissulescu
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?

2010-12-20 Thread Ulrich Weigand
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

2010-12-20 Thread Jeff Law

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

2010-12-20 Thread Mohamed Shafi
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

2010-12-20 Thread Jeff Law

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

2010-12-20 Thread Ian Lance Taylor
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

2010-12-20 Thread Diego Novillo
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?

2010-12-20 Thread Liu
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

2010-12-20 Thread Arnaud Lacombe
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

2010-12-20 Thread Jack Howarth
  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

2010-12-20 Thread Jie Zhang

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?

2010-12-20 Thread Ian Lance Taylor
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