[comp.sys.amiga.tech] Lattice C : pragma? Whats all this then?

cctr120@canterbury.ac.nz (Brendon Wyber, C.S.C.) (11/09/90)

Hi,

I am using Lattice C v5.05 and have been using the ProtoType files. I've
noticed that the #pragma calls for INCLUDE:proto/cstrings.h refer to
a variable CStringBase. 

This was a real nuisance because when linking it kept wanting me to define it 
until I figures out I needed to to a #define NO_PRAMGAS. However what is 
bothering me is exactly what Library is that calling to?

Also what difference do Pramgas make? Is it done so that I can link to less
things? IE use my own c.o and miss out amiga.lib and lc.lib, (all in the
search for smaller code :-) ).

Sorry to bother you all, but the only documentation I can find about pragmas
isn't in the manuals at all but on a read me file!

Be seeing you,
-------
Brendon Wyber                 Computer Services Centre,
b.wyber@canterbury.ac.nz      University of Canterbury, New Zealand.

jmeissen@oregon.oacis.org ( Staff OACIS) (11/10/90)

In article <1990Nov10.001056.9736@canterbury.ac.nz> cctr120@canterbury.ac.nz (Brendon Wyber, C.S.C.) writes:
>Hi,
>
>I am using Lattice C v5.05 and have been using the ProtoType files. I've
>noticed that the #pragma calls for INCLUDE:proto/cstrings.h refer to
>a variable CStringBase. 

You should not be including INCLUDE:proto/cstrings.h. The cstrings functions
were dropped some time around the release of V1.0. Why are they still there?

As for CStringsBase,...you need to understand some Amiga library fundamentals.
All Amiga libraries are dynamically referenced at run-time. The mechanism
that allows this is a library base pointer, or vector, that points to a table
of library entry points. The Amiga routine OpenLibrary returns this pointer
value.

All the routines in Amiga.lib are hard-coded to use library vectors with
specific names. The #pragma statements use the same names in order to be
compatible with the non-#pragma mechanism. These names are all of the form
"xxxxxBase" where "xxxxx" is related to the library name. Hence, dos.library
is DosBase, intuition.library is IntuitionBase, etc.

It is the responsibility of the applications code to define these. Some time
back Lattice added them to the standard run-time library to help eliminate
confusion when the same base was defined in multiple modules, especially when
they were compiled with different options. (Note that ExecBase is hard-wired
at location 0x0004, and DosBase is defined in c.o). CStringsBase was left
out because this library is not supported (or even available, if memory
serves me).

>Also what difference do Pramgas make? Is it done so that I can link to less
>things? IE use my own c.o and miss out amiga.lib and lc.lib, (all in the
>search for smaller code :-) ).

#pragma support makes your code smaller and faster (in general). Without them,
calls to Amiga libraries actually call stub routines that save the registers,
load arguments off the stack into appropriate registers (Amiga libraries take
arguments in registers), load the library base vector into A6, and branch to
the real routine.

With #pragmas, the compiler generates the code to load the appropriate registers
in-line, and directly calls the library routine based on the library base vector.
This eliminates the argument pushing and popping, and allows the compiler to
optimize register allocation and usage around the call. Also, since the call
is direct, the stub code doesn't have to be linked in, making the code a little
smaller.

-- 
John Meissen .............................. Oregon Advanced Computing Institute
jmeissen@oacis.org        (Internet) | "That's the remarkable thing about life;
..!sequent!oacis!jmeissen (UUCP)     |  things are never so bad that they can't
jmeissen                  (BIX)      |  get worse." - Calvin & Hobbes

markv@kuhub.cc.ukans.edu (11/14/90)

> It is the responsibility of the applications code to define these. Some time
> back Lattice added them to the standard run-time library to help eliminate
> confusion when the same base was defined in multiple modules, especially when
> they were compiled with different options. (Note that ExecBase is hard-wired
> at location 0x0004, and DosBase is defined in c.o). CStringsBase was left
> out because this library is not supported (or even available, if memory
> serves me).

Lattice defines several bases in their libraries including DosBase,
SysBase, MathBase, GfxBase, IntuitionBase, etc.  DosBase and SysBase
are always valid (the OS gives these to a program when it runs).  The 
MathXXXBase's are opened depending on the floating point options.  All
other bases you need to open and close yourself.  One easy way to
check if your not sure is something like:

	if (!MathTransBase) {
		MathTransBase = OpenLibrary("mathtrans.library", 33L);
		MathTransOpened = TRUE;
	}
	...
	if (MathTrasOpened) {
		CloseLibrary(MathTransBase);
	}

This works since library bases start out as null because they are
global data.  The only place this would be a problem is the math
libraries since they may or may not be opened and if you want to call
them directly they need to be, but you dont want to open/close them if
the startup code has.
 
>>Also what difference do Pramgas make? Is it done so that I can link to less
>>things? IE use my own c.o and miss out amiga.lib and lc.lib, (all in the
>>search for smaller code :-) ).
 
>#pragma support makes your code smaller and faster (in general). Without them,
> calls to Amiga libraries actually call stub routines that save the registers,
> load arguments off the stack into appropriate registers (Amiga libraries take
> arguments in registers), load the library base vector into A6, and branch to
> the real routine.
>With #pragmas,the compilergenerates the code to load the appropriate registers
>in-line,and directly calls the library routine based on thelibrary basevector.
> This eliminates the argument pushing and popping ... smaller.

Actually the code can be a lot smaller, especially with the optimizer.
Every parameter that doesn't have to be pushed is 4-8 bytes of
savings.  Multiply that by every parameter and every function call and
it adds up.  Also you dont need to clean up the stack afterwords.
Another important thing is that none of the code, stub or pragma
checks to be sure the library base is valid.  If it isnt, can you say
jump in space?  Most times with pragmas are you can skip amiga.lib
completely, unless you need some of the constants (like ciaa, etc) or
a function that doesn't work with pragmas (like NewModifyProp() under
5.0X).
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Gooderum			Only...		\    Good Cheer !!!
Academic Computing Services	       ///	  \___________________________
University of Kansas		     ///  /|         __    _
Bix:	  markgood	      \\\  ///  /__| |\/| | | _   /_\  makes it
Bitnet:   MARKV@UKANVAX		\/\/  /    | |  | | |__| /   \ possible...
Internet: markv@kuhub.cc.ukans.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

sie@fulcrum.bt.co.uk (Simon Raybould) (11/20/90)

In article <26892.273fe53b@kuhub.cc.ukans.edu> markv@kuhub.cc.ukans.edu writes:
>Lattice defines several bases in their libraries including DosBase,
>SysBase, MathBase, GfxBase, IntuitionBase, etc.  DosBase and SysBase
                                                  ^^^^^^^
>are always valid (the OS gives these to a program when it runs).  The 

The OS doesn't open the Dos library, surely thats done by the startup code
LIB:c.o in the case of Lattice ?

If you don't link in the startup code then you have to set DosBase yourself!

SJR

markv@kuhub.cc.ukans.edu (11/27/90)

>>Lattice defines several bases in their libraries including DosBase,
>>SysBase, MathBase, GfxBase, IntuitionBase, etc.  DosBase and SysBase
>                                                   ^^^^^^^
>>are always valid (the OS gives these to a program when it runs).  The 
> 
> The OS doesn't open the Dos library, surely thats done by the startup code
> LIB:c.o in the case of Lattice ?

I don't think so (I'll double check c.a to be sure), but, DOS gives
DOSBase in a register to every process on startup (along with other
things like the command line) and I am pretty sure Lattice/SAS startup
just uses this.  Obviously SysBase is fetched from AbsExecBase.
 
> If you don't link in the startup code then you have to set DosBase yourself!

True, but my main point is from the point of view of main() of a
normal program you never have to worry about SysBase and DOSBase yourself.
 
> SJR
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mark Gooderum                 /\     \ | /     H a p p y  
Academic Computing Services  / v\   -- * --         H o l i d a y s ! :-)
University of Kansas        /v  v\   / | \    ///
                           /__v___\   Only  ///  /|         __    _  
Bitnet:   MARKV@UKANVAX       ||     \\\  ///  /__| |\/| | | _   /_\  makes it
Internet: markv@kuhub.cc.ukans.edu     \/\/  /    | |  | | |__| /   \ possible
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

p554mve@mpirbn.mpifr-bonn.mpg.de (Michael van Elst) (11/28/90)

In article <27079.2750fd01@kuhub.cc.ukans.edu> markv@kuhub.cc.ukans.edu writes:
>I don't think so (I'll double check c.a to be sure), but, DOS gives
>DOSBase in a register to every process on startup (along with other
>things like the command line) and I am pretty sure Lattice/SAS startup
>just uses this.  Obviously SysBase is fetched from AbsExecBase.

Lattice Startup opens the dos.library itself. Regardless wether the
current AmigaDOS passes a pointer to the library (it does not) it
is not documented. The only thing a program can rely is that the
command line is passed via registers a0 and d0.

Regards,
-- 
Michael van Elst
UUCP:     universe!local-cluster!milky-way!sol!earth!uunet!unido!mpirbn!p554mve
Internet: p554mve@mpirbn.mpifr-bonn.mpg.de
                                "A potential Snark may lurk in every tree."

dillon@overload.Berkeley.CA.US (Matthew Dillon) (11/28/90)

In article <CM|^9R|@uzi-9mm.fulcrum.bt.co.uk> sie@fulcrum.bt.co.uk (Simon Raybould) writes:
>In article <26892.273fe53b@kuhub.cc.ukans.edu> markv@kuhub.cc.ukans.edu writes:
>>Lattice defines several bases in their libraries including DosBase,
>>SysBase, MathBase, GfxBase, IntuitionBase, etc.  DosBase and SysBase
>						   ^^^^^^^
>>are always valid (the OS gives these to a program when it runs).  The
>
>The OS doesn't open the Dos library, surely thats done by the startup code
>LIB:c.o in the case of Lattice ?

    The only thing the OS gives to the executable when it starts it up
    is a pointer to the argument line and the length of that line, in
    registers.

    The startup code must retrieve SysBase (move.l 4.W,_SysBase), DOSBase
    (by using OpenLibrary("dos.library",0)), and everything else.

    Different compilers will open different things when you use the _main()
    entry point instead of the normal main() (unfortunately).

    Writing your own startup module can be dangerous, different compilers
    expect different things to be set up.  Try to avoid writing your own
    startup module whenever possible.

>If you don't link in the startup code then you have to set DosBase yourself!
>
>SJR

					-Matt

--


    Matthew Dillon	    dillon@Overload.Berkeley.CA.US
    891 Regal Rd.	    uunet.uu.net!overload!dillon
    Berkeley, Ca. 94708
    USA

walker@unx.sas.com (Doug Walker) (11/29/90)

In article <1990Nov10.001056.9736@canterbury.ac.nz> cctr120@canterbury.ac.nz (Brendon Wyber, C.S.C.) writes:
>Hi,
>
>I am using Lattice C v5.05 and have been using the ProtoType files. I've
>noticed that the #pragma calls for INCLUDE:proto/cstrings.h refer to
>a variable CStringBase. 

cstrings.h is obsolete.  That library no longer exists.  You can delete
all references to it.

>
>This was a real nuisance because when linking it kept wanting me to define it 
>until I figures out I needed to to a #define NO_PRAMGAS. However what is 
>bothering me is exactly what Library is that calling to?

Defining NO_PRAGMAS is bad - it means you won't call any other Amiga
libraries through the pragmas either.

>
>Also what difference do Pramgas make? Is it done so that I can link to less
>things? IE use my own c.o and miss out amiga.lib and lc.lib, (all in the
>search for smaller code :-) ).

This is a fairly often-asked question, so here's my canned spiel
on pragmas:

Amiga shared libraries (like dos.library, exec.library, intuition.library)
all have lists of functions that are accessible via that library's base
pointer (DOSBase, ExecBase, IntuitionBase, etc.)  The #pragma statement
is used to access these functions.  Basically, the library base points to
a section of memory with a list of assember JMP instructions right before
it.  To call routine FOO in that library, your code does a JSR (jump to
subroutine) to some offset relative to the library base, the JMP (jump)
jumps you into the ROM or RAM or whereever the library routine is, the 
routine executes, and it does an RTS to return to your code.
 
The problem with this is that the library routines take their parameters in
specific registers.  Normal C calling conventions call for pushing the
parameters onto the stack.  The solution back in the early days was to
provide small 'stub' routines for each library routine that your C program
would call.  The stub routine would pop the parameters off the stack into
the proper registers, load up the proper library base into register A5,
and branch to the right place.  These routines still exist in amiga.lib.
 
The #pragmas tell the compiler everything it needs to know to eliminate
these stub routines and call the library function directly.  It gives
the library base name (like IntuitionBase), the offset of the JMP
instruction for the routine, and a 'magic' value that tells it what
registers each parameter goes in.  When the compiler sees a call to, say,
OpenScreen, it loads the parameters in the proper registers, loads 
IntuitionBase into A5, and JSR's to the proper offset relative to A5.
This is quite a bit less overhead than the amiga.lib method.
 


  *****                              v Yes, I mean Distiller, not Distillery!
=*|_o_o|\\=====Doug Walker, Software Distiller====== BBS: (919)460-7430 =
 *|. o.| ||                                          1200/2400/9600 Dual
  | o  |//     For all you do, this bug's for you!
  ====== 
usenet: ...mcnc!rti!sas!walker   plink: dwalker  bix: djwalker 

walker@unx.sas.com (Doug Walker) (11/29/90)

In article <63@oregon.oacis.org> jmeissen@oregon.oacis.org ( Staff OACIS) writes:
>they were compiled with different options. (Note that ExecBase is hard-wired
>at location 0x0004, and DosBase is defined in c.o). CStringsBase was left

Well, not exactly... &ExecBase is at location 0x0004...


  *****                              v Yes, I mean Distiller!
=*|_o_o|\\=====Doug Walker, Software Distiller====== BBS: (919)460-7430 =
 *|. o.| ||                                          1200/2400/9600 Dual
  | o  |//     For all you do, this bug's for you!
  ====== 
usenet: ...mcnc!rti!sas!walker   plink: dwalker  bix: djwalker