home *** CD-ROM | disk | FTP | other *** search
- static const char version[] = "$VER: fd2pragma 2.131 (11.06.2001) by Dirk Stoecker <stoecker@epost.de>";
- /* #define FD2PRAGMA_READARGS */
- /* #define FD2PRAGMA_AMIGA */
- /* #define DEBUG */
- /* #define DEBUG_OLD */
-
- /* Programmheader
-
- Name: fd2pragma
- Author: SDI
- Distribution: PD
- Description: creates pragmas files, lvo files, ...
- Compileropts: -
- Linkeropts: -
-
- 1.2 : added pragmas for the Dice compiler. Available via switch "Dice".
- added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
- turn on the default (except that Maxon expects pragma files to be
- called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
- Dice, except that SAS supports the pragma tagcall.
- 2.0 : Added support for tag functions. See the docs for details.
- Author until this version:
- Jochen Wiedmann
- Am Eisteich 9
- 72555 Metzingen (Germany)
- Tel. 07123 / 14881
- 2.1 19.08.96 : now made by SDI, added correct __MAXON__ support and
- support for StormC++, added auto recognition of tagcall functions
- changed the CLI interface completely
- 2.2 21.08.96 : fixed a lot of errors, added debug code
- 2.3 22.08.96 : little changes
- 2.4 24.08.96 : added proto-file creation
- 2.5 25.08.96 : added syscall and fix for functions ending in ...DMA
- 2.6 26.08.96 : fixed some errors, added CLIB parameter (used later for
- CSTUBS)
- 2.7 01.09.96 : added correct Storm definition, added CLIB scan
- 2.8 02.09.96 : added assembler stub functions, added first ASM-stub code
- 2.9 04.09.96 : added Comment-Support
- 2.10 05.09.96 : changed CSTUB creation a bit
- 2.11 07.09.96 : speeded up output, reduced number of strndup calls
- 2.12 26.09.96 : pressing CTRL-C in early startup brought a wrong error
- message - fixed
- 2.13 30.09.96 : made RegNames field to RegNames string - shorter Exe-file
- 2.14 01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
- 2.15 13.10.96 : corrected an error text
- 2.16 14.10.96 : added correct comment support and PRIVATE option
- 2.17 19.10.96 : now Maxon-compiled in Small data mode
- 2.18 22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
- the texts, again SAS compiled
- 2.19 26.10.96 : added option to create FD files out of pragma files,
- reworked a lot in the source
- 2.20 27.10.96 : fixed errors of previous version
- 2.21 28.10.96 : fixed error in CLIB scan
- 2.22 27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
- bug in Tag function stubs
- 2.23 06.12.96 : lib and stub creation still was wrong
- 2.24 31.12.96 : formed stub libs matching C++ file names, corrected CLIB
- scan errors
- 2.25 04.01.97 : added HEADER option (I was asked for)
- 2.26 05.01.97 : added HEADER scan (in old file) and auto inserting
- 2.27 10.01.97 : stub functions missed register saving, outfuncs skip now,
- when error occured (makes lots of error checking obsolete)
- 2.28 11.01.97 : forgot to add offset made by register saving
- 2.29 18.01.97 : now libtags and amitags defines only, when at least 1
- tagfunc
- 2.30 13.02.97 : added local library base functions, rearranged SPECIAL
- options, fixed some bugs
- 2.31 15.02.97 : corrected bugs inserted in previous version
- 2.32 16.02.97 : and again bug fixes, still didn't work
- 2.33 18.02.97 : corrected texts, added SPECIAL 28
- 2.34 25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
- 2.35 26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
- 2.36 29.03.97 : corrected *tagcall scan a bit
- 2.37 20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
- 2.38 01.07.97 : fixed ##end handling
- 2.39 20.07.97 : added better proto file (__GNUC__ inline and pragma call),
- removed C++ comments
- 2.40 24.11.97 : added new basenames to the list (devices and resources),
- added tag-exception name checking (dos, utility libraries)
- 2.41 27.11.97 : fixed little bug with private functions, CSTUBS now
- special option and no longer commandline arg, SPECIAL 10-15 got
- numbers 11-16 (Sorry)
- 2.42 28.11.97 : Added two new warnings for CLIB
- 2.43 12.12.97 : faster FD file scan, one new warning
- 2.44 19.12.97 : fixed MODE settings for SPECIAL 15,16
- 2.45 30.01.98 : added function recognition, included inline creation,
- inline stuff is based on fd2inline 1.11 (incomplete)
- 2.46 31.01.98 : continued inline stuff, fixed clib functions
- 2.47 05.02.98 : completed inline stuff, added alias names for dos functions
- 2.48 06.02.98 : changed Func interface - flags instead of tagmode
- 2.49 10.02.98 : fixed inline generation a bit, added SORTED argument,
- RegNames got strings again
- 2.50 11.02.98 : bug-fixes, still did not work completely, hopefully got
- all now
- 2.51 12.02.98 : and bug-fixes again :-(
- 2.52 15.02.98 : changed sorting order of arguments
- 2.53 20.02.98 : some code style changes
- 2.54 25.02.98 : added SMALLDATA model, removed 5 global variables (better
- style), stub libs use MOVEM when possible, own MemRemember function
- 2.55 26.02.98 : bug fixes
- 2.56 15.03.98 : added FPU support
- 2.57 17.03.98 : added NOFPU keyword
- 2.58 19.03.98 : little fixes
- 2.59 20.03.98 : added enum and external type definitions defines
- 2.60 22.03.98 : added external types file scan
- 2.61 23.03.98 : fixed SAS flibcall, added FPU stubs
- 2.62 28.03.98 : bug fix with NOFPU and new option FPUONLY, total new clib
- handling
- 2.63 29.03.98 : really lots of bug fixes, There are so much problems.
- A better definition format would have been wonderful.
- 2.64 05.04.98 : bug fixes
- 2.65 07.04.98 : fixed Enforcer hit
- 2.66 08.04.98 : bug fix with type detection
- 2.67 20.04.98 : added GNU-only stuff
- 2.68 28.04.98 : SPECIAL 8 defaults to SAS-C names now
- 2.69 25.05.98 : added PowerUP stuff support
- 2.70 28.05.98 : added SAS PowerUP stuff, fixed error with function
- detection in CLIB scan
- 2.71 30.05.98 : added PowerUP Inlines
- 2.72 12.06.98 : sorting turns of COMMENT now
- 2.73 05.07.98 : added first FPC stuff, added HEADER to PowerUP stuff,
- added PASCAL header scan
- 2.74 06.07.98 : finished FPC stuff
- 2.75 07.07.98 : bug fixes for FPC stuff
- 2.76 09.07.98 : style changes for FPC stuff, bug fixes
- 2.77 11.07.98 : hopefully last FPC bug removed
- 2.78 23.07.98 : style changes and bug fixes for FPC stuff, more comments
- 2.79 10.08.98 : bug fix, when TO was used with a directory, clib got
- wrong path if it was a relative path description
- 2.80 16.08.98 : now prints better error when filopen failed
- 2.81 26.10.98 : added BMAP files for BASIC, CODE needs to use large mode
- now :-(
- 2.82 28.10.98 : optimizations and bug fixes
- 2.83 31.12.98 : fixed powerup stuff a bit
- 2.84 05.01.99 : fixed bug in Lib creation, when Dx/Ax and FPx were mixed
- 2.85 06.01.99 : added recognition of names ending in MESA, added notagcall
- comment support, void functions no longer can be tagcall
- 2.86 10.01.99 : added BGUI special funcs, fixed bug in SPECIAL 42 code
- 2.87 12.01.99 : added asm-text (SECTION), moved 12-17 to 13-18
- 2.88 17.01.99 : better type detection, added some more basenames, some
- little bug fixes, new makefile reduces file size a lot
- 2.89 17.07.99 : added union support
- 2.90 12.11.99 : added new motorola syntax, opt040 and vbcc inlines
- 2.91 13.11.99 : Now supports changes in OS3.5 includes, why the hell must
- such changes be? I thought new includes will bring cleanup and not
- cleandown. And the reported bugs are still unfixed, but there are
- new ones!, bug-fixes
- 2.92 14.11.99 : added PPC-WOS library text and code, FD-creation moved from
- 80 to 200 (now finally! - there should be enough free number space),
- added VBCC-PUP text generation
- 2.93 15.11.99 : added CheckError function, moved DisplayInfoHandle to
- types definition file
- 2.94 16.11.99 : added first VBCC-PowerUP-Lib production stuff, only ELF
- tables missing
- 2.95 17.11.99 : finished PowerUP stub stuff, startet PPC-ABI stuff
- 2.96 18.11.99 : little bug fixes
- 2.97 19.11.99 : added SECTION keyword, moved 11-18 to 12-17, ahh 3 releases
- more and we get an anniversary, my first program using third revision
- digit :-)
- 2.98 20.11.99 : added VBCC-WOS-Code for PPC libs
- 2.99 25.11.99 : bug fixes
- 2.100 17.02.00 : fixed bug for VBCC inlines
- 2.101 29.02.00 : fixed name for VBCC inlines
- 2.102 13.03.00 : added new style GCC inlines
- 2.103 21.03.00 : bug fixed, SPECIAL 35 has VBCC stuff now.
- 2.104 25.03.00 : fixed path lock problem
- 2.105 11.04.00 : library HUNK_UNIT get functionname now
- 2.106 13.07.00 : added E-Modules
- 2.107 06.08.00 : removed VBCC inline support from 35 and moved it to 38, 35
- does now skip pragma/inline files for VBCC
- 2.108 18.08.00 : added new ppc modification proto file 39, modified protos a
- bit, support for register types and function pointer args, int got
- internally type CPP_TYPE_INT
- 2.109 19.08.00 : bug fixes
- 2.110 24.08.00 : fixed SPECIAL 7,40-44, added SPECIAL 80-83
- 2.111 31.08.00 : bug fixes
- 2.112 03.09.00 : FD2Pragma.types scanner no longer accepts multi-word types.
- 2.113 29.12.00 : added extern keword support for return types.
- 2.114 07.01.01 : made FD2Pragma partly portable, removed 4 direct pragma arguments
- 2.115 14.01.01 : lots of bug fixes, renamed from FD2Pragma to fd2pragma
- 2.116 28.01.01 : added internal types, SPECIAL 90, NOCPPNAMES and bug fixes,
- VBCC inlines fix for data in A-regs
- 2.117 04.02.01 : changed NOCPPNAMES to ONLYCNAMES, added HUNKNAME, LocCode is
- portable, added BASENAME, added VBCCWOSInlines
- 2.118 07.02.01 : added destination file printout, LIBTYPE, fixes VBCC-PUP-Code
- 2.119 11.02.01 : bug fixes
- 2.120 17.02.01 : added NOPPCREGNAME, bug fixes
- 2.121 04.03.01 : added MorphOS text
- 2.122 11.03.01 : little bug fixes
- 2.123 03.04.01 : now uses EXT_DEXT16 instead of EXT_REF16 also for 68k files
- 2.124 08.04.01 : bug fixes, added MorphOS binary mode, finally full portable
- 2.125 28.04.01 : added LVO's for PPC, started support for SFD format
- 2.126 29.05.01 : fixed PPC LVO's, removed STORMFD Option (auto detection),
- now handles up to 5 alias names, finished SFD format read, added FD
- creation, added keyword checks for argument names, lots of optimizations
- and fixes, which came in hand with SFD inclusion.
- Thanks Olaf Barthel for making the SFD stuff possible.
- 2.127 30.04.01 : private comments are skipped now, finished SFD production,
- fixed bugs, removed SPECIAL 8 redirect (is replaced by 80-83)
- 2.128 01.05.01 : bug fixes
- 2.129 03.06.01 : included support for files previous made by vbcc genauto tool
- 2.130 04.06.01 : bug fixes in genauto stuff
- 2.131 11.06.01 : newer types handle cia now correct
- */
-
- /* A short note, how fd2pragma works.
- Working mode for SPECIAL 200 is a bit different!
- The main function parses arguments. Switches are converted into FLAG_XXX values
- and stored in global "Flags" or "Flags2" variable. SPECIAL numbers are parsed and are used
- to call a CreateXXX function, with its interface depending on the need of
- arguments (Some have 2, some none, ...). Before SPECIAL arguments are parsed,
- fd2pragma loads (S)FD file and scans it using ScanFDFile(). If SORTED is specified,
- the list gets sorted nearly directly afterwards. IF CLIB argument is given, the clib
- file is scanned after FD file and a clib list is created. Now SPECIAL is parsed
- and mode is set to any of the MODUS_XXX values. Also the destination file name
- is created if not given. The destination file is opened now. The mode variable
- is used to determine the correct CreateXXX function, which is called afterwards.
- This function produces file headers and stuff like that and calls CallFunc to
- process each FD entry. CallFunc gets 3 arguments. First the workmode (TAG,
- NORMAL, BOTH). Second the comment method (for C it is "/%s *\x2F\n",
- for ASM it is "\n%s", no comment is reached with 0 argument). The last is most
- important. It is the function pointer to a function creating the entries.
- These functions have always the same interface and are called through CallFunc
- only! They create an entry for the specified function (e.g. FD entry).
- Parsing special functions, adding comments, checking for tag-functions, ...
- is done by CallFunc. It is no problem to call CallFunc multiple with different
- function pointers (as is done for SPECIAL 6 pragmas).
-
- The functions can use DoOutput to output texts in printf style or DoOutputDirect
- to output all data in fwrite style. Buffering is done automatically.
-
- fd2pragma has its own memory managment. All memory must be allocated using
- AllocListMem and is freed automatically. This is especially useful for DupString
- function, which is used in FD and CLIB scanner.
-
- Normally this source-file is to big and should be splitted in different files
- compiled alone and linked together. :-)
- */
-
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <time.h>
-
- /* These are the only allowed variable types of all related programs! */
- typedef signed char int8; /* signed 8 bit */
- typedef unsigned char uint8; /* unsigned 8 bit */
- typedef signed short int int16; /* signed 16 bit */
- typedef unsigned short int uint16; /* unsigned 16 bit */
- typedef signed long int int32; /* signed 32 bit */
- typedef unsigned long int uint32; /* unsigned 32 bit */
- typedef float fl32; /* 32 bit IEEE float value */
- typedef double fl64; /* 64 bit IEEE double value */
- typedef char string; /* the string datatype [e.g. one character of string!] */
- typedef char * strptr; /* and an string pointer */
-
- #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
- (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
- #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
- #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
- (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
- #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
-
- #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
- #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
- #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
- #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
-
- #define TEXT_SAS "__SASC" /* verified */
- #define TEXT_SAS_60 "__SASC_60" /* verified */
- #define TEXT_MAXON "__MAXON__" /* verified */
- #define TEXT_STORM "__STORM__" /* verified */
- #define TEXT_DICE "_DCC" /* in 2.0 code */
- #define TEXT_AZTEC "AZTEC_C" /* verified */
- #define TEXT_GNUC "__GNUC__" /* verified */
- #define TEXT_VBCC "__VBCC__" /* verified */
-
- #define TEMPSIZE 20480
-
- #define FLAG_EXTERNC (1<< 0) /* add externc statements */
- #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
- #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
- #define FLAG_PRIVATE (1<< 3) /* also use private functions */
- #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
- #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
- #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
- #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
- #define FLAG_DONE (1<< 8) /* destination file is not empty */
- #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
- #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
- #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
- #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
- #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
- #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
- #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
- #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
- #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
- #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
- #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
- #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
- #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
- #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
- #define FLAG_INLINEMAC (1<<24) /* use inline macro instead of inline function */
- #define FLAG_SORTED (1<<25) /* sort the functions by name */
- #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
- #define FLAG_SINGLEFILE (1<<27) /* create single files */
- #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
- #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
- #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
- #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
-
- #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
- #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
- #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
- #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
- #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
- #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
- #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
-
- #define FUNCFLAG_NORMAL (1<<0) /* normal function */
- #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
- #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
-
- /* Different modes the main program uses, one for each different file
- type (except for those done with one function and flag settings). */
- #define MODUS_STUBTEXT 1
- #define MODUS_STUBCODE 2
- #define MODUS_LOCALDATA 3
- #define MODUS_PRAGMA 4
- #define MODUS_CSTUB 5
- #define MODUS_SASPOWER 6
- #define MODUS_PROTOPOWER 7
- #define MODUS_BMAP 8
- #define MODUS_PASCAL 9
- #define MODUS_VBCCINLINE 10
- #define MODUS_VBCCPUPLIB 11
- #define MODUS_LVOLIB 12
- #define MODUS_EMODULE 13
- #define MODUS_REDIRECT 14
- #define MODUS_ASMTEXTSF 15
- #define MODUS_VBCCPUPTEXTSF 16
- #define MODUS_VBCCWOSTEXTSF 17
- #define MODUS_VBCCWOSINLINE 18
- #define MODUS_VBCCMORPHTEXTSF 19
- #define MODUS_VBCCMORPHCODE 20
- #define MODUS_LVOLIBPPC 21
- #define MODUS_FD 22
- #define MODUS_CLIB 23
- #define MODUS_SFD 24
- #define MODUS_LVO 50 /* and 51 and 52 and 53 */
- #define MODUS_PROTO 60 /* and 61 to 69 */
- /* new protos start with 90, but are added to MODUS_PROTO ! */
- #define MODUS_INLINE 80 /* and 81 to 84 */
- #define MODUS_VBCC 90 /* and 91 to 94 */
- #define MODUS_LVOPPC 100 /* and 101 */
- #define MODUS_GENAUTO 110 /* and 111 to 113 */
- #define MODUS_ERROR 200
-
- #define ABI_M68K 1
- #define ABI_PPC 2
- #define ABI_PPC2 3
- #define ABI_PPC0 4
-
- /* call types for CallFunc */
- #define TAGMODE_NORMAL 0 /* produce normal functions only */
- #define TAGMODE_TAGS 1 /* produce only tag functions */
- #define TAGMODE_BOTH 2 /* produce both types */
-
- /* types specifying name method for pragma creation */
- #define PRAGMODE_PRAGLIB 1
- #define PRAGMODE_PRAGSLIB 2
- #define PRAGMODE_PRAGSPRAGS 3
- #define PRAGMODE_NONE 4
-
- #define BIAS_START 30 /* the library start offset */
- #define BIAS_OFFSET 6 /* value to switch from one to next function */
-
- #define EXTTYPESFILE "fd2pragma.types"
- #ifdef FD2PRAGMA_AMIGA
- #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
- #else
- #define EXTTYPESFILE2 "/usr/local/fd2pragma.types"
- #endif
- #define FDFILEEXTENSION "_lib.fd"
- #define SFDFILEEXTENSION "_lib.sfd"
-
- static const strptr RegNames[] = {
- "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
- "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
- "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
- };
-
- static const strptr RegNamesUpper[] = {
- "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
- "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
- "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
- };
-
- enum Register_ID {
- REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
- REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7,
- REG_FP0, REG_FP1, REG_FP2, REG_FP3, REG_FP4, REG_FP5, REG_FP6, REG_FP7
- };
- #define MAXREGPPC 26
- #define MAXREG 24 /* maximum registers of 68K */
- #define MAXREGNF 16 /* maximum register number without float regs */
- #define UNDEFREGISTER 255 /* for type scanner */
-
- struct Args {
- strptr infile;
- strptr to;
- strptr clib;
- strptr header;
- int32 special;
- int32 mode;
- };
-
- struct ShortList {
- struct ShortList *Next;
- };
-
- struct ShortListRoot {
- struct ShortList *First;
- struct ShortList *Last;
- size_t Size;
- };
-
- #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
- #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
- #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
- #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
- #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
- #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
- #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
- #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
- #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
- #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
- #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
- #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
- #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
- #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
- #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
- #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
-
- struct AmiArgs {
- strptr ArgName;
- uint16 ArgReg;
- };
-
- #define NUMALIASNAMES 5
-
- struct AmiPragma {
- struct ShortList List;
- uint32 Line;
- uint32 Flags;
- strptr FuncName;
- strptr TagName;
- struct Pragma_AliasName * AliasName[NUMALIASNAMES]; /* possible alias names */
- uint16 NumArgs; /* register numbers */
- uint16 CallArgs; /* argument number in fd file */
- int16 Bias;
- int8 NumAlias;
- int8 Abi;
- struct AmiArgs Args[MAXREGPPC];
- };
-
- struct Comment {
- struct ShortList List;
- strptr Data;
- int16 Bias;
- uint16 ReservedNum;
- uint16 Version;
- uint8 Private; /* is a flag only */
- };
-
- struct Include {
- struct ShortList List;
- strptr Include;
- };
-
- struct PragList {
- struct ShortList List;
- struct ShortListRoot Data; /* contains list of PragData */
- strptr Basename;
- };
-
- struct PragData {
- struct ShortList List;
- struct ShortListRoot Name;
- uint32 NumNames;
- uint32 Bias;
- uint32 NumArgs;
- uint8 ArgReg[MAXREG];
- };
-
- struct FDData {
- strptr Name;
- strptr Basename;
- uint32 Bias;
- uint32 Mode; /* 0 = Normal, != 0 is TagName */
- uint32 NumArgs;
- uint8 ArgReg[MAXREG];
- };
-
- /* These CPP types match the strings used for CPP name creation. The
- defines are used both for name creation and type specification. */
- #define CPP_TYPE_VOID 'v' /* void, VOID */
- #define CPP_TYPE_BYTE 'c' /* char, int8 */
- #define CPP_TYPE_WORD 's' /* short, int16 */
- #define CPP_TYPE_LONG 'j' /* long, int32 */
- #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
- #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
- #define CPP_TYPE_INT 'i' /* int */
- #define CPP_TYPE_STRUCTURE 0
- #define CPP_TYPE_VARARGS 'e'
-
- /* These types are for string creation only. */
- #define CPP_TYPE_ENUM 'E'
- #define CPP_TYPE_CONST 'C'
- #define CPP_TYPE_FUNCTION 'F'
- #define CPP_TYPE_POINTER 'P'
- #define CPP_TYPE_UNSIGNED 'U'
- #define CPP_TYPE_FUNCEND 'p'
- #define CPP_TYPE_REGISTER 'r'
-
- /* Some flags to be used in CPP_NameType->Flags. */
- #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
- #define CPP_FLAG_CONST (1<<1) /* type is const */
- #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
- #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
- #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
- #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
- #define CPP_FLAG_UNION (1<<6) /* it is a union */
- #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
- #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
- #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
- /* STRPTR is defined different under C and CPP -> I have to create two
- names, one time unsigned char *, one time signed char *, when somewhere
- a STRPTR occurs */
-
- #define COPYCPP_PASSES 4
-
- struct CPP_NameType { /* structure to describe a argument type */
- strptr StructureName; /* if a structure or enum only */
- strptr FuncArgs; /* arguments of function - unterminated */
- strptr TypeStart; /* start of this type */
- strptr FunctionName; /* Argument name of function argument */
- struct ClibData *FuncPtr; /* if it is a function pointer */
- uint16 StructureLength; /* length of the structure name */
- uint16 ArgsLength; /* length of FuncArgs */
- uint16 TypeLength; /* length of this type */
- uint16 FullLength; /* length of complete type */
- uint16 PointerDepth; /* number of * in type */
- uint16 Flags; /* see above flags */
- uint8 Type; /* see above defines */
- uint8 Register; /* register number */
- };
-
- struct ClibData { /* structure to describe data in CLIB file */
- struct ClibData * Next; /* The next entry in this list */
- strptr FuncName; /* name of the function */
- struct CPP_NameType ReturnType; /* data for return type */
- struct CPP_NameType Args[MAXREGPPC+1]; /* data for argument types */
- uint16 NumArgs; /* number of arguments */
- };
-
- struct CPP_ExternNames { /* structure for EXTTYPESFILE data */
- struct CPP_ExternNames * Next; /* The next entry in this list */
- strptr Type; /* The unknown type */
- struct CPP_NameType NameType; /* The replacement */
- };
-
- struct CPP_TypeField { /* structure for internal defined types */
- strptr Text; /* name of the type */
- uint16 Length; /* length of the name string */
- uint16 Flags; /* CPP_FLAG flags */
- uint8 Type; /* CPP_TYPE value */
- };
-
- struct Proto_LibType { /* structure to define structure type of base vars */
- strptr BaseName; /* name of the library base */
- strptr StructureName; /* name of the structure to be used (maybe 0 for default) */
- strptr LibraryName; /* name of the library (maybe 0 for default method) */
- strptr ShortBaseName; /* short name of the library base */
- };
-
- struct Pragma_ExecpName { /* structure to specify special tagnames */
- strptr FunctionName; /* function name */
- strptr TagName; /* tag name to be used for this function */
- }; /* TagName 0 is valid as well to disable tagfunctions */
-
- struct Pragma_AliasName {
- strptr FunctionName;
- strptr AliasName;
- uint32 Type;
- };
-
- #define NTP_NORMAL 0 /* no tags/args */
- #define NTP_TAGS 1 /* TagFunction */
- #define NTP_ARGS 2 /* ArgFunction */
- #define NTP_UNKNOWN 3 /* CommentFunction */
-
- struct NameList {
- struct ShortList List;
- uint32 Type; /* set by OptimizeFDData */
- strptr NormName;
- strptr PragName;
- };
-
- struct InFile {
- strptr pos;
- strptr buf;
- size_t size;
- };
-
- /* EHF definitions! */
- #define HUNK_PPC_CODE 0x4E9
- #define HUNK_RELRELOC26 0x4EC
- #define EXT_RELREF26 229
-
- /* ------------------------------------------------------------------ */
- /* A short set of ELF definitions, see pasm sources in vbcc release for an
- more complete set of stuff or get elf documentation. These are needed for
- VBCCPUPCode function. */
- #define ELFCLASS32 1
- #define ELFDATA2MSB 2
- #define EV_CURRENT 1 /* version information */
- #define ET_REL 1 /* type information */
- #define EM_POWERPC 20
-
- #define SHT_NULL 0 /* inactive */
- #define SHT_PROGBITS 1 /* program information */
- #define SHT_SYMTAB 2 /* symbol table */
- #define SHT_STRTAB 3 /* string table */
- #define SHT_RELA 4 /* relocation */
-
- #define SHF_ALLOC 0x2 /* needs memory when started */
- #define SHF_EXECINSTR 0x4 /* executable instructions */
-
- #define SHN_ABS 0xFFF1
-
- #define EI_NIDENT 16
- #define EI_MAG0 0
- #define EI_MAG1 1
- #define EI_MAG2 2
- #define EI_MAG3 3
- #define EI_CLASS 4
- #define EI_DATA 5
- #define EI_VERSION 6
-
- #define STB_LOCAL 0
- #define STB_GLOBAL 1
- #define STT_FUNC 2
- #define STT_NOTYPE 0
- #define STT_SECTION 3
- #define STT_FILE 4
- #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
- #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
-
- #define R_PPC_ADDR16_LO 4
- #define R_PPC_ADDR16_HA 6
- #define R_PPC_REL24 10
- #define R_PPC_SDAREL16 32
-
- struct ArHeader {
- string ar_name[16]; /* name */
- string ar_time[12]; /* modification time */
- string ar_uid[6]; /* user id */
- string ar_gid[6]; /* group id */
- string ar_mode[8]; /* octal file permissions */
- string ar_size[10]; /* size in bytes */
- string ar_fmag[2]; /* consistency check */
- };
-
- /* AmigaOS hunk structure definitions */
- #define HUNK_UNIT 999
- #define HUNK_NAME 1000
- #define HUNK_CODE 1001
- #define HUNK_BSS 1003
- #define HUNK_ABSRELOC32 1004
- #define HUNK_EXT 1007
- #define HUNK_SYMBOL 1008
- #define HUNK_END 1010
- #define HUNK_DREL16 1016
-
- #define EXT_DEF 1 /* normal definition */
- #define EXT_ABS 2 /* Absolute definition */
- #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
- #define EXT_DEXT16 134 /* 16 bit data relative reference */
- /* ------------------------------------------------------------------ */
-
- static struct Args args = {0,0,0,0,6,0};
- static struct InFile in = {0,0,0};
- static FILE * outfile;
- static struct ClibData * clibdata = 0;
- static struct ShortListRoot AmiPragma = {0,0,sizeof(struct AmiPragma)},
- Comment = {0,0,sizeof(struct Comment)},
- Includes = {0,0,sizeof(struct Include)};
- static struct CPP_ExternNames *extnames = 0;
- static strptr BaseName = 0; /* the correct basename */
- static strptr ShortBaseName = 0; /* the filename part of basename without Base */
- static strptr ShortBaseNameUpper = 0; /* like ShortBaseName, but upper case */
- static strptr HEADER = 0;
- static strptr Copyright = 0;
- static strptr filenamefmt = 0;
- static strptr libtype = 0;
- static strptr libname = 0;
- static strptr defabi = 0;
- static strptr hunkname = ".text";
- static strptr datahunkname = "__MERGED";
- static strptr PPCRegPrefix = "r";
- static strptr IDstring = 0;
- static uint8 * tempbuf = 0;
- static size_t headersize = 0;
- static uint32 Flags = 0;
- static uint32 Flags2 = 0;
- static uint32 Output_Error = 1; /* Output error occured when 0 */
- static uint32 tagfuncs = 0; /* are there some tagfuncs in FD */
- static uint32 priority = 5; /* priority for auto libopen */
- static string filename[255]; /* needed for filename */
-
- static int32 LastBias = 0; /* Only for E-Stuff, FD, SFD creation */
- static uint8 * elfbufpos = 0; /* Only for PPC-LVO Lib's */
- static uint32 symoffset = 0; /* Only for PPC-LVO Lib's */
- static uint32 CurrentABI = 0; /* Only for FD, SFD creation */
-
- /* Prototypes for the functions */
- static strptr DupString(strptr, size_t);
- static strptr AllocListMem(size_t);
- static strptr SkipBlanks(strptr);
- static strptr SkipBlanksRet(strptr);
- static strptr SkipName(strptr);
- static strptr GetBaseType(void);
- static strptr GetLibraryName(void);
- static int32 MakeShortBaseName(void);
- static uint32 OpenDest(strptr);
- static uint32 CloseDest(strptr);
- static uint32 MakeTagFunction(struct AmiPragma *);
- static void MakeLines(strptr, uint32);
- static uint32 SpecialFuncs(void);
- static void SortFDList(void);
- static void AddAliasName(struct AmiPragma *, struct Pragma_AliasName *, uint32);
- static uint32 CheckNames(struct AmiPragma *);
- static uint32 ScanSFDFile(uint32);
- static uint32 ScanFDFile(void);
- static int32 ScanTypes(strptr, uint32);
- static void FindHeader(void);
- static uint32 GetRegisterData(struct AmiPragma *);
- static uint16 GetFRegisterData(struct AmiPragma *);
- static uint32 OutputXDEF(uint32, strptr, ...);
- static uint32 OutputXREF(uint32, uint32, strptr, ...);
- static uint32 OutputXREF2(uint32, uint32, uint32, strptr, ...);
- static uint32 OutputSYMBOL(uint32, strptr, ...);
- static uint8 * AsmStackCopy(uint8 *, struct AmiPragma *, uint32, uint32);
- /* ------------------------------------------------------------------ */
- static void DoError(uint32, uint32, ...);
- static uint32 CheckError(struct AmiPragma *, uint32);
- static uint32 DoOutputDirect(void *, size_t);
-
- #if defined(__GNUC__)
- static uint32 DoOutput(strptr, ...) __attribute__ ((format(printf, 1, 2)));
- #else
- static uint32 DoOutput(strptr, ...);
- #endif
- /* ------------------------------------------------------------------ */
- static struct ShortList *NewItem(struct ShortListRoot *);
- static struct ShortList *RemoveItem(struct ShortListRoot *, struct ShortList *);
- static void AddItem(struct ShortListRoot *, struct ShortList *);
- /* ------------------------------------------------------------------ */
- typedef uint32 (*FuncType)(struct AmiPragma *, uint32, strptr);
-
- uint32 FuncAMICALL (struct AmiPragma *, uint32, strptr);
- uint32 FuncLIBCALL (struct AmiPragma *, uint32, strptr);
- uint32 FuncAsmText (struct AmiPragma *, uint32, strptr);
- uint32 FuncAsmCode (struct AmiPragma *, uint32, strptr);
- uint32 FuncCSTUBS (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVOXDEF (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVO (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVOPPCXDEF (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVOPPC (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVOPPCBias (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVOPPCName (struct AmiPragma *, uint32, strptr);
- uint32 FuncLVOLib (struct AmiPragma *, uint32, strptr);
- uint32 FuncLocCode (struct AmiPragma *, uint32, strptr);
- uint32 FuncLocText (struct AmiPragma *, uint32, strptr);
- uint32 FuncInline (struct AmiPragma *, uint32, strptr);
- uint32 FuncInlineNS (struct AmiPragma *, uint32, strptr);
- uint32 FuncPowerUP (struct AmiPragma *, uint32, strptr);
- uint32 FuncFPCUnit (struct AmiPragma *, uint32, strptr);
- uint32 FuncFPCType (struct AmiPragma *, uint32, strptr);
- uint32 FuncBMAP (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCInline (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCWOSInline (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCWOSText (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCWOSCode (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCPUPText (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCPUPCode (struct AmiPragma *, uint32, strptr);
- uint32 FuncEModule (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCMorphText (struct AmiPragma *, uint32, strptr);
- uint32 FuncVBCCMorphCode (struct AmiPragma *, uint32, strptr);
- uint32 FuncFD (struct AmiPragma *, uint32, strptr);
- uint32 FuncClib (struct AmiPragma *, uint32, strptr);
- uint32 FuncSFD (struct AmiPragma *, uint32, strptr);
- static uint32 PrintComment (struct Comment *, strptr);
- static uint32 DoCallFunc(struct AmiPragma *, uint32, strptr, FuncType);
- static uint32 CallFunc(uint32, strptr, FuncType);
- static uint32 PrintIncludes(void);
- /* ------------------------------------------------------------------ */
- static int32 AddClibEntry(strptr, strptr, uint32);
- static int32 ScanClibFile(strptr, strptr);
- static int32 IsCPPType(struct CPP_NameType *, uint8);
- static uint32 CheckRegisterNum(strptr, struct CPP_NameType *);
- static uint32 ParseFuncPtrArgs(strptr, struct CPP_NameType *);
- static int32 GetCPPType(struct CPP_NameType *, strptr, uint32);
- static struct ClibData *GetClibFunc(strptr, struct AmiPragma *, uint32);
- static int32 CheckKeyword(strptr, strptr, int32);
- static uint32 CopyCPPType(strptr, uint32, struct ClibData *, struct AmiArgs *);
- static uint32 OutClibType(struct CPP_NameType *, strptr);
- static uint32 MakeClibType(strptr, struct CPP_NameType *, strptr);
- static uint32 OutPASCALType(struct CPP_NameType *, strptr, uint32);
- /* ------------------------------------------------------------------ */
- static uint32 CallPrag(uint32, strptr, FuncType);
- static uint32 CreatePragmaFile(strptr, strptr, strptr, strptr, uint32);
- static uint32 CreateCSTUBSFile(void);
- static uint32 CreateLVOFile(uint32);
- static uint32 CreateLVOFilePPC(uint32);
- static uint32 CreateAsmStubs(uint32, uint32);
- static uint32 CreateProtoFile(uint32);
- static uint32 CreateLocalData(strptr, uint32);
- static uint32 CreateInline(uint32, uint32);
- static uint32 CreateSASPowerUP(uint32);
- static uint32 CreateProtoPowerUP(void);
- static uint32 CreateFPCUnit(void);
- static uint32 CreateBMAP(void);
- static uint32 CreateLVOLib(void);
- static uint32 CreateLVOLibPPC(void);
- static uint32 CreateVBCCInline(uint32);
- static uint32 CreateVBCC(uint32, uint32);
- static uint32 CreateVBCCPUPLib(uint32);
- static uint32 CreateVBCCMorphCode(uint32);
- static uint32 CreateEModule(uint32);
- static uint32 CreateProtoRedirect(void);
- static uint32 CreateFD(void);
- static uint32 CreateSFD(uint32);
- static uint32 CreateClib(uint32);
- static uint32 CreateGenAuto(strptr, uint32);
- /* ------------------------------------------------------------------ */
- static uint32 GetName(struct NameList *, struct ShortListRoot *, uint32);
- static uint32 MakeFD(struct PragList *);
- static void OptimizeFDData(struct PragData *);
- static string GetHexValue(string);
- static string GetDoubleHexValue(strptr);
- static uint32 AddFDData(struct ShortListRoot *, struct FDData *);
- static uint32 GetLibData(struct FDData *);
- static uint32 GetFlibData(struct FDData *);
- static uint32 GetAmiData(struct FDData *);
- static uint32 CreateFDFile(void);
- /* ------------------------------------------------------------------ */
- static void GetArgs(int argc, char **argv);
- static strptr mygetfile(strptr name, size_t *len);
-
- #define ERROFFSET_CLIB (1<<20)
-
- enum {
- ERR_TAGFUNC_NEEDS_ARGUMENT,
- ERR_CANNOT_CONVERT_PRAGMA_TAGCALL,
- ERR_TAG_DEF_WITHOUT_PRAGMA,
- ERR_BASENAME_DECLARED_TWICE,
- ERR_EXPECTED_SLASH_IN_BASENAME,
- ERR_EXPECTED_BASENAME,
- ERR_EXPECTED_BIAS_VALUE,
- ERR_ASSUMING_POSITIVE_BIAS_VALUE,
- ERR_MISSING_FUNCTION_NAME,
- ERR_EXPECTED_OPEN_BRACKET,
- ERR_TO_MUCH_ARGUMENTS,
- ERR_EXPECTED_ARGUMENT_NAME,
- ERR_EXPECTED_CLOSE_BRACKET,
- ERR_EXPECTED_REGISTER_NAME,
- ERR_A7_NOT_ALLOWED,
- ERR_REGISTER_USED_TWICE,
- ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER,
- ERR_ASSUMING_BIAS_OF_30,
- ERR_EXTRA_CHARACTERS,
- ERR_MISSING_BASENAME,
- ERR_WRITING_FILE,
- ERR_EXPECTED_COMMA,
- ERR_DIFFERENT_TO_PREVIOUS,
- ERR_UNKNOWN_VARIABLE_TYPE,
- ERR_UNKNOWN_ERROR,
- ERR_MISSING_END,
- ERR_PROTOTYPE_MISSING,
- ERR_NOPROTOTYPES_FILE,
- ERR_UNKNOWN_DIRECTIVE,
- ERR_INLINE_A4_AND_A5,
- ERR_INLINE_D7_AND_A45,
- ERR_MISSING_SHORTBASENAME,
- ERR_A6_NOT_ALLOWED,
- ERR_EMPTY_FILE,
- ERR_FLOATARG_NOT_ALLOWED,
- ERR_WRONG_TYPES_LINE,
- ERR_LONG_DOUBLE,
- ERR_CLIB_ARG_COUNT,
- ERR_OPEN_FILE,
- ERR_A5_NOT_ALLOWED,
- ERR_PPC_FUNCTION_NOT_SUPPORTED,
- ERR_UNKNOWN_ABI,
- ERR_NO_SORTED,
- ERR_ILLEGAL_FUNCTION_POSITION,
- ERR_SORTED_COMMENT,
- ERR_COMMENT_SINGLEFILE,
- ERR_NOFD2PRAGMATYPES,
- ERR_M68K_FUNCTION_NOT_SUPPORTED,
- ERR_UNKNOWN_RETURNVALUE_TYPE,
- ERR_SFD_AND_CLIB,
- ERR_EXCPECTED_IDSTRING,
- ERR_EXPECTED_ID_ENDSIGN,
- ERR_MISSING_SFDEND,
- ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER,
- ERR_IDSTRING_DECLARED_TWICE,
- ERR_COMMANDLINE_LIBTYPE,
- ERR_COMMANDLINE_BASENAME,
- ERR_LIBTYPE_DECLARED_TWICE,
- ERR_EXPECTED_LIBTYPE,
- ERR_SORTED_SFD_FD,
- ERR_EARLY_SHADOW,
- ERR_DOUBLE_VARARGS,
- ERR_VARARGS_ARGUMENTS_DIFFER,
- ERR_UNEXPECTED_FILEEND,
- ERR_VARARGS_ALIAS_FIRST,
- ERR_ALIASNAMES,
- ERR_EXPECTED_STRUCT,
- ERR_EXPECTED_POINTERSIGN,
- ERR_ARGNAME_KEYWORD_CONFLICT,
- ERR_ARGNAME_ARGNAME_CONFLICT,
- ERR_ONLYTAGMODE_NOTALLOWED,
- ERR_COMMANDLINE_LIBNAME,
- ERR_LIBNAME_DECLARED_TWICE,
- ERR_EXPECTED_LIBNAME
- };
-
- static const struct ErrField {
- uint8 Type; /* 0 = Error, 1 = Warning */
- uint8 Skip;
- strptr Error;
- } Errors[] = {
- {1, 1, "Tag function must have arguments."},
- {1, 1, "Cannot convert pragma name into tag name."},
- {1, 1, "Tag definition without preceding Pragma."},
- {1, 0, "Basename declared twice."},
- {1, 0, "Expected preceding _ in Basename."},
- {1, 1, "Expected Basename."},
- {1, 0, "Expected Bias value."},
- {1, 0, "Assuming positive bias value."},
- {1, 1, "Missing function name."},
- {1, 1, "Expected '('."},
- {1, 1, "Too much arguments."},
- {1, 1, "Expected argument name."},
- {1, 1, "Expected ')'."},
- {1, 1, "Expected register name."},
- {1, 1, "A7 not allowed as argument register."},
- {1, 1, "Register used twice."},
- {1, 0, "Number of arguments != number of registers."},
- {1, 0, "Assuming bias of 30."},
- {1, 1, "Extra characters."},
- {0, 0, "Missing Basename in FD file."},
- {0, 0, "Failed to write destination file."},
- {1, 1, "Expected ','."},
- {0, 1, "Data different to previous given."},
- {1, 0, "Unknown type of argument %ld."},
- {0, 0, "Unknown problem: program error or corrupt input data."},
- {1, 0, "Missing ##end."},
- {1, 0, "Prototype for function \"%s\" not found."},
- {0, 0, "No prototypes file (CLIB parameter) was specified."},
- {1, 1, "Unknown directive '%s' found."},
- {1, 0, "Usage of both A4 and A5 is not supported."},
- {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
- {0, 0, "Missing Basename in FD file and FD filename."},
- {1, 0, "A6 not allowed as argument register."},
- {1, 0, "Empty or partial file deleted."},
- {1, 1, "Floating point arguments not allowed."},
- {0, 0, "Wrong definition in external type definition file."},
- {1, 0, "Cannot determine if FPU argument is double or single."},
- {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
- {0, 0, "Could not open file \"%s\"."},
- {1, 0, "A5 cannot be used as argument register."},
- {1, 0, "Format supports no PPC functions."},
- {1, 0, "Unknown ABI '%s' found."},
- {0, 0, "SORTED cannot be used with that type."},
- {1, 0, "Position of function %s not supported with that type."},
- {1, 0, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
- {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
- {1, 0, "Missing the " EXTTYPESFILE " file. Using internal defaults."},
- {1, 0, "Format supports no M68k functions."},
- {1, 0, "Unknown type of return value."},
- {1, 0, "With SFD as input CLIB file is ignored."},
- {1, 0, "Expected $Id: in ID string."},
- {1, 0, "Expected $ at end of ID string."},
- {1, 0, "Missing ==end."},
- {1, 1, "Expected positive decimal number."},
- {1, 0, "ID string declared twice."},
- {1, 0, "Library type of commandline overwrites file settings."},
- {1, 0, "Basename of commandline overwrites file settings."},
- {1, 0, "Library type declared twice."},
- {1, 1, "Expected library type definition."},
- {1, 0, "SORTED cannot be used with SFD and FD output."},
- {1, 0, "Function expected before ##shadow."},
- {1, 0, "There is already a varargs function, handling as alias."},
- {1, 0, "Varargs function cannot have different arguments."},
- {1, 0, "Unexpected end of file."},
- {1, 0, "Commands varargs and alias cannot be at file start."},
- {1, 0, "Only %d alias names supported."},
- {1, 1, "Expected struct keyword in library type."},
- {1, 0, "Expected '*' at end of library type definition."},
- {1, 0, "Name of argument %d conflicts with keyword '%s'."},
- {1, 0, "Name of argument %d conflicts with argument %d."},
- {1, 0, "SFD files cannot consist only of varargs functions."},
- {1, 0, "Library name of commandline overwrites file settings."},
- {1, 0, "Library name declared twice."},
- {1, 1, "Expected library name definition."},
- };
-
- static const uint8 InternalTypes[] = {
- "IX:struct InputXpression\n"
- "Msg:struct ? *\n"
- "Class:struct IClass\n"
- "BootBlock:struct bootblock\n"
- "ValidIDstruct:struct ValidIDstruct\n"
- "DisplayInfoHandle:void *\n"
- "RESOURCEFILE:void *\n"
- "RESOURCEID:unsigned long\n"
- "GLvoid:void\n"
- "GLbitfield:unsigned long\n"
- "GLbyte:signed char\n"
- "GLshort:short\n"
- "GLint:long\n"
- "GLsizei:unsigned long\n"
- "GLubyte:unsigned char\n"
- "GLushort:unsigned short\n"
- "GLuint:unsigned long\n"
- "GLfloat:float\n"
- "GLclampf:float\n"
- "GLdouble:double\n"
- "GLclampd:double\n"
- "GLboolean:enum ?\n"
- "GLenum:enum ?\n"
- "GLlookAt:struct GLlookAt\n"
- "GLproject:struct GLproject\n"
- "GLunProject:struct GLunProject\n"
- "GLfrustum:struct GLfrustum\n"
- "GLortho:struct GLortho\n"
- "GLbitmap:struct GLbitmap\n"
- "GLUquadricObj:struct GLUquadricObj\n"
- "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
- "GLUnurbsObj:struct GLUnurbsObj\n"
- "GLvisual:struct gl_visual\n"
- "GLframebuffer:struct gl_frame_buffer\n"
- "GLcontext:struct gl_context\n"
- "HGIDA_Stack:unsigned long *\n"
- "HGIDA_BoundedStack:unsigned long *\n"
- "HGIDA_Queue:unsigned long *\n"
- "HGIDA_BoundedQueue:unsigned long *\n"
- "HGIDA_List:unsigned long *\n"
- "HGIDA_ListItem:unsigned long *\n"
- "HGIDA_Error:enum ?\n"
- "HGIDA_Direction:enum ?\n"
- "uid_t:long\n"
- "gid_t:long\n"
- "mode_t:unsigned short\n"
- "pid_t:struct Task *\n"
- "fd_set:struct fd_set\n"
- "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 unsigned long, register __a1 const unsigned char *, register __a2 struct CSource *, register __a3 struct CSource *)\n"
- "pcap_t:struct pcap\n"
- "pcap_dumper_t:struct pcap_dumper\n"
- "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const unsigned char *)\n"
- "u_char:unsigned char\n"
- "bpf_u_int32:unsigned long\n"
- "Fixed:long\n"
- "sposition:long\n"
- "MPEGA_STREAM:struct MPEGA_STREAM\n"
- "MPEGA_CTRL:struct MPEGA_CTRL\n"
- "W3D_Context:struct W3DContext\n"
- "W3D_Driver:struct W3DDriver\n"
- "W3D_Texture:struct W3DTexture\n"
- "W3D_Scissor:struct W3DScissor\n"
- "W3D_Line:struct W3D_Line\n"
- "W3D_Point:struct W3D_Point\n"
- "W3D_Triangle:struct W3D_Triangle\n"
- "W3D_Triangles:struct W3D_Triangles\n"
- "W3D_Float:float\n"
- "W3D_Bitmap:struct W3D_Bitmap\n"
- "W3D_Fog:struct W3D_Fog\n"
- "W3D_Bool:short\n"
- "W3D_Double:double\n"
- "W3D_TriangleV:struct W3D_TriangleV\n"
- "W3D_TrianglesV:struct W3D_TriangleV\n"
- "W3D_ScreenMode:struct W3D_Screenmode\n"
- "W3D_Color:struct W3D_Color\n"
- "W3D_Lines:struct W3D_Lines\n"
- "RGBFTYPE:enum ?\n"
- "DITHERINFO:void *\n"
- "SLayer:void *\n"
- "va_list:char *\n"
- };
-
- static const struct CPP_TypeField CPP_Field[] = {
- {"int", 3, 0, CPP_TYPE_INT},
- {"long", 4, 0, CPP_TYPE_LONG},
- {"LONG", 4, 0, CPP_TYPE_LONG},
- {"BPTR", 4, 0, CPP_TYPE_LONG},
- {"BSTR", 4, 0, CPP_TYPE_LONG},
- {"CxObj", 5, 0, CPP_TYPE_LONG},
- {"CxMsg", 5, 0, CPP_TYPE_LONG},
- {"ULONG", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
- {"LONGBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
- {"CPTR", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
- {"Tag", 3, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
- {"Object", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
- {"short", 5, 0, CPP_TYPE_WORD},
- {"SHORT", 5, 0, CPP_TYPE_WORD},
- {"COUNT", 5, 0, CPP_TYPE_WORD},
- {"WORD", 4, 0, CPP_TYPE_WORD},
- {"USHORT", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
- {"UWORD", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
- {"UCOUNT", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
- {"WORDBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
- {"RPTR", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
- {"BOOL", 4, CPP_FLAG_BOOLEAN, CPP_TYPE_WORD},
- {"char", 4, 0, CPP_TYPE_BYTE},
- {"BYTE", 4, 0, CPP_TYPE_BYTE},
- {"UBYTE", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
- {"TEXT", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
- {"BYTEBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
- {"float", 5, 0, CPP_TYPE_FLOAT},
- {"FLOAT", 5, 0, CPP_TYPE_FLOAT},
- {"double", 6, 0, CPP_TYPE_DOUBLE},
- {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE},
- {"void", 4, 0, CPP_TYPE_VOID},
- {"VOID", 4, 0, CPP_TYPE_VOID},
- {"APTR", 4, CPP_FLAG_POINTER, CPP_TYPE_VOID},
- {"STRPTR", 6, CPP_FLAG_POINTER|CPP_FLAG_STRPTR, CPP_TYPE_BYTE},
- {"CONST_STRPTR",12,CPP_FLAG_POINTER|CPP_FLAG_CONST, CPP_TYPE_BYTE},
- {"ClassID", 7, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
- {"PLANEPTR", 8, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
- {0,0,0,0},
- };
-
- /* defaults: "Library" shortbname+".library" basename-last 4 chars */
- static const struct Proto_LibType Proto_LibTypes[] = {
- {"DOSBase", "DosLibrary", 0, 0},
- {"SysBase", "ExecBase", 0, 0},
- {"ExpansionBase", "ExpansionBase", 0, 0},
- {"GfxBase", "GfxBase", "graphics.library", "graphics"},
- {"IntuitionBase", "IntuitionBase", 0, 0},
- {"LocaleBase", "LocaleBase", 0, 0},
- {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
- {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
- {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
- {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
- {"RealTimeBase", "RealTimeBase", 0, 0},
- {"RexxSysBase", "RxsLib", 0, 0},
- {"UtilityBase", "UtilityBase", 0, 0},
- {"WorkbenchBase", 0, "workbench.library", "wb"},
- /* resources - The Node entries may be correct, but I don't know it. */
- {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
- {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
- {"CardResource", 0/*"Node"*/, "card.resource", "card"},
- {"DiskBase", "DiskResource", "disk.resource", 0},
- {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
- {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
- /* devices */
- {"ConsoleDevice", "Device", "console.device", "console"},
- {"InputBase", "Device", "input.device", 0},
- {"RamdriveDevice", "Device", "ramdrive.device", "ramdrive"},
- {"TimerBase", "Device", "timer.device", 0},
- /* non default Basenames */
- {"DatamasterBase", "DatamasterBase", 0, 0},
- {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
- {"ReqToolsBase", "ReqToolsBase", 0, 0},
- {"UnpackBase", "UnpackLibrary", 0, 0},
- {"xfdMasterBase", "xfdMasterBase", 0, 0},
- {"xadMasterBase", "xadMasterBase", 0, 0},
- {"xvsBase", "xvsBase", 0, 0},
- {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
- {"ArpBase", "ArpBase", 0, 0},
- {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
- {0, 0},
- };
-
- /* CachePostDMA, CachePreDMA are done by #?DMA check */
- static const struct Pragma_ExecpName Pragma_ExecpNames[] = {
- {"VFWritef", "FWritef"},
- {"VFPrintf", "FPrintf"},
- {"VPrintf", "Printf"},
- {"ReadArgs", 0},
- {"FreeArgs", 0},
- {"CloneTagItems", 0},
- {"FindTagItem", 0},
- {"FreeTagItems", 0},
- {"GetTagData", 0},
- {"PackBoolTags", 0},
- {"PackStructureTags", 0},
- {"UnpackStructureTags", 0},
- {"BGUI_PackStructureTags", 0},
- {"BGUI_UnpackStructureTags", 0},
- {"Inet_NtoA", 0}, /* socket.library */
- {"vsyslog", "syslog"},
- {"NewPPCStackSwap", 0},
- {0,0},
- };
-
- /* For double tagcall names (currently only necessary for dos.library and
- datatypes.library). Only one alias supported for a function! */
- static const struct Pragma_AliasName Pragma_AliasNames[] = {
- {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL},
- {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL},
- {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL},
- {"SystemTagList", "System", FUNCFLAG_NORMAL},
- {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG},
- {0,0,0},
- };
-
- /* special names, which get an x before name in BMAP files */
- static const strptr BMAPSpecial[] =
- {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
- "Translate", "Wait", "Write", 0};
-
- #define FIRST_KNOWN_RELEASE 30
- #define LAST_KNOWN_RELEASE 45
- static const strptr Release[] =
- {
- "Release 1.0", /* V30 */
- "Release 1.1", /* V31 */
- "Preliminary Release 1.2", /* V32 */
- "Release 1.2", /* V33 */
- "Release 1.3", /* V34 */
- "Release 1.3 A2024", /* V35 */
- "Release 2.0", /* V36 */
- "Release 2.04", /* V37 */
- "Release 2.1", /* V38 */
- "Release 3", /* V39 */
- "Release 3.1", /* V40 */
- "Transitional Release 3.2", /* V41 */
- "Transitional Release 3.3", /* V42 */
- "Transitional Release 3.4", /* V43 */
- "Release 3.5", /* V44 */
- "Release 3.9", /* V45 */
- };
-
- /* Keywords, which cannot be argument names. They are used case_insensitive to
- be sure they make no conflicts in non-C-languages as well.
- Currently these are mostly C keywords.
- */
- static const strptr Keywords[] =
- {
- "and", "and_eq", "asm", "auto", "bitand",
- "bitor", "break", "case", "catch", "char",
- "class", "compl", "const", "continue", "default",
- "delete", "do", "double", "else", "enum",
- "extern", "false", "float", "for", "friend",
- "goto", "if", "inline", "int", "long",
- "new", "not", "not_eq", "operator", "or",
- "or_eq", "private", "protected", "public", "register",
- "return", "short", "signed", "sizeof", "static",
- "struct", "switch", "template", "this", "throw",
- "true", "try", "typedef", "union", "unsigned",
- "virtual", "void", "volatile", "wchar_t", "while",
- "xor", "xor_eq",
- 0
- };
-
- #ifndef __SASC
- static int stricmp(const char *a, const char *b)
- {
- while(*a && tolower(*a) == tolower(*b))
- {
- ++a; ++b;
- }
- return (tolower(*a) - tolower(*b));
- }
-
- static int strnicmp(const char *a, const char *b, size_t num)
- {
- while(num && *a && tolower(*a) == tolower(*b))
- {
- ++a; ++b; --num;
- }
- return num ? (tolower(*a) - tolower(*b)) : 0;
- }
- #endif
-
- static strptr DupString(strptr Str, size_t Len)
- {
- strptr res;
- if((res = AllocListMem(Len+1)))
- {
- memcpy(res, Str, Len);
- res[Len] = '\0';
- }
- return res;
- }
-
- static strptr AllocListMem(size_t size)
- {
- strptr a;
- if((a = (strptr) malloc(size)))
- memset(a, 0, size);
- return a;
- }
-
- static strptr SkipBlanks(strptr OldPtr)
- {
- while(*OldPtr == ' ' || *OldPtr == '\t')
- ++OldPtr;
- return OldPtr;
- }
-
- static strptr SkipBlanksRet(strptr OldPtr)
- {
- while(*OldPtr == ' ' || *OldPtr == '\t' || *OldPtr == '\n')
- ++OldPtr;
- return OldPtr;
- }
-
- /*
- This function is used to skip over variable names.
-
- Inputs: OldPtr - pointer to the beginning of a string.
-
- Result: Pointer to the first character of the string, that is not one
- of a-z, A-Z, 0-9 or the underscore.
- */
-
- static strptr SkipName(strptr OldPtr)
- {
- while(isalnum(*OldPtr) || *OldPtr == '_')
- ++OldPtr;
- return OldPtr;
- }
-
- static strptr GetBaseType(void)
- {
- uint32 i;
-
- if(libtype)
- return libtype;
-
- for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
- {
- if(Proto_LibTypes[i].StructureName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
- {
- return Proto_LibTypes[i].StructureName;
- }
- }
- return "Library";
- }
-
- static strptr GetLibraryName(void)
- {
- uint32 i;
-
- if(libname)
- return libname;
-
- for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
- {
- if(Proto_LibTypes[i].LibraryName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
- {
- return (libname = Proto_LibTypes[i].LibraryName);
- }
- }
- if(!(libname = malloc(strlen(ShortBaseName)+9)))
- return 0;
-
- /* auto create name */
- for(i = 0; ShortBaseName[i]; ++i)
- libname[i] = ShortBaseName[i];
- strcpy(libname+i,".library");
- return libname;
- }
-
- static int32 MakeShortBaseName(void)
- {
- strptr ptr, p2;
- uint32 i;
-
- ptr = p2 = args.infile;
- while(*p2)
- {
- if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
- ptr = p2+1;
- ++p2;
- }
-
- /* first get name from file */
-
- p2 -= (sizeof(SFDFILEEXTENSION)-1);
- if(p2 > ptr && !stricmp(p2, SFDFILEEXTENSION))
- ShortBaseName = DupString(ptr, p2-ptr);
- p2 += sizeof(SFDFILEEXTENSION)-sizeof(FDFILEEXTENSION);
- if(p2 > ptr && !stricmp(p2, FDFILEEXTENSION))
- ShortBaseName = DupString(ptr, p2-ptr);
-
- /* then try exceptions (overriding filename) */
- if(BaseName)
- {
- for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
- {
- if(Proto_LibTypes[i].ShortBaseName && !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
- {
- ShortBaseName = Proto_LibTypes[i].ShortBaseName; break;
- }
- }
- /* and last use default method */
- if(!ShortBaseName)
- ShortBaseName = DupString(BaseName, strlen(BaseName)-4);
- }
-
- if(!ShortBaseName)
- return 0;
-
- ptr = ShortBaseName;
- while((*ptr = tolower(*ptr))) /* Convert to lowercase */
- ptr++;
-
- if((ShortBaseNameUpper = DupString(ShortBaseName, strlen(ShortBaseName))))
- {
- ptr = ShortBaseNameUpper;
- while((*ptr = toupper(*ptr))) /* Convert to uppercase */
- ptr++;
- }
- else
- return 0;
-
- return 1;
- }
-
- static uint32 OpenDest(strptr name)
- {
- static uint8 printedname = 0;
- strptr b, t;
-
- t = (strptr) tempbuf;
- if((b = args.to) && *b)
- {
- while(*b)
- *(t++) = *(b++);
- if(*(t-1) != ':' && *(t-1) != '/')
- *(t++) = '/';
- }
- *t = 0;
-
- if(!(Flags & FLAG_SINGLEFILE))
- printf("ResultFile: %s%s\n", tempbuf, name);
- else if(!printedname++)
- {
- printf("ResultType: %s", tempbuf); printf(filenamefmt, "*");
- printf("\n");
- }
-
- while(*name)
- *(t++) = *(name++);
- *t = 0;
-
- if(args.header)
- {
- HEADER = mygetfile((strptr)tempbuf, &headersize);
- FindHeader();
- }
-
- if((outfile = fopen((strptr)tempbuf, "wb")))
- return 1;
- DoError(ERR_OPEN_FILE, 0, tempbuf);
- return 0;
- }
-
- static uint32 CloseDest(strptr name)
- {
- if(outfile)
- {
- fclose(outfile);
- outfile = 0;
-
- if(!(Flags & FLAG_DONE) || !Output_Error)
- {
- strptr b, t;
- if(!Output_Error || !(Flags & FLAG_SINGLEFILE))
- DoError(ERR_EMPTY_FILE, 0);
-
- t = (strptr) tempbuf;
- if((b = args.to) && *b)
- {
- while(*b)
- *(t++) = *(b++);
- if(*(t-1) != ':' && *(t-1) != '/')
- *(t++) = '/';
- }
- while(*name)
- *(t++) = *(name++);
- *t = 0;
-
- remove((strptr)tempbuf);
- return 0;
- }
- Flags &= ~FLAG_DONE; /* clear the flag */
- }
- else
- return 0;
- return 1;
- }
-
- static uint32 MakeTagFunction(struct AmiPragma *ap)
- {
- size_t len = strlen(ap->FuncName);
- long i=0;
-
- #ifdef DEBUG_OLD
- printf("MakeTagFunction:\n");
- #endif
-
- if(!ap->NumArgs || ap->TagName)
- return 1;
-
- ++tagfuncs;
- ap->Flags |= AMIPRAGFLAG_OWNTAGFUNC;
-
- while(Pragma_ExecpNames[i].FunctionName && /* check the exception names */
- strcmp(ap->FuncName, Pragma_ExecpNames[i].FunctionName))
- ++i;
-
- if(Pragma_ExecpNames[i].FunctionName)
- {
- if(!(ap->TagName = Pragma_ExecpNames[i].TagName))
- {
- ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
- --tagfuncs;
- }
- }
- else if(ap->FuncName[len-1] == 'A')
- {
- if(!strcmp(ap->FuncName+len-3, "DMA") ||
- !strcmp(ap->FuncName+len-4, "MESA")) /* skip names with DMA or MESA at end */
- { ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC; --tagfuncs; return 1;}
- if(!(ap->TagName = DupString(ap->FuncName, len-1)))
- return 0;
- }
- else if(!strcmp(ap->FuncName + len-7, "TagList"))
- {
- if(!(ap->TagName = DupString(ap->FuncName, len-3)))
- return 0;
- ap->TagName[len-4] = 's';
- }
- else if(!strcmp(ap->FuncName + len-4, "Args"))
- {
- if(!(ap->TagName = DupString(ap->FuncName, len-4)))
- return 0;
- }
- else if(!stricmp(ap->Args[ap->NumArgs-1].ArgName, "tags") ||
- !stricmp(ap->Args[ap->NumArgs-1].ArgName, "taglist"))
- {
- if(!(ap->TagName = DupString(ap->FuncName, len+4)))
- return 0;
- memcpy(ap->TagName + len, "Tags", 5);
- }
- else if(!stricmp(ap->Args[ap->NumArgs-1].ArgName, "args"))
- {
- if(!(ap->TagName = DupString(ap->FuncName, len+4)))
- return 0;
- memcpy(ap->TagName + len, "Args", 5);
- }
- else
- {
- ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
- --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
- }
-
- return 1;
- }
-
- static void MakeLines(strptr buffer, uint32 size)
- {
- if(size && buffer)
- {
- /* make a real C++ zero string ending line */
- while(--size)
- {
- if(*buffer == '\n')
- *buffer = '\0';
- ++buffer;
- }
- *buffer = '\0';
- }
- }
-
- /* Do any special functions, which cannot be done with other exception
- stuff - currently only dos.library DoPkt function. */
- static uint32 SpecialFuncs(void)
- {
- struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last, *ap2 = (struct AmiPragma *) AmiPragma.First;
-
- /* first let one more go away, so we can detect if the DoPkt parts are
- already inserted in the FD file */
-
- while(ap2 && (struct AmiPragma *)(ap2->List.Next) != ap)
- ap2 = (struct AmiPragma *)(ap2->List.Next);
-
- if(ap2 && ap2->Bias == 0xF0 && ap->Bias != 0xF0 && !strcmp("DoPkt", ap2->FuncName))
- {
- struct AmiPragma *d;
- uint32 i;
-
- RemoveItem(&AmiPragma, (struct ShortList *) ap); /* add in correct order */
- for(i = 0; i < 5; ++i)
- {
- if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
- return 0;
- memcpy(d, ap2, sizeof(struct AmiPragma));
- d->FuncName = DupString(ap2->FuncName, 6);
- d->FuncName[5] = '0'+i;
- d->NumArgs = d->CallArgs = i + 2;
- AddItem(&AmiPragma, (struct ShortList *) d);
- }
- AddItem(&AmiPragma, (struct ShortList *) ap);
- }
- return 1;
- }
-
- static void SortFDList(void)
- {
- struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.First, *ap2, *ap3;
- AmiPragma.First = AmiPragma.Last = 0;
-
- while(ap)
- {
- ap3 = 0;
- ap2 = (struct AmiPragma *) AmiPragma.First;
-
- /* for FD2Inline style we need to use strcmp instead of stricmp here */
- while(ap2 && stricmp(ap2->FuncName, ap->FuncName) < 0)
- {
- ap3 = ap2;
- ap2 = (struct AmiPragma *) ap2->List.Next;
- }
-
- ap2 = ap;
- ap = (struct AmiPragma *) ap->List.Next;
-
- if(ap3)
- {
- ap2->List.Next = (struct ShortList *) ap3->List.Next;
- ap3->List.Next = (struct ShortList *) ap2;
- }
- else
- {
- ap2->List.Next = AmiPragma.First;
- AmiPragma.First = (struct ShortList *) ap2;
- }
- if(ap && !ap->List.Next)
- AmiPragma.Last = (struct ShortList *) ap2;
- }
- }
-
- static void AddAliasName(struct AmiPragma *ap, struct Pragma_AliasName *alias, uint32 linenum)
- {
- uint32 i;
-
- if(ap->NumAlias > NUMALIASNAMES)
- DoError(ERR_ALIASNAMES, linenum, NUMALIASNAMES);
- else
- {
- /* prevent double names */
- for(i = 0; i < ap->NumAlias; ++i)
- {
- if(!strcmp(ap->AliasName[i]->AliasName, alias->AliasName))
- return;
- }
- ap->AliasName[ap->NumAlias++] = alias;
- }
- }
-
- static uint32 CheckNames(struct AmiPragma *ap)
- {
- uint32 i, j;
- const strptr *k;
-
- #ifdef DEBUG_OLD
- printf("CheckNames\n");
- #endif
- for(i = 0; i < ap->CallArgs; ++i)
- {
- if(!ap->Args[i].ArgName)
- {
- if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
- return 0;
- sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
- }
- else
- {
- for(k = Keywords; *k; ++k)
- {
- if(!stricmp(ap->Args[i].ArgName, *k))
- {
- DoError(ERR_ARGNAME_KEYWORD_CONFLICT, ap->Line, i, *k);
- if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
- return 0;
- sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
- }
- }
- for(j = 0; j < i; ++j)
- {
- if(!stricmp(ap->Args[i].ArgName, ap->Args[j].ArgName))
- {
- DoError(ERR_ARGNAME_ARGNAME_CONFLICT, ap->Line, i+1, j+1);
- if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
- return 0;
- sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
- }
- }
- }
- }
- /* NOTE: the replaced argument names aren't checked for conflicts */
- /* replaced names are of style a0arg */
- return 1;
- }
-
- static uint32 ScanSFDFile(uint32 abi)
- {
- uint32 _public = 1;
- int32 bias = -1;
- uint32 linenum;
- uint32 actcom = 0;
- uint32 functype = 0;
-
- Flags2 |= FLAG2_SFDMODE;
-
- for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
- {
- if(*in.pos == '*')
- {
- if(actcom)
- *(in.pos-1) = '\n';
- else
- {
- struct Comment *d;
- if(!(d = (struct Comment *) NewItem(&Comment)))
- return 0;
- d->Bias = bias;
- d->Data = in.pos;
- d->ReservedNum = 0;
- d->Version = 0;
- d->Private = _public ? 0 : 1;
- AddItem(&Comment, (struct ShortList *) d);
- actcom = 1;
- }
- while(*in.pos)
- ++in.pos;
- }
- else if(*in.pos == '=' && in.pos[1] == '=')
- {
- in.pos += 2;
- actcom = 0; /* no Comment */
-
- if(!strnicmp(in.pos, "basetype", 8))
- {
- #ifdef DEBUG
- printf("ScanSFDFile: found ==basetype\n");
- #endif
- if(!(Flags2 & FLAG2_LIBTYPE))
- {
- if(libtype)
- DoError(ERR_LIBTYPE_DECLARED_TWICE, linenum);
-
- in.pos = SkipBlanks(in.pos+8);
- if(strncmp(in.pos, "struct", 6))
- DoError(ERR_EXPECTED_STRUCT, linenum);
- else
- {
- in.pos = SkipBlanks(in.pos+6);
- if(!*in.pos)
- DoError(ERR_EXPECTED_LIBTYPE, linenum);
- else
- {
- libtype = in.pos;
- in.pos = SkipName(libtype);
- if(*SkipBlanks(in.pos) != '*')
- DoError(ERR_EXPECTED_POINTERSIGN, linenum);
- if(*in.pos)
- *(in.pos++) = 0;
- }
- }
- }
- else
- DoError(ERR_COMMANDLINE_LIBTYPE, linenum);
- while(*in.pos)
- ++in.pos;
- }
- if(!strnicmp(in.pos, "libname", 8))
- {
- #ifdef DEBUG
- printf("ScanSFDFile: found ==libname\n");
- #endif
- if(!(Flags2 & FLAG2_LIBNAME))
- {
- if(libname)
- DoError(ERR_LIBNAME_DECLARED_TWICE, linenum);
-
- in.pos = SkipBlanks(in.pos+8);
- if(strncmp(in.pos, "struct", 6))
- DoError(ERR_EXPECTED_STRUCT, linenum);
- else
- {
- in.pos = SkipBlanks(in.pos+6);
- if(!*in.pos)
- DoError(ERR_EXPECTED_LIBNAME, linenum);
- else
- {
- libtype = in.pos;
- in.pos = SkipName(libname);
- if(*SkipBlanks(in.pos) != '*')
- DoError(ERR_EXPECTED_POINTERSIGN, linenum);
- if(*in.pos)
- *(in.pos++) = 0;
- }
- }
- }
- else
- DoError(ERR_COMMANDLINE_LIBNAME, linenum);
- while(*in.pos)
- ++in.pos;
- }
- else if(!strnicmp(in.pos, "base", 4))
- {
- strptr oldptr;
-
- #ifdef DEBUG
- printf("ScanSFDFile: found ==base\n");
- #endif
- if(!(Flags & FLAG_BASENAME))
- {
- if(BaseName)
- DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
-
- in.pos = SkipBlanks(in.pos+4);
- if(*in.pos != '_')
- DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
- else
- ++in.pos;
-
- BaseName = oldptr = in.pos;
- in.pos = SkipName(in.pos);
- if(!(in.pos-oldptr))
- DoError(ERR_EXPECTED_BASENAME, linenum);
- }
- else
- {
- DoError(ERR_COMMANDLINE_BASENAME, linenum);
- while(*in.pos)
- ++in.pos;
- }
- }
- else if(!strnicmp(in.pos, "bias", 4))
- {
- strptr ptr;
- int32 newbias;
-
- #ifdef DEBUG
- printf("ScanSFDFile: found ==bias\n");
- #endif
- in.pos += 5;
- newbias = strtol(in.pos, &ptr, 10);
- if(ptr == in.pos)
- DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
- else if(newbias < 0)
- {
- DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
- bias = -newbias;
- }
- else
- bias = newbias;
- in.pos = SkipName(in.pos);
- }
- else if(!strnicmp(in.pos, "end", 3))
- {
- bias = 0; break;
- }
- else if(!strnicmp(in.pos, "public", 6))
- {
- in.pos += 6;
- _public = 1;
- }
- else if(!strnicmp(in.pos, "private", 7))
- {
- in.pos += 7;
- _public = 0;
- }
- else if(!strnicmp(in.pos, "abi", 3))
- {
- #ifdef DEBUG
- printf("ScanSFDFile: found ==abi\n");
- #endif
- in.pos = SkipBlanks(in.pos+3);
- if(!strnicmp(in.pos, "M68k", 4))
- {
- abi = ABI_M68K; in.pos += 4;
- }
- else if(!strnicmp(in.pos, "PPC0", 4))
- {
- abi = ABI_PPC0; in.pos += 4;
- }
- else if(!strnicmp(in.pos, "PPC2", 4))
- {
- abi = ABI_PPC2; in.pos += 4;
- }
- else if(!strnicmp(in.pos, "PPC", 3))
- {
- abi = ABI_PPC; in.pos += 3;
- }
- else
- DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
- }
- else if(!strnicmp(in.pos, "id", 2))
- {
- if(IDstring)
- DoError(ERR_IDSTRING_DECLARED_TWICE, linenum);
- IDstring = in.pos = SkipBlanks(in.pos+2);
- if(strncmp(in.pos, "$Id: ", 5))
- {
- DoError(ERR_EXCPECTED_IDSTRING, linenum);
- }
- while(*in.pos)
- ++in.pos;
- if(*(in.pos-1) != '$')
- DoError(ERR_EXPECTED_ID_ENDSIGN, linenum);
- }
- else if(!strnicmp(in.pos, "include", 7))
- {
- struct Include *d;
-
- if(!(d = (struct Include *) NewItem(&Includes)))
- return 0;
- d->Include = SkipBlanks(in.pos+7);
- AddItem(&Includes, (struct ShortList *) d);
- while(*in.pos)
- ++in.pos;
- }
- else if(!strnicmp(in.pos, "varargs", 7))
- {
- if(bias == -1)
- DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
- else
- {
- if(!functype)
- bias -= BIAS_OFFSET;
- functype |= FUNCFLAG_TAG;
- }
- in.pos += 7;
- }
- else if(!strnicmp(in.pos, "alias", 5))
- {
- if(bias == -1)
- DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
- else
- {
- if(!functype)
- bias -= BIAS_OFFSET;
- functype |= FUNCFLAG_ALIAS;
- }
- in.pos += 5;
- }
- else if(!strnicmp(in.pos, "version", 7))
- {
- /* store version entries as comments */
- struct Comment *d;
- strptr ptr;
- int16 v;
-
- in.pos = SkipBlanks(in.pos+7);
- v = strtol(in.pos, &ptr, 10);
- #ifdef DEBUG
- printf("ScanSFDFile: found ==version %d\n", v);
- #endif
- if(ptr == in.pos || v < 0)
- DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
- else
- {
- if(!(d = (struct Comment *) NewItem(&Comment)))
- return 0;
- d->Bias = bias;
- d->Data = 0;
- d->ReservedNum = 0;
- d->Version = v;
- d->Private = _public ? 0 : 1;
- AddItem(&Comment, (struct ShortList *) d);
- in.pos = SkipName(in.pos);
- }
- }
- else if(!strnicmp(in.pos, "reserve", 7))
- {
- /* store reserved entries as comments */
- struct Comment *d;
- strptr ptr;
- int16 v;
-
- in.pos = SkipBlanks(in.pos+7);
- v = strtol(in.pos, &ptr, 10);
- #ifdef DEBUG
- printf("ScanSFDFile: found ==reserve %d\n", v);
- #endif
- if(bias == -1)
- {
- DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
- bias = BIAS_START;
- }
-
- if(ptr == in.pos || v < 0)
- DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
- else
- {
- if(!(d = (struct Comment *) NewItem(&Comment)))
- return 0;
- d->Bias = bias;
- d->Data = 0;
- d->ReservedNum = v;
- d->Version = 0;
- d->Private = _public ? 0 : 1;
- AddItem(&Comment, (struct ShortList *) d);
- in.pos = SkipName(in.pos);
- bias += BIAS_OFFSET*v;
- }
- }
- else
- DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
- }
- else /* function */
- {
- uint32 ft, startlinenum;
- struct AmiPragma ap, *ap2;
- struct ClibData d, *f;
- strptr oldptr;
- uint32 maxreg;
- strptr data;
-
- actcom = 0;
- maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
- /* join lines, if necessary */
- startlinenum = linenum;
- data = in.pos;
- while(*data != '('/*)*/ && data < in.buf + in.size) /* first open bracket */
- { if(!*data) {*data = ' '; ++linenum; } ++data; }
- ++data;
- ft = 0; /* this is needed for function pointer types, which have own brackets */
- while((*data != /*(*/')' || ft) && data < in.buf + in.size) /* first close bracket */
- {
- if(!*data)
- {
- *data = ' ';
- ++linenum;
- }
- else if(*data == '('/*)*/)
- ++ft;
- else if(*data == /*(*/')')
- --ft;
- ++data;
- }
- while(*data != '('/*)*/ && data < in.buf + in.size) /* second open bracket */
- { if(!*data) {*data = ' '; ++linenum; } ++data; }
- while(*data != /*(*/')' && data < in.buf + in.size) /* second close bracket */
- { if(!*data) {*data = ' '; ++linenum; } ++data; }
- if(data == in.buf + in.size)
- {
- in.pos = data;
- DoError(ERR_UNEXPECTED_FILEEND, linenum);
- continue;
- }
-
- ft = functype; functype = 0;
- memset(&ap, 0, sizeof(struct AmiPragma));
- memset(&d, 0, sizeof(struct ClibData));
- if(!GetCPPType(&d.ReturnType, in.pos, 1))
- {
- DoError(ERR_UNKNOWN_RETURNVALUE_TYPE, startlinenum);
- while(*(in.pos++))
- ;
- continue;
- }
- ap.FuncName = d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
- in.pos = SkipBlanks(SkipName(d.FuncName));
- ;
- if(*in.pos != '('/*)*/)
- {
- DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
- ++in.pos;
- continue;
- }
- *(SkipName(d.FuncName)) = 0;
- in.pos = SkipBlanks(++in.pos);
-
- oldptr = 0;
- while(*in.pos && *in.pos != /*(*/')')
- {
- oldptr = (strptr) 1;
- if(d.NumArgs >= maxreg)
- {
- DoError(ERR_TO_MUCH_ARGUMENTS, startlinenum);
- return 0;
- }
- else if(!GetCPPType(&d.Args[d.NumArgs++], in.pos, 0))
- {
- DoError(ERR_UNKNOWN_VARIABLE_TYPE, startlinenum, d.NumArgs);
- break;
- }
-
- oldptr = in.pos = SkipBlanks(d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength);
- if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS)
- {
- if(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION)
- {
- oldptr = d.Args[d.NumArgs-1].FunctionName;
- if(!oldptr)
- {
- DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
- break;
- }
- else if(!(oldptr = DupString(oldptr, SkipName(oldptr)-oldptr)))
- return 0;
- ap.Args[ap.CallArgs++].ArgName = oldptr;
- }
- else
- {
- ap.Args[ap.CallArgs++].ArgName = in.pos;
- in.pos = SkipName(in.pos);
-
- if(in.pos == oldptr)
- {
- DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
- break;
- }
- }
- }
- else
- ++ap.CallArgs;
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos != ',' && *in.pos != /*(*/')')
- {
- DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
- break;
- }
- if(*in.pos == ')')
- {
- in.pos = SkipBlanks(++in.pos);
- if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS && !(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION))
- *(SkipName(oldptr)) = 0;
- #ifdef DEBUG_OLD
- printf("Added last argument %ld (%s) for %s (%ld bytes)\n", d.NumArgs, oldptr, d.FuncName,
- d.Args[d.NumArgs-1].FullLength);
- #endif
- oldptr = 0;
- break;
- }
- else
- {
- in.pos = SkipBlanks(++in.pos);
- *(SkipName(oldptr)) = 0;
- #ifdef DEBUG_OLD
- printf("Added argument %ld (%s) for %s (%ld bytes)\n", d.NumArgs, oldptr, d.FuncName,
- d.Args[d.NumArgs-1].FullLength);
- #endif
- }
- }
- if(*in.pos == /*(*/')')
- ++in.pos;
- if(!oldptr) /* oldptr == 0 means parsing was valid */
- {
- if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
- return -1;
-
- memcpy(f, &d, sizeof(struct ClibData));
-
- if(!clibdata)
- clibdata = f;
- else
- {
- struct ClibData *e = clibdata;
- while(e->Next)
- e = e->Next;
- e->Next = f;
- }
-
- #ifdef DEBUG_OLD
- printf("Added prototype for %s (line %ld) with %ld args\n", f->FuncName, startlinenum, f->NumArgs);
- #endif
- if(*(in.pos = SkipBlanks(in.pos)) != '('/*)*/)
- {
- DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
- ++in.pos;
- continue;
- }
-
- if(bias == -1)
- {
- DoError(ERR_ASSUMING_BIAS_OF_30, startlinenum);
- bias = BIAS_START;
- }
-
- ap.Bias = bias;
- ap.Abi = abi;
- ap.Line = startlinenum;
- bias += BIAS_OFFSET;
-
- if(_public)
- ap.Flags |= AMIPRAGFLAG_PUBLIC;
-
- if(abi != ABI_M68K)
- {
- while(*in.pos && *in.pos != /*(*/')')
- ++in.pos;
- if(*in.pos != /*(*/')')
- {
- DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
- ++in.pos;
- continue;
- }
- ++in.pos;
- ap.NumArgs = ap.CallArgs;
-
- ap.Flags |= AMIPRAGFLAG_PPC;
- if(abi == ABI_PPC0)
- ap.Flags |= AMIPRAGFLAG_PPC0;
- else if(abi == ABI_PPC2)
- ap.Flags |= AMIPRAGFLAG_PPC2;
- }
- else
- {
- uint32 len;
-
- do
- {
- uint32 i;
-
- oldptr = in.pos = SkipBlanks(in.pos+1);
-
- if(*in.pos == /*(*/')' && !ap.NumArgs)
- break;
-
- in.pos = SkipName(oldptr);
- len = in.pos-oldptr;
-
- for(i = 0; i < MAXREG; ++i)
- if(!strnicmp(RegNames[i], oldptr, len))
- break;
-
- if(i == MAXREG)
- {
- DoError(ERR_EXPECTED_REGISTER_NAME, startlinenum);
- break;
- }
- else if(i == REG_A6)
- ap.Flags |= AMIPRAGFLAG_A6USE;
- else if(i == REG_A5)
- ap.Flags |= AMIPRAGFLAG_A5USE;
- else if(i == REG_A4)
- ap.Flags |= AMIPRAGFLAG_A4USE;
- else if(i == REG_D7)
- ap.Flags |= AMIPRAGFLAG_D7USE;
- else if(i == REG_A7)
- {
- DoError(ERR_A7_NOT_ALLOWED, startlinenum);
- break;
- }
- else if(i >= REG_FP0)
- ap.Flags |= AMIPRAGFLAG_FLOATARG;
-
- ap.Args[ap.NumArgs].ArgReg = i;
-
- for(i = 0; i < ap.NumArgs; i++)
- {
- if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
- {
- DoError(ERR_REGISTER_USED_TWICE, startlinenum);
- break;
- }
- }
- if(i < ap.NumArgs)
- break;
-
- ++ap.NumArgs;
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos != ',' && *in.pos != '-' && *in.pos != '/' && *in.pos != /*(*/')')
- {
- DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
- break;
- }
- } while(*in.pos != /*(*/')');
-
- if(*in.pos != /*(*/')')
- {
- while(*(in.pos++))
- ++in.pos;
- continue;
- }
- else
- ++in.pos;
- }
- ap2 = (struct AmiPragma *)(AmiPragma.Last);
- if(ft && !(ft & FUNCFLAG_TAG) && ap.NumArgs != ap2->NumArgs)
- ft = 0; /* like DoPkt, handle as seperate function */
- if(ft) /* handle alias and varargs */
- {
- if(ap2->TagName || (ft & FUNCFLAG_ALIAS))
- {
- struct Pragma_AliasName *p;
-
- if((p = (struct Pragma_AliasName *)AllocListMem(sizeof(struct Pragma_AliasName))))
- {
- p->FunctionName = ap2->TagName;
- p->AliasName = ap.FuncName;
- p->Type = (ft & FUNCFLAG_TAG) ? FUNCFLAG_TAG : FUNCFLAG_NORMAL;
- AddAliasName(ap2, p, startlinenum);
- }
- else
- return 0;
- }
- else
- {
- ap2->TagName = ap.FuncName;
- ++tagfuncs;
- }
- if(ap.CallArgs != ap2->CallArgs)
- {
- if(ap2->CallArgs + 1 == ap.CallArgs && d.Args[d.NumArgs-1].Type == CPP_TYPE_VARARGS)
- {
- --ap.CallArgs;
- if(abi != ABI_M68K)
- --ap.NumArgs;
- }
- }
- if(ap.NumArgs != ap2->NumArgs)
- {
- DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
- }
- else if(abi == ABI_M68K)
- {
- uint32 i;
-
- for(i = 0; i < ap2->NumArgs; ++i)
- {
- if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
- {
- DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
- break;
- }
- }
- }
- }
- else if(abi == ABI_M68K)
- {
- if(ap.CallArgs != ap.NumArgs)
- { /* this is surely no longer necessary, as there wont be any varargs functions here */
- if(ap.CallArgs == ap.NumArgs+1 && d.Args[d.NumArgs-1].Type == CPP_TYPE_VARARGS)
- --ap.CallArgs;
- else
- ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
- }
-
- ap.Flags |= AMIPRAGFLAG_M68K;
-
- if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
- DoError(ERR_FLOATARG_NOT_ALLOWED, startlinenum);
- else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
- && !(Flags & FLAG_PPCONLY))
- { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
- struct AmiPragma *d;
- if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
- return 0;
- memcpy(d, &ap, sizeof(struct AmiPragma));
- if(!CheckNames(d))
- return 0;
- AddItem(&AmiPragma, (struct ShortList *) d);
- }
- }
- else
- {
- if(!(Flags & FLAG_NOPPC))
- {
- struct AmiPragma *d;
- if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
- return 0;
- memcpy(d, &ap, sizeof(struct AmiPragma));
- if(!CheckNames(d))
- return 0;
- AddItem(&AmiPragma, (struct ShortList *) d);
- }
- }
- }
- }
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos)
- DoError(ERR_EXTRA_CHARACTERS, linenum);
- ++in.pos; /* skip '\0' */
- }
-
- if(bias)
- DoError(ERR_MISSING_SFDEND, 0);
-
- return 1;
- }
-
- static uint32 ScanFDFile(void)
- {
- uint32 _public = 1;
- int32 bias = -1;
- uint32 linenum;
- size_t len;
- uint32 actcom = 0;
- uint32 shadowmode = 0;
- uint32 abi = ABI_M68K;
-
- if(defabi)
- {
- if(!stricmp(defabi, "M68k"))
- abi = ABI_M68K;
- else if(!stricmp(defabi, "PPC0"))
- abi = ABI_PPC0;
- else if(!stricmp(defabi, "PPC2"))
- abi = ABI_PPC2;
- else if(!stricmp(defabi, "PPC"))
- abi = ABI_PPC;
- else
- DoError(ERR_UNKNOWN_ABI, 0, defabi);
- }
-
- if(in.size > 10 && in.pos[0] == '=' && in.pos[1] == '=' && in.pos[2] == 'i' && in.pos[3] == 'd')
- return ScanSFDFile(abi);
-
- #ifdef DEBUG_OLD
- printf("ScanFDFile:\n");
- #endif
-
- for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
- {
- if(*in.pos == '*') /* Comment */
- {
- strptr oldpos = in.pos;
- #ifdef DEBUG_OLD
- printf("ScanFDFile: found a comment\n");
- #endif
- in.pos = SkipBlanks(in.pos+1);
- if(!strnicmp(in.pos, "notagcall", 9))
- {
- struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last;
-
- if(ap->TagName)
- {
- --tagfuncs; ap->TagName = 0;
- ap->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
- }
- in.pos = SkipBlanks(in.pos + 9);
- }
- else if(!strnicmp(in.pos, "tagcall", 7)) /* Tag to create? */
- {
- struct AmiPragma *prevpragma = (struct AmiPragma *) AmiPragma.Last;
-
- in.pos = SkipBlanks(in.pos + 7);
- if(!prevpragma)
- {
- DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
- ++in.pos;
- continue;
- }
-
- if(!prevpragma->NumArgs)
- {
- DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
- ++in.pos;
- continue;
- }
-
- /* Get the tag functions name. */
-
- if(!prevpragma->TagName && (_public || (Flags & FLAG_PRIVATE)))
- ++tagfuncs;
-
- if(*in.pos)
- {
- strptr oldptr, tptr = prevpragma->TagName;
-
- len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
- if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len)))
- return 0;
-
- if(*in.pos == '-')
- {
- strptr removeptr;
-
- oldptr = in.pos = SkipBlanks(in.pos+1);
- in.pos = SkipName(in.pos);
- if((len = in.pos-oldptr))
- {
- removeptr = prevpragma->TagName+strlen(prevpragma->TagName)-len;
- if(strncmp(removeptr, oldptr, len))
- {
- #ifdef DEBUG_OLD
- printf("ScanFDFile: *tagcall -: %s, %s, %ld\n", removeptr, oldptr, len);
- #endif
- DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
- prevpragma->TagName = tptr;
- ++in.pos;
- continue;
- }
-
- *removeptr = '\0';
- }
- in.pos = SkipBlanks(in.pos);
- }
- if(*in.pos == '+')
- in.pos = SkipBlanks(in.pos+1);
- else
- *in.pos = toupper(*in.pos);
-
- in.pos = SkipName((oldptr = in.pos));
- len = in.pos-oldptr;
- if(len)
- {
- uint32 a = strlen(prevpragma->TagName);
- memcpy(prevpragma->TagName+a, oldptr, len);
- prevpragma->TagName[a+len] = '\0';
- }
- }
- else if(!prevpragma->TagName)
- {
- len = strlen(prevpragma->FuncName);
- if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len+4)))
- return 0;
- memcpy(prevpragma->TagName + len, "Tags", 5);
- }
- }
- else
- {
- if(actcom)
- *(oldpos-1) = '\n';
- else
- {
- struct Comment *d;
- if(!(d = (struct Comment *) NewItem(&Comment)))
- return 0;
- d->Bias = bias;
- d->Data = oldpos;
- d->ReservedNum = 0;
- d->Version = 0;
- d->Private = _public ? 0 : 1;
- AddItem(&Comment, (struct ShortList *) d);
- actcom = 1;
- }
- while(*in.pos)
- ++in.pos;
- }
- }
- else if(*in.pos == '#' && in.pos[1] == '#')
- {
- in.pos += 2;
- actcom = 0; /* no Comment */
-
- if(!strnicmp(in.pos, "base", 4))
- {
- strptr oldptr;
-
- #ifdef DEBUG_OLD
- printf("ScanFDFile: found ##base\n");
- #endif
- if(!(Flags & FLAG_BASENAME))
- {
- if(BaseName)
- DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
-
- in.pos = SkipBlanks(in.pos+4);
- if(*in.pos != '_')
- DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
- else
- ++in.pos;
-
- BaseName = oldptr = in.pos;
- in.pos = SkipName(in.pos);
- if(!(in.pos-oldptr))
- DoError(ERR_EXPECTED_BASENAME, linenum);
- }
- else
- {
- DoError(ERR_COMMANDLINE_BASENAME, linenum);
- while(*in.pos)
- ++in.pos;
- }
- }
- else if(!strnicmp(in.pos, "bias", 4))
- {
- strptr ptr;
- int32 newbias;
-
- #ifdef DEBUG_OLD
- printf("ScanFDFile: found ##bias\n");
- #endif
- in.pos += 5;
- newbias = strtol(in.pos, &ptr, 10);
- if(ptr == in.pos)
- DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
- else if(newbias < 0)
- {
- DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
- bias = -newbias;
- }
- else
- bias = newbias;
- in.pos = SkipName(in.pos);
- }
- else if(!strnicmp(in.pos, "end", 3))
- {
- bias = 0; break;
- }
- else if(!strnicmp(in.pos, "shadow", 6)) /* introduced by Storm */
- {
- in.pos += 6;
- if(bias == -1 || !AmiPragma.First)
- DoError(ERR_EARLY_SHADOW, linenum);
- else
- {
- bias -= BIAS_OFFSET;
- shadowmode = 1;
- }
- }
- else if(!strnicmp(in.pos, "public", 6))
- {
- in.pos += 6;
- _public = 1;
- }
- else if(!strnicmp(in.pos, "private", 7))
- {
- in.pos += 7;
- _public = 0;
- }
- else if(!strnicmp(in.pos, "abi", 3))
- {
- #ifdef DEBUG_OLD
- printf("ScanFDFile: found ##abi\n");
- #endif
- in.pos = SkipBlanks(in.pos+3);
- if(!strnicmp(in.pos, "M68k", 4))
- {
- abi = ABI_M68K; in.pos += 4;
- }
- else if(!strnicmp(in.pos, "PPC0", 4))
- {
- abi = ABI_PPC0; in.pos += 4;
- }
- else if(!strnicmp(in.pos, "PPC2", 4))
- {
- abi = ABI_PPC2; in.pos += 4;
- }
- else if(!strnicmp(in.pos, "PPC", 3))
- {
- abi = ABI_PPC; in.pos += 3;
- }
- else
- DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
- }
- else
- DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
- }
- else
- {
- strptr oldptr;
- uint32 maxreg;
- struct AmiPragma ap, *ap2;
-
- #ifdef DEBUG_OLD
- printf("ScanFDFile: scan Function\n");
- #endif
- memset(&ap, 0, sizeof(struct AmiPragma));
- actcom = 0;
-
- oldptr = in.pos = SkipBlanks(in.pos);
- in.pos = SkipName(oldptr);
- if(!(len = in.pos-oldptr))
- {
- DoError(ERR_MISSING_FUNCTION_NAME, linenum);
- ++in.pos;
- continue;
- }
-
- ap.FuncName = oldptr;
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos != '('/*)*/)
- {
- DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
- ++in.pos;
- continue;
- }
-
- *in.pos = '\0'; /* create c string of FunctionName */
-
- #ifdef DEBUG_OLD
- printf("ScanFDFile: found function %s\n", ap.FuncName);
- #endif
-
- maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
- do
- {
- oldptr = in.pos = SkipBlanks(in.pos+1);
-
- if(*in.pos == /*(*/')' && !ap.CallArgs)
- break;
-
- if(ap.CallArgs >= maxreg)
- {
- DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
- }
-
- in.pos = SkipName(oldptr);
- if(*in.pos == '*')
- ++in.pos;
- if(!(len = in.pos-oldptr))
- {
- DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
- break;
- }
-
- ap.Args[ap.CallArgs++].ArgName = oldptr;
- oldptr = in.pos;
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
- {
- DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
- break;
- }
- if(*in.pos != /*(*/')') /* create c string ending */
- *oldptr = '\0';
- } while(*in.pos != /*(*/')');
-
- if(*in.pos != /*(*/')')
- {
- while(*(in.pos++))
- ++in.pos;
- continue;
- }
- else
- *oldptr = '\0'; /* create c string ending for last argument */
-
- if(*(in.pos = SkipBlanks(in.pos+1)) != '('/*)*/)
- {
- DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
- ++in.pos;
- continue;
- }
-
- if(bias == -1)
- {
- DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
- bias = BIAS_START;
- }
-
- ap.Bias = bias;
- ap.Abi = abi;
- ap.Line = linenum;
- bias += BIAS_OFFSET;
-
- if(_public)
- ap.Flags |= AMIPRAGFLAG_PUBLIC;
-
- if(abi == ABI_M68K)
- {
- do
- {
- uint32 i;
-
- oldptr = in.pos = SkipBlanks(in.pos + 1);
-
- if(*in.pos == /*(*/')' && !ap.NumArgs)
- break;
-
- in.pos = SkipName(oldptr);
- len = in.pos-oldptr;
-
- for(i = 0; i < MAXREG; ++i)
- if(!strnicmp(RegNames[i], oldptr, len))
- break;
-
- if(i == MAXREG)
- {
- DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
- break;
- }
- else if(i == REG_A6)
- ap.Flags |= AMIPRAGFLAG_A6USE;
- else if(i == REG_A5)
- ap.Flags |= AMIPRAGFLAG_A5USE;
- else if(i == REG_A4)
- ap.Flags |= AMIPRAGFLAG_A4USE;
- else if(i == REG_D7)
- ap.Flags |= AMIPRAGFLAG_D7USE;
- else if(i == REG_A7)
- {
- DoError(ERR_A7_NOT_ALLOWED, linenum);
- break;
- }
- else if(i >= REG_FP0)
- ap.Flags |= AMIPRAGFLAG_FLOATARG;
-
- ap.Args[ap.NumArgs].ArgReg = i;
-
- for(i = 0; i < ap.NumArgs; i++)
- {
- if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
- {
- DoError(ERR_REGISTER_USED_TWICE, linenum);
- break;
- }
- }
- if(i < ap.NumArgs)
- break;
-
- ++ap.NumArgs;
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
- {
- DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
- break;
- }
- } while(*in.pos != /*(*/')');
-
- if(*in.pos != /*(*/')')
- {
- while(*(in.pos++))
- ++in.pos;
- continue;
- }
- else
- ++in.pos;
- }
- else
- {
- while(*in.pos && *in.pos != /*(*/')')
- ++in.pos;
- if(*in.pos != /*(*/')')
- {
- DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
- ++in.pos;
- continue;
- }
- ++in.pos;
- ap.NumArgs = ap.CallArgs;
-
- ap.Flags |= AMIPRAGFLAG_PPC;
- if(abi == ABI_PPC0)
- ap.Flags |= AMIPRAGFLAG_PPC0;
- else if(abi == ABI_PPC2)
- ap.Flags |= AMIPRAGFLAG_PPC2;
- }
-
- ap2 = (struct AmiPragma *)(AmiPragma.Last);
- if(shadowmode)
- {
- if(ap2->TagName && !(ap2->Flags & AMIPRAGFLAG_OWNTAGFUNC))
- {
- struct Pragma_AliasName *p;
- DoError(ERR_DOUBLE_VARARGS, linenum);
-
- if((p = (struct Pragma_AliasName *)AllocListMem(sizeof(struct Pragma_AliasName))))
- {
- p->FunctionName = ap2->TagName;
- p->AliasName = ap.FuncName;
- p->Type = FUNCFLAG_TAG;
- AddAliasName(ap2, p, linenum);
- }
- else
- return 0;
- #ifdef DEBUG
- printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2->TagName);
- #endif
- }
- else
- {
- #ifdef DEBUG
- printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2->TagName);
- #endif
- ap2->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
- ap2->TagName = ap.FuncName;
- ++tagfuncs;
- }
- if(ap.NumArgs != ap2->NumArgs)
- DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
- else if(abi == ABI_M68K)
- {
- uint32 i;
-
- for(i = 0; i < ap2->NumArgs; ++i)
- {
- if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
- {
- DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
- break;
- }
- }
- }
- }
- else if(ap2 && ap2->Bias == ap.Bias && ap2->NumArgs == ap.NumArgs) /* handle them as alias instead seperate */
- {
- struct Pragma_AliasName *p;
-
- if((p = (struct Pragma_AliasName *)AllocListMem(sizeof(struct Pragma_AliasName))))
- {
- p->FunctionName = ap2->TagName;
- p->AliasName = ap.FuncName;
- p->Type = FUNCFLAG_NORMAL;
- AddAliasName(ap2, p, linenum);
- }
- if(abi == ABI_M68K)
- {
- uint32 i;
-
- for(i = 0; i < ap2->NumArgs; ++i)
- {
- if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
- {
- DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
- break;
- }
- }
- }
- }
- else
- {
- if((_public || (Flags & FLAG_PRIVATE)) && !MakeTagFunction(&ap))
- return 0;
- else /* check the alias names */
- {
- uint32 i = 0;
-
- while(Pragma_AliasNames[i].FunctionName)
- {
- if(!strcmp(ap.FuncName, Pragma_AliasNames[i].FunctionName) ||
- (ap.TagName && !strcmp(ap.TagName, Pragma_AliasNames[i].FunctionName)))
- {
- AddAliasName(&ap, (struct Pragma_AliasName *) &Pragma_AliasNames[i], linenum);
- }
- ++i;
- }
- }
-
- if(abi == ABI_M68K)
- {
- if(ap.CallArgs != ap.NumArgs)
- ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
-
- ap.Flags |= AMIPRAGFLAG_M68K;
-
- if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
- DoError(ERR_FLOATARG_NOT_ALLOWED, linenum);
- else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
- && !(Flags & FLAG_PPCONLY))
- { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
- struct AmiPragma *d;
- if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
- return 0;
- memcpy(d, &ap, sizeof(struct AmiPragma));
- if(!CheckNames(d))
- return 0;
- AddItem(&AmiPragma, (struct ShortList *) d);
- if(!SpecialFuncs())
- return 0;
- }
- }
- else
- {
- if(!(Flags & FLAG_NOPPC))
- {
- struct AmiPragma *d;
- if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
- return 0;
- memcpy(d, &ap, sizeof(struct AmiPragma));
- if(!CheckNames(d))
- return 0;
- AddItem(&AmiPragma, (struct ShortList *) d);
- /*
- if(!SpecialFuncs())
- return 0;
- */
- }
- }
- }
- shadowmode = 0;
- }
-
- in.pos = SkipBlanks(in.pos);
- if(*in.pos)
- DoError(ERR_EXTRA_CHARACTERS, linenum);
- ++in.pos; /* skip '\0' */
- }
-
- if(bias)
- DoError(ERR_MISSING_END, 0);
-
- return 1;
- }
-
- static int32 ScanTypes(strptr ptr, uint32 size)
- {
- struct CPP_ExternNames *a = 0, *b = 0;
- strptr endptr = ptr+size;
- int32 line;
-
- for(line = 1; ptr < endptr; ++line)
- {
- struct CPP_ExternNames *n;
-
- if(*ptr == '*') /* skip comments */
- {
- while(ptr < endptr && *(ptr++) != '\n')
- ;
- }
- else if((n = (struct CPP_ExternNames *)
- AllocListMem(sizeof(struct CPP_ExternNames))))
- {
- strptr wptr;
-
- n->Type = ptr; /* store start */
-
- while(ptr < endptr && *ptr != ':' && *ptr != '\n' && *ptr != '\t' && *ptr != ' ')
- ++ptr;
- wptr = SkipBlanks(ptr);
- if(*(wptr++) != ':')
- return line;
- *ptr = 0;
-
- if(!GetCPPType(&n->NameType, (ptr = SkipBlanks(wptr)), 0))
- return line;
- #ifdef DEBUG_OLD
- printf("'%20s', slen %2ld, typelen %3ld, pntd %ld, type %lc, sn '%.3s'\n",
- n->Type, n->NameType.StructureLength, n->NameType.FullLength,
- n->NameType.PointerDepth, n->NameType.Type ? n->NameType.Type : 's',
- n->NameType.StructureName ? n->NameType.StructureName : "<e>");
- #endif
- ptr = SkipBlanks(n->NameType.TypeStart+n->NameType.FullLength);
- if(*(ptr++) != '\n')
- {
- #ifdef DEBUG_OLD
- printf("%.30s\n", ptr);
- #endif
- return line;
- }
-
- if(!a)
- b = n;
- else
- a->Next = n;
- a = n;
- }
- else
- return -1;
- }
- extnames = b; /* now store the list */
- return 0;
- }
-
- static void FindHeader(void)
- {
- strptr str = HEADER;
- uint32 mode = 0;
-
- do
- {
- if(!mode)
- HEADER = str;
-
- if(*str == '/')
- {
- ++str;
- if(*str == '*')
- {
- mode = 2; break;
- }
- else if(*str == '/')
- mode = 1;
- }
- else if(*str == '*' || *str == ';')
- mode = 1;
- else if(*str == '{'/*}*/)
- {
- mode = 3; break;
- }
- else if(*str == '('/*)*/ && *(++str) == '*')
- {
- mode = 4; break;
- }
- else if(mode)
- break;
- while(*str && *(str++) != '\n')
- ;
- } while(*str);
-
- if(mode == 2)
- {
- while(*str && (*(str-1) != '*' || *str != '/'))
- ++str;
- while(*str && *(str++) != '\n')
- ;
- }
- else if(mode == 3)
- {
- while(*str && *str != /*{*/'}')
- ++str;
- while(*str && *(str++) != '\n')
- ;
- }
- else if(mode == 4)
- {
- while(*str && (*(str-1) != '*' || *str != /*(*/')'))
- ++str;
- while(*str && *(str++) != '\n')
- ;
- }
-
- if(mode)
- headersize = str-HEADER;
- else
- {
- HEADER = 0; headersize = 0;
- }
- }
-
- /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
- static uint32 GetRegisterData(struct AmiPragma *ap)
- {
- /* usage of result:
- 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
- 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
- */
- register uint32 i, data = 0, reg;
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- if((reg = ap->Args[i].ArgReg) <= REG_FP0)
- {
- if(reg >= 10 || (reg >= 2 && reg <= 7)) /* A2-A7 and D2-D7 */
- data |= (1 << (reg + 16)) + (1 << (15 - reg));
- }
- }
- if(data) /* set A6 only when other register used */
- data |= 0x40000002;
- return data;
- }
-
- static uint16 GetFRegisterData(struct AmiPragma *ap)
- {
- /* usage of result:
- F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
- F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
- */
- register uint32 i, reg;
- register uint16 data = 0;
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- if((reg = ap->Args[i].ArgReg) >= REG_FP2)
- {
- reg -= REG_FP0;
- data |= (1 << (reg + 8)) + (1 << (7 - reg));
- }
- }
- return data;
- }
-
- static uint32 OutputXDEF(uint32 offset, strptr format, ...)
- {
- uint8 buf[150];
- va_list a;
- size_t i;
-
- va_start(a, format);
- i = vsprintf((strptr)(buf+4), format, a);
- va_end(a);
- while(i&3)
- buf[4+i++] = 0;
- EndPutM32(buf+4+i, offset); /* the definition offset */
-
- EndPutM32(buf, (EXT_DEF<<24) + (i>>2));
-
- return DoOutputDirect(buf, i+8);
- }
-
- static uint32 OutputXREF(uint32 offset, uint32 type, strptr format, ...)
- {
- uint8 buf[150];
- va_list a;
- size_t i;
-
- va_start(a, format);
- i = vsprintf((strptr)(buf+4), format, a);
- va_end(a);
- while(i&3)
- buf[4+i++] = 0;
- EndPutM32(buf+4+i, 1); /* 1 reference */
- EndPutM32(buf+8+i, offset); /* the definition offset */
-
- EndPutM32(buf, (type << 24) + (i>>2));
-
- return DoOutputDirect(buf, i+12);
- }
-
- static uint32 OutputXREF2(uint32 offset1, uint32 offset2, uint32 type, strptr format, ...)
- {
- uint8 buf[150];
- va_list a;
- size_t i;
-
- va_start(a, format);
- i = vsprintf((strptr)(buf+4), format, a);
- va_end(a);
- while(i&3)
- buf[4+i++] = 0;
- EndPutM32(buf+4+i, 2); /* 2 references */
- EndPutM32(buf+8+i, offset1); /* the definition offset */
- EndPutM32(buf+12+i, offset2); /* the definition offset */
-
- EndPutM32(buf, (type << 24) + (i>>2));
-
- return DoOutputDirect(buf, i+16);
- }
-
- static uint32 OutputSYMBOL(uint32 offset, strptr format, ...)
- {
- va_list a;
- uint8 buf[150];
- size_t i;
-
- va_start(a, format);
- i = vsprintf((strptr)(buf+4), format, a);
- va_end(a);
- while(i&3)
- buf[4+i++] = 0;
- EndPutM32(buf+4+i, offset);
-
- EndPutM32(buf, (0 << 24) + (i>>2));
-
- return DoOutputDirect(buf, i+8);
- }
-
- static uint8 *AsmStackCopy(uint8 *data, struct AmiPragma *ap, uint32 flags, uint32 ofs)
- {
- uint32 i, j, k, l, tofs;
-
- if(Flags & FLAG_PASCAL)
- {
- k = ap->NumArgs;
-
- while(k)
- {
- if(ap->Args[k-1].ArgReg >= REG_FP0)
- {
- struct ClibData *cd;
-
- cd = GetClibFunc(ap->FuncName, ap, flags);
- EndPutM16Inc(data, 0xF22F); /* FMOVE.? offs(A7),FPx */
-
- if(cd && IsCPPType(&cd->Args[k-1], CPP_TYPE_DOUBLE))
- {
- EndPutM16Inc(data, 0x5400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
- EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
- ofs += 2;
- }
- else
- {
- if(!cd || !IsCPPType(&cd->Args[k-1], CPP_TYPE_FLOAT))
- DoError(ERR_LONG_DOUBLE, ap->Line);
- EndPutM16Inc(data, 0x4400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
- EndPutM16Inc(data, (ofs++) << 2);
- }
- }
- else if((k >= 2) && (ap->Args[k-1].ArgReg < ap->Args[k-2].ArgReg)
- && ap->Args[k-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
- {
- l = 0; tofs = ofs;
- do
- {
- j = ap->Args[--k].ArgReg;
-
- ++ofs;
- l |= 1 << j;
- } while(k && j < ap->Args[k-1].ArgReg && ap->Args[k-1].ArgReg < REG_FP0);
- EndPutM16Inc(data, 0x4CEF); /* MOVEM.L offs(A7),xxx */
- EndPutM16Inc(data, l);
- EndPutM16Inc(data, tofs << 2); /* store start offset */
- }
- else
- {
- l = 0x202F; /* MOVE.L offs(A7),xxx */
-
- if((j = ap->Args[--k].ArgReg) > 7)
- {
- l |= (1<<6); j -= 8; /* set MOVEA bit */
- }
- EndPutM16Inc(data, l | (j << 9)); /* set destination register and store */
- EndPutM16Inc(data, (ofs++) << 2);
- }
- }
- }
- else
- {
- i = 0;
-
- k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
-
- while(i < k)
- {
- if(ap->Args[i].ArgReg >= REG_FP0)
- {
- struct ClibData *cd;
-
- cd = GetClibFunc(ap->FuncName, ap, flags);
- EndPutM16Inc(data, 0xF22F); /* FMOVE.? offs(A7),FPx */
-
- if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
- {
- EndPutM16Inc(data, 0x5400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
- EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
- ofs += 2;
- }
- else
- {
- if(!cd || !IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
- DoError(ERR_LONG_DOUBLE, ap->Line);
- EndPutM16Inc(data, 0x4400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
- EndPutM16Inc(data, (ofs++) << 2);
- }
- }
- else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg)
- && ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
- {
- l = 0; tofs = ofs;
- do
- {
- j = ap->Args[i++].ArgReg;
-
- ++ofs;
- l |= 1 << j;
- } while(i < k && j < ap->Args[i].ArgReg && ap->Args[i].ArgReg < REG_FP0);
- EndPutM16Inc(data, 0x4CEF); /* MOVEM.L offs(A7),xxx */
- EndPutM16Inc(data, l); /* Store MOVEM.L data */
- EndPutM16Inc(data, tofs << 2); /* store start offset */
- }
- else
- {
- l = 0x202F; /* MOVE.L offs(A7),xxx */
-
- if((j = ap->Args[i++].ArgReg) > 7)
- {
- l |= (1<<6); j -= 8; /* set MOVEA bit */
- }
- EndPutM16Inc(data, l | (j << 9)); /* set destination register and store */
- EndPutM16Inc(data, (ofs++) << 2);
- }
- }
-
- if(i < ap->NumArgs)
- {
- if((j = ap->Args[i].ArgReg) > 7)
- {
- EndPutM16Inc(data, 0x41EF | ((j-8) << 9)); /* LEA xxx(A7),Ax */
- EndPutM16Inc(data, ofs << 2);
- }
- else if(ofs == 2)
- {
- EndPutM16Inc(data, 0x200F | (j << 9)); /* MOVE.L A7,Dx */
- EndPutM16Inc(data, 0x5080 | j); /* ADDQ.L #8,Dx */
- }
- else
- {
- EndPutM16Inc(data, 0x486F); /* PEA xxx(A7) */
- EndPutM16Inc(data, ofs << 2);
- EndPutM16Inc(data, 0x201F | j << 9); /* MOVE.L offs(A7),Dx */
- }
- }
- }
-
- return data;
- }
- /* ------------------------------------------------------------------ */
-
- static void DoError(uint32 errnum, uint32 line, ...)
- {
- va_list a;
- if(Flags & FLAG_DIDERROR)
- return;
-
- if(!Errors[errnum].Type)
- Flags |= FLAG_DIDERROR;
-
- va_start(a, line);
- printf((line ? "%s %ld in line %ld%s: " : "%s %ld : "), (uint32)
- (Errors[errnum].Type ? "Warning" : "Error"), errnum & 0xFFFF, line,
- errnum > ERROFFSET_CLIB ? " of clib file" : "");
- vprintf(Errors[errnum&0xFFFF].Error, a);
- printf("\n");
- if(line && Errors[errnum&0xFFFF].Skip)
- {
- while(*in.pos)
- ++in.pos;
- }
- va_end(a);
- }
-
- static uint32 CheckError(struct AmiPragma *ap, uint32 errflags)
- {
- errflags &= ap->Flags;
-
- if(errflags & AMIPRAGFLAG_ARGCOUNT)
- {
- if(!(ap->Flags & AMIPRAGFLAG_DIDARGWARN))
- {
- DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
- ap->Flags |= AMIPRAGFLAG_DIDARGWARN;
- }
- return 1;
- }
- else if(errflags & AMIPRAGFLAG_FLOATARG)
- {
- if(!(ap->Flags & AMIPRAGFLAG_DIDFLOATWARN))
- {
- DoError(ERR_FLOATARG_NOT_ALLOWED, ap->Line);
- ap->Flags |= AMIPRAGFLAG_DIDFLOATWARN;
- }
- return 1;
- }
- else if(errflags & AMIPRAGFLAG_A6USE)
- {
- DoError(ERR_A6_NOT_ALLOWED, ap->Line);
- return 1;
- }
- else if(errflags & AMIPRAGFLAG_A5USE)
- {
- DoError(ERR_A5_NOT_ALLOWED, ap->Line);
- return 1;
- }
- else if(errflags & AMIPRAGFLAG_PPC)
- {
- if(!(Flags & FLAG_DIDPPCWARN))
- {
- DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
- Flags |= FLAG_DIDPPCWARN;
- }
- return 1;
- }
- else if(errflags & AMIPRAGFLAG_M68K)
- {
- if(!(Flags & FLAG_DIDM68KWARN))
- {
- DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
- Flags |= FLAG_DIDM68KWARN;
- }
- return 1;
- }
-
- return 0;
- }
-
- static uint32 DoOutput(strptr format, ...)
- {
- va_list a;
-
- if(!Output_Error)
- return 0;
-
- va_start(a, format);
- if(vfprintf(outfile, format, a) < 0)
- Output_Error = 1;
- va_end(a);
-
- return Output_Error;
- }
-
- static uint32 DoOutputDirect(void * data, size_t size)
- {
- if(!Output_Error)
- return 0;
- if(size)
- {
- if(fwrite(data, size, 1, outfile) != 1)
- Output_Error = 0;
- }
- return Output_Error;
- }
-
- /* ------------------------------------------------------------------ */
-
- static struct ShortList *NewItem(struct ShortListRoot *list)
- {
- struct ShortList *item;
- if(!list || !list->Size)
- return 0;
- if(!(item = (struct ShortList *) AllocListMem(list->Size)))
- return 0;
- return item;
- }
-
- static struct ShortList *RemoveItem(struct ShortListRoot *list,
- struct ShortList *item)
- {
- struct ShortList *n = list->First;
-
- if(n == item)
- list->First = item->Next;
- else
- {
- while(n && n->Next != item)
- n = n->Next;
- if(!n)
- return 0;
- if(!(n->Next = item->Next))
- list->Last = n;
- }
- item->Next = 0;
- return item;
- }
-
- static void AddItem(struct ShortListRoot *list, struct ShortList *item)
- {
- if(!list->First)
- list->First = list->Last = item;
- else
- {
- list->Last->Next = item;
- list->Last = item;
- }
- }
-
- /* ------------------------------------------------------------------ */
-
- uint32 FuncAMICALL(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags & FUNCFLAG_TAG ?
- "tagcall" : "amicall", BaseName, ap->Bias, name);
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput(RegNames[ap->Args[i].ArgReg]);
- if(i+1 < ap->NumArgs)
- DoOutput(",");
- }
-
- return DoOutput(/*((*/"))\n");
- }
-
- uint32 FuncLIBCALL(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(ap->Flags & AMIPRAGFLAG_FLOATARG)
- {
- DoOutput("#pragma flibcall %s %-20s %03x ", BaseName, name, ap->Bias);
- for(i = ap->NumArgs-1; i >= 0; --i)
- DoOutput("%02x", ap->Args[i].ArgReg);
-
- return DoOutput("00%02x\n", ap->NumArgs);
- }
-
- if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase") &&
- (flags & FUNCFLAG_NORMAL))
- DoOutput("#pragma syscall %-20s %03x ", name, ap->Bias);
- else
- DoOutput("#pragma %s %s %-20s %03x ", (flags & FUNCFLAG_TAG) ?
- "tagcall" : "libcall", BaseName, name, ap->Bias);
-
- for(i = ap->NumArgs-1; i >= 0; --i)
- DoOutput("%x", ap->Args[i].ArgReg);
-
- return DoOutput("0%x\n", ap->NumArgs);
- }
-
- uint32 FuncAsmText(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
- uint32 registers;
- uint16 fregs;
- uint32 offset = 1;
- strptr c1, c2;
- struct ClibData *cd;
-
- if(CheckError(ap, AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
- c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
-
- if(Flags & FLAG_SINGLEFILE)
- {
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
- }
-
- if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
- {
- DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
- Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
- }
-
- DoOutput("\n\tXDEF\t_%s\n_%s:\n",name, name);
- if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
- {
- DoOutput("\tXDEF\t%s\n%s:\n",name, name);
- if(clibdata)
- {
- if(!ap->NumArgs)
- DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
- else if((cd = GetClibFunc(name, ap, flags)))
- {
- string txt[300];
- uint32 i;
-
- for(i = 0; i < COPYCPP_PASSES; ++i)
- {
- if(CopyCPPType(txt, i, cd, ap->Args))
- DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name, txt, name, txt);
- }
- }
- }
- }
-
- if((registers = GetRegisterData(ap) >> 16))
- {
- if(Flags & FLAG_NOMOVEM)
- {
- for(i = 0; i <= 15; ++i)
- {
- if(registers & (1 << i))
- {
- ++offset;
- DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper[i]);
- }
- }
- }
- else
- {
- uint16 l = registers;
-
- DoOutput("\tMOVEM.L\t");
-
- for(i = 0; i <= 15; ++i)
- {
- if(l & (1 << i))
- {
- ++offset;
- l ^= 1 << i;
- DoOutput(RegNamesUpper[i]);
- if(l)
- DoOutput("/");
- }
- }
- DoOutput(",-(A7)\n");
- }
- }
- else
- {
- DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
- }
-
- if((fregs = GetFRegisterData(ap) >> 8))
- {
- uint8 l = fregs;
-
- DoOutput("\tFMOVEM.X\t");
-
- for(i = 0; i <= 7; ++i)
- {
- if(l & (1 << i))
- {
- offset += 3;
- l ^= 1 << i;
- DoOutput(RegNamesUpper[REG_FP0 + i]);
- if(l)
- DoOutput("/");
- }
- }
- DoOutput(",-(A7)\n");
- }
-
- if(Flags & FLAG_SMALLDATA)
- {
- DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1, BaseName, c2);
- }
- else
- DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName);
-
- if(!(Flags & FLAG_PASCAL))
- {
- int32 k;
-
- k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
-
- for(i = 0; i < k;)
- {
- if(ap->Args[i].ArgReg >= REG_FP0)
- {
- uint32 t;
- struct ClibData *cd;
-
- cd = GetClibFunc(name, ap, flags);
- if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
- t = CPP_TYPE_DOUBLE;
- else if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
- t = CPP_TYPE_FLOAT;
- else
- {
- DoError(ERR_LONG_DOUBLE, ap->Line);
- t = CPP_TYPE_FLOAT;
- }
-
- DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ? 'D' : 'S', c1,
- offset<<2, c2, RegNamesUpper[ap->Args[i++].ArgReg]);
-
- if(t == CPP_TYPE_DOUBLE)
- ++offset;
- ++offset;
- }
- else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg) &&
- ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
- {
- DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
- RegNamesUpper[ap->Args[i++].ArgReg]);
-
- do
- {
- DoOutput("/%s", RegNamesUpper[ap->Args[i++].ArgReg]);
- ++offset;
- } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg) &&
- ap->Args[i].ArgReg < REG_FP0);
- DoOutput("\n");
- }
- else
- {
- DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
- ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
- RegNamesUpper[ap->Args[i].ArgReg]);
- ++i;
- }
- }
-
- if(i < ap->NumArgs)
- {
- if(ap->Args[i].ArgReg > 7)
- DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1, offset<<2, c2,
- RegNamesUpper[ap->Args[i].ArgReg]);
- else if(offset <= 2)
- DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
- RegNamesUpper[ap->Args[i].ArgReg],offset<<2,
- RegNamesUpper[ap->Args[i].ArgReg]);
- else
- DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1,
- offset<<2, c2,RegNamesUpper[ap->Args[i].ArgReg]);
- }
- }
- else
- {
- i = ap->NumArgs;
-
- while(i)
- {
- if(ap->Args[i-1].ArgReg >= REG_FP0)
- {
- uint32 t;
- struct ClibData *cd;
-
- cd = GetClibFunc(name, ap, flags);
-
- if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_DOUBLE))
- t = CPP_TYPE_DOUBLE;
- else if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_FLOAT))
- t = CPP_TYPE_FLOAT;
- else
- {
- DoError(ERR_LONG_DOUBLE, ap->Line);
- t = CPP_TYPE_FLOAT;
- }
-
- DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ? 'D' : 'S',
- c1, offset<<2, c2, RegNamesUpper[ap->Args[--i].ArgReg]);
- if(t == CPP_TYPE_DOUBLE)
- ++offset;
- ++offset;
- }
- else if((i >= 2) && (ap->Args[i-1].ArgReg < ap->Args[i-2].ArgReg) &&
- ap->Args[i-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
- {
- DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
- RegNamesUpper[ap->Args[--i].ArgReg]);
-
- do
- {
- DoOutput("/%s", RegNamesUpper[ap->Args[--i].ArgReg]);
- ++offset;
- } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg) &&
- ap->Args[i-1].ArgReg < REG_FP0);
- DoOutput("\n");
- }
- else
- {
- --i;
- DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
- ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
- RegNamesUpper[ap->Args[i].ArgReg]);
- }
- }
- }
-
- DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1, ap->Bias, c2);
-
- if(fregs)
- {
- DoOutput("\tFMOVEM.X\t(A7)+,");
-
- for(i = 0; i <= 7; ++i)
- {
- if(fregs & (1 << i))
- {
- fregs ^= 1 << i;
- DoOutput(RegNamesUpper[REG_FP0 + i]);
- if(fregs)
- DoOutput("/");
- }
- }
- DoOutput("\n");
- }
-
- if(registers)
- {
- if(Flags & FLAG_NOMOVEM)
- {
- for(i = 15; i >= 0; --i)
- {
- if(registers & (1 << i))
- DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i >= REG_A0 ? "A" : "", RegNamesUpper[i]);
- }
- }
- else
- {
- DoOutput("\tMOVEM.L\t(A7)+,");
-
- for(i = 0; i <= 15; ++i)
- {
- if(registers & (1 << i))
- {
- registers ^= 1 << i;
- DoOutput(RegNamesUpper[i]);
- if(registers)
- DoOutput("/");
- }
- }
- DoOutput("\n");
- }
- }
- else
- DoOutput("\tMOVEA.L\t(A7)+,A6\n");
-
- return DoOutput("\tRTS\n");
- }
-
- uint32 FuncAsmCode(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 registers, offset = 1, baseref;
- size_t i;
- uint8 *data;
- uint16 fregs;
-
- if(CheckError(ap, AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- registers = GetRegisterData(ap);
- fregs = GetFRegisterData(ap);
-
- i = strlen(name);
- EndPutM32(tempbuf, HUNK_UNIT);
- EndPutM32(tempbuf+4, (i+3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(name, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- i = strlen(hunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(hunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- data = tempbuf+8; /* we need HUNK_CODE + size at start */
-
- if(!registers)
- {
- EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
- ++offset; /* one long more on stack */
- }
- else
- {
- if(Flags & FLAG_NOMOVEM)
- {
- for(i = 0; i <= 15; ++i)
- {
- if(registers & (1<< (16+i)))
- {
- EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
- ++offset;
- }
- }
- }
- else
- {
- uint32 l;
- EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
- EndPutM16Inc(data, registers); /* store MOVEM.L registers */
- for(l = (uint16) registers; l; l >>= 1)
- {
- if(l & 1)
- ++offset; /* get offset addition */
- }
- }
- }
-
- if(fregs)
- {
- uint32 l;
- EndPutM16Inc(data, 0xF227); /* FMOVEM.X xxx,-(A7) */
- EndPutM16Inc(data, 0xE000 + ((fregs>>8)&0xFF));
- for(l = (uint8) fregs; l; l >>= 1)
- {
- if(l & 1)
- offset+=3; /* get offset addition */
- }
- }
-
- baseref = (data-tempbuf)-8+2; /* one word later (MOVE) - 2 header longs */
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
- EndPutM16Inc(data, 0); /* place for base reference */
- }
- else
- {
- EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
- EndPutM32Inc(data, 0); /* place for base reference */
- }
-
- data = AsmStackCopy(data, ap, flags, offset);
-
- /* here comes the base reference */
- EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
- EndPutM16Inc(data, -ap->Bias); /* JSR offset */
-
- if(fregs)
- {
- EndPutM16Inc(data, 0xF21F); /* FMOVEM.X (A7)+,xxx */
- EndPutM16Inc(data, 0xD000 + (fregs&0xFF));
- }
-
- if(registers)
- {
- if(Flags & FLAG_NOMOVEM)
- {
- int32 i;
- for(i = 15; i >= 0; --i)
- {
- if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
- EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
- }
- }
- else
- {
- EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
- EndPutM16Inc(data, (registers >> 16)); /* store MOVEM.L registers */
- }
- }
- else
- EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
- EndPutM16Inc(data, 0x4E75); /* RTS */
-
- EndPutM16Inc(data, 0); /* get longword assignment if not yet */
-
- EndPutM32(tempbuf, HUNK_CODE);
- EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
- DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
-
- EndPutM32(tempbuf, HUNK_EXT);
- DoOutputDirect(tempbuf, 4);
-
- OutputXREF(baseref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_%s", BaseName);
- /* here come the XDEF name references */
- OutputXDEF(0, "_%s", name); /* C name */
-
- if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
- {
- struct ClibData *cd;
- OutputXDEF(0, "%s", name); /* ASM name */
-
- if(clibdata)
- {
- if(!ap->NumArgs)
- OutputXDEF(0, "%s_", name); /* C++ name no parameters */
- else if((cd = GetClibFunc(name, ap, flags)))
- {
- for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
- {
- if(CopyCPPType((strptr)tempbuf, i, cd, ap->Args))
- OutputXDEF(0, "%s__%s", name, tempbuf);
- }
- }
- }
- }
-
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf, 4);
- if(!(Flags & FLAG_NOSYMBOL))
- {
- EndPutM32(tempbuf, HUNK_SYMBOL);
- DoOutputDirect(tempbuf, 4);
- OutputSYMBOL(0, "_%s", name); /* C name */
-
- if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
- {
- struct ClibData *cd;
- OutputSYMBOL(0, "%s", name); /* ASM name */
-
- if(clibdata)
- {
- if(!ap->NumArgs)
- OutputSYMBOL(0, "%s_", name); /* C++ name no parameters */
- else if((cd = GetClibFunc(name, ap, flags)))
- {
- for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
- {
- if(CopyCPPType((strptr) data, i, cd, ap->Args))
- OutputSYMBOL(0, "%s__%s", name, (strptr) data);
- }
- }
- }
- }
-
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf, 4);
- }
-
- EndPutM32(tempbuf, HUNK_END);
- return DoOutputDirect(tempbuf, 4);
- }
-
- /* Directly called by FuncInline also! */
- uint32 FuncCSTUBS(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- struct ClibData *f, *t;
- strptr ret = "return ";
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
- return 1;
- t = GetClibFunc(name, ap, flags);
-
- if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
- ret = 0;
-
- if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
- return 0;
- for(i = 0; i < ap->NumArgs-1; i++)
- {
- if(!OutClibType(&f->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
- return 0;
- }
- if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
- {
- if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
- return 0;
- }
- else if(ap->NumArgs == 1 && !DoOutput("uint32 tag, "))
- return 0;
-
- if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret, ap->FuncName))
- return 0;
- for(i = 0; i < ap->NumArgs-1; i++)
- {
- if(!DoOutput("%s, ", ap->Args[i].ArgName))
- return 0;
- }
- if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
- return 0;
-
- if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
- {
- if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
- return 0;
- }
- else if(ap->NumArgs == 1)
- {
- if(!DoOutput(/*((*/") &tag);\n}\n\n"))
- return 0;
- }
- else if (!DoOutput(/*(*/") ((uint32) &%s + sizeof("/*))*/,
- ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(&f->Args[ap->NumArgs-2],0)
- || !DoOutput(/*(((*/")));\n}\n\n"))
- return 0;
- return 1;
- }
-
- uint32 FuncLVOXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- Flags |= FLAG_DONE; /* We did something */
- return DoOutput("\t\tXDEF\t_LVO%s\n", name);
- }
-
- uint32 FuncLVO(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- Flags |= FLAG_DONE; /* We did something */
- return DoOutput("\n_LVO%-24s\tEQU\t-%d", name, ap->Bias);
- }
-
- uint32 FuncLVOPPCXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- Flags |= FLAG_DONE; /* We did something */
- return DoOutput("\t.globl\t%sLVO%s\n", Flags & FLAG_ABIV4 ? "" : "_", name);
- }
-
- uint32 FuncLVOPPC(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- Flags |= FLAG_DONE; /* We did something */
- return DoOutput(".set\t%sLVO%s,-%d\n", Flags & FLAG_ABIV4 ? "" : "_", name, ap->Bias);
- }
-
- uint32 FuncLVOPPCBias(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- Flags |= FLAG_DONE; /* We did something */
-
- EndPutM32Inc(elfbufpos, symoffset); /* st_name */
- symoffset += strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1) + 1;
- EndPutM32Inc(elfbufpos, -ap->Bias); /* st_value */
- EndPutM32Inc(elfbufpos, 0); /* st_size */
- *(elfbufpos++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* st_info */
- *(elfbufpos++) = 0; /* st_other */
- EndPutM16Inc(elfbufpos, SHN_ABS); /* st_shndx */
-
- return 1;
- }
-
- uint32 FuncLVOPPCName(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- Flags |= FLAG_DONE; /* We did something */
- DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
- return DoOutputDirect("", 1);
- }
-
- uint32 FuncLVOLib(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 j;
-
- Flags |= FLAG_DONE; /* We did something */
- j = strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1);
- EndPutM32(tempbuf, (EXT_ABS << 24) + ((j+3)>>2));
-
- DoOutputDirect(tempbuf, 4);
- DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
- DoOutputDirect("\0\0\0", ((j+3)&(~3))-j);
- EndPutM32(tempbuf, -ap->Bias);
- return DoOutputDirect(tempbuf, 4);
- }
-
- uint32 FuncLocCode(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- strptr str2 = Flags & FLAG_LOCALREG ? "rE" : "";
- uint8 *data;
- int32 i;
- struct ClibData *cd = 0;
-
- if(CheckError(ap, AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- i = strlen(name);
- EndPutM32(tempbuf, HUNK_UNIT);
- EndPutM32(tempbuf+4, (i+3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(name, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- i = strlen(hunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(hunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- data = tempbuf+8; /* we need HUNK_CODE + size at start */
-
- if(Flags & FLAG_LOCALREG)
- {
- if((flags & FUNCFLAG_TAG))
- {
- i = ap->Args[ap->NumArgs-1].ArgReg;
- EndPutM16Inc(data, 0x2F00 + i); /* MOVE <ea>,-(A7) */
-
- if(i > 7)
- {
- EndPutM16Inc(data, 0x41EF | ((i-8) << 9)); /* LEA 8(A7),Ax */
- EndPutM16Inc(data, 8);
- }
- else
- {
- EndPutM16Inc(data, 0x200F | (i << 9)); /* MOVE.L A7,Dx */
- EndPutM16Inc(data, 0x5080 | i); /* ADDQ.L #8,Dx */
- }
-
- EndPutM16Inc(data, 0x4EAE);
- EndPutM16Inc(data, -ap->Bias); /* JSR instruction */
-
- EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6)); /* MOVE (A7)+,<ea> */
- EndPutM16Inc(data, 0x4E75); /* RTS */
- }
- else
- {
- EndPutM16Inc(data, 0x4EEE);
- EndPutM16Inc(data, -ap->Bias); /* JMP instruction */
- }
- }
- else
- {
- uint32 registers, offset = 1;
-
- registers = GetRegisterData(ap);
-
- if(!registers) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
- {
- EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
- ++offset; /* one long more on stack */
- }
- else
- {
- if(Flags & FLAG_NOMOVEM)
- {
- for(i = 0; i <= 15; ++i)
- {
- if(registers & (1<< (16+i)))
- {
- EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
- ++offset;
- }
- }
- }
- else
- {
- EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
- EndPutM16Inc(data, registers); /* store MOVEM.L registers */
- for(i = registers&0xFFFF; i; i >>= 1)
- {
- if(i & 1)
- ++offset; /* get offset addition */
- }
- }
- }
-
- if(!(ap->Flags & AMIPRAGFLAG_A6USE)) /* store library base in A6 */
- {
- EndPutM16Inc(data, 0x2C6F); /* MOVE.L ofs(A7),A6 */
- EndPutM16Inc(data, (offset++) << 2);
- }
-
- data = AsmStackCopy(data, ap, flags, offset);
-
- /* here comes the base reference */
- EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
- EndPutM16Inc(data, -ap->Bias); /* JSR offset */
- if(registers)
- {
- if(Flags & FLAG_NOMOVEM)
- {
- for(i = 15; i >= 0; --i)
- {
- if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
- EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
- }
- }
- else
- {
- EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
- EndPutM16Inc(data, registers >> 16); /* store MOVEM.L registers */
- }
- }
- else
- EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
-
- EndPutM16Inc(data, 0x4E75); /* RTS */
- }
-
- EndPutM16Inc(data, 0); /* get longword assignment if not yet */
-
- EndPutM32(tempbuf, HUNK_CODE);
- EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
- DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
-
- EndPutM32(tempbuf, HUNK_EXT);
- DoOutputDirect(tempbuf,4);
-
- /* here come the XDEF name references */
-
- if(!(Flags & FLAG_ONLYCNAMES))
- {
- OutputXDEF(0, "%s", name); /* ASM names */
- OutputXDEF(0, "LOC_%s", name);
- }
-
- OutputXDEF(0, "_%s", name); /* C names */
- OutputXDEF(0, "_LOC_%s", name);
-
- if(clibdata && !(Flags & FLAG_ONLYCNAMES))
- {
- if(!ap->NumArgs)
- {
- OutputXDEF(0, "%s__%sP07Library", name, str2); /* C++ names no parameters */
- OutputXDEF(0, "LOC_%s__%sP07Library", name, str2);
- }
- else if((cd = GetClibFunc(name, ap, flags)))
- {
- strptr txt;
-
- txt = (strptr) tempbuf;
-
- for(i = 0; i < COPYCPP_PASSES; ++i)
- {
- if(CopyCPPType(txt, i, cd, ap->Args))
- { /* C++ names with parameters */
- if(!(ap->Flags & AMIPRAGFLAG_A6USE))
- {
- OutputXDEF(0, "%s__%sP07Library%s", name, str2, txt);
- OutputXDEF(0, "LOC_%s__%sP07Library%s", name, str2, txt);
- }
- else
- {
- OutputXDEF(0, "%s__%s", name, txt);
- OutputXDEF(0, "LOC_%s__%s", name, txt);
- }
- }
- }
- }
- }
-
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf,4);
- if(!(Flags & FLAG_NOSYMBOL))
- {
- EndPutM32(tempbuf, HUNK_SYMBOL);
- DoOutputDirect(tempbuf,4);
- if(!(Flags & FLAG_ONLYCNAMES))
- {
- OutputSYMBOL(0, "%s", name); /* ASM names */
- OutputSYMBOL(0, "LOC_%s", name);
- }
-
- OutputSYMBOL(0, "_%s", name); /* C names */
- OutputSYMBOL(0, "_LOC_%s", name);
-
- if(clibdata && !(Flags & FLAG_ONLYCNAMES))
- {
- if(!ap->NumArgs)
- {
- OutputSYMBOL(0, "%s__%sP07Library", name, str2); /* C++ names no parameters */
- OutputSYMBOL(0, "LOC_%s__%sP07Library", name, str2);
- }
- else if(cd)
- {
- strptr txt;
-
- txt = (strptr) tempbuf;
-
- for(i = 0; i < COPYCPP_PASSES; ++i)
- {
- if(CopyCPPType(txt, i, cd, ap->Args))
- { /* C++ names with parameters */
- if(!(ap->Flags & AMIPRAGFLAG_A6USE))
- {
- OutputSYMBOL(0, "%s__%sP07Library%s", name, str2, txt);
- OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name, str2, txt);
- }
- else
- {
- OutputSYMBOL(0, "%s__%s", name, txt);
- OutputSYMBOL(0, "LOC_%s__%s", name, txt);
- }
- }
- }
- }
- }
-
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf,4);
- }
- EndPutM32(tempbuf, HUNK_END);
- return DoOutputDirect(tempbuf,4);
- }
-
- uint32 FuncLocText(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- struct ClibData *cd;
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- OutClibType(&cd->ReturnType, 0);
- DoOutput(" LOC_%s("/*)*/, name);
- if(!(ap->Flags & AMIPRAGFLAG_A6USE))
- {
- if(Flags & FLAG_LOCALREG)
- DoOutput("register __a6 ");
- DoOutput("struct %s * libbase", GetBaseType());
- if(ap->NumArgs)
- DoOutput(", ");
- }
-
- if(ap->NumArgs)
- {
- for(i = 0; i < ap->NumArgs-1; i++)
- {
- if(((Flags & FLAG_LOCALREG &&
- !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
- !OutClibType(&cd->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
- return 0;
- }
-
- if(flags & FUNCFLAG_NORMAL)
- {
- if(((Flags & FLAG_LOCALREG &&
- !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
- !OutClibType(&cd->Args[i], ap->Args[i].ArgName) ||
- !DoOutput(/*(*/");\n"))
- return 0;
- if(BaseName)
- {
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%c, ", 'a'+(char)i);
- DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i, name, BaseName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%c, ",'a'+(char)i);
- return DoOutput(/*(*/"%c)\n\n",'a'+(char)i);
- }
- }
- else
- return DoOutput(/*(*/"...);\n");
- }
- else if(BaseName)
- return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
- name, name);
- else
- return DoOutput(/*(*/");\n");
- return 1;
- }
-
- uint32 FuncInline(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 noret = 0, a45 = 0, j;
- int32 fp = -1, i;
- struct ClibData *cd;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(flags & FUNCFLAG_ALIAS)
- {
- if(flags & FUNCFLAG_TAG)
- return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
- Flags & FLAG_POWERUP ? "PPC" : "", name, ap->TagName);
-
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
- }
-
- if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
- return 1;
-
- if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
- noret = 1; /* this is a void function */
-
- if(ap->Flags & AMIPRAGFLAG_A5USE)
- a45 = REG_A5;
- if(ap->Flags & AMIPRAGFLAG_A4USE)
- {
- if(a45)
- {
- DoError(ERR_INLINE_A4_AND_A5, ap->Line);
- return 1; /* skip this entry */
- }
- a45 = REG_A4;
- }
- if(a45 && (ap->Flags & AMIPRAGFLAG_D7USE))
- {
- DoError(ERR_INLINE_D7_AND_A45, ap->Line);
- return 1; /* skip this entry */
- }
-
- if((flags & FUNCFLAG_TAG))
- {
- if(Flags & FLAG_INLINENEW)
- {
- DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
- Flags & FLAG_POWERUP ? "PPC" : "", name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- {
- DoOutput("%s, ", ap->Args[i].ArgName);
- }
- DoOutput(/*(*/"tags...) \\\n\t({uint32 _tags[] = {tags}; %s("/*}))*/,
- ap->FuncName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- DoOutput("("/*)*/);
- OutClibType(&cd->Args[i], 0);
- return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
- }
- else
- {
- DoOutput("%s%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ",
- Flags & FLAG_POWERUP ? "static " : "");
- return FuncCSTUBS(ap, flags, name);
- /* call CSTUBS, as this equals the method used there */
- }
- }
-
- if(Flags & FLAG_INLINENEW) /* new style */
- {
- strptr funcpar = "";
- DoOutput("#define %s("/*)*/, name);
-
- for(i = 0; i < cd->NumArgs; ++i)
- {
- if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
- funcpar = "FP";
- }
-
- if(ap->NumArgs)
- {
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput("%s", ap->Args[i].ArgName);
- }
- DoOutput(/*(*/") \\\n\tLP%d%s%s%s%s(0x%x, "/*)*/, ap->NumArgs,
- (noret ? "NR" : ""), (a45 ? RegNamesUpper[a45] : (strptr) ""),
- (BaseName ? "" : "UB"), funcpar, ap->Bias);
- if(!noret)
- {
- OutClibType(&cd->ReturnType, 0);
- DoOutput(", ");
- }
- DoOutput("%s, ", name);
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- j = ap->Args[i].ArgReg;
- if(a45 && (j == REG_A4 || j == REG_A5))
- j = REG_D7;
- if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
- {
- DoOutput("__fpt"); fp = i;
- }
- else
- OutClibType(&cd->Args[i], 0);
-
- DoOutput(", %s, %s%s", ap->Args[i].ArgName, RegNames[j],
- (i == ap->NumArgs-1 && !BaseName ? "" : ", "));
- }
-
- if(BaseName) /* was "##base" used? */
- DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper);
-
- if(fp >= 0)
- {
- DoOutput(", ");
- OutClibType(&cd->Args[fp], "__fpt");
- }
-
- if(Flags & FLAG_POWERUP)
- DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
-
- return DoOutput(/*(*/")\n\n");
- }
-
- /* old mode or stubs mode */
-
- DoOutput("%s%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ",
- Flags & FLAG_POWERUP ? "static " : "");
- OutClibType(&cd->ReturnType, 0);
- DoOutput("\n%s(%s"/*)*/, name, (BaseName ?
- (ap->NumArgs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- OutClibType(&cd->Args[i], ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
-
- if(Flags & FLAG_POWERUP)
- {
- DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
- "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
- "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
- "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
- "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
- "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
- "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
-
- if(ap->NumArgs)
- {
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("\tMyCaos.%s\t\t= (uint32) %s;\n",
- RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
- }
- }
-
- DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
-
- if(BaseName)
- DoOutput("\tMyCaos.a6\t\t= (uint32) %s_BASE_NAME;\n", ShortBaseNameUpper);
- if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
- DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
- else
- {
- DoOutput("\treturn(("/*))*/);
- OutClibType(&cd->ReturnType, 0);
- DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
- }
- return Output_Error;
- }
-
- DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName ? " BASE_EXT_DECL\n" : ""));
-
- if(!noret)
- {
- DoOutput(" register ");
- OutClibType(&cd->ReturnType, "res");
- DoOutput(" __asm(\"d0\");\n");
- }
-
- if(BaseName)
- DoOutput(" register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
- GetBaseType());
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- j = ap->Args[i].ArgReg;
- if(a45 && (j == REG_A4 || j == REG_A5))
- j = REG_D7;
-
- DoOutput(" register ");
- OutClibType(&cd->Args[i], RegNames[j]);
- DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
- }
-
- if(a45)
- {
- DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
- "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames[a45],
- ap->Bias, RegNames[a45]);
- }
- else
- DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap->Bias);
-
- DoOutput(noret ? " : /* No Output */\n" : " : \"=r\" (res)\n");
-
- DoOutput(" : ");
- if(BaseName)
- DoOutput("\"r\" (a6)%s", (ap->NumArgs ? ", ": ""));
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- j = ap->Args[i].ArgReg;
- if(a45 && (j == REG_A4 || j == REG_A5))
- j = REG_D7;
-
- DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
- }
-
- DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
-
- if(noret)
- return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
- else
- return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
- }
-
- /* new style inlines designed by Bernardo Innocenti */
- uint32 FuncInlineNS(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
- struct ClibData *cd;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(flags & FUNCFLAG_ALIAS)
- {
- if(flags & FUNCFLAG_TAG)
- return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n", name, ap->TagName);
-
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
- }
-
- if(!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- if((flags & FUNCFLAG_TAG))
- {
- if(!(Flags & FLAG_INLINEMAC))
- {
- DoOutput("static __inline ");
- return FuncCSTUBS(ap, flags, name);
- /* call CSTUBS, as this equals the method used there */
- }
- else
- {
- DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/, Flags & FLAG_POWERUP ? "PPC" : "", name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"tags...) \\\n\t({uint32 _tags[] = {tags}; %s("/*}))*/,
- ap->FuncName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- DoOutput("("/*)*/);
- OutClibType(&cd->Args[i], 0);
- return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
- }
- }
-
- if(Flags & FLAG_INLINEMAC)
- {
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("%s", ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- DoOutput(/*(*/") \\\n\t");
- }
- else
- {
- DoOutput("static __inline ");
- OutClibType(&cd->ReturnType, 0);
- DoOutput(" %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- OutClibType(&cd->Args[i], ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- DoOutput(/*(*/")\n{\n "/*}*/);
- if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
- DoOutput("return ");
- }
- DoOutput("(("/*))*/);
- OutClibType(&cd->ReturnType, 0);
- DoOutput(" (*)("/*)*/);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- OutClibType(&cd->Args[i], 0);
- DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- if(BaseName)
- {
- if(ap->NumArgs)
- DoOutput(", ");
- DoOutput("struct %s * __asm(\"a6\")", GetBaseType());
- }
- DoOutput(/*((*/"))");
- if(Flags & FLAG_INLINEMAC)
- DoOutput(" \\");
- if(BaseName)
- DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/, ShortBaseNameUpper, ap->Bias);
- else
- {
- for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
- ;
- if(i == ap->NumArgs)
- return 1;
- DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap->Args[i].ArgName, ap->Bias);
- }
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("%s", ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- if(BaseName)
- {
- if(ap->NumArgs)
- DoOutput(", ");
- DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
- }
-
- if(Flags & FLAG_INLINEMAC)
- DoOutput(/*(*/")\n");
- else
- DoOutput(/*{(*/");\n}\n");
-
- return DoOutput("\n");
- }
-
- uint32 FuncPowerUP(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
- struct ClibData *cd;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(flags & FUNCFLAG_ALIAS)
- {
- if(flags & FUNCFLAG_TAG)
- return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n", name, ap->TagName);
-
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
- }
-
- if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
- return 1;
-
- if(flags & FUNCFLAG_TAG)
- {
- DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"tags...) \\\n\t({uint32 _tags[] = {tags}; %s("/*)})*/,
- ap->FuncName);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- DoOutput("("/*)*/);
- OutClibType(&cd->Args[i], 0);
- return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
- }
-
- DoOutput("#define\t%s("/*)*/, name);
-
- if(ap->NumArgs)
- {
-
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"%s)\t_%s("/*)*/, ap->Args[i].ArgName, name);
-
- if(BaseName)
- DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper);
-
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"%s)\n\n", ap->Args[i].ArgName);
- }
- else if(BaseName)
- DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name, ShortBaseNameUpper);
- else
- DoOutput(/*(*/")\t_%s()\n\n", name);
-
- DoOutput("static __inline ");
- OutClibType(&cd->ReturnType, 0);
-
- DoOutput("\n_%s("/*)*/, name);
- if(BaseName)
- DoOutput("void * %s%s", BaseName, ap->NumArgs ? ", " : "");
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- OutClibType(&cd->Args[i], ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
-
- DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
- "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
- "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
- "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
- "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
- "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
- "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
-
- if(ap->NumArgs)
- {
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("\tMyCaos.%s\t\t= (uint32) %s;\n",
- RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
- }
- }
-
- DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
-
- if(BaseName)
- DoOutput("\tMyCaos.a6\t\t= (uint32) %s;\n", BaseName);
- if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
- DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
- else
- {
- DoOutput("\treturn(("/*))*/);
- OutClibType(&cd->ReturnType, 0);
- DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
- }
- return Output_Error;
- }
-
- uint32 FuncFPCUnit(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
- struct ClibData *cd;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
- return 1;
- else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
- return 1;
-
- if(!FuncFPCType(ap, flags, name))
- return 0;
-
- DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
-
- for(i = 0; i < ap->NumArgs; ++i)
- DoOutput("\tMOVE%s.L\t%s,%s\n", ap->Args[i].ArgReg >= REG_A0 ? "A" : "",
- ap->Args[i].ArgName, RegNamesUpper[ap->Args[i].ArgReg]);
-
- if(BaseName)
- DoOutput("\tMOVEA.L\t%s,A6\n", BaseName);
- DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap->Bias);
-
- if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
- {
- if(!cd->ReturnType.PointerDepth &&
- cd->ReturnType.Flags == CPP_FLAG_BOOLEAN)
- DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
- " @end:\tMOVE.B\tD0,@RESULT\n");
- else
- DoOutput("\tMOVE.L\tD0,@RESULT\n");
- }
- return DoOutput(" END;\nEND;\n\n");
- }
-
- uint32 FuncFPCType(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 ret = 1;
- int32 i;
- struct ClibData *cd;
-
- if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
- return 1;
- else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
- return 1;
-
- if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
- {
- ret = 0; DoOutput("PROCEDURE %s", name);
- }
- else
- DoOutput("FUNCTION %s", name);
-
- if(ap->NumArgs)
- {
- DoOutput("("/*)*/);
- for(i = 0; i < ap->NumArgs;)
- {
- OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
- if(++i != ap->NumArgs)
- DoOutput("; ");
- }
- DoOutput(/*(*/")");
- }
-
- if(ret)
- OutPASCALType(&cd->ReturnType, "", 1);
-
- Flags |= FLAG_DONE; /* We did something */
-
- return DoOutput(";\n");
- }
-
- uint32 FuncBMAP(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint8 reg, i;
-
- if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_A5USE|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE; /* We did something */
-
- for(i = 0; BMAPSpecial[i]; ++i)
- {
- if(!stricmp(name, BMAPSpecial[i]))
- {
- DoOutput("x"); break;
- }
- }
-
- DoOutput(name);
- reg = 0; DoOutputDirect(®, 1);
- reg = (-ap->Bias)>>8; DoOutputDirect(®, 1);
- reg = -ap->Bias; DoOutputDirect(®, 1);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- reg = 1+ap->Args[i].ArgReg; DoOutputDirect(®, 1);
- }
- reg = 0;
- return DoOutputDirect(®, 1);
- }
-
- uint32 FuncVBCCInline(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- struct ClibData *cd;
- strptr c1, c2;
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
- return 1;
-
- if(!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
- c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(flags & FUNCFLAG_ALIAS)
- {
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs-1; ++i)
- DoOutput("%s, ", ap->Args[i].ArgName);
- DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
- for(i = 0; i < ap->NumArgs; ++i)
- DoOutput("(%s), ", ap->Args[i].ArgName);
- return DoOutput(/*(*/"%s)\n\n", BaseName);
- }
-
- OutClibType(&cd->ReturnType, 0);
- DoOutput(" __%s("/*)*/, name);
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("__reg(\"%s\") ", RegNames[ap->Args[i].ArgReg]);
- if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
- && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
- {
- DoOutput("void * %s", ap->Args[i].ArgName);
- }
- else
- OutClibType(&cd->Args[i], ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
-
- if(BaseName)
- {
- if(ap->NumArgs)
- DoOutput(", ");
- DoOutput("__reg(\"a6\") struct %s *", GetBaseType());
- }
- DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1, ap->Bias, c2);
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("%s", ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- DoOutput(/*(*/") __%s("/*)*/, name);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
- && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
- {
- DoOutput("(void *)");
- }
- DoOutput("(%s)", ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- if(BaseName)
- {
- if(ap->NumArgs)
- DoOutput(", ");
- DoOutput("%s", BaseName);
- }
-
- return DoOutput(/*(*/")\n\n");
- }
-
- uint32 FuncVBCCWOSInline(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- struct ClibData *cd;
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_M68K))
- return 1;
-
- if(!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- if(!BaseName)
- {
- DoError(ERR_MISSING_BASENAME, ap->Line);
- return 1;
- }
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(!(flags & FUNCFLAG_ALIAS))
- {
- OutClibType(&cd->ReturnType, 0);
- DoOutput(" __%s("/*)*/, name);
-
- if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
- {
- DoOutput("struct %s *", GetBaseType());
- if(ap->NumArgs)
- DoOutput(", ");
- }
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- OutClibType(&cd->Args[i], ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
-
- DoOutput(/*(*/")=\"");
- if(ap->Flags & AMIPRAGFLAG_PPC0)
- {
- DoOutput("\\t.extern\\t_%s\\n"
- "\\tlwz\\t%s11,_%s(%s2)\\n"
- "\\tlwz\\t%s0,-%d(%s11)\\n"
- "\\tmtlr\\t%s0\\n"
- "\\tblrl",
- BaseName, PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix,
- ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
- }
- else if(ap->Flags & AMIPRAGFLAG_PPC2)
- {
- DoOutput("\\tstw\\t%s2,20(%s1)\\n"
- "\\t.extern\\t_%s\\n"
- "\\tlwz\\t%s2,_%s(%s2)\\n"
- "\\tlwz\\t%s0,-%d(%s2)\\n"
- "\\tmtlr\\t%s0\\n"
- "\\tblrl\\n"
- "\\tlwz\\t%s2,20(%s1)",
- PPCRegPrefix, PPCRegPrefix, BaseName, PPCRegPrefix, BaseName,
- PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix);
- }
- else
- {
- DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
- "\\tmtlr\\t%s0\\n"
- "\\tblrl",
- PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
- }
-
- DoOutput("\";\n");
- }
-
- DoOutput("#define %s("/*)*/, name);
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("%s", ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
- DoOutput(/*(*/") __%s("/*)*/, ap->FuncName);
- if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
- {
- DoOutput("%s", BaseName);
- if(ap->NumArgs)
- DoOutput(", ");
- }
- for(i = 0; i < ap->NumArgs; ++i)
- {
- DoOutput("(%s)", ap->Args[i].ArgName);
- if(i < ap->NumArgs-1)
- DoOutput(", ");
- }
-
- return DoOutput(/*(*/")\n\n");
- }
-
- uint32 FuncVBCCWOSText(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 i, k, count, ofs;
- struct ClibData *cd = 0;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
- return 1;
-
- if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
- ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) || !(Flags & FLAG_WOSLIBBASE)))
- {
- DoError(ERR_MISSING_BASENAME, ap->Line);
- return 1;
- }
-
- Flags |= FLAG_DONE;
-
- if(Flags & FLAG_SINGLEFILE)
- {
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
- }
-
- if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
- DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
-
- if(Flags & FLAG_SINGLEFILE)
- DoOutput("\t.file\t\"%s.s\"\n", name);
- DoOutput("\t.align\t3\n");
- if(Flags & FLAG_WOSLIBBASE) /* PPCBase already in r3, LibBase in r4 */
- {
- if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
- DoOutput("\t.extern _%s\n", BaseName);
- DoOutput("\t.global __%s\n__%s:\n", name, name);
- }
- else
- {
- if(BaseName)
- DoOutput("\t.extern _%s\n", BaseName);
- if(!(ap->Flags & AMIPRAGFLAG_PPC))
- DoOutput("\t.extern _PowerPCBase\n");
- DoOutput("\t.global _%s\n_%s:\n", name, name);
- }
-
- if(ap->Flags & AMIPRAGFLAG_PPC2)
- {
- DoOutput("\tstw\t%s2,20(%s1)\n"
- "\tmflr\t%s0\n"
- "\tstw\t%s0,16(%s1)\n"
- "\tlwz\t%s2,_%s(%s2)\n"
- "\tlwz\t%s0,-%d(%s2)\n"
- "\tmtlr\t%s0\n"
- "\tblrl\n"
- "\tlwz\t%s0,16(%s1)\n"
- "\tlwz\t%s2,20(%s1)\n"
- "\tmtlr\t%s0\n"
- "\tblr\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- }
- else if(ap->Flags & AMIPRAGFLAG_PPC0)
- {
- DoOutput("\tlwz\t%s11,_%s(%s2)\n\tlwz\t%s0,-%d(%s11)\n\tmtlr\t%s0\n\tblrl\n",
- PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
- }
- else if(ap->Flags & AMIPRAGFLAG_PPC)
- {
- count = ap->NumArgs;
- if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
- {
- /* init stack frame */
- i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
- DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
-
- if(count > 8)
- {
- /* extra arguments must be passed on the stack */
- k = 32-(count-8); /* firstreg */
-
- DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
- PPCRegPrefix, k, 56+(count-8)*4, PPCRegPrefix, PPCRegPrefix, k,
- i+56, PPCRegPrefix);
- if(flags & FUNCFLAG_TAG)
- DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
- i+20+count*4);
- DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
- }
- else if(flags & FUNCFLAG_TAG)
- {
- DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
- PPCRegPrefix, i+20+count*4);
- --count;
- }
- }
- else /* Args must be shifted! */
- {
- /* init stack frame */
- i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
- DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
-
- if(count > 7)
- {
- /* extra arguments must be passed on the stack */
- if(count == 8)
- {
- /* special case: move 8th argument into stack frame */
- if(flags & FUNCFLAG_TAG)
- DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
- i+20+count*4);
- DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix, PPCRegPrefix);
- }
- else
- {
- k = 32-(count-7); /* firstreg */
-
- DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
- "\tmr\t%s%ld,%s10\n"
- "\tlmw\t%s%ld,%ld(%s1)\n",
- PPCRegPrefix, k, 56+(count-7)*4, PPCRegPrefix,
- PPCRegPrefix, k, PPCRegPrefix, PPCRegPrefix, k+1,
- i+56, PPCRegPrefix);
- if(flags & FUNCFLAG_TAG)
- DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix,
- PPCRegPrefix, i+20+count*4);
- DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
- }
- }
- else if(flags & FUNCFLAG_TAG)
- {
- DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
- PPCRegPrefix, i+20+count*4);
- --count;
- }
-
- /* shift all arguments into their following register */
- for(k=(count<8)?count:7; k > 0; --k)
- DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix, 3+k, PPCRegPrefix, 2+k);
-
- /* load library base and LVO, then call LVO via LR */
- DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
- }
-
- /* call LVO */
- DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix,
- ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
-
- /* cleanup stack frame and return */
- if(count > 8)
- {
- k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
- DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, 32-(count-k),
- 56+(count-k)*4, PPCRegPrefix);
- }
-
- DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
- PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- }
- else
- {
- DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- /* clear PP_Flags, PP_Stack and PP_StackSize */
- DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
- "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- if(Flags & FLAG_WOSLIBBASE)
- DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
- "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix, ap->Bias, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- else if(!BaseName)
- DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix,
- ap->Bias, PPCRegPrefix, PPCRegPrefix);
- else
- DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
- "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
- PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix);
-
- ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
- k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
- for(i = 0; i < k; ++i)
- {
- if(i + ofs <= 7)
- {
- if(ap->Args[i].ArgReg == REG_A6)
- DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix, i+3+ofs, PPCRegPrefix);
- DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3+ofs);
- }
- else
- {
- DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix, (i+1+ofs)*4+196, PPCRegPrefix);
- if(ap->Args[i].ArgReg == REG_A6)
- DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix, PPCRegPrefix);
- DoOutput("\tstw\t%s11,", PPCRegPrefix);
- }
- DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
- }
- if(flags & FUNCFLAG_TAG)
- {
- if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
- DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i+3+ofs,
- 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
- DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix,
- PPCRegPrefix, 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
- DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
- }
-
- if(!(Flags & FLAG_WOSLIBBASE))
- DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix, PPCRegPrefix);
-
- DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n\tblrl\n"
- "\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- }
-
- if(Flags & FLAG_WOSLIBBASE)
- return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
- name, name, name);
- else
- return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
- name, name, name);
- }
-
- uint32 FuncVBCCWOSCode(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint32 i, j, k, ofs, count;
- uint8 *data, *basepos = 0, *pbasepos = 0;
- struct ClibData *cd = 0;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
- return 1;
-
- if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) && !(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
- ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) || !(Flags & FLAG_WOSLIBBASE)))
- {
- DoError(ERR_MISSING_BASENAME, ap->Line);
- return 1;
- }
-
- Flags |= FLAG_DONE; /* We did something */
-
- i = strlen(name);
- if(Flags & FLAG_WOSLIBBASE)
- ++i;
- EndPutM32(tempbuf, HUNK_UNIT);
- EndPutM32(tempbuf+4, (i+3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutput("%s%s", Flags & FLAG_WOSLIBBASE ? "_" : "", name);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- i = strlen(hunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(hunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- data = tempbuf+8; /* we need HUNK_PPC_CODE + size at start */
-
- if(ap->Flags & AMIPRAGFLAG_PPC2)
- {
- EndPutM32Inc(data, 0x90410014); /* stw r2,20(r1) */
- EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
- EndPutM32Inc(data, 0x90010010); /* stw r0,16(r1) */
- basepos = data;
- EndPutM32Inc(data, 0x80420000); /* lwz r2,BaseName(r2) */
- EndPutM32Inc(data, 0x80030000 - ap->Bias); /* lwz r0,-ap->Bias(r2) */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
- EndPutM32Inc(data, 0x80010010); /* lwz r0,16(r1) */
- EndPutM32Inc(data, 0x80410014); /* lwz r2,20(r1) */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
- }
- else if(ap->Flags & AMIPRAGFLAG_PPC0)
- {
- basepos = data;
- EndPutM32Inc(data, 0x81620000); /* lwz r11,BaseName(r2) */
- EndPutM32Inc(data, 0x800C0000 - ap->Bias); /* lwz r0,-ap->Bias(r11) */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
- EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
- }
- else if(ap->Flags & AMIPRAGFLAG_PPC)
- {
- count = ap->NumArgs;
- if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
- {
- /* init stack frame */
- i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
- EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
- EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
- EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
-
- if(count > 8)
- {
- /* extra arguments must be passed on the stack */
- k = 32-(count-8); /* firstreg */
- EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-8)*4)); /* stmw rk,X(r1) */
- EndPutM32Inc(data, 0xB8010000 + (k << 21) + (i+56)); /* lmw rk,Y(r1) */
- if(flags & FUNCFLAG_TAG)
- EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4)); /* addi r31,r1,X */
- EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
- }
- else if(flags & FUNCFLAG_TAG)
- {
- EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4)); /* addi rX,r1,Y */
- --count;
- }
- }
- else /* Args must be shifted! */
- {
- /* init stack frame */
- i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
- EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
- EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
- EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
-
- if(count > 7)
- {
- /* extra arguments must be passed on the stack */
- if(count == 8)
- {
- /* special case: move 8th argument into stack frame */
- if(flags & FUNCFLAG_TAG)
- EndPutM32Inc(data, 0x39410000 + (i+20+count*4)); /* addi r10,r1,X */
- EndPutM32Inc(data, 0x91410038); /* stw r10,56(r1) */
- }
- else
- {
- k = 32-(count-7); /* firstreg */
-
- EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-7)*4));/* stmw rk,X(r1) */
- EndPutM32Inc(data, 0x7D405378 + (k<<16)); /* mr rk,r10 = or rk,r10,r10 */
- EndPutM32Inc(data, 0xB8010000 + ((k+1) << 21) + (i+56)); /* lmw rk,Y(r1) */
- if(flags & FUNCFLAG_TAG)
- EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4)); /* addi r31,r1,X */
- EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
- }
- }
- else if(flags & FUNCFLAG_TAG)
- {
- EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4)); /* addi rX,r1,Y */
- --count;
- }
-
- /* shift all arguments into their following register */
- for(k=(count<8)?count:7; k > 0; --k)
- EndPutM32Inc(data, 0x7C000378 + ((3+k)<<16) + ((2+k)<<21) + ((2+k)<<11)); /* mr rX,rY = or rX,rY,rY */
-
- /* load library base and LVO, then call LVO via LR */
- basepos = data;
- EndPutM32Inc(data, 0x80620000); /* lwz r3,BaseName(r2) */
- }
- /* call LVO */
- EndPutM32Inc(data, 0x80040000 - (ap->Bias-2)); /* lwz r0,-(ap->Bias-2)(r3) */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
-
-
- /* cleanup stack frame and return */
- if(count > 8)
- {
- k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
- EndPutM32Inc(data, 0xB8010000 + ((32-(count-k))<<21) + (56+(count-k)*4)); /* lmw rX,Y(r1) */
- }
- EndPutM32Inc(data, 0x38210000 + i); /* addi r1,r1,i */
- EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
- }
- else
- {
- EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
- EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
- EndPutM32Inc(data, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
-
- EndPutM32Inc(data, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
- EndPutM32Inc(data, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
- EndPutM32Inc(data, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
- EndPutM32Inc(data, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
-
- if(Flags & FLAG_WOSLIBBASE)
- {
- EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
- EndPutM32Inc(data, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
- EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
- EndPutM32Inc(data, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
- }
- else if(!BaseName)
- {
- EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
- EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
- }
- else
- {
- basepos = data;
- EndPutM32Inc(data, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
- EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
- EndPutM32Inc(data, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
- EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
- EndPutM32Inc(data, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
- }
-
- ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
- k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
- for(i = 0; i < k; ++i)
- {
- j = 0x34+4*ap->Args[i].ArgReg; /* PP_Regs offset */
- if(i + ofs <= 7)
- {
- if(ap->Args[i].ArgReg == REG_A6)
- EndPutM32Inc(data, 0x90010020 + ((i+3+ofs)<<21)); /* stw rX,0x20(r1) */
- EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
- }
- else
- {
- EndPutM32Inc(data, 0x81610000 + ((i+1+ofs)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
- if(ap->Args[i].ArgReg == REG_A6)
- EndPutM32Inc(data, 0x91610020); /* stw r11,0x20(r1) */
- EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
- }
- }
- if(flags & FUNCFLAG_TAG)
- {
- j = (ap->NumArgs+ofs)*4+0xC4;
-
- if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
- EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
- EndPutM32Inc(data, 0x39610000 + j); /* addi r11,r1,j */
- EndPutM32Inc(data, 0x91610000 + (0x34+4*ap->Args[i].ArgReg)); /* stw r11,X(r1) */
- }
-
- if(!(Flags & FLAG_WOSLIBBASE))
- {
- pbasepos = data; /* store 16BIT reloc offset */
- EndPutM32Inc(data, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
- }
- EndPutM32Inc(data, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
- EndPutM32Inc(data, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
- EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
- EndPutM32Inc(data, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
- EndPutM32Inc(data, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
- EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) = get old link register */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump back */
- }
-
- EndPutM32(tempbuf, HUNK_PPC_CODE);
- EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
- DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
-
- EndPutM32(tempbuf, HUNK_EXT);
- DoOutputDirect(tempbuf,4);
-
- /* here come the XDEF name references */
-
- if(Flags & FLAG_WOSLIBBASE)
- {
- if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
- OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
- OutputXDEF(0, "__%s", name);
- }
- else
- {
- if(BaseName)
- OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
- if(!(ap->Flags & AMIPRAGFLAG_PPC))
- OutputXREF((pbasepos-tempbuf-8)+2, EXT_DEXT16, "_PowerPCBase");
- OutputXDEF(0, "_%s", name);
- }
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf,4);
- if(!(Flags & FLAG_NOSYMBOL))
- {
- EndPutM32(tempbuf, HUNK_SYMBOL);
- DoOutputDirect(tempbuf,4);
- if(Flags & FLAG_WOSLIBBASE)
- OutputSYMBOL(0, "__%s", name);
- else
- OutputSYMBOL(0, "_%s", name);
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf,4);
- }
- EndPutM32(tempbuf, HUNK_END);
-
- return DoOutputDirect(tempbuf,4);
- }
-
- uint32 FuncVBCCPUPText(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE;
-
- if(Flags & FLAG_SINGLEFILE)
- {
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
- }
-
- if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
- DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
-
- if(Flags & FLAG_SINGLEFILE)
- DoOutput("\t.file\t\"%s.s\"\n", name);
- if(BaseName)
- DoOutput("\t.global %s\n", BaseName);
- DoOutput("\t.global PPCCallOS\n\t.global %s\n"
- "\t.align\t3\n%s:\n",name, name);
-
- if(flags & FUNCFLAG_TAG)
- {
- /* Hack the stack-frame for varargs.
- Build stack-frame, but save LR in our own stack-frame,
- because we have to overwrite the lower 8 bytes of the
- caller's frame. */
- DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- /* Save the caller's saved SP in our own stack-frame. */
- DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- /* Store r3-r8 at the top of our stack-frame and r9-r10
- at the low 8 bytes of the caller's frame. This way all
- arguments will reside in one continuous area. */
- for(i=3+ap->NumArgs-1; i <= 10; ++i)
- DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i, 104+4*(i-3),
- PPCRegPrefix);
- }
- else
- DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
- {
- if(i <= 7)
- DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
- else
- DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
- 100+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
- }
- else
- DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix,
- PPCRegPrefix, 100+ap->NumArgs*4, PPCRegPrefix);
- DoOutput("%d(%s1)\n", 36+4*ap->Args[i].ArgReg, PPCRegPrefix);
- }
-
- /* Now place the real function call */
- DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n" /* store offset in Chaos->caos_Un.Offset */
- "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix,
- ap->Bias, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix);
- /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
-
- if(BaseName)
- {
- if(Flags & FLAG_SMALLDATA)
- DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
- else
- DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix,
- BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
- DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix, PPCRegPrefix); /* store basepointer in A6 */
- }
-
- DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix, PPCRegPrefix);
- if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
- DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
- "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- else
- DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name, name, name);
- }
-
- uint32 FuncVBCCPUPCode(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i, j=0, k, size;
- uint8 *data, *data2, *data3;
- struct ArHeader *arh;
-
- data = tempbuf;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE;
-
- *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
- *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
- *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
- *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
- *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
- *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
- *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- EndPutM16Inc(data, ET_REL); /* eeh->e_type */
- EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
- EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
- EndPutM32Inc(data, 0); /* eeh->e_entry */
- EndPutM32Inc(data, 0); /* eeh->e_phoff */
- data2 = data; data += 4;
- EndPutM32Inc(data, 0); /* eeh->e_flags */
- EndPutM16Inc(data, 52); /* eeh->e_ehsize */
- EndPutM16Inc(data, 0); /* eeh->e_phentsize */
- EndPutM16Inc(data, 0); /* eeh->e_phnum */
- EndPutM16Inc(data, 40); /* eeh->e_shentsize */
- EndPutM16Inc(data, 6); /* eeh->e_shnum */
- EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
-
- data3 = data;
- if(flags & FUNCFLAG_TAG)
- {
- /* Hack the stack-frame for varargs.
- Build stack-frame, but save LR in our own stack-frame,
- because we have to overwrite the lower 8 bytes of the
- caller's frame. */
- EndPutM32Inc(data, 0x9421FF80); /* stwu r1,-128(r1) */
- EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
- EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
-
- /* Save the caller's saved SP in our own stack-frame. */
- EndPutM32Inc(data, 0x81610080); /* lwz r11,128(r1) */
- EndPutM32Inc(data, 0x91610060); /* stw r11,96(r1) */
-
- /* Store r3-r8 at the top of our stack-frame and r9-r10
- at the low 8 bytes of the caller's frame. This way all
- arguments will reside in one continuous area. */
- for(i=3+ap->NumArgs-1; i <= 10; ++i)
- EndPutM32Inc(data, 0x90010000 + (i<<21) + (104+4*(i-3))); /* stw rX,Y(r1) */
- }
- else
- {
- EndPutM32Inc(data, 0x9421FFA0); /* stwu r1,-96(r1) */
- EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
- EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
- }
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- j = 36+4*ap->Args[i].ArgReg;
- if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
- {
- if(i <= 7)
- {
- EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j); /* stw rX,j(r1) */
- }
- else
- {
- EndPutM32Inc(data, 0x81610000 + (100+(i+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
- EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
- }
- }
- else
- {
- EndPutM32Inc(data, 0x39610000 + (100+ap->NumArgs*4)); /* addi r11,r1,X */
- EndPutM32Inc(data, 0x91610000 + j); /* stw r11,X(r1) */
- }
- }
-
- /* Now place the real function call */
- EndPutM32Inc(data, 0x39610000 - ap->Bias); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
- EndPutM32Inc(data, 0x91610008); /* stw r11,8(r1) */
- EndPutM32Inc(data, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
- EndPutM32Inc(data, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
- EndPutM32Inc(data, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
-
- if(BaseName)
- {
- if(Flags & FLAG_SMALLDATA)
- {
- j = (data-data3)+2; /* store reloc offset */
- EndPutM32Inc(data, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
- }
- else
- {
- j = (data-data3)+2; /* store reloc offset */
- EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
- EndPutM32Inc(data, 0x816B0000); /* lwz r11,BaseName@l(r11) */
- }
- EndPutM32Inc(data, 0x9161005C); /* stw r11,92(r1) */
- }
-
- EndPutM32Inc(data, 0x38610008); /* addi r3,r1,8 */
- k = (data-data3); /* store reloc offset */
- EndPutM32Inc(data, 0x48000001); /* bl PPCCallOS */
- if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
- {
- EndPutM32Inc(data, 0x81610060); /* lwz r11,96(r1) */
- EndPutM32Inc(data, 0x91610080); /* stw r11,128(r1) */
- EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
- EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
- EndPutM32Inc(data, 0x38210080); /* addi r1,r1,128 */
- }
- else
- {
- EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
- EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
- EndPutM32Inc(data, 0x38210060); /* addi r1,r1,96 */
- }
-
- EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
-
- memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
- data += 44; /* 1 9 17 27 33 */
-
- EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
- data2 = data-44;
-
- EndPutM32Inc(data, 0); /* esh[0].sh_name */
- EndPutM32Inc(data, 0); /* esh[0].sh_type */
- EndPutM32Inc(data, 0); /* esh[0].sh_flags */
- EndPutM32Inc(data, 0); /* esh[0].sh_addr */
- EndPutM32Inc(data, 0); /* esh[0].sh_offset */
- EndPutM32Inc(data, 0); /* esh[0].sh_size */
- EndPutM32Inc(data, 0); /* esh[0].sh_link */
- EndPutM32Inc(data, 0); /* esh[0].sh_info */
- EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
-
- size = data2-data3;
- EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
- EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
- EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
- EndPutM32Inc(data, 0); /* esh[1].sh_addr */
- EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
- EndPutM32Inc(data, size); /* esh[1].sh_size */
- EndPutM32Inc(data, 0); /* esh[1].sh_link */
- EndPutM32Inc(data, 0); /* esh[1].sh_info */
- EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
-
- data3 = data;
- EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
- EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
- EndPutM32Inc(data, 0); /* esh[2].sh_flags */
- EndPutM32Inc(data, 0); /* esh[2].sh_addr */
- data += 4; /* esh[2].sh_offset */
- data += 4; /* esh[2].sh_size */
- EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
- EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
- EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
- EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
-
- EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
- EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
- EndPutM32Inc(data, 0); /* esh[3].sh_flags */
- EndPutM32Inc(data, 0); /* esh[3].sh_addr */
- EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
- EndPutM32Inc(data, 44); /* esh[3].sh_size */
- EndPutM32Inc(data, 0); /* esh[3].sh_link */
- EndPutM32Inc(data, 0); /* esh[3].sh_info */
- EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
-
- EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
- EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
- EndPutM32Inc(data, 0); /* esh[4].sh_flags */
- EndPutM32Inc(data, 0); /* esh[4].sh_addr */
- data += 4; /* esh[4].sh_offset */
- data += 4; /* esh[4].sh_size */
- EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
- EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
- EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
- EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
-
- EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
- EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
- EndPutM32Inc(data, 0); /* esh[0].sh_flags */
- EndPutM32Inc(data, 0); /* esh[0].sh_addr */
- data += 4; /* esh[0].sh_offset */
- data += 4; /* esh[0].sh_size */
- EndPutM32Inc(data, 0); /* esh[0].sh_link */
- EndPutM32Inc(data, 0); /* esh[0].sh_info */
- EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
-
- EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
- EndPutM32(data3+(2*40)+(5*4), BaseName ? 6*16 : 5*16); /* esh[4].sh_size */
-
- data2 = data;
- data += BaseName ? 6*16 : 5*16;
-
- EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
-
- i = 0;
- EndPutM32Inc(data2, i); /* esym[0].st_name */
- EndPutM32Inc(data2, 0); /* esym[0].st_value */
- EndPutM32Inc(data2, 0); /* esym[0].st_size */
- *(data2++) = 0; /* esym[0].st_info */
- *(data2++) = 0; /* esym[0].st_other */
- EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
- data[0] = 0;
-
- i += 1;
- EndPutM32Inc(data2, i); /* esym[1].st_name */
- EndPutM32Inc(data2, 0); /* esym[1].st_value */
- EndPutM32Inc(data2, 0); /* esym[1].st_size */
- *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
- *(data2++) = 0; /* esym[1].st_other */
- EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
-
- sprintf((strptr)data+i, "%s.s", name); while(data[i++]) ; /* get next store space */
- EndPutM32Inc(data2, 0); /* esym[2].st_name */
- EndPutM32Inc(data2, 0); /* esym[2].st_value */
- EndPutM32Inc(data2, 0); /* esym[2].st_size */
- *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
- *(data2++) = 0; /* esym[2].st_other */
- EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
-
- EndPutM32Inc(data2, i); /* esym[3].st_name */
- EndPutM32Inc(data2, 0); /* esym[3].st_value */
- EndPutM32Inc(data2, size); /* esym[3].st_size */
- *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
- *(data2++) = 0; /* esym[3].st_other */
- EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
-
- sprintf((strptr)data+i, name); while(data[i++]) ; /* get next store space */
- EndPutM32Inc(data2, i); /* esym[4].st_name */
- EndPutM32Inc(data2, 0); /* esym[4].st_value */
- EndPutM32Inc(data2, 0); /* esym[4].st_size */
- *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
- *(data2++) = 0; /* esym[4].st_other */
- EndPutM16Inc(data2, 0); /* esym[4].st_shndx */
-
- sprintf((strptr)data+i, "PPCCallOS"); while(data[i++]) ; /* get next store space */
- if(BaseName)
- {
- EndPutM32Inc(data2, i); /* esym[5].st_name */
- EndPutM32Inc(data2, 0); /* esym[5].st_value */
- EndPutM32Inc(data2, 0); /* esym[5].st_size */
- *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[5].st_info */
- *(data2++) = 0; /* esym[5].st_other */
- EndPutM16/*Inc*/(data2, 0); /* esym[5].st_shndx */
-
- sprintf((strptr)data+i, BaseName); while(data[i++]) ; /* get next store space */
- }
- EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
- while(i&3) /* long aligned */
- data[i++] = 0;
- data += i;
-
- EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
-
- data2 = data;
-
- EndPutM32Inc(data, k); /* erel[0].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_REL24)); /* erel[0].r_info - entry 4, type 10 */
- EndPutM32Inc(data, 0); /* erel[0].r_addend */
-
- if(BaseName)
- {
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM32Inc(data, j); /* erel[1].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_SDAREL16)); /* erel[1].r_info - entry 5, type 32 */
- EndPutM32Inc(data, 0); /* erel[1].r_addend */
- }
- else
- {
- EndPutM32Inc(data, j); /* erel[1].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_HA)); /* erel[1].r_info - entry 5, type 6 */
- EndPutM32Inc(data, 0); /* erel[1].r_addend */
- EndPutM32Inc(data, j+4); /* erel[2].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_LO)); /* erel[2].r_info - entry 5, type 4 */
- EndPutM32Inc(data, 0); /* erel[2].r_addend */
- }
- }
- EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
-
- /* make ar header and store all */
- arh = (struct ArHeader *) (data+20);
- memset(arh, ' ', sizeof(struct ArHeader));
-
- arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
- arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
- arh->ar_mode[2] = '0';
- arh->ar_mode[0] = '6';
- arh->ar_fmag[0] = 96;
- arh->ar_fmag[1] = '\n';
-
- if((k = strlen(name) + 2) >= 16)
- {
- arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
- }
- else
- {
- k = 0;
- arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
- }
-
- j = k + (data-tempbuf);
- for(i = 9; j; --i) /* make decimal number */
- {
- data[i] = (j%10)+'0';
- j /= 10;
- }
- for(j = 0; i < 9; ++j)
- arh->ar_size[j] = data[++i];
-
- DoOutputDirect(arh, sizeof(struct ArHeader));
-
- if(k)
- {
- DoOutput("%s.o", name);
- if(k & 1)
- *(data++) = 0x0A; /* alignment byte! */
- }
-
- return DoOutputDirect(tempbuf, data-tempbuf);
- }
-
- uint32 FuncVBCCMorphText(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE;
-
- if(Flags & FLAG_SINGLEFILE)
- {
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
- }
-
- if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
- DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
-
- if(Flags & FLAG_SINGLEFILE)
- DoOutput("\t.file\t\"%s.s\"\n", name);
- if(BaseName)
- DoOutput("\t.global %s\n", BaseName);
- DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name, name);
-
- if(flags & FUNCFLAG_TAG)
- {
- /* Hack the stack-frame for varargs.
- Build stack-frame, but save LR in our own stack-frame,
- because we have to overwrite the lower 8 bytes of the
- caller's frame. */
- DoOutput("\tstwu\t%s1,-112(%s1)\n\tmflr\t%s0\n\tstw\t%s0,84(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- /* Save the caller's saved SP in our own stack-frame. */
- DoOutput("\tlwz\t%s11,112(%s1)\n\tstw\t%s11,80(%s1)\n", PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- /* Store r3-r8 at the top of our stack-frame and r9-r10
- at the low 8 bytes of the caller's frame. This way all
- arguments will reside in one continuous area. */
- for(i=3+ap->NumArgs-1; i <= 10; ++i)
- DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i, 88+4*(i-3),
- PPCRegPrefix);
- }
- else
- DoOutput("\tstwu\t%s1,-80(%s1)\n\tmflr\t%s0\n\tstw\t%s0,84(%s1)\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- if(BaseName)
- {
- if(Flags & FLAG_SMALLDATA)
- DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
- else
- DoOutput("\tlis\t%s12,%s@ha\n\tlwz\t%s12,%s@l(%s12)\n", PPCRegPrefix,
- BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
-
- DoOutput("\tstw\t%s12,68(%s1)\n", PPCRegPrefix, PPCRegPrefix); /* store basepointer in A6 */
- }
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
- {
- if(i <= 7)
- DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
- else
- DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
- 84+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
- }
- else
- DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix,
- PPCRegPrefix, 84+ap->NumArgs*4, PPCRegPrefix);
- DoOutput("%d(%s1)\n", 12+4*ap->Args[i].ArgReg, PPCRegPrefix);
- }
-
- /* Now place the real function call */
- DoOutput("\tli\t%s0,-%d\n\tstw\t%s0,8(%s1)\n", /* store offset in Chaos->caos_Un.Offset */
- PPCRegPrefix, ap->Bias, PPCRegPrefix, PPCRegPrefix);
-
- DoOutput("\taddi\t%s3,%s1,8\n\tlwz\t%s0,88(%s2)\n\tmtlr\t%s0\n\tblrl\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
- DoOutput("\tlwz\t%s11,80(%s1)\n\tstw\t%s11,112(%s1)\n"
- "\tlwz\t%s0,84(%s1)\n\taddi\t%s1,%s1,112\n\tmtlr\t%s0\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
- else
- DoOutput("\tlwz\t%s0,84(%s1)\n\taddi\t%s1,%s1,80\n\tmtlr\t%s0\n",
- PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
-
- return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name, name, name);
- }
-
- uint32 FuncVBCCMorphCode(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i, j, k=0, size;
- uint8 *data, *data2, *data3;
- struct ArHeader *arh;
-
- data = tempbuf;
-
- if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
- return 1;
-
- Flags |= FLAG_DONE;
-
- *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
- *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
- *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
- *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
- *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
- *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
- *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- EndPutM16Inc(data, ET_REL); /* eeh->e_type */
- EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
- EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
- EndPutM32Inc(data, 0); /* eeh->e_entry */
- EndPutM32Inc(data, 0); /* eeh->e_phoff */
- data2 = data; data += 4;
- EndPutM32Inc(data, 0); /* eeh->e_flags */
- EndPutM16Inc(data, 52); /* eeh->e_ehsize */
- EndPutM16Inc(data, 0); /* eeh->e_phentsize */
- EndPutM16Inc(data, 0); /* eeh->e_phnum */
- EndPutM16Inc(data, 40); /* eeh->e_shentsize */
- EndPutM16Inc(data, 6); /* eeh->e_shnum */
- EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
-
- data3 = data;
- if(flags & FUNCFLAG_TAG)
- {
- /* Hack the stack-frame for varargs.
- Build stack-frame, but save LR in our own stack-frame,
- because we have to overwrite the lower 8 bytes of the
- caller's frame. */
- EndPutM32Inc(data, 0x9421FF90); /* stwu r1,-112(r1) */
- EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
- EndPutM32Inc(data, 0x90010054); /* stw r0,84(r1) */
-
- /* Save the caller's saved SP in our own stack-frame. */
- EndPutM32Inc(data, 0x81610070); /* lwz r11,112(r1) */
- EndPutM32Inc(data, 0x91610050); /* stw r11,80(r1) */
-
- /* Store r3-r8 at the top of our stack-frame and r9-r10
- at the low 8 bytes of the caller's frame. This way all
- arguments will reside in one continuous area. */
- for(i=3+ap->NumArgs-1; i <= 10; ++i)
- EndPutM32Inc(data, 0x90010000 + (i<<21) + (88+4*(i-3))); /* stw rX,Y(r1) */
- }
- else
- {
- EndPutM32Inc(data, 0x9421FFB0); /* stwu r1,-80(r1) */
- EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
- EndPutM32Inc(data, 0x90010054); /* stw r0,84(r1) */
- }
-
- if(BaseName)
- {
- if(Flags & FLAG_SMALLDATA)
- {
- k = (data-data3)+2; /* store reloc offset */
- EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
- }
- else
- {
- k = (data-data3)+2; /* store reloc offset */
- EndPutM32Inc(data, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
- EndPutM32Inc(data, 0x818C0000); /* lwz r12,BaseName@l(r12) */
- }
- EndPutM32Inc(data, 0x91810044); /* stw r12,68(r1) */
- }
-
- for(i = 0; i < ap->NumArgs; ++i)
- {
- j = 12+4*ap->Args[i].ArgReg;
- if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
- {
- if(i <= 7)
- {
- EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j); /* stw rX,j(r1) */
- }
- else
- {
- EndPutM32Inc(data, 0x81610000 + (84+(i+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
- EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
- }
- }
- else
- {
- EndPutM32Inc(data, 0x39610000 + (84+ap->NumArgs*4)); /* addi r11,r1,X */
- EndPutM32Inc(data, 0x91610000 + j); /* stw r11,X(r1) */
- }
- }
-
- /* Now place the real function call */
- EndPutM32Inc(data, 0x38010000 - ap->Bias); /* li r0,-(ap->Bias) = addi r0,0,-ap->Bias */
- EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
-
- EndPutM32Inc(data, 0x38610008); /* addi r3,r1,8 */
- EndPutM32Inc(data, 0x80020058); /* lwz r0,88(r2) */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 */
-
- if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
- {
- EndPutM32Inc(data, 0x81610050); /* lwz r11,80(r1) */
- EndPutM32Inc(data, 0x91610070); /* stw r11,112(r1) */
- EndPutM32Inc(data, 0x80010054); /* lwz r0,84(r1) */
- EndPutM32Inc(data, 0x38210070); /* addi r1,r1,112 */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- }
- else
- {
- EndPutM32Inc(data, 0x80010054); /* lwz r0,84(r1) */
- EndPutM32Inc(data, 0x38210050); /* addi r1,r1,80 */
- EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
- }
-
- EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
-
- memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
- data += 44; /* 1 9 17 27 33 */
-
- EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
- data2 = data-44;
-
- EndPutM32Inc(data, 0); /* esh[0].sh_name */
- EndPutM32Inc(data, 0); /* esh[0].sh_type */
- EndPutM32Inc(data, 0); /* esh[0].sh_flags */
- EndPutM32Inc(data, 0); /* esh[0].sh_addr */
- EndPutM32Inc(data, 0); /* esh[0].sh_offset */
- EndPutM32Inc(data, 0); /* esh[0].sh_size */
- EndPutM32Inc(data, 0); /* esh[0].sh_link */
- EndPutM32Inc(data, 0); /* esh[0].sh_info */
- EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
-
- size = data2-data3;
- EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
- EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
- EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
- EndPutM32Inc(data, 0); /* esh[1].sh_addr */
- EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
- EndPutM32Inc(data, size); /* esh[1].sh_size */
- EndPutM32Inc(data, 0); /* esh[1].sh_link */
- EndPutM32Inc(data, 0); /* esh[1].sh_info */
- EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
-
- data3 = data;
- EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
- EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
- EndPutM32Inc(data, 0); /* esh[2].sh_flags */
- EndPutM32Inc(data, 0); /* esh[2].sh_addr */
- data += 4; /* esh[2].sh_offset */
- data += 4; /* esh[2].sh_size */
- EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
- EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
- EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
- EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
-
- EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
- EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
- EndPutM32Inc(data, 0); /* esh[3].sh_flags */
- EndPutM32Inc(data, 0); /* esh[3].sh_addr */
- EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
- EndPutM32Inc(data, 44); /* esh[3].sh_size */
- EndPutM32Inc(data, 0); /* esh[3].sh_link */
- EndPutM32Inc(data, 0); /* esh[3].sh_info */
- EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
-
- EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
- EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
- EndPutM32Inc(data, 0); /* esh[4].sh_flags */
- EndPutM32Inc(data, 0); /* esh[4].sh_addr */
- data += 4; /* esh[4].sh_offset */
- data += 4; /* esh[4].sh_size */
- EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
- EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
- EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
- EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
-
- EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
- EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
- EndPutM32Inc(data, 0); /* esh[0].sh_flags */
- EndPutM32Inc(data, 0); /* esh[0].sh_addr */
- data += 4; /* esh[0].sh_offset */
- data += 4; /* esh[0].sh_size */
- EndPutM32Inc(data, 0); /* esh[0].sh_link */
- EndPutM32Inc(data, 0); /* esh[0].sh_info */
- EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
-
- EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
- EndPutM32(data3+(2*40)+(5*4), BaseName ? 5*16 : 4*16); /* esh[4].sh_size */
-
- data2 = data;
- data += BaseName ? 5*16 : 4*16;
-
- EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
-
- i = 0;
- EndPutM32Inc(data2, i); /* esym[0].st_name */
- EndPutM32Inc(data2, 0); /* esym[0].st_value */
- EndPutM32Inc(data2, 0); /* esym[0].st_size */
- *(data2++) = 0; /* esym[0].st_info */
- *(data2++) = 0; /* esym[0].st_other */
- EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
- data[0] = 0;
-
- i += 1;
- EndPutM32Inc(data2, i); /* esym[1].st_name */
- EndPutM32Inc(data2, 0); /* esym[1].st_value */
- EndPutM32Inc(data2, 0); /* esym[1].st_size */
- *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
- *(data2++) = 0; /* esym[1].st_other */
- EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
-
- sprintf((strptr)data+i, "%s.s", name); while(data[i++]) ; /* get next store space */
- EndPutM32Inc(data2, 0); /* esym[2].st_name */
- EndPutM32Inc(data2, 0); /* esym[2].st_value */
- EndPutM32Inc(data2, 0); /* esym[2].st_size */
- *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
- *(data2++) = 0; /* esym[2].st_other */
- EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
-
- EndPutM32Inc(data2, i); /* esym[3].st_name */
- EndPutM32Inc(data2, 0); /* esym[3].st_value */
- EndPutM32Inc(data2, size); /* esym[3].st_size */
- *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
- *(data2++) = 0; /* esym[3].st_other */
- EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
-
- sprintf((strptr)data+i, name); while(data[i++]) ; /* get next store space */
- if(BaseName)
- {
- EndPutM32Inc(data2, i); /* esym[4].st_name */
- EndPutM32Inc(data2, 0); /* esym[4].st_value */
- EndPutM32Inc(data2, 0); /* esym[4].st_size */
- *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
- *(data2++) = 0; /* esym[4].st_other */
- EndPutM16/*Inc*/(data2, 0); /* esym[4].st_shndx */
-
- sprintf((strptr)data+i, BaseName); while(data[i++]) ; /* get next store space */
- }
- EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
- while(i&3) /* long aligned */
- data[i++] = 0;
- data += i;
-
- EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
-
- data2 = data;
-
- if(BaseName)
- {
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM32Inc(data, k); /* erel[0].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_SDAREL16)); /* erel[0].r_info - entry 4, type 32 */
- EndPutM32Inc(data, 0); /* erel[0].r_addend */
- }
- else
- {
- EndPutM32Inc(data, k); /* erel[0].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_HA)); /* erel[0].r_info - entry 4, type 6 */
- EndPutM32Inc(data, 0); /* erel[0].r_addend */
- EndPutM32Inc(data, k+4); /* erel[1].r_offset */
- EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_LO)); /* erel[1].r_info - entry 4, type 4 */
- EndPutM32Inc(data, 0); /* erel[1].r_addend */
- }
- }
- EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
-
- /* make ar header and store all */
- arh = (struct ArHeader *) (data+20);
- memset(arh, ' ', sizeof(struct ArHeader));
-
- arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
- arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
- arh->ar_mode[2] = '0';
- arh->ar_mode[0] = '6';
- arh->ar_fmag[0] = 96;
- arh->ar_fmag[1] = '\n';
-
- if((k = strlen(name) + 2) >= 16)
- {
- arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
- }
- else
- {
- k = 0;
- arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
- }
-
- j = k + (data-tempbuf);
- for(i = 9; j; --i) /* make decimal number */
- {
- data[i] = (j%10)+'0';
- j /= 10;
- }
- for(j = 0; i < 9; ++j)
- arh->ar_size[j] = data[++i];
-
- DoOutputDirect(arh, sizeof(struct ArHeader));
-
- if(k)
- {
- DoOutput("%s.o", name);
- if(k & 1)
- *(data++) = 0x0A; /* alignment byte! */
- }
-
- return DoOutputDirect(tempbuf, data-tempbuf);
- }
-
- uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- uint8 i, r;
-
- if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
- (flags & FUNCFLAG_ALIAS))
- return 1;
-
- if(LastBias >= ap->Bias)
- DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
- else
- {
- Flags |= FLAG_DONE; /* We did something */
-
- for(LastBias += BIAS_OFFSET; LastBias < ap->Bias; LastBias += BIAS_OFFSET)
- DoOutputDirect("Dum\x10", 4);
-
- DoOutput("%c", toupper(name[0]));
- if(name[1])
- {
- DoOutput("%c", tolower(name[1]));
- if(name[2])
- DoOutput("%s", name+2);
- }
- if(!ap->NumArgs)
- DoOutputDirect("\x10", 1);
- else
- {
- for(i = 0; i < ap->NumArgs; ++i)
- {
- r = ap->Args[i].ArgReg;
- DoOutputDirect(&r, 1);
- }
- }
- }
- return 1;
- }
-
- uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- int32 i;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(ap->Flags & AMIPRAGFLAG_PUBLIC)
- {
- if(Flags & FLAG_ISPRIVATE)
- {
- Flags ^= FLAG_ISPRIVATE;
- DoOutput("##public\n");
- }
- }
- else
- {
- if(!(Flags & FLAG_ISPRIVATE))
- DoOutput("##private\n");
- Flags |= FLAG_ISPRIVATE;
- }
-
- LastBias += BIAS_OFFSET;
- if(LastBias != ap->Bias)
- {
- DoOutput("##bias %d\n", ap->Bias);
- LastBias = ap->Bias;
- }
-
- if(ap->Abi != CurrentABI)
- {
- switch(ap->Abi)
- {
- case ABI_M68K: DoOutput("##abi M68k\n"); break;
- case ABI_PPC0: DoOutput("##abi PPC0\n"); break;
- case ABI_PPC2: DoOutput("##abi PPC2\n"); break;
- case ABI_PPC: DoOutput("##abi PPC\n"); break;
- }
- CurrentABI = ap->Abi;
- }
-
- DoOutput("%s("/*)*/, name);
- for(i = 0; i < ap->CallArgs; i++)
- DoOutput("%s%s", ap->Args[i].ArgName, i < ap->CallArgs-1 ? "," : "");
- DoOutput(/*(*/")("/*)*/);
-
- if(!(ap->Flags & AMIPRAGFLAG_PPC))
- {
- for(i = 0; i < ap->CallArgs; i++)
- {
- DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], i < ap->CallArgs-1 ?
- (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg ? "/" : ",") : "");
- }
- }
- return DoOutput(/*(*/")\n");
- }
-
- /* called from FuncSFD directly */
- uint32 FuncClib(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- struct ClibData *cd;
- int32 i, s, c;
-
- Flags |= FLAG_DONE; /* We did something */
-
- if(!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- s = MakeClibType(tempbuf, &cd->ReturnType, 0);
- DoOutputDirect(tempbuf, s);
- DoOutput(" %s("/*)*/, name);
-
- if(ap->NumArgs)
- {
- for(i = 0; i < cd->NumArgs; i++)
- {
- c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
- if(s+c+2 > 75 && s)
- {
- DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
- }
- else if(i)
- {
- DoOutput(", "); s += 2;
- }
- DoOutputDirect(tempbuf, c);
- s += c;
- }
- }
- else if(Flags2 & FLAG2_CLIBOUT)
- DoOutput("void");
- return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
- }
-
- uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
- {
- struct ClibData *cd;
- int32 i, j;
-
- if(!(cd = GetClibFunc(name, ap, flags)))
- return 1;
-
- if(ap->Flags & AMIPRAGFLAG_PUBLIC)
- {
- if(Flags & FLAG_ISPRIVATE)
- {
- Flags ^= FLAG_ISPRIVATE;
- DoOutput("==public\n");
- }
- }
- else
- {
- if(!(Flags & FLAG_ISPRIVATE))
- DoOutput("==private\n");
- Flags |= FLAG_ISPRIVATE;
- }
-
- if(ap->Abi != CurrentABI)
- {
- switch(ap->Abi)
- {
- case ABI_M68K: DoOutput("==abi M68k\n"); break;
- case ABI_PPC0: DoOutput("==abi PPC0\n"); break;
- case ABI_PPC2: DoOutput("==abi PPC2\n"); break;
- case ABI_PPC: DoOutput("==abi PPC\n"); break;
- }
- CurrentABI = ap->Abi;
- }
-
- if(LastBias+BIAS_OFFSET < ap->Bias)
- {
- DoOutput("==reserve %ld\n", ((ap->Bias-LastBias)/BIAS_OFFSET)-1);
- LastBias = ap->Bias;
- }
- else if(flags & FUNCFLAG_TAG)
- DoOutput("==varargs\n");
- else if((flags & FUNCFLAG_ALIAS) || LastBias == ap->Bias)
- DoOutput("==alias\n");
- else
- LastBias += BIAS_OFFSET;
-
- if(!FuncClib(ap, flags, name))
- return 0;
-
- DoOutput(" ("/*)*/);
- if(!(ap->Flags & AMIPRAGFLAG_PPC))
- {
- strptr s;
-
- /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
- in step one, so the "-" can be placed at proper position. */
- for(j = i = 0; i < ap->NumArgs; i++)
- {
- if(i == ap->NumArgs-1)
- {
- s = ""; j += 2;
- }
- else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
- {
- s = (j&1) ? "," : "-"; ++j;
- }
- else
- {
- s = ","; j += 2;
- }
- DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], s);
- }
- }
- return DoOutput(/*(*/")\n");
- }
-
- static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
- {
- uint32 res;
-
- if(Flags & FLAG_SINGLEFILE)
- {
- sprintf(filename, filenamefmt, name);
- if(!OpenDest(filename))
- return 0;
- }
- res = Func(ap, flags, name);
- if(Flags & FLAG_SINGLEFILE)
- {
- CloseDest(filename);
- }
- return res;
- }
-
- static uint32 PrintComment(struct Comment *com, strptr comment)
- {
- if(com->Private && !(Flags & FLAG_PRIVATE))
- return 1;
- else if((Flags2 & FLAG2_SFDOUT) && com->Version)
- {
- return DoOutput("==version %d\n", com->Version);
- }
- else if((Flags2 & FLAG2_SFDOUT) && com->ReservedNum)
- {
- LastBias += BIAS_OFFSET*com->ReservedNum;
- return DoOutput("==reserve %d\n", com->ReservedNum);
- }
- else if(!(Flags & FLAG_DOCOMMENT) || !comment)
- return 1;
-
- if(com->Data)
- {
- if(!DoOutput(comment, com->Data))
- return 0;
- }
- else if(com->ReservedNum)
- {
- string temp[256];
- sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
- com->ReservedNum == 1 ? "" : "s");
- if(!DoOutput(comment, temp))
- return 0;
- }
- else if(com->Version)
- {
- string temp[256];
- if(com->Version >= FIRST_KNOWN_RELEASE && com->Version <= LAST_KNOWN_RELEASE &&
- (Flags2 & FLAG2_SYSTEMRELEASE))
- sprintf(temp, "* --- functions in V%u or higher %s ---", com->Version,
- Release[com->Version-FIRST_KNOWN_RELEASE]);
- else
- sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
-
- if(!DoOutput(comment, temp))
- return 0;
- }
- return 1;
- }
-
- static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
- {
- struct Comment *com;
- uint32 i;
- struct AmiPragma *ap;
-
- com = (struct Comment *) Comment.First;
-
- for(ap = (struct AmiPragma *) AmiPragma.First; ap;
- ap = (struct AmiPragma *) ap->List.Next)
- {
- if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
- {
- DoError(ERR_A6_NOT_ALLOWED, ap->Line);
- }
- else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
- {
- while(com && com->Bias <= ap->Bias)
- {
- if(!PrintComment(com, comment))
- return 0;
- com = (struct Comment *) com->List.Next;
- } /* comment loop */
-
- #ifdef DEBUG_OLD
- printf("Processing %s\n", ap->FuncName);
- #endif
-
- if(tagmode != TAGMODE_TAGS)
- {
- if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
- return 0;
-
- for(i = 0; i < ap->NumAlias; ++i)
- {
- if(ap->AliasName[i]->Type & FUNCFLAG_NORMAL)
- {
- if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
- return 0;
- }
- }
- }
-
- if(tagmode)
- {
- if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
- return 0;
-
- for(i = 0; i < ap->NumAlias; ++i)
- {
- if(ap->AliasName[i]->Type & FUNCFLAG_TAG)
- {
- if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
- return 0;
- }
- }
- }
- }
- }
- while(com)
- {
- if(!PrintComment(com, comment))
- return 0;
- com = (struct Comment *) com->List.Next;
- } /* comment loop */
- return 1;
- }
-
- static uint32 PrintIncludes(void) /* copies the include lines */
- {
- struct Include *inc;
- strptr s, s2;
-
- inc = (struct Include *) Includes.First;
-
- while(inc)
- {
- s2 = (strptr) tempbuf;
- for(s = inc->Include; *s; ++s)
- {
- switch(*s)
- {
- case '<': *(s2++) = ' '; break;
- case '/':
- case '.': *(s2++) = '_'; break;
- case '>': break;
- default: *(s2++) = toupper(*s);
- }
- *s2 = 0;
- }
- DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
- inc = (struct Include *) inc->List.Next;
- }
- if(!Includes.First)
- DoOutput("#include <exec/types.h>\n");
- return DoOutput("\n");
- }
-
- /* ------------------------------------------------------------------ */
-
- static int32 AddClibEntry(strptr buffer, strptr bufend, uint32 linenum)
- {
- strptr buf = buffer;
- struct ClibData d, *f;
-
- memset(&d, 0, sizeof(struct ClibData));
- buf = SkipBlanks(buf);
- if(*buf == '#') /* preprozessor lines */
- {
- #ifdef DEBUG
- printf("Found non-function bracket in preprozessor line %ld\n", linenum);
- #endif
- while(buf < bufend && *buf != '\n')
- ++buf;
- return buf-buffer;
- }
- if(!strnicmp(buf, "ASM", 3))
- buf = SkipBlanks(buf+3);
- else if(!strnicmp(buf, "STACK", 5))
- buf = SkipBlanks(buf+5);
- else if(!strnicmp(buf, "REGS", 4))
- buf = SkipBlanks(buf+4);
-
- if(!strnicmp(buf, "extern", 6))
- buf = SkipBlanks(buf+6);
-
- if(!GetCPPType(&d.ReturnType, buf, 1))
- {
- DoError(ERROFFSET_CLIB+ERR_UNKNOWN_RETURNVALUE_TYPE, linenum);
- return 0;
- }
- d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
- while(*(buf++) != '('/*)*/)
- ;
- *(SkipName(d.FuncName)) = 0;
- if(!(*d.FuncName))
- {
- #ifdef DEBUG
- printf("Found non-function bracket in line %ld\n", linenum);
- #endif
- while(buf < bufend && *buf != '\n')
- ++buf;
- return buf-buffer;
- }
- buf = SkipBlanksRet(buf);
-
- while(*buf != /*(*/')' && buf < bufend)
- {
- if(d.NumArgs == MAXREGPPC+1)
- {
- DoError(ERROFFSET_CLIB+ERR_TO_MUCH_ARGUMENTS, linenum);
- return 0;
- }
- else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0))
- {
- DoError(ERROFFSET_CLIB+ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
- return 0;
- }
-
- buf = d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength;
- while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
- ++buf;
- #ifdef DEBUG_OLD
- printf("Added argument %ld for %s (%ld bytes)\n", d.NumArgs, d.FuncName,
- d.Args[d.NumArgs-1].FullLength);
- #endif
- if(*buf == ',')
- buf = SkipBlanksRet(++buf);
- }
-
- if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
- d.NumArgs = 0; /* void arguments are no arguments */
-
- if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
- return -1;
-
- memcpy(f, &d, sizeof(struct ClibData));
-
- if(!clibdata)
- clibdata = f;
- else
- {
- struct ClibData *e = clibdata;
- while(e->Next)
- e = e->Next;
- e->Next = f;
- }
-
- #ifdef DEBUG_OLD
- printf("Added prototype for %s (line %ld, %ld bytes) with %ld args\n",
- f->FuncName, linenum, buf-buffer, f->NumArgs);
- #endif
- return buf-buffer;
- }
-
- static int32 ScanClibFile(strptr buf, strptr bufend)
- {
- strptr linestart = buf;
- uint32 linenum = 1;
-
- while(buf < bufend)
- {
- if(*buf == '/' && buf[1] == '*')
- {
- while(buf < bufend && (*buf != '*' || buf[1] != '/'))
- {
- if(*(buf++) == '\n')
- {
- ++linenum; linestart = buf;
- } /* skip comments */
- }
- }
- else if(*buf == '/' && buf[1] == '/')
- {
- while(buf < bufend && *buf != '\n')
- ++buf; /* skip line comments */
- }
- else if(*buf == '\n')
- {
- linestart = ++buf; ++linenum;
- }
- else if(!strncmp("#include", buf, 8))
- {
- struct Include *d;
-
- if(!(d = (struct Include *) NewItem(&Includes)))
- return 0;
- d->Include = buf = SkipBlanks(buf+8);
- AddItem(&Includes, (struct ShortList *) d);
- while(*buf && *buf != '>' && *buf != '\n')
- ++buf;
- if(*buf == '>')
- ++buf;
- if(*buf == '\n')
- ++linenum;
- *(buf++) = 0;
- #ifdef DEBUG
- printf("Added Include line %s\n", d->Include);
- #endif
- }
- else if(*buf == '('/*)*/)
- {
- int32 i;
-
- if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
- return 0;
- else if(!i)
- {
- while(buf < bufend && *buf != '\n')
- ++buf; /* skip this line */
- }
- else
- {
- i -= buf-linestart;
- while(buf < bufend && i-- > 0)
- {
- if(*(buf++) == '\n')
- {
- linestart = buf;
- ++linenum;
- } /* skip this function */
- }
- }
- }
- else
- ++buf;
- } /* while */
- return 1;
- }
-
- static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
- {
- if(!data || data->Flags || data->Type != type || data->PointerDepth)
- return 0;
- return type;
- }
-
- static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
- {
- uint32 i, j;
-
- for(i = 0; i < MAXREG; ++i)
- {
- j = strlen(RegNames[i]);
- if(!strnicmp(string, RegNames[i], j))
- {
- string += j;
- if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
- {
- data->Register = i;
- data->Flags |= CPP_FLAG_REGISTER;
- return j;
- }
- }
- }
- return 0;
- }
-
- static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
- {
- strptr buf = buffer;
- struct ClibData d;
-
- memset(&d, 0, sizeof(struct ClibData));
- while(*buf != /*(*/')')
- {
- if(d.NumArgs == MAXREGPPC+1)
- return 0;
- else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1))
- return 0;
-
- buf += d.Args[d.NumArgs-1].FullLength;
- while(*buf != ',' && *buf != /*(*/')')
- ++buf;
- if(*buf == ',')
- buf = SkipBlanksRet(++buf);
- }
-
- if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
- d.NumArgs = 0; /* void arguments are no arguments */
-
- if(d.NumArgs) /* no need to allocate structure for nothing */
- {
- if(!(data->FuncPtr = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
- return 0;
-
- memcpy(data->FuncPtr, &d, sizeof(struct ClibData));
- }
- return (uint32) (buf+1-buffer);
- }
-
- /* rettype turns on usage of "extern" specifier */
- static int32 GetCPPType(struct CPP_NameType *data, strptr start, uint32 rettype)
- {
- uint32 ok = 1, j;
- strptr u;
-
- data->TypeStart = start = SkipBlanks(start);
-
- if(!strncmp(start, "REG", 3) && (start[3] == ' ' || start[3] == '\t' || start[3] == '\n' || start[3] == '('/*)*/))
- {
- u = SkipBlanksRet(start+3);
- if(*u == '('/*)*/)
- {
- u = SkipBlanks(u+1);
- if((j = CheckRegisterNum(u, data)))
- {
- u = SkipBlanks(u+j);
- if(*u == ')')
- start = SkipBlanks(u+1);
- }
- }
- }
- data->TypeStart = start;
-
- do
- {
- start = SkipBlanks((u = start));
- if(!strncmp("...",start,3))
- {
- data->Type = CPP_TYPE_VARARGS;
- data->TypeLength = start+3 - (data->TypeStart);
- data->FullLength = data->TypeLength;
- return 1;
- }
- if(CheckKeyword(start, "const", 5) || CheckKeyword(start, "CONST", 5))
- {
- data->Flags |= CPP_FLAG_CONST; start += 6;
- }
- else if(rettype && CheckKeyword(start, "extern", 6))
- {
- start += 7; /* ignore it */
- }
- else if(CheckKeyword(start, "signed", 6))
- start += 7;
- else if(CheckKeyword(start, "unsigned", 8))
- {
- data->Flags |= CPP_FLAG_UNSIGNED; start += 9;
- }
- else if(CheckKeyword(start, "register", 8))
- {
- data->Flags |= CPP_FLAG_REGISTER; start += 9;
- data->Register = UNDEFREGISTER;
- }
- else if(CheckKeyword(start, "struct", 6))
- {
- start = SkipBlanks(start+6);
- data->Flags |= CPP_FLAG_STRUCT;
- if(*start != '?') /* ? for external types */
- {
- start = SkipName((data->StructureName = start));
- data->StructureLength = start-data->StructureName;
- }
- else
- {
- data->StructureLength = 0;
- data->StructureName = "";
- ++start;
- }
- }
- else if(CheckKeyword(start, "union", 5))
- {
- start = SkipBlanks(start+5);
- data->Flags |= CPP_FLAG_UNION;
- if(*start != '?') /* ? for external types */
- {
- start = SkipName((data->StructureName = start));
- data->StructureLength = start-data->StructureName;
- }
- else
- {
- data->StructureLength = 0;
- data->StructureName = "";
- ++start;
- }
- }
- else if(CheckKeyword(start, "enum", 4))
- {
- start = SkipBlanks(start+4);
- data->Flags |= CPP_FLAG_ENUM;
- if(*start != '?') /* ? for external types */
- {
- start = SkipName((data->StructureName = start));
- data->StructureLength = start-data->StructureName;
- }
- else
- {
- data->StructureLength = 0;
- data->StructureName = "";
- ++start;
- }
- }
- else if(*start == '*')
- {
- ++start; ++data->PointerDepth;
- }
- else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
- start += 2 + j;
- else
- {
- uint32 i;
-
- for(i = 0; CPP_Field[i].Text; ++i)
- {
- if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length) &&
- (start[CPP_Field[i].Length] == ' ' ||
- start[CPP_Field[i].Length] == '\t' ||
- start[CPP_Field[i].Length] == '\n' ||
- start[CPP_Field[i].Length] == ',' ||
- start[CPP_Field[i].Length] == /*(*/')' ||
- start[CPP_Field[i].Length] == '('/*)*/ ||
- start[CPP_Field[i].Length] == '*'))
- {
- start += CPP_Field[i].Length;
- data->Type = CPP_Field[i].Type;
- data->Flags |= CPP_Field[i].Flags;
- if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
- ++data->PointerDepth;
- break;
- }
- }
- if(CPP_Field[i].Text)
- continue;
- else if(extnames)
- {
- struct CPP_ExternNames *a = extnames;
-
- while(a)
- {
- i = strlen(a->Type);
- if(!strncmp(a->Type, start, i) && !isalnum(start[i]) &&
- start[i] != '_')
- {
- start += i;
- data->StructureName = a->NameType.StructureName;
- data->FuncPtr = a->NameType.FuncPtr;
- data->StructureLength = a->NameType.StructureLength;
- data->PointerDepth += a->NameType.PointerDepth;
- data->Type = a->NameType.Type;
- data->Flags |= a->NameType.Flags;
- data->FuncArgs = a->NameType.FuncArgs;
- data->ArgsLength = a->NameType.ArgsLength;
- break;
- }
-
- /* check types here */
- a = a->Next;
- }
- if(a)
- continue;
- }
- break;
- }
- } while(1);
-
- if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
- u = start;
-
- data->TypeLength = u - (data->TypeStart);
- data->FullLength = data->TypeLength;
-
- u = SkipBlanks(u);
-
- if(*u == '('/*)*/)
- {
- ok = 0;
- u = SkipBlanks(++u);
- if(*u == '*')
- {
- u = SkipBlanks(++u);
- if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
- {
- data->Flags |= CPP_FLAG_CONST; u += 6;
- }
- u = SkipBlanks(u);
- if(*u != /*(*/')')
- data->FunctionName = u;
- u = SkipBlanks(SkipName(u));
- if(*u == /*(*/')')
- {
- u = SkipBlanks(++u);
- if(*u == '('/*)*/)
- {
- data->Flags |= CPP_FLAG_FUNCTION;
- if((j = ParseFuncPtrArgs(u+1, data)))
- ok = 1;
- data->FuncArgs = u;
- data->ArgsLength = j+1;
- data->FullLength = u+data->ArgsLength - (data->TypeStart);
- }
- }
- }
- }
-
- if(data->PointerDepth)
- data->Flags |= CPP_FLAG_POINTER;
-
- if((!data->Type && !data->Flags) || !ok)
- return 0;
- return 1;
- }
-
- static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
- {
- struct ClibData *d = clibdata;
-
- while(d && strcmp(name, d->FuncName))
- d = d->Next;
-
- if(!d)
- {
- if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
- {
- DoError(ERR_PROTOTYPE_MISSING, 0, name);
- ap->Flags |= AMIPRAGFLAG_NOCLIB;
- }
- }
- else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
- ap->CallArgs+1 != d->NumArgs))
- {
- if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDARGWARN)))
- {
- DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
- ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
- }
- return 0;
- }
-
- return d;
- }
-
- static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
- {
- if(!strncmp(string, keyword, size))
- {
- string += size;
- if(*string == ' ' || *string == '\t' || *string == '\n')
- return size;
- }
- return 0;
- }
-
- /* return nonzero, when usable, zero, when string already emitted */
- static uint32 CopyCPPType(strptr buffer, uint32 pass, struct ClibData *cd,
- struct AmiArgs *args)
- {
- uint32 ret = 0, reg;
- uint32 i, j, k = 0;
-
- /* pass 0: signed strptr, MaxonC++ high args */
- /* pass 1: unsigned strptr, MaxonC++ high args */
- /* pass 2: signed strptr, StormC++ high args */
- /* pass 3: unsigned strptr, StormC++ high args */
-
- for(i = 0; i < cd->NumArgs; ++i)
- {
- struct CPP_NameType *nt;
-
- nt = &cd->Args[i];
-
- if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
- reg = 1 + args[k].ArgReg;
- else if((nt->Flags & CPP_FLAG_REGISTER) && nt->Register != UNDEFREGISTER)
- reg = 1 + nt->Register;
- else
- reg = 0;
-
- if(reg--) /* subtract the added 1 */
- {
- *(buffer++) = CPP_TYPE_REGISTER;
- if(reg >= 10)
- {
- if(pass & 2)
- {
- *(buffer++) = reg/10 + '0';
- *(buffer++) = reg%10 + '0';
- ret |= 2;
- }
- else
- *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
- }
- else
- *(buffer++) = reg + '0';
- }
-
- if(nt->Flags & CPP_FLAG_FUNCTION)
- {
- *(buffer++) = CPP_TYPE_POINTER; *(buffer++) = CPP_TYPE_FUNCTION;
- }
- for(j = 0; j < nt->PointerDepth; ++j)
- *(buffer++) = CPP_TYPE_POINTER;
- if(nt->Flags & CPP_FLAG_CONST)
- *(buffer++) = CPP_TYPE_CONST;
- if(nt->Flags & CPP_FLAG_UNSIGNED)
- *(buffer++) = CPP_TYPE_UNSIGNED;
- else if((nt->Flags & CPP_FLAG_STRPTR) && (pass & 1))
- {
- *(buffer++) = CPP_TYPE_UNSIGNED;
- ret |= 1; /* we really use this pass */
- }
- if(nt->Flags & CPP_FLAG_ENUM)
- *(buffer++) = CPP_TYPE_ENUM;
- if(nt->Type)
- *(buffer++) = cd->Args[i].Type;
- else
- {
- uint32 i;
- sprintf(buffer, "%02lu", (uint32) nt->StructureLength); buffer += 2;
- for(i = 0; i < nt->StructureLength; ++i)
- *(buffer++) = nt->StructureName[i];
- }
- if(nt->Flags & CPP_FLAG_FUNCTION)
- {
- if(nt->FuncPtr)
- {
- ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
- while(*buffer)
- ++buffer; /* skip to the new end */
- }
- *(buffer++) = CPP_TYPE_FUNCEND;
- }
- ++k;
- if(IsCPPType(nt, CPP_TYPE_DOUBLE)) /* double needs 2 registers */
- ++k;
- }
-
- *(buffer) = 0;
-
- if(ret != pass)
- ret = 0;
- if(!pass)
- ret = 0x80;
-
- return ret; /* return nozero if this pass should be used */
- }
-
- static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
- {
- DoOutputDirect(nt->TypeStart, nt->TypeLength);
- if(nt->Type != CPP_TYPE_VARARGS)
- {
- if(!DoOutput((nt->Flags & CPP_FLAG_FUNCTION) ? (txt ? " (*%s)" : " (*)") :
- (txt ? " %s" : ""), txt))
- return 0;
-
- if(nt->Flags & CPP_FLAG_FUNCTION)
- {
- if(nt->FuncArgs)
- DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
- else
- return DoOutput("()");
- }
- }
-
- return 1;
- }
-
- static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
- {
- strptr a;
-
- a = dest;
- memcpy(a, nt->TypeStart, nt->TypeLength);
- a += nt->TypeLength;
-
- if(nt->Type != CPP_TYPE_VARARGS)
- {
- if(nt->Flags & CPP_FLAG_FUNCTION)
- {
- a += sprintf(a, (txt ? " (*%s)" : " (*)"), txt);
- if(nt->FuncArgs)
- {
- memcpy(a, nt->FuncArgs, nt->ArgsLength);
- a += nt->ArgsLength;
- }
- else
- a += sprintf(a, "()");
- }
- else if(txt)
- a += sprintf(a, " %s", txt);
- }
- return (uint32)(a-dest);
- }
-
- static uint32 OutPASCALType(struct CPP_NameType *t, strptr txt, uint32 ret)
- {
- int32 i = t->PointerDepth;
-
- if(t->Flags & CPP_FLAG_CONST)
- DoOutput("CONST ");
- if(!ret && i == 1 &&
- (t->Type == CPP_TYPE_LONG || t->Type == CPP_TYPE_WORD))
- {
- DoOutput("VAR "); --i;
- }
-
- DoOutput("%s : ", txt);
-
- if(!i && t->Flags == CPP_FLAG_BOOLEAN)
- return DoOutput("BOOLEAN");
- else if(i && t->Type == CPP_TYPE_VOID)
- return DoOutput("POINTER");
- else if(t->Flags & CPP_FLAG_FUNCTION)
- return DoOutput("tPROCEDURE");
-
- while(i--)
- DoOutput("p");
-
- if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
- {
- if(!t->PointerDepth)
- DoOutput("t");
- return DoOutputDirect(t->StructureName, t->StructureLength);
- }
-
- if(t->Flags & CPP_FLAG_UNSIGNED)
- {
- if(t->Type == CPP_TYPE_LONG)
- return DoOutput("CARDINAL");
- if(t->Type == CPP_TYPE_WORD)
- return DoOutput("int16");
- if(t->Type == CPP_TYPE_BYTE)
- return DoOutput(t->PointerDepth == 1 ? "CHAR" : "int8");
- }
- else if(t->Type == CPP_TYPE_WORD)
- return DoOutput("INTEGER");
- else if(t->Type == CPP_TYPE_BYTE)
- return DoOutput("SHORTINT");
- return DoOutput("int32INT");
- }
-
- /* ------------------------------------------------------------------ */
-
- static uint32 CallPrag(uint32 tagmode, strptr type, FuncType Func)
- {
- if(type)
- if((*type && !DoOutput("#if%s\n", type)) ||
- !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
- (*type && !DoOutput("#endif\n")))
- return 0;
- return 1;
- }
-
- static uint32 CreatePragmaFile(strptr amicall, strptr libcall, strptr amitags,
- strptr libtags, uint32 mode)
- {
- switch(mode)
- {
- case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
- "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper,
- ShortBaseNameUpper); break;
- case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
- "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
- case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
- "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
- case PRAGMODE_NONE: break;
- default: return 0;
- }
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
- "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
- return 0;
-
- if((Flags & FLAG_EXTERNC) &&
- !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
- return 0;
-
- if(Flags & FLAG_GNUPRAG)
- {
- DoOutput("#ifdef " TEXT_GNUC "\n#ifdef NO_OBSOLETE\n"
- "#error \"Please include the proto file and not the compiler specific file!\"\n"
- "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName);
- Flags |= FLAG_DONE;
- }
-
- if(
- !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
- !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
- return 0;
-
- if(tagfuncs)
- {
- if(
- !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
- !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
- return 0;
- }
-
- if((Flags & FLAG_EXTERNC) &&
- !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
- return 0;
-
- switch(mode)
- {
- case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
- ShortBaseNameUpper); break;
- case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
- ShortBaseNameUpper); break;
- case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
- ShortBaseNameUpper); break;
- case PRAGMODE_NONE: break;
- default: return 0;
- }
- return Output_Error;
- }
-
- static uint32 CreateCSTUBSFile(void)
- {
- DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
- ShortBaseNameUpper, ShortBaseNameUpper);
-
- if(!clibdata)
- {
- DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
- }
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
- "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
- return 0;
-
- if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
- return 0;
-
- return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
- ShortBaseNameUpper);
- }
-
- static uint32 CreateLVOFile(uint32 mode)
- {
- strptr data = "_LVO_I";
-
- if(mode == 2 || mode == 4)
- data = "_LIB_I";
-
- if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
- ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
- (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
- (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
- !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
- !DoOutput("\n\n\t\tENDC\n"))
- return 0;
-
- return 1;
- }
-
- static uint32 CreateLVOFilePPC(uint32 mode)
- {
- if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
- ShortBaseNameUpper, ShortBaseNameUpper))
- return 0;
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
- switch(mode)
- {
- case 0: CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCXDEF);
- case 1: CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVOPPC);
- }
- return DoOutput("\n\t.endif\n");
- }
-
- static uint32 CreateAsmStubs(uint32 mode, uint32 callmode)
- {
- /* 1 = Text, 2 = Code */
- switch(mode)
- {
- case 1:
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- if(!(Flags & FLAG_ASMSECTION))
- DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
- Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
- if(!CallFunc(callmode, "\n%s", FuncAsmText))
- return 0;
- break;
- case 2:
- if(!CallFunc(callmode, 0, FuncAsmCode))
- return 0;
- break;
- }
-
- return 1;
- }
-
- static uint32 CreateProtoFile(uint32 Type)
- {
-
- DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
- ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
- if(Type != 5)
- DoOutput("#ifndef CLIB_%s_PROTOS_H\n"
- "#include <clib/%s_protos.h>\n#endif\n",
- ShortBaseNameUpper, ShortBaseName);
-
- if(BaseName)
- {
- DoOutput("\n#ifndef __NOLIBBASE__\nextern struct %s *", GetBaseType());
- if(Type == 7)
- DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
- "#endif\n");
- DoOutput("%s;\n#endif\n", BaseName);
- }
-
- if(Type != 8)
- {
- if(Type >= 6)
- {
- DoOutput("\n#ifdef " TEXT_GNUC "\n");
- if(Type == 10)
- DoOutput("#ifndef __cplusplus\n");
- DoOutput("#include <inline/%s.h>\n", ShortBaseName);
- if(Type == 10)
- DoOutput("#endif\n");
- if(Type != 7)
- {
- if(Type == 9)
- DoOutput("#elif defined(" TEXT_VBCC ")\n#ifndef __PPC__\n"
- "#include <inline/%s_protos.h>\n#endif\n#else", ShortBaseName);
- else
- DoOutput("#elif !defined(" TEXT_VBCC ")");
- }
- }
- if(Type == 10)
- DoOutput("\n#ifndef __PPC__");
- if(Type != 7)
- {
- strptr str1 = "pragma", str2 = "lib";
-
- switch(Type)
- {
- case 4: str1 = "pragmas"; /* no break; */
- case 2: str2 = "pragmas"; break;
- case 3: str1 = "pragmas"; break;
- case 5: str1 = "local"; str2 = "loc"; break;
- }
- DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
- }
- if(Type == 10)
- DoOutput("#endif\n");
- if(Type >= 6)
- DoOutput("#endif\n");
- }
-
- Flags |= FLAG_DONE;
-
- return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
- }
-
- static uint32 CreateLocalData(strptr to, uint32 callmode)
- {
- DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
- "#define _INCLUDE_PROTO_%s_LOC_H\n",
- ShortBaseNameUpper, ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\n");
- PrintIncludes();
-
- if((Flags & FLAG_EXTERNC) &&
- !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
- return 0;
-
- if(!CallFunc(callmode, "/%s */\n", FuncLocText))
- return 0;
-
- if((Flags & FLAG_EXTERNC) &&
- !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
- return 0;
-
- DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper);
-
- sprintf(filename, "%s_loc.lib", ShortBaseName);
- if(!CloseDest(to) || !OpenDest(filename))
- return 0;
-
- CallFunc(callmode, 0, FuncLocCode);
-
- return CloseDest(filename);
- }
-
- static uint32 CreateInline(uint32 mode, uint32 callmode)
- {
- if(!clibdata)
- {
- DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
- }
-
- DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
- Flags & FLAG_POWERUP ? "PPC" : "", ShortBaseNameUpper,
- Flags & FLAG_POWERUP ? "PPC" : "", ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\n");
-
- if(!mode)
- {
- if(Flags & FLAG_POWERUP)
- DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
- "#include <powerup/ppcinline/macros.h>\n#endif\n\n");
- else
- DoOutput("#ifndef __INLINE_MACROS_H\n"
- "#include <inline/macros.h>\n#endif\n\n");
- Flags |= FLAG_INLINENEW;
- }
- else if(mode <= 2)
- {
- if(Flags & FLAG_POWERUP)
- DoOutput("#ifndef __PPCINLINE_STUB_H\n"
- "#include <powerup/ppcinline/stubs.h>\n#endif\n\n");
- else
- DoOutput("#ifndef __INLINE_STUB_H\n"
- "#include <inline/stubs.h>\n#endif\n\n");
- if(mode == 2)
- Flags |= FLAG_INLINESTUB;
- }
- else if(mode == 3)
- Flags |= FLAG_INLINEMAC;
- else if(mode == 5)
- PrintIncludes();
-
- if(BaseName)
- {
- if(mode && mode <= 2)
- DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
- "#define BASE_EXT_DECL0 extern struct %s *%s;\n#endif\n"
- "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
- "#define BASE_PAR_DECL0 void\n#endif\n"
- "#ifndef BASE_NAME\n#define BASE_NAME %s\n#endif\n\n"
- "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, BaseName);
- else
- DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
- ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
- }
-
- if(mode <= 2)
- {
- if(!CallFunc(callmode, "/%s */\n", FuncInline))
- return 0;
- }
- else
- {
- if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
- return 0;
- }
-
- if(mode && mode <= 2 && BaseName)
- DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
- "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef BASE_NAME\n\n");
-
- return DoOutput("#endif /* _%sINLINE_%s_H */\n",
- Flags & FLAG_POWERUP ? "PPC" : "", ShortBaseNameUpper);
- }
-
- static uint32 CreateSASPowerUP(uint32 callmode)
- {
- DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
- ShortBaseNameUpper, ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\n#ifdef __GNUC__\n"
- "#ifndef _PPCINLINE__%s_H\n"
- "#include <powerup/ppcinline/%s.h>\n"
- "#endif\n"
- "#else\n\n"
- "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
- "#include <powerup/ppclib/interface.h>\n"
- "#endif\n\n"
- "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
- "#include <powerup/gcclib/powerup_protos.h>\n"
- "#endif\n\n"
- "#ifndef NO_PPCINLINE_STDARG\n"
- "#define NO_PPCINLINE_STDARG\n"
- "#endif /* SAS-C PPC inlines */\n\n",
- ShortBaseNameUpper, ShortBaseName);
-
- if(BaseName)
- {
- DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
- ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
- }
-
- if(!CallFunc(callmode, "/%s */\n", FuncPowerUP))
- return 0;
-
- return DoOutput("#endif /* SAS-C PPC pragmas */\n"
- "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper);
- }
-
- static uint32 CreateProtoPowerUP(void)
- {
- DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
- ShortBaseNameUpper, ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
-
- if(BaseName)
- {
- DoOutput("\n#ifndef __NOLIBBASE__\nextern struct %s *", GetBaseType());
- DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
- "#endif\n%s;\n#endif\n", BaseName);
- }
-
- DoOutput("\n#ifdef " TEXT_GNUC "\n"
- "#include <powerup/ppcinline/%s.h>\n#else /* SAS-C */\n"
- "#include <powerup/ppcpragmas/%s_pragmas.h>\n#endif\n",
- ShortBaseName, ShortBaseName);
-
- Flags |= FLAG_DONE;
-
- return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
- }
-
- static uint32 CreateFPCUnit(void)
- {
- if(!clibdata)
- {
- DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
- }
-
- DoOutput("UNIT %s;\n", ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName,
- GetBaseType());
-
- if(!CallFunc(TAGMODE_NORMAL, 0, FuncFPCType))
- return 0;
-
- DoOutput("\nIMPLEMENTATION\n\n");
-
- if(!CallFunc(TAGMODE_NORMAL, "(%s *)\n", FuncFPCUnit))
- return 0;
-
- return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper);
- }
-
- static uint32 CreateBMAP(void)
- {
- return CallFunc(TAGMODE_NORMAL, 0, FuncBMAP);
- }
-
- static uint32 CreateLVOLib(void)
- {
- uint32 i;
-
- i = strlen(ShortBaseNameUpper);
- EndPutM32(tempbuf, HUNK_UNIT);
- EndPutM32(tempbuf+4, (i+3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(ShortBaseNameUpper, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- i = strlen(hunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(hunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- EndPutM32(tempbuf, HUNK_CODE);
- EndPutM32(tempbuf+4, 0);
- EndPutM32(tempbuf+8, HUNK_EXT);
- DoOutputDirect(tempbuf, 12);
-
- if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOLib))
- return 0;
-
- EndPutM32(tempbuf, 0);
- EndPutM32(tempbuf+4, HUNK_END);
- return DoOutputDirect(tempbuf, 8);
- }
-
- static uint32 CreateLVOLibPPC(void)
- {
- uint8 *data = tempbuf, *data2, *data3;
-
- *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
- *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
- *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
- *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
- *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
- *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
- *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- *(data++) = 0; *(data++) = 0; *(data++) = 0;
- EndPutM16Inc(data, ET_REL); /* eeh->e_type */
- EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
- EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
- EndPutM32Inc(data, 0); /* eeh->e_entry */
- EndPutM32Inc(data, 0); /* eeh->e_phoff */
- data2 = data; data += 4;
- EndPutM32Inc(data, 0); /* eeh->e_flags */
- EndPutM16Inc(data, 52); /* eeh->e_ehsize */
- EndPutM16Inc(data, 0); /* eeh->e_phentsize */
- EndPutM16Inc(data, 0); /* eeh->e_phnum */
- EndPutM16Inc(data, 40); /* eeh->e_shentsize */
- EndPutM16Inc(data, 4); /* eeh->e_shnum */
- EndPutM16Inc(data, 1); /* eeh->e_shstrndx - first table is string table */
-
- data3 = data;
- memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
- data += 28; /* 1 9 17*/
- EndPutM32(data2, data-tempbuf); /* store the entry */
-
- EndPutM32Inc(data, 0); /* esh[0].sh_name */
- EndPutM32Inc(data, 0); /* esh[0].sh_type */
- EndPutM32Inc(data, 0); /* esh[0].sh_flags */
- EndPutM32Inc(data, 0); /* esh[0].sh_addr */
- EndPutM32Inc(data, 0); /* esh[0].sh_offset */
- EndPutM32Inc(data, 0); /* esh[0].sh_size */
- EndPutM32Inc(data, 0); /* esh[0].sh_link */
- EndPutM32Inc(data, 0); /* esh[0].sh_info */
- EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
-
- EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
- EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
- EndPutM32Inc(data, 0); /* esh[3].sh_flags */
- EndPutM32Inc(data, 0); /* esh[3].sh_addr */
- EndPutM32Inc(data, data3-tempbuf); /* esh[3].sh_offset */
- EndPutM32Inc(data, 27); /* esh[3].sh_size */
- EndPutM32Inc(data, 0); /* esh[3].sh_link */
- EndPutM32Inc(data, 0); /* esh[3].sh_info */
- EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
-
- EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
- EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
- EndPutM32Inc(data, 0); /* esh[4].sh_flags */
- EndPutM32Inc(data, 0); /* esh[4].sh_addr */
- data2 = data;
- data += 4; /* esh[4].sh_offset */
- data += 4; /* esh[4].sh_size */
- EndPutM32Inc(data, 3); /* esh[4].sh_link - the third entry is our string table */
- EndPutM32Inc(data, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
- EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
- EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
-
- EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
- EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
- EndPutM32Inc(data, 0); /* esh[0].sh_flags */
- EndPutM32Inc(data, 0); /* esh[0].sh_addr */
- data3 = data;
- data += 4; /* esh[0].sh_offset */
- data += 4; /* esh[0].sh_size */
- EndPutM32Inc(data, 0); /* esh[0].sh_link */
- EndPutM32Inc(data, 0); /* esh[0].sh_info */
- EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
- EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
-
- EndPutM32Inc(data2, data-tempbuf);
-
- EndPutM32Inc(data,0);
- EndPutM32Inc(data,0); /* first entry is empty */
- EndPutM32Inc(data,0);
- EndPutM32Inc(data,0);
-
- symoffset = 1; /* initial value */
- elfbufpos = data;
-
- if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
- return 0;
- EndPutM32(data2, elfbufpos-data+16);
- EndPutM32Inc(data3, elfbufpos-tempbuf);
- EndPutM32(data3, symoffset);
-
- *(elfbufpos++) = 0; /* first sym entry */
- if(!DoOutputDirect(tempbuf, elfbufpos-tempbuf))
- return 0;
-
- if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
- return 0;
-
- while((symoffset++)&3)
- {
- if(!DoOutputDirect("", 1))
- return 0;
- }
-
- return 1;
- }
-
- static uint32 CreateVBCCInline(uint32 mode)
- {
- if(!clibdata)
- {
- DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
- }
-
- DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
- ShortBaseNameUpper, ShortBaseNameUpper);
-
- DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- DoOutput("\n");
-
- if(!CallFunc(TAGMODE_NORMAL, "/%s */\n", mode ? FuncVBCCWOSInline : FuncVBCCInline))
- return 0;
-
- return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper);
- }
-
- static uint32 CreateVBCC(uint32 mode, uint32 callmode)
- {
- uint32 res = 0;
-
- if(mode != 2 && mode != 3 && HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
-
- switch(mode)
- {
- case 4: res = CallFunc(callmode, 0, FuncVBCCPUPText); break;
-
- case 3: Flags |= FLAG_WOSLIBBASE; /* no break! */
- case 2: res = CallFunc(callmode, 0, FuncVBCCWOSCode); break;
-
- case 1: Flags |= FLAG_WOSLIBBASE; /* no break! */
- case 0: res = CallFunc(callmode, "\n%s", FuncVBCCWOSText); break;
- }
- return res;
- }
-
- static uint32 CreateVBCCPUPLib(uint32 callmode)
- {
- /* output header */
- DoOutput("!<arch>\n");
-
- return CallFunc(callmode, 0, FuncVBCCPUPCode);
- }
-
- static uint32 CreateVBCCMorphCode(uint32 callmode)
- {
- /* output header */
- DoOutput("!<arch>\n");
-
- return CallFunc(callmode, 0, FuncVBCCMorphCode);
- }
-
- static uint32 CreateEModule(uint32 sorted)
- {
- uint32 res = 0, i;
- if(sorted)
- DoError(ERR_NO_SORTED, 0);
- else
- {
- DoOutputDirect("EMOD\0\x06", 6);
- for(res = 0; res < 2; ++res)
- {
- for(i = 0; BaseName[i]; ++i)
- DoOutput("%c", tolower(BaseName[i]));
- DoOutputDirect("\x00",1);
- }
- LastBias = BIAS_START-BIAS_OFFSET;
- CallFunc(TAGMODE_NORMAL, 0, FuncEModule);
- res = DoOutputDirect("\xFF",1);
- }
- return res;
- }
-
- static uint32 CreateProtoRedirect(void)
- {
- Flags |= FLAG_DONE;
- return DoOutput("#ifdef NO_OBSOLETE\n"
- "#error \"Please include the proto file and not the compiler specific file!\"\n"
- "#endif\n\n#include <proto/%s.h>\n", ShortBaseName);
- }
-
- static uint32 CreateSFD(uint32 callmode)
- {
- struct Include *inc;
- struct AmiPragma *ap;
- if(!clibdata)
- {
- DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
- }
-
- if((ap = (struct AmiPragma *) AmiPragma.First))
- LastBias = ap->Bias-BIAS_OFFSET;
- else /* only security, never used normally */
- LastBias = 0;
- CurrentABI = ABI_M68K;
-
- if(IDstring)
- DoOutput("==id %s\n", IDstring);
- else
- {
- time_t t;
- struct tm * tim;
-
- t = time(&t);
- tim = localtime(&t);
-
- DoOutput("==id $Id: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d noname Exp $\n", filename,
- tim->tm_year+1900, tim->tm_mon+1, tim->tm_mday, tim->tm_hour, tim->tm_min,
- tim->tm_sec);
- }
-
- if(BaseName)
- DoOutput("==base _%s\n==basetype struct %s *\n==libname %s\n", BaseName,
- GetBaseType(), GetLibraryName());
- DoOutput("==bias %ld\n==public\n", LastBias+BIAS_OFFSET);
-
- for(inc = (struct Include *) Includes.First; inc; inc = (struct Include *) inc->List.Next)
- DoOutput("==include %s\n", inc->Include);
- if(!Includes.First)
- DoOutput("==include <exec/types.h>\n");
-
- CallFunc(callmode, "%s\n", FuncSFD);
-
- return DoOutput("==end\n");
- }
-
- static uint32 CreateClib(uint32 callmode)
- {
- if(!clibdata)
- {
- DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
- }
-
- DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper,
- ShortBaseNameUpper);
-
- if(HEADER)
- {
- DoOutput("\n");
- DoOutputDirect(HEADER, headersize);
- }
- else
- {
- strptr s = 0;
- time_t t;
- struct tm * tim;
-
- t = time(&t);
- tim = localtime(&t);
-
- if(IDstring)
- {
- s = SkipBlanks(IDstring+4);
- while(*s && *s != ' ')
- ++s;
- s=SkipBlanks(s);
- }
- if(!s || !*s)
- s = "1.0";
-
- if(Flags2 & FLAG2_SYSTEMRELEASE)
- {
- DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
- }
- else
- {
- strptr t;
-
- t = s;
- while(*t && *t != ' ')
- ++t;
- *t = 0;
-
- DoOutput("\n/*\n**\t$VER: %s %s (%02d.%02d.%04d)\n", filename, s, tim->tm_mday, tim->tm_mon+1, tim->tm_year+1900);
- }
- DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n"
- "**\tCopyright © %d %s\n", tim->tm_year+1900, Copyright ? Copyright :
- Flags2 & FLAG2_SYSTEMRELEASE ? "Amiga, Inc." : "");
- DoOutput("**\tAll Rights Reserved\n*/\n\n");
- }
-
- PrintIncludes();
-
- if((Flags & FLAG_EXTERNC) &&
- !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
- return 0;
-
- CallFunc(callmode, "\n/%s */\n\n", FuncClib);
-
- if((Flags & FLAG_EXTERNC) &&
- !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
- return 0;
-
- return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper);
- }
-
- static uint32 CreateFD(void)
- {
- LastBias = 0;
- CurrentABI = ABI_M68K;
-
- if(BaseName)
- DoOutput("##base _%s\n", BaseName);
- DoOutput("##public\n");
-
- CallFunc(TAGMODE_NORMAL, "%s\n", FuncFD);
-
- return DoOutput("##end\n");
- }
-
- static uint32 CreateGenAuto(strptr to, uint32 type)
- {
- strptr name, btype;
- uint8 *data;
- uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
- if(!(name = GetLibraryName()))
- return 0;
- btype = GetBaseType();
-
- switch(type)
- {
- case 0:
- Flags |= FLAG_DONE;
- if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
- "struct %s *%s = 0;\nextern unsigned long _%sVer;\n\n"
- "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
- "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
- btype, BaseName, BaseName,
- priority, BaseName, BaseName, !strcmp("Library", btype) ? "" : "(struct Library *) ", name, BaseName,
- priority, BaseName, BaseName, !strcmp("Library", btype) ? "" : "(struct Library *) ", BaseName)))
- return 0;
- sprintf(filename, "%s_autoopenver.c", ShortBaseName);
- if(!CloseDest(to) || !OpenDest(filename))
- return 0;
- Flags |= FLAG_DONE;
- return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
- break;
- case 1: /* m68k */
- Flags |= FLAG_DONE;
- i = strlen(filename)-4; /* remove .lib extension */
- EndPutM32(tempbuf, HUNK_UNIT);
- EndPutM32(tempbuf+4, (i+3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(filename, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- i = strlen(hunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(hunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- data = tempbuf+8; /* we need HUNK_CODE + size at start */
- EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
- /* SysBase */
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
- EndPutM16Inc(data, 0); /* place for sysbase reference */
- }
- else
- {
- EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
- EndPutM32Inc(data, 0); /* place for sysbase reference */
- }
- verref = data-tempbuf-8+2;
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
- EndPutM16Inc(data, 0); /* place for basevers reference */
- }
- else
- {
- EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
- EndPutM32Inc(data, 0); /* place for basevers reference */
- }
- EndPutM32Inc(data, 0x43FA0030 + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2) + ((Flags & FLAG_SMALLDATA) ? 0 : 6));
- EndPutM32Inc(data, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
-
- rel1 = data-tempbuf-8+2;
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM16Inc(data, 0x2940); /* MOVE.L D0,xxx(A4) */
- EndPutM16Inc(data, 0);
- }
- else
- {
- EndPutM16Inc(data, 0x23C0); /* MOVE.L D0,xxx */
- EndPutM32Inc(data, 0);
- }
- EndPutM16Inc(data, 0x660A + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2)); /* BNE.B .lib */
- EndPutM32Inc(data, 0x48780014); /* PEA 20 */
-
- exitfuncref = data-tempbuf-8+2;
- if(Flags2 & FLAG2_SMALLCODE)
- {
- EndPutM16Inc(data, 0x4EBA); /* JSR _exit(PC) */
- EndPutM16Inc(data, 0); /* place for base reference */
- }
- else
- {
- EndPutM16Inc(data, 0x4EB9); /* JSR _exit */
- EndPutM32Inc(data, 0); /* place for base reference */
- }
- EndPutM16Inc(data, 0x584F); /* ADDQ.W, #4,A7 */
- EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
- EndPutM16Inc(data,0x4E75); /* RTS */
- exitref = data-tempbuf-8;
-
- EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
- sysref2 = data-tempbuf-8+2;
- /* SysBase */
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
- EndPutM16Inc(data, 0); /* place for sysbase reference */
- }
- else
- {
- EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
- EndPutM32Inc(data, 0); /* place for sysbase reference */
- }
- rel2 = data-tempbuf-8+2;
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
- EndPutM16Inc(data, 0); /* place for base reference */
- }
- else
- {
- EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
- EndPutM32Inc(data, 0); /* place for base reference */
- }
- EndPutM16Inc(data, 0x6606); /* BNE.B .nolib */
- EndPutM16Inc(data, 0x2240); /* MOVEA.L D0,A1 */
-
- EndPutM32Inc(data, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
- EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
- EndPutM16Inc(data,0x4E75); /* RTS */
- nameref = data-tempbuf-8;
- memcpy(data, name, strlen(name));
- data += strlen(name);
- do { *(data++) = 0; } while((data-tempbuf)&3);
-
- EndPutM32(tempbuf, HUNK_CODE);
- EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
- DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
-
- if(Flags & FLAG_SMALLDATA)
- {
- EndPutM32(tempbuf, HUNK_DREL16);
- }
- else
- {
- EndPutM32(tempbuf, HUNK_ABSRELOC32);
- }
- EndPutM32(tempbuf+4, 2); /* 2 entries */
- EndPutM32(tempbuf+8, 1); /* to hunk 1 */
- EndPutM32(tempbuf+12, rel1); /* address 0 */
- EndPutM32(tempbuf+16, rel2); /* address 0 */
- EndPutM32(tempbuf+20, 0); /* end of reloc hunk */
- DoOutputDirect(tempbuf, 24);
-
- /* extern references */
- EndPutM32(tempbuf, HUNK_EXT);
- DoOutputDirect(tempbuf, 4);
-
- OutputXREF2(4, sysref2, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_SysBase");
- OutputXREF(verref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "__%sVer", BaseName);
- OutputXREF(exitfuncref, (Flags2 & FLAG2_SMALLCODE ? EXT_DEXT16 : EXT_REF32), "_exit");
- OutputXDEF(0, "__INIT_%ld_%s", priority, BaseName);
- OutputXDEF(exitref, "__EXIT_%ld_%s", priority, BaseName);
- OutputXDEF(nameref, "%sname", ShortBaseName);
- EndPutM32(tempbuf, 0); /* ext end */
- DoOutputDirect(tempbuf, 4);
-
- if(!(Flags & FLAG_NOSYMBOL))
- {
- EndPutM32(tempbuf, HUNK_SYMBOL);
- DoOutputDirect(tempbuf, 4);
- OutputSYMBOL(0, "__INIT_%ld_%s", priority, BaseName);
- OutputSYMBOL(exitref, "__EXIT_%ld_%s", priority, BaseName);
- OutputSYMBOL(nameref, "%sname", ShortBaseName);
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf, 4);
- }
-
- EndPutM32(tempbuf, HUNK_END);
- DoOutputDirect(tempbuf, 4);
-
- i = strlen(datahunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(datahunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- EndPutM32(tempbuf, HUNK_BSS);
- EndPutM32(tempbuf+4, 1);
- DoOutputDirect(tempbuf, 8);
-
- EndPutM32(tempbuf, HUNK_EXT);
- DoOutputDirect(tempbuf, 4);
- OutputXDEF(0, "_%s", BaseName);
- EndPutM32(tempbuf, 0); /* ext end */
- DoOutputDirect(tempbuf, 4);
-
- if(!(Flags & FLAG_NOSYMBOL))
- {
- EndPutM32(tempbuf, HUNK_SYMBOL);
- DoOutputDirect(tempbuf, 4);
- OutputSYMBOL(0, "_%s", BaseName);
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf, 4);
- }
-
- EndPutM32(tempbuf, HUNK_END);
- DoOutputDirect(tempbuf, 4);
-
- sprintf(filename, "%s_autoopenver", ShortBaseName);
- i = strlen(filename);
- EndPutM32(tempbuf, HUNK_UNIT);
- EndPutM32(tempbuf+4, (i+3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(filename, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- i = strlen(datahunkname);
- EndPutM32(tempbuf, HUNK_NAME);
- EndPutM32(tempbuf+4, (i + 3)>>2);
- DoOutputDirect(tempbuf, 8);
- DoOutputDirect(datahunkname, i);
- DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
-
- EndPutM32(tempbuf, HUNK_BSS);
- EndPutM32(tempbuf+4, 1);
- DoOutputDirect(tempbuf, 8);
-
- EndPutM32(tempbuf, HUNK_EXT);
- DoOutputDirect(tempbuf, 4);
- OutputXDEF(0, "_%sVer", BaseName);
- EndPutM32(tempbuf, 0); /* ext end */
- DoOutputDirect(tempbuf, 4);
-
- if(!(Flags & FLAG_NOSYMBOL))
- {
- EndPutM32(tempbuf, HUNK_SYMBOL);
- DoOutputDirect(tempbuf, 4);
- OutputSYMBOL(0, "_%sVer", BaseName);
- EndPutM32(tempbuf, 0);
- DoOutputDirect(tempbuf, 4);
- }
-
- EndPutM32(tempbuf, HUNK_END);
- return DoOutputDirect(tempbuf, 4);
-
- break;
- }
- return 0;
- }
-
- /* ------------------------------------------------------------------ */
-
- static uint32 GetName(struct NameList *t, struct ShortListRoot *p, uint32 args)
- {
- struct NameList *p2 = (struct NameList *) p->First;
- struct AmiPragma ap;
- ap.FuncName = t->NormName;
- ap.NumArgs = 1;
- ap.Args[0].ArgName = (args ? "args" : "tags");
- if(!MakeTagFunction(&ap))
- return 0;
-
- if(!ap.TagName)
- return 0;
-
- while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
- p2 = (struct NameList *) p2->List.Next;
-
- if(!p2)
- return 0;
-
- t->Type = (args ? NTP_ARGS : NTP_TAGS);
- t->PragName = ap.TagName;
- RemoveItem(p, (struct ShortList *) p2);
-
- #ifdef DEBUG_OLD
- printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
- #endif
-
- return 1;
- }
-
- static void OptimizeFDData(struct PragData *pd)
- {
- #ifdef DEBUG_OLD
- printf("OptimizeFDData\n");
- #endif
-
- while(pd)
- {
- if(pd->NumNames > 1)
- {
- struct ShortListRoot n = {0,0,0}, p = {0,0,0};
- struct NameList *t;
- while(pd->Name.First) /* sorts in AmiCall and TagCall */
- {
- t = (struct NameList *) pd->Name.First;
-
- RemoveItem(&pd->Name, (struct ShortList *) t);
- AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
- }
-
- if(p.First)
- {
- t = (struct NameList *) n.First;
- while(p.First && t)
- {
- if(!GetName(t, &p, 0))
- {
- GetName(t, &p, 1);
- }
- if(t->PragName)
- {
- struct NameList *t2 = (struct NameList *) t->List.Next;
- RemoveItem(&n, (struct ShortList *)t);
- AddItem(&pd->Name, (struct ShortList *) t);
- t = t2;
- }
- else
- t = (struct NameList *) t->List.Next;
- }
- while(p.First)
- {
- if(n.First)
- {
- t = (struct NameList *) n.First;
- t->PragName = ((struct NameList *)(p.First))->PragName;
- RemoveItem(&n, (struct ShortList *) t);
- #ifdef DEBUG_OLD
- printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
- #endif
- t->Type = NTP_UNKNOWN;
- }
- else
- {
- uint32 i;
-
- t = (struct NameList *) p.First;
- i = strlen(t->PragName);
- t->NormName = DupString(t->PragName, i+1);
- t->NormName[i++] = 'A';
- t->NormName[i] = 0;
- t->Type = NTP_TAGS;
- #ifdef DEBUG_OLD
- printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
- #endif
- }
-
- AddItem(&pd->Name, (struct ShortList *) t);
- RemoveItem(&p, p.First);
- }
- }
-
- AddItem(&pd->Name, n.First); /* add left NormNames */
- }
- pd = (struct PragData *) pd->List.Next;
- }
- }
-
- static uint32 MakeFD(struct PragList *pl)
- {
- struct PragData *pd = (struct PragData *) pl->Data.First;
- uint32 bias;
-
- #ifdef DEBUG_OLD
- printf("MakeFD\n");
- #endif
- bias = pd->Bias;
-
- OptimizeFDData(pd);
- #ifdef DEBUG_OLD
- printf("MakeFD: after Optimizing\n");
- #endif
- DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
-
- while(pd && Output_Error)
- {
- struct NameList *n = (struct NameList *) pd->Name.First;
-
- if(bias != pd->Bias)
- DoOutput("##bias %ld\n", (bias = pd->Bias));
-
- while(n)
- {
- strptr lastpar = "last";
- uint32 i;
-
- if(n->Type == NTP_TAGS)
- lastpar = "tags";
- else if(n->Type == NTP_ARGS)
- lastpar = "args";
-
- DoOutput("%s("/*)*/,n->NormName);
- if(!pd->NumArgs)
- DoOutput(/*(*/")()\n");
- else
- {
- for(i = 0; i < pd->NumArgs-1; ++i)
- DoOutput("par%ld,",i+1);
- DoOutput(/*(*/"%s)("/*)*/, lastpar);
- for(i = 0; i < pd->NumArgs-1; ++i)
- DoOutput("%s,", RegNames[pd->ArgReg[i]]);
- DoOutput(/*(*/"%s)\n", RegNames[pd->ArgReg[i]]);
-
- if(n->Type == NTP_UNKNOWN)
- {
- uint32 i;
- for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
- ;
- DoOutput("*tagcall");
- if(n->NormName[i])
- DoOutput("-%s", n->NormName+i);
- if(n->PragName[i])
- DoOutput("+%s", n->PragName+i);
-
- DoOutput("\n");
- }
- }
- if((n = (struct NameList *) n->List.Next))
- DoOutput("##bias %ld\n", pd->Bias);
- Flags |= FLAG_DONE;
- }
-
- pd = (struct PragData *)pd->List.Next; bias += BIAS_OFFSET;
- }
-
- DoOutput("##end\n");
-
- return Output_Error;
- }
-
- static uint32 AddFDData(struct ShortListRoot *pls, struct FDData *fd)
- {
- struct NameList *t;
- struct PragList *pl = (struct PragList *) pls->First;
- struct PragData *pd;
-
- while(pl && strcmp(pl->Basename, fd->Basename))
- pl = (struct PragList *) pl->List.Next;
-
- if(!pl)
- {
- #ifdef DEBUG_OLD
- printf("AddFDData: New PragList - %s\n", fd->Basename);
- #endif
- if(!(pl = (struct PragList *) NewItem(pls)))
- return 100;
- pl->Basename = fd->Basename;
- pl->Data.Size = sizeof(struct PragData);
- AddItem(pls, (struct ShortList *) pl);
- }
-
- if((pd = (struct PragData *) pl->Data.First))
- {
- while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
- <= fd->Bias)
- pd = (struct PragData *) pd->List.Next;
- }
-
- if(!pd || pd->Bias != fd->Bias)
- {
- struct PragData *pd2;
- #ifdef DEBUG_OLD
- printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
- #endif
- if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
- return 100;
- pd2->Bias = fd->Bias;
- memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
- pd2->NumArgs = fd->NumArgs;
- pd2->Name.Size = sizeof(struct NameList);
- if(!pd)
- AddItem(&pl->Data, (struct ShortList *) pd2);
- else if(pd->Bias > fd->Bias) /* Insert at start */
- {
- pd2->List.Next = pl->Data.First;
- pl->Data.First = (struct ShortList *) pd2;
- }
- else /* Insert the entry */
- {
- pd2->List.Next = pd->List.Next;
- pd->List.Next = (struct ShortList *) pd2;
- }
- pd = pd2;
- }
- else
- {
- uint32 i = fd->NumArgs;
- if(fd->NumArgs != pd->NumArgs)
- {
- #ifdef DEBUG_OLD
- printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
- #endif
- return ERR_DIFFERENT_TO_PREVIOUS;
- }
-
- while(i--)
- {
- if(fd->ArgReg[i] != pd->ArgReg[i])
- {
- #ifdef DEBUG_OLD
- printf("ArgReg %lx != %lx\n", fd->ArgReg[i], pd->ArgReg[i]);
- #endif
- return ERR_DIFFERENT_TO_PREVIOUS;
- }
- }
- }
-
- t = (struct NameList *) pd->Name.First; /* skips same names */
- while(t && (!(fd->Mode ? t->PragName : t->NormName) ||
- strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName)))
- t = (struct NameList *) t->List.Next;
-
- if(t)
- return 0;
-
- if(!(t = (struct NameList *) NewItem(&pd->Name)))
- return 100;
- if(fd->Mode)
- t->PragName = fd->Name;
- else
- t->NormName = fd->Name;
- AddItem(&pd->Name, (struct ShortList *) t);
- ++(pd->NumNames);
- #ifdef DEBUG_OLD
- printf("AddFDData: New NameList - %s\n", fd->Name);
- #endif
- return 0;
- }
-
- static string GetHexValue(string data)
- {
- if(data >= 'a')
- return (string) (data - 'a' + 10);
- else if(data >= 'A')
- return (string) (data - 'A' + 10);
- else
- return (string) (data - '0');
- }
-
- static string GetDoubleHexValue(strptr data)
- {
- return (string)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
- }
-
- static uint32 GetLibData(struct FDData *fd)
- {
- uint32 i;
- fd->Name = SkipBlanks(in.pos);
- in.pos = SkipName(fd->Name); *(in.pos++) = 0;
- in.pos = SkipBlanks(in.pos);
- fd->Bias = strtoul(in.pos, 0, 16);
- in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
- if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
- return ERR_TO_MUCH_ARGUMENTS;
- --in.pos; /* skips return register */
- for(i = 0; i < fd->NumArgs; ++i)
- {
- if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
- return ERR_EXPECTED_REGISTER_NAME;
- }
- return 0;
- }
-
- static uint32 GetFlibData(struct FDData *fd)
- {
- uint32 i;
- fd->Name = SkipBlanks(in.pos);
- in.pos = SkipName(fd->Name); *(in.pos++) = 0;
- in.pos = SkipBlanks(in.pos);
- fd->Bias = strtoul(in.pos, 0, 16);
- in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
- if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
- return ERR_TO_MUCH_ARGUMENTS;
- in.pos -= 2; /* skips return register */
- for(i = 0; i < fd->NumArgs; ++i)
- {
- in.pos -= 2;
- if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
- return ERR_EXPECTED_REGISTER_NAME;
- else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
- return ERR_FLOATARG_NOT_ALLOWED;
- }
- return 0;
- }
-
- static uint32 GetAmiData(struct FDData *fd)
- {
- strptr endptr;
- in.pos = SkipBlanks(in.pos);
- if(*in.pos != '('/*)*/)
- return ERR_EXPECTED_OPEN_BRACKET;
- fd->Basename = ++in.pos;
- in.pos = SkipBlanks(endptr = SkipName(in.pos));
- if(*in.pos != ',')
- return ERR_EXPECTED_COMMA;
- *endptr = 0;
- in.pos = SkipBlanks(++in.pos);
- if(!strncmp(in.pos, "0x", 2))
- fd->Bias = strtoul(in.pos+2, 0, 16);
- else
- fd->Bias = strtoul(in.pos, 0, 10);
-
- in.pos = SkipBlanks(SkipName(in.pos));
- if(*in.pos != ',')
- return ERR_EXPECTED_COMMA;
- fd->Name = in.pos = SkipBlanks(++in.pos);
- in.pos = SkipBlanks(endptr = SkipName(in.pos));
- if(*in.pos != '('/*)*/)
- return ERR_EXPECTED_OPEN_BRACKET;
- *endptr = 0;
- in.pos = SkipBlanks(++in.pos);
- if(*in.pos == /*(*/')')
- return 0;
- --in.pos;
- while(*in.pos != /*(*/')')
- {
- uint32 i;
- in.pos = SkipBlanks(in.pos+1);
-
- for(i = 0; i < REG_FP0; i++)
- if(!strnicmp(RegNames[i], in.pos, 2))
- break;
- if(i == REG_FP0)
- {
- for(; i < MAXREG; i++)
- if(!strnicmp(RegNames[i], in.pos, 3))
- break;
- }
-
- if(i == MAXREG)
- return ERR_EXPECTED_REGISTER_NAME;
- else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
- return ERR_FLOATARG_NOT_ALLOWED;
-
- fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
-
- if(fd->NumArgs > MAXREG-2)
- return ERR_TO_MUCH_ARGUMENTS;
-
- in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
-
- if(*in.pos != ',' && *in.pos != /*(*/')')
- return ERR_EXPECTED_CLOSE_BRACKET;
- }
- in.pos = SkipBlanks(in.pos+1);
- if(*in.pos != /*(*/')')
- return ERR_EXPECTED_CLOSE_BRACKET;
- return 0;
- }
-
- static uint32 CreateFDFile(void)
- {
- struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
- uint32 linenum, err = 0, skip;
- strptr ptr, p2;
-
- ptr = p2 = args.infile;
- while(*p2)
- {
- if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
- ptr = p2+1;
- ++p2;
- }
- for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
- ;
- if(p2 != ptr)
- {
- ShortBaseName = ptr;
- *p2 = '\0';
- }
-
- for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
- {
- in.pos = SkipBlanks(in.pos);
- if(!strncmp("#pragma", in.pos, 7))
- {
- struct FDData fd;
-
- skip = 0;
- memset(&fd, 0, sizeof(struct FDData));
-
- in.pos = SkipBlanks(in.pos+7);
- if(!strncmp("tagcall", in.pos, 7))
- {
- fd.Mode = 1;
- in.pos = SkipBlanks(in.pos+7);
- if(*in.pos == '(' /*)*/) /* Storm method */
- err = GetAmiData(&fd);
- else /* SAS method */
- {
- fd.Basename = in.pos;
- in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
- err = GetLibData(&fd);
- }
- }
- else if(!strncmp("amicall", in.pos, 7)) /* Storm method */
- {
- in.pos += 7;
- err = GetAmiData(&fd);
- }
- else if(!strncmp("libcall", in.pos, 7)) /* SAS method */
- {
- fd.Basename = SkipBlanks(in.pos+7);
- in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
- err = GetLibData(&fd);
- }
- else if(!strncmp("flibcall", in.pos, 8)) /* SAS method */
- {
- fd.Basename = SkipBlanks(in.pos+8);
- in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
- err = GetFlibData(&fd);
- }
- else if(!strncmp("syscall", in.pos, 7)) /* SAS method */
- {
- fd.Basename = "SysBase";
- err = GetLibData(&fd);
- }
- else
- skip = 1;
-
- if(err)
- DoError(err, linenum);
- else if(skip)
- ;
- else if((err = AddFDData(&pl, &fd)))
- {
- if(err != 100)
- DoError(err, linenum);
- return 0;
- }
- }
- while(*(in.pos++)) /* jumps to first char of next line */
- ;
- }
-
- if(pl.First)
- {
- struct PragList *p = (struct PragList *) pl.First;
- if(!p->List.Next)
- {
- strptr text, to;
- uint32 i;
-
- if(ShortBaseName)
- {
- text = ShortBaseName; i = strlen(text);
- }
- else
- {
- text = p->Basename; i = strlen(text)-4;
- }
-
- to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
- memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
- if(!OpenDest(to))
- return 0;
-
- err = MakeFD(p);
- CloseDest(to);
- if(!err)
- return 0;
- }
- else
- {
- while(p)
- {
- strptr to;
- uint32 i;
- i = strlen(p->Basename) - 4;
- to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
- memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
- if(!OpenDest(to))
- return 0;
- i = MakeFD(p);
- CloseDest(to);
- if(!i)
- return 0;
- p = (struct PragList *) p->List.Next;
- }
- }
- }
-
- return 1;
- }
-
- #ifdef FD2PRAGMA_READARGS
- #include <proto/dos.h>
-
- #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
- "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
- "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
- "COMMENT/S,EXTERNC/S,FPUONLY/S,NEWSYNTAX/S," \
- "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
- "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
- "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S,SORTED/S," \
- "SYSTEMRELEASE/S,USESYSCALL/S"
-
- struct AmiArg
- {
- strptr INFILE;
- uint32* SPECIAL;
- uint32* MODE;
- strptr TO;
- strptr ABI;
- strptr CLIB;
- strptr COPYRIGHT;
- strptr HEADER;
- strptr HUNKNAME;
- strptr BASENAME;
- strptr LIBTYPE;
- strptr LIBNAME;
- uint32* PRIORITY;
- uint32 COMMENT;
- uint32 EXTERNC;
- uint32 FPUONLY;
- uint32 NEWSYNTAX;
- uint32 NOFPU;
- uint32 NOPPC;
- uint32 NOPPCREGNAME;
- uint32 NOSYMBOL;
- uint32 ONLYCNAMES;
- uint32 OPT040;
- uint32 PPCONLY;
- uint32 PRIVATE;
- uint32 SECTION;
- uint32 SMALLCODE;
- uint32 SMALLDATA;
- uint32 SORTED;
- uint32 SYSTEMRELEASE;
- uint32 USESYSCALL;
- };
-
- static const strptr helptext =
- "INFILE: the input file which should be used\n"
- "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
- "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
- "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
- "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
- "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
- "\t 6 - all compilers [default]\n"
- "\t 7 - all compilers with pragma to inline redirect for GCC\n"
- "\t10 - stub-functions for C - C text\n"
- "\t11 - stub-functions for C - assembler text\n"
- "\t12 - stub-functions for C - link library\n"
- "\t13 - defines and link library for local library base (register call)\n"
- "\t14 - defines and link library for local library base (stack call)\n"
- "\t15 - stub-functions for Pascal - assembler text\n"
- "\t16 - stub-functions for Pascal - link library\n"
- "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
- "\t18 - module for AmigaE\n"
- "\t20 - assembler lvo _lvo.i file\n"
- "\t21 - assembler lvo _lib.i file\n"
- "\t22 - assembler lvo _lvo.i file no XDEF\n"
- "\t23 - assembler lvo _lib.i file no XDEF\n"
- "\t24 - assembler lvo link library\n"
- "\t30 - proto file with pragma/..._lib.h call\n"
- "\t31 - proto file with pragma/..._pragmas.h call\n"
- "\t32 - proto file with pragmas/..._lib.h call\n"
- "\t33 - proto file with pragmas/..._pragmas.h call\n"
- "\t34 - proto file with local/..._loc.h call\n"
- "\t35 - proto file for all compilers\n"
- "\t36 - proto file for GNU-C compiler only\n"
- "\t37 - proto file without lib definitions\n"
- "\t38 - proto file with VBCC inline support\n"
- "\t39 - proto file with special PPC related checks\n"
- "\t40 - GCC inline file (preprocessor based)\n"
- "\t41 - GCC inline file (old type - inline based)\n"
- "\t42 - GCC inline file (library stubs)\n"
- "\t43 - GCC inline file (new style - macro)\n"
- "\t44 - GCC inline file (new style - inline)\n"
- "\t45 - GCC inline file (new style - inline with include lines)\n"
- "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
- "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
- "\t52 - GCC inline files for PowerUP (library stubs)\n"
- "\t53 - SAS-C include file for PowerUP\n"
- "\t54 - Proto file for PowerUP\n"
- "\t60 - FPC pascal unit text\n"
- "\t70 - VBCC inline files\n"
- "\t71 - VBCC WOS stub-functions - assembler text\n"
- "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
- "\t73 - VBCC WOS stub-functions - link library\n"
- "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
- "\t75 - VBCC PowerUP stub-functions - assembler text\n"
- "\t76 - VBCC PowerUP stub-functions - link library\n"
- "\t77 - VBCC WOS inline files\n"
- "\t78 - VBCC MorphOS stub-functions - link library\n"
- "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
- "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
- "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
- "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
- "\t90 - stub-functions for C - assembler text (multiple files)\n"
- "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
- "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
- "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
- " 100 - PPC assembler lvo file\n"
- " 101 - PPC assembler lvo file no XDEF\n"
- " 102 - PPC assembler lvo ELF link library\n"
- " 103 - PPC assembler lvo EHF link library\n"
- " 104 - PPC V.4-ABI assembler file\n"
- " 105 - PPC V.4-ABI assembler file no XDEF\n"
- " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
- " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
- " 110 - FD file\n"
- " 111 - CLIB file\n"
- " 112 - SFD file\n"
- " 120 - VBCC auto libopen files (C source)\n"
- " 121 - VBCC auto libopen files (m68k link library)\n"
- " 200 - FD file (source is a pragma file!)\n"
- "MODE: SPECIAL 1-7:\n"
- " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
- " 2: _PRAGMAS_..._LIB_H definition method\n"
- " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
- " 4: no definition\n"
- " SPECIAL 11-14,40-45,50-53,71-76,78,90-91,111-112:\n"
- " 1: all functions, normal interface\n"
- " 2: only tag-functions, tagcall interface\n"
- " 3: all functions, normal and tagcall interface [default]\n"
- "TO: the destination directory (self creation of filename)\n"
- "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
- "CLIB: name of the prototypes file in clib directory\n"
- "COPYRIGHT: the copyright text for CLIB files\n"
- "HEADER: inserts given file into header of created file (\"\" is scan)\n"
- "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
- "BASENAME: name of library base without '_'\n"
- "LIBNAME: name of the library (.e.g. dos.library)\n"
- "LIBTYPE: type of base library structure\n"
- "PRIORITY: priority for auto open files\n"
- "Switches:\n"
- "COMMENT: copy comments found in FD file\n"
- "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
- "FPUONLY: work only with functions using FPU register arguments\n"
- "NEWSYNTAX: uses new Motorola syntax for asm files\n"
- "NOFPU: disable usage of FPU register arguments\n"
- "NOPPC: disable usage of PPC-ABI functions\n"
- "NOPPCREGNAME: do not add 'r' to PPC register names\n"
- "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
- "ONLYCNAMES: do not create C++ or ASM names\n"
- "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
- "PPCONLY: only use PPC-ABI functions\n"
- "PRIVATE: includes private declared functions\n"
- "SECTION: add section statements to asm texts\n"
- "SMALLCODE: generate small code link libraries or assembler text\n"
- "SMALLDATA: generate small data link libraries or assembler text\n"
- "SORTED: sort generated files by name and not by bias value\n"
- "SYSTEMRELEASE: special handling of comments for system includes\n"
- "USESYSCALL: uses syscall pragma instead of libcall SysBase\n";
-
- /* print the help text */
- static void printhelp(void)
- {
- printf("%s\n%s\n\n%s", version+6, PARAM, helptext);
- exit(20);
- }
-
- /* initializes the arguments and starts argument parsing */
- static void GetArgs(int argc, char **argv)
- {
- struct RDArgs *rda;
- struct AmiArg amiargs;
- int res = 0;
-
- if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
- {
- rda->RDA_ExtHelp = helptext;
- memset(&amiargs, 0, sizeof(struct AmiArg));
- if(ReadArgs(PARAM, (int32 *) &amiargs, rda))
- {
- int l;
- strptr d, s;
-
- l = strlen(amiargs.TO ? amiargs.TO : "")
- + strlen(amiargs.CLIB ? amiargs.CLIB : "")
- + strlen(amiargs.HEADER ? amiargs.HEADER : "")
- + strlen(amiargs.ABI ? amiargs.ABI : "")
- + strlen(amiargs.HUNKNAME ? amiargs.HUNKNAME : "")
- + strlen(amiargs.BASENAME ? amiargs.BASENAME : "")
- + strlen(amiargs.LIBTYPE ? amiargs.LIBTYPE : "")
- + strlen(amiargs.LIBNAME ? amiargs.LIBNAME : "")
- + strlen(amiargs.COPYRIGHT ? amiargs.COPYRIGHT : "")
- + strlen(amiargs.INFILE) + 5;
- if((d = AllocListMem(l)))
- {
- res = 1;
-
- s = amiargs.INFILE;
- args.infile = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- if((s = amiargs.TO))
- {
- args.to = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.HEADER))
- {
- args.header = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.CLIB))
- {
- args.clib = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.HUNKNAME))
- {
- hunkname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.BASENAME))
- {
- Flags |= FLAG_BASENAME;
- BaseName = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.LIBTYPE))
- {
- Flags2 |= FLAG2_LIBTYPE;
- libtype = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.LIBNAME))
- {
- Flags2 |= FLAG2_LIBNAME;
- libname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.COPYRIGHT))
- {
- Copyright = d; while(*s) *(d++) = *(s++); *(d++) = 0;
- }
- if((s = amiargs.ABI))
- {
- defabi = d; while(*s) *(d++) = *(s++); *d = 0;
- }
- if(amiargs.EXTERNC) Flags ^= FLAG_EXTERNC;
- if(amiargs.PRIVATE) Flags ^= FLAG_PRIVATE;
- if(amiargs.NEWSYNTAX) Flags ^= FLAG_NEWSYNTAX;
- if(amiargs.SMALLDATA) Flags ^= FLAG_SMALLDATA;
- if(amiargs.SMALLCODE) Flags2 ^= FLAG2_SMALLCODE;
- if(amiargs.USESYSCALL) Flags ^= FLAG_SYSCALL;
- if(amiargs.OPT040) Flags ^= FLAG_NOMOVEM;
- if(amiargs.NOFPU) Flags ^= FLAG_NOFPU;
- if(amiargs.FPUONLY) Flags ^= FLAG_FPUONLY;
- if(amiargs.NOPPC) Flags ^= FLAG_NOPPC;
- if(amiargs.NOSYMBOL) Flags ^= FLAG_NOSYMBOL;
- if(amiargs.PPCONLY) Flags ^= FLAG_PPCONLY;
- if(amiargs.SECTION) Flags ^= FLAG_ASMSECTION;
- if(amiargs.COMMENT) Flags ^= FLAG_DOCOMMENT;
- if(amiargs.SORTED) Flags ^= FLAG_SORTED;
- if(amiargs.ONLYCNAMES) Flags ^= FLAG_ONLYCNAMES;
- if(amiargs.SYSTEMRELEASE) Flags2 ^= FLAG2_SYSTEMRELEASE;
- if(amiargs.NOPPCREGNAME) PPCRegPrefix = "";
- if(amiargs.SPECIAL)
- args.special = *amiargs.SPECIAL;
- if(amiargs.MODE)
- args.mode = *amiargs.MODE;
- if(amiargs.PRIORITY)
- priority = *amiargs.PRIORITY;
- }
- FreeArgs(rda);
- }
- else
- PrintFault(IoErr(), 0);
- FreeDosObject(DOS_RDARGS, rda);
- }
-
- if(!res)
- /* printhelp(); */
- exit(20);
- }
-
- #else
- static const strptr helptext =
- " -h,--help\n"
- " -i,--infile <input filename>\n"
- " -s,--special <number>\n"
- " -m,--mode <number>\n"
- " -t,--to <destination directory>\n"
- " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
- " -c,--clib <clib prototypes filename>\n"
- " -h,--header <header file or \"\">\n"
- " -i,--libname <name of library>\n"
- " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
- " -b,--basename <name of library base without '_'>\n"
- " -l,--libtype <name of base library type>\n"
- " -p,--priority <priority for auto open files>\n"
- " -r,--copyright<copyright text>\n"
- "\n"
- "Switches:\n"
- "--comment copy comments found in FD file\n"
- "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
- "--fpuonly work only with functions using FPU register arguments\n"
- "--newsyntax uses new Motorola syntax for asm files\n"
- "--nofpu disable usage of FPU register arguments\n"
- "--noppc disable usage of PPC-ABI functions\n"
- "--noppcregname do not add 'r' to PPC register names\n"
- "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
- "--onlycnames do not create C++ or ASM names\n"
- "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
- "--ppconly only use PPC-ABI functions\n"
- "--private includes private declared functions\n"
- "--section add section statements to asm texts\n"
- "--smallcode generate small code link libraries or assembler text\n"
- "--smalldata generate small data link libraries or assembler text\n"
- "--sorted sort generated files by name and not by bias value\n"
- "--systemrelease special handling of comments for system includes\n"
- "--usesyscall uses syscall pragma instead of libcall SysBase\n"
- "\n"
- "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
- " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
- " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
- " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
- " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
- " 6 - all compilers [default]\n"
- " 7 - all compilers with pragma to inline redirect for GCC\n"
- " 10 - stub-functions for C - C text\n"
- " 11 - stub-functions for C - assembler text\n"
- " 12 - stub-functions for C - link library\n"
- " 13 - defines and link library for local library base (register call)\n"
- " 14 - defines and link library for local library base (stack call)\n"
- " 15 - stub-functions for Pascal - assembler text\n"
- " 16 - stub-functions for Pascal - link library\n"
- " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
- " 18 - module for AmigaE\n"
- " 20 - assembler lvo _lvo.i file\n"
- " 21 - assembler lvo _lib.i file\n"
- " 22 - assembler lvo _lvo.i file no XDEF\n"
- " 23 - assembler lvo _lib.i file no XDEF\n"
- " 24 - assembler lvo link library\n"
- " 30 - proto file with pragma/..._lib.h call\n"
- " 31 - proto file with pragma/..._pragmas.h call\n"
- " 32 - proto file with pragmas/..._lib.h call\n"
- " 33 - proto file with pragmas/..._pragmas.h call\n"
- " 34 - proto file with local/..._loc.h call\n"
- " 35 - proto file for all compilers\n"
- " 36 - proto file for GNU-C compiler only\n"
- " 37 - proto file without lib definitions\n"
- " 38 - proto file with VBCC inline support\n"
- " 39 - proto file with special PPC related checks\n"
- " 40 - GCC inline file (preprocessor based)\n"
- " 41 - GCC inline file (old type - inline based)\n"
- " 42 - GCC inline file (library stubs)\n"
- " 43 - GCC inline file (new style - macro)\n"
- " 44 - GCC inline file (new style - inline)\n"
- " 45 - GCC inline file (new style - inline with include lines)\n"
- " 50 - GCC inline files for PowerUP (preprocessor based)\n"
- " 51 - GCC inline files for PowerUP (old type - inline based)\n"
- " 52 - GCC inline files for PowerUP (library stubs)\n"
- " 53 - SAS-C include file for PowerUP\n"
- " 54 - Proto file for PowerUP\n"
- " 60 - FPC pascal unit text\n"
- " 70 - VBCC inline files\n"
- " 71 - VBCC WOS stub-functions - assembler text\n"
- " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
- " 73 - VBCC WOS stub-functions - link library\n"
- " 74 - VBCC WOS stub-functions - link library (libbase)\n"
- " 75 - VBCC PowerUP stub-functions - assembler text\n"
- " 76 - VBCC PowerUP stub-functions - link library\n"
- " 77 - VBCC WOS inline files\n"
- " 78 - VBCC MorphOS stub-functions - link library\n"
- " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
- " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
- " 82 - pragma/proto redirect (xxx.h, GCC)\n"
- " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
- " 90 - stub-functions for C - assembler text (multiple files)\n"
- " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
- " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
- " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
- " 100 - PPC assembler lvo file\n"
- " 101 - PPC assembler lvo file no XDEF\n"
- " 102 - PPC assembler lvo ELF link library\n"
- " 103 - PPC assembler lvo EHF link library\n"
- " 104 - PPC V.4-ABI assembler file\n"
- " 105 - PPC V.4-ABI assembler file no XDEF\n"
- " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
- " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
- " 110 - FD file\n"
- " 111 - CLIB file\n"
- " 112 - SFD file\n"
- " 120 - VBCC auto libopen files (C source)\n"
- " 121 - VBCC auto libopen files (m68k link library)\n"
- " 200 - FD file (source is a pragma file!)\n"
- "mode: SPECIAL 1-7\n"
- " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
- " 2 - _PRAGMAS_..._LIB_H definition method\n"
- " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
- " 4 - no definition\n"
- " SPECIAL 11-14,40-45,50-53,71-76,78,90-93,111-112:\n"
- " 1 - all functions, normal interface\n"
- " 2 - only tag-functions, tagcall interface\n"
- " 3 - all functions, normal and tagcall interface [default]\n";
-
- /* print the help text */
- static void printhelp(void)
- {
- printf("%s\n%s", version+6, helptext);
- exit(20);
- }
-
- struct ArgData
- {
- strptr ArgName;
- uint8 ArgChar;
- uint8 ArgNameLen;
- uint8 ArgNum;
- };
-
- enum ArgNums {
- ARG_HELP, ARG_INFILE, ARG_SPECIAL, ARG_MODE, ARG_TO, ARG_CLIB, ARG_ABI, ARG_COPYRIGHT,
- ARG_HEADER, ARG_HUNKNAME, ARG_BASENAME, ARG_LIBTYPE,
- ARG_COMMENT, ARG_EXTERNC, ARG_FPUONLY, ARG_NEWSYNTAX, ARG_NOFPU, ARG_NOPPC,
- ARG_NOSYMBOL, ARG_ONLYCNAMES, ARG_OPT040, ARG_PPCONLY, ARG_PRIVATE, ARG_SECTION,
- ARG_SMALLDATA, ARG_SORTED, ARG_USESYSCALL, ARG_NOPPCREGNAME,
- ARG_SYSTEMRELEASE, ARG_PRIORITY, ARG_LIBNAME, ARG_SMALLCODE
- };
-
- /* argument definition array */
- static const struct ArgData argtexts[] = {
- {"help", 'h', 4, ARG_HELP},
- {"infile", 'i', 6, ARG_INFILE},
- {"special", 's', 7, ARG_SPECIAL},
- {"mode", 'm', 4, ARG_MODE},
- {"to", 't', 2, ARG_TO},
- {"clib", 'c', 4, ARG_CLIB},
- {"abi", 'a', 3, ARG_ABI},
- {"copyright", 'r', ARG_COPYRIGHT},
- {"header", 'h', 6, ARG_HEADER},
- {"hunkname", 'n', 8, ARG_HUNKNAME},
- {"basename", 'b', 8, ARG_BASENAME},
- {"libtype", 'l', 7, ARG_LIBTYPE},
- {"libname", 'i', 7, ARG_LIBNAME},
- {"priority", 'p', 8, ARG_PRIORITY},
- {"comment", 0, 7, ARG_COMMENT},
- {"externc", 0, 7, ARG_EXTERNC},
- {"fpuonly", 0, 7, ARG_FPUONLY},
- {"newsyntax", 0, 9, ARG_NEWSYNTAX},
- {"nofpu", 0, 5, ARG_NOFPU},
- {"noppc", 0, 5, ARG_NOPPC},
- {"noppcregname", 0, 12, ARG_NOPPCREGNAME},
- {"nosymbol", 0, 8, ARG_NOSYMBOL},
- {"onlycnames", 0, 10, ARG_ONLYCNAMES},
- {"opt040", 0, 6, ARG_OPT040},
- {"ppconly", 0, 7, ARG_PPCONLY},
- {"private", 0, 7, ARG_PRIVATE},
- {"section", 0, 7, ARG_SECTION},
- {"smalldata", 0, 9, ARG_SMALLDATA},
- {"smallcode", 0, 9, ARG_SMALLCODE},
- {"sorted", 0, 6, ARG_SORTED},
- {"systemrelease", 13, ARG_SYSTEMRELEASE},
- {"usesyscall", 0, 10, ARG_USESYSCALL},
- {0,0,0,0}, /* end marker */
- };
-
- /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
- static uint32 ParseArgEntry(uint32 argc, strptr *argv)
- {
- uint32 numentries = 1, l;
- strptr a, b;
- const struct ArgData *ad;
-
- if((*argv)[0] != '-' || !(*argv)[1])
- return 0;
-
- ad = argtexts;
- while(ad->ArgName)
- {
- if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
- break;
- ++ad;
- }
- if(!ad->ArgName)
- return 0;
- switch(ad->ArgNum)
- {
- case ARG_HELP: printhelp(); break;
- case ARG_EXTERNC: Flags ^= FLAG_EXTERNC; break;
- case ARG_PRIVATE: Flags ^= FLAG_PRIVATE; break;
- case ARG_NEWSYNTAX: Flags ^= FLAG_NEWSYNTAX; break;
- case ARG_SMALLDATA: Flags ^= FLAG_SMALLDATA; break;
- case ARG_SMALLCODE: Flags2 ^= FLAG2_SMALLCODE; break;
- case ARG_USESYSCALL: Flags ^= FLAG_SYSCALL; break;
- case ARG_OPT040: Flags ^= FLAG_NOMOVEM; break;
- case ARG_NOFPU: Flags ^= FLAG_NOFPU; break;
- case ARG_FPUONLY: Flags ^= FLAG_FPUONLY; break;
- case ARG_NOPPC: Flags ^= FLAG_NOPPC; break;
- case ARG_NOSYMBOL: Flags ^= FLAG_NOSYMBOL; break;
- case ARG_PPCONLY: Flags ^= FLAG_PPCONLY; break;
- case ARG_SECTION: Flags ^= FLAG_ASMSECTION; break;
- case ARG_COMMENT: Flags ^= FLAG_DOCOMMENT; break;
- case ARG_SORTED: Flags ^= FLAG_SORTED; break;
- case ARG_ONLYCNAMES: Flags ^= FLAG_ONLYCNAMES; break;
- case ARG_SYSTEMRELEASE: Flags2 ^= FLAG2_SYSTEMRELEASE; break;
- case ARG_NOPPCREGNAME: PPCRegPrefix = "";
- default:
- a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
- if(!(*a))
- {
- if(argc > 1) { a = argv[1]; numentries = 2; }
- else { a = 0; numentries = 0;}
- }
- else if(*a == '=')
- ++a;
- if(a)
- {
- if(*a == '\"')
- {
- l = strlen(++a);
- if(a[l-1] == '\"')
- a[--l] = 0; /* remove second " */
- }
- switch(ad->ArgNum)
- {
- case ARG_INFILE: args.infile = a; break;
- case ARG_COPYRIGHT: Copyright = a; break;
- case ARG_TO: args.to = a; break;
- case ARG_ABI: defabi = a; break;
- case ARG_CLIB: args.clib = a; break;
- case ARG_HEADER: args.header = a; break;
- case ARG_HUNKNAME: hunkname = a; break;
- case ARG_LIBTYPE: libtype = a; Flags2 |= FLAG2_LIBTYPE; break;
- case ARG_LIBNAME: libname = a; Flags2 |= FLAG2_LIBNAME; break;
- case ARG_BASENAME: BaseName = a; Flags |= FLAG_BASENAME; break;
- case ARG_SPECIAL:
- args.special = strtoul(a, &b, 10);
- if(*b)
- numentries = 0;
- break;
- case ARG_PRIORITY:
- priority = strtoul(a, &b, 10);
- if(*b)
- numentries = 0;
- break;
- case ARG_MODE:
- args.mode = strtoul(a, &b, 10);
- if(*b || args.mode < 1 || args.mode > 3)
- numentries = 0;
- break;
- }
- }
- }
- return numentries;
- }
-
- /* initializes the arguments and starts argument parsing */
- static void GetArgs(int argc, char **argv)
- {
- int res = 1;
- int i = 1, j;
-
- while(i < argc && res)
- {
- if((j = ParseArgEntry(argc-i, argv+i)) < 1)
- res = 0;
- else
- i += j;
- }
- if(!res || !args.infile)
- printhelp();
- }
-
- #endif
-
- static strptr mygetfile(strptr name, size_t *len)
- {
- strptr ptr = 0;
- FILE *infile;
-
- if((infile = fopen(name, "rb")))
- {
- if(!fseek(infile, 0, SEEK_END))
- {
- *len = ftell(infile);
- if(!fseek(infile, SEEK_SET, 0))
- {
- if((ptr = AllocListMem(*len+1)))
- {
- ptr[*len] = 0;
- #ifdef DEBUG_OLD
- printf("mygetfile: '%s' size %ld\n", name, *len);
- #endif
- if(fread(ptr, *len, 1, infile) != 1)
- ptr = 0;
- }
- }
- }
- fclose(infile);
- }
- return ptr;
- }
-
- int main(int argc, char **argv)
- {
- uint32 mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_BOTH;
- strptr amicall = 0, libcall = 0, amitags = 0, libtags = 0;
- strptr clibbuf, ptr;
- size_t clibsize = 0, len;
-
- GetArgs(argc, argv);
-
- if((tempbuf = (uint8 *) AllocListMem(TEMPSIZE)))
- {
- if(!(in.pos = in.buf = mygetfile(args.infile, &in.size)))
- {
- if(args.special == 200)
- {
- DoError(ERR_OPEN_FILE, 0, args.infile);
- exit(20);
- }
- else
- {
- sprintf((strptr)tempbuf, "%s" SFDFILEEXTENSION, args.infile);
- if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
- {
- sprintf((strptr)tempbuf, "%s" FDFILEEXTENSION, args.infile);
- if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
- {
- DoError(ERR_OPEN_FILE, 0, args.infile);
- exit(20);
- }
- else
- args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
- }
- else
- args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
- }
- }
- printf("SourceFile: %s\n", args.infile);
-
- MakeLines(in.pos, in.size);
-
- if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SORTED)) /* is not possible to use both */
- {
- DoError(ERR_SORTED_COMMENT, 0);
- Flags &= (~FLAG_SORTED);
- }
-
- if(args.special == 200)
- {
- CreateFDFile();
- exit(0);
- }
-
- if(!(ptr = mygetfile(EXTTYPESFILE, &len)))
- {
- if(!(ptr = mygetfile(EXTTYPESFILE2, &len)))
- {
- DoError(ERR_NOFD2PRAGMATYPES, 0);
- ptr = (strptr) InternalTypes;
- len = sizeof(InternalTypes)-1;
- }
- }
- {
- uint32 i;
-
- if((i = ScanTypes(ptr, len)) > 0)
- DoError(ERR_WRONG_TYPES_LINE, i);
- if(i)
- exit(20);
- }
-
- if(!ScanFDFile())
- exit(20);
-
- if(args.clib)
- {
- if(Flags2 & FLAG2_SFDMODE)
- DoError(ERR_SFD_AND_CLIB, 0);
- else
- {
- sprintf((strptr)tempbuf, "%s_protos.h", args.clib);
- if(!(clibbuf = mygetfile(args.clib, &clibsize)) && !(clibbuf = mygetfile((strptr)tempbuf, &clibsize)))
- {
- DoError(ERR_OPEN_FILE, 0, args.clib);
- exit(20);
- }
- ScanClibFile(clibbuf, clibbuf+clibsize);
- }
- }
-
- if(!MakeShortBaseName())
- {
- DoError(ERR_MISSING_SHORTBASENAME, 0);
- exit(20);
- }
-
- if(args.special < 10) /* the pragma area is up to 9 */
- {
- mode = MODUS_PRAGMA;
- sprintf(filename, "%s_lib.h", ShortBaseName);
-
- switch(args.special)
- {
- case 0: break;
- case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
- case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
- pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
- case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
- pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
- libtags = "def " TEXT_SAS_60; break;
- case 4: amicall = ""; break;
- case 5: amicall = amitags = ""; break;
- case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
- case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
- TEXT_MAXON ") || defined(" TEXT_STORM ")";
- libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
- libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
- default: mode = MODUS_ERROR; break;
- }
-
- if(args.mode > 0 && args.mode < 5)
- pragmode = args.mode;
- }
- else if(args.special < 20) /* the misc area is up to 19 */
- {
- if(args.mode > 0 && args.mode < 4)
- callmode = args.mode - 1;
- switch(args.special)
- {
- case 10: mode = MODUS_CSTUB;
- sprintf(filename, "%s_cstub.h", ShortBaseName); break;
- case 11: mode = MODUS_STUBTEXT;
- sprintf(filename, "%s_stub.s", ShortBaseName); break;
- case 12: mode = MODUS_STUBCODE;
- sprintf(filename, "%s.lib", ShortBaseName); break;
- case 13: Flags |= FLAG_LOCALREG; /* no break ! */
- case 14: mode = MODUS_LOCALDATA;
- sprintf(filename, "%s_loc.h", ShortBaseName); break;
- case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
- Flags ^= FLAG_PASCAL;
- sprintf(filename, "%s_stub.s", ShortBaseName); break;
- case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
- Flags ^= FLAG_PASCAL;
- sprintf(filename, "%s.lib", ShortBaseName); break;
- case 17: mode = MODUS_BMAP; callmode = TAGMODE_NORMAL;
- sprintf(filename, "%s.bmap", ShortBaseName); break;
- case 18: mode = MODUS_EMODULE;
- sprintf(filename, "%s.m", ShortBaseName); break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 30) /* the lvo area is up to 29 */
- {
- switch(args.special)
- {
- case 20: case 22: mode = MODUS_LVO+args.special-20;
- sprintf(filename, "%s_lvo.i", ShortBaseName); break;
- case 21: case 23: mode = MODUS_LVO+args.special-20;
- sprintf(filename, "%s_lib.i", ShortBaseName); break;
- case 24: mode = MODUS_LVOLIB;
- sprintf(filename, "%slvo.o", ShortBaseName); break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 40) /* the proto area is up to 39 */
- {
- if(args.special < 40)
- {
- mode = MODUS_PROTO+args.special-30;
- sprintf(filename, "%s.h", ShortBaseName);
- }
- else
- mode = MODUS_ERROR;
- }
- else if(args.special < 50) /* the inline area is up to 49 */
- {
- if(args.mode > 0 && args.mode < 4)
- callmode = args.mode - 1;
-
- switch(args.special)
- {
- case 40: case 41: case 42: case 43: case 44: case 45:
- mode = MODUS_INLINE+args.special-40;
- sprintf(filename, "%s.h", ShortBaseName); break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 60) /* the PowerUP area is up to 59 */
- {
- if(args.mode > 0 && args.mode < 4)
- callmode = args.mode - 1;
-
- switch(args.special)
- {
- case 50: case 51: case 52: mode = MODUS_INLINE+args.special-50;
- sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_POWERUP;
- break;
- case 53:
- sprintf(filename, "%s_pragmas.h", ShortBaseName);
- mode = MODUS_SASPOWER; break;
- case 54:
- sprintf(filename, "%s.h", ShortBaseName);
- mode = MODUS_PROTOPOWER; break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 70) /* the PASCAL stuff */
- {
- if(args.special == 60)
- {
- mode = MODUS_PASCAL;
- sprintf(filename, "%s.pas", ShortBaseName);
- }
- else
- mode = MODUS_ERROR;
- }
- else if(args.special < 80) /* the VBCC stuff */
- {
- if(args.mode > 0 && args.mode < 4)
- callmode = args.mode - 1;
-
- switch(args.special)
- {
- case 70: mode = MODUS_VBCCINLINE;
- sprintf(filename, "%s_protos.h", ShortBaseName); break;
- case 71: case 72: case 75:
- mode = MODUS_VBCC+args.special-71;
- sprintf(filename, "%s_stub.s", ShortBaseName); break;
- case 73: case 74:
- mode = MODUS_VBCC+args.special-71;
- sprintf(filename, "%s.lib", ShortBaseName); break;
- case 76:
- mode = MODUS_VBCCPUPLIB;
- sprintf(filename, "lib%s.a", ShortBaseName); break;
- case 77: mode = MODUS_VBCCWOSINLINE;
- sprintf(filename, "%s_protos.h", ShortBaseName); break;
- case 78: mode = MODUS_VBCCMORPHCODE;
- sprintf(filename, "lib%s.a", ShortBaseName); break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 90) /* redirect stuff */
- {
- mode = MODUS_REDIRECT;
- switch(args.special)
- {
- case 80: sprintf(filename, "%s_pragmas.h", ShortBaseName); break;
- case 81: sprintf(filename, "%s_lib.h", ShortBaseName); break;
- case 82: sprintf(filename, "%s.h", ShortBaseName); break;
- case 83: sprintf(filename, "%s_protos.h", ShortBaseName); break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 100) /* multifile stuff */
- {
- Flags |= FLAG_SINGLEFILE;
- switch(args.special)
- {
- case 90:
- if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
- mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
- break;
- case 91:
- if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
- mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
- break;
- case 92:
- if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
- mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
- break;
- case 93:
- if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
- mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
- break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 110) /* PPC lvo's */
- {
- switch(args.special)
- {
- case 100: case 101: mode = MODUS_LVOPPC+args.special-100;
- sprintf(filename, "%s_lib.i", ShortBaseName);
- break;
- case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
- Flags |= FLAG_ABIV4;
- sprintf(filename, "%s_lib.i", ShortBaseName);
- break;
- case 103: mode = MODUS_LVOLIB;
- sprintf(filename, "%slvo.o", ShortBaseName);
- break;
- case 107: mode = MODUS_LVOLIB;
- Flags |= FLAG_ABIV4;
- sprintf(filename, "%slvo.o", ShortBaseName);
- break;
- case 102: mode = MODUS_LVOLIBPPC;
- sprintf(filename, "%slvo.o", ShortBaseName); break;
- case 106: mode = MODUS_LVOLIBPPC;
- Flags |= FLAG_ABIV4;
- sprintf(filename, "%slvo.o", ShortBaseName); break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 120) /* different files */
- {
- if(args.mode > 0 && args.mode < 4)
- callmode = args.mode - 1;
-
- switch(args.special)
- {
- case 110: mode = MODUS_FD;
- sprintf(filename, "%s_lib.fd", ShortBaseName);
- if(Flags & FLAG_SORTED) /* is not possible to use here */
- {
- DoError(ERR_SORTED_SFD_FD, 0);
- Flags &= (~FLAG_SORTED);
- }
- break;
- case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
- sprintf(filename, "%s_protos.h", ShortBaseName);
- break;
- case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
- sprintf(filename, "%s_lib.sfd", ShortBaseName);
- if(callmode == 1)
- {
- callmode = 2;
- DoError(ERR_ONLYTAGMODE_NOTALLOWED, 0);
- }
-
- if(Flags & FLAG_SORTED) /* is not possible to use here */
- {
- DoError(ERR_SORTED_SFD_FD, 0);
- Flags &= (~FLAG_SORTED);
- }
- break;
- default: mode = MODUS_ERROR; break;
- }
- }
- else if(args.special < 130) /* auto libopen files */
- {
- switch(args.special)
- {
- case 120: mode = MODUS_GENAUTO;
- sprintf(filename, "%s_autoopenlib.c", ShortBaseName);
- break;
- case 121: mode = MODUS_GENAUTO+(args.special-120);
- sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
- break;
- default: mode = MODUS_ERROR; break;
- }
- }
-
- if(Flags & FLAG_SORTED)
- SortFDList();
-
- if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SINGLEFILE)) /* is not possible to use both */
- {
- DoError(ERR_COMMENT_SINGLEFILE, 0);
- Flags &= (~FLAG_SORTED);
- }
-
- if(!mode || mode == MODUS_ERROR)
- printhelp();
-
- /* These modes need BaseName always. */
- if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
- mode == MODUS_STUBCODE || mode == MODUS_EMODULE || (mode >= MODUS_GENAUTO &&
- mode <= MODUS_GENAUTO+9)))
- {
- DoError(ERR_MISSING_BASENAME, 0);
- exit(20);
- }
-
- if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
- {
- HEADER = mygetfile(args.header, &headersize);
- args.header = 0;
- }
-
- if(!(Flags & FLAG_SINGLEFILE))
- {
- if(!OpenDest(filename))
- exit(20);
- }
-
- /* from here mode is used as return result */
- if(mode >= MODUS_GENAUTO)
- mode = CreateGenAuto(filename, mode-MODUS_GENAUTO);
- else if(mode >= MODUS_LVOPPC)
- mode = CreateLVOFilePPC(mode-MODUS_LVOPPC);
- else if(mode >= MODUS_VBCC)
- mode = CreateVBCC(mode-MODUS_VBCC, callmode);
- else if(mode >= MODUS_INLINE)
- mode = CreateInline(mode-MODUS_INLINE, callmode);
- else if(mode >= MODUS_PROTO)
- mode = CreateProtoFile(mode-MODUS_PROTO+1);
- else if(mode >= MODUS_LVO)
- mode = CreateLVOFile(mode-MODUS_LVO+1);
- else if(mode == MODUS_SFD)
- mode = CreateSFD(callmode);
- else if(mode == MODUS_CLIB)
- mode = CreateClib(callmode);
- else if(mode == MODUS_FD)
- mode = CreateFD();
- else if(mode == MODUS_LVOLIBPPC)
- mode = CreateLVOLibPPC();
- else if(mode == MODUS_VBCCMORPHCODE)
- mode = CreateVBCCMorphCode(callmode);
- else if(mode == MODUS_VBCCMORPHTEXTSF) /* single files */
- mode = CallFunc(callmode, "\n%s", FuncVBCCMorphText);
- else if(mode == MODUS_VBCCWOSINLINE)
- mode = CreateVBCCInline(1);
- else if(mode == MODUS_VBCCWOSTEXTSF) /* single files */
- mode = CallFunc(callmode, "\n%s", FuncVBCCWOSText);
- else if(mode == MODUS_VBCCPUPTEXTSF) /* single files */
- mode = CallFunc(callmode, "\n%s", FuncVBCCPUPText);
- else if(mode == MODUS_ASMTEXTSF) /* single files */
- mode = CallFunc(callmode, "\n%s", FuncAsmText);
- else if(mode == MODUS_REDIRECT)
- mode = CreateProtoRedirect();
- else if(mode == MODUS_EMODULE)
- mode = CreateEModule(Flags & FLAG_SORTED);
- else if(mode == MODUS_LVOLIB)
- mode = CreateLVOLib();
- else if(mode == MODUS_VBCCPUPLIB)
- mode = CreateVBCCPUPLib(callmode);
- else if(mode == MODUS_VBCCINLINE)
- mode = CreateVBCCInline(0);
- else if(mode == MODUS_PASCAL)
- mode = CreateFPCUnit();
- else if(mode == MODUS_BMAP)
- mode = CreateBMAP();
- else if(mode == MODUS_PROTOPOWER)
- mode = CreateProtoPowerUP();
- else if(mode == MODUS_SASPOWER)
- mode = CreateSASPowerUP(callmode);
- else if(mode == MODUS_CSTUB)
- mode = CreateCSTUBSFile();
- else if(mode == MODUS_PRAGMA)
- mode = CreatePragmaFile(amicall, libcall, amitags, libtags, pragmode);
- else if(mode == MODUS_LOCALDATA)
- mode = CreateLocalData(filename, callmode);
- else if(mode) /* MODUS_STUBTEXT starts with 1 */
- mode = CreateAsmStubs(mode, callmode);
-
- CloseDest(filename);
-
- if(!mode)
- {
- DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
- exit(20);
- }
- free(tempbuf);
- }
-
- return 0;
- }
-
-