public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Adjust offset of array reference in named address space
@ 2021-01-08 23:23 Tucker Kern
  2021-01-11  7:49 ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Tucker Kern @ 2021-01-08 23:23 UTC (permalink / raw)
  To: Tucker Kern via Gcc

Hi,

I'm implementing named addresses spaces for a Harvard architecture machine
to support copying data from instruction memory to data memory. This is
achieved via a special instruction. e.g. think AVR and progmem/__flash.

However, the instruction memory is narrower than the data memory (12 vs 16
bits) on this machine. So a single data word is split across 2 instruction
words. When copied from IMEM to DMEM the two parts are combined via SHIFT +
OR patterns.

This is all working fine for regular variables (i.e. int som_var), but it
falls apart for array references (i.e. some_array[1]). Since the data is
stored across 2 IMEM words, I need to scale the calculated offset of each
array reference by 2. e.g. array[0] is actually stored in imem[0] & imem[1]
and array[1] is stored in imem[2] & imem[3].

e.g.
static __imem int imem_array[2];
return imem_array[1];

// needs to generate a symbol reference like
&imem_array.869+2

Similarly if the array index was a function parameter, I need to scale the
parameter by 2.
__imem int imem_array[2];
int some_func(int a)
{
  // a needs to be scaled by 2 when generating RTL/ASM
  return imem_array[a];
}

I haven't found any target hooks that would allow me to override the offset
calculation. Originally I thought I could handle it in a splitter but this
approach didn't work for the function parameter example as I ended up
scaling the entire address instead of just the offset.

I had another thought of using a combo of
TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS and
TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P to scale the offset and mark it as
adjusted but I don't think this combo will work in the end.

Is there any way to achieve this?

Thanks,
Tucker

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Adjust offset of array reference in named address space
  2021-01-08 23:23 Adjust offset of array reference in named address space Tucker Kern
@ 2021-01-11  7:49 ` Richard Biener
  2021-01-12 15:28   ` Tucker Kern
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Biener @ 2021-01-11  7:49 UTC (permalink / raw)
  To: Tucker Kern; +Cc: Tucker Kern via Gcc

On Sat, Jan 9, 2021 at 12:24 AM Tucker Kern via Gcc <gcc@gcc.gnu.org> wrote:
>
> Hi,
>
> I'm implementing named addresses spaces for a Harvard architecture machine
> to support copying data from instruction memory to data memory. This is
> achieved via a special instruction. e.g. think AVR and progmem/__flash.
>
> However, the instruction memory is narrower than the data memory (12 vs 16
> bits) on this machine. So a single data word is split across 2 instruction
> words. When copied from IMEM to DMEM the two parts are combined via SHIFT +
> OR patterns.
>
> This is all working fine for regular variables (i.e. int som_var), but it
> falls apart for array references (i.e. some_array[1]). Since the data is
> stored across 2 IMEM words, I need to scale the calculated offset of each
> array reference by 2. e.g. array[0] is actually stored in imem[0] & imem[1]
> and array[1] is stored in imem[2] & imem[3].

So you are saying that a 16bit data word in IMEM is actually two 12bit
data words (supposedly only the lower 8 bits used in each) and thus the
array contains "padding"?  That's not really supported and is also not
the scope of named address spaces.  I'd suggest you go down the route
of providing intrinsics for the transfer of data instead which could resort
to target specific builtin functions.

> e.g.
> static __imem int imem_array[2];
> return imem_array[1];
>
> // needs to generate a symbol reference like
> &imem_array.869+2
>
> Similarly if the array index was a function parameter, I need to scale the
> parameter by 2.
> __imem int imem_array[2];
> int some_func(int a)
> {
>   // a needs to be scaled by 2 when generating RTL/ASM
>   return imem_array[a];
> }
>
> I haven't found any target hooks that would allow me to override the offset
> calculation. Originally I thought I could handle it in a splitter but this
> approach didn't work for the function parameter example as I ended up
> scaling the entire address instead of just the offset.
>
> I had another thought of using a combo of
> TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS and
> TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P to scale the offset and mark it as
> adjusted but I don't think this combo will work in the end.
>
> Is there any way to achieve this?
>
> Thanks,
> Tucker

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Adjust offset of array reference in named address space
  2021-01-11  7:49 ` Richard Biener
@ 2021-01-12 15:28   ` Tucker Kern
  2021-01-12 15:37     ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Tucker Kern @ 2021-01-12 15:28 UTC (permalink / raw)
  To: Richard Biener; +Cc: Tucker Kern via Gcc

> So you are saying that a 16bit data word in IMEM is actually two 12bit
> data words (supposedly only the lower 8 bits used in each) and thus the
> array contains "padding"?

Effectively yes. The assembler handles dividing constants into their LSB
and MSB components. I have insn patterns and splitters defined that emit
the correct instructions to read and "pack" the value into a register or
generic memory location.

All I really need at this point is a means to augment how addresses (e.g.
array offsets or struct members) are calculated in a non-generic address
space. This doesn't feel like a far fetched idea as GCC currently supports
address space specific legitimization and modes.

On Mon, Jan 11, 2021 at 12:50 AM Richard Biener <richard.guenther@gmail.com>
wrote:

> On Sat, Jan 9, 2021 at 12:24 AM Tucker Kern via Gcc <gcc@gcc.gnu.org>
> wrote:
> >
> > Hi,
> >
> > I'm implementing named addresses spaces for a Harvard architecture
> machine
> > to support copying data from instruction memory to data memory. This is
> > achieved via a special instruction. e.g. think AVR and progmem/__flash.
> >
> > However, the instruction memory is narrower than the data memory (12 vs
> 16
> > bits) on this machine. So a single data word is split across 2
> instruction
> > words. When copied from IMEM to DMEM the two parts are combined via
> SHIFT +
> > OR patterns.
> >
> > This is all working fine for regular variables (i.e. int som_var), but it
> > falls apart for array references (i.e. some_array[1]). Since the data is
> > stored across 2 IMEM words, I need to scale the calculated offset of each
> > array reference by 2. e.g. array[0] is actually stored in imem[0] &
> imem[1]
> > and array[1] is stored in imem[2] & imem[3].
>
> So you are saying that a 16bit data word in IMEM is actually two 12bit
> data words (supposedly only the lower 8 bits used in each) and thus the
> array contains "padding"?  That's not really supported and is also not
> the scope of named address spaces.  I'd suggest you go down the route
> of providing intrinsics for the transfer of data instead which could resort
> to target specific builtin functions.
>
> > e.g.
> > static __imem int imem_array[2];
> > return imem_array[1];
> >
> > // needs to generate a symbol reference like
> > &imem_array.869+2
> >
> > Similarly if the array index was a function parameter, I need to scale
> the
> > parameter by 2.
> > __imem int imem_array[2];
> > int some_func(int a)
> > {
> >   // a needs to be scaled by 2 when generating RTL/ASM
> >   return imem_array[a];
> > }
> >
> > I haven't found any target hooks that would allow me to override the
> offset
> > calculation. Originally I thought I could handle it in a splitter but
> this
> > approach didn't work for the function parameter example as I ended up
> > scaling the entire address instead of just the offset.
> >
> > I had another thought of using a combo of
> > TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS and
> > TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P to scale the offset and mark it as
> > adjusted but I don't think this combo will work in the end.
> >
> > Is there any way to achieve this?
> >
> > Thanks,
> > Tucker
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Adjust offset of array reference in named address space
  2021-01-12 15:28   ` Tucker Kern
@ 2021-01-12 15:37     ` Richard Biener
  2021-01-14  3:56       ` Tucker Kern
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Biener @ 2021-01-12 15:37 UTC (permalink / raw)
  To: Tucker Kern; +Cc: Tucker Kern via Gcc, Joseph S. Myers

On Tue, Jan 12, 2021 at 4:29 PM Tucker Kern <tuckkern@gmail.com> wrote:
>
> > So you are saying that a 16bit data word in IMEM is actually two 12bit
> > data words (supposedly only the lower 8 bits used in each) and thus the
> > array contains "padding"?
>
> Effectively yes. The assembler handles dividing constants into their LSB and MSB components. I have insn patterns and splitters defined that emit the correct instructions to read and "pack" the value into a register or generic memory location.
>
> All I really need at this point is a means to augment how addresses (e.g. array offsets or struct members) are calculated in a non-generic address space. This doesn't feel like a far fetched idea as GCC currently supports address space specific legitimization and modes.

I think you'd need to hook this up in structure layouting which then
runs into the issue that
the address space is a qualifier and GCC internals expect layouts to
be compatible between
qualified and unqualified types.  Also all target hooks in the layout
code mostly deal with
bitfields only.

The offset is computed via get_inner_reference from expand_expr_real_*
so I don't
see a good way to handle this correctly.  But maybe Joseph has an idea.

Richard.

> On Mon, Jan 11, 2021 at 12:50 AM Richard Biener <richard.guenther@gmail.com> wrote:
>>
>> On Sat, Jan 9, 2021 at 12:24 AM Tucker Kern via Gcc <gcc@gcc.gnu.org> wrote:
>> >
>> > Hi,
>> >
>> > I'm implementing named addresses spaces for a Harvard architecture machine
>> > to support copying data from instruction memory to data memory. This is
>> > achieved via a special instruction. e.g. think AVR and progmem/__flash.
>> >
>> > However, the instruction memory is narrower than the data memory (12 vs 16
>> > bits) on this machine. So a single data word is split across 2 instruction
>> > words. When copied from IMEM to DMEM the two parts are combined via SHIFT +
>> > OR patterns.
>> >
>> > This is all working fine for regular variables (i.e. int som_var), but it
>> > falls apart for array references (i.e. some_array[1]). Since the data is
>> > stored across 2 IMEM words, I need to scale the calculated offset of each
>> > array reference by 2. e.g. array[0] is actually stored in imem[0] & imem[1]
>> > and array[1] is stored in imem[2] & imem[3].
>>
>> So you are saying that a 16bit data word in IMEM is actually two 12bit
>> data words (supposedly only the lower 8 bits used in each) and thus the
>> array contains "padding"?  That's not really supported and is also not
>> the scope of named address spaces.  I'd suggest you go down the route
>> of providing intrinsics for the transfer of data instead which could resort
>> to target specific builtin functions.
>>
>> > e.g.
>> > static __imem int imem_array[2];
>> > return imem_array[1];
>> >
>> > // needs to generate a symbol reference like
>> > &imem_array.869+2
>> >
>> > Similarly if the array index was a function parameter, I need to scale the
>> > parameter by 2.
>> > __imem int imem_array[2];
>> > int some_func(int a)
>> > {
>> >   // a needs to be scaled by 2 when generating RTL/ASM
>> >   return imem_array[a];
>> > }
>> >
>> > I haven't found any target hooks that would allow me to override the offset
>> > calculation. Originally I thought I could handle it in a splitter but this
>> > approach didn't work for the function parameter example as I ended up
>> > scaling the entire address instead of just the offset.
>> >
>> > I had another thought of using a combo of
>> > TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS and
>> > TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P to scale the offset and mark it as
>> > adjusted but I don't think this combo will work in the end.
>> >
>> > Is there any way to achieve this?
>> >
>> > Thanks,
>> > Tucker

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Adjust offset of array reference in named address space
  2021-01-12 15:37     ` Richard Biener
@ 2021-01-14  3:56       ` Tucker Kern
  0 siblings, 0 replies; 5+ messages in thread
From: Tucker Kern @ 2021-01-14  3:56 UTC (permalink / raw)
  To: Richard Biener; +Cc: Tucker Kern via Gcc, Joseph S. Myers

Richard,

As always thanks for the insight. I'll take a look at those functions as
well.

-Tucker

On Tue, Jan 12, 2021 at 8:37 AM Richard Biener <richard.guenther@gmail.com>
wrote:

> On Tue, Jan 12, 2021 at 4:29 PM Tucker Kern <tuckkern@gmail.com> wrote:
> >
> > > So you are saying that a 16bit data word in IMEM is actually two 12bit
> > > data words (supposedly only the lower 8 bits used in each) and thus the
> > > array contains "padding"?
> >
> > Effectively yes. The assembler handles dividing constants into their LSB
> and MSB components. I have insn patterns and splitters defined that emit
> the correct instructions to read and "pack" the value into a register or
> generic memory location.
> >
> > All I really need at this point is a means to augment how addresses
> (e.g. array offsets or struct members) are calculated in a non-generic
> address space. This doesn't feel like a far fetched idea as GCC currently
> supports address space specific legitimization and modes.
>
> I think you'd need to hook this up in structure layouting which then
> runs into the issue that
> the address space is a qualifier and GCC internals expect layouts to
> be compatible between
> qualified and unqualified types.  Also all target hooks in the layout
> code mostly deal with
> bitfields only.
>
> The offset is computed via get_inner_reference from expand_expr_real_*
> so I don't
> see a good way to handle this correctly.  But maybe Joseph has an idea.
>
> Richard.
>
> > On Mon, Jan 11, 2021 at 12:50 AM Richard Biener <
> richard.guenther@gmail.com> wrote:
> >>
> >> On Sat, Jan 9, 2021 at 12:24 AM Tucker Kern via Gcc <gcc@gcc.gnu.org>
> wrote:
> >> >
> >> > Hi,
> >> >
> >> > I'm implementing named addresses spaces for a Harvard architecture
> machine
> >> > to support copying data from instruction memory to data memory. This
> is
> >> > achieved via a special instruction. e.g. think AVR and
> progmem/__flash.
> >> >
> >> > However, the instruction memory is narrower than the data memory (12
> vs 16
> >> > bits) on this machine. So a single data word is split across 2
> instruction
> >> > words. When copied from IMEM to DMEM the two parts are combined via
> SHIFT +
> >> > OR patterns.
> >> >
> >> > This is all working fine for regular variables (i.e. int som_var),
> but it
> >> > falls apart for array references (i.e. some_array[1]). Since the data
> is
> >> > stored across 2 IMEM words, I need to scale the calculated offset of
> each
> >> > array reference by 2. e.g. array[0] is actually stored in imem[0] &
> imem[1]
> >> > and array[1] is stored in imem[2] & imem[3].
> >>
> >> So you are saying that a 16bit data word in IMEM is actually two 12bit
> >> data words (supposedly only the lower 8 bits used in each) and thus the
> >> array contains "padding"?  That's not really supported and is also not
> >> the scope of named address spaces.  I'd suggest you go down the route
> >> of providing intrinsics for the transfer of data instead which could
> resort
> >> to target specific builtin functions.
> >>
> >> > e.g.
> >> > static __imem int imem_array[2];
> >> > return imem_array[1];
> >> >
> >> > // needs to generate a symbol reference like
> >> > &imem_array.869+2
> >> >
> >> > Similarly if the array index was a function parameter, I need to
> scale the
> >> > parameter by 2.
> >> > __imem int imem_array[2];
> >> > int some_func(int a)
> >> > {
> >> >   // a needs to be scaled by 2 when generating RTL/ASM
> >> >   return imem_array[a];
> >> > }
> >> >
> >> > I haven't found any target hooks that would allow me to override the
> offset
> >> > calculation. Originally I thought I could handle it in a splitter but
> this
> >> > approach didn't work for the function parameter example as I ended up
> >> > scaling the entire address instead of just the offset.
> >> >
> >> > I had another thought of using a combo of
> >> > TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS and
> >> > TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P to scale the offset and mark
> it as
> >> > adjusted but I don't think this combo will work in the end.
> >> >
> >> > Is there any way to achieve this?
> >> >
> >> > Thanks,
> >> > Tucker
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-01-14  3:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-08 23:23 Adjust offset of array reference in named address space Tucker Kern
2021-01-11  7:49 ` Richard Biener
2021-01-12 15:28   ` Tucker Kern
2021-01-12 15:37     ` Richard Biener
2021-01-14  3:56       ` Tucker Kern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).