[Coco] GCC: DFLOAT / DIRECT_PAGE

John E. Malmberg wb8tyw at qsl.net
Sat Nov 15 01:08:00 EST 2003


David wrote:
> On Fri, Nov 14, 2003 at 11:31:41AM -0600, John E. Malmberg wrote:
> 
>>
>>
>>If I can do it, this is what I will do for direct_page:
>>
>>1. The compiler will treat it like a hint, just as register is a hint.
>>   This means that the compiler will prefer to use direct page addressing
>>   mode for the designated variable, but since it also has the absolute
>>   address for the variable, or a stack/register relative address for
>>   the variable, it can decide to use that instead.
>>
>>2. The compiler will default to treating the direct page pointer as
>>   what other platforms refer to as a frame pointer for stack variables
>>   that are in range.

When I wrote #2, I forgot about the 256 byte alignment issue.  That 
almost completely eliminates using it for stack variables.  But it is 
still fair game for static varaibles anywhere in the program.

> 
> Yes, but how to get the directive "direct" installed.  Won't this need
> to be installed as a reserved word?

No.  It would be installed as a GNU extention of either 
__mode__(direct_page, params...) or __attribute__(direct_page, params...)

Then for the cross compiler, there is a predefine of

#define direct_page(params...) __attribute__(direct_page, params...)

I do not have the syntax exactly right, but that is how GCC is 
implementing this feature for other targets.

> Check out the files c-parse* and
> also c-common.h, all in the gcc directory.  I really believe that this
> word will need to be added to all(?) these places.

I will look at them later, but from looking at the 68HC11 and the other
targets, it still looks like if the right stuff is put in the *6809* 
files, the compiler will be able to do it with out changing the common code.

> Also, as for using hints.  I believe that the usage of "direct" will
> need to be absolute.

A "direct" psect could be absolutely based, but since the compiler and 
linker already know how to deal with ones that are not, there is no 
reason to restrict them.

The compiler should already know how to put a psect at a fixed location.

> If it's defined, use direct referencing else use
> 16-bit.  At least, if we're dealing with linkable modules.  Let's look
> at the process of compiling a program.  If the compiler decides which
> mode to use in the assembler output, although it realizes the relative
> addresses for the variables in _this_ module, it cannot know the
> ultimate address in the final program.

The compiler knows the relative address, the linker knows the absolute 
address.  The mechanism is already there to figure it out.

If the compiler generates "direct" addresses, it will need to make sure 
that the direct register has the correct value, and that value will 
either be known at compile time, or supplied by the linker, or even the 
loader.

As far as the compiler needs to be concerned, a direct page reference is 
just a variant of index addressing.  And the compiler knows how to do that.

Generally a compiler, GCC included, groups code and data in to program 
sections, commonly called psects.

The direct page attribute applied to a psect that would have the 
requirement that it is aligned on a 256 byte boundary.

>  However, this is where the
> program code is generated.  Suppose we're doing "cc p1.c p2.c p3.c".
> Now, after the assembler source files are generated and the object
> modules are created, the linker will go through and first allocate all
> the direct-page variables (beginning with whatever might be in the
> lead-in module, then place the d-p variables of p1 above those.. dp of
> p2 above those.. then p3. Now, it goes back and, beginning at the next
> address above p3's last dp variables, it begins the same process with
> the non-dp variables.

No, the linker will collect all of the psects that have the direct page 
attribute and are compatable into one cluster, and fixup the symbol that 
the compiler initialized the direct page register.  Multiple clusters 
will be generated as needed.  An OS-9 compatable linker could know to 
put the static variables in one loadable modules, and the executable 
code in a set of other modules.

But here I am losing precision, because there are words that have 
different meanings.

> For this reason, it would be impossible for the compiler to
> automatically determine what would be DP at compile time.

The compiler knows that each direct page psect has an alignment of 256 
bytes.  Having it take advantage of this for stack variables may be a 
challenge, but is doable.

The compiler only needs to know the alignment of the direct page 
register.  The linker or the program loader.

> If we do provide our own assembler/linker, one thing would be needed.  I
> believe it was Mike Knudsen who mentioned that the MW linker did not
> warn you if you had more than 256 DP bytes.  The linker should
> check and warn you if more than this max was reached.  It shouldn't be a
> problem to implement, and would be a very good addition.

I have not used the MW linker, so I am not aware of it's limitations.

But there is no reason for their to only be one direct page section. 
There can be up to 256 of them, only one active at any given time.

If the compiler is working with direct page variables that are not in 
the same psect, it would know that it would need to use a different 
address mode for at least one.

This is something that the GCC compiler already should know how to do, 
and so should any linker that goes with it.

>>   A direct page reference, depending on the internals of the CPU may take
>>   one less clock cycle than an 8 bit stack or register offset.  I would need
>>   to look at the 6809 specs to see if this is the case.  The difference
>>   is that a register offset has to do an 8 bit fetch and 16 bit add, and
>>   a direct page reference just has to do an 8 bit fetch.
>>
>>3. The direct_page attribute for a variable name will be able to take
>>   a value indicating the program section that the variable will be in.
>>   The attributes of the program section will determine the real address
>>   of the program section.  GCC already knows how to do the program section
>>   part.
> 
> I'm not sure I understand what you're saying here.  And another thought
> just occurred to me.  I've been thinking in terms of all variables from
> all modules to be stored consecutively in one area.

That is a model for all static variables, for languages like BASIC.  For 
languages like C, that is not the case.  For reentrant code, variables 
go in and out of scope, and typically live only on the stack or in 
registers.

> This would be the case for OS9,

No, the case for OS9, unless OS9 reserves the direct page register for 
it's own use, would be for a program to have as many direct page 
sections as it needs.  These sections can be put at fixed memory 
locations by the linker, or at dynamic locations, where the compiler 
knows where they are.

> but for RS-BASIC programs, this would not be necessary.
> The only reason for this would be to utilize the DP function.
> Otherwise, it would not hurt for the variables to simply be stored at
> the end of the code for the module.

The static variables are are put in program sections with the same name, 
and the linker puts them in the data segment of the image.

The linker uses a process known as a fixup, to make sure that the 
compiler loads the direct page register before referencing the variables.

On some operating systems, the final fixups are done by the operating 
system when it loads an executable module into memory.


> I don't know about FLEX and other systems.
> 
> Actually, it just occurred to me that it might be difficult to use
> DP-referencing in BASIC.  For it to work, wouldn't we have to insure
> that the variables began on an even page boundary?  Or at least, by some
> means, determine an even page reference point for the variables.  At
> this point, I'm beginning to doubt that there is much way to implement
> DP referencing for BASIC.

BASIC knows that the direct page register refers to a specific part of 
it's work area.  If a subroutine changes the direct page register, it 
must put it back before it returns.

> But we _do_ need it for OS9.

I see that it would be vary useful.  And if you treat the direct page as 
a psect that is aligned on a 256 byte foundary, the compiler already 
knows how to transparently manage any number of these psects, fixed or 
relocatable.  As the register has only 256 possible values, it puts a 
bound that only 256 psects could possibly have the direct attribute.

>  I'm still struggling with how to determine
> if an operator is data in the program.  This needs to be done in order
> to determine whether the operand should be referenced by pc or y
> (assuming we keep y as the data pointer)..

That is something that I need to look at.  What really matters in that 
decision is the calling conventions for the run time library.

GCC has some expectations of that some registers will be used for some 
things.

>  I had hoped that SYMBOL_REF
> would be a data pointer, but apparently not.  Can someone tell me what
> gcc interprets SYMBOL_REF, LABEL_REF and PROG_REF (or maybe PROGRAM_REF)
> to be?

Try the command "info gccint" at the command prompt, it claims to be up 
to date for GCC 3.3.1 on my installation.

I have not had time to study it that closely.

I do not know if I can achieve my goals, but from what I can see so far, 
something like this has been implemented with other targets.

What is bothering me right now, is I can see how it is done by examining 
the files emitted by configure and make, but I have not found out yet 
how to specify it on the input files.

At this stage I could probably edit the output file to produce the 
desired result in the XGCC6809 code, if I changed the makefile not to 
overwrite the edits.

But I have not had time since getting the first binary to do more than 
skim the code.

-John
wb8tyw at qsl.net
Personal Opinion Only




More information about the Coco mailing list