avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] [avr-as]: How to assembler a 24-bit integer?


From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] [avr-as]: How to assembler a 24-bit integer?
Date: Tue, 01 Nov 2011 16:28:03 +0100
User-agent: Thunderbird 2.0.0.24 (X11/20100302)

Björn Haase wrote:
> Am 30.10.2011 21:43, schrieb Georg-Johann Lay:
>> Hi,
>>
>> I need to assemble 24-bit integers in avr-as as if they were generated
>> from C code like
>>
>>     const __pgmx char c = 1;
>>     const __pgmx char *pc = &c;
>>
>> where __pgmx generates 24-bit addresses.
>>
>> If pc just held a 16 bit address the code was
>>
>>     .global   pc
>>         .data
>>         .type   pc, @object
>>         .size   pc, 2
>>     pc:
>>         .word c
>>
>> Now the question is: How to write down a 24-bit symbol?
>>
>>     .global   pc
>>         .data
>>         .type   pc, @object
>>         .size   pc, 3
>>     pc:
>>         .word c
>>         .byte hlo8(c) ??? error from as
>>
>> gives an error from the assembler, same for .byte hh8(c)
>>
>> Moreover, a const-integer offset can be added to c:
>>
>>         .word c+2
>>         .byte hlo8(c+2) ??? error from as
>>
>> What is the right way to write it own?
>>
>> Many thanks,
>>
>> Johann
>>
>>
> Dear Johann,
> 
> in order to initialize memory with 24 bit "data type" addresses, a
> corresponding 24 bit "relocation" would be required in the ".elf" format
> description. I.e. in order to realize what you want, a new ".elf" object
> format version would have to be defined.
> 
> In case of 24 bit "program memory type" addresses, you could simply use
> 16 bit addresses. The linker will generate jump stubs. The 16 bit
> address will then point to the jump instruction in the first 128k of the
> memory.

No, not in this specific case because byte-addresses to data object is needed
and not a word-address to some function.

For data objects, jump stubs make no sense.

> For now, the reccommendation, I could give you is, to try to place all
> of your "data type" constant tables in the first 64k of memory by use of
> an appropriate linker script. As long as they reside within the first
> 64k, a 16 bit pointer will do.

As Jörg already wrote, this is not for user code or some application but for a
avr-gcc extension to support 24-bit wide pointer types.

The corresponding function that assembles respective objects is
  $GCC-SOURCE/gcc/config/avr.c::avr_assemble_integer()

static bool
avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
  if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
      && text_segment_operand (x, VOIDmode))
    {
      fputs ("\t.word\tgs(", asm_out_file);
      output_addr_const (asm_out_file, x);
      fputs (")\n", asm_out_file);
      return true;
    }
  return default_assemble_integer (x, size, aligned_p);
}

Up to now, the only special part therein is gs() magic for function address
like in following C code:

extern void foo ();
void * pf = foo;

However, what is needed is code that can assemble a 24-bit address like so:

   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
       && text_segment_operand (x, VOIDmode))
     {
       fputs ("\t.word\tgs(", asm_out_file);
       output_addr_const (asm_out_file, x);
       fputs (")\n", asm_out_file);
       return true;
     }
+  else if (GET_MODE (x) == PSImode)
+    {
+      default_assemble_integer (avr_const_address_lo16 (x),
+                                GET_MODE_SIZE (HImode), aligned_p);
+
+      fputs ("\t.warning\t\"24-bit address needs assembler extension for hh8(",
+             asm_out_file);
+      output_addr_const (asm_out_file, x);
+      fputs (")\"\n", asm_out_file);
+
+      fputs ("\t.byte\t0\t" ASM_COMMENT_START " hh8(", asm_out_file);
+      output_addr_const (asm_out_file, x);
+      fputs (")\n", asm_out_file);
+
+      return true;
+    }

   return default_assemble_integer (x, size, aligned_p);
 }

PSImode is the new 24-bit machine mode. The code

const __pgmx char c = 1;
const __pgmx char *pc = &c;

from above is assembled as:

.global pc
        .data
        .type   pf, @object
        .size   pf, 3
pc:
        .word   c
        .warning "24-bit address needs assembler extension for hh8(c)"
        .byte 0 ; hh8(c)

> The other option, that you might try to use is to use a 32 bit variable,
> i.e. by using
>     .long c

As a true 24-bit type/address is needed: Could you implement such an extension
Björn?

The most general approach would be to support relocation modifiers with
canonical names already fully supported in instructions like

        .byte   lo8 (c + offset)
        .byte   hi8 (c + offset)
        .byte   hlo8 (c + offset) and/or hh8 (c + offset)
        .byte   hhi8 (c + offset)

No problem if offset=0 has to be mentioned explicitly.  I saw already users
trying to write similar code in their assembler programs (for whatever reason)
like .byte hi8 (c)

The semantics is obvious and for someone like you who is familiar with binutils
internals it's just a copy-and-paste extension I guess.

Unfortunately, I have no FSF assignment for binutils and am not familiar with
binutils internals.

Or maybe Eric can have a look if the likes to do the extension? Should be
straight forward for a avr-binutils maintainer ;-)

Johann

--

FYI, as there is the plan to have 24-bit pointer type, I'd like to expose the
24-bit type for general arithmetic usage as 24-bit integers.  Arithmetic
support is way more than what is needed for a pointer-only support, but the
implementation is straight forward and no GCC front-/middle-end extension is
needed:

http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02852.html




reply via email to

[Prev in Thread] Current Thread [Next in Thread]