Bug 16894 - far/section attributes on function parameters, typedefs, and literals
Summary: far/section attributes on function parameters, typedefs, and literals
Status: RESOLVED WONTFIX
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 3.2.2
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-08-06 08:23 UTC by Mark Whitis
Modified: 2008-08-07 13:11 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Whitis 2004-08-06 08:23:03 UTC
These bugs concern gcc's failure to accept memory space attributes (near, far,
and section) in several places:
   - On parameters to functions
   - on typedefs
   - on string literals
gcc only takes near and far keywords on functions and severely
restricts use of data.
On many commercial compilers, one would just declare functions
like 
   printf(const char far *fmt, ....)
And the compler pass in a far address and would let compiler helper 
functions do the work of retreiving the data.   But on gcc variants,
this not only doesn't work but the obvious workarounds don't work either.

This applies particularly to the various 8 and 16 bit ports of gcc that are
mainly used for embedded use:
  - 8086    16 bit address, 16 bit segment
  - 8051    Harvard architecture
            Synthetic 24/32 bit pointers used on commercial compiler
            which, when used with compiler helper functions, allow
            pointers that can point into either code space or data.
            In addition, bank switching is used on some systems.
  - 68HC11/12 
            Bank switching. 
I am filling this as a bug against the main gcc since many gcc forks
have the same problem.

However, the near/far issues also apply to newer 64 bit processors.  It would
be very wasteful to compile most applications with 64 bit pointers.  Even for
some applications that have large data, it might be best to mix 32 and 64 bit
pointers if you have a few large data structures and the rest fall with
32 bit space (have to copy data before passing to 32 bit functions, though).


The 9S12DP256 single chip micro (68HC12 family) has the following memory
layout:
   0000-03FFF  Ram and registers
   4000-7FFFF  Fixed EEPROM
   8000-BFFFF  Window into 256K of bank switched EEPROM
   C000-CFFFF  Fixed EEPROM

Now, I am trying to port an application that has a lot of "const" data.  It
won't fit comfortably in ram or the fixed windows (or will displace
things that really need to be there.   In this particular case, memory 
pressure can be relieved by moving two classes of const data into
bank switched memory:
   - printf() format strings
   = a single type of structure that describes a user settable parameter.

Other compilers have much better support for the near/far keyword.  All 8086
compilers I have ever used, for example, allowed pointers, typedefs,
pointers passed to functions, etc. to by declared as "far".
#define far __attribute__((far))
#define FIXED_BANK0 __asttribute((section("fixed0")))
#define BANK30 __attribute((section("bank30")))
#define BAKK31 __attribute((section("bank31")))
char far *foo;   // pointer to far data


char bank31 * bank 30 foo2; 
     // Pointer stored in bank 30 pointing to data in bank 31 


void yyyprintf(char BANK30 *fmt, ...);
   // Pass in 16 bit pointer only valid for bank30

char BANK30 fmt1[] = "hello, world");
yyyprintf(fmt1);
yyyprintf(BANK30 "hello, world\n");

in a pointer to the wrong section it won't
  
#define xxxprintf(fmt,...) emstdio_printf(copy_format(fmt), ##__VA_ARGS__);

// function itself must to be loaded in non-bank-switched section
// If you leave off tha attribute it will compile ok and might
// even work but there is no type checking so you could pass
// a pointer to the wrong bank.
FIXED_BANK char *copy_format(char __attribute__((section("bank30") *fmt)
{
   static buf[256];   //in non-bank-switched-section
   // switch banks

   // In case relocation gets confused about high order bits and gives
   // the lower 16 bits of linear address or the offset from the beginning
   // of the bank instead of the address where data appears in bank window
   fmt &= 0x3FFF;
   fmt &= 0x8000;

   memcpy(buf,fmt,sizeof(buf));

   // restore bank
   return(buf);
}

const char zot30[] __attribute__((section("bank30"))) = "Put me in Bank30\n";
void foo300()
{
  xxxprintf("hello, world\n");
  xxxprintf("hello, world %d\n",1);
  xxxprintf("hello, world %d %d\n",1,2);
}

There should also be a __attribute__((section("void"))) or similar that
will mix with any other section, to be used similarly to void pointers
where you know what you are doing.

It would be nice to have a directive that allowed data to be placed
in specific sections by default
   #pragma gcc section rodata bank30
        // data the compiler would otherwise put in rodata goes in bank30
        // instead.
   #pragma gcc section text bank31
   #pragma gcc section bss bank32
   #pragma gcc section data bank33
Or better yet
   pragma "gcc section text bank30" {
      // all code here is affected
   }
Yeah, I know what you can do in linker scripts.  It is a poor substitute.

And the compiler should generate code to use compiler helper functions
to access far data on systems where the processor itself can't handle
them.
Comment 1 Andrew Pinski 2004-08-06 15:28:49 UTC
IIRC the x86 (16bit edition) supports these attributes on those places so these are all target problems.
Comment 2 Manuel López-Ibáñez 2007-11-14 02:07:51 UTC
Maybe we should close this. If someone is interested on this, they should fill bugs against specific targets.
Comment 3 Manuel López-Ibáñez 2008-08-07 13:11:28 UTC
4 years old, no activity, unconfirmed. Please fill bugs for specific targets with testcases so the target maintainers are aware of this issue.