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