Re: Storing 16bit values in upper part of 32bit registers
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
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
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
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