[comp.sys.amiga.programmer] DICE and relocatable/reentrant/resident code

mpierce@ewu.UUCP (Mathew Pierce) (05/07/91)

Does anyone (Matt Dillon perhaps) know the required steps
to make resident/relocatable/reentrant code with DICE? Do you
have to eliminate global variables, and all that stuff, or is
it as simple as using the -r option?  I mean can I take a 
generic program that I wrote to accept,process, and output
commands through the CLI and make it RRR merely by using
the -r option with no worries about globals?

Thanks

-Matt Pierce

dillon@overload.Berkeley.CA.US (Matthew Dillon) (05/09/91)

In article <1570@ewu.UUCP> mpierce@ewu.UUCP (Mathew Pierce) writes:
>Does anyone (Matt Dillon perhaps) know the required steps
>to make resident/relocatable/reentrant code with DICE? Do you
>have to eliminate global variables, and all that stuff, or is
>it as simple as using the -r option?  I mean can I take a
>generic program that I wrote to accept,process, and output
>commands through the CLI and make it RRR merely by using
>the -r option with no worries about globals?
>
>Thanks
>
>-Matt Pierce

    With DICE you can take a generic program and simply compile it with the
    -r option.	With SAS/C it's almost as simple, but you are required to
    include the appropriate pragma's for library calls and link with a
    different startup module.

    Essentially, the non-residentable small-data model declares data & bss
    in a section, meaning that the base is known on program execution and
    can be retrieved with an lea __DATA_BASE+32766,A4.	 The startup code
    simply sets up the base register and clears BSS.  __geta4 works because
    the base is known (it's __DATA_BASE+32766) so it can figure it out from
    ground 0.

    The residentable small-data model does NOT declare data & bss in a
    section.  It declares data in a read-only section but ONLY for the
    purpose of relocating it to somewhere else on startup.  The startup
    code will AllocMem(data + bss, ...), copy the read-only data section
    (containing your initialized data), do whatever other relocations are
    necessary, and set up the A4 register relative to the AllocMem()d
    data+bss area.  Thus, since A4 is relative the allocmem'd block there
    is no way __geta4 can possibly work since it doesn't know where the
    allocmem'd block is from ground 0.  It's not even safe to store this in
    the task structure because, well, there may not BE a task structure.

    Other differences between SAS/C and DICE:

	* SAS/C needs a separate startup object module for residentable
	  code because it must relocate the initialized data via a
	  relocation table (i.e. when you have int a; int *b = &a; as
	  globals).  DICE, on the otherhand, generates autoinit code to
	  handle relocations instead of table and thus DICE's
	  residentable/non-residentable startup are actually a single
	  object module.

	  Generating residentable code with DICE requires you to compile
	  every source module with the -r option, whereas in many cases you
	  can simply link with a different startup module in SAS/C without
	  recompilation (but, frankly, this has never been a problem for me
	  since -r works just fine with code that you do not make resident,
	  so I usually specify it for everything except shared library
	  source).  The reason for this is related to the way DICE & SAS/C
	  relocate the allocated data section.	Under SAS/C, blink
	  generates a relocation table which the startup code scans.  Under
	  DICE, the compiler generates autoinit code for any data-absolute
	  relocations which is run from the startup code to accomplish the
	  same thing.  Of course, I'm hopelessly biased, but I like the way
	  DICE does it better because it's so much cleaner.

	* SAS/C requires you to #include pragma's for library calls to avoid
	  referencing amiga.lib, which is large data.  Of course, this
	  yields a small speed advantage to SAS/C (note that SAS/C in
	  general will produce somewhat faster code due to more complex
	  optimizations, DICE does not do any complex code optimizations by
	  design -- i.e. on purpose).  DICE does not require any source
	  modifications at all because it's amiga.lib is small-data, and
	  thus works with residentable code.

	  I should mention that, like SAS/C, DICE also has an option to
	  enable automatic registerization of arguments for subroutine
	  calls and this does work with library calls as well, as long as
	  full prototypes are provided (Commodore provides prototypes for
	  all library calls in <clib/*.h> using the 2.0 includes).


    There are some basic restrictions with residentable code that applies
    to both compilers:

	__geta4 storage qualifier cannot be used since there is no way
	to determine what the base register is from ground 0.

	__chip storage qualifer cannot be used for modifiable data
	(but can be used for 'const' data since that goes into the
	read-only code section).

	small data model, so max 64KB of data+bss

	You generally can't make a shared library residentable (don't want
	to anyway since it doesn't make shared libraries more efficient as
	there is only one instance of it in memory at any given time).	The
	reason being that your library functions would need to use __geta4.


					-Matt
--

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