Re: Storing 16bit values in upper part of 32bit registers

2009-11-05 Thread H. Peter Anvin
On 10/15/2009 08:56 AM, Richard Henderson wrote:
> On 10/15/2009 07:41 AM, Markus L wrote:
>> However the IS is designed so that it is beneficial to to store 16bit
>> values in the high part of the registers (rNh) and also the calling
>> conventions that we want follow require 16bit values to be passed and
>> returned in rNh.
>>
>> What would be the "proper way" make the compiler use the upper parts
>> of these registers for the 16bit operands?
> 
> This feature is going to be difficult, but not impossible, and unless 
> your ISA has some really odd features I won't vouch for the code quality.
> 
> You say you want to canonically represent HImode in the high-part of the 
> register.  Additionally, you'll have to represent QImode in the 
> high-part (if not further in the high byte).
> 
> You'll need to follow the mips port and define TRULY_NOOP_TRUNCATION and 
> the associated truncMN2 patterns.
> 
> If you do all this, you won't have to do anything with FUNCTION_VALUE 
> etc at all.
> 

Sorry for a *way* *late* reply to this, but wouldn't it also work to
model the register file as a set of 16-bit registers (since that's what
you really have -- individually addressable 16-bit registers) and
exclude SImode values from register pairs which are not aligned.  Then
one can simply prefer the high 16-bit registers to the low 16-bit
registers in the register priority sequence.

I'm assuming there is something wrong with this, but I'm kind of curious
as to what it would be.

-hpa


Re: Storing 16bit values in upper part of 32bit registers

2009-10-15 Thread Richard Henderson

On 10/15/2009 07:41 AM, Markus L wrote:

However the IS is designed so that it is beneficial to to store 16bit
values in the high part of the registers (rNh) and also the calling
conventions that we want follow require 16bit values to be passed and
returned in rNh.

What would be the "proper way" make the compiler use the upper parts
of these registers for the 16bit operands?


This feature is going to be difficult, but not impossible, and unless 
your ISA has some really odd features I won't vouch for the code quality.


You say you want to canonically represent HImode in the high-part of the 
register.  Additionally, you'll have to represent QImode in the 
high-part (if not further in the high byte).


You'll need to follow the mips port and define TRULY_NOOP_TRUNCATION and 
the associated truncMN2 patterns.


If you do all this, you won't have to do anything with FUNCTION_VALUE 
etc at all.



r~


Re: Storing 16bit values in upper part of 32bit registers

2009-10-15 Thread sumanth

Hi Marcus,
   Though I am novice in gcc , I think I can answer your 
question.
   As far as I know, your load instruction will take care 
of this issue.
   You need to restrict your load instruction so that it 
will place your return value of function in lower register.
   So Ideally , the instruction will be like , load r0h 
with the content pointer by that instruction. ( Assuming you have  16 
bit load instruction with 16-bit loading capability)


Thanks,
Sumanth G

Markus L wrote:

Hi,

I am working with an architecture where the 32bit registers (rN) are
divided into high (rNh) and low (rNl) 16bit sub registers that can in
principle be individually accessed by the instructions in the IS.
However the IS is designed so that it is beneficial to to store 16bit
values in the high part of the registers (rNh) and also the calling
conventions that we want follow require 16bit values to be passed and
returned in rNh.

What would be the "proper way" make the compiler use the upper parts
of these registers for the 16bit operands?

Currently this is done by having the registers in two register classes
('full' and 'high_only') and printing the 'h' in the output template
when the constraint matches the 'high_only' class. This however causes
problems when converting between 16 and 32bit operands. One annoying
example is returning scalar values. E.g. assume that a 32bit variable
(long) is assigned to a 16bit variable (int) like in

int foo(void)
{
  long sum;
  ...
  return (int)sum;
}

then we want the low part of sum to be moved to the high part of the
return register r0h. However TARGET_FUNCTION_VALUE only seem to allow
me to return the RTX for register r0 but not the subreg for r0h so the
compiler will not emit the necessary RTL to move the value from the
low part of sum to r0h before the return. This (and probably many
other issues that I am about to discover) makes me think that maybe
this is not the ideal way to do this. I have searched the available
ports but have not been able to find any which seem to use its
registers in a similar way. Any advice or pointers to code to look
into would be much appreciated.

Thanks in advance.

/Markus


  





Storing 16bit values in upper part of 32bit registers

2009-10-15 Thread Markus L
Hi,

I am working with an architecture where the 32bit registers (rN) are
divided into high (rNh) and low (rNl) 16bit sub registers that can in
principle be individually accessed by the instructions in the IS.
However the IS is designed so that it is beneficial to to store 16bit
values in the high part of the registers (rNh) and also the calling
conventions that we want follow require 16bit values to be passed and
returned in rNh.

What would be the "proper way" make the compiler use the upper parts
of these registers for the 16bit operands?

Currently this is done by having the registers in two register classes
('full' and 'high_only') and printing the 'h' in the output template
when the constraint matches the 'high_only' class. This however causes
problems when converting between 16 and 32bit operands. One annoying
example is returning scalar values. E.g. assume that a 32bit variable
(long) is assigned to a 16bit variable (int) like in

int foo(void)
{
  long sum;
  ...
  return (int)sum;
}

then we want the low part of sum to be moved to the high part of the
return register r0h. However TARGET_FUNCTION_VALUE only seem to allow
me to return the RTX for register r0 but not the subreg for r0h so the
compiler will not emit the necessary RTL to move the value from the
low part of sum to r0h before the return. This (and probably many
other issues that I am about to discover) makes me think that maybe
this is not the ideal way to do this. I have searched the available
ports but have not been able to find any which seem to use its
registers in a similar way. Any advice or pointers to code to look
into would be much appreciated.

Thanks in advance.

/Markus