1 static const char version
[] = "$VER: fd2pragma 2.164 (15.02.2003) by Dirk Stoecker <stoecker@epost.de>";
2 /* #define FD2PRAGMA_READARGS */
3 /* #define FD2PRAGMA_AMIGA */
5 /* #define DEBUG_OLD */
12 Description: creates pragmas files, lvo files, ...
16 1.2 : added pragmas for the Dice compiler. Available via switch "Dice".
17 added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
18 turn on the default (except that Maxon expects pragma files to be
19 called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
20 Dice, except that SAS supports the pragma tagcall.
21 2.0 : Added support for tag functions. See the docs for details.
22 Author until this version:
25 72555 Metzingen (Germany)
27 2.1 19.08.96 : now made by SDI, added correct __MAXON__ support and
28 support for StormC++, added auto recognition of tagcall functions
29 changed the CLI interface completely
30 2.2 21.08.96 : fixed a lot of errors, added debug code
31 2.3 22.08.96 : little changes
32 2.4 24.08.96 : added proto-file creation
33 2.5 25.08.96 : added syscall and fix for functions ending in ...DMA
34 2.6 26.08.96 : fixed some errors, added CLIB parameter (used later for
36 2.7 01.09.96 : added correct Storm definition, added CLIB scan
37 2.8 02.09.96 : added assembler stub functions, added first ASM-stub code
38 2.9 04.09.96 : added Comment-Support
39 2.10 05.09.96 : changed CSTUB creation a bit
40 2.11 07.09.96 : speeded up output, reduced number of strndup calls
41 2.12 26.09.96 : pressing CTRL-C in early startup brought a wrong error
43 2.13 30.09.96 : made RegNames field to RegNames string - shorter Exe-file
44 2.14 01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
45 2.15 13.10.96 : corrected an error text
46 2.16 14.10.96 : added correct comment support and PRIVATE option
47 2.17 19.10.96 : now Maxon-compiled in Small data mode
48 2.18 22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
49 the texts, again SAS compiled
50 2.19 26.10.96 : added option to create FD files out of pragma files,
51 reworked a lot in the source
52 2.20 27.10.96 : fixed errors of previous version
53 2.21 28.10.96 : fixed error in CLIB scan
54 2.22 27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
55 bug in Tag function stubs
56 2.23 06.12.96 : lib and stub creation still was wrong
57 2.24 31.12.96 : formed stub libs matching C++ file names, corrected CLIB
59 2.25 04.01.97 : added HEADER option (I was asked for)
60 2.26 05.01.97 : added HEADER scan (in old file) and auto inserting
61 2.27 10.01.97 : stub functions missed register saving, outfuncs skip now,
62 when error occured (makes lots of error checking obsolete)
63 2.28 11.01.97 : forgot to add offset made by register saving
64 2.29 18.01.97 : now libtags and amitags defines only, when at least 1
66 2.30 13.02.97 : added local library base functions, rearranged SPECIAL
67 options, fixed some bugs
68 2.31 15.02.97 : corrected bugs inserted in previous version
69 2.32 16.02.97 : and again bug fixes, still didn't work
70 2.33 18.02.97 : corrected texts, added SPECIAL 28
71 2.34 25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
72 2.35 26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
73 2.36 29.03.97 : corrected *tagcall scan a bit
74 2.37 20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
75 2.38 01.07.97 : fixed ##end handling
76 2.39 20.07.97 : added better proto file (__GNUC__ inline and pragma call),
78 2.40 24.11.97 : added new basenames to the list (devices and resources),
79 added tag-exception name checking (dos, utility libraries)
80 2.41 27.11.97 : fixed little bug with private functions, CSTUBS now
81 special option and no longer commandline arg, SPECIAL 10-15 got
83 2.42 28.11.97 : Added two new warnings for CLIB
84 2.43 12.12.97 : faster FD file scan, one new warning
85 2.44 19.12.97 : fixed MODE settings for SPECIAL 15,16
86 2.45 30.01.98 : added function recognition, included inline creation,
87 inline stuff is based on fd2inline 1.11 (incomplete)
88 2.46 31.01.98 : continued inline stuff, fixed clib functions
89 2.47 05.02.98 : completed inline stuff, added alias names for dos functions
90 2.48 06.02.98 : changed Func interface - flags instead of tagmode
91 2.49 10.02.98 : fixed inline generation a bit, added SORTED argument,
92 RegNames got strings again
93 2.50 11.02.98 : bug-fixes, still did not work completely, hopefully got
95 2.51 12.02.98 : and bug-fixes again :-(
96 2.52 15.02.98 : changed sorting order of arguments
97 2.53 20.02.98 : some code style changes
98 2.54 25.02.98 : added SMALLDATA model, removed 5 global variables (better
99 style), stub libs use MOVEM when possible, own MemRemember function
100 2.55 26.02.98 : bug fixes
101 2.56 15.03.98 : added FPU support
102 2.57 17.03.98 : added NOFPU keyword
103 2.58 19.03.98 : little fixes
104 2.59 20.03.98 : added enum and external type definitions defines
105 2.60 22.03.98 : added external types file scan
106 2.61 23.03.98 : fixed SAS flibcall, added FPU stubs
107 2.62 28.03.98 : bug fix with NOFPU and new option FPUONLY, total new clib
109 2.63 29.03.98 : really lots of bug fixes, There are so much problems.
110 A better definition format would have been wonderful.
111 2.64 05.04.98 : bug fixes
112 2.65 07.04.98 : fixed Enforcer hit
113 2.66 08.04.98 : bug fix with type detection
114 2.67 20.04.98 : added GNU-only stuff
115 2.68 28.04.98 : SPECIAL 8 defaults to SAS-C names now
116 2.69 25.05.98 : added PowerUP stuff support
117 2.70 28.05.98 : added SAS PowerUP stuff, fixed error with function
118 detection in CLIB scan
119 2.71 30.05.98 : added PowerUP Inlines
120 2.72 12.06.98 : sorting turns of COMMENT now
121 2.73 05.07.98 : added first FPC stuff, added HEADER to PowerUP stuff,
122 added PASCAL header scan
123 2.74 06.07.98 : finished FPC stuff
124 2.75 07.07.98 : bug fixes for FPC stuff
125 2.76 09.07.98 : style changes for FPC stuff, bug fixes
126 2.77 11.07.98 : hopefully last FPC bug removed
127 2.78 23.07.98 : style changes and bug fixes for FPC stuff, more comments
128 2.79 10.08.98 : bug fix, when TO was used with a directory, clib got
129 wrong path if it was a relative path description
130 2.80 16.08.98 : now prints better error when filopen failed
131 2.81 26.10.98 : added BMAP files for BASIC, CODE needs to use large mode
133 2.82 28.10.98 : optimizations and bug fixes
134 2.83 31.12.98 : fixed powerup stuff a bit
135 2.84 05.01.99 : fixed bug in Lib creation, when Dx/Ax and FPx were mixed
136 2.85 06.01.99 : added recognition of names ending in MESA, added notagcall
137 comment support, void functions no longer can be tagcall
138 2.86 10.01.99 : added BGUI special funcs, fixed bug in SPECIAL 42 code
139 2.87 12.01.99 : added asm-text (SECTION), moved 12-17 to 13-18
140 2.88 17.01.99 : better type detection, added some more basenames, some
141 little bug fixes, new makefile reduces file size a lot
142 2.89 17.07.99 : added union support
143 2.90 12.11.99 : added new motorola syntax, opt040 and vbcc inlines
144 2.91 13.11.99 : Now supports changes in OS3.5 includes, why the hell must
145 such changes be? I thought new includes will bring cleanup and not
146 cleandown. And the reported bugs are still unfixed, but there are
148 2.92 14.11.99 : added PPC-WOS library text and code, FD-creation moved from
149 80 to 200 (now finally! - there should be enough free number space),
150 added VBCC-PUP text generation
151 2.93 15.11.99 : added CheckError function, moved DisplayInfoHandle to
152 types definition file
153 2.94 16.11.99 : added first VBCC-PowerUP-Lib production stuff, only ELF
155 2.95 17.11.99 : finished PowerUP stub stuff, startet PPC-ABI stuff
156 2.96 18.11.99 : little bug fixes
157 2.97 19.11.99 : added SECTION keyword, moved 11-18 to 12-17, ahh 3 releases
158 more and we get an anniversary, my first program using third revision
160 2.98 20.11.99 : added VBCC-WOS-Code for PPC libs
161 2.99 25.11.99 : bug fixes
162 2.100 17.02.00 : fixed bug for VBCC inlines
163 2.101 29.02.00 : fixed name for VBCC inlines
164 2.102 13.03.00 : added new style GCC inlines
165 2.103 21.03.00 : bug fixed, SPECIAL 35 has VBCC stuff now.
166 2.104 25.03.00 : fixed path lock problem
167 2.105 11.04.00 : library HUNK_UNIT get functionname now
168 2.106 13.07.00 : added E-Modules
169 2.107 06.08.00 : removed VBCC inline support from 35 and moved it to 38, 35
170 does now skip pragma/inline files for VBCC
171 2.108 18.08.00 : added new ppc modification proto file 39, modified protos a
172 bit, support for register types and function pointer args, int got
173 internally type CPP_TYPE_INT
174 2.109 19.08.00 : bug fixes
175 2.110 24.08.00 : fixed SPECIAL 7,40-44, added SPECIAL 80-83
176 2.111 31.08.00 : bug fixes
177 2.112 03.09.00 : FD2Pragma.types scanner no longer accepts multi-word types.
178 2.113 29.12.00 : added extern keword support for return types.
179 2.114 07.01.01 : made FD2Pragma partly portable, removed 4 direct pragma arguments
180 2.115 14.01.01 : lots of bug fixes, renamed from FD2Pragma to fd2pragma
181 2.116 28.01.01 : added internal types, SPECIAL 90, NOCPPNAMES and bug fixes,
182 VBCC inlines fix for data in A-regs
183 2.117 04.02.01 : changed NOCPPNAMES to ONLYCNAMES, added HUNKNAME, LocCode is
184 portable, added BASENAME, added VBCCWOSInlines
185 2.118 07.02.01 : added destination file printout, LIBTYPE, fixes VBCC-PUP-Code
186 2.119 11.02.01 : bug fixes
187 2.120 17.02.01 : added NOPPCREGNAME, bug fixes
188 2.121 04.03.01 : added MorphOS text
189 2.122 11.03.01 : little bug fixes
190 2.123 03.04.01 : now uses EXT_DEXT16 instead of EXT_REF16 also for 68k files
191 2.124 08.04.01 : bug fixes, added MorphOS binary mode, finally full portable
192 2.125 28.04.01 : added LVO's for PPC, started support for SFD format
193 2.126 29.05.01 : fixed PPC LVO's, removed STORMFD Option (auto detection),
194 now handles up to 5 alias names, finished SFD format read, added FD
195 creation, added keyword checks for argument names, lots of optimizations
196 and fixes, which came in hand with SFD inclusion.
197 Thanks Olaf Barthel for making the SFD stuff possible.
198 2.127 30.04.01 : private comments are skipped now, finished SFD production,
199 fixed bugs, removed SPECIAL 8 redirect (is replaced by 80-83)
200 2.128 01.05.01 : bug fixes
201 2.129 03.06.01 : included support for files previous made by vbcc genauto tool
202 2.130 04.06.01 : bug fixes in genauto stuff
203 2.131 11.06.01 : newer types handle cia now correct
204 2.132 27.06.01 : fixed crash caused by illegal interpretation of ANSI-C :-)
205 2.133 28.06.01 : added VOIDBASE argument
206 2.134 01.07.01 : added MorphOS types, fixed PowerUp stuff
207 2.135 28.07.01 : added VBCC inline varargs support
208 2.136 30.07.01 : fixed VBCC inline varargs
209 2.137 18.11.01 : little bug-fix
210 2.138 30.11.01 : fixed CLIB scanning (now a preparser cleans the file a lot)
211 2.139 13.12.01 : fixed ==libname scan and xvsBase
212 2.140 21.12.01 : fixed some uint32 in created files, which have been wrongly
213 introduced in 2.1xx versions when making tool portable
214 2.141 04.01.02 : fixed problem with multiple pointer function args like in
215 "void (**func)(void)"
216 2.142 07.01.02 : started new direct inline types 46 and 47.
217 2.143 08.01.02 : Fixed warnings, bugs, card.resouce entry and added
218 ==copyright directive
219 2.144 09.01.02 : Fixed MUI varargs inlines
220 2.145 03.03.02 : Some bug fixes
221 2.146 20.05.02 : one little bug fix, added support for missing empty () in
223 2.147 01.05.02 : now continues when detecting no fd-arg name
224 2.148 09.06.02 : fixed problem with MorphOS stubs, added AUTOHEADER keyword,
225 added auto type defaults to int, fixed bug with STACK type
226 2.149 24.06.02 : fixed lots of problems found when converting amissl includes
227 2.150 08.08.02 : fixed inline files a bit
228 2.151 31.08.02 : fixed SPECIAL 46 files (error when no args, but return value)
229 2.152 01.09.02 : bug-fix with SPECIAL 47
230 2.153 11.09.02 : modified SPECIAL 46 varargs on request of Sebastian Bauer
232 2.154 03.10.02 : added VBCC MorphOS inlines (SPECIAL 122). Thanks Frank Wille
234 2.155 04.10.02 : optimized VBCC MorphOS text (SPECIAL 93), fixed VBCC MorphOS
236 2.156 06.10.02 : added warning about obsolete types, fixed VBCC MorphOS Code
238 2.157 12.10.02 : Fixed CLIB scan problem
239 2.158 19.10.02 : added CLIB define in SPECIAL 46
240 2.159 16.11.02 : bugfix with SPECIAL 46 varargs redefine
241 2.160 04.12.02 : fixed bug in MorphOS-vbcc code
242 2.161 15.12.02 : now no longer includes clib files for GCC, the GCC inlines
243 include the needed include lines directly
244 2.162 26.01.03 : bug fixes, added updated fpc code made by Nils Sjöholm (it
245 is not that complicated to do fixes yourself, fd2pragma's inner
246 structure is really easy)
247 2.163 28.01.03 : little fixes
248 2.164 15.02.03 : fixed DirectInline for GCC mode, changed FPC layout
251 /* A short note, how fd2pragma works.
252 Working mode for SPECIAL 200 is a bit different!
253 The main function parses arguments. Switches are converted into FLAG_XXX
254 values and stored in global "Flags" or "Flags2" variable. SPECIAL numbers
255 are parsed and are used to call a CreateXXX function, with its interface
256 depending on the need of arguments (Some have 2, some none, ...). Before
257 SPECIAL arguments are parsed, fd2pragma loads (S)FD file and scans it using
258 ScanFDFile(). If SORTED is specified, the list gets sorted nearly directly
259 afterwards. IF CLIB argument is given, the clib file is scanned after FD file
260 and a clib list is created. Now SPECIAL is parsed and mode is set to any of
261 the MODUS_XXX values. Also the destination file name is created if not given.
262 The destination file is opened now. The mode variable is used to determine
263 the correct CreateXXX function, which is called afterwards. This function
264 produces file headers and stuff like that and calls CallFunc to process each
265 FD entry. CallFunc gets 3 arguments. First the workmode (TAG, NORMAL, BOTH).
266 Second the comment method (for C it is "/%s *\x2F\n", for ASM it is "\n%s",
267 no comment is reached with 0 argument). The last is most important. It is the
268 function pointer to a function creating the entries. These functions have
269 always the same interface and are called through CallFunc only! They create
270 an entry for the specified function (e.g. FD entry). Parsing special
271 functions, adding comments, checking for tag-functions, ... is done by
272 CallFunc. It is no problem to call CallFunc multiple with different function
273 pointers (as is done for SPECIAL 6 pragmas).
274 This is also the method if information abount the type or number of functions
275 is needed somewhere in the begin out the output file. A special function to
276 collect this data needs to be started before doing real output. Althought I
277 do not like it much, global variables or flags can be used to store that
280 The functions can use DoOutput to output texts in printf style or
281 DoOutputDirect to output all data in fwrite style. Buffering is done
284 fd2pragma has its own memory managment. All memory must be allocated using
285 AllocListMem and is freed automatically. This is especially useful for
286 DupString function, which is used in FD and CLIB scanner.
288 Normally this source-file is to big and should be splitted into different
289 files compiled alone and linked together. :-) It takes about 20 minutes to
290 compile it on my Amiga system with optimizations turned on.
300 /* These are the only allowed variable types of all related programs! */
301 typedef signed char int8
; /* signed 8 bit */
302 typedef unsigned char uint8
; /* unsigned 8 bit */
303 typedef signed short int int16
; /* signed 16 bit */
304 typedef unsigned short int uint16
; /* unsigned 16 bit */
305 typedef signed long int int32
; /* signed 32 bit */
306 typedef unsigned long int uint32
; /* unsigned 32 bit */
307 typedef float fl32
; /* 32 bit IEEE float value */
308 typedef double fl64
; /* 64 bit IEEE double value */
309 typedef char string
; /* the string datatype [e.g. one character of string!] */
310 typedef char * strptr
; /* and an string pointer */
312 #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
313 (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
314 #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
315 #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
316 (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
317 #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
319 #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
320 #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
321 #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
322 #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
324 #define TEXT_SAS "__SASC" /* verified */
325 #define TEXT_SAS_60 "__SASC_60" /* verified */
326 #define TEXT_MAXON "__MAXON__" /* verified */
327 #define TEXT_STORM "__STORM__" /* verified */
328 #define TEXT_DICE "_DCC" /* in 2.0 code */
329 #define TEXT_AZTEC "AZTEC_C" /* verified */
330 #define TEXT_GNUC "__GNUC__" /* verified */
331 #define TEXT_VBCC "__VBCC__" /* verified */
333 #define TEMPSIZE 20480
335 #define FLAG_EXTERNC (1<< 0) /* add externc statements */
336 #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
337 #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
338 #define FLAG_PRIVATE (1<< 3) /* also use private functions */
339 #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
340 #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
341 #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
342 #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
343 #define FLAG_DONE (1<< 8) /* destination file is not empty */
344 #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
345 #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
346 #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
347 #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
348 #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
349 #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
350 #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
351 #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
352 #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
353 #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
354 #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
355 #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
356 #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
357 #define FLAG_STORMGCC (1<<22) /* special workaround for StormGCC */
358 #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
359 #define FLAG_MORPHOS (1<<24) /* create MorphOS files */
360 #define FLAG_SORTED (1<<25) /* sort the functions by name */
361 #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
362 #define FLAG_SINGLEFILE (1<<27) /* create single files */
363 #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
364 #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
365 #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
366 #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
368 #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
369 #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
370 #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
371 #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
372 #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
373 #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
374 #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
375 #define FLAG2_VOIDBASE (1<< 7) /* library base should be of type "void *" */
376 #define FLAG2_INLINEMAC (1<< 8) /* use inline macro instead of inline function */
377 #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
378 #define FLAG2_PRELIB (1<<10) /* MorphOS gate PRELIB flag */
379 #define FLAG2_POSTLIB (1<<11) /* MorphOS gate POSTLIB flag */
380 #define FLAG2_REGLIB (1<<12) /* MorphOS gate REGLIB flag */
381 #define FLAG2_OLDVBCC (1<<13) /* old VBCC style */
382 #define FLAG2_SMALLTYPES (1<<14) /* allow small data types */
383 #define FLAG2_AUTOHEADER (1<<15) /* creates auto generated header */
385 #define FUNCFLAG_NORMAL (1<<0) /* normal function */
386 #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
387 #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
388 #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
390 /* Different modes the main program uses, one for each different file
391 type (except for those done with one function and flag settings). */
392 #define MODUS_STUBTEXT 1
393 #define MODUS_STUBCODE 2
394 #define MODUS_LOCALDATA 3
395 #define MODUS_PRAGMA 4
396 #define MODUS_CSTUB 5
397 #define MODUS_SASPOWER 6
398 #define MODUS_PROTOPOWER 7
400 #define MODUS_PASCAL 9
401 #define MODUS_VBCCINLINE 10
402 #define MODUS_VBCCPUPLIB 11
403 #define MODUS_LVOLIB 12
404 #define MODUS_EMODULE 13
405 #define MODUS_REDIRECT 14
406 #define MODUS_ASMTEXTSF 15
407 #define MODUS_VBCCPUPTEXTSF 16
408 #define MODUS_VBCCWOSTEXTSF 17
409 #define MODUS_VBCCWOSINLINE 18
410 #define MODUS_VBCCMORPHTEXTSF 19
411 #define MODUS_VBCCMORPHCODE 20
412 #define MODUS_LVOLIBPPC 21
414 #define MODUS_CLIB 23
416 #define MODUS_GATESTUBS 25
417 #define MODUS_VBCCMORPHINLINE 26
418 #define MODUS_LVO 50 /* and 51 and 52 and 53 */
419 #define MODUS_PROTO 60 /* and 61 to 69 */
420 /* new protos start with 90, but are added to MODUS_PROTO ! */
421 #define MODUS_INLINE 80 /* and 81 to 86 */
422 #define MODUS_VBCC 90 /* and 91 to 94 */
423 #define MODUS_LVOPPC 100 /* and 101 */
424 #define MODUS_GENAUTO 110 /* and 111 to 113 */
425 #define MODUS_ERROR 200
432 /* call types for CallFunc */
433 #define TAGMODE_NORMAL 0 /* produce normal functions only */
434 #define TAGMODE_TAGS 1 /* produce only tag functions */
435 #define TAGMODE_BOTH 2 /* produce both types */
437 /* types specifying name method for pragma creation */
438 #define PRAGMODE_PRAGLIB 1
439 #define PRAGMODE_PRAGSLIB 2
440 #define PRAGMODE_PRAGSPRAGS 3
441 #define PRAGMODE_NONE 4
443 #define BIAS_START 30 /* the library start offset */
444 #define BIAS_OFFSET 6 /* value to switch from one to next function */
446 #ifndef FD2PRAGMA_AMIGA
447 #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
450 #define EXTTYPESFILE "fd2pragma.types"
452 #ifndef EXTTYPESFILE2
453 #ifdef FD2PRAGMA_AMIGA
454 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
456 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
460 #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
462 #define FDFILEEXTENSION "_lib.fd"
463 #define SFDFILEEXTENSION "_lib.sfd"
465 static const strptr RegNames
[] = {
466 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
467 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
468 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
471 static const strptr RegNamesUpper
[] = {
472 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
473 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
474 "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
478 REG_D0
, REG_D1
, REG_D2
, REG_D3
, REG_D4
, REG_D5
, REG_D6
, REG_D7
,
479 REG_A0
, REG_A1
, REG_A2
, REG_A3
, REG_A4
, REG_A5
, REG_A6
, REG_A7
,
480 REG_FP0
, REG_FP1
, REG_FP2
, REG_FP3
, REG_FP4
, REG_FP5
, REG_FP6
, REG_FP7
483 #define MAXREG 24 /* maximum registers of 68K */
484 #define MAXREGNF 16 /* maximum register number without float regs */
485 #define UNDEFREGISTER 255 /* for type scanner */
497 struct ShortList
*Next
;
500 struct ShortListRoot
{
501 struct ShortList
*First
;
502 struct ShortList
*Last
;
506 #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
507 #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
508 #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
509 #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
510 #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
511 #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
512 #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
513 #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
514 #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
515 #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
516 #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
517 #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
518 #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
519 #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
520 #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
521 #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
528 #define NUMALIASNAMES 5
531 struct ShortList List
;
536 struct Pragma_AliasName
* AliasName
[NUMALIASNAMES
]; /* possible alias names */
537 uint16 NumArgs
; /* register numbers */
538 uint16 CallArgs
; /* argument number in fd file */
542 struct AmiArgs Args
[MAXREGPPC
];
546 struct ShortList List
;
551 uint8 Private
; /* is a flag only */
555 struct ShortList List
;
560 struct ShortList List
;
561 struct ShortListRoot Data
; /* contains list of PragData */
566 struct ShortList List
;
567 struct ShortListRoot Name
;
571 uint8 ArgReg
[MAXREG
];
578 uint32 Mode
; /* 0 = Normal, != 0 is TagName */
580 uint8 ArgReg
[MAXREG
];
583 /* These CPP types match the strings used for CPP name creation. The
584 defines are used both for name creation and type specification. */
585 #define CPP_TYPE_VOID 'v' /* void, VOID */
586 #define CPP_TYPE_BYTE 'c' /* char, int8 */
587 #define CPP_TYPE_WORD 's' /* short, int16 */
588 #define CPP_TYPE_LONG 'j' /* long, int32 */
589 #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
590 #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
591 #define CPP_TYPE_INT 'i' /* int */
592 #define CPP_TYPE_STRUCTURE 0
593 #define CPP_TYPE_VARARGS 'e'
595 /* These types are for string creation only. */
596 #define CPP_TYPE_ENUM 'E'
597 #define CPP_TYPE_CONST 'C'
598 #define CPP_TYPE_FUNCTION 'F'
599 #define CPP_TYPE_POINTER 'P'
600 #define CPP_TYPE_UNSIGNED 'U'
601 #define CPP_TYPE_FUNCEND 'p'
602 #define CPP_TYPE_REGISTER 'r'
604 /* Some flags to be used in CPP_NameType->Flags. */
605 #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
606 #define CPP_FLAG_CONST (1<<1) /* type is const */
607 #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
608 #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
609 #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
610 #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
611 #define CPP_FLAG_UNION (1<<6) /* it is a union */
612 #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
613 #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
614 #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
615 #define CPP_FLAG_TYPEDEFNAME (1<<10) /* name is created from typedef */
616 #define CPP_FLAG_ARRAY (1<<11) /* this type is an array */
617 /* STRPTR is defined different under C and CPP -> I have to create two
618 names, one time unsigned char *, one time signed char *, when somewhere
621 #define COPYCPP_PASSES 4
623 struct CPP_NameType
{ /* structure to describe a argument type */
624 strptr StructureName
; /* if a structure or enum only */
625 strptr FuncArgs
; /* arguments of function - unterminated */
626 strptr TypeStart
; /* start of this type */
627 strptr Replace
; /* replacement of type for SFD files */
628 strptr Unknown
; /* unknown type handled as int */
629 strptr FunctionName
; /* Argument name of function argument */
630 struct ClibData
*FuncPtr
; /* if it is a function pointer */
631 uint16 StructureLength
; /* length of the structure name */
632 uint16 ArgsLength
; /* length of FuncArgs */
633 uint16 TypeLength
; /* length of this type */
634 uint16 FullLength
; /* length of complete type */
635 uint16 PointerDepth
; /* number of * in type */
636 uint16 FuncPointerDepth
; /* number of * in function pointer */
637 uint16 Flags
; /* see above flags */
638 uint8 Type
; /* see above defines */
639 uint8 Register
; /* register number */
642 struct ClibData
{ /* structure to describe data in CLIB file */
643 struct ClibData
* Next
; /* The next entry in this list */
644 strptr FuncName
; /* name of the function */
645 struct CPP_NameType ReturnType
; /* data for return type */
646 struct CPP_NameType Args
[MAXREGPPC
+1]; /* data for argument types */
647 uint16 NumArgs
; /* number of arguments */
650 struct CPP_ExternNames
{ /* structure for EXTTYPESFILE data */
651 struct CPP_ExternNames
* Next
; /* The next entry in this list */
652 strptr Type
; /* The unknown type */
653 struct CPP_NameType NameType
; /* The replacement */
656 struct CPP_TypeField
{ /* structure for internal defined types */
657 strptr Text
; /* name of the type */
658 uint16 Length
; /* length of the name string */
659 uint16 Flags
; /* CPP_FLAG flags */
660 uint8 Type
; /* CPP_TYPE value */
664 struct CPP_Unknown
*Next
;
668 struct Proto_LibType
{ /* structure to define structure type of base vars */
669 strptr BaseName
; /* name of the library base */
670 strptr StructureName
; /* name of the structure to be used (maybe 0 for default) */
671 strptr LibraryName
; /* name of the library (maybe 0 for default method) */
672 strptr ShortBaseName
; /* short name of the library base */
675 struct Pragma_ExecpName
{ /* structure to specify special tagnames */
676 strptr FunctionName
; /* function name */
677 strptr TagName
; /* tag name to be used for this function */
678 }; /* TagName 0 is valid as well to disable tagfunctions */
680 struct Pragma_AliasName
{
686 #define NTP_NORMAL 0 /* no tags/args */
687 #define NTP_TAGS 1 /* TagFunction */
688 #define NTP_ARGS 2 /* ArgFunction */
689 #define NTP_UNKNOWN 3 /* CommentFunction */
692 struct ShortList List
;
693 uint32 Type
; /* set by OptimizeFDData */
704 /* EHF definitions! */
705 #define HUNK_PPC_CODE 0x4E9
706 #define HUNK_RELRELOC26 0x4EC
707 #define EXT_RELREF26 229
709 /* ------------------------------------------------------------------ */
710 /* A short set of ELF definitions, see pasm sources in vbcc release for an
711 more complete set of stuff or get elf documentation. These are needed for
712 VBCCPUPCode function. */
714 #define ELFDATA2MSB 2
715 #define EV_CURRENT 1 /* version information */
716 #define ET_REL 1 /* type information */
717 #define EM_POWERPC 20
719 #define SHT_NULL 0 /* inactive */
720 #define SHT_PROGBITS 1 /* program information */
721 #define SHT_SYMTAB 2 /* symbol table */
722 #define SHT_STRTAB 3 /* string table */
723 #define SHT_RELA 4 /* relocation */
725 #define SHF_ALLOC 0x2 /* needs memory when started */
726 #define SHF_EXECINSTR 0x4 /* executable instructions */
728 #define SHN_ABS 0xFFF1
743 #define STT_SECTION 3
745 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
746 #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
748 #define R_PPC_ADDR16_LO 4
749 #define R_PPC_ADDR16_HA 6
750 #define R_PPC_REL24 10
751 #define R_PPC_SDAREL16 32
754 string ar_name
[16]; /* name */
755 string ar_time
[12]; /* modification time */
756 string ar_uid
[6]; /* user id */
757 string ar_gid
[6]; /* group id */
758 string ar_mode
[8]; /* octal file permissions */
759 string ar_size
[10]; /* size in bytes */
760 string ar_fmag
[2]; /* consistency check */
763 /* AmigaOS hunk structure definitions */
764 #define HUNK_UNIT 999
765 #define HUNK_NAME 1000
766 #define HUNK_CODE 1001
767 #define HUNK_BSS 1003
768 #define HUNK_ABSRELOC32 1004
769 #define HUNK_EXT 1007
770 #define HUNK_SYMBOL 1008
771 #define HUNK_END 1010
772 #define HUNK_DREL16 1016
774 #define EXT_DEF 1 /* normal definition */
775 #define EXT_ABS 2 /* Absolute definition */
776 #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
777 #define EXT_DEXT16 134 /* 16 bit data relative reference */
778 /* ------------------------------------------------------------------ */
780 static struct Args args
= {0,0,0,0,6,0};
781 static struct InFile in
= {0,0,0};
782 static FILE * outfile
;
783 static struct ClibData
* clibdata
= 0;
784 static struct ShortListRoot AmiPragma
= {0,0,sizeof(struct AmiPragma
)},
785 Comment
= {0,0,sizeof(struct Comment
)},
786 Includes
= {0,0,sizeof(struct Include
)};
787 static struct CPP_ExternNames
*extnames
= 0;
788 static struct CPP_Unknown
*unknown
= 0;
789 static strptr BaseName
= 0; /* the correct basename */
790 static strptr ShortBaseName
= 0; /* the filename part of basename without Base */
791 static strptr ShortBaseNameUpper
= 0; /* like ShortBaseName, but upper case */
792 static strptr HEADER
= 0;
793 static strptr Copyright
= 0;
794 static strptr filenamefmt
= 0;
795 static strptr libtype
= 0;
796 static strptr libname
= 0;
797 static strptr defabi
= 0;
798 static strptr hunkname
= ".text";
799 static strptr datahunkname
= "__MERGED";
800 static strptr PPCRegPrefix
= "r";
801 static strptr IDstring
= 0;
802 static strptr prefix
= "";
803 static strptr subprefix
= "";
804 static strptr premacro
= "";
805 static uint8
* tempbuf
= 0;
806 static size_t headersize
= 0;
807 static uint32 Flags
= 0;
808 static uint32 Flags2
= 0;
809 static uint32 Output_Error
= 1; /* Output error occured when 0 */
810 static uint32 tagfuncs
= 0; /* are there some tagfuncs in FD */
811 static uint32 priority
= 5; /* priority for auto libopen */
812 static string filename
[255]; /* needed for filename */
814 static int32 LastBias
= 0; /* Only for E-Stuff, FD, SFD creation */
815 static uint8
* elfbufpos
= 0; /* Only for PPC-LVO Lib's */
816 static uint32 symoffset
= 0; /* Only for PPC-LVO Lib's */
817 static uint32 CurrentABI
= 0; /* Only for FD, SFD creation */
819 /* Prototypes for the functions */
820 static strptr
DupString(strptr
, size_t);
821 static strptr
AllocListMem(size_t);
822 static strptr
SkipBlanks(strptr
);
823 static strptr
SkipBlanksRet(strptr
);
824 static strptr
SkipName(strptr
);
825 static uint32
GetTypes(void);
826 static strptr
GetBaseType(void);
827 static strptr
GetBaseTypeLib(void);
828 static strptr
GetLibraryName(void);
829 static int32
MakeShortBaseName(void);
830 static uint32
OpenDest(strptr
);
831 static uint32
CloseDest(strptr
);
832 static uint32
MakeTagFunction(struct AmiPragma
*);
833 static void MakeLines(strptr
, uint32
);
834 static uint32
SpecialFuncs(void);
835 static void SortFDList(void);
836 static void AddAliasName(struct AmiPragma
*, struct Pragma_AliasName
*, uint32
);
837 static uint32
CheckNames(struct AmiPragma
*);
838 static uint32
ScanSFDFile(uint32
);
839 static uint32
ScanFDFile(void);
840 static int32
ScanTypes(strptr
, uint32
);
841 static void FindHeader(void);
842 static uint32
GetRegisterData(struct AmiPragma
*);
843 static uint16
GetFRegisterData(struct AmiPragma
*);
844 static uint32
OutputXDEF(uint32
, strptr
, ...);
845 static uint32
OutputXREF(uint32
, uint32
, strptr
, ...);
846 static uint32
OutputXREF2(uint32
, uint32
, uint32
, strptr
, ...);
847 static uint32
OutputSYMBOL(uint32
, strptr
, ...);
848 static uint8
* AsmStackCopy(uint8
*, struct AmiPragma
*, uint32
, uint32
);
849 /* ------------------------------------------------------------------ */
850 static void DoError(uint32
, uint32
, ...);
851 static uint32
CheckError(struct AmiPragma
*, uint32
);
852 static uint32
DoOutputDirect(void *, size_t);
854 #if defined(__GNUC__)
855 static uint32
DoOutput(strptr
, ...) __attribute__ ((format(printf
, 1, 2)));
857 static uint32
DoOutput(strptr
, ...);
859 /* ------------------------------------------------------------------ */
860 static struct ShortList
*NewItem(struct ShortListRoot
*);
861 static struct ShortList
*RemoveItem(struct ShortListRoot
*, struct ShortList
*);
862 static void AddItem(struct ShortListRoot
*, struct ShortList
*);
863 /* ------------------------------------------------------------------ */
864 typedef uint32 (*FuncType
)(struct AmiPragma
*, uint32
, strptr
);
866 uint32
FuncAMICALL (struct AmiPragma
*, uint32
, strptr
);
867 uint32
FuncLIBCALL (struct AmiPragma
*, uint32
, strptr
);
868 uint32
FuncAsmText (struct AmiPragma
*, uint32
, strptr
);
869 uint32
FuncAsmCode (struct AmiPragma
*, uint32
, strptr
);
870 uint32
FuncCSTUBS (struct AmiPragma
*, uint32
, strptr
);
871 uint32
FuncLVOXDEF (struct AmiPragma
*, uint32
, strptr
);
872 uint32
FuncLVO (struct AmiPragma
*, uint32
, strptr
);
873 uint32
FuncLVOPPCXDEF (struct AmiPragma
*, uint32
, strptr
);
874 uint32
FuncLVOPPC (struct AmiPragma
*, uint32
, strptr
);
875 uint32
FuncLVOPPCBias (struct AmiPragma
*, uint32
, strptr
);
876 uint32
FuncLVOPPCName (struct AmiPragma
*, uint32
, strptr
);
877 uint32
FuncLVOLib (struct AmiPragma
*, uint32
, strptr
);
878 uint32
FuncLocCode (struct AmiPragma
*, uint32
, strptr
);
879 uint32
FuncLocText (struct AmiPragma
*, uint32
, strptr
);
880 uint32
FuncInline (struct AmiPragma
*, uint32
, strptr
);
881 uint32
FuncInlineDirect (struct AmiPragma
*, uint32
, strptr
);
882 uint32
FuncInlineNS (struct AmiPragma
*, uint32
, strptr
);
883 uint32
FuncPowerUP (struct AmiPragma
*, uint32
, strptr
);
884 uint32
FuncFPCUnit (struct AmiPragma
*, uint32
, strptr
);
885 uint32
FuncFPCType (struct AmiPragma
*, uint32
, strptr
);
886 uint32
FuncFPCTypeTags (struct AmiPragma
*, uint32
, strptr
);
887 uint32
FuncFPCTypeTagsUnit (struct AmiPragma
*, uint32
, strptr
);
888 uint32
FuncBMAP (struct AmiPragma
*, uint32
, strptr
);
889 uint32
FuncVBCCInline (struct AmiPragma
*, uint32
, strptr
);
890 uint32
FuncVBCCWOSInline (struct AmiPragma
*, uint32
, strptr
);
891 uint32
FuncVBCCMorphInline (struct AmiPragma
*, uint32
, strptr
);
892 uint32
FuncVBCCWOSText (struct AmiPragma
*, uint32
, strptr
);
893 uint32
FuncVBCCWOSCode (struct AmiPragma
*, uint32
, strptr
);
894 uint32
FuncVBCCPUPText (struct AmiPragma
*, uint32
, strptr
);
895 uint32
FuncVBCCPUPCode (struct AmiPragma
*, uint32
, strptr
);
896 uint32
FuncEModule (struct AmiPragma
*, uint32
, strptr
);
897 uint32
FuncVBCCMorphText (struct AmiPragma
*, uint32
, strptr
);
898 uint32
FuncVBCCMorphCode (struct AmiPragma
*, uint32
, strptr
);
899 uint32
FuncFD (struct AmiPragma
*, uint32
, strptr
);
900 uint32
FuncClib (struct AmiPragma
*, uint32
, strptr
);
901 uint32
FuncSFD (struct AmiPragma
*, uint32
, strptr
);
902 uint32
FuncGateStubs (struct AmiPragma
*, uint32
, strptr
);
903 static uint32
PrintComment (struct Comment
*, strptr
);
904 static uint32
DoCallFunc (struct AmiPragma
*, uint32
, strptr
, FuncType
);
905 static uint32
CallFunc (uint32
, strptr
, FuncType
);
906 static uint32
PrintIncludes(void);
907 /* ------------------------------------------------------------------ */
908 static int32
AddClibEntry(strptr
, strptr
, uint32
);
909 static int32
ScanClibFile(strptr
, strptr
);
910 static int32
IsCPPType(struct CPP_NameType
*, uint8
);
911 static uint32
CheckRegisterNum(strptr
, struct CPP_NameType
*);
912 static uint32
ParseFuncPtrArgs(strptr
, struct CPP_NameType
*);
913 static int32
GetCPPType(struct CPP_NameType
*, strptr
, uint32
, uint32
);
914 static struct ClibData
*GetClibFunc(strptr
, struct AmiPragma
*, uint32
);
915 static int32
CheckKeyword(strptr
, strptr
, int32
);
916 static uint32
CopyCPPType(strptr
, uint32
, struct ClibData
*, struct AmiArgs
*);
917 static uint32
OutClibType(struct CPP_NameType
*, strptr
);
918 static uint32
MakeClibType(strptr
, struct CPP_NameType
*, strptr
);
919 static uint32
OutPASCALType(struct CPP_NameType
*, strptr
, uint32
);
920 /* ------------------------------------------------------------------ */
921 static uint32
CallPrag(uint32
, strptr
, FuncType
);
922 static uint32
CreatePragmaFile(strptr
, strptr
, strptr
, strptr
, uint32
);
923 static uint32
CreateCSTUBSFile(void);
924 static uint32
CreateLVOFile(uint32
);
925 static uint32
CreateLVOFilePPC(uint32
);
926 static uint32
CreateAsmStubs(uint32
, uint32
);
927 static uint32
CreateProtoFile(uint32
);
928 static uint32
CreateLocalData(strptr
, uint32
);
929 static uint32
CreateInline(uint32
, uint32
);
930 static uint32
CreateGateStubs(uint32
);
931 static uint32
CreateSASPowerUP(uint32
);
932 static uint32
CreateProtoPowerUP(void);
933 static uint32
CreateFPCUnit(void);
934 static uint32
CreateBMAP(void);
935 static uint32
CreateLVOLib(void);
936 static uint32
CreateLVOLibPPC(void);
937 static uint32
CreateVBCCInline(uint32
, uint32
);
938 static uint32
CreateVBCC(uint32
, uint32
);
939 static uint32
CreateVBCCPUPLib(uint32
);
940 static uint32
CreateVBCCMorphCode(uint32
);
941 static uint32
CreateEModule(uint32
);
942 static uint32
CreateProtoRedirect(void);
943 static uint32
CreateFD(void);
944 static uint32
CreateSFD(uint32
);
945 static uint32
CreateClib(uint32
);
946 static uint32
CreateGenAuto(strptr
, uint32
);
947 /* ------------------------------------------------------------------ */
948 static uint32
GetName(struct NameList
*, struct ShortListRoot
*, uint32
);
949 static uint32
MakeFD(struct PragList
*);
950 static void OptimizeFDData(struct PragData
*);
951 static string
GetHexValue(string
);
952 static string
GetDoubleHexValue(strptr
);
953 static uint32
AddFDData(struct ShortListRoot
*, struct FDData
*);
954 static uint32
GetLibData(struct FDData
*);
955 static uint32
GetFlibData(struct FDData
*);
956 static uint32
GetAmiData(struct FDData
*);
957 static uint32
CreateFDFile(void);
958 /* ------------------------------------------------------------------ */
959 static void GetArgs(int argc
, char **argv
);
960 static strptr
mygetfile(strptr name
, size_t *len
);
962 #define ERROFFSET_CLIB (1<<31)
965 ERR_TAGFUNC_NEEDS_ARGUMENT
,
966 ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
,
967 ERR_TAG_DEF_WITHOUT_PRAGMA
,
968 ERR_BASENAME_DECLARED_TWICE
,
969 ERR_EXPECTED_SLASH_IN_BASENAME
,
970 ERR_EXPECTED_BASENAME
,
971 ERR_EXPECTED_BIAS_VALUE
,
972 ERR_ASSUMING_POSITIVE_BIAS_VALUE
,
973 ERR_MISSING_FUNCTION_NAME
,
974 ERR_EXPECTED_OPEN_BRACKET
,
975 ERR_TO_MUCH_ARGUMENTS
,
976 ERR_EXPECTED_ARGUMENT_NAME
,
977 ERR_EXPECTED_CLOSE_BRACKET
,
978 ERR_EXPECTED_REGISTER_NAME
,
980 ERR_REGISTER_USED_TWICE
,
981 ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
,
982 ERR_ASSUMING_BIAS_OF_30
,
983 ERR_EXTRA_CHARACTERS
,
984 ERR_MISSING_BASENAME
,
987 ERR_DIFFERENT_TO_PREVIOUS
,
988 ERR_UNKNOWN_VARIABLE_TYPE
,
991 ERR_PROTOTYPE_MISSING
,
992 ERR_NOPROTOTYPES_FILE
,
993 ERR_UNKNOWN_DIRECTIVE
,
994 ERR_INLINE_A4_AND_A5
,
995 ERR_INLINE_D7_AND_A45
,
996 ERR_MISSING_SHORTBASENAME
,
999 ERR_FLOATARG_NOT_ALLOWED
,
1000 ERR_WRONG_TYPES_LINE
,
1005 ERR_PPC_FUNCTION_NOT_SUPPORTED
,
1008 ERR_ILLEGAL_FUNCTION_POSITION
,
1010 ERR_COMMENT_SINGLEFILE
,
1011 ERR_NOFD2PRAGMATYPES
,
1012 ERR_M68K_FUNCTION_NOT_SUPPORTED
,
1013 ERR_UNKNOWN_RETURNVALUE_TYPE
,
1015 ERR_EXCPECTED_IDSTRING
,
1016 ERR_EXPECTED_ID_ENDSIGN
,
1018 ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
,
1019 ERR_IDSTRING_DECLARED_TWICE
,
1020 ERR_COMMANDLINE_LIBTYPE
,
1021 ERR_COMMANDLINE_BASENAME
,
1022 ERR_LIBTYPE_DECLARED_TWICE
,
1023 ERR_EXPECTED_LIBTYPE
,
1027 ERR_VARARGS_ARGUMENTS_DIFFER
,
1028 ERR_UNEXPECTED_FILEEND
,
1029 ERR_VARARGS_ALIAS_FIRST
,
1031 ERR_EXPECTED_STRUCT
,
1032 ERR_EXPECTED_POINTERSIGN
,
1033 ERR_ARGNAME_KEYWORD_CONFLICT
,
1034 ERR_ARGNAME_ARGNAME_CONFLICT
,
1035 ERR_ONLYTAGMODE_NOTALLOWED
,
1036 ERR_COMMANDLINE_LIBNAME
,
1037 ERR_LIBNAME_DECLARED_TWICE
,
1038 ERR_EXPECTED_LIBNAME
,
1040 ERR_MULTIPLEFUNCTION
,
1041 ERR_INLINE_AX_SWAPREG
,
1043 ERR_ILLEGAL_CHARACTER_DETECTED
,
1044 ERR_UNKNOWN_VARIABLE_TYPE_INT
,
1045 ERR_UNKNOWN_RETURNVALUE_TYPE_INT
,
1048 static const struct ErrField
{
1049 uint8 Type
; /* 0 = Error, 1 = Warning */
1053 {1, 1, "Tag function must have arguments."},
1054 {1, 1, "Cannot convert pragma name into tag name."},
1055 {1, 1, "Tag definition without preceding Pragma."},
1056 {1, 0, "Basename declared twice."},
1057 {1, 0, "Expected preceding _ in Basename."},
1058 {1, 1, "Expected Basename."},
1059 {1, 0, "Expected Bias value."},
1060 {1, 0, "Assuming positive bias value."},
1061 {1, 1, "Missing function name."},
1062 {1, 1, "Expected '('."},
1063 {1, 1, "Too much arguments."},
1064 {1, 1, "Expected argument name."},
1065 {1, 1, "Expected ')'."},
1066 {1, 1, "Expected register name."},
1067 {1, 1, "A7 not allowed as argument register."},
1068 {1, 1, "Register used twice."},
1069 {1, 0, "Number of arguments != number of registers."},
1070 {1, 0, "Assuming bias of 30."},
1071 {1, 1, "Extra characters."},
1072 {0, 0, "Missing Basename in FD file."},
1073 {0, 0, "Failed to write destination file."},
1074 {1, 1, "Expected ','."},
1075 {0, 1, "Data different to previous given."},
1076 {1, 0, "Unknown type of argument %ld."},
1077 {0, 0, "Unknown problem: program error or corrupt input data."},
1078 {1, 0, "Missing ##end."},
1079 {1, 0, "Prototype for function \"%s\" not found."},
1080 {0, 0, "No prototypes file (CLIB parameter) was specified."},
1081 {1, 1, "Unknown directive '%s' found."},
1082 {1, 0, "Usage of both A4 and A5 is not supported."},
1083 {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
1084 {0, 0, "Missing Basename in FD file and FD filename."},
1085 {1, 0, "A6 not allowed as argument register."},
1086 {1, 0, "Empty or partial file deleted."},
1087 {1, 1, "Floating point arguments not allowed."},
1088 {0, 0, "Wrong definition in external type definition file."},
1089 {1, 0, "Cannot determine if FPU argument is double or single."},
1090 {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
1091 {0, 0, "Could not open file \"%s\"."},
1092 {1, 0, "A5 cannot be used as argument register."},
1093 {1, 0, "Format supports no PPC functions."},
1094 {1, 0, "Unknown ABI '%s' found."},
1095 {0, 0, "SORTED cannot be used with that type."},
1096 {1, 0, "Position of function %s not supported with that type."},
1097 {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
1098 {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
1099 {1, 0, "Missing the types definition file. Using internal defaults."},
1100 {1, 0, "Format supports no M68k functions."},
1101 {1, 0, "Unknown type of return value."},
1102 {1, 0, "With SFD as input CLIB file is ignored."},
1103 {1, 0, "Expected $Id: in ID string."},
1104 {1, 0, "Expected $ at end of ID string."},
1105 {1, 0, "Missing ==end."},
1106 {1, 1, "Expected positive decimal number."},
1107 {1, 0, "ID string declared twice."},
1108 {1, 1, "Library type of commandline overwrites file settings."},
1109 {1, 1, "Basename of commandline overwrites file settings."},
1110 {1, 0, "Library type declared twice."},
1111 {1, 1, "Expected library type definition."},
1112 {1, 1, "SORTED cannot be used with SFD and FD output."},
1113 {1, 0, "Function expected before ##shadow."},
1114 {1, 1, "There is already a varargs function, handling as alias."},
1115 {1, 0, "Varargs function cannot have different arguments."},
1116 {1, 0, "Unexpected end of file."},
1117 {1, 0, "Commands varargs and alias cannot be at file start."},
1118 {1, 0, "Only %d alias names supported."},
1119 {1, 1, "Expected struct keyword in library type."},
1120 {1, 0, "Expected '*' at end of library type definition."},
1121 {1, 1, "Name of argument %d conflicts with keyword '%s'."},
1122 {1, 1, "Name of argument %d conflicts with argument %d."},
1123 {1, 0, "SFD files cannot consist only of varargs functions."},
1124 {1, 1, "Library name of commandline overwrites file settings."},
1125 {1, 0, "Library name declared twice."},
1126 {1, 1, "Expected library name definition."},
1127 {1, 0, "Neither prefix nor subprefix specified."},
1128 {1, 0, "Format supports single function pointer only (void * used)."},
1129 {1, 0, "No swap register left for %s."},
1130 {1, 0, "SFD files should always start with ==id directive."},
1131 {1, 0, "Illegal character detected."},
1132 {1, 0, "Unknown type of argument %ld (%s) handled as int."},
1133 {1, 0, "Unknown type of return value (%s) handled as int."},
1139 static uint8 InternalTypes
[] = {
1140 "IX:struct InputXpression\n"
1142 "Class:struct IClass\n"
1143 "BootBlock:struct bootblock\n"
1144 "ValidIDstruct:struct ValidIDstruct\n"
1145 "DisplayInfoHandle:void *\n"
1146 "RESOURCEFILE:void *\n"
1147 "RESOURCEID:unsigned long\n"
1149 "GLbitfield:unsigned long\n"
1150 "GLbyte:signed char\n"
1153 "GLsizei:unsigned long\n"
1154 "GLubyte:unsigned char\n"
1155 "GLushort:unsigned short\n"
1156 "GLuint:unsigned long\n"
1161 "GLboolean:enum ?\n"
1163 "GLlookAt:struct GLlookAt\n"
1164 "GLproject:struct GLproject\n"
1165 "GLunProject:struct GLunProject\n"
1166 "GLfrustum:struct GLfrustum\n"
1167 "GLortho:struct GLortho\n"
1168 "GLbitmap:struct GLbitmap\n"
1169 "GLUquadricObj:struct GLUquadricObj\n"
1170 "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
1171 "GLUnurbsObj:struct GLUnurbsObj\n"
1172 "GLvisual:struct gl_visual\n"
1173 "GLframebuffer:struct gl_frame_buffer\n"
1174 "GLcontext:struct gl_context\n"
1175 "HGIDA_Stack:unsigned long *\n"
1176 "HGIDA_BoundedStack:unsigned long *\n"
1177 "HGIDA_Queue:unsigned long *\n"
1178 "HGIDA_BoundedQueue:unsigned long *\n"
1179 "HGIDA_List:unsigned long *\n"
1180 "HGIDA_ListItem:unsigned long *\n"
1181 "HGIDA_Error:enum ?\n"
1182 "HGIDA_Direction:enum ?\n"
1185 "mode_t:unsigned short\n"
1186 "pid_t:struct Task *\n"
1187 "fd_set:struct fd_set\n"
1188 "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"
1189 "pcap_t:struct pcap\n"
1190 "pcap_dumper_t:struct pcap_dumper\n"
1191 "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const unsigned char *)\n"
1192 "u_char:unsigned char\n"
1193 "bpf_u_int32:unsigned long\n"
1196 "MPEGA_STREAM:struct MPEGA_STREAM\n"
1197 "MPEGA_CTRL:struct MPEGA_CTRL\n"
1198 "W3D_Context:struct W3DContext\n"
1199 "W3D_Driver:struct W3DDriver\n"
1200 "W3D_Texture:struct W3DTexture\n"
1201 "W3D_Scissor:struct W3DScissor\n"
1202 "W3D_Line:struct W3D_Line\n"
1203 "W3D_Point:struct W3D_Point\n"
1204 "W3D_Triangle:struct W3D_Triangle\n"
1205 "W3D_Triangles:struct W3D_Triangles\n"
1207 "W3D_Bitmap:struct W3D_Bitmap\n"
1208 "W3D_Fog:struct W3D_Fog\n"
1210 "W3D_Double:double\n"
1211 "W3D_TriangleV:struct W3D_TriangleV\n"
1212 "W3D_TrianglesV:struct W3D_TriangleV\n"
1213 "W3D_ScreenMode:struct W3D_Screenmode\n"
1214 "W3D_Color:struct W3D_Color\n"
1215 "W3D_Lines:struct W3D_Lines\n"
1217 "DITHERINFO:void *\n"
1221 "size_t:unsigned int\n"
1222 "uint8:unsigned char\n"
1223 "uint16:unsigned short\n"
1224 "uint32:unsigned long\n"
1229 "PtrBigNum:struct BigNum *\n"
1230 "BF_KEY:struct bf_key_st\n"
1231 "BF_LONG:unsigned long\n"
1232 "CAST_KEY:struct cast_key_st\n"
1233 "CAST_LONG:unsigned long\n"
1234 "DES_LONG:unsigned long\n"
1235 "des_key_schedule:struct des_ks_struct\n"
1236 "const_des_cblock:unsigned char [8]\n"
1237 "des_cblock:unsigned char [8]\n"
1238 "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
1239 "MD2_CTX:struct MD2state_st\n"
1240 "MD5_CTX:struct MD5state_st\n"
1241 "MDC2_CTX:struct mdc2_ctx_st\n"
1242 "RC2_KEY:struct rc2_key_st\n"
1243 "RC4_KEY:struct rc4_key_st\n"
1244 "RC5_32_KEY:struct rc5_key_st\n"
1245 "RIPEMD160_CTX:struct RIPEMD160state_st\n"
1246 "SHA_CTX:struct SHAstate_st\n"
1247 "ASN1_CTX:struct asn1_ctx_st\n"
1248 "ASN1_OBJECT:struct asn1_object_st\n"
1249 "ASN1_STRING:struct asn1_string_st\n"
1250 "ASN1_TYPE:struct asn1_type_st\n"
1251 "ASN1_METHOD:struct asn1_method_st\n"
1252 "ASN1_HEADER:struct asn1_header_st\n"
1253 "ASN1_INTEGER:struct asn1_string_st\n"
1254 "ASN1_ENUMERATED:struct asn1_string_st\n"
1255 "ASN1_BIT_STRING:struct asn1_string_st\n"
1256 "ASN1_OCTET_STRING:struct asn1_string_st\n"
1257 "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
1258 "ASN1_T61STRING:struct asn1_string_st\n"
1259 "ASN1_IA5STRING:struct asn1_string_st\n"
1260 "ASN1_UTCTIME:struct asn1_string_st\n"
1261 "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
1262 "ASN1_TIME:struct asn1_string_st\n"
1263 "ASN1_GENERALSTRING:struct asn1_string_st\n"
1264 "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
1265 "ASN1_BMPSTRING:struct asn1_string_st\n"
1266 "ASN1_VISIBLESTRING:struct asn1_string_st\n"
1267 "ASN1_UTF8STRING:struct asn1_string_st\n"
1268 "BIO:struct bio_st\n"
1269 "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
1270 "BIO_METHOD:struct bio_method_st\n"
1271 "BIGNUM:struct bignum_st\n"
1272 "BN_CTX:struct bignum_ctx\n"
1273 "BN_ULONG:unsigned long\n"
1274 "BN_MONT_CTX:struct bn_mont_ctx_st\n"
1275 "BN_BLINDING:struct bn_blinding_st\n"
1276 "BN_RECP_CTX:struct bn_recp_ctx_st\n"
1277 "BUF_MEM:struct buf_mem_st\n"
1278 "COMP_METHOD:struct comp_method_st\n"
1279 "COMP_CTX:struct comp_ctx_st\n"
1280 "CONF_VALUE:struct !\n"
1281 "LHASH_NODE:struct lhash_node_st\n"
1282 "LHASH:struct lhash_st\n"
1283 "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
1284 "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
1286 "DSA:struct dsa_st\n"
1287 "DSA_SIG:struct DSA_SIG_st\n"
1288 "ERR_STATE:struct err_state_st\n"
1289 "ERR_STRING_DATA:struct ERR_string_data_st\n"
1290 "EVP_PKEY:struct evp_pkey_st\n"
1291 "EVP_MD:struct env_md_st\n"
1292 "EVP_MD_CTX:struct env_md_ctx_st\n"
1293 "EVP_CIPHER:struct evp_cipher_st\n"
1294 "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
1295 "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
1296 "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
1297 "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char *pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st *cipher, struct env_md_st *md, int en_de)\n"
1298 "HMAC_CTX:struct hmac_ctx_st\n"
1299 "OBJ_NAME:struct obj_name_st\n"
1300 "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
1301 "PEM_USER:struct pem_recip_st\n"
1302 "PEM_CTX:struct pem_ctx_st\n"
1303 "PKCS12_MAC_DATA:struct !\n"
1305 "PKCS12_SAFEBAG:struct !\n"
1306 "PKCS12_BAGS:struct pkcs12_bag_st\n"
1307 "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
1308 "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
1309 "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
1310 "PKCS7_SIGNED:struct pkcs7_signed_st\n"
1311 "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
1312 "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
1313 "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
1314 "PKCS7_DIGEST:struct pkcs7_digest_st\n"
1315 "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
1316 "PKCS7:struct pkcs7_st\n"
1317 "RAND_METHOD:struct rand_meth_st\n"
1318 "RSA:struct rsa_st\n"
1319 "RSA_METHOD:struct rsa_meth_st\n"
1320 "TXT_DB:struct txt_db_st\n"
1321 "X509_OBJECTS:struct X509_objects_st\n"
1322 "X509_ALGOR:struct X509_algor_st\n"
1323 "X509_VAL:struct X509_val_st\n"
1324 "X509_PUBKEY:struct X509_pubkey_st\n"
1325 "X509_SIG:struct X509_sig_st\n"
1326 "X509_NAME_ENTRY:struct X509_name_entry_st\n"
1327 "X509_NAME:struct X509_name_st\n"
1328 "X509_EXTENSION:struct X509_extension_st\n"
1329 "X509_ATTRIBUTE:struct x509_attributes_st\n"
1330 "X509_REQ_INFO:struct X509_req_info_st\n"
1331 "X509_REQ:struct X509_req_st\n"
1332 "X509_CINF:struct x509_cinf_st\n"
1333 "X509:struct x509_st\n"
1334 "X509_REVOKED:struct X509_revoked_st\n"
1335 "X509_CRL_INFO:struct X509_crl_info_st\n"
1336 "X509_CRL:struct X509_crl_st\n"
1337 "X509_PKEY:struct private_key_st\n"
1338 "X509_INFO:struct X509_info_st\n"
1339 "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
1340 "NETSCAPE_SPKI:struct Netscape_spki_st\n"
1341 "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
1342 "CBC_PARAM:struct CBCParameter_st\n"
1343 "PBEPARAM:struct PBEPARAM_st\n"
1344 "PBE2PARAM:struct PBE2PARAM_st\n"
1345 "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
1346 "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
1347 "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
1348 "X509V3_EXT_METHOD:struct v3_ext_method\n"
1349 "X509V3_CTX:struct v3_ext_ctx\n"
1350 "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
1351 "X509_CERT_FILE_CTX:struct x509_file_st\n"
1352 "X509_OBJECT:struct X509_objects_st\n"
1353 "X509_LOOKUP:struct x509_lookup_st\n"
1354 "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
1355 "X509_STORE_CTX:struct x509_store_state_st\n"
1356 "X509_STORE:struct x509_store_st\n"
1357 "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
1358 "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
1359 "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
1360 "GENERAL_NAME:struct GENERAL_NAME_st\n"
1361 "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
1362 "DIST_POINT:struct DIST_POINT_st\n"
1363 "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
1364 "SXNETID:struct SXNET_ID_st\n"
1365 "SXNET:struct SXNET_st\n"
1366 "NOTICEREF:struct NOTICEREF_st\n"
1367 "USERNOTICE:struct USERNOTICE_st\n"
1368 "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
1369 "POLICYINFO:struct POLICYINFO_st\n"
1370 "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
1371 "SSL_CIPHER:struct ssl_cipher_st\n"
1372 "SSL:struct ssl_st\n"
1373 "SSL_CTX:struct ssl_ctx_st\n"
1374 "SSL_METHOD:struct ssl_method_st\n"
1375 "SSL_SESSION:struct ssl_session_st\n"
1376 "SSL_COMP:struct ssl_comp_st\n"
1377 "SSL2_CTX:struct ssl2_ctx_st\n"
1378 "SSL3_RECORD:struct ssl3_record_st\n"
1379 "SSL3_BUFFER:struct ssl3_buffer_st\n"
1380 "SSL3_CTX:struct ssl3_ctx_st\n"
1381 "CERT_PKEY:struct cert_pkey_st\n"
1382 "CERT:struct cert_st\n"
1383 "SESS_CERT:struct sess_cert_st\n"
1384 "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
1385 "SSL3_COMP:struct ssl3_comp_st\n"
1386 "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
1387 "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
1388 "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
1389 "STACK_OF(X509):struct stack_st_X509\n"
1390 "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
1391 "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
1392 "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
1393 "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
1394 "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
1395 "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
1396 "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
1397 "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
1398 "STACK:struct stack_st\n"
1401 static const struct CPP_TypeField CPP_Field
[] = {
1402 {"int", 3, 0, CPP_TYPE_INT
},
1403 {"long", 4, 0, CPP_TYPE_LONG
},
1404 {"LONG", 4, 0, CPP_TYPE_LONG
},
1405 {"BPTR", 4, 0, CPP_TYPE_LONG
},
1406 {"BSTR", 4, 0, CPP_TYPE_LONG
},
1407 {"CxObj", 5, 0, CPP_TYPE_LONG
},
1408 {"CxMsg", 5, 0, CPP_TYPE_LONG
},
1409 {"ULONG", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1410 {"LONGBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1411 {"CPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1412 {"Tag", 3, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1413 {"Object", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1414 {"short", 5, 0, CPP_TYPE_WORD
},
1415 {"SHORT", 5, 0, CPP_TYPE_WORD
},
1416 {"COUNT", 5, 0, CPP_TYPE_WORD
},
1417 {"WORD", 4, 0, CPP_TYPE_WORD
},
1418 {"USHORT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1419 {"UWORD", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1420 {"UCOUNT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1421 {"WORDBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1422 {"RPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1423 {"BOOL", 4, CPP_FLAG_BOOLEAN
, CPP_TYPE_WORD
},
1424 {"char", 4, 0, CPP_TYPE_BYTE
},
1425 {"BYTE", 4, 0, CPP_TYPE_BYTE
},
1426 {"UBYTE", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1427 {"TEXT", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1428 {"BYTEBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1429 {"float", 5, 0, CPP_TYPE_FLOAT
},
1430 {"FLOAT", 5, 0, CPP_TYPE_FLOAT
},
1431 {"double", 6, 0, CPP_TYPE_DOUBLE
},
1432 {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE
},
1433 {"void", 4, 0, CPP_TYPE_VOID
},
1434 {"VOID", 4, 0, CPP_TYPE_VOID
},
1435 {"APTR", 4, CPP_FLAG_POINTER
, CPP_TYPE_VOID
},
1436 {"STRPTR", 6, CPP_FLAG_POINTER
|CPP_FLAG_STRPTR
, CPP_TYPE_BYTE
},
1437 {"CONST_STRPTR",12,CPP_FLAG_POINTER
|CPP_FLAG_CONST
, CPP_TYPE_BYTE
},
1438 {"ClassID", 7, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1439 {"PLANEPTR", 8, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1443 /* defaults: "Library" shortbname+".library" basename-last 4 chars */
1444 static const struct Proto_LibType Proto_LibTypes
[] = {
1445 {"DOSBase", "DosLibrary", 0, 0},
1446 {"SysBase", "ExecBase", 0, 0},
1447 {"ExpansionBase", "ExpansionBase", 0, 0},
1448 {"GfxBase", "GfxBase", "graphics.library", "graphics"},
1449 {"IntuitionBase", "IntuitionBase", 0, 0},
1450 {"LocaleBase", "LocaleBase", 0, 0},
1451 {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
1452 {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
1453 {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
1454 {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
1455 {"RealTimeBase", "RealTimeBase", 0, 0},
1456 {"RexxSysBase", "RxsLib", 0, 0},
1457 {"UtilityBase", "UtilityBase", 0, 0},
1458 {"WorkbenchBase", 0, "workbench.library", "wb"},
1459 /* resources - The Node entries may be correct, but I don't know it. */
1460 {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
1461 {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
1462 {"CardResource", 0/*"Node"*/, "card.resource", "cardres"},
1463 {"DiskBase", "DiskResource", "disk.resource", 0},
1464 {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
1465 {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
1467 {"ConsoleDevice", "Device", "console.device", "console"},
1468 {"InputBase", "Device", "input.device", 0},
1469 {"RamdriveDevice", "Device", "ramdrive.device", "ramdrive"},
1470 {"TimerBase", "Device", "timer.device", 0},
1471 /* non default Basenames */
1472 {"DatamasterBase", "DatamasterBase", 0, 0},
1473 {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
1474 {"ReqToolsBase", "ReqToolsBase", 0, 0},
1475 {"UnpackBase", "UnpackLibrary", 0, 0},
1476 {"xfdMasterBase", "xfdMasterBase", 0, 0},
1477 {"xadMasterBase", "xadMasterBase", 0, 0},
1478 /*{"xvsBase", "xvsBase", 0, 0}, now completely private */
1479 {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
1480 {"ArpBase", "ArpBase", 0, 0},
1481 {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
1482 {"PowerPCBase", "PPCBase", 0, 0},
1483 {"MC68060Base", 0, "68060.library", "mc68060"},
1484 {"MC68040Base", 0, "68040.library", "mc68040"},
1485 {"MC680x0Base", 0, "680x0.library", "mc680x0"},
1489 /* CachePostDMA, CachePreDMA are done by #?DMA check */
1490 static const struct Pragma_ExecpName Pragma_ExecpNames
[] = {
1491 {"VFWritef", "FWritef"},
1492 {"VFPrintf", "FPrintf"},
1493 {"VPrintf", "Printf"},
1496 {"CloneTagItems", 0},
1498 {"FreeTagItems", 0},
1500 {"PackBoolTags", 0},
1501 {"PackStructureTags", 0},
1502 {"UnpackStructureTags", 0},
1503 {"BGUI_PackStructureTags", 0},
1504 {"BGUI_UnpackStructureTags", 0},
1505 {"Inet_NtoA", 0}, /* socket.library */
1506 {"vsyslog", "syslog"},
1507 {"NewPPCStackSwap", 0},
1511 /* For double tagcall names (currently only necessary for dos.library and
1512 datatypes.library). Only one alias supported for a function! */
1513 static const struct Pragma_AliasName Pragma_AliasNames
[] = {
1514 {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL
},
1515 {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL
},
1516 {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL
},
1517 {"SystemTagList", "System", FUNCFLAG_NORMAL
},
1518 {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG
},
1522 /* special names, which get an x before name in BMAP files */
1523 static const strptr BMAPSpecial
[] =
1524 {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
1525 "Translate", "Wait", "Write", 0};
1527 #define FIRST_KNOWN_RELEASE 30
1528 #define LAST_KNOWN_RELEASE 45
1529 static const strptr Release
[] =
1531 "Release 1.0", /* V30 */
1532 "Release 1.1", /* V31 */
1533 "Preliminary Release 1.2", /* V32 */
1534 "Release 1.2", /* V33 */
1535 "Release 1.3", /* V34 */
1536 "Release 1.3 A2024", /* V35 */
1537 "Release 2.0", /* V36 */
1538 "Release 2.04", /* V37 */
1539 "Release 2.1", /* V38 */
1540 "Release 3.0", /* V39 */
1541 "Release 3.1", /* V40 */
1542 "Transitional Release 3.2", /* V41 */
1543 "Transitional Release 3.3", /* V42 */
1544 "Transitional Release 3.4", /* V43 */
1545 "Release 3.5", /* V44 */
1546 "Release 3.9", /* V45 */
1549 /* Keywords, which cannot be argument names. They are used case_insensitive to
1550 be sure they make no conflicts in non-C-languages as well.
1551 Currently these are mostly C keywords.
1553 static const strptr Keywords
[] =
1555 "and", "and_eq", "asm", "auto", "bitand",
1556 "bitor", "break", "case", "catch", "char",
1557 "class", "compl", "const", "continue", "default",
1558 "delete", "do", "double", "else", "enum",
1559 "extern", "false", "float", "for", "friend",
1560 "goto", "if", "inline", "int", "long",
1561 "new", "not", "not_eq", "operator", "or",
1562 "or_eq", "private", "protected", "public", "register",
1563 "return", "short", "signed", "sizeof", "static",
1564 "struct", "switch", "template", "this", "throw",
1565 "true", "try", "typedef", "union", "unsigned",
1566 "virtual", "void", "volatile", "wchar_t", "while",
1567 "xor", "xor_eq", "RastPort", "Tag",
1572 static int stricmp(const char *a
, const char *b
)
1574 while(*a
&& tolower(*a
) == tolower(*b
))
1578 return (tolower(*a
) - tolower(*b
));
1581 static int strnicmp(const char *a
, const char *b
, size_t num
)
1583 while(num
&& *a
&& tolower(*a
) == tolower(*b
))
1587 return num
? (tolower(*a
) - tolower(*b
)) : 0;
1591 static strptr
DupString(strptr Str
, size_t Len
)
1594 if((res
= r
= AllocListMem(Len
+1)))
1596 while(Len
-- && *Str
)
1601 printf("DupString %s.\n", res
);
1606 static strptr
AllocListMem(size_t size
)
1610 printf("AllocListMem Size %ld.\n", size
);
1612 if((a
= (strptr
) malloc(size
)))
1617 static strptr
SkipBlanks(strptr OldPtr
)
1619 while(*OldPtr
== ' ' || *OldPtr
== '\t')
1624 static strptr
SkipBlanksRet(strptr OldPtr
)
1626 while(*OldPtr
== ' ' || *OldPtr
== '\t' || *OldPtr
== '\n')
1632 This function is used to skip over variable names.
1634 Inputs: OldPtr - pointer to the beginning of a string.
1636 Result: Pointer to the first character of the string, that is not one
1637 of a-z, A-Z, 0-9 or the underscore.
1640 static strptr
SkipName(strptr OldPtr
)
1642 while(isalnum(*OldPtr
) || *OldPtr
== '_')
1647 static uint32
GetTypes(void)
1653 if(!(ptr
= mygetfile(EXTTYPESFILE
, &len
)))
1655 #ifdef EXTTYPESFILEHIDDEN
1656 if((ptr
= getenv("HOME")))
1658 strptr ptrh
= EXTTYPESFILEHIDDEN
;
1661 ptr
= DupString(ptr
, i
+ sizeof(EXTTYPESFILEHIDDEN
) + 1);
1662 if(i
&& ptr
[i
-1] != '/')
1665 ptr
[i
++] = *(ptrh
++);
1667 ptr
= mygetfile(ptr
, &len
);
1669 if(!ptr
) /* disabled following if ptr != 0 */
1671 if(!(ptr
= mygetfile(EXTTYPESFILE2
, &len
)))
1673 DoError(ERR_NOFD2PRAGMATYPES
, 0);
1674 ptr
= (strptr
) InternalTypes
;
1675 len
= sizeof(InternalTypes
)-1;
1678 if((i
= ScanTypes(ptr
, len
)) > 0)
1680 DoError(ERR_WRONG_TYPES_LINE
, i
);
1686 static strptr
GetBaseType(void)
1688 static strptr basetype
= 0;
1691 if(Flags2
& FLAG2_VOIDBASE
)
1692 basetype
= "void *";
1695 for(i
= 0; !libtype
&& BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1697 if(Proto_LibTypes
[i
].StructureName
&& !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1699 libtype
= Proto_LibTypes
[i
].StructureName
;
1702 if(libtype
&& (basetype
= malloc(strlen(libtype
) + 9+1)))
1704 sprintf(basetype
, "struct %s *", libtype
);
1707 basetype
= "struct Library *";
1713 static strptr
GetBaseTypeLib(void)
1720 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1722 if(Proto_LibTypes
[i
].StructureName
&& !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1724 return Proto_LibTypes
[i
].StructureName
;
1730 static strptr
GetLibraryName(void)
1737 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1739 if(Proto_LibTypes
[i
].LibraryName
&& !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1741 return (libname
= Proto_LibTypes
[i
].LibraryName
);
1744 if(!(libname
= malloc(strlen(ShortBaseName
)+9)))
1747 /* auto create name */
1748 for(i
= 0; ShortBaseName
[i
]; ++i
)
1749 libname
[i
] = ShortBaseName
[i
];
1750 strcpy(libname
+i
,".library");
1754 static int32
MakeShortBaseName(void)
1759 ptr
= p2
= args
.infile
;
1762 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
1767 /* first get name from file */
1769 p2
-= (sizeof(SFDFILEEXTENSION
)-1);
1770 if(p2
> ptr
&& !stricmp(p2
, SFDFILEEXTENSION
))
1771 ShortBaseName
= DupString(ptr
, p2
-ptr
);
1772 p2
+= sizeof(SFDFILEEXTENSION
)-sizeof(FDFILEEXTENSION
);
1773 if(p2
> ptr
&& !stricmp(p2
, FDFILEEXTENSION
))
1774 ShortBaseName
= DupString(ptr
, p2
-ptr
);
1776 /* then try exceptions (overriding filename) */
1779 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1781 if(Proto_LibTypes
[i
].ShortBaseName
&& !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1783 if(!(ShortBaseName
= DupString(Proto_LibTypes
[i
].ShortBaseName
,
1784 strlen(Proto_LibTypes
[i
].ShortBaseName
))))
1789 /* and last use default method */
1791 ShortBaseName
= DupString(BaseName
, strlen(BaseName
)-4);
1797 ptr
= ShortBaseName
;
1798 while((*ptr
= tolower(*ptr
))) /* Convert to lowercase */
1801 if((ShortBaseNameUpper
= DupString(ShortBaseName
, strlen(ShortBaseName
))))
1803 ptr
= ShortBaseNameUpper
;
1804 while((*ptr
= toupper(*ptr
))) /* Convert to uppercase */
1813 static uint32
OpenDest(strptr name
)
1815 static uint8 printedname
= 0;
1818 t
= (strptr
) tempbuf
;
1819 if((b
= args
.to
) && *b
)
1823 if(*(t
-1) != ':' && *(t
-1) != '/')
1828 if(!(Flags
& FLAG_SINGLEFILE
))
1829 printf("ResultFile: %s%s\n", tempbuf
, name
);
1830 else if(!printedname
++)
1832 printf("ResultType: %s", tempbuf
); printf(filenamefmt
, "*");
1842 HEADER
= mygetfile((strptr
)tempbuf
, &headersize
);
1846 if((outfile
= fopen((strptr
)tempbuf
, "wb")))
1848 DoError(ERR_OPEN_FILE
, 0, tempbuf
);
1852 static uint32
CloseDest(strptr name
)
1859 if(!(Flags
& FLAG_DONE
) || !Output_Error
)
1862 if(!Output_Error
|| !(Flags
& FLAG_SINGLEFILE
))
1863 DoError(ERR_EMPTY_FILE
, 0);
1865 t
= (strptr
) tempbuf
;
1866 if((b
= args
.to
) && *b
)
1870 if(*(t
-1) != ':' && *(t
-1) != '/')
1877 remove((strptr
)tempbuf
);
1880 Flags
&= ~FLAG_DONE
; /* clear the flag */
1887 static uint32
MakeTagFunction(struct AmiPragma
*ap
)
1889 size_t len
= strlen(ap
->FuncName
);
1893 printf("MakeTagFunction:\n");
1896 if(!ap
->NumArgs
|| ap
->TagName
)
1900 ap
->Flags
|= AMIPRAGFLAG_OWNTAGFUNC
;
1902 while(Pragma_ExecpNames
[i
].FunctionName
&& /* check the exception names */
1903 strcmp(ap
->FuncName
, Pragma_ExecpNames
[i
].FunctionName
))
1906 if(Pragma_ExecpNames
[i
].FunctionName
)
1908 if(!(ap
->TagName
= Pragma_ExecpNames
[i
].TagName
))
1910 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
1914 else if(ap
->FuncName
[len
-1] == 'A')
1916 if(!strcmp(ap
->FuncName
+len
-3, "DMA") ||
1917 !strcmp(ap
->FuncName
+len
-4, "MESA")) /* skip names with DMA or MESA at end */
1918 { ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
; --tagfuncs
; return 1;}
1919 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-1)))
1922 else if(!strcmp(ap
->FuncName
+ len
-7, "TagList"))
1924 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-3)))
1926 ap
->TagName
[len
-4] = 's';
1928 else if(!strcmp(ap
->FuncName
+ len
-4, "Args"))
1930 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-4)))
1933 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "tags") ||
1934 !stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "taglist"))
1936 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
1938 memcpy(ap
->TagName
+ len
, "Tags", 5);
1940 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "args"))
1942 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
1944 memcpy(ap
->TagName
+ len
, "Args", 5);
1948 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
1949 --tagfuncs
; /* not a tagfunction, incrementing was false, undo it */
1955 static void MakeLines(strptr buffer
, uint32 size
)
1959 /* make a real C++ zero string ending line */
1970 /* Do any special functions, which cannot be done with other exception
1971 stuff - currently only dos.library DoPkt function. */
1972 static uint32
SpecialFuncs(void)
1974 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
, *ap2
= (struct AmiPragma
*) AmiPragma
.First
;
1976 /* first let one more go away, so we can detect if the DoPkt parts are
1977 already inserted in the FD file */
1979 while(ap2
&& (struct AmiPragma
*)(ap2
->List
.Next
) != ap
)
1980 ap2
= (struct AmiPragma
*)(ap2
->List
.Next
);
1982 if(ap2
&& ap2
->Bias
== 0xF0 && ap
->Bias
!= 0xF0 && !strcmp("DoPkt", ap2
->FuncName
))
1984 struct AmiPragma
*d
;
1987 RemoveItem(&AmiPragma
, (struct ShortList
*) ap
); /* add in correct order */
1988 for(i
= 0; i
< 5; ++i
)
1990 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
1992 memcpy(d
, ap2
, sizeof(struct AmiPragma
));
1993 d
->FuncName
= DupString(ap2
->FuncName
, 6);
1994 d
->FuncName
[5] = '0'+i
;
1995 d
->NumArgs
= d
->CallArgs
= i
+ 2;
1996 AddItem(&AmiPragma
, (struct ShortList
*) d
);
1998 AddItem(&AmiPragma
, (struct ShortList
*) ap
);
2003 static void SortFDList(void)
2005 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.First
, *ap2
, *ap3
;
2006 AmiPragma
.First
= AmiPragma
.Last
= 0;
2011 ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2013 /* for FD2Inline style we need to use strcmp instead of stricmp here */
2014 while(ap2
&& stricmp(ap2
->FuncName
, ap
->FuncName
) < 0)
2017 ap2
= (struct AmiPragma
*) ap2
->List
.Next
;
2021 ap
= (struct AmiPragma
*) ap
->List
.Next
;
2025 ap2
->List
.Next
= (struct ShortList
*) ap3
->List
.Next
;
2026 ap3
->List
.Next
= (struct ShortList
*) ap2
;
2030 ap2
->List
.Next
= AmiPragma
.First
;
2031 AmiPragma
.First
= (struct ShortList
*) ap2
;
2033 if(ap
&& !ap
->List
.Next
)
2034 AmiPragma
.Last
= (struct ShortList
*) ap2
;
2038 static void AddAliasName(struct AmiPragma
*ap
, struct Pragma_AliasName
*alias
, uint32 linenum
)
2042 if(ap
->NumAlias
> NUMALIASNAMES
)
2043 DoError(ERR_ALIASNAMES
, linenum
, NUMALIASNAMES
);
2046 /* prevent double names */
2047 for(i
= 0; i
< ap
->NumAlias
; ++i
)
2049 if(!strcmp(ap
->AliasName
[i
]->AliasName
, alias
->AliasName
))
2052 ap
->AliasName
[ap
->NumAlias
++] = alias
;
2056 static uint32
CheckNames(struct AmiPragma
*ap
)
2062 printf("CheckNames\n");
2064 for(i
= 0; i
< ap
->CallArgs
; ++i
)
2066 if(!ap
->Args
[i
].ArgName
)
2068 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4+strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2070 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2074 for(k
= Keywords
; *k
; ++k
)
2076 if(!stricmp(ap
->Args
[i
].ArgName
, *k
))
2078 DoError(ERR_ARGNAME_KEYWORD_CONFLICT
, ap
->Line
, i
, *k
);
2079 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4+strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2081 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2084 for(j
= 0; j
< i
; ++j
)
2086 if(!stricmp(ap
->Args
[i
].ArgName
, ap
->Args
[j
].ArgName
))
2088 DoError(ERR_ARGNAME_ARGNAME_CONFLICT
, ap
->Line
, i
+1, j
+1);
2089 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4+strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2091 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2096 /* NOTE: the replaced argument names aren't checked for conflicts */
2097 /* replaced names are of style a0arg */
2101 static uint32
ScanSFDFile(uint32 abi
)
2107 uint32 functype
= 0;
2109 Flags2
|= FLAG2_SFDMODE
;
2111 if(strncmp("==id", in
.pos
, 4))
2112 DoError(ERR_SFD_START
, 1);
2114 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
2123 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2129 d
->Private
= _public
? 0 : 1;
2130 AddItem(&Comment
, (struct ShortList
*) d
);
2136 else if(*in
.pos
== '=' && in
.pos
[1] == '=')
2139 actcom
= 0; /* no Comment */
2141 if(!strnicmp(in
.pos
, "basetype", 8))
2144 printf("ScanSFDFile: found ==basetype\n");
2146 if(!(Flags2
& FLAG2_LIBTYPE
))
2149 DoError(ERR_LIBTYPE_DECLARED_TWICE
, linenum
);
2151 in
.pos
= SkipBlanks(in
.pos
+8);
2152 if(strncmp(in
.pos
, "struct", 6))
2153 DoError(ERR_EXPECTED_STRUCT
, linenum
);
2156 in
.pos
= SkipBlanks(in
.pos
+6);
2158 DoError(ERR_EXPECTED_LIBTYPE
, linenum
);
2162 in
.pos
= SkipName(libtype
);
2163 if(*SkipBlanks(in
.pos
) != '*')
2164 DoError(ERR_EXPECTED_POINTERSIGN
, linenum
);
2171 DoError(ERR_COMMANDLINE_LIBTYPE
, linenum
);
2175 else if(!strnicmp(in
.pos
, "copyright", 9))
2177 Copyright
= SkipBlanks(in
.pos
+9);
2181 else if(!strnicmp(in
.pos
, "libname", 7))
2184 printf("ScanSFDFile: found ==libname\n");
2186 if(!(Flags2
& FLAG2_LIBNAME
))
2189 DoError(ERR_LIBNAME_DECLARED_TWICE
, linenum
);
2191 in
.pos
= SkipBlanks(in
.pos
+7);
2193 DoError(ERR_EXPECTED_LIBNAME
, linenum
);
2195 in
.pos
= SkipName(libname
= in
.pos
);
2198 DoError(ERR_COMMANDLINE_LIBNAME
, linenum
);
2202 else if(!strnicmp(in
.pos
, "base", 4))
2207 printf("ScanSFDFile: found ==base\n");
2209 if(!(Flags
& FLAG_BASENAME
))
2212 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
2214 in
.pos
= SkipBlanks(in
.pos
+4);
2216 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
2220 BaseName
= oldptr
= in
.pos
;
2221 in
.pos
= SkipName(in
.pos
);
2222 if(!(in
.pos
-oldptr
))
2223 DoError(ERR_EXPECTED_BASENAME
, linenum
);
2227 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
2232 else if(!strnicmp(in
.pos
, "bias", 4))
2238 printf("ScanSFDFile: found ==bias\n");
2241 newbias
= strtol(in
.pos
, &ptr
, 10);
2243 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
2244 else if(newbias
< 0)
2246 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
2251 in
.pos
= SkipName(in
.pos
);
2253 else if(!strnicmp(in
.pos
, "end", 3))
2257 else if(!strnicmp(in
.pos
, "public", 6))
2262 else if(!strnicmp(in
.pos
, "private", 7))
2267 else if(!strnicmp(in
.pos
, "abi", 3))
2270 printf("ScanSFDFile: found ==abi\n");
2272 in
.pos
= SkipBlanks(in
.pos
+3);
2273 if(!strnicmp(in
.pos
, "M68k", 4))
2275 abi
= ABI_M68K
; in
.pos
+= 4;
2277 else if(!strnicmp(in
.pos
, "PPC0", 4))
2279 abi
= ABI_PPC0
; in
.pos
+= 4;
2281 else if(!strnicmp(in
.pos
, "PPC2", 4))
2283 abi
= ABI_PPC2
; in
.pos
+= 4;
2285 else if(!strnicmp(in
.pos
, "PPC", 3))
2287 abi
= ABI_PPC
; in
.pos
+= 3;
2290 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
2292 else if(!strnicmp(in
.pos
, "id", 2))
2295 DoError(ERR_IDSTRING_DECLARED_TWICE
, linenum
);
2296 IDstring
= in
.pos
= SkipBlanks(in
.pos
+2);
2297 if(strncmp(in
.pos
, "$Id: ", 5))
2299 DoError(ERR_EXCPECTED_IDSTRING
, linenum
);
2303 if(*(in
.pos
-1) != '$')
2304 DoError(ERR_EXPECTED_ID_ENDSIGN
, linenum
);
2306 else if(!strnicmp(in
.pos
, "include", 7))
2310 if(!(d
= (struct Include
*) NewItem(&Includes
)))
2312 d
->Include
= SkipBlanks(in
.pos
+7);
2313 AddItem(&Includes
, (struct ShortList
*) d
);
2317 else if(!strnicmp(in
.pos
, "varargs", 7))
2320 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2324 bias
-= BIAS_OFFSET
;
2325 functype
|= FUNCFLAG_TAG
;
2329 else if(!strnicmp(in
.pos
, "alias", 5))
2332 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2336 bias
-= BIAS_OFFSET
;
2337 functype
|= FUNCFLAG_ALIAS
;
2341 else if(!strnicmp(in
.pos
, "version", 7))
2343 /* store version entries as comments */
2348 in
.pos
= SkipBlanks(in
.pos
+7);
2349 v
= strtol(in
.pos
, &ptr
, 10);
2351 printf("ScanSFDFile: found ==version %d\n", v
);
2353 if(ptr
== in
.pos
|| v
< 0)
2354 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2357 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2363 d
->Private
= _public
? 0 : 1;
2364 AddItem(&Comment
, (struct ShortList
*) d
);
2365 in
.pos
= SkipName(in
.pos
);
2368 else if(!strnicmp(in
.pos
, "reserve", 7))
2370 /* store reserved entries as comments */
2375 in
.pos
= SkipBlanks(in
.pos
+7);
2376 v
= strtol(in
.pos
, &ptr
, 10);
2378 printf("ScanSFDFile: found ==reserve %d\n", v
);
2382 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
2386 if(ptr
== in
.pos
|| v
< 0)
2387 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2390 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2396 d
->Private
= _public
? 0 : 1;
2397 AddItem(&Comment
, (struct ShortList
*) d
);
2398 in
.pos
= SkipName(in
.pos
);
2399 bias
+= BIAS_OFFSET
*v
;
2403 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
2407 uint32 ft
, startlinenum
;
2408 struct AmiPragma ap
, *ap2
;
2409 struct ClibData d
, *f
;
2415 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
2416 /* join lines, if necessary */
2417 startlinenum
= linenum
;
2419 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
) /* first open bracket */
2420 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2422 ft
= 0; /* this is needed for function pointer types, which have own brackets */
2423 while((*data
!= /*(*/')' || ft
) && data
< in
.buf
+ in
.size
) /* first close bracket */
2430 else if(*data
== '('/*)*/)
2432 else if(*data
== /*(*/')')
2436 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
) /* second open bracket */
2437 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2438 while(*data
!= /*(*/')' && data
< in
.buf
+ in
.size
) /* second close bracket */
2439 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2440 if(data
== in
.buf
+ in
.size
)
2443 DoError(ERR_UNEXPECTED_FILEEND
, linenum
);
2447 ft
= functype
; functype
= 0;
2448 memset(&ap
, 0, sizeof(struct AmiPragma
));
2449 memset(&d
, 0, sizeof(struct ClibData
));
2450 if(!GetCPPType(&d
.ReturnType
, in
.pos
, 1, 1))
2452 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE
, startlinenum
);
2457 else if(d
.ReturnType
.Unknown
)
2458 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, startlinenum
,
2459 d
.ReturnType
.Unknown
);
2461 ap
.FuncName
= d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
+d
.ReturnType
.FullLength
);
2462 in
.pos
= SkipBlanks(SkipName(d
.FuncName
));
2464 if(*in
.pos
!= '('/*)*/)
2466 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2470 *(SkipName(d
.FuncName
)) = 0;
2471 in
.pos
= SkipBlanks(++in
.pos
);
2474 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2476 oldptr
= (strptr
) 1;
2477 if(d
.NumArgs
>= maxreg
)
2479 DoError(ERR_TO_MUCH_ARGUMENTS
, startlinenum
);
2482 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], in
.pos
, 0, 0))
2484 DoError(ERR_UNKNOWN_VARIABLE_TYPE
, startlinenum
, d
.NumArgs
);
2487 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
2488 DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT
, startlinenum
, d
.NumArgs
,
2489 d
.Args
[d
.NumArgs
-1].Unknown
);
2491 oldptr
= in
.pos
= SkipBlanks(d
.Args
[d
.NumArgs
-1].TypeStart
+ d
.Args
[d
.NumArgs
-1].FullLength
);
2492 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
2494 if(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
)
2496 oldptr
= d
.Args
[d
.NumArgs
-1].FunctionName
;
2499 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2502 else if(!(oldptr
= DupString(oldptr
, SkipName(oldptr
)-oldptr
)))
2504 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
2508 ap
.Args
[ap
.CallArgs
++].ArgName
= in
.pos
;
2509 in
.pos
= SkipName(in
.pos
);
2511 if(in
.pos
== oldptr
)
2513 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2521 in
.pos
= SkipBlanks(in
.pos
);
2522 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
2524 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2529 in
.pos
= SkipBlanks(++in
.pos
);
2530 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
&& !(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
))
2531 *(SkipName(oldptr
)) = 0;
2533 printf("Added last argument %ld (%s) for %s (%ld bytes)\n", d
.NumArgs
, oldptr
, d
.FuncName
,
2534 d
.Args
[d
.NumArgs
-1].FullLength
);
2541 in
.pos
= SkipBlanks(++in
.pos
);
2542 *(SkipName(oldptr
)) = 0;
2544 printf("Added argument %ld (%s) for %s (%ld bytes)\n", d
.NumArgs
, oldptr
, d
.FuncName
,
2545 d
.Args
[d
.NumArgs
-1].FullLength
);
2549 if(*in
.pos
== /*(*/')')
2551 if(!oldptr
) /* oldptr == 0 means parsing was valid */
2553 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
2556 memcpy(f
, &d
, sizeof(struct ClibData
));
2562 struct ClibData
*e
= clibdata
;
2569 printf("Added prototype for %s (line %ld) with %ld args\n", f
->FuncName
, startlinenum
, f
->NumArgs
);
2571 if(*(in
.pos
= SkipBlanks(in
.pos
)) != '('/*)*/)
2573 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2580 DoError(ERR_ASSUMING_BIAS_OF_30
, startlinenum
);
2586 ap
.Line
= startlinenum
;
2587 bias
+= BIAS_OFFSET
;
2590 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
2594 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2596 if(*in
.pos
!= /*(*/')')
2598 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2603 ap
.NumArgs
= ap
.CallArgs
;
2605 ap
.Flags
|= AMIPRAGFLAG_PPC
;
2607 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
2608 else if(abi
== ABI_PPC2
)
2609 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
2619 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
2621 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
2624 in
.pos
= SkipName(oldptr
);
2625 len
= in
.pos
-oldptr
;
2627 for(i
= 0; i
< MAXREG
; ++i
)
2628 if(!strnicmp(RegNames
[i
], oldptr
, len
))
2633 DoError(ERR_EXPECTED_REGISTER_NAME
, startlinenum
);
2636 else if(i
== REG_A6
)
2637 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
2638 else if(i
== REG_A5
)
2639 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
2640 else if(i
== REG_A4
)
2641 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
2642 else if(i
== REG_D7
)
2643 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
2644 else if(i
== REG_A7
)
2646 DoError(ERR_A7_NOT_ALLOWED
, startlinenum
);
2649 else if(i
>= REG_FP0
)
2650 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
2652 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
2654 for(i
= 0; i
< ap
.NumArgs
; i
++)
2656 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
2658 DoError(ERR_REGISTER_USED_TWICE
, startlinenum
);
2667 in
.pos
= SkipBlanks(in
.pos
);
2668 if(*in
.pos
!= ',' && *in
.pos
!= '-' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
2670 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2673 } while(*in
.pos
!= /*(*/')');
2675 if(*in
.pos
!= /*(*/')')
2684 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
2685 if(ft
&& !(ft
& FUNCFLAG_TAG
) && ap
.NumArgs
!= ap2
->NumArgs
)
2686 ft
= 0; /* like DoPkt, handle as seperate function */
2687 if(ft
) /* handle alias and varargs */
2689 if(ap2
->TagName
|| (ft
& FUNCFLAG_ALIAS
))
2691 struct Pragma_AliasName
*p
;
2693 if((p
= (struct Pragma_AliasName
*)AllocListMem(sizeof(struct Pragma_AliasName
))))
2695 p
->FunctionName
= ap2
->TagName
;
2696 p
->AliasName
= ap
.FuncName
;
2697 p
->Type
= (ft
& FUNCFLAG_TAG
) ? FUNCFLAG_TAG
: FUNCFLAG_NORMAL
;
2698 AddAliasName(ap2
, p
, startlinenum
);
2705 ap2
->TagName
= ap
.FuncName
;
2708 if(ap
.CallArgs
!= ap2
->CallArgs
)
2710 if(ap2
->CallArgs
+ 1 == ap
.CallArgs
&& d
.Args
[d
.NumArgs
-1].Type
== CPP_TYPE_VARARGS
)
2717 if(ap
.NumArgs
!= ap2
->NumArgs
)
2719 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
2721 else if(abi
== ABI_M68K
)
2725 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
2727 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
2729 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
2735 else if(abi
== ABI_M68K
)
2737 if(ap
.CallArgs
!= ap
.NumArgs
)
2738 { /* this is surely no longer necessary, as there wont be any varargs functions here */
2739 if(ap
.CallArgs
== ap
.NumArgs
+1 && d
.Args
[d
.NumArgs
-1].Type
== CPP_TYPE_VARARGS
)
2742 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
2745 ap
.Flags
|= AMIPRAGFLAG_M68K
;
2747 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
2748 DoError(ERR_FLOATARG_NOT_ALLOWED
, startlinenum
);
2749 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
2750 && !(Flags
& FLAG_PPCONLY
))
2751 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
2752 struct AmiPragma
*d
;
2753 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
2755 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
2758 AddItem(&AmiPragma
, (struct ShortList
*) d
);
2763 if(!(Flags
& FLAG_NOPPC
))
2765 struct AmiPragma
*d
;
2766 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
2768 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
2771 AddItem(&AmiPragma
, (struct ShortList
*) d
);
2777 in
.pos
= SkipBlanks(in
.pos
);
2779 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
2780 ++in
.pos
; /* skip '\0' */
2784 DoError(ERR_MISSING_SFDEND
, 0);
2789 static uint32
ScanFDFile(void)
2796 uint32 shadowmode
= 0;
2797 uint32 abi
= ABI_M68K
;
2801 if(!stricmp(defabi
, "M68k"))
2803 else if(!stricmp(defabi
, "PPC0"))
2805 else if(!stricmp(defabi
, "PPC2"))
2807 else if(!stricmp(defabi
, "PPC"))
2810 DoError(ERR_UNKNOWN_ABI
, 0, defabi
);
2813 if(in
.size
> 10 && in
.pos
[0] == '=' && in
.pos
[1] == '=')
2814 return ScanSFDFile(abi
);
2817 printf("ScanFDFile:\n");
2820 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
2822 if(*in
.pos
== '*') /* Comment */
2824 strptr oldpos
= in
.pos
;
2826 printf("ScanFDFile: found a comment\n");
2828 in
.pos
= SkipBlanks(in
.pos
+1);
2829 if(!strnicmp(in
.pos
, "notagcall", 9))
2831 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
;
2835 --tagfuncs
; ap
->TagName
= 0;
2836 ap
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
2838 in
.pos
= SkipBlanks(in
.pos
+ 9);
2840 else if(!strnicmp(in
.pos
, "tagcall", 7)) /* Tag to create? */
2842 struct AmiPragma
*prevpragma
= (struct AmiPragma
*) AmiPragma
.Last
;
2844 in
.pos
= SkipBlanks(in
.pos
+ 7);
2847 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA
, linenum
);
2852 if(!prevpragma
->NumArgs
)
2854 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT
, linenum
);
2859 /* Get the tag functions name. */
2861 if(!prevpragma
->TagName
&& (_public
|| (Flags
& FLAG_PRIVATE
)))
2866 strptr oldptr
, tptr
= prevpragma
->TagName
;
2868 len
= strlen(prevpragma
->FuncName
)+strlen(in
.pos
)+1;
2869 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
)))
2876 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
2877 in
.pos
= SkipName(in
.pos
);
2878 if((len
= in
.pos
-oldptr
))
2880 removeptr
= prevpragma
->TagName
+strlen(prevpragma
->TagName
)-len
;
2881 if(strncmp(removeptr
, oldptr
, len
))
2884 printf("ScanFDFile: *tagcall -: %s, %s, %ld\n", removeptr
, oldptr
, len
);
2886 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
, linenum
);
2887 prevpragma
->TagName
= tptr
;
2894 in
.pos
= SkipBlanks(in
.pos
);
2897 in
.pos
= SkipBlanks(in
.pos
+1);
2899 *in
.pos
= toupper(*in
.pos
);
2901 in
.pos
= SkipName((oldptr
= in
.pos
));
2902 len
= in
.pos
-oldptr
;
2905 uint32 a
= strlen(prevpragma
->TagName
);
2906 memcpy(prevpragma
->TagName
+a
, oldptr
, len
);
2907 prevpragma
->TagName
[a
+len
] = '\0';
2910 else if(!prevpragma
->TagName
)
2912 len
= strlen(prevpragma
->FuncName
);
2913 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
+4)))
2915 memcpy(prevpragma
->TagName
+ len
, "Tags", 5);
2925 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2931 d
->Private
= _public
? 0 : 1;
2932 AddItem(&Comment
, (struct ShortList
*) d
);
2939 else if(*in
.pos
== '#' && in
.pos
[1] == '#')
2942 actcom
= 0; /* no Comment */
2944 if(!strnicmp(in
.pos
, "base", 4))
2949 printf("ScanFDFile: found ##base\n");
2951 if(!(Flags
& FLAG_BASENAME
))
2954 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
2956 in
.pos
= SkipBlanks(in
.pos
+4);
2958 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
2962 BaseName
= oldptr
= in
.pos
;
2963 in
.pos
= SkipName(in
.pos
);
2964 if(!(in
.pos
-oldptr
))
2965 DoError(ERR_EXPECTED_BASENAME
, linenum
);
2969 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
2974 else if(!strnicmp(in
.pos
, "bias", 4))
2980 printf("ScanFDFile: found ##bias\n");
2983 newbias
= strtol(in
.pos
, &ptr
, 10);
2985 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
2986 else if(newbias
< 0)
2988 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
2993 in
.pos
= SkipName(in
.pos
);
2995 else if(!strnicmp(in
.pos
, "end", 3))
2999 else if(!strnicmp(in
.pos
, "shadow", 6)) /* introduced by Storm */
3002 if(bias
== -1 || !AmiPragma
.First
)
3003 DoError(ERR_EARLY_SHADOW
, linenum
);
3006 bias
-= BIAS_OFFSET
;
3010 else if(!strnicmp(in
.pos
, "public", 6))
3015 else if(!strnicmp(in
.pos
, "private", 7))
3020 else if(!strnicmp(in
.pos
, "abi", 3))
3023 printf("ScanFDFile: found ##abi\n");
3025 in
.pos
= SkipBlanks(in
.pos
+3);
3026 if(!strnicmp(in
.pos
, "M68k", 4))
3028 abi
= ABI_M68K
; in
.pos
+= 4;
3030 else if(!strnicmp(in
.pos
, "PPC0", 4))
3032 abi
= ABI_PPC0
; in
.pos
+= 4;
3034 else if(!strnicmp(in
.pos
, "PPC2", 4))
3036 abi
= ABI_PPC2
; in
.pos
+= 4;
3038 else if(!strnicmp(in
.pos
, "PPC", 3))
3040 abi
= ABI_PPC
; in
.pos
+= 3;
3043 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
3046 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
3052 struct AmiPragma ap
, *ap2
;
3055 printf("ScanFDFile: scan Function\n");
3057 memset(&ap
, 0, sizeof(struct AmiPragma
));
3060 oldptr
= in
.pos
= SkipBlanks(in
.pos
);
3061 in
.pos
= SkipName(oldptr
);
3062 if(!(len
= in
.pos
-oldptr
))
3064 DoError(ERR_MISSING_FUNCTION_NAME
, linenum
);
3069 ap
.FuncName
= oldptr
;
3071 in
.pos
= SkipBlanks(in
.pos
);
3072 if(*in
.pos
!= '('/*)*/)
3074 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3079 oldptr
[len
] = '\0'; /* create c string of FunctionName */
3082 printf("ScanFDFile: found function %s\n", ap
.FuncName
);
3085 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
3088 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3090 if(*in
.pos
== '*') /* strange OS3.9 files */
3092 DoError(ERR_ILLEGAL_CHARACTER_DETECTED
, linenum
);
3093 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3096 if(*in
.pos
== /*(*/')' && !ap
.CallArgs
)
3099 if(ap
.CallArgs
>= maxreg
)
3101 DoError(ERR_TO_MUCH_ARGUMENTS
, linenum
); break;
3104 in
.pos
= SkipName(oldptr
);
3107 if(!(len
= in
.pos
-oldptr
))
3109 DoError(ERR_EXPECTED_ARGUMENT_NAME
, linenum
);
3110 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3114 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
3116 in
.pos
= SkipBlanks(in
.pos
);
3118 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3120 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3123 if(*in
.pos
!= /*(*/')') /* create c string ending */
3125 } while(*in
.pos
!= /*(*/')');
3127 if(*in
.pos
!= /*(*/')')
3134 *oldptr
= '\0'; /* create c string ending for last argument */
3138 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
3145 bias
+= BIAS_OFFSET
;
3148 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
3150 in
.pos
= SkipBlanks(in
.pos
+1);
3152 if(*in
.pos
|| ap
.CallArgs
)
3153 /* support for FD's without second empty bracket pair */
3155 if(*in
.pos
!= '('/*)*/)
3157 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3168 oldptr
= in
.pos
= SkipBlanks(in
.pos
+ 1);
3170 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
3173 in
.pos
= SkipName(oldptr
);
3174 len
= in
.pos
-oldptr
;
3176 for(i
= 0; i
< MAXREG
; ++i
)
3177 if(!strnicmp(RegNames
[i
], oldptr
, len
))
3182 DoError(ERR_EXPECTED_REGISTER_NAME
, linenum
);
3185 else if(i
== REG_A6
)
3186 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
3187 else if(i
== REG_A5
)
3188 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
3189 else if(i
== REG_A4
)
3190 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
3191 else if(i
== REG_D7
)
3192 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
3193 else if(i
== REG_A7
)
3195 DoError(ERR_A7_NOT_ALLOWED
, linenum
);
3198 else if(i
>= REG_FP0
)
3199 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
3201 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
3203 for(i
= 0; i
< ap
.NumArgs
; i
++)
3205 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
3207 DoError(ERR_REGISTER_USED_TWICE
, linenum
);
3216 in
.pos
= SkipBlanks(in
.pos
);
3217 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3219 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3222 } while(*in
.pos
!= /*(*/')');
3224 if(*in
.pos
!= /*(*/')')
3235 while(*in
.pos
&& *in
.pos
!= /*(*/')')
3237 if(*in
.pos
!= /*(*/')')
3239 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3244 ap
.NumArgs
= ap
.CallArgs
;
3246 ap
.Flags
|= AMIPRAGFLAG_PPC
;
3248 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
3249 else if(abi
== ABI_PPC2
)
3250 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
3254 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3256 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
3259 if(ap2
->TagName
&& !(ap2
->Flags
& AMIPRAGFLAG_OWNTAGFUNC
))
3261 struct Pragma_AliasName
*p
;
3262 DoError(ERR_DOUBLE_VARARGS
, linenum
);
3264 if((p
= (struct Pragma_AliasName
*)AllocListMem(sizeof(struct Pragma_AliasName
))))
3266 p
->FunctionName
= ap2
->TagName
;
3267 p
->AliasName
= ap
.FuncName
;
3268 p
->Type
= FUNCFLAG_TAG
;
3269 AddAliasName(ap2
, p
, linenum
);
3274 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2
->TagName
);
3280 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2
->TagName
);
3282 ap2
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3283 ap2
->TagName
= ap
.FuncName
;
3286 if(ap
.NumArgs
!= ap2
->NumArgs
)
3287 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3288 else if(abi
== ABI_M68K
)
3292 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3294 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3296 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3302 else if(ap2
&& ap2
->Bias
== ap
.Bias
&& ap2
->NumArgs
== ap
.NumArgs
) /* handle them as alias instead seperate */
3304 struct Pragma_AliasName
*p
;
3306 if((p
= (struct Pragma_AliasName
*)AllocListMem(sizeof(struct Pragma_AliasName
))))
3308 p
->FunctionName
= ap2
->TagName
;
3309 p
->AliasName
= ap
.FuncName
;
3310 p
->Type
= FUNCFLAG_NORMAL
;
3311 AddAliasName(ap2
, p
, linenum
);
3317 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3319 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3321 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3329 if((_public
|| (Flags
& FLAG_PRIVATE
)) && !MakeTagFunction(&ap
))
3331 else /* check the alias names */
3335 while(Pragma_AliasNames
[i
].FunctionName
)
3337 if(!strcmp(ap
.FuncName
, Pragma_AliasNames
[i
].FunctionName
) ||
3338 (ap
.TagName
&& !strcmp(ap
.TagName
, Pragma_AliasNames
[i
].FunctionName
)))
3340 AddAliasName(&ap
, (struct Pragma_AliasName
*) &Pragma_AliasNames
[i
], linenum
);
3348 if(ap
.CallArgs
!= ap
.NumArgs
)
3349 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3351 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3353 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3354 DoError(ERR_FLOATARG_NOT_ALLOWED
, linenum
);
3355 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3356 && !(Flags
& FLAG_PPCONLY
))
3357 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3358 struct AmiPragma
*d
;
3359 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3361 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3364 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3371 if(!(Flags
& FLAG_NOPPC
))
3373 struct AmiPragma
*d
;
3374 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3376 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3379 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3390 in
.pos
= SkipBlanks(in
.pos
);
3392 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3393 ++in
.pos
; /* skip '\0' */
3397 DoError(ERR_MISSING_END
, 0);
3402 static int32
ScanTypes(strptr ptr
, uint32 size
)
3404 struct CPP_ExternNames
*a
= 0, *b
= 0;
3405 strptr endptr
= ptr
+size
;
3408 for(line
= 1; ptr
< endptr
; ++line
)
3410 struct CPP_ExternNames
*n
;
3412 if(*ptr
== '*') /* skip comments */
3414 while(ptr
< endptr
&& *(ptr
++) != '\n')
3417 else if((n
= (struct CPP_ExternNames
*)
3418 AllocListMem(sizeof(struct CPP_ExternNames
))))
3422 n
->Type
= ptr
; /* store start */
3424 while(ptr
< endptr
&& *ptr
!= ':' && *ptr
!= '\n' && *ptr
!= '\t' && *ptr
!= ' ')
3426 wptr
= SkipBlanks(ptr
);
3427 if(*(wptr
++) != ':')
3431 n
->NameType
.StructureName
= n
->Type
;
3432 n
->NameType
.StructureLength
= ptr
-n
->Type
; /* for struct ! types */
3434 if(!GetCPPType(&n
->NameType
, (ptr
= SkipBlanks(wptr
)), 0, 1))
3437 printf("'%20s', slen %2ld, typelen %3ld, pntd %ld, type %lc, sn '%.3s'\n",
3438 n
->Type
, n
->NameType
.StructureLength
, n
->NameType
.FullLength
,
3439 n
->NameType
.PointerDepth
, n
->NameType
.Type
? n
->NameType
.Type
: 's',
3440 n
->NameType
.StructureName
? n
->NameType
.StructureName
: "<e>");
3442 ptr
= SkipBlanks(n
->NameType
.TypeStart
+n
->NameType
.FullLength
);
3443 if(*(ptr
++) != '\n')
3446 printf("%.30s\n", ptr
);
3460 extnames
= b
; /* now store the list */
3464 static void FindHeader(void)
3466 strptr str
= HEADER
;
3481 else if(*str
== '/')
3484 else if(*str
== '*' || *str
== ';')
3486 else if(*str
== '{'/*}*/)
3490 else if(*str
== '('/*)*/ && *(++str
) == '*')
3496 while(*str
&& *(str
++) != '\n')
3502 while(*str
&& (*(str
-1) != '*' || *str
!= '/'))
3504 while(*str
&& *(str
++) != '\n')
3509 while(*str
&& *str
!= /*{*/'}')
3511 while(*str
&& *(str
++) != '\n')
3516 while(*str
&& (*(str
-1) != '*' || *str
!= /*(*/')'))
3518 while(*str
&& *(str
++) != '\n')
3523 headersize
= str
-HEADER
;
3526 HEADER
= 0; headersize
= 0;
3530 /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
3531 static uint32
GetRegisterData(struct AmiPragma
*ap
)
3534 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
3535 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
3537 register uint32 i
, data
= 0, reg
;
3539 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3541 if((reg
= ap
->Args
[i
].ArgReg
) <= REG_FP0
)
3543 if(reg
>= 10 || (reg
>= 2 && reg
<= 7)) /* A2-A7 and D2-D7 */
3544 data
|= (1 << (reg
+ 16)) + (1 << (15 - reg
));
3547 if(data
) /* set A6 only when other register used */
3552 static uint16
GetFRegisterData(struct AmiPragma
*ap
)
3555 F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
3556 F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
3558 register uint32 i
, reg
;
3559 register uint16 data
= 0;
3561 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3563 if((reg
= ap
->Args
[i
].ArgReg
) >= REG_FP2
)
3566 data
|= (1 << (reg
+ 8)) + (1 << (7 - reg
));
3572 static uint32
OutputXDEF(uint32 offset
, strptr format
, ...)
3578 va_start(a
, format
);
3579 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3583 EndPutM32(buf
+4+i
, offset
); /* the definition offset */
3585 EndPutM32(buf
, (EXT_DEF
<<24) + (i
>>2));
3587 return DoOutputDirect(buf
, i
+8);
3590 static uint32
OutputXREF(uint32 offset
, uint32 type
, strptr format
, ...)
3596 va_start(a
, format
);
3597 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3601 EndPutM32(buf
+4+i
, 1); /* 1 reference */
3602 EndPutM32(buf
+8+i
, offset
); /* the definition offset */
3604 EndPutM32(buf
, (type
<< 24) + (i
>>2));
3606 return DoOutputDirect(buf
, i
+12);
3609 static uint32
OutputXREF2(uint32 offset1
, uint32 offset2
, uint32 type
, strptr format
, ...)
3615 va_start(a
, format
);
3616 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3620 EndPutM32(buf
+4+i
, 2); /* 2 references */
3621 EndPutM32(buf
+8+i
, offset1
); /* the definition offset */
3622 EndPutM32(buf
+12+i
, offset2
); /* the definition offset */
3624 EndPutM32(buf
, (type
<< 24) + (i
>>2));
3626 return DoOutputDirect(buf
, i
+16);
3629 static uint32
OutputSYMBOL(uint32 offset
, strptr format
, ...)
3635 va_start(a
, format
);
3636 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3640 EndPutM32(buf
+4+i
, offset
);
3642 EndPutM32(buf
, (0 << 24) + (i
>>2));
3644 return DoOutputDirect(buf
, i
+8);
3647 static uint8
*AsmStackCopy(uint8
*data
, struct AmiPragma
*ap
, uint32 flags
, uint32 ofs
)
3649 uint32 i
, j
, k
, l
, tofs
;
3651 if(Flags
& FLAG_PASCAL
)
3657 if(ap
->Args
[k
-1].ArgReg
>= REG_FP0
)
3659 struct ClibData
*cd
;
3661 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
3662 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
3664 if(cd
&& IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_DOUBLE
))
3666 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
3667 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
3672 if(!cd
|| !IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_FLOAT
))
3673 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
3674 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
3675 EndPutM16Inc(data
, (ofs
++) << 2);
3678 else if((k
>= 2) && (ap
->Args
[k
-1].ArgReg
< ap
->Args
[k
-2].ArgReg
)
3679 && ap
->Args
[k
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
3684 j
= ap
->Args
[--k
].ArgReg
;
3688 } while(k
&& j
< ap
->Args
[k
-1].ArgReg
&& ap
->Args
[k
-1].ArgReg
< REG_FP0
);
3689 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
3690 EndPutM16Inc(data
, l
);
3691 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
3695 l
= 0x202F; /* MOVE.L offs(A7),xxx */
3697 if((j
= ap
->Args
[--k
].ArgReg
) > 7)
3699 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
3701 EndPutM16Inc(data
, l
| (j
<< 9)); /* set destination register and store */
3702 EndPutM16Inc(data
, (ofs
++) << 2);
3710 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
3714 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
3716 struct ClibData
*cd
;
3718 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
3719 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
3721 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
3723 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
3724 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
3729 if(!cd
|| !IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
3730 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
3731 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
3732 EndPutM16Inc(data
, (ofs
++) << 2);
3735 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
)
3736 && ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
3741 j
= ap
->Args
[i
++].ArgReg
;
3745 } while(i
< k
&& j
< ap
->Args
[i
].ArgReg
&& ap
->Args
[i
].ArgReg
< REG_FP0
);
3746 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
3747 EndPutM16Inc(data
, l
); /* Store MOVEM.L data */
3748 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
3752 l
= 0x202F; /* MOVE.L offs(A7),xxx */
3754 if((j
= ap
->Args
[i
++].ArgReg
) > 7)
3756 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
3758 EndPutM16Inc(data
, l
| (j
<< 9)); /* set destination register and store */
3759 EndPutM16Inc(data
, (ofs
++) << 2);
3765 if((j
= ap
->Args
[i
].ArgReg
) > 7)
3767 EndPutM16Inc(data
, 0x41EF | ((j
-8) << 9)); /* LEA xxx(A7),Ax */
3768 EndPutM16Inc(data
, ofs
<< 2);
3772 EndPutM16Inc(data
, 0x200F | (j
<< 9)); /* MOVE.L A7,Dx */
3773 EndPutM16Inc(data
, 0x5080 | j
); /* ADDQ.L #8,Dx */
3777 EndPutM16Inc(data
, 0x486F); /* PEA xxx(A7) */
3778 EndPutM16Inc(data
, ofs
<< 2);
3779 EndPutM16Inc(data
, 0x201F | j
<< 9); /* MOVE.L offs(A7),Dx */
3786 /* ------------------------------------------------------------------ */
3788 static void DoError(uint32 errnum
, uint32 line
, ...)
3790 uint32 err
= errnum
& 0xFFFF;
3793 if(Flags
& FLAG_DIDERROR
)
3796 if(!Errors
[err
].Type
)
3797 Flags
|= FLAG_DIDERROR
;
3800 printf((line
? "%s %ld in line %ld%s: " : "%s %ld : "),
3801 (Errors
[err
].Type
? "Warning" : "Error"), err
, line
,
3802 errnum
& ERROFFSET_CLIB
? " of clib file" : "");
3803 vprintf(Errors
[err
].Error
, a
);
3805 if(line
&& Errors
[err
].Skip
)
3813 static uint32
CheckError(struct AmiPragma
*ap
, uint32 errflags
)
3815 errflags
&= ap
->Flags
;
3817 if(errflags
& AMIPRAGFLAG_ARGCOUNT
)
3819 if(!(ap
->Flags
& AMIPRAGFLAG_DIDARGWARN
))
3821 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
, ap
->Line
);
3822 ap
->Flags
|= AMIPRAGFLAG_DIDARGWARN
;
3826 else if(errflags
& AMIPRAGFLAG_FLOATARG
)
3828 if(!(ap
->Flags
& AMIPRAGFLAG_DIDFLOATWARN
))
3830 DoError(ERR_FLOATARG_NOT_ALLOWED
, ap
->Line
);
3831 ap
->Flags
|= AMIPRAGFLAG_DIDFLOATWARN
;
3835 else if(errflags
& AMIPRAGFLAG_A6USE
)
3837 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
3840 else if(errflags
& AMIPRAGFLAG_A5USE
)
3842 DoError(ERR_A5_NOT_ALLOWED
, ap
->Line
);
3845 else if(errflags
& AMIPRAGFLAG_PPC
)
3847 if(!(Flags
& FLAG_DIDPPCWARN
))
3849 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
3850 Flags
|= FLAG_DIDPPCWARN
;
3854 else if(errflags
& AMIPRAGFLAG_M68K
)
3856 if(!(Flags
& FLAG_DIDM68KWARN
))
3858 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
3859 Flags
|= FLAG_DIDM68KWARN
;
3867 static uint32
DoOutput(strptr format
, ...)
3874 va_start(a
, format
);
3875 if(vfprintf(outfile
, format
, a
) < 0)
3879 return Output_Error
;
3882 static uint32
DoOutputDirect(void * data
, size_t size
)
3888 if(fwrite(data
, size
, 1, outfile
) != 1)
3891 return Output_Error
;
3894 /* ------------------------------------------------------------------ */
3896 static struct ShortList
*NewItem(struct ShortListRoot
*list
)
3898 struct ShortList
*item
;
3899 if(!list
|| !list
->Size
)
3901 if(!(item
= (struct ShortList
*) AllocListMem(list
->Size
)))
3906 static struct ShortList
*RemoveItem(struct ShortListRoot
*list
,
3907 struct ShortList
*item
)
3909 struct ShortList
*n
= list
->First
;
3912 list
->First
= item
->Next
;
3915 while(n
&& n
->Next
!= item
)
3919 if(!(n
->Next
= item
->Next
))
3926 static void AddItem(struct ShortListRoot
*list
, struct ShortList
*item
)
3929 list
->First
= list
->Last
= item
;
3932 list
->Last
->Next
= item
;
3937 /* ------------------------------------------------------------------ */
3939 uint32
FuncAMICALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
3943 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
3946 Flags
|= FLAG_DONE
; /* We did something */
3948 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags
& FUNCFLAG_TAG
?
3949 "tagcall" : "amicall", BaseName
, ap
->Bias
, name
);
3951 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3953 DoOutput(RegNames
[ap
->Args
[i
].ArgReg
]);
3954 if(i
+1 < ap
->NumArgs
)
3958 return DoOutput(/*((*/"))\n");
3961 uint32
FuncLIBCALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
3965 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
3968 Flags
|= FLAG_DONE
; /* We did something */
3970 if(ap
->Flags
& AMIPRAGFLAG_FLOATARG
)
3972 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName
, name
, ap
->Bias
);
3973 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
3974 DoOutput("%02x", ap
->Args
[i
].ArgReg
);
3976 return DoOutput("00%02x\n", ap
->NumArgs
);
3979 if((Flags
& FLAG_SYSCALL
) && !strcmp(BaseName
,"SysBase") &&
3980 (flags
& FUNCFLAG_NORMAL
))
3981 DoOutput("#pragma syscall %-22s %03x ", name
, ap
->Bias
);
3983 DoOutput("#pragma %s %s %-22s %03x ", (flags
& FUNCFLAG_TAG
) ?
3984 "tagcall" : "libcall", BaseName
, name
, ap
->Bias
);
3986 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
3987 DoOutput("%x", ap
->Args
[i
].ArgReg
);
3989 return DoOutput("0%x\n", ap
->NumArgs
);
3992 uint32
FuncAsmText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
3999 struct ClibData
*cd
;
4001 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4004 Flags
|= FLAG_DONE
; /* We did something */
4006 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
4007 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
4009 if(Flags
& FLAG_SINGLEFILE
)
4011 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
4016 DoOutputDirect(HEADER
, headersize
);
4020 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
4022 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
4023 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
4026 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name
, name
);
4027 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4029 DoOutput("\tXDEF\t%s\n%s:\n",name
, name
);
4033 DoOutput("\tXDEF\t%s_\n%s_:\n",name
, name
);
4034 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4039 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4041 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4042 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name
, txt
, name
, txt
);
4048 if((registers
= GetRegisterData(ap
) >> 16))
4050 if(Flags
& FLAG_NOMOVEM
)
4052 for(i
= 0; i
<= 15; ++i
)
4054 if(registers
& (1 << i
))
4057 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper
[i
]);
4063 uint16 l
= registers
;
4065 DoOutput("\tMOVEM.L\t");
4067 for(i
= 0; i
<= 15; ++i
)
4073 DoOutput(RegNamesUpper
[i
]);
4078 DoOutput(",-(A7)\n");
4083 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset
;
4086 if((fregs
= GetFRegisterData(ap
) >> 8))
4090 DoOutput("\tFMOVEM.X\t");
4092 for(i
= 0; i
<= 7; ++i
)
4098 DoOutput(RegNamesUpper
[REG_FP0
+ i
]);
4103 DoOutput(",-(A7)\n");
4106 if(Flags
& FLAG_SMALLDATA
)
4108 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1
, BaseName
, c2
);
4111 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName
);
4113 if(!(Flags
& FLAG_PASCAL
))
4117 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4121 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4124 struct ClibData
*cd
;
4126 cd
= GetClibFunc(name
, ap
, flags
);
4127 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4128 t
= CPP_TYPE_DOUBLE
;
4129 else if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4133 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4137 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
? 'D' : 'S', c1
,
4138 offset
<<2, c2
, RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4140 if(t
== CPP_TYPE_DOUBLE
)
4144 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
) &&
4145 ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4147 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4148 RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4152 DoOutput("/%s", RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4154 } while((i
< k
) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
].ArgReg
) &&
4155 ap
->Args
[i
].ArgReg
< REG_FP0
);
4160 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4161 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4162 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4169 if(ap
->Args
[i
].ArgReg
> 7)
4170 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1
, offset
<<2, c2
,
4171 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4172 else if(offset
<= 2)
4173 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4174 RegNamesUpper
[ap
->Args
[i
].ArgReg
],offset
<<2,
4175 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4177 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1
,
4178 offset
<<2, c2
,RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4187 if(ap
->Args
[i
-1].ArgReg
>= REG_FP0
)
4190 struct ClibData
*cd
;
4192 cd
= GetClibFunc(name
, ap
, flags
);
4194 if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_DOUBLE
))
4195 t
= CPP_TYPE_DOUBLE
;
4196 else if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_FLOAT
))
4200 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4204 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
? 'D' : 'S',
4205 c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4206 if(t
== CPP_TYPE_DOUBLE
)
4210 else if((i
>= 2) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
-2].ArgReg
) &&
4211 ap
->Args
[i
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4213 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4214 RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4218 DoOutput("/%s", RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4220 } while(i
&& (ap
->Args
[i
].ArgReg
< ap
->Args
[i
-1].ArgReg
) &&
4221 ap
->Args
[i
-1].ArgReg
< REG_FP0
);
4227 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4228 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4229 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4234 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1
, ap
->Bias
, c2
);
4238 DoOutput("\tFMOVEM.X\t(A7)+,");
4240 for(i
= 0; i
<= 7; ++i
)
4242 if(fregs
& (1 << i
))
4245 DoOutput(RegNamesUpper
[REG_FP0
+ i
]);
4255 if(Flags
& FLAG_NOMOVEM
)
4257 for(i
= 15; i
>= 0; --i
)
4259 if(registers
& (1 << i
))
4260 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i
>= REG_A0
? "A" : "", RegNamesUpper
[i
]);
4265 DoOutput("\tMOVEM.L\t(A7)+,");
4267 for(i
= 0; i
<= 15; ++i
)
4269 if(registers
& (1 << i
))
4271 registers
^= 1 << i
;
4272 DoOutput(RegNamesUpper
[i
]);
4281 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4283 return DoOutput("\tRTS\n");
4286 uint32
FuncAsmCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4288 uint32 registers
, offset
= 1, baseref
;
4293 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4296 Flags
|= FLAG_DONE
; /* We did something */
4298 registers
= GetRegisterData(ap
);
4299 fregs
= GetFRegisterData(ap
);
4302 EndPutM32(tempbuf
, HUNK_UNIT
);
4303 EndPutM32(tempbuf
+4, (i
+3)>>2);
4304 DoOutputDirect(tempbuf
, 8);
4305 DoOutputDirect(name
, i
);
4306 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4308 i
= strlen(hunkname
);
4309 EndPutM32(tempbuf
, HUNK_NAME
);
4310 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
4311 DoOutputDirect(tempbuf
, 8);
4312 DoOutputDirect(hunkname
, i
);
4313 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4315 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
4319 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
4320 ++offset
; /* one long more on stack */
4324 if(Flags
& FLAG_NOMOVEM
)
4326 for(i
= 0; i
<= 15; ++i
)
4328 if(registers
& (1<< (16+i
)))
4330 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
4338 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
4339 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
4340 for(l
= (uint16
) registers
; l
; l
>>= 1)
4343 ++offset
; /* get offset addition */
4351 EndPutM16Inc(data
, 0xF227); /* FMOVEM.X xxx,-(A7) */
4352 EndPutM16Inc(data
, 0xE000 + ((fregs
>>8)&0xFF));
4353 for(l
= (uint8
) fregs
; l
; l
>>= 1)
4356 offset
+=3; /* get offset addition */
4360 baseref
= (data
-tempbuf
)-8+2; /* one word later (MOVE) - 2 header longs */
4361 if(Flags
& FLAG_SMALLDATA
)
4363 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
4364 EndPutM16Inc(data
, 0); /* place for base reference */
4368 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
4369 EndPutM32Inc(data
, 0); /* place for base reference */
4372 data
= AsmStackCopy(data
, ap
, flags
, offset
);
4374 /* here comes the base reference */
4375 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
4376 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
4380 EndPutM16Inc(data
, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4381 EndPutM16Inc(data
, 0xD000 + (fregs
&0xFF));
4386 if(Flags
& FLAG_NOMOVEM
)
4389 for(i
= 15; i
>= 0; --i
)
4391 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
4392 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
4397 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4398 EndPutM16Inc(data
, (registers
>> 16)); /* store MOVEM.L registers */
4402 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
4403 EndPutM16Inc(data
, 0x4E75); /* RTS */
4405 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
4407 EndPutM32(tempbuf
, HUNK_CODE
);
4408 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
4409 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
4411 EndPutM32(tempbuf
, HUNK_EXT
);
4412 DoOutputDirect(tempbuf
, 4);
4414 OutputXREF(baseref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "_%s", BaseName
);
4415 /* here come the XDEF name references */
4416 OutputXDEF(0, "_%s", name
); /* C name */
4418 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4420 struct ClibData
*cd
;
4421 OutputXDEF(0, "%s", name
); /* ASM name */
4426 OutputXDEF(0, "%s_", name
); /* C++ name no parameters */
4427 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4429 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4431 if(CopyCPPType((strptr
)tempbuf
, i
, cd
, ap
->Args
))
4432 OutputXDEF(0, "%s__%s", name
, tempbuf
);
4438 EndPutM32(tempbuf
, 0);
4439 DoOutputDirect(tempbuf
, 4);
4440 if(!(Flags
& FLAG_NOSYMBOL
))
4442 EndPutM32(tempbuf
, HUNK_SYMBOL
);
4443 DoOutputDirect(tempbuf
, 4);
4444 OutputSYMBOL(0, "_%s", name
); /* C name */
4446 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4448 struct ClibData
*cd
;
4449 OutputSYMBOL(0, "%s", name
); /* ASM name */
4454 OutputSYMBOL(0, "%s_", name
); /* C++ name no parameters */
4455 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4457 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4459 if(CopyCPPType((strptr
) data
, i
, cd
, ap
->Args
))
4460 OutputSYMBOL(0, "%s__%s", name
, (strptr
) data
);
4466 EndPutM32(tempbuf
, 0);
4467 DoOutputDirect(tempbuf
, 4);
4470 EndPutM32(tempbuf
, HUNK_END
);
4471 return DoOutputDirect(tempbuf
, 4);
4474 /* Directly called by FuncInline and FuncInlineDirect also! */
4475 uint32
FuncCSTUBS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4477 struct ClibData
*f
, *t
;
4478 strptr ret
= "return ";
4481 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4484 Flags
|= FLAG_DONE
; /* We did something */
4486 if(!(f
= GetClibFunc(ap
->FuncName
, ap
, 0)))
4488 t
= GetClibFunc(name
, ap
, flags
);
4490 if(flags
& FUNCFLAG_EXTENDMODE
)
4492 sprintf(tempbuf
, "___%s", name
);
4496 if(IsCPPType(&f
->ReturnType
, CPP_TYPE_VOID
))
4499 if(!OutClibType(&f
->ReturnType
, name
) || !DoOutput("("/*)*/))
4501 if(flags
& FUNCFLAG_EXTENDMODE
)
4503 DoOutput("%s %s, ", GetBaseType(), BaseName
);
4506 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4508 if(!OutClibType(&f
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4511 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4513 if(!OutClibType(&t
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4516 else if(ap
->NumArgs
== 1 && !DoOutput("ULONG tag, "))
4519 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret
, ap
->FuncName
))
4521 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4523 if(!DoOutput("%s, ", ap
->Args
[i
].ArgName
))
4526 if(!DoOutput("("/*)*/) || !OutClibType(&f
->Args
[ap
->NumArgs
-1],0))
4529 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4531 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap
->Args
[ap
->NumArgs
-1].ArgName
))
4534 else if(ap
->NumArgs
== 1)
4536 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4539 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4540 ap
->Args
[ap
->NumArgs
-2].ArgName
) || !OutClibType(&f
->Args
[ap
->NumArgs
-2],0)
4541 || !DoOutput(/*(((*/")));\n}\n\n"))
4546 uint32
FuncLVOXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4548 Flags
|= FLAG_DONE
; /* We did something */
4549 return DoOutput("\t\tXDEF\t_LVO%s\n", name
);
4552 uint32
FuncLVO(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4554 Flags
|= FLAG_DONE
; /* We did something */
4555 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name
, ap
->Bias
);
4558 uint32
FuncLVOPPCXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4560 Flags
|= FLAG_DONE
; /* We did something */
4561 return DoOutput("\t.globl\t%sLVO%s\n", Flags
& FLAG_ABIV4
? "" : "_", name
);
4564 uint32
FuncLVOPPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4566 Flags
|= FLAG_DONE
; /* We did something */
4567 return DoOutput(".set\t%sLVO%s,-%d\n", Flags
& FLAG_ABIV4
? "" : "_", name
, ap
->Bias
);
4570 uint32
FuncLVOPPCBias(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4572 Flags
|= FLAG_DONE
; /* We did something */
4574 EndPutM32Inc(elfbufpos
, symoffset
); /* st_name */
4575 symoffset
+= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1) + 1;
4576 EndPutM32Inc(elfbufpos
, -ap
->Bias
); /* st_value */
4577 EndPutM32Inc(elfbufpos
, 0); /* st_size */
4578 *(elfbufpos
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* st_info */
4579 *(elfbufpos
++) = 0; /* st_other */
4580 EndPutM16Inc(elfbufpos
, SHN_ABS
); /* st_shndx */
4585 uint32
FuncLVOPPCName(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4587 Flags
|= FLAG_DONE
; /* We did something */
4588 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
4589 return DoOutputDirect("", 1);
4592 uint32
FuncLVOLib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4596 Flags
|= FLAG_DONE
; /* We did something */
4597 j
= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1);
4598 EndPutM32(tempbuf
, (EXT_ABS
<< 24) + ((j
+3)>>2));
4600 DoOutputDirect(tempbuf
, 4);
4601 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
4602 DoOutputDirect("\0\0\0", ((j
+3)&(~3))-j
);
4603 EndPutM32(tempbuf
, -ap
->Bias
);
4604 return DoOutputDirect(tempbuf
, 4);
4607 uint32
FuncLocCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4609 strptr str2
= Flags
& FLAG_LOCALREG
? "rE" : "";
4612 struct ClibData
*cd
= 0;
4614 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4617 Flags
|= FLAG_DONE
; /* We did something */
4620 EndPutM32(tempbuf
, HUNK_UNIT
);
4621 EndPutM32(tempbuf
+4, (i
+3)>>2);
4622 DoOutputDirect(tempbuf
, 8);
4623 DoOutputDirect(name
, i
);
4624 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4626 i
= strlen(hunkname
);
4627 EndPutM32(tempbuf
, HUNK_NAME
);
4628 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
4629 DoOutputDirect(tempbuf
, 8);
4630 DoOutputDirect(hunkname
, i
);
4631 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4633 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
4635 if(Flags
& FLAG_LOCALREG
)
4637 if((flags
& FUNCFLAG_TAG
))
4639 i
= ap
->Args
[ap
->NumArgs
-1].ArgReg
;
4640 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE <ea>,-(A7) */
4644 EndPutM16Inc(data
, 0x41EF | ((i
-8) << 9)); /* LEA 8(A7),Ax */
4645 EndPutM16Inc(data
, 8);
4649 EndPutM16Inc(data
, 0x200F | (i
<< 9)); /* MOVE.L A7,Dx */
4650 EndPutM16Inc(data
, 0x5080 | i
); /* ADDQ.L #8,Dx */
4653 EndPutM16Inc(data
, 0x4EAE);
4654 EndPutM16Inc(data
, -ap
->Bias
); /* JSR instruction */
4656 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6)); /* MOVE (A7)+,<ea> */
4657 EndPutM16Inc(data
, 0x4E75); /* RTS */
4661 EndPutM16Inc(data
, 0x4EEE);
4662 EndPutM16Inc(data
, -ap
->Bias
); /* JMP instruction */
4667 uint32 registers
, offset
= 1;
4669 registers
= GetRegisterData(ap
);
4671 if(!registers
) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
4673 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
4674 ++offset
; /* one long more on stack */
4678 if(Flags
& FLAG_NOMOVEM
)
4680 for(i
= 0; i
<= 15; ++i
)
4682 if(registers
& (1<< (16+i
)))
4684 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
4691 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
4692 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
4693 for(i
= registers
&0xFFFF; i
; i
>>= 1)
4696 ++offset
; /* get offset addition */
4701 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
)) /* store library base in A6 */
4703 EndPutM16Inc(data
, 0x2C6F); /* MOVE.L ofs(A7),A6 */
4704 EndPutM16Inc(data
, (offset
++) << 2);
4707 data
= AsmStackCopy(data
, ap
, flags
, offset
);
4709 /* here comes the base reference */
4710 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
4711 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
4714 if(Flags
& FLAG_NOMOVEM
)
4716 for(i
= 15; i
>= 0; --i
)
4718 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
4719 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
4724 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4725 EndPutM16Inc(data
, registers
>> 16); /* store MOVEM.L registers */
4729 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
4731 EndPutM16Inc(data
, 0x4E75); /* RTS */
4734 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
4736 EndPutM32(tempbuf
, HUNK_CODE
);
4737 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
4738 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
4740 EndPutM32(tempbuf
, HUNK_EXT
);
4741 DoOutputDirect(tempbuf
,4);
4743 /* here come the XDEF name references */
4745 if(!(Flags
& FLAG_ONLYCNAMES
))
4747 OutputXDEF(0, "%s", name
); /* ASM names */
4748 OutputXDEF(0, "LOC_%s", name
);
4751 OutputXDEF(0, "_%s", name
); /* C names */
4752 OutputXDEF(0, "_LOC_%s", name
);
4754 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
4758 OutputXDEF(0, "%s__%sP07Library", name
, str2
); /* C++ names no parameters */
4759 OutputXDEF(0, "LOC_%s__%sP07Library", name
, str2
);
4761 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4765 txt
= (strptr
) tempbuf
;
4767 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4769 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4770 { /* C++ names with parameters */
4771 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
4773 OutputXDEF(0, "%s__%sP07Library%s", name
, str2
, txt
);
4774 OutputXDEF(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
4778 OutputXDEF(0, "%s__%s", name
, txt
);
4779 OutputXDEF(0, "LOC_%s__%s", name
, txt
);
4786 EndPutM32(tempbuf
, 0);
4787 DoOutputDirect(tempbuf
,4);
4788 if(!(Flags
& FLAG_NOSYMBOL
))
4790 EndPutM32(tempbuf
, HUNK_SYMBOL
);
4791 DoOutputDirect(tempbuf
,4);
4792 if(!(Flags
& FLAG_ONLYCNAMES
))
4794 OutputSYMBOL(0, "%s", name
); /* ASM names */
4795 OutputSYMBOL(0, "LOC_%s", name
);
4798 OutputSYMBOL(0, "_%s", name
); /* C names */
4799 OutputSYMBOL(0, "_LOC_%s", name
);
4801 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
4805 OutputSYMBOL(0, "%s__%sP07Library", name
, str2
); /* C++ names no parameters */
4806 OutputSYMBOL(0, "LOC_%s__%sP07Library", name
, str2
);
4812 txt
= (strptr
) tempbuf
;
4814 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4816 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4817 { /* C++ names with parameters */
4818 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
4820 OutputSYMBOL(0, "%s__%sP07Library%s", name
, str2
, txt
);
4821 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
4825 OutputSYMBOL(0, "%s__%s", name
, txt
);
4826 OutputSYMBOL(0, "LOC_%s__%s", name
, txt
);
4833 EndPutM32(tempbuf
, 0);
4834 DoOutputDirect(tempbuf
,4);
4836 EndPutM32(tempbuf
, HUNK_END
);
4837 return DoOutputDirect(tempbuf
,4);
4840 uint32
FuncLocText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4842 struct ClibData
*cd
;
4845 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4848 Flags
|= FLAG_DONE
; /* We did something */
4850 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
4853 OutClibType(&cd
->ReturnType
, 0);
4854 DoOutput(" LOC_%s("/*)*/, name
);
4855 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
4857 if(Flags
& FLAG_LOCALREG
)
4858 DoOutput("register __a6 ");
4859 DoOutput("%s libbase", GetBaseType());
4866 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4868 if(((Flags
& FLAG_LOCALREG
&&
4869 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
4870 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4874 if(flags
& FUNCFLAG_NORMAL
)
4876 if(((Flags
& FLAG_LOCALREG
&&
4877 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
4878 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) ||
4879 !DoOutput(/*(*/");\n"))
4883 DoOutput("#define %s("/*)*/, name
);
4884 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4885 DoOutput("%c, ", 'a'+(char)i
);
4886 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i
, name
, BaseName
);
4887 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4888 DoOutput("%c, ",'a'+(char)i
);
4889 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i
);
4893 return DoOutput(/*(*/"...);\n");
4896 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
4899 return DoOutput(/*(*/");\n");
4903 uint32
FuncInlineDirect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4905 uint32 a4
= 0, a5
= 0;
4907 int32 i
, maxargs
, reg
=0;
4908 struct ClibData
*cd
;
4910 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4913 Flags
|= FLAG_DONE
; /* We did something */
4915 if(flags
& FUNCFLAG_ALIAS
)
4917 if(flags
& FUNCFLAG_TAG
)
4918 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
4921 DoOutput("#define %s("/*)*/, name
);
4922 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4923 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
4924 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
4925 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4926 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
4927 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
4930 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
4933 if(flags
& FUNCFLAG_TAG
)
4935 /* do not create MUI_NewObject */
4936 if(!strcmp(name
, "MUI_NewObject") || !strcmp(name
, "PM_MakeItem"))
4937 DoOutput("#if !defined(NO_INLINE_STDARG) && defined(SPECIALMACRO_INLINE_STDARG)\n");
4939 DoOutput("#ifndef NO_INLINE_STDARG\n");
4940 DoOutput("static __inline__ ");
4941 FuncCSTUBS(ap
, flags
|FUNCFLAG_EXTENDMODE
, name
);
4943 DoOutput("#define %s("/*)*/, name
);
4944 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4946 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
4950 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name
, ShortBaseNameUpper
);
4951 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4952 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
4955 DoOutput(/*(*/")\n");
4956 return DoOutput("#endif\n\n");
4959 DoOutput("#define %s("/*)*/, name
);
4962 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
4963 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
4964 DoOutput("%s", ap
->Args
[i
].ArgName
);
4966 DoOutput(/*(*/") ({ \\\n"/*})*/);
4968 for(i
= 0; i
< ap
->NumArgs
; ++i
)
4970 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
4972 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
4973 DoOutput(" = (%s); \\\n", ap
->Args
[i
].ArgName
);
4975 if(Flags
& FLAG_INLINENEW
)
4978 DoOutput(" ({ \\\n"/*})*/);
4979 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name
);
4981 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper
);
4984 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
4986 if(i
== ap
->NumArgs
)
4988 DoOutput("(%s);\\\n", ap
->Args
[i
].ArgName
);
4991 DoOutput(" (("/*))*/);
4992 OutClibType(&cd
->ReturnType
, 0);
4993 DoOutput(" (*)("/*)*/);
4996 DoOutput("char * __asm(\"a6\")");
5000 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5002 OutClibType(&cd
->Args
[i
], 0);
5003 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
5004 if(i
< ap
->NumArgs
-1)
5007 DoOutput(/*((*/")) \\\n");
5008 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name
, ap
->Bias
);
5011 DoOutput("_%s__bn", name
);
5015 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5017 if(ap
->Args
[i
].ArgReg
== REG_A6
)
5018 DoOutput("_%s__bn", name
);
5020 DoOutput("_%s_%s", name
, ap
->Args
[i
].ArgName
);
5021 if(i
< ap
->NumArgs
-1)
5024 DoOutput(/*(*/"); \\\n");
5026 DoOutput(/*({*/"});");
5030 /* do A5 first, as it is more important */
5031 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5033 a5
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5034 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5035 a5
|= 1<<ap
->Args
[i
].ArgReg
;
5039 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A5
]);
5044 for(i
= 0; (a5
& 1) && a5
; ++i
)
5046 a5
= i
; /* this is our A5 swap register */
5049 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5051 a4
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5054 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5055 a4
|= 1<<ap
->Args
[i
].ArgReg
;
5059 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A4
]);
5064 for(i
= 0; (a4
& 1) && a4
; ++i
)
5066 a4
= i
; /* this is our A4 swap register */
5069 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5070 noret
= 1; /* this is a void function */
5073 sprintf((strptr
)tempbuf
, "_%s__re", name
);
5075 OutClibType(&cd
->ReturnType
, (strptr
) tempbuf
);
5076 DoOutput(" = \\\n");
5078 if(ap
->NumArgs
|| !noret
)
5079 DoOutput(" %s{ \\\n", noret
? "" : "(" /*})*/);
5081 DoOutput(" register %s const __%s__bn __asm(\"a6\") = (%s) (%s_BASE_NAME);\\\n",
5082 GetBaseType(), name
, GetBaseType(), ShortBaseNameUpper
);
5086 sprintf((strptr
)tempbuf
, "__%s__re", name
);
5087 DoOutput(" register ");
5088 OutClibType(&cd
->ReturnType
, (strptr
) tempbuf
);
5089 DoOutput(" __asm(\"d0\"); \\\n");
5091 if((maxargs
= ap
->NumArgs
) >= 9 && (Flags
& FLAG_STORMGCC
))
5093 for(i
= 0; i
< maxargs
; ++i
)
5095 reg
= ap
->Args
[i
].ArgReg
;
5096 if(a5
&& reg
== REG_A5
) reg
= a5
; /* we need to switch */
5097 if(a4
&& reg
== REG_A4
) reg
= a4
; /* we need to switch */
5099 sprintf((strptr
)tempbuf
, "__%s_%s", name
, ap
->Args
[i
].ArgName
);
5100 DoOutput(" register ");
5101 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5102 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames
[reg
], (strptr
) (tempbuf
+1));
5104 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5106 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name
);
5107 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5109 DoOutput(" ULONG __%s_%s; \\\n", name
, ap
->Args
[i
].ArgName
);
5110 reg
= ap
->Args
[i
].ArgReg
;
5115 else if(reg
== REG_A5
)
5120 /* reg is now either the last register argument or its a4/a5 redirect */
5121 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name
);
5122 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5124 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5125 DoOutput("(ULONG)(%s)%s", (strptr
)tempbuf
, i
== ap
->NumArgs
-1 ? "" : ", ");
5127 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr *__%s__ArgsPtr __asm(\"%s\")"
5128 " = &(__%s__Args); \\\n", name
, name
, RegNames
[reg
], name
);
5130 DoOutput(" __asm volatile (\""/*)*/);
5131 if(a5
) DoOutput("exg a5,%s\\n\\t", RegNames
[a5
]);
5132 if(a4
) DoOutput("exg a4,%s\\n\\t", RegNames
[a4
]);
5133 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5135 DoOutput("movem.l ");
5136 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5138 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5139 i
== ap
->NumArgs
-1 ? "" : "/");
5141 DoOutput(",-(a7)\\n\\t");
5142 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5145 DoOutput("move.l (%s),%s\\n\\t", RegNames
[reg
],
5146 RegNames
[ap
->Args
[i
].ArgReg
]);
5148 DoOutput("move.l %ld(%s),%s\\n\\t", (i
-maxargs
)*4, RegNames
[reg
],
5149 RegNames
[ap
->Args
[i
].ArgReg
]);
5152 DoOutput("jsr a6@(-%d:W)", ap
->Bias
);
5153 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5155 DoOutput("\\n\\tmovem.l (a7)+,");
5156 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5158 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5159 i
== ap
->NumArgs
-1 ? "" : "/");
5162 if(a4
) DoOutput("\\n\\texg a4,%s", RegNames
[a4
]);
5163 if(a5
) DoOutput("\\n\\texg a5,%s", RegNames
[a5
]);
5164 DoOutput("\" \\\n");
5167 DoOutput(" : \\\n");
5169 DoOutput(" : \"=r\"(__%s__re) \\\n", name
);
5172 DoOutput(" \"r\"(__%s__bn)%s", name
, ap
->NumArgs
? "," : "");
5173 for(i
= 0; i
< maxargs
; ++i
)
5175 DoOutput(" \"r\"(__%s_%s)", name
, ap
->Args
[i
].ArgName
);
5176 if(i
< ap
->NumArgs
-1)
5179 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5180 DoOutput(" \"r\"(__%s__ArgsPtr)", name
);
5181 DoOutput(/*(*/" \\\n : %s\"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n",
5182 noret
? "\"d0\", " : "");
5185 DoOutput(" __%s__re; \\\n", name
);
5187 if(ap
->NumArgs
|| !noret
)
5188 DoOutput(/*({*/" }%s \\\n", noret
? "" : ");");
5191 DoOutput(" _%s__re; \\\n", name
);
5194 return DoOutput(/*({*/"})\n\n");
5197 uint32
FuncInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5199 uint32 noret
= 0, a45
= 0, j
;
5201 struct ClibData
*cd
;
5203 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5206 Flags
|= FLAG_DONE
; /* We did something */
5208 if(flags
& FUNCFLAG_ALIAS
)
5210 if(flags
& FUNCFLAG_TAG
)
5211 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5212 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
5214 DoOutput("#define %s("/*)*/, name
);
5215 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5216 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5217 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5218 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5219 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5220 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5223 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5226 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5227 noret
= 1; /* this is a void function */
5229 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5231 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5235 DoError(ERR_INLINE_A4_AND_A5
, ap
->Line
);
5236 return 1; /* skip this entry */
5240 if(a45
&& (ap
->Flags
& AMIPRAGFLAG_D7USE
))
5242 DoError(ERR_INLINE_D7_AND_A45
, ap
->Line
);
5243 return 1; /* skip this entry */
5246 if((flags
& FUNCFLAG_TAG
))
5248 if(Flags
& FLAG_INLINENEW
)
5250 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5251 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "");
5252 if(!strcmp(name
, "MUI_NewObject") || !strcmp(name
, "PM_MakeItem"))
5254 DoOutput("__inline ");
5255 FuncCSTUBS(ap
, flags
, name
);
5256 /* call CSTUBS, as this equals the method used there */
5260 DoOutput("#define %s("/*)*/, name
);
5261 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5263 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5265 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5267 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5268 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5270 OutClibType(&cd
->Args
[i
], 0);
5271 DoOutput(/*({((*/") _tags);})\n");
5273 return DoOutput("#endif\n\n");
5275 else if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
)) == (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5277 int32 n
, d
, tagl
, local
;
5281 tagl
= 8 + (Flags2
& FLAG2_DIRECTVARARGS
? 0 : 64);
5282 local
= (n
* 4+d
+8+15) & ~15; /* size of the stack frame */
5285 * 0- 3: next frame ptr
5288 * 72-72+n*4+d+8-1: tag list start
5289 * ?-local-1: padding
5292 DoOutput("asm(\"\n"/*)*/
5295 "\t.type\t%s,@function\n"
5297 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5299 "\tstw\t0,%ld(1)\n",
5300 name
, name
, name
, local
, local
+4);
5302 /* If n is odd, one tag is split between regs and stack.
5303 * Copy its ti_Data together with the ti_Tag. */
5305 DoOutput("\tlwz\t0,%ld(1)\n", local
+8); /* read ti_Data */
5307 /* Save the registers */
5308 for(i
= ap
->NumArgs
; i
<= 8; ++i
)
5309 DoOutput("\tstw\t%ld,%ld(1)\n", i
+2, (i
-ap
->NumArgs
) * 4+tagl
);
5312 DoOutput("\tstw\t0,%ld(1)\n", tagl
+n
* 4); /* write ti_Data */
5315 DoOutput("\tli\t0,2\n"
5316 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5318 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5319 tagl
+n
* 4+d
, local
+8+d
, tagl
+n
* 4+d
+4);
5321 if(Flags2
& FLAG2_DIRECTVARARGS
)
5323 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5324 "\tbl\t%s\n", ap
->NumArgs
+2, tagl
, name
);
5331 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
5334 /* Caos.Offset = -fD_GetOffset(obj) */
5335 DoOutput("\tli\t0,%d\n"
5336 "\tstw\t0,8(1)\n", -ap
->Bias
);
5338 /* Save the non-varargs registers in the Caos struct. */
5339 for(i
=0; i
< ap
->NumArgs
-1; ++i
)
5341 DoOutput("\tstw\t%ld,%d(1)\n", i
+3, 8+4+(ap
->Args
[i
].ArgReg
* 4));
5344 DoOutput("\taddi\t0,1,%ld\n"
5346 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5347 "\tlwz\t12,%s@l(3)\n"
5349 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5352 "\tbctrl\n", /* EmulCallOS() */
5353 tagl
, BaseName
, 12+(4 * ap
->Args
[i
].ArgReg
), BaseName
);
5355 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5359 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local
+4, local
, name
, name
);
5363 DoOutput("%s%s__inline ", Flags
& FLAG_INLINESTUB
? "" : "extern ",
5364 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5365 return FuncCSTUBS(ap
, flags
, name
);
5366 /* call CSTUBS, as this equals the method used there */
5370 if(Flags
& FLAG_INLINENEW
) /* new style */
5372 strptr funcpar
= "";
5373 DoOutput("#define %s("/*)*/, name
);
5375 for(i
= 0; i
< cd
->NumArgs
; ++i
)
5377 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5383 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5384 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5385 DoOutput("%s", ap
->Args
[i
].ArgName
);
5387 DoOutput(/*(*/") \\\n\tLP%d%s%s%s%s(0x%x, "/*)*/, ap
->NumArgs
,
5388 (noret
? "NR" : ""), (a45
? RegNamesUpper
[a45
] : (strptr
) ""),
5389 (BaseName
? "" : "UB"), funcpar
, ap
->Bias
);
5392 OutClibType(&cd
->ReturnType
, 0);
5395 DoOutput("%s, ", name
);
5397 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5399 j
= ap
->Args
[i
].ArgReg
;
5400 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5402 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5406 DoError(ERR_MULTIPLEFUNCTION
, ap
->Line
);
5411 DoOutput("__fpt"); fp
= i
;
5415 OutClibType(&cd
->Args
[i
], 0);
5417 DoOutput(", %s, %s%s", ap
->Args
[i
].ArgName
, RegNames
[j
],
5418 (i
== ap
->NumArgs
-1 && !BaseName
? "" : ", "));
5421 if(BaseName
) /* was "##base" used? */
5422 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper
);
5427 OutClibType(&cd
->Args
[fp
], "__fpt");
5430 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
5431 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5433 return DoOutput(/*(*/")\n\n");
5436 /* old mode or stubs mode */
5438 if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
)) != (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5439 DoOutput("%s%s__inline ", Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
) ? "" : "extern ",
5440 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5441 OutClibType(&cd
->ReturnType
, 0);
5442 DoOutput("\n%s(%s"/*)*/, name
, (BaseName
?
5443 (ap
->NumArgs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5445 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5447 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5448 if(i
< ap
->NumArgs
-1)
5452 if(Flags
& FLAG_POWERUP
)
5454 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5455 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5456 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5457 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5458 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5459 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5460 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5464 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5466 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5467 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5471 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5474 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper
);
5475 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5476 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5479 DoOutput("\treturn(("/*))*/);
5480 OutClibType(&cd
->ReturnType
, 0);
5481 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5483 return Output_Error
;
5485 else if( Flags
& FLAG_MORPHOS
)
5487 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5491 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5493 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5494 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5498 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5500 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper
);
5502 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5503 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5506 DoOutput("\treturn(("/*))*/);
5507 OutClibType(&cd
->ReturnType
, 0);
5508 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5510 return Output_Error
;
5513 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName
? " BASE_EXT_DECL\n" : ""));
5517 DoOutput(" register ");
5518 OutClibType(&cd
->ReturnType
, "res");
5519 DoOutput(" __asm(\"d0\");\n");
5523 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n", GetBaseType(), ShortBaseNameUpper
);
5525 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5527 j
= ap
->Args
[i
].ArgReg
;
5528 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5531 DoOutput(" register ");
5532 OutClibType(&cd
->Args
[i
], RegNames
[j
]);
5533 DoOutput(" __asm(\"%s\") = %s;\n", RegNames
[j
], ap
->Args
[i
].ArgName
);
5538 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
5539 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames
[a45
],
5540 ap
->Bias
, RegNames
[a45
]);
5543 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap
->Bias
);
5545 DoOutput(noret
? " : /* No Output */\n" : " : \"=r\" (res)\n");
5549 DoOutput("\"r\" (a6)%s", (ap
->NumArgs
? ", ": ""));
5551 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5553 j
= ap
->Args
[i
].ArgReg
;
5554 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5557 DoOutput("\"r\" (%s)%s", RegNames
[j
], (i
< ap
->NumArgs
-1 ? ", " : ""));
5560 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
5563 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
5565 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
5569 /* new style inlines designed by Bernardo Innocenti */
5570 uint32
FuncInlineNS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5573 struct ClibData
*cd
;
5575 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5578 Flags
|= FLAG_DONE
; /* We did something */
5580 if(flags
& FUNCFLAG_ALIAS
)
5582 if(flags
& FUNCFLAG_TAG
)
5583 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n", name
, ap
->TagName
);
5585 DoOutput("#define %s("/*)*/, name
);
5586 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5587 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5588 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5589 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5590 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5591 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5594 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5597 if((flags
& FUNCFLAG_TAG
))
5599 if(!(Flags2
& FLAG2_INLINEMAC
))
5601 DoOutput("static __inline ");
5602 return FuncCSTUBS(ap
, flags
, name
);
5603 /* call CSTUBS, as this equals the method used there */
5607 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/, Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
5608 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5609 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5610 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5612 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5613 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5615 OutClibType(&cd
->Args
[i
], 0);
5616 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
5620 if(Flags2
& FLAG2_INLINEMAC
)
5622 DoOutput("#define %s("/*)*/, name
);
5623 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5625 DoOutput("%s", ap
->Args
[i
].ArgName
);
5626 if(i
< ap
->NumArgs
-1)
5629 DoOutput(/*(*/") \\\n\t");
5633 DoOutput("static __inline ");
5634 OutClibType(&cd
->ReturnType
, 0);
5635 DoOutput(" %s("/*)*/, name
);
5636 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5638 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5639 if(i
< ap
->NumArgs
-1)
5642 DoOutput(/*(*/")\n{\n "/*}*/);
5643 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5644 DoOutput("return ");
5646 DoOutput("(("/*))*/);
5647 OutClibType(&cd
->ReturnType
, 0);
5648 DoOutput(" (*)("/*)*/);
5649 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5651 OutClibType(&cd
->Args
[i
], 0);
5652 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
5653 if(i
< ap
->NumArgs
-1)
5660 DoOutput("%s __asm(\"a6\")", GetBaseType());
5662 DoOutput(/*((*/"))");
5663 if(Flags2
& FLAG2_INLINEMAC
)
5666 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/, ShortBaseNameUpper
, ap
->Bias
);
5669 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
5671 if(i
== ap
->NumArgs
)
5673 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap
->Args
[i
].ArgName
, ap
->Bias
);
5675 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5677 DoOutput("%s", ap
->Args
[i
].ArgName
);
5678 if(i
< ap
->NumArgs
-1)
5685 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
5688 if(Flags2
& FLAG2_INLINEMAC
)
5689 DoOutput(/*(*/")\n");
5691 DoOutput(/*{(*/");\n}\n");
5693 return DoOutput("\n");
5696 uint32
FuncPowerUP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5699 struct ClibData
*cd
;
5701 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5704 Flags
|= FLAG_DONE
; /* We did something */
5706 if(flags
& FUNCFLAG_ALIAS
)
5708 if(flags
& FUNCFLAG_TAG
)
5709 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n", name
, ap
->TagName
);
5711 DoOutput("#define %s("/*)*/, name
);
5712 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5713 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5714 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5715 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5716 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5717 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5720 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5723 if(flags
& FUNCFLAG_TAG
)
5725 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name
);
5726 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5727 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5728 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
5730 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5731 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5733 OutClibType(&cd
->Args
[i
], 0);
5734 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
5737 DoOutput("#define\t%s("/*)*/, name
);
5742 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5743 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5744 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap
->Args
[i
].ArgName
, name
);
5747 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper
);
5749 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5750 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5751 DoOutput(/*(*/"%s)\n\n", ap
->Args
[i
].ArgName
);
5754 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name
, ShortBaseNameUpper
);
5756 DoOutput(/*(*/")\t_%s()\n\n", name
);
5758 DoOutput("static __inline ");
5759 OutClibType(&cd
->ReturnType
, 0);
5761 DoOutput("\n_%s("/*)*/, name
);
5763 DoOutput("void * %s%s", BaseName
, ap
->NumArgs
? ", " : "");
5765 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5767 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5768 if(i
< ap
->NumArgs
-1)
5772 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5773 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5774 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5775 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5776 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5777 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5778 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5782 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5784 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5785 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5789 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5792 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName
);
5793 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5794 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5797 DoOutput("\treturn(("/*))*/);
5798 OutClibType(&cd
->ReturnType
, 0);
5799 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5801 return Output_Error
;
5804 uint32
FuncFPCUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5807 struct ClibData
*cd
;
5809 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
5811 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5814 if(!FuncFPCType(ap
, flags
, name
))
5817 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
5819 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5820 DoOutput("\tMOVE%s.L\t%s,%s\n", ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "",
5821 ap
->Args
[i
].ArgName
, RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
5824 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName
);
5825 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap
->Bias
);
5827 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5829 if(!cd
->ReturnType
.PointerDepth
&&
5830 cd
->ReturnType
.Flags
== CPP_FLAG_BOOLEAN
)
5831 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
5832 " @end:\tMOVE.B\tD0,@RESULT\n");
5834 DoOutput("\tMOVE.L\tD0,@RESULT\n");
5836 return DoOutput(" END;\nEND;\n\n");
5839 uint32
FuncFPCType(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5843 struct ClibData
*cd
;
5845 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
5847 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5850 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5852 ret
= 0; DoOutput("PROCEDURE %s", name
);
5855 DoOutput("FUNCTION %s", name
);
5860 for(i
= 0; i
< ap
->NumArgs
;)
5862 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
5863 if(++i
!= ap
->NumArgs
)
5870 OutPASCALType(&cd
->ReturnType
, "", 1);
5872 Flags
|= FLAG_DONE
; /* We did something */
5874 return DoOutput(";\n");
5877 uint32
FuncFPCTypeTags(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5881 struct ClibData
*cd
;
5883 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
5885 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5888 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5890 ret
= 0; DoOutput("PROCEDURE %s", name
);
5893 DoOutput("FUNCTION %s", name
);
5898 for(i
= 0; i
< ap
->NumArgs
-1;)
5900 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
5901 if(++i
!= ap
->NumArgs
)
5904 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
5909 OutPASCALType(&cd
->ReturnType
, "", 1);
5911 Flags
|= FLAG_DONE
; /* We did something */
5913 return DoOutput(";\n");
5916 uint32
FuncFPCTypeTagsUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5920 struct ClibData
*cd
;
5922 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
5924 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5927 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5929 ret
= 0; DoOutput("PROCEDURE %s", name
);
5932 DoOutput("FUNCTION %s", name
);
5937 for(i
= 0; i
< ap
->NumArgs
-1;)
5939 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
5940 if(++i
!= ap
->NumArgs
)
5943 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
5948 OutPASCALType(&cd
->ReturnType
, "", 1);
5950 DoOutput(";\nbegin\n");
5953 DoOutput(" %s := %s",name
, ap
->FuncName
);
5954 else DoOutput(" %s", ap
->FuncName
);
5959 for(i
= 0; i
< ap
->NumArgs
-1;)
5961 DoOutput("%s ", ap
->Args
[i
].ArgName
);
5962 if(++i
!= ap
->NumArgs
)
5965 DoOutput("readintags(%s)",ap
->Args
[i
].ArgName
);
5966 DoOutput(/*(*/");");
5971 Flags
|= FLAG_DONE
; /* We did something */
5973 return DoOutput(";\n\n");
5977 uint32
FuncBMAP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5981 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_A5USE
|AMIPRAGFLAG_PPC
))
5984 Flags
|= FLAG_DONE
; /* We did something */
5986 for(i
= 0; BMAPSpecial
[i
]; ++i
)
5988 if(!stricmp(name
, BMAPSpecial
[i
]))
5990 DoOutput("x"); break;
5995 reg
= 0; DoOutputDirect(®
, 1);
5996 reg
= (-ap
->Bias
)>>8; DoOutputDirect(®
, 1);
5997 reg
= -ap
->Bias
; DoOutputDirect(®
, 1);
5998 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6000 reg
= 1+ap
->Args
[i
].ArgReg
; DoOutputDirect(®
, 1);
6003 return DoOutputDirect(®
, 1);
6006 uint32
FuncVBCCInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6008 struct ClibData
*cd
;
6012 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6015 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6018 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
6019 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
6021 Flags
|= FLAG_DONE
; /* We did something */
6023 if(flags
& FUNCFLAG_TAG
)
6025 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && (__STDC_VERSION__ >= 199901L)\n");
6028 if(flags
& FUNCFLAG_ALIAS
)
6030 DoOutput("#define %s("/*)*/, name
);
6031 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6032 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6033 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6034 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6035 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6036 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6039 if(flags
& FUNCFLAG_TAG
)
6041 if(ap
->Args
[ap
->NumArgs
-1].ArgReg
>= REG_D2
&& ap
->Args
[ap
->NumArgs
-1].ArgReg
<= REG_D7
)
6042 DoOutput("__regsused(\"d0/d1/%s/a0/a1\") ", RegNames
[ap
->Args
[ap
->NumArgs
-1].ArgReg
]);
6043 else if(ap
->Args
[ap
->NumArgs
-1].ArgReg
>= REG_A2
&& ap
->Args
[ap
->NumArgs
-1].ArgReg
<= REG_A7
)
6044 DoOutput("__regsused(\"d0/d1/a0/a1/%s\") ", RegNames
[ap
->Args
[ap
->NumArgs
-1].ArgReg
]);
6047 OutClibType(&cd
->ReturnType
, 0);
6048 DoOutput(" __%s("/*)*/, name
);
6050 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6052 DoOutput("__reg(\"a6\") %s", GetBaseType());
6057 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6058 for(i
= 0; i
< k
; ++i
)
6060 DoOutput("__reg(\"%s\") ", RegNames
[ap
->Args
[i
].ArgReg
]);
6061 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6062 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6064 DoOutput("void * %s", ap
->Args
[i
].ArgName
);
6067 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6068 if(i
< ap
->NumArgs
-1)
6072 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6076 DoOutput("__reg(\"a6\") %s", GetBaseType());
6079 if(flags
& FUNCFLAG_TAG
)
6081 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6083 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6086 DoOutput(/*((*/"...)=\"\\tmove%s.l\\ta7,%s\\n\\tjsr\\t%s-%d%sa6)\";\n",
6087 ap
->Args
[k
].ArgReg
>= REG_A0
? "a" : "", RegNames
[ap
->Args
[k
].ArgReg
], c1
,
6091 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1
, ap
->Bias
, c2
);
6093 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6094 DoOutput("#define %s("/*)*/, name
);
6095 for(i
= 0; i
< k
; ++i
)
6097 DoOutput("%s", ap
->Args
[i
].ArgName
);
6098 if(i
< ap
->NumArgs
-1)
6101 if(flags
& FUNCFLAG_TAG
)
6103 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6104 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6107 DoOutput(/*(*/") __%s("/*)*/, name
);
6108 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6110 DoOutput("%s", BaseName
);
6114 for(i
= 0; i
< k
; ++i
)
6116 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6117 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6119 DoOutput("(void *)");
6121 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6122 if(i
< ap
->NumArgs
-1)
6125 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6129 DoOutput("%s", BaseName
);
6131 if(flags
& FUNCFLAG_TAG
)
6133 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6134 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6135 DoOutput("__VA_ARGS__");
6138 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6141 uint32
FuncVBCCWOSInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6143 struct ClibData
*cd
;
6146 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_M68K
))
6149 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6154 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
6158 Flags
|= FLAG_DONE
; /* We did something */
6160 if(!(flags
& FUNCFLAG_ALIAS
))
6162 OutClibType(&cd
->ReturnType
, 0);
6163 DoOutput(" __%s("/*)*/, name
);
6165 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6167 DoOutput("%s", GetBaseType());
6172 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6174 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6175 if(i
< ap
->NumArgs
-1)
6179 DoOutput(/*(*/")=\"");
6180 if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6182 DoOutput("\\t.extern\\t_%s\\n"
6183 "\\tlwz\\t%s11,_%s(%s2)\\n"
6184 "\\tlwz\\t%s0,-%d(%s11)\\n"
6187 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
,
6188 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6190 else if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6192 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6193 "\\t.extern\\t_%s\\n"
6194 "\\tlwz\\t%s2,_%s(%s2)\\n"
6195 "\\tlwz\\t%s0,-%d(%s2)\\n"
6198 "\\tlwz\\t%s2,20(%s1)",
6199 PPCRegPrefix
, PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
,
6200 PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
,
6201 PPCRegPrefix
, PPCRegPrefix
);
6205 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6208 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6214 DoOutput("#define %s("/*)*/, name
);
6215 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6217 DoOutput("%s", ap
->Args
[i
].ArgName
);
6218 if(i
< ap
->NumArgs
-1)
6221 DoOutput(/*(*/") __%s("/*)*/, ap
->FuncName
);
6222 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6224 DoOutput("%s", BaseName
);
6228 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6230 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6231 if(i
< ap
->NumArgs
-1)
6235 return DoOutput(/*(*/")\n\n");
6238 uint32
FuncVBCCMorphInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6240 struct ClibData
*cd
;
6243 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6246 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6249 Flags
|= FLAG_DONE
; /* We did something */
6251 if(flags
& FUNCFLAG_TAG
)
6253 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && (__STDC_VERSION__ >= 199901L)\n");
6256 if(flags
& FUNCFLAG_ALIAS
)
6258 DoOutput("#define %s("/*)*/, name
);
6259 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6260 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6261 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6262 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6263 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6264 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6267 OutClibType(&cd
->ReturnType
, 0);
6268 DoOutput(" __%s("/*)*/, name
);
6272 DoOutput("%s", GetBaseType());
6277 if(flags
& FUNCFLAG_TAG
)
6279 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6283 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6284 for(i
= 0; i
< k
; ++i
)
6286 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6287 if(i
< ap
->NumArgs
-1)
6291 if(flags
& FUNCFLAG_TAG
)
6293 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6295 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6301 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6302 PPCRegPrefix
, PPCRegPrefix
);
6305 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix
, k
++, PPCRegPrefix
);
6306 if(flags
& FUNCFLAG_TAG
)
6308 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6312 DoOutput("\t\"\\tmtlr\\t%s11\\n\"\n", PPCRegPrefix
);
6313 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6315 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
6318 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix
, k
++);
6320 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,", PPCRegPrefix
,
6321 8+(k
++-11)*4, PPCRegPrefix
, PPCRegPrefix
);
6324 DoOutput("\t\"\\taddi\\t%s4,%s1,%ld\\n\"\n\t\"\\tstw\\t%s4,", PPCRegPrefix
,
6325 PPCRegPrefix
, (2+k
-11)*4, PPCRegPrefix
);
6326 DoOutput("%d(%s2)\\n\"\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6328 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tblrl\";\n", PPCRegPrefix
, ap
->Bias
);
6330 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6331 DoOutput("#define %s("/*)*/, name
);
6332 for(i
= 0; i
< k
; ++i
)
6334 DoOutput("%s", ap
->Args
[i
].ArgName
);
6335 if(i
< ap
->NumArgs
-1)
6338 if(flags
& FUNCFLAG_TAG
)
6340 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6341 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6344 DoOutput(/*(*/") __%s("/*)*/, name
);
6347 DoOutput("%s", BaseName
);
6351 if(flags
& FUNCFLAG_TAG
)
6353 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6356 for(i
= 0; i
< k
; ++i
)
6358 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6359 if(i
< ap
->NumArgs
-1)
6362 if(flags
& FUNCFLAG_TAG
)
6364 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6365 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6366 DoOutput("__VA_ARGS__");
6369 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6372 uint32
FuncVBCCWOSText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6374 uint32 i
, k
, count
, ofs
;
6375 struct ClibData
*cd
= 0;
6377 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
6380 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&!(cd
= GetClibFunc(name
, ap
, flags
)))
6383 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
6384 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) || !(Flags
& FLAG_WOSLIBBASE
)))
6386 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
6392 if(Flags
& FLAG_SINGLEFILE
)
6394 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
6399 DoOutputDirect(HEADER
, headersize
);
6403 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
6404 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
6406 if(Flags
& FLAG_SINGLEFILE
)
6407 DoOutput("\t.file\t\"%s.s\"\n", name
);
6408 DoOutput("\t.align\t3\n");
6409 if(Flags
& FLAG_WOSLIBBASE
) /* PPCBase already in r3, LibBase in r4 */
6411 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
6412 DoOutput("\t.extern _%s\n", BaseName
);
6413 DoOutput("\t.global __%s\n__%s:\n", name
, name
);
6418 DoOutput("\t.extern _%s\n", BaseName
);
6419 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
6420 DoOutput("\t.extern _PowerPCBase\n");
6421 DoOutput("\t.global _%s\n_%s:\n", name
, name
);
6424 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6426 DoOutput("\tstw\t%s2,20(%s1)\n"
6428 "\tstw\t%s0,16(%s1)\n"
6429 "\tlwz\t%s2,_%s(%s2)\n"
6430 "\tlwz\t%s0,-%d(%s2)\n"
6433 "\tlwz\t%s0,16(%s1)\n"
6434 "\tlwz\t%s2,20(%s1)\n"
6437 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
6438 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
6439 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6441 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6443 DoOutput("\tlwz\t%s11,_%s(%s2)\n\tlwz\t%s0,-%d(%s11)\n\tmtlr\t%s0\n\tblrl\n",
6444 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6446 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
6448 count
= ap
->NumArgs
;
6449 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
6451 /* init stack frame */
6452 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
6453 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
6454 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
6458 /* extra arguments must be passed on the stack */
6459 k
= 32-(count
-8); /* firstreg */
6461 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
6462 PPCRegPrefix
, k
, 56+(count
-8)*4, PPCRegPrefix
, PPCRegPrefix
, k
,
6463 i
+56, PPCRegPrefix
);
6464 if(flags
& FUNCFLAG_TAG
)
6465 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
6467 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
6469 else if(flags
& FUNCFLAG_TAG
)
6471 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
6472 PPCRegPrefix
, i
+20+count
*4);
6476 else /* Args must be shifted! */
6478 /* init stack frame */
6479 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
6480 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
6481 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
6485 /* extra arguments must be passed on the stack */
6488 /* special case: move 8th argument into stack frame */
6489 if(flags
& FUNCFLAG_TAG
)
6490 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
6492 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
6496 k
= 32-(count
-7); /* firstreg */
6498 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
6499 "\tmr\t%s%ld,%s10\n"
6500 "\tlmw\t%s%ld,%ld(%s1)\n",
6501 PPCRegPrefix
, k
, 56+(count
-7)*4, PPCRegPrefix
,
6502 PPCRegPrefix
, k
, PPCRegPrefix
, PPCRegPrefix
, k
+1,
6503 i
+56, PPCRegPrefix
);
6504 if(flags
& FUNCFLAG_TAG
)
6505 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
,
6506 PPCRegPrefix
, i
+20+count
*4);
6507 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
6510 else if(flags
& FUNCFLAG_TAG
)
6512 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
6513 PPCRegPrefix
, i
+20+count
*4);
6517 /* shift all arguments into their following register */
6518 for(k
=(count
<8)?count
:7; k
> 0; --k
)
6519 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix
, 3+k
, PPCRegPrefix
, 2+k
);
6521 /* load library base and LVO, then call LVO via LR */
6522 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
6526 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix
,
6527 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6529 /* cleanup stack frame and return */
6532 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
6533 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, 32-(count
-k
),
6534 56+(count
-k
)*4, PPCRegPrefix
);
6537 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
6538 PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6542 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
6543 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6545 /* clear PP_Flags, PP_Stack and PP_StackSize */
6546 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
6547 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
6548 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6550 if(Flags
& FLAG_WOSLIBBASE
)
6551 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
6552 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix
, ap
->Bias
, PPCRegPrefix
,
6553 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6555 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix
,
6556 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
);
6558 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
6559 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
6560 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
,
6561 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
6564 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
6565 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
6566 for(i
= 0; i
< k
; ++i
)
6570 if(ap
->Args
[i
].ArgReg
== REG_A6
)
6571 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix
, i
+3+ofs
, PPCRegPrefix
);
6572 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3+ofs
);
6576 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix
, (i
+1+ofs
)*4+196, PPCRegPrefix
);
6577 if(ap
->Args
[i
].ArgReg
== REG_A6
)
6578 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
6579 DoOutput("\tstw\t%s11,", PPCRegPrefix
);
6581 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6583 if(flags
& FUNCFLAG_TAG
)
6585 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
6586 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
6587 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
6588 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix
,
6589 PPCRegPrefix
, 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
6590 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6593 if(!(Flags
& FLAG_WOSLIBBASE
))
6594 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
6596 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n\tblrl\n"
6597 "\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
6598 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
6599 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6602 if(Flags
& FLAG_WOSLIBBASE
)
6603 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
6606 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
6610 uint32
FuncVBCCWOSCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6612 uint32 i
, j
, k
, ofs
, count
;
6613 uint8
*data
, *basepos
= 0, *pbasepos
= 0;
6614 struct ClibData
*cd
= 0;
6616 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
6619 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) && !(cd
= GetClibFunc(name
, ap
, flags
)))
6622 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
6623 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) || !(Flags
& FLAG_WOSLIBBASE
)))
6625 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
6629 Flags
|= FLAG_DONE
; /* We did something */
6632 if(Flags
& FLAG_WOSLIBBASE
)
6634 EndPutM32(tempbuf
, HUNK_UNIT
);
6635 EndPutM32(tempbuf
+4, (i
+3)>>2);
6636 DoOutputDirect(tempbuf
, 8);
6637 DoOutput("%s%s", Flags
& FLAG_WOSLIBBASE
? "_" : "", name
);
6638 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
6640 i
= strlen(hunkname
);
6641 EndPutM32(tempbuf
, HUNK_NAME
);
6642 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
6643 DoOutputDirect(tempbuf
, 8);
6644 DoOutputDirect(hunkname
, i
);
6645 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
6647 data
= tempbuf
+8; /* we need HUNK_PPC_CODE + size at start */
6649 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6651 EndPutM32Inc(data
, 0x90410014); /* stw r2,20(r1) */
6652 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
6653 EndPutM32Inc(data
, 0x90010010); /* stw r0,16(r1) */
6655 EndPutM32Inc(data
, 0x80420000); /* lwz r2,BaseName(r2) */
6656 EndPutM32Inc(data
, 0x80030000 - ap
->Bias
); /* lwz r0,-ap->Bias(r2) */
6657 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
6658 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
6659 EndPutM32Inc(data
, 0x80010010); /* lwz r0,16(r1) */
6660 EndPutM32Inc(data
, 0x80410014); /* lwz r2,20(r1) */
6661 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
6662 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
6664 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6667 EndPutM32Inc(data
, 0x81620000); /* lwz r11,BaseName(r2) */
6668 EndPutM32Inc(data
, 0x800C0000 - ap
->Bias
); /* lwz r0,-ap->Bias(r11) */
6669 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
6670 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
6672 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
6674 count
= ap
->NumArgs
;
6675 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
6677 /* init stack frame */
6678 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
6679 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
6680 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
6681 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
6685 /* extra arguments must be passed on the stack */
6686 k
= 32-(count
-8); /* firstreg */
6687 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-8)*4)); /* stmw rk,X(r1) */
6688 EndPutM32Inc(data
, 0xB8010000 + (k
<< 21) + (i
+56)); /* lmw rk,Y(r1) */
6689 if(flags
& FUNCFLAG_TAG
)
6690 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4)); /* addi r31,r1,X */
6691 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
6693 else if(flags
& FUNCFLAG_TAG
)
6695 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4)); /* addi rX,r1,Y */
6699 else /* Args must be shifted! */
6701 /* init stack frame */
6702 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
6703 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
6704 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
6705 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
6709 /* extra arguments must be passed on the stack */
6712 /* special case: move 8th argument into stack frame */
6713 if(flags
& FUNCFLAG_TAG
)
6714 EndPutM32Inc(data
, 0x39410000 + (i
+20+count
*4)); /* addi r10,r1,X */
6715 EndPutM32Inc(data
, 0x91410038); /* stw r10,56(r1) */
6719 k
= 32-(count
-7); /* firstreg */
6721 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-7)*4));/* stmw rk,X(r1) */
6722 EndPutM32Inc(data
, 0x7D405378 + (k
<<16)); /* mr rk,r10 = or rk,r10,r10 */
6723 EndPutM32Inc(data
, 0xB8010000 + ((k
+1) << 21) + (i
+56)); /* lmw rk,Y(r1) */
6724 if(flags
& FUNCFLAG_TAG
)
6725 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4)); /* addi r31,r1,X */
6726 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
6729 else if(flags
& FUNCFLAG_TAG
)
6731 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4)); /* addi rX,r1,Y */
6735 /* shift all arguments into their following register */
6736 for(k
=(count
<8)?count
:7; k
> 0; --k
)
6737 EndPutM32Inc(data
, 0x7C000378 + ((3+k
)<<16) + ((2+k
)<<21) + ((2+k
)<<11)); /* mr rX,rY = or rX,rY,rY */
6739 /* load library base and LVO, then call LVO via LR */
6741 EndPutM32Inc(data
, 0x80620000); /* lwz r3,BaseName(r2) */
6744 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2)); /* lwz r0,-(ap->Bias-2)(r3) */
6745 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
6746 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
6749 /* cleanup stack frame and return */
6752 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
6753 EndPutM32Inc(data
, 0xB8010000 + ((32-(count
-k
))<<21) + (56+(count
-k
)*4)); /* lmw rX,Y(r1) */
6755 EndPutM32Inc(data
, 0x38210000 + i
); /* addi r1,r1,i */
6756 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) */
6757 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
6758 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
6762 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
6763 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
6764 EndPutM32Inc(data
, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
6766 EndPutM32Inc(data
, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
6767 EndPutM32Inc(data
, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
6768 EndPutM32Inc(data
, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
6769 EndPutM32Inc(data
, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
6771 if(Flags
& FLAG_WOSLIBBASE
)
6773 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
6774 EndPutM32Inc(data
, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
6775 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
6776 EndPutM32Inc(data
, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
6780 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
6781 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
6786 EndPutM32Inc(data
, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
6787 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
6788 EndPutM32Inc(data
, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
6789 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
6790 EndPutM32Inc(data
, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
6793 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
6794 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
6795 for(i
= 0; i
< k
; ++i
)
6797 j
= 0x34+4*ap
->Args
[i
].ArgReg
; /* PP_Regs offset */
6800 if(ap
->Args
[i
].ArgReg
== REG_A6
)
6801 EndPutM32Inc(data
, 0x90010020 + ((i
+3+ofs
)<<21)); /* stw rX,0x20(r1) */
6802 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
6806 EndPutM32Inc(data
, 0x81610000 + ((i
+1+ofs
)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
6807 if(ap
->Args
[i
].ArgReg
== REG_A6
)
6808 EndPutM32Inc(data
, 0x91610020); /* stw r11,0x20(r1) */
6809 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
6812 if(flags
& FUNCFLAG_TAG
)
6814 j
= (ap
->NumArgs
+ofs
)*4+0xC4;
6816 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
6817 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
6818 EndPutM32Inc(data
, 0x39610000 + j
); /* addi r11,r1,j */
6819 EndPutM32Inc(data
, 0x91610000 + (0x34+4*ap
->Args
[i
].ArgReg
)); /* stw r11,X(r1) */
6822 if(!(Flags
& FLAG_WOSLIBBASE
))
6824 pbasepos
= data
; /* store 16BIT reloc offset */
6825 EndPutM32Inc(data
, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
6827 EndPutM32Inc(data
, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
6828 EndPutM32Inc(data
, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
6829 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
6830 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
6831 EndPutM32Inc(data
, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
6832 EndPutM32Inc(data
, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
6833 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) = get old link register */
6834 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
6835 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump back */
6838 EndPutM32(tempbuf
, HUNK_PPC_CODE
);
6839 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
6840 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
6842 EndPutM32(tempbuf
, HUNK_EXT
);
6843 DoOutputDirect(tempbuf
,4);
6845 /* here come the XDEF name references */
6847 if(Flags
& FLAG_WOSLIBBASE
)
6849 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
6850 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
6851 OutputXDEF(0, "__%s", name
);
6856 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
6857 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
6858 OutputXREF((pbasepos
-tempbuf
-8)+2, EXT_DEXT16
, "_PowerPCBase");
6859 OutputXDEF(0, "_%s", name
);
6861 EndPutM32(tempbuf
, 0);
6862 DoOutputDirect(tempbuf
,4);
6863 if(!(Flags
& FLAG_NOSYMBOL
))
6865 EndPutM32(tempbuf
, HUNK_SYMBOL
);
6866 DoOutputDirect(tempbuf
,4);
6867 if(Flags
& FLAG_WOSLIBBASE
)
6868 OutputSYMBOL(0, "__%s", name
);
6870 OutputSYMBOL(0, "_%s", name
);
6871 EndPutM32(tempbuf
, 0);
6872 DoOutputDirect(tempbuf
,4);
6874 EndPutM32(tempbuf
, HUNK_END
);
6876 return DoOutputDirect(tempbuf
,4);
6879 uint32
FuncVBCCPUPText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6883 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6888 if(Flags
& FLAG_SINGLEFILE
)
6890 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
6895 DoOutputDirect(HEADER
, headersize
);
6899 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
6900 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
6902 if(Flags
& FLAG_SINGLEFILE
)
6903 DoOutput("\t.file\t\"%s.s\"\n", name
);
6905 DoOutput("\t.global %s\n", BaseName
);
6906 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
6907 "\t.align\t3\n%s:\n",name
, name
);
6909 if(flags
& FUNCFLAG_TAG
)
6911 /* Hack the stack-frame for varargs.
6912 Build stack-frame, but save LR in our own stack-frame,
6913 because we have to overwrite the lower 8 bytes of the
6915 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
6916 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6918 /* Save the caller's saved SP in our own stack-frame. */
6919 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix
,
6920 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6922 /* Store r3-r8 at the top of our stack-frame and r9-r10
6923 at the low 8 bytes of the caller's frame. This way all
6924 arguments will reside in one continuous area. */
6925 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
6926 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
, 104+4*(i
-3),
6930 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
6931 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6933 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6935 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
6938 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
6940 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
6941 100+(i
+1-8)*4, PPCRegPrefix
, PPCRegPrefix
);
6944 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix
,
6945 PPCRegPrefix
, 100+ap
->NumArgs
*4, PPCRegPrefix
);
6946 DoOutput("%d(%s1)\n", 36+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6949 /* Now place the real function call */
6950 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n" /* store offset in Chaos->caos_Un.Offset */
6951 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix
,
6952 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
6953 PPCRegPrefix
, PPCRegPrefix
);
6954 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
6958 if(Flags
& FLAG_SMALLDATA
)
6959 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
6961 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix
,
6962 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
6963 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix
, PPCRegPrefix
); /* store basepointer in A6 */
6966 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix
, PPCRegPrefix
);
6967 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
6968 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
6969 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
6970 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
6971 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6973 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
6974 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6976 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name
, name
, name
);
6979 uint32
FuncVBCCPUPCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6981 int32 i
, j
=0, k
, size
;
6982 uint8
*data
, *data2
, *data3
;
6983 struct ArHeader
*arh
;
6987 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6992 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
6993 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
6994 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
6995 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
6996 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
6997 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
6998 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
6999 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7000 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7001 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7002 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
7003 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
7004 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
7005 EndPutM32Inc(data
, 0); /* eeh->e_entry */
7006 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
7007 data2
= data
; data
+= 4;
7008 EndPutM32Inc(data
, 0); /* eeh->e_flags */
7009 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
7010 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
7011 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
7012 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
7013 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
7014 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
7017 if(flags
& FUNCFLAG_TAG
)
7019 /* Hack the stack-frame for varargs.
7020 Build stack-frame, but save LR in our own stack-frame,
7021 because we have to overwrite the lower 8 bytes of the
7023 EndPutM32Inc(data
, 0x9421FF80); /* stwu r1,-128(r1) */
7024 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7025 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7027 /* Save the caller's saved SP in our own stack-frame. */
7028 EndPutM32Inc(data
, 0x81610080); /* lwz r11,128(r1) */
7029 EndPutM32Inc(data
, 0x91610060); /* stw r11,96(r1) */
7031 /* Store r3-r8 at the top of our stack-frame and r9-r10
7032 at the low 8 bytes of the caller's frame. This way all
7033 arguments will reside in one continuous area. */
7034 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7035 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (104+4*(i
-3))); /* stw rX,Y(r1) */
7039 EndPutM32Inc(data
, 0x9421FFA0); /* stwu r1,-96(r1) */
7040 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7041 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7044 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7046 j
= 36+4*ap
->Args
[i
].ArgReg
;
7047 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7051 EndPutM32Inc(data
, 0x90010000 + ((i
+3)<<21) + j
); /* stw rX,j(r1) */
7055 EndPutM32Inc(data
, 0x81610000 + (100+(i
+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7056 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7061 EndPutM32Inc(data
, 0x39610000 + (100+ap
->NumArgs
*4)); /* addi r11,r1,X */
7062 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,X(r1) */
7066 /* Now place the real function call */
7067 EndPutM32Inc(data
, 0x39610000 - ap
->Bias
); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7068 EndPutM32Inc(data
, 0x91610008); /* stw r11,8(r1) */
7069 EndPutM32Inc(data
, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7070 EndPutM32Inc(data
, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7071 EndPutM32Inc(data
, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7075 if(Flags
& FLAG_SMALLDATA
)
7077 j
= (data
-data3
)+2; /* store reloc offset */
7078 EndPutM32Inc(data
, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7082 j
= (data
-data3
)+2; /* store reloc offset */
7083 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7084 EndPutM32Inc(data
, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7086 EndPutM32Inc(data
, 0x9161005C); /* stw r11,92(r1) */
7089 EndPutM32Inc(data
, 0x38610008); /* addi r3,r1,8 */
7090 k
= (data
-data3
); /* store reloc offset */
7091 EndPutM32Inc(data
, 0x48000001); /* bl PPCCallOS */
7092 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7094 EndPutM32Inc(data
, 0x81610060); /* lwz r11,96(r1) */
7095 EndPutM32Inc(data
, 0x91610080); /* stw r11,128(r1) */
7096 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7097 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7098 EndPutM32Inc(data
, 0x38210080); /* addi r1,r1,128 */
7102 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7103 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7104 EndPutM32Inc(data
, 0x38210060); /* addi r1,r1,96 */
7107 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
7109 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7110 data
+= 44; /* 1 9 17 27 33 */
7112 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
7115 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
7116 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
7117 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7118 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7119 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
7120 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
7121 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7122 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7123 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
7124 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7127 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
7128 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
7129 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
7130 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
7131 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
7132 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
7133 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
7134 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
7135 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
7136 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
7139 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
7140 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
7141 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
7142 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
7143 data
+= 4; /* esh[2].sh_offset */
7144 data
+= 4; /* esh[2].sh_size */
7145 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7146 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
7147 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
7148 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7150 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
7151 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
7152 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
7153 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
7154 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
7155 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
7156 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
7157 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
7158 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
7159 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
7161 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
7162 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
7163 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
7164 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
7165 data
+= 4; /* esh[4].sh_offset */
7166 data
+= 4; /* esh[4].sh_size */
7167 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
7168 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7169 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
7170 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7172 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
7173 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
7174 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7175 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7176 data
+= 4; /* esh[0].sh_offset */
7177 data
+= 4; /* esh[0].sh_size */
7178 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7179 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7180 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
7181 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7183 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
7184 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 6*16 : 5*16); /* esh[4].sh_size */
7187 data
+= BaseName
? 6*16 : 5*16;
7189 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
7192 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
7193 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
7194 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
7195 *(data2
++) = 0; /* esym[0].st_info */
7196 *(data2
++) = 0; /* esym[0].st_other */
7197 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
7201 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
7202 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
7203 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
7204 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
7205 *(data2
++) = 0; /* esym[1].st_other */
7206 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
7208 sprintf((strptr
)data
+i
, "%s.s", name
); while(data
[i
++]) ; /* get next store space */
7209 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
7210 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
7211 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
7212 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
7213 *(data2
++) = 0; /* esym[2].st_other */
7214 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
7216 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
7217 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
7218 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
7219 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
7220 *(data2
++) = 0; /* esym[3].st_other */
7221 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
7223 sprintf((strptr
)data
+i
, name
); while(data
[i
++]) ; /* get next store space */
7224 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
7225 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
7226 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
7227 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
7228 *(data2
++) = 0; /* esym[4].st_other */
7229 EndPutM16Inc(data2
, 0); /* esym[4].st_shndx */
7231 sprintf((strptr
)data
+i
, "PPCCallOS"); while(data
[i
++]) ; /* get next store space */
7234 EndPutM32Inc(data2
, i
); /* esym[5].st_name */
7235 EndPutM32Inc(data2
, 0); /* esym[5].st_value */
7236 EndPutM32Inc(data2
, 0); /* esym[5].st_size */
7237 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[5].st_info */
7238 *(data2
++) = 0; /* esym[5].st_other */
7239 EndPutM16
/*Inc*/(data2
, 0); /* esym[5].st_shndx */
7241 sprintf((strptr
)data
+i
, BaseName
); while(data
[i
++]) ; /* get next store space */
7243 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
7244 while(i
&3) /* long aligned */
7248 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
7252 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7253 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_REL24
)); /* erel[0].r_info - entry 4, type 10 */
7254 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7258 if(Flags
& FLAG_SMALLDATA
)
7260 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7261 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_SDAREL16
)); /* erel[1].r_info - entry 5, type 32 */
7262 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7266 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7267 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_HA
)); /* erel[1].r_info - entry 5, type 6 */
7268 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7269 EndPutM32Inc(data
, j
+4); /* erel[2].r_offset */
7270 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_LO
)); /* erel[2].r_info - entry 5, type 4 */
7271 EndPutM32Inc(data
, 0); /* erel[2].r_addend */
7274 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
7276 /* make ar header and store all */
7277 arh
= (struct ArHeader
*) (data
+20);
7278 memset(arh
, ' ', sizeof(struct ArHeader
));
7280 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
7281 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
7282 arh
->ar_mode
[2] = '0';
7283 arh
->ar_mode
[0] = '6';
7284 arh
->ar_fmag
[0] = 96;
7285 arh
->ar_fmag
[1] = '\n';
7287 if((k
= strlen(name
) + 2) >= 16)
7289 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
7294 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
7297 j
= k
+ (data
-tempbuf
);
7298 for(i
= 9; j
; --i
) /* make decimal number */
7300 data
[i
] = (j
%10)+'0';
7303 for(j
= 0; i
< 9; ++j
)
7304 arh
->ar_size
[j
] = data
[++i
];
7306 DoOutputDirect(arh
, sizeof(struct ArHeader
));
7310 DoOutput("%s.o", name
);
7312 *(data
++) = 0x0A; /* alignment byte! */
7315 return DoOutputDirect(tempbuf
, data
-tempbuf
);
7318 uint32
FuncVBCCMorphText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7320 int32 i
, nrcopyar
= 0, stcksize
= 16;
7322 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7327 if(Flags
& FLAG_SINGLEFILE
)
7329 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7334 DoOutputDirect(HEADER
, headersize
);
7338 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7339 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7341 if(Flags
& FLAG_SINGLEFILE
)
7342 DoOutput("\t.file\t\"%s.s\"\n", name
);
7344 DoOutput("\t.global %s\n", BaseName
);
7345 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name
, name
);
7347 if(flags
& FUNCFLAG_TAG
)
7349 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
7350 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
7353 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
7355 PPCRegPrefix
, stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
);
7359 /* Hack the stack-frame for varargs.
7360 Build stack-frame, but save LR in our own stack-frame,
7361 because we have to overwrite the lower 8 bytes of the
7363 /* Save the caller's saved SP in our own stack-frame. */
7364 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix
,
7365 stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
);
7367 /* Store r3-r8 at the top of our stack-frame and r9-r10
7368 at the low 8 bytes of the caller's frame. This way all
7369 arguments will reside in one continuous area.
7370 Only copy the really relevant parts. */
7371 for(i
= 10; i
> 10-nrcopyar
; --i
)
7372 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
,
7373 stcksize
+4*(i
-1+nrcopyar
-8),PPCRegPrefix
);
7378 if(Flags
& FLAG_SMALLDATA
)
7379 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7381 DoOutput("\tlis\t%s12,%s@ha\n\tlwz\t%s12,%s@l(%s12)\n", PPCRegPrefix
,
7382 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7385 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
7387 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7389 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7392 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
7394 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
7395 stcksize
+(i
+2-8)*4, PPCRegPrefix
, PPCRegPrefix
);
7398 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix
,
7399 PPCRegPrefix
, stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0),
7401 DoOutput("%d(%s2)\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7404 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
7405 PPCRegPrefix
, PPCRegPrefix
);
7408 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix
, PPCRegPrefix
); /* store basepointer in A6 */
7410 /* Now place the real function call */
7411 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
7412 PPCRegPrefix
, ap
->Bias
);
7414 DoOutput("\tmtlr\t%s11\n\tblrl\n", PPCRegPrefix
);
7416 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7418 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
7419 PPCRegPrefix
, stcksize
, PPCRegPrefix
, PPCRegPrefix
,
7420 stcksize
+nrcopyar
*4,PPCRegPrefix
);
7423 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
7424 "\taddi\t%s1,%s1,%ld\n"
7426 PPCRegPrefix
, stcksize
+4,PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7427 stcksize
+nrcopyar
*4, PPCRegPrefix
);
7429 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name
, name
, name
);
7432 uint32
FuncVBCCMorphCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7434 int32 i
, j
, k
=0, size
, nrcopyar
= 0, stcksize
= 16;
7435 uint8
*data
, *data2
, *data3
;
7436 struct ArHeader
*arh
;
7440 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7445 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7446 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7447 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7448 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7449 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
7450 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
7451 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
7452 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7453 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7454 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7455 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
7456 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
7457 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
7458 EndPutM32Inc(data
, 0); /* eeh->e_entry */
7459 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
7460 data2
= data
; data
+= 4;
7461 EndPutM32Inc(data
, 0); /* eeh->e_flags */
7462 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
7463 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
7464 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
7465 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
7466 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
7467 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
7471 if(flags
& FUNCFLAG_TAG
)
7473 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
7474 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
7477 EndPutM32Inc(data
, 0x94210000+0x10000-(stcksize
+nrcopyar
*4)); /* stwu r1,-%d(r1) */
7478 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7482 /* Hack the stack-frame for varargs.
7483 Build stack-frame, but save LR in our own stack-frame,
7484 because we have to overwrite the lower 8 bytes of the
7486 /* Save the caller's saved SP in our own stack-frame. */
7487 EndPutM32Inc(data
, 0x81610000+stcksize
+nrcopyar
*4); /* lwz r11,%d(r1) */
7488 EndPutM32Inc(data
, 0x91610000+stcksize
); /* stw r11,%d(r1) */
7490 /* Store r3-r8 at the top of our stack-frame and r9-r10
7491 at the low 8 bytes of the caller's frame. This way all
7492 arguments will reside in one continuous area.
7493 Only copy the really relevant parts. */
7494 for(i
= 10; i
> 10-nrcopyar
; --i
)
7495 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (stcksize
+4*(i
-1+nrcopyar
-8))); /* stw rX,Y(r1) */
7500 if(Flags
& FLAG_SMALLDATA
)
7502 k
= (data
-data3
)+2; /* store reloc offset */
7503 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
7507 k
= (data
-data3
)+2; /* store reloc offset */
7508 EndPutM32Inc(data
, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
7509 EndPutM32Inc(data
, 0x818C0000); /* lwz r12,BaseName@l(r12) */
7513 EndPutM32Inc(data
, 0x90010000+stcksize
+4); /* stw r0,%d(r1) */
7515 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7517 j
= 4*ap
->Args
[i
].ArgReg
;
7518 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7522 EndPutM32Inc(data
, 0x90020000 + ((i
+3)<<21) + j
); /* stw rX,j(r2) */
7526 EndPutM32Inc(data
, 0x81610000 + (stcksize
+(i
+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
7527 EndPutM32Inc(data
, 0x91620000 + j
); /* stw r11,j(r1) */
7532 EndPutM32Inc(data
, 0x38810000 + (stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0))); /* addi r4,r1,X */
7533 EndPutM32Inc(data
, 0x90820000 + j
); /* stw r4,X(r2) */
7537 EndPutM32Inc(data
, 0x81620064); /* lwz r11,100(r2) */
7540 EndPutM32Inc(data
, 0x91820038); /* stw r12,56(r2) */
7542 /* Now place the real function call */
7543 EndPutM32Inc(data
, 0x38600000 + 0x10000 - ap
->Bias
); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
7545 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7546 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 */
7548 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7550 EndPutM32Inc(data
, 0x81610000 + stcksize
); /* lwz r11,X(r1) */
7551 EndPutM32Inc(data
, 0x91610000 + (stcksize
+nrcopyar
*4)); /* stw r11,Y(r1) */
7554 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
7555 EndPutM32Inc(data
, 0x38210000 + (stcksize
+nrcopyar
*4)); /* addi r1,r1,Y */
7556 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7558 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
7560 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7561 data
+= 44; /* 1 9 17 27 33 */
7563 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
7566 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
7567 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
7568 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7569 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7570 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
7571 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
7572 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7573 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7574 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
7575 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7578 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
7579 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
7580 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
7581 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
7582 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
7583 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
7584 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
7585 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
7586 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
7587 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
7590 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
7591 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
7592 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
7593 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
7594 data
+= 4; /* esh[2].sh_offset */
7595 data
+= 4; /* esh[2].sh_size */
7596 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7597 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
7598 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
7599 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7601 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
7602 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
7603 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
7604 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
7605 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
7606 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
7607 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
7608 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
7609 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
7610 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
7612 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
7613 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
7614 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
7615 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
7616 data
+= 4; /* esh[4].sh_offset */
7617 data
+= 4; /* esh[4].sh_size */
7618 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
7619 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7620 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
7621 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7623 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
7624 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
7625 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7626 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7627 data
+= 4; /* esh[0].sh_offset */
7628 data
+= 4; /* esh[0].sh_size */
7629 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7630 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7631 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
7632 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7634 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
7635 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 5*16 : 4*16); /* esh[4].sh_size */
7638 data
+= BaseName
? 5*16 : 4*16;
7640 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
7643 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
7644 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
7645 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
7646 *(data2
++) = 0; /* esym[0].st_info */
7647 *(data2
++) = 0; /* esym[0].st_other */
7648 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
7652 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
7653 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
7654 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
7655 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
7656 *(data2
++) = 0; /* esym[1].st_other */
7657 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
7659 sprintf((strptr
)data
+i
, "%s.s", name
); while(data
[i
++]) ; /* get next store space */
7660 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
7661 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
7662 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
7663 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
7664 *(data2
++) = 0; /* esym[2].st_other */
7665 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
7667 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
7668 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
7669 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
7670 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
7671 *(data2
++) = 0; /* esym[3].st_other */
7672 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
7674 sprintf((strptr
)data
+i
, name
); while(data
[i
++]) ; /* get next store space */
7677 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
7678 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
7679 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
7680 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
7681 *(data2
++) = 0; /* esym[4].st_other */
7682 EndPutM16
/*Inc*/(data2
, 0); /* esym[4].st_shndx */
7684 sprintf((strptr
)data
+i
, BaseName
); while(data
[i
++]) ; /* get next store space */
7686 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
7687 while(i
&3) /* long aligned */
7691 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
7697 if(Flags
& FLAG_SMALLDATA
)
7699 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7700 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_SDAREL16
)); /* erel[0].r_info - entry 4, type 32 */
7701 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7705 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7706 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_HA
)); /* erel[0].r_info - entry 4, type 6 */
7707 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7708 EndPutM32Inc(data
, k
+4); /* erel[1].r_offset */
7709 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_LO
)); /* erel[1].r_info - entry 4, type 4 */
7710 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7713 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
7715 /* make ar header and store all */
7716 arh
= (struct ArHeader
*) (data
+20);
7717 memset(arh
, ' ', sizeof(struct ArHeader
));
7719 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
7720 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
7721 arh
->ar_mode
[2] = '0';
7722 arh
->ar_mode
[0] = '6';
7723 arh
->ar_fmag
[0] = 96;
7724 arh
->ar_fmag
[1] = '\n';
7726 if((k
= strlen(name
) + 2) >= 16)
7728 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
7733 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
7736 j
= k
+ (data
-tempbuf
);
7737 for(i
= 9; j
; --i
) /* make decimal number */
7739 data
[i
] = (j
%10)+'0';
7742 for(j
= 0; i
< 9; ++j
)
7743 arh
->ar_size
[j
] = data
[++i
];
7745 DoOutputDirect(arh
, sizeof(struct ArHeader
));
7749 DoOutput("%s.o", name
);
7751 *(data
++) = 0x0A; /* alignment byte! */
7754 return DoOutputDirect(tempbuf
, data
-tempbuf
);
7757 uint32
FuncEModule(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7761 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_PPC
) ||
7762 (flags
& FUNCFLAG_ALIAS
))
7765 if(LastBias
>= ap
->Bias
)
7766 DoError(ERR_ILLEGAL_FUNCTION_POSITION
, ap
->Line
, name
);
7769 Flags
|= FLAG_DONE
; /* We did something */
7771 for(LastBias
+= BIAS_OFFSET
; LastBias
< ap
->Bias
; LastBias
+= BIAS_OFFSET
)
7772 DoOutputDirect("Dum\x10", 4);
7774 DoOutput("%c", toupper(name
[0]));
7777 DoOutput("%c", tolower(name
[1]));
7779 DoOutput("%s", name
+2);
7782 DoOutputDirect("\x10", 1);
7785 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7787 r
= ap
->Args
[i
].ArgReg
;
7788 DoOutputDirect(&r
, 1);
7795 uint32
FuncFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7799 Flags
|= FLAG_DONE
; /* We did something */
7801 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
7803 if(Flags
& FLAG_ISPRIVATE
)
7805 Flags
^= FLAG_ISPRIVATE
;
7806 DoOutput("##public\n");
7811 if(!(Flags
& FLAG_ISPRIVATE
))
7812 DoOutput("##private\n");
7813 Flags
|= FLAG_ISPRIVATE
;
7816 LastBias
+= BIAS_OFFSET
;
7817 if(LastBias
!= ap
->Bias
)
7819 DoOutput("##bias %d\n", ap
->Bias
);
7820 LastBias
= ap
->Bias
;
7823 if(ap
->Abi
!= CurrentABI
)
7827 case ABI_M68K
: DoOutput("##abi M68k\n"); break;
7828 case ABI_PPC0
: DoOutput("##abi PPC0\n"); break;
7829 case ABI_PPC2
: DoOutput("##abi PPC2\n"); break;
7830 case ABI_PPC
: DoOutput("##abi PPC\n"); break;
7832 CurrentABI
= ap
->Abi
;
7835 DoOutput("%s("/*)*/, name
);
7836 for(i
= 0; i
< ap
->CallArgs
; i
++)
7837 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->CallArgs
-1 ? "," : "");
7838 DoOutput(/*(*/")("/*)*/);
7840 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7842 for(i
= 0; i
< ap
->CallArgs
; i
++)
7844 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], i
< ap
->CallArgs
-1 ?
7845 (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
? "/" : ",") : "");
7848 return DoOutput(/*(*/")\n");
7851 /* called from FuncSFD directly */
7852 uint32
FuncClib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7854 struct ClibData
*cd
;
7857 Flags
|= FLAG_DONE
; /* We did something */
7859 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
7862 s
= MakeClibType(tempbuf
, &cd
->ReturnType
, 0);
7863 DoOutputDirect(tempbuf
, s
);
7864 DoOutput(" %s("/*)*/, name
);
7868 for(i
= 0; i
< cd
->NumArgs
; i
++)
7870 c
= MakeClibType(tempbuf
, &cd
->Args
[i
], ap
->Args
[i
].ArgName
);
7873 DoOutput(i
? ",\n\t" : "\n\t"); s
= 8;
7877 DoOutput(", "); s
+= 2;
7879 DoOutputDirect(tempbuf
, c
);
7883 else if(Flags2
& FLAG2_CLIBOUT
)
7885 return DoOutput(/*(*/")%s", Flags2
& FLAG2_CLIBOUT
? ";\n" : "");
7888 uint32
FuncSFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7890 struct ClibData
*cd
;
7893 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
7896 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
7898 if(Flags
& FLAG_ISPRIVATE
)
7900 Flags
^= FLAG_ISPRIVATE
;
7901 DoOutput("==public\n");
7906 if(!(Flags
& FLAG_ISPRIVATE
))
7907 DoOutput("==private\n");
7908 Flags
|= FLAG_ISPRIVATE
;
7911 if(ap
->Abi
!= CurrentABI
)
7915 case ABI_M68K
: DoOutput("==abi M68k\n"); break;
7916 case ABI_PPC0
: DoOutput("==abi PPC0\n"); break;
7917 case ABI_PPC2
: DoOutput("==abi PPC2\n"); break;
7918 case ABI_PPC
: DoOutput("==abi PPC\n"); break;
7920 CurrentABI
= ap
->Abi
;
7923 if(LastBias
+BIAS_OFFSET
< ap
->Bias
)
7925 DoOutput("==reserve %ld\n", ((ap
->Bias
-LastBias
)/BIAS_OFFSET
)-1);
7926 LastBias
= ap
->Bias
;
7928 else if(flags
& FUNCFLAG_TAG
)
7929 DoOutput("==varargs\n");
7930 else if((flags
& FUNCFLAG_ALIAS
) || LastBias
== ap
->Bias
)
7931 DoOutput("==alias\n");
7933 LastBias
+= BIAS_OFFSET
;
7935 if(!FuncClib(ap
, flags
, name
))
7938 DoOutput(" ("/*)*/);
7939 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7943 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
7944 in step one, so the "-" can be placed at proper position. */
7945 for(j
= i
= 0; i
< ap
->NumArgs
; i
++)
7947 if(i
== ap
->NumArgs
-1)
7951 else if(IsCPPType(&cd
->Args
[j
>>1], CPP_TYPE_DOUBLE
) && ap
->Args
[i
].ArgReg
< REG_FP0
)
7953 s
= (j
&1) ? "," : "-"; ++j
;
7959 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], s
);
7962 return DoOutput(/*(*/")\n");
7965 uint32
FuncGateStubs(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7967 struct ClibData
*cd
;
7968 strptr ret
= "return ";
7971 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
7974 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
7977 Flags
|= FLAG_DONE
; /* We did something */
7979 if(flags
& FUNCFLAG_ALIAS
)
7981 if(flags
& FUNCFLAG_TAG
)
7982 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
7983 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
7985 DoOutput("#define %s("/*)*/, name
);
7986 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
7987 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
7988 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
7989 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
7990 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
7991 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
7994 if((flags
& FUNCFLAG_TAG
))
7996 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
7997 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
7998 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8000 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
8002 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
8004 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8005 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
8007 OutClibType(&cd
->Args
[i
], 0);
8008 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
8011 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
8014 if(!OutClibType(&cd
->ReturnType
, 0))
8017 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix
, name
);
8019 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8022 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8023 DoOutput(" = ("/*)*/);
8024 OutClibType(&cd
->Args
[i
], 0);
8025 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
8026 if((Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
)) && (Flags2
& FLAG2_REGLIB
))
8027 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
8029 DoOutput(" %s%s%s("/*)*/, ret
, subprefix
, name
);
8032 if(Flags2
& FLAG2_PRELIB
)
8034 if(Flags2
& FLAG2_REGLIB
)
8035 DoOutput("___RegBase,");
8037 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper
);
8040 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8042 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
8044 if(Flags2
& FLAG2_POSTLIB
)
8046 if(Flags2
& FLAG2_REGLIB
)
8047 DoOutput("%s, ___RegBase", ap
->Args
[i
].ArgName
);
8049 DoOutput("%s, %s_BASE_NAME", ap
->Args
[i
].ArgName
, ShortBaseNameUpper
);
8052 DoOutput("%s", ap
->Args
[i
].ArgName
);
8056 if(Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
))
8058 if(Flags2
& FLAG2_REGLIB
)
8059 DoOutput("___RegBase");
8061 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
8064 return DoOutput(/*(({*/"));\n}\n");
8067 static uint32
DoCallFunc(struct AmiPragma
*ap
, uint32 flags
, strptr name
, FuncType Func
)
8071 if(Flags
& FLAG_SINGLEFILE
)
8073 sprintf(filename
, filenamefmt
, name
);
8074 if(!OpenDest(filename
))
8077 res
= Func(ap
, flags
, name
);
8078 if(Flags
& FLAG_SINGLEFILE
)
8080 CloseDest(filename
);
8085 static uint32
PrintComment(struct Comment
*com
, strptr comment
)
8087 if(com
->Private
&& !(Flags
& FLAG_PRIVATE
))
8089 else if((Flags2
& FLAG2_SFDOUT
) && com
->Version
)
8091 return DoOutput("==version %d\n", com
->Version
);
8093 else if((Flags2
& FLAG2_SFDOUT
) && com
->ReservedNum
)
8095 LastBias
+= BIAS_OFFSET
*com
->ReservedNum
;
8096 return DoOutput("==reserve %d\n", com
->ReservedNum
);
8098 else if(!(Flags
& FLAG_DOCOMMENT
) || !comment
)
8103 if(!DoOutput(comment
, com
->Data
))
8106 else if(com
->ReservedNum
)
8109 sprintf(temp
, "* --- (%u function slot%s reserved here) ---", com
->ReservedNum
,
8110 com
->ReservedNum
== 1 ? "" : "s");
8111 if(!DoOutput(comment
, temp
))
8114 else if(com
->Version
)
8117 if(com
->Version
>= FIRST_KNOWN_RELEASE
&& com
->Version
<= LAST_KNOWN_RELEASE
&&
8118 (Flags2
& FLAG2_SYSTEMRELEASE
))
8119 sprintf(temp
, "* --- functions in V%u or higher %s ---", com
->Version
,
8120 Release
[com
->Version
-FIRST_KNOWN_RELEASE
]);
8122 sprintf(temp
, "* --- functions in V%u or higher ---", com
->Version
);
8124 if(!DoOutput(comment
, temp
))
8130 static uint32
CallFunc(uint32 tagmode
, strptr comment
, FuncType Func
)
8132 struct Comment
*com
;
8134 struct AmiPragma
*ap
;
8136 com
= (struct Comment
*) Comment
.First
;
8138 for(ap
= (struct AmiPragma
*) AmiPragma
.First
; ap
;
8139 ap
= (struct AmiPragma
*) ap
->List
.Next
)
8141 if(BaseName
&& (ap
->Flags
& AMIPRAGFLAG_A6USE
))
8143 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
8145 else if((ap
->Flags
& AMIPRAGFLAG_PUBLIC
) || (Flags
& FLAG_PRIVATE
))
8147 while(com
&& com
->Bias
<= ap
->Bias
)
8149 if(!PrintComment(com
, comment
))
8151 com
= (struct Comment
*) com
->List
.Next
;
8152 } /* comment loop */
8155 printf("Processing %s\n", ap
->FuncName
);
8158 if(tagmode
!= TAGMODE_TAGS
)
8160 if(ap
->FuncName
&& !DoCallFunc(ap
, FUNCFLAG_NORMAL
, ap
->FuncName
, Func
))
8163 for(i
= 0; i
< ap
->NumAlias
; ++i
)
8165 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_NORMAL
)
8167 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
8175 if(ap
->TagName
&& !DoCallFunc(ap
, FUNCFLAG_TAG
, ap
->TagName
, Func
))
8178 for(i
= 0; i
< ap
->NumAlias
; ++i
)
8180 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_TAG
)
8182 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
8191 if(!PrintComment(com
, comment
))
8193 com
= (struct Comment
*) com
->List
.Next
;
8194 } /* comment loop */
8198 static uint32
PrintIncludes(void) /* copies the include lines */
8200 struct Include
*inc
;
8203 inc
= (struct Include
*) Includes
.First
;
8207 s2
= (strptr
) tempbuf
;
8208 for(s
= inc
->Include
; *s
; ++s
)
8212 case '<': *(s2
++) = ' '; break;
8214 case '.': *(s2
++) = '_'; break;
8216 default: *(s2
++) = toupper(*s
);
8220 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf
, inc
->Include
);
8221 inc
= (struct Include
*) inc
->List
.Next
;
8224 DoOutput("#include <exec/types.h>\n");
8225 return DoOutput("\n");
8228 /* ------------------------------------------------------------------ */
8230 static int32
AddClibEntry(strptr buffer
, strptr bufend
, uint32 linenum
)
8232 strptr buf
= buffer
;
8233 struct ClibData d
, *f
;
8235 memset(&d
, 0, sizeof(struct ClibData
));
8236 buf
= SkipBlanks(buf
);
8237 if(*buf
== '#') /* preprozessor lines */
8240 printf("Found non-function bracket in preprozessor line %ld\n", linenum
);
8242 while(buf
< bufend
&& *buf
!= '\n')
8246 if(!strnicmp(buf
, "ASM", 3))
8247 buf
= SkipBlanks(buf
+3);
8248 /* else if(!strnicmp(buf, "STACK", 5))
8249 buf = SkipBlanks(buf+5);
8251 else if(!strnicmp(buf
, "REGS", 4))
8252 buf
= SkipBlanks(buf
+4);
8254 if(!strnicmp(buf
, "extern", 6))
8255 buf
= SkipBlanks(buf
+6);
8257 if(!GetCPPType(&d
.ReturnType
, buf
, 1, 1))
8259 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE
, linenum
);
8262 else if(d
.ReturnType
.Unknown
)
8263 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, linenum
,
8264 d
.ReturnType
.Unknown
);
8266 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
8268 strptr r
= d
.ReturnType
.TypeStart
;
8269 while(*r
!= '('/*)*/) ++r
;
8270 r
= SkipBlanks(++r
); /* the bracket */
8271 d
.FuncName
= SkipBlanks(++r
); /* the asterix */
8274 d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
+d
.ReturnType
.FullLength
);
8276 while(*(buf
++) != '('/*)*/)
8278 *(SkipName(d
.FuncName
)) = 0;
8282 printf("Found non-function bracket in line %ld\n", linenum
);
8284 while(buf
< bufend
&& *buf
!= '\n')
8288 buf
= SkipBlanksRet(buf
);
8290 while(*buf
!= /*(*/')' && buf
< bufend
)
8292 if(d
.NumArgs
== MAXREGPPC
+1)
8294 DoError(ERROFFSET_CLIB
| ERR_TO_MUCH_ARGUMENTS
, linenum
);
8297 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 0, 1))
8299 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE
, linenum
, d
.NumArgs
);
8302 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
8303 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE_INT
, linenum
,
8304 d
.NumArgs
, d
.Args
[d
.NumArgs
-1].Unknown
);
8306 buf
= d
.Args
[d
.NumArgs
-1].TypeStart
+ d
.Args
[d
.NumArgs
-1].FullLength
;
8307 while(*buf
!= ',' && *buf
!= /*(*/')' && buf
< bufend
)
8310 printf("Added argument %ld for %s (%ld bytes)\n", d
.NumArgs
, d
.FuncName
,
8311 d
.Args
[d
.NumArgs
-1].FullLength
);
8314 buf
= SkipBlanksRet(++buf
);
8317 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
8318 d
.NumArgs
= 0; /* void arguments are no arguments */
8320 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
8323 memcpy(f
, &d
, sizeof(struct ClibData
));
8329 struct ClibData
*e
= clibdata
;
8334 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
8336 int numclose
= 2, numopen
= 1;
8337 while(buf
< bufend
&& (numclose
|| numopen
> 0))
8339 if(*buf
== '('/*)*/) { ++numclose
; --numopen
; }
8340 else if(*buf
== /*(*/')') --numclose
;
8346 printf("Added prototype for %s (line %ld, %ld bytes) with %ld args\n",
8347 f
->FuncName
, linenum
, buf
-buffer
, f
->NumArgs
);
8352 static int32
ScanClibFile(strptr buf
, strptr bufend
)
8354 strptr linestart
= buf
;
8357 /* remove comments and other not so nice characters */
8360 if(*buf
== '\t' || *buf
== '\r' || *buf
== (string
)0xA0)
8362 else if(buf
[0] == '/' && buf
< bufend
-1)
8366 while(buf
< bufend
-1 && (buf
[0] != '*' || buf
[1] != '/'))
8375 else if(buf
[1] == '/')
8377 while(buf
< bufend
&& buf
[0] != '\n')
8384 else if(buf
[0] == '#' && strncmp("#include", buf
, 8))
8386 while(buf
< bufend
&& buf
[0] != '\n')
8395 printf("-----------\n%s-----------\n", linestart
);
8403 linestart
= ++buf
; ++linenum
;
8405 else if(!strncmp("#include", buf
, 8))
8409 if(!(d
= (struct Include
*) NewItem(&Includes
)))
8411 d
->Include
= buf
= SkipBlanks(buf
+8);
8412 AddItem(&Includes
, (struct ShortList
*) d
);
8413 while(*buf
&& *buf
!= '>' && *buf
!= '\n')
8421 printf("Added Include line %s\n", d
->Include
);
8424 else if(*buf
== '('/*)*/)
8428 if((i
= AddClibEntry(linestart
, bufend
, linenum
)) == -1) /* no memory */
8432 while(buf
< bufend
&& *buf
!= '\n')
8433 ++buf
; /* skip this line */
8438 while(buf
< bufend
&& i
-- > 0)
8440 if(*(buf
++) == '\n')
8444 } /* skip this function */
8454 static int32
IsCPPType(struct CPP_NameType
*data
, uint8 type
)
8456 if(!data
|| data
->Flags
|| data
->Type
!= type
|| data
->PointerDepth
)
8461 static uint32
CheckRegisterNum(strptr string
, struct CPP_NameType
*data
)
8465 for(i
= 0; i
< MAXREG
; ++i
)
8467 j
= strlen(RegNames
[i
]);
8468 if(!strnicmp(string
, RegNames
[i
], j
))
8471 if(*string
== ' ' || *string
== '\t' || *string
== '\n' || *string
== /*(*/')')
8474 data
->Flags
|= CPP_FLAG_REGISTER
;
8482 static uint32
ParseFuncPtrArgs(strptr buffer
, struct CPP_NameType
*data
)
8484 strptr buf
= buffer
;
8487 memset(&d
, 0, sizeof(struct ClibData
));
8488 while(*buf
!= /*(*/')')
8490 if(d
.NumArgs
== MAXREGPPC
+1)
8492 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 1, 1))
8495 buf
+= d
.Args
[d
.NumArgs
-1].FullLength
;
8496 while(*buf
!= ',' && *buf
!= /*(*/')')
8499 buf
= SkipBlanksRet(++buf
);
8502 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
8503 d
.NumArgs
= 0; /* void arguments are no arguments */
8505 if(d
.NumArgs
) /* no need to allocate structure for nothing */
8507 if(!(data
->FuncPtr
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
8510 memcpy(data
->FuncPtr
, &d
, sizeof(struct ClibData
));
8512 return (uint32
) (buf
+1-buffer
);
8515 /* rettype turns on usage of "extern" specifier */
8516 static int32
GetCPPType(struct CPP_NameType
*data
, strptr start
, uint32 rettype
, uint32 small
)
8523 data
->TypeStart
= start
= SkipBlanks(start
);
8525 if(!strncmp(start
, "REG", 3) && (start
[3] == ' ' || start
[3] == '\t' || start
[3] == '\n' || start
[3] == '('/*)*/))
8527 u
= SkipBlanksRet(start
+3);
8530 u
= SkipBlanks(u
+1);
8531 if((j
= CheckRegisterNum(u
, data
)))
8533 u
= SkipBlanks(u
+j
);
8535 start
= SkipBlanks(u
+1);
8539 data
->TypeStart
= start
;
8543 start
= SkipBlanks((u
= start
));
8544 if(!strncmp("...",start
,3))
8546 data
->Type
= CPP_TYPE_VARARGS
;
8547 data
->TypeLength
= start
+3 - (data
->TypeStart
);
8548 data
->FullLength
= data
->TypeLength
;
8551 if(CheckKeyword(start
, "const", 5) || CheckKeyword(start
, "CONST", 5))
8553 data
->Flags
|= CPP_FLAG_CONST
; start
+= 6;
8555 else if(rettype
&& CheckKeyword(start
, "extern", 6))
8557 start
+= 7; /* ignore it */
8559 else if(CheckKeyword(start
, "signed", 6))
8561 else if(CheckKeyword(start
, "unsigned", 8))
8563 data
->Flags
|= CPP_FLAG_UNSIGNED
; start
+= 9;
8565 else if(CheckKeyword(start
, "register", 8))
8567 data
->Flags
|= CPP_FLAG_REGISTER
; start
+= 9;
8568 data
->Register
= UNDEFREGISTER
;
8570 else if(CheckKeyword(start
, "struct", 6))
8572 start
= SkipBlanks(start
+6);
8573 data
->Flags
|= CPP_FLAG_STRUCT
;
8574 if(*start
== '?') /* ? for external types */
8576 data
->StructureLength
= 0;
8577 data
->StructureName
= "";
8580 else if(*start
== '!') /* ! for typedef types */
8582 data
->Flags
|= CPP_FLAG_TYPEDEFNAME
;
8584 /* structure name and length already set */
8588 start
= SkipName((data
->StructureName
= start
));
8589 data
->StructureLength
= start
-data
->StructureName
;
8592 else if(CheckKeyword(start
, "union", 5))
8594 start
= SkipBlanks(start
+5);
8595 data
->Flags
|= CPP_FLAG_UNION
;
8596 if(*start
!= '?') /* ? for external types */
8598 start
= SkipName((data
->StructureName
= start
));
8599 data
->StructureLength
= start
-data
->StructureName
;
8603 data
->StructureLength
= 0;
8604 data
->StructureName
= "";
8608 else if(CheckKeyword(start
, "enum", 4))
8610 start
= SkipBlanks(start
+4);
8611 data
->Flags
|= CPP_FLAG_ENUM
;
8612 if(*start
!= '?') /* ? for external types */
8614 start
= SkipName((data
->StructureName
= start
));
8615 data
->StructureLength
= start
-data
->StructureName
;
8619 data
->StructureLength
= 0;
8620 data
->StructureName
= "";
8624 else if(*start
== '*')
8626 ++start
; ++data
->PointerDepth
;
8628 else if(*start
== '[')
8630 data
->Flags
|= CPP_FLAG_ARRAY
;
8631 while(*start
&& *start
!= ']')
8636 else if(start
[0] == '_' && start
[1] == '_' && (j
= CheckRegisterNum(start
+2, data
)))
8638 else if(!data
->Type
)
8642 for(i
= 0; CPP_Field
[i
].Text
; ++i
)
8644 if(!strncmp(start
, CPP_Field
[i
].Text
, CPP_Field
[i
].Length
) &&
8645 (start
[CPP_Field
[i
].Length
] == ' ' ||
8646 start
[CPP_Field
[i
].Length
] == '\t' ||
8647 start
[CPP_Field
[i
].Length
] == '\n' ||
8648 start
[CPP_Field
[i
].Length
] == ',' ||
8649 start
[CPP_Field
[i
].Length
] == /*(*/')' ||
8650 start
[CPP_Field
[i
].Length
] == '('/*)*/ ||
8651 start
[CPP_Field
[i
].Length
] == '*'))
8653 start
+= CPP_Field
[i
].Length
;
8654 data
->Type
= CPP_Field
[i
].Type
;
8655 data
->Flags
|= CPP_Field
[i
].Flags
;
8656 if(CPP_Field
[i
].Flags
& CPP_FLAG_POINTER
)
8657 ++data
->PointerDepth
;
8661 if(CPP_Field
[i
].Text
)
8665 struct CPP_ExternNames
*a
= extnames
;
8669 i
= strlen(a
->Type
);
8670 if(!strncmp(a
->Type
, start
, i
) && !isalnum(start
[i
]) &&
8674 data
->StructureName
= a
->NameType
.StructureName
;
8675 data
->FuncPtr
= a
->NameType
.FuncPtr
;
8676 data
->StructureLength
= a
->NameType
.StructureLength
;
8677 data
->PointerDepth
+= a
->NameType
.PointerDepth
;
8678 data
->Type
= a
->NameType
.Type
;
8679 data
->Flags
|= a
->NameType
.Flags
;
8680 data
->FuncArgs
= a
->NameType
.FuncArgs
;
8681 data
->ArgsLength
= a
->NameType
.ArgsLength
;
8685 /* check types here */
8690 else if((!data
->Type
) && (!data
->Flags
))
8693 struct CPP_Unknown
*u
;
8695 data
->Type
= CPP_TYPE_INT
;
8696 size
= SkipName(start
)-start
;
8697 for(u
= unknown
; u
&& strncmp(u
->Unknown
, start
, size
); u
= u
->Next
)
8701 data
->Unknown
= DupString(start
, size
);
8702 if((u
= (struct CPP_Unknown
*) AllocListMem(sizeof(struct CPP_Unknown
))))
8705 u
->Unknown
= data
->Unknown
;
8719 if(start
!= SkipBlanks(u
)) /* we broke the loop after increasing start */
8722 data
->TypeLength
= u
- (data
->TypeStart
);
8723 data
->FullLength
= data
->TypeLength
;
8730 u
= SkipBlanks(++u
);
8735 ++data
->FuncPointerDepth
; ++u
;
8738 if(CheckKeyword(u
, "const", 5) || CheckKeyword(u
, "CONST", 5))
8740 data
->Flags
|= CPP_FLAG_CONST
; u
+= 6;
8744 data
->FunctionName
= u
;
8745 u
= SkipBlanks(SkipName(u
));
8750 while(*u
&& numclose
)
8752 if(*u
== '('/*)*/) ++numclose
;
8753 else if(*u
== /*(*/')') --numclose
;
8759 u
= SkipBlanks(++u
);
8762 data
->Flags
|= CPP_FLAG_FUNCTION
;
8764 if((j
= ParseFuncPtrArgs(u
+1, data
)))
8767 data
->ArgsLength
= j
+1;
8768 data
->FullLength
= u
+data
->ArgsLength
- (data
->TypeStart
);
8774 if(data
->PointerDepth
)
8775 data
->Flags
|= CPP_FLAG_POINTER
;
8777 if(!(Flags2
& FLAG2_SMALLTYPES
) && !small
)
8779 if(!(data
->Flags
& (CPP_FLAG_STRPTR
|CPP_FLAG_POINTER
|CPP_FLAG_ENUM
8780 |CPP_FLAG_STRUCT
|CPP_FLAG_UNION
|CPP_FLAG_FUNCTION
|CPP_FLAG_REGISTER
)))
8782 if(data
->Type
== CPP_TYPE_BYTE
|| data
->Type
== CPP_TYPE_WORD
|| data
->Type
== CPP_TYPE_INT
)
8784 if(data
->Flags
& CPP_FLAG_UNSIGNED
)
8785 data
->Replace
= "const ULONG";
8787 data
->Replace
= "const LONG";
8788 data
->Type
= CPP_TYPE_LONG
;
8789 if(!(data
->Flags
& CPP_FLAG_CONST
))
8795 if((!data
->Type
&& !data
->Flags
) || !ok
)
8800 static struct ClibData
*GetClibFunc(strptr name
, struct AmiPragma
*ap
, uint32 flags
)
8802 struct ClibData
*d
= clibdata
;
8804 while(d
&& strcmp(name
, d
->FuncName
))
8809 if(!(ap
->Flags
& AMIPRAGFLAG_NOCLIB
))
8811 DoError(ERR_PROTOTYPE_MISSING
, 0, name
);
8812 ap
->Flags
|= AMIPRAGFLAG_NOCLIB
;
8815 else if(ap
->CallArgs
!= d
->NumArgs
&& (!(flags
& FUNCFLAG_TAG
) ||
8816 ap
->CallArgs
+1 != d
->NumArgs
))
8818 if(!(ap
->Flags
& (AMIPRAGFLAG_CLIBARGCNT
|AMIPRAGFLAG_DIDARGWARN
)))
8820 DoError(ERR_CLIB_ARG_COUNT
, 0, name
, d
->NumArgs
, ap
->NumArgs
);
8821 ap
->Flags
|= AMIPRAGFLAG_CLIBARGCNT
;
8829 static int32
CheckKeyword(strptr string
, strptr keyword
, int32 size
)
8831 if(!strncmp(string
, keyword
, size
))
8834 if(*string
== ' ' || *string
== '\t' || *string
== '\n')
8840 /* return nonzero, when usable, zero, when string already emitted */
8841 static uint32
CopyCPPType(strptr buffer
, uint32 pass
, struct ClibData
*cd
,
8842 struct AmiArgs
*args
)
8844 uint32 ret
= 0, reg
;
8847 /* pass 0: signed strptr, MaxonC++ high args */
8848 /* pass 1: unsigned strptr, MaxonC++ high args */
8849 /* pass 2: signed strptr, StormC++ high args */
8850 /* pass 3: unsigned strptr, StormC++ high args */
8852 for(i
= 0; i
< cd
->NumArgs
; ++i
)
8854 struct CPP_NameType
*nt
;
8858 if(args
&& (Flags
& FLAG_LOCALREG
) && (nt
->Type
!= CPP_TYPE_VARARGS
))
8859 reg
= 1 + args
[k
].ArgReg
;
8860 else if((nt
->Flags
& CPP_FLAG_REGISTER
) && nt
->Register
!= UNDEFREGISTER
)
8861 reg
= 1 + nt
->Register
;
8865 if(reg
--) /* subtract the added 1 */
8867 *(buffer
++) = CPP_TYPE_REGISTER
;
8872 *(buffer
++) = reg
/10 + '0';
8873 *(buffer
++) = reg
%10 + '0';
8877 *(buffer
++) = reg
+ (reg
< 10 ? '0' : 'A'-10);
8880 *(buffer
++) = reg
+ '0';
8883 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
8885 for(j
= 0; j
< nt
->FuncPointerDepth
; ++j
)
8886 *(buffer
++) = CPP_TYPE_POINTER
;
8887 *(buffer
++) = CPP_TYPE_FUNCTION
;
8889 for(j
= 0; j
< nt
->PointerDepth
; ++j
)
8890 *(buffer
++) = CPP_TYPE_POINTER
;
8891 if(nt
->Flags
& CPP_FLAG_CONST
)
8892 *(buffer
++) = CPP_TYPE_CONST
;
8893 if(nt
->Flags
& CPP_FLAG_UNSIGNED
)
8894 *(buffer
++) = CPP_TYPE_UNSIGNED
;
8895 else if((nt
->Flags
& CPP_FLAG_STRPTR
) && (pass
& 1))
8897 *(buffer
++) = CPP_TYPE_UNSIGNED
;
8898 ret
|= 1; /* we really use this pass */
8900 if(nt
->Flags
& CPP_FLAG_ENUM
)
8901 *(buffer
++) = CPP_TYPE_ENUM
;
8903 *(buffer
++) = cd
->Args
[i
].Type
;
8907 sprintf(buffer
, "%02lu", (uint32
) nt
->StructureLength
); buffer
+= 2;
8908 for(i
= 0; i
< nt
->StructureLength
; ++i
)
8909 *(buffer
++) = nt
->StructureName
[i
];
8911 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
8915 ret
|= CopyCPPType(buffer
, pass
, nt
->FuncPtr
, 0);
8917 ++buffer
; /* skip to the new end */
8919 *(buffer
++) = CPP_TYPE_FUNCEND
;
8922 if(IsCPPType(nt
, CPP_TYPE_DOUBLE
)) /* double needs 2 registers */
8933 return ret
; /* return nozero if this pass should be used */
8936 static uint32
OutClibType(struct CPP_NameType
*nt
, strptr txt
)
8939 DoOutput("%s", nt
->Replace
);
8941 DoOutputDirect(nt
->TypeStart
, nt
->TypeLength
);
8942 if(nt
->Type
!= CPP_TYPE_VARARGS
)
8944 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
8947 DoOutput(" ("/*)*/);
8948 for(i
= 0; i
< nt
->FuncPointerDepth
; ++i
)
8950 DoOutput(/*((*/txt
? "%s)" : ")", txt
);
8952 return DoOutputDirect(nt
->FuncArgs
, nt
->ArgsLength
);
8954 return DoOutput("()");
8957 return DoOutput(" %s", txt
);
8963 static uint32
MakeClibType(strptr dest
, struct CPP_NameType
*nt
, strptr txt
)
8971 i
= strlen(nt
->Replace
);
8972 memcpy(a
, nt
->Replace
, i
);
8977 memcpy(a
, nt
->TypeStart
, nt
->TypeLength
);
8978 a
+= nt
->TypeLength
;
8981 if(nt
->Type
!= CPP_TYPE_VARARGS
)
8983 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
8985 a
+= sprintf(a
, (txt
? " (*%s)" : " (*)"), txt
);
8988 memcpy(a
, nt
->FuncArgs
, nt
->ArgsLength
);
8989 a
+= nt
->ArgsLength
;
8992 a
+= sprintf(a
, "()");
8995 a
+= sprintf(a
, " %s", txt
);
8997 return (uint32
)(a
-dest
);
9000 static uint32
OutPASCALType(struct CPP_NameType
*t
, strptr txt
, uint32 ret
)
9002 int32 i
= t
->PointerDepth
;
9004 if(t
->Flags
& CPP_FLAG_CONST
)
9006 if(!ret
&& i
== 1 &&
9007 (t
->Type
== CPP_TYPE_LONG
|| t
->Type
== CPP_TYPE_WORD
))
9009 DoOutput("VAR "); --i
;
9012 DoOutput("%s : ", txt
);
9014 if(!i
&& t
->Flags
== CPP_FLAG_BOOLEAN
)
9015 return DoOutput("BOOLEAN");
9016 else if(i
&& t
->Type
== CPP_TYPE_VOID
)
9017 return DoOutput("POINTER");
9018 else if(t
->Flags
& CPP_FLAG_FUNCTION
)
9019 return DoOutput("tPROCEDURE");
9024 if((t
->Flags
& (CPP_FLAG_STRUCT
|CPP_FLAG_UNION
)) && t
->StructureLength
)
9026 if(!t
->PointerDepth
)
9028 return DoOutputDirect(t
->StructureName
, t
->StructureLength
);
9031 if(t
->Flags
& CPP_FLAG_UNSIGNED
)
9033 if(t
->Type
== CPP_TYPE_LONG
)
9034 return DoOutput("CARDINAL");
9035 if(t
->Type
== CPP_TYPE_WORD
)
9036 return DoOutput("int16");
9037 if(t
->Type
== CPP_TYPE_BYTE
)
9038 return DoOutput(t
->PointerDepth
== 1 ? "CHAR" : "int8");
9040 else if(t
->Type
== CPP_TYPE_WORD
)
9041 return DoOutput("INTEGER");
9042 else if(t
->Type
== CPP_TYPE_BYTE
)
9043 return DoOutput("SHORTINT");
9044 return DoOutput("int32INT");
9047 /* ------------------------------------------------------------------ */
9049 static uint32
CallPrag(uint32 tagmode
, strptr type
, FuncType Func
)
9052 if((*type
&& !DoOutput("#if%s\n", type
)) ||
9053 !(CallFunc(tagmode
, tagmode
? 0 : "/%s */\n", Func
)) ||
9054 (*type
&& !DoOutput("#endif\n")))
9059 static uint32
CreatePragmaFile(strptr amicall
, strptr libcall
, strptr amitags
,
9060 strptr libtags
, uint32 mode
)
9062 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9066 case PRAGMODE_PRAGLIB
: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
9067 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper
,
9068 ShortBaseNameUpper
); break;
9069 case PRAGMODE_PRAGSLIB
: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
9070 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
9071 case PRAGMODE_PRAGSPRAGS
: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
9072 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
9073 case PRAGMODE_NONE
: break;
9080 DoOutputDirect(HEADER
, headersize
);
9083 if(mode
!= PRAGMODE_NONE
&& !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
9084 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
9087 if((Flags
& FLAG_EXTERNC
) &&
9088 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
9091 if(Flags
& FLAG_GNUPRAG
)
9093 DoOutput("#ifdef " TEXT_GNUC
"\n#ifdef NO_OBSOLETE\n"
9094 "#error \"Please include the proto file and not the compiler specific file!\"\n"
9095 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName
);
9100 !CallPrag(TAGMODE_NORMAL
, amicall
, FuncAMICALL
) ||
9101 !CallPrag(TAGMODE_NORMAL
, libcall
, FuncLIBCALL
))
9107 !CallPrag(TAGMODE_TAGS
, amitags
, FuncAMICALL
) ||
9108 !CallPrag(TAGMODE_TAGS
, libtags
, FuncLIBCALL
))
9112 if((Flags
& FLAG_EXTERNC
) &&
9113 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
9118 case PRAGMODE_PRAGLIB
: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
9119 ShortBaseNameUpper
); break;
9120 case PRAGMODE_PRAGSLIB
: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
9121 ShortBaseNameUpper
); break;
9122 case PRAGMODE_PRAGSPRAGS
: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
9123 ShortBaseNameUpper
); break;
9124 case PRAGMODE_NONE
: break;
9127 return Output_Error
;
9130 static uint32
CreateCSTUBSFile(void)
9132 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9134 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
9135 ShortBaseNameUpper
, ShortBaseNameUpper
);
9139 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
9145 DoOutputDirect(HEADER
, headersize
);
9148 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
9149 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
9152 if(!CallFunc(TAGMODE_TAGS
, "/%s */\n", FuncCSTUBS
))
9155 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
9156 ShortBaseNameUpper
);
9159 static uint32
CreateLVOFile(uint32 mode
)
9161 strptr data
= "_LVO_I";
9163 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
9165 if(mode
== 2 || mode
== 4)
9168 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
9169 ShortBaseNameUpper
, data
, ShortBaseNameUpper
, data
) ||
9170 (HEADER
&& (!DoOutput("\n") || !DoOutputDirect(HEADER
, headersize
))) ||
9171 (mode
<= 2 && !CallFunc(TAGMODE_NORMAL
, 0, FuncLVOXDEF
)) ||
9172 !CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVO
) ||
9173 !DoOutput("\n\n\t\tENDC\n"))
9179 static uint32
CreateLVOFilePPC(uint32 mode
)
9181 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
9183 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
9184 ShortBaseNameUpper
, ShortBaseNameUpper
))
9189 DoOutputDirect(HEADER
, headersize
);
9193 case 0: CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCXDEF
);
9194 case 1: CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVOPPC
);
9196 return DoOutput("\n\t.endif\n");
9199 static uint32
CreateAsmStubs(uint32 mode
, uint32 callmode
)
9201 if(mode
== 1 && (Flags2
& FLAG2_AUTOHEADER
)) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
9203 /* 1 = Text, 2 = Code */
9210 DoOutputDirect(HEADER
, headersize
);
9213 if(!(Flags
& FLAG_ASMSECTION
))
9214 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
9215 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
9216 if(!CallFunc(callmode
, "\n%s", FuncAsmText
))
9220 if(!CallFunc(callmode
, 0, FuncAsmCode
))
9228 static uint32
CreateProtoFile(uint32 Type
)
9230 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9232 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper
,
9233 ShortBaseNameUpper
);
9238 DoOutputDirect(HEADER
, headersize
);
9241 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
9243 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC
")\n"
9244 "#include <clib/%s_protos.h>\n#endif\n",
9245 ShortBaseNameUpper
, ShortBaseName
);
9249 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
9251 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
9253 DoOutput("%s;\n#endif\n", BaseName
);
9260 DoOutput("\n#ifdef " TEXT_GNUC
"\n");
9262 DoOutput("#ifndef __cplusplus\n");
9263 DoOutput("#include <inline/%s.h>\n", ShortBaseName
);
9265 DoOutput("#endif\n");
9269 DoOutput("#elif defined(" TEXT_VBCC
")\n#if defined(__MORPHOS__) || !defined(__PPC__)\n"
9270 "#include <inline/%s_protos.h>\n#endif\n#else", ShortBaseName
);
9272 DoOutput("#elif !defined(" TEXT_VBCC
")");
9276 DoOutput("\n#ifndef __PPC__");
9279 strptr str1
= "pragma", str2
= "lib";
9283 case 4: str1
= "pragmas"; /* no break; */
9284 case 2: str2
= "pragmas"; break;
9285 case 3: str1
= "pragmas"; break;
9286 case 5: str1
= "local"; str2
= "loc"; break;
9288 DoOutput("\n#include <%s/%s_%s.h>\n", str1
, ShortBaseName
, str2
);
9291 DoOutput("#endif\n");
9293 DoOutput("#endif\n");
9298 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
9301 static uint32
CreateLocalData(strptr to
, uint32 callmode
)
9303 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9305 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
9306 "#define _INCLUDE_PROTO_%s_LOC_H\n",
9307 ShortBaseNameUpper
, ShortBaseNameUpper
);
9312 DoOutputDirect(HEADER
, headersize
);
9318 if((Flags
& FLAG_EXTERNC
) &&
9319 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
9322 if(!CallFunc(callmode
, "/%s */\n", FuncLocText
))
9325 if((Flags
& FLAG_EXTERNC
) &&
9326 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
9329 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper
);
9331 sprintf(filename
, "%s_loc.lib", ShortBaseName
);
9332 if(!CloseDest(to
) || !OpenDest(filename
))
9335 CallFunc(callmode
, 0, FuncLocCode
);
9337 return CloseDest(filename
);
9340 static uint32
CreateInline(uint32 mode
, uint32 callmode
)
9342 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9346 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
9349 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
9350 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
,
9351 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
9356 DoOutputDirect(HEADER
, headersize
);
9361 /* prevent loading of clib-file after inline */
9362 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
9363 ShortBaseNameUpper
, ShortBaseNameUpper
);
9367 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
9368 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
9369 "#include <ppcinline/macros.h>\n#endif\n\n");
9371 DoOutput("#ifndef __INLINE_MACROS_H\n"
9372 "#include <inline/macros.h>\n#endif\n\n");
9373 Flags
|= FLAG_INLINENEW
;
9377 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
9378 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
9379 "#include <ppcinline/stubs.h>\n#endif\n\n");
9381 DoOutput("#ifndef __INLINE_STUB_H\n"
9382 "#include <inline/stubs.h>\n#endif\n\n");
9384 Flags
|= FLAG_INLINESTUB
;
9387 Flags2
|= FLAG2_INLINEMAC
;
9391 if((Flags
& FLAG_EXTERNC
) &&
9392 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
9397 if(mode
&& mode
<= 2)
9399 if(Flags
& FLAG_MORPHOS
)
9400 DoOutput("#include <emul/emulregs.h>\n");
9401 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
9402 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
9403 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
9404 "#define BASE_PAR_DECL0 void\n#endif\n"
9405 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
9406 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
9409 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
9410 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
9415 if(!CallFunc(callmode
, "/%s */\n", FuncInline
))
9421 Flags
|= FLAG_INLINENEW
;
9422 if(!CallFunc(callmode
, "/%s */\n", FuncInlineDirect
))
9427 if(!CallFunc(callmode
, "/%s */\n", FuncInlineNS
))
9431 if(mode
&& mode
<= 2 && BaseName
)
9432 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
9433 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper
);
9435 if((Flags
& FLAG_EXTERNC
) &&
9436 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
9439 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
9440 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
9443 static uint32
CreateGateStubs(uint32 callmode
)
9445 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9449 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
9451 if(!prefix
[0] && !subprefix
[0])
9453 DoError(ERR_PREFIX
, 0); return 1;
9456 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
9457 ShortBaseNameUpper
, ShortBaseNameUpper
);
9459 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
9460 premacro
, ShortBaseName
);
9465 DoOutputDirect(HEADER
, headersize
);
9470 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
9471 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
9472 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
9473 "#define BASE_PAR_DECL0 void\n#endif\n"
9474 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
9475 "BASE_EXT_DECL0\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
9480 if(!CallFunc(callmode
, "/%s */\n", FuncGateStubs
))
9483 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper
);
9486 static uint32
CreateSASPowerUP(uint32 callmode
)
9488 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9490 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
9491 ShortBaseNameUpper
, ShortBaseNameUpper
);
9496 DoOutputDirect(HEADER
, headersize
);
9499 DoOutput("\n#ifdef __GNUC__\n"
9500 "#ifndef _PPCINLINE__%s_H\n"
9501 "#include <ppcinline/%s.h>\n"
9504 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
9505 "#include <ppclib/interface.h>\n"
9507 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
9508 "#include <gcclib/powerup_protos.h>\n"
9510 "#ifndef NO_PPCINLINE_STDARG\n"
9511 "#define NO_PPCINLINE_STDARG\n"
9512 "#endif /* SAS-C PPC inlines */\n\n",
9513 ShortBaseNameUpper
, ShortBaseName
);
9517 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
9518 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
9521 if(!CallFunc(callmode
, "/%s */\n", FuncPowerUP
))
9524 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
9525 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper
);
9528 static uint32
CreateProtoPowerUP(void)
9530 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9532 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
9533 ShortBaseNameUpper
, ShortBaseNameUpper
);
9538 DoOutputDirect(HEADER
, headersize
);
9541 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName
);
9545 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
9546 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
9547 "#endif\n%s;\n#endif\n", BaseName
);
9550 DoOutput("\n#ifdef " TEXT_GNUC
"\n"
9551 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
9552 "#else\n#include <inline/%s.h>\n#endif\n"
9553 "#else /* SAS-C */\n"
9554 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
9555 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
9556 ShortBaseName
, ShortBaseName
, ShortBaseName
, ShortBaseName
);
9560 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
9563 static uint32
CreateFPCUnit(void)
9566 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT
);
9570 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
9574 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName
);
9579 DoOutputDirect(HEADER
, headersize
);
9582 DoOutput("**********************************************************************}\n\n");
9583 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
9584 DoOutput("{$mode objfpc}\n");
9585 DoOutput("{$I useamigasmartlink.inc}\n");
9586 DoOutput("{$ifdef use_amiga_smartlink}\n");
9587 DoOutput(" {$smartlink on}\n");
9588 DoOutput("{$endif use_amiga_smartlink}\n\n");
9590 DoOutput("UNIT %s;\n", ShortBaseNameUpper
);
9592 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName
, GetBaseTypeLib());
9594 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper
,ShortBaseName
);
9595 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName
);
9596 DoOutput("{$I %s.inc}\n\n",ShortBaseName
);
9598 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncFPCType
))
9601 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
9602 if(!CallFunc(TAGMODE_TAGS
, 0, FuncFPCTypeTags
))
9605 DoOutput("\n{Here we read how to compile this unit}\n");
9606 DoOutput("{You can remove this include and use a define instead}\n");
9607 DoOutput("{$I useautoopenlib.inc}\n");
9608 DoOutput("{$ifdef use_init_openlib}\n");
9609 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
9610 DoOutput("{$endif use_init_openlib}\n");
9611 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
9612 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper
);
9613 DoOutput("\nIMPLEMENTATION\n\n");
9614 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
9615 DoOutput("uses \n");
9616 DoOutput("{$ifndef dont_use_openlib}\n");
9617 DoOutput("msgbox, \n");
9618 DoOutput("{$endif dont_use_openlib}\n");
9619 DoOutput("tagsarray;\n\n");
9621 if(!CallFunc(TAGMODE_NORMAL
, "(%s *)\n", FuncFPCUnit
))
9624 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
9625 if(!CallFunc(TAGMODE_TAGS
,"(%s *)\n", FuncFPCTypeTagsUnit
))
9628 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
9629 DoOutput(" VERSION : string[2] = '0';\n");
9630 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
9632 DoOutput("{$ifdef use_init_openlib}\n");
9633 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName
);
9634 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper
);
9636 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
9637 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
9638 DoOutput("begin\n");
9639 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
9640 DoOutput(" if %s <> nil then begin\n",BaseName
);
9641 DoOutput(" CloseLibrary(%s);\n",BaseName
);
9642 DoOutput(" %s := nil;\n",BaseName
);
9643 DoOutput(" end;\n");
9644 DoOutput("end;\n\n");
9645 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
9646 DoOutput("begin\n %s := nil;\n",BaseName
);
9647 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
9648 DoOutput(" if %s <> nil then begin\n",BaseName
);
9649 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
9650 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
9651 DoOutput(" end else begin\n");
9652 DoOutput(" MessageBox('FPC Pascal Error',\n");
9653 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
9654 DoOutput(" 'Deallocating resources and closing down',\n");
9655 DoOutput(" 'Oops');\n");
9656 DoOutput(" halt(20);\n");
9657 DoOutput(" end;\n");
9658 DoOutput("end;\n\n");
9659 DoOutput("begin\n");
9660 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper
);
9661 DoOutput("{$endif use_init_openlib}\n\n");
9663 DoOutput("{$ifdef use_auto_openlib}\n");
9664 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName
);
9666 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
9667 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
9668 DoOutput("begin\n");
9669 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
9670 DoOutput(" if %s <> nil then begin\n",BaseName
);
9671 DoOutput(" CloseLibrary(%s);\n",BaseName
);
9672 DoOutput(" %s := nil;\n",BaseName
);
9673 DoOutput(" end;\n");
9674 DoOutput("end;\n\n");
9675 DoOutput("begin\n %s := nil;\n",BaseName
);
9676 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
9677 DoOutput(" if %s <> nil then begin\n",BaseName
);
9678 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
9679 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
9680 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper
);
9681 DoOutput(" end else begin\n");
9682 DoOutput(" MessageBox('FPC Pascal Error',\n");
9683 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
9684 DoOutput(" 'Deallocating resources and closing down',\n");
9685 DoOutput(" 'Oops');\n");
9686 DoOutput(" halt(20);\n");
9687 DoOutput(" end;\n\n");
9688 DoOutput("{$endif use_auto_openlib}\n\n");
9690 DoOutput("{$ifdef dont_use_openlib}\n");
9691 DoOutput("begin\n");
9692 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper
);
9693 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName
);
9694 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName
);
9695 DoOutput("{$endif dont_use_openlib}\n\n");
9697 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper
);
9700 static uint32
CreateBMAP(void)
9702 return CallFunc(TAGMODE_NORMAL
, 0, FuncBMAP
);
9705 static uint32
CreateLVOLib(void)
9709 i
= strlen(ShortBaseNameUpper
);
9710 EndPutM32(tempbuf
, HUNK_UNIT
);
9711 EndPutM32(tempbuf
+4, (i
+3)>>2);
9712 DoOutputDirect(tempbuf
, 8);
9713 DoOutputDirect(ShortBaseNameUpper
, i
);
9714 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
9716 i
= strlen(hunkname
);
9717 EndPutM32(tempbuf
, HUNK_NAME
);
9718 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
9719 DoOutputDirect(tempbuf
, 8);
9720 DoOutputDirect(hunkname
, i
);
9721 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
9723 EndPutM32(tempbuf
, HUNK_CODE
);
9724 EndPutM32(tempbuf
+4, 0);
9725 EndPutM32(tempbuf
+8, HUNK_EXT
);
9726 DoOutputDirect(tempbuf
, 12);
9728 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOLib
))
9731 EndPutM32(tempbuf
, 0);
9732 EndPutM32(tempbuf
+4, HUNK_END
);
9733 return DoOutputDirect(tempbuf
, 8);
9736 static uint32
CreateLVOLibPPC(void)
9738 uint8
*data
= tempbuf
, *data2
, *data3
;
9740 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
9741 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
9742 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
9743 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
9744 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
9745 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
9746 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
9747 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
9748 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
9749 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
9750 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
9751 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
9752 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
9753 EndPutM32Inc(data
, 0); /* eeh->e_entry */
9754 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
9755 data2
= data
; data
+= 4;
9756 EndPutM32Inc(data
, 0); /* eeh->e_flags */
9757 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
9758 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
9759 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
9760 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
9761 EndPutM16Inc(data
, 4); /* eeh->e_shnum */
9762 EndPutM16Inc(data
, 1); /* eeh->e_shstrndx - first table is string table */
9765 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
9766 data
+= 28; /* 1 9 17*/
9767 EndPutM32(data2
, data
-tempbuf
); /* store the entry */
9769 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
9770 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
9771 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
9772 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
9773 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
9774 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
9775 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
9776 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
9777 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
9778 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
9780 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
9781 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
9782 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
9783 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
9784 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[3].sh_offset */
9785 EndPutM32Inc(data
, 27); /* esh[3].sh_size */
9786 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
9787 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
9788 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
9789 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
9791 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
9792 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
9793 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
9794 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
9796 data
+= 4; /* esh[4].sh_offset */
9797 data
+= 4; /* esh[4].sh_size */
9798 EndPutM32Inc(data
, 3); /* esh[4].sh_link - the third entry is our string table */
9799 EndPutM32Inc(data
, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
9800 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
9801 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
9803 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
9804 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
9805 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
9806 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
9808 data
+= 4; /* esh[0].sh_offset */
9809 data
+= 4; /* esh[0].sh_size */
9810 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
9811 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
9812 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
9813 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
9815 EndPutM32Inc(data2
, data
-tempbuf
);
9817 EndPutM32Inc(data
,0);
9818 EndPutM32Inc(data
,0); /* first entry is empty */
9819 EndPutM32Inc(data
,0);
9820 EndPutM32Inc(data
,0);
9822 symoffset
= 1; /* initial value */
9825 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCBias
))
9827 EndPutM32(data2
, elfbufpos
-data
+16);
9828 EndPutM32Inc(data3
, elfbufpos
-tempbuf
);
9829 EndPutM32(data3
, symoffset
);
9831 *(elfbufpos
++) = 0; /* first sym entry */
9832 if(!DoOutputDirect(tempbuf
, elfbufpos
-tempbuf
))
9835 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCName
))
9838 while((symoffset
++)&3)
9840 if(!DoOutputDirect("", 1))
9847 static uint32
CreateVBCCInline(uint32 mode
, uint32 callmode
)
9849 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9853 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
9856 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
9857 ShortBaseNameUpper
, ShortBaseNameUpper
);
9859 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
9864 DoOutputDirect(HEADER
, headersize
);
9869 if(!CallFunc(callmode
, "/%s */\n", mode
? (mode
== 2 ? FuncVBCCMorphInline
9870 : FuncVBCCWOSInline
) : FuncVBCCInline
))
9873 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper
);
9876 static uint32
CreateVBCC(uint32 mode
, uint32 callmode
)
9880 if(mode
!= 2 && mode
!= 3)
9882 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
9887 DoOutputDirect(HEADER
, headersize
);
9893 case 4: res
= CallFunc(callmode
, 0, FuncVBCCPUPText
); break;
9895 case 3: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
9896 case 2: res
= CallFunc(callmode
, 0, FuncVBCCWOSCode
); break;
9898 case 1: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
9899 case 0: res
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
); break;
9904 static uint32
CreateVBCCPUPLib(uint32 callmode
)
9907 DoOutput("!<arch>\n");
9909 return CallFunc(callmode
, 0, FuncVBCCPUPCode
);
9912 static uint32
CreateVBCCMorphCode(uint32 callmode
)
9915 DoOutput("!<arch>\n");
9917 return CallFunc(callmode
, 0, FuncVBCCMorphCode
);
9920 static uint32
CreateEModule(uint32 sorted
)
9924 DoError(ERR_NO_SORTED
, 0);
9927 DoOutputDirect("EMOD\0\x06", 6);
9928 for(res
= 0; res
< 2; ++res
)
9930 for(i
= 0; BaseName
[i
]; ++i
)
9931 DoOutput("%c", tolower(BaseName
[i
]));
9932 DoOutputDirect("\x00",1);
9934 LastBias
= BIAS_START
-BIAS_OFFSET
;
9935 CallFunc(TAGMODE_NORMAL
, 0, FuncEModule
);
9936 res
= DoOutputDirect("\xFF",1);
9941 static uint32
CreateProtoRedirect(void)
9944 return DoOutput("#ifdef NO_OBSOLETE\n"
9945 "#error \"Please include the proto file and not the compiler specific file!\"\n"
9946 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName
);
9949 static uint32
CreateSFD(uint32 callmode
)
9951 struct Include
*inc
;
9952 struct AmiPragma
*ap
;
9955 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
9958 if((ap
= (struct AmiPragma
*) AmiPragma
.First
))
9959 LastBias
= ap
->Bias
-BIAS_OFFSET
;
9960 else /* only security, never used normally */
9962 CurrentABI
= ABI_M68K
;
9965 DoOutput("==id %s\n", IDstring
);
9972 tim
= localtime(&t
);
9974 DoOutput("==id $Id$\n", filename
,
9975 tim
->tm_year
+1900, tim
->tm_mon
+1, tim
->tm_mday
, tim
->tm_hour
, tim
->tm_min
,
9980 DoOutput("==base _%s\n==basetype %s\n==libname %s\n", BaseName
,
9981 GetBaseType(), GetLibraryName());
9982 DoOutput("==bias %ld\n==public\n", LastBias
+BIAS_OFFSET
);
9984 for(inc
= (struct Include
*) Includes
.First
; inc
; inc
= (struct Include
*) inc
->List
.Next
)
9985 DoOutput("==include %s\n", inc
->Include
);
9987 DoOutput("==include <exec/types.h>\n");
9989 CallFunc(callmode
, "%s\n", FuncSFD
);
9991 return DoOutput("==end\n");
9994 static uint32
CreateClib(uint32 callmode
)
9998 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10001 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10003 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper
,
10004 ShortBaseNameUpper
);
10009 DoOutputDirect(HEADER
, headersize
);
10018 tim
= localtime(&t
);
10022 s
= SkipBlanks(IDstring
+4);
10023 while(*s
&& *s
!= ' ')
10030 if(Flags2
& FLAG2_SYSTEMRELEASE
)
10032 DoOutput("\n/*\n**\t$Id: %s %s\n", filename
, s
);
10039 while(*t
&& *t
!= ' ')
10043 DoOutput("\n/*\n**\t$VER: %s %s (%02d.%02d.%04d)\n", filename
, s
,
10044 tim
->tm_mday
, tim
->tm_mon
+1, tim
->tm_year
+1900);
10046 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
10047 if(!Copyright
|| (Copyright
&& strncmp("Copyright ", Copyright
, 10)))
10048 DoOutput("Copyright © %d ", tim
->tm_year
+1900);
10049 DoOutput("%s\n", Copyright
? Copyright
: Flags2
& FLAG2_SYSTEMRELEASE
?
10050 "Amiga, Inc." : "");
10051 DoOutput("**\tAll Rights Reserved\n*/\n\n");
10056 if((Flags
& FLAG_EXTERNC
) &&
10057 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10060 CallFunc(callmode
, "\n/%s */\n\n", FuncClib
);
10062 if((Flags
& FLAG_EXTERNC
) &&
10063 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10066 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper
);
10069 static uint32
CreateFD(void)
10072 CurrentABI
= ABI_M68K
;
10075 DoOutput("##base _%s\n", BaseName
);
10076 DoOutput("##public\n");
10078 CallFunc(TAGMODE_NORMAL
, "%s\n", FuncFD
);
10080 return DoOutput("##end\n");
10083 static uint32
CreateGenAuto(strptr to
, uint32 type
)
10085 strptr name
, btype
;
10087 uint32 i
, verref
, exitfuncref
, sysref2
, exitref
, rel1
, rel2
, nameref
;
10088 if(!(name
= GetLibraryName()))
10090 btype
= GetBaseType();
10095 Flags
|= FLAG_DONE
;
10096 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
10097 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
10098 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
10099 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
10100 btype
, BaseName
, BaseName
,
10101 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", name
, BaseName
,
10102 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", BaseName
)))
10104 sprintf(filename
, "%s_autoopenver.c", ShortBaseName
);
10105 if(!CloseDest(to
) || !OpenDest(filename
))
10107 Flags
|= FLAG_DONE
;
10108 return DoOutput("unsigned long _%sVer = 0;\n", BaseName
);
10111 Flags
|= FLAG_DONE
;
10112 i
= strlen(filename
)-4; /* remove .lib extension */
10113 EndPutM32(tempbuf
, HUNK_UNIT
);
10114 EndPutM32(tempbuf
+4, (i
+3)>>2);
10115 DoOutputDirect(tempbuf
, 8);
10116 DoOutputDirect(filename
, i
);
10117 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10119 i
= strlen(hunkname
);
10120 EndPutM32(tempbuf
, HUNK_NAME
);
10121 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
10122 DoOutputDirect(tempbuf
, 8);
10123 DoOutputDirect(hunkname
, i
);
10124 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10126 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
10127 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
10129 if(Flags
& FLAG_SMALLDATA
)
10131 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
10132 EndPutM16Inc(data
, 0); /* place for sysbase reference */
10136 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
10137 EndPutM32Inc(data
, 0); /* place for sysbase reference */
10139 verref
= data
-tempbuf
-8+2;
10140 if(Flags
& FLAG_SMALLDATA
)
10142 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
10143 EndPutM16Inc(data
, 0); /* place for basevers reference */
10147 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
10148 EndPutM32Inc(data
, 0); /* place for basevers reference */
10150 EndPutM32Inc(data
, 0x43FA0030 + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2) + ((Flags
& FLAG_SMALLDATA
) ? 0 : 6));
10151 EndPutM32Inc(data
, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
10153 rel1
= data
-tempbuf
-8+2;
10154 if(Flags
& FLAG_SMALLDATA
)
10156 EndPutM16Inc(data
, 0x2940); /* MOVE.L D0,xxx(A4) */
10157 EndPutM16Inc(data
, 0);
10161 EndPutM16Inc(data
, 0x23C0); /* MOVE.L D0,xxx */
10162 EndPutM32Inc(data
, 0);
10164 EndPutM16Inc(data
, 0x660A + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2)); /* BNE.B .lib */
10165 EndPutM32Inc(data
, 0x48780014); /* PEA 20 */
10167 exitfuncref
= data
-tempbuf
-8+2;
10168 if(Flags2
& FLAG2_SMALLCODE
)
10170 EndPutM16Inc(data
, 0x4EBA); /* JSR _exit(PC) */
10171 EndPutM16Inc(data
, 0); /* place for base reference */
10175 EndPutM16Inc(data
, 0x4EB9); /* JSR _exit */
10176 EndPutM32Inc(data
, 0); /* place for base reference */
10178 EndPutM16Inc(data
, 0x584F); /* ADDQ.W, #4,A7 */
10179 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
10180 EndPutM16Inc(data
,0x4E75); /* RTS */
10181 exitref
= data
-tempbuf
-8;
10183 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
10184 sysref2
= data
-tempbuf
-8+2;
10186 if(Flags
& FLAG_SMALLDATA
)
10188 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
10189 EndPutM16Inc(data
, 0); /* place for sysbase reference */
10193 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
10194 EndPutM32Inc(data
, 0); /* place for sysbase reference */
10196 rel2
= data
-tempbuf
-8+2;
10197 if(Flags
& FLAG_SMALLDATA
)
10199 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
10200 EndPutM16Inc(data
, 0); /* place for base reference */
10204 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
10205 EndPutM32Inc(data
, 0); /* place for base reference */
10207 EndPutM16Inc(data
, 0x6606); /* BNE.B .nolib */
10208 EndPutM16Inc(data
, 0x2240); /* MOVEA.L D0,A1 */
10210 EndPutM32Inc(data
, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
10211 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
10212 EndPutM16Inc(data
,0x4E75); /* RTS */
10213 nameref
= data
-tempbuf
-8;
10214 memcpy(data
, name
, strlen(name
));
10215 data
+= strlen(name
);
10216 do { *(data
++) = 0; } while((data
-tempbuf
)&3);
10218 EndPutM32(tempbuf
, HUNK_CODE
);
10219 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
10220 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
10222 if(Flags
& FLAG_SMALLDATA
)
10224 EndPutM32(tempbuf
, HUNK_DREL16
);
10228 EndPutM32(tempbuf
, HUNK_ABSRELOC32
);
10230 EndPutM32(tempbuf
+4, 2); /* 2 entries */
10231 EndPutM32(tempbuf
+8, 1); /* to hunk 1 */
10232 EndPutM32(tempbuf
+12, rel1
); /* address 0 */
10233 EndPutM32(tempbuf
+16, rel2
); /* address 0 */
10234 EndPutM32(tempbuf
+20, 0); /* end of reloc hunk */
10235 DoOutputDirect(tempbuf
, 24);
10237 /* extern references */
10238 EndPutM32(tempbuf
, HUNK_EXT
);
10239 DoOutputDirect(tempbuf
, 4);
10241 OutputXREF2(4, sysref2
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "_SysBase");
10242 OutputXREF(verref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "__%sVer", BaseName
);
10243 OutputXREF(exitfuncref
, (Flags2
& FLAG2_SMALLCODE
? EXT_DEXT16
: EXT_REF32
), "_exit");
10244 OutputXDEF(0, "__INIT_%ld_%s", priority
, BaseName
);
10245 OutputXDEF(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
10246 OutputXDEF(nameref
, "%sname", ShortBaseName
);
10247 EndPutM32(tempbuf
, 0); /* ext end */
10248 DoOutputDirect(tempbuf
, 4);
10250 if(!(Flags
& FLAG_NOSYMBOL
))
10252 EndPutM32(tempbuf
, HUNK_SYMBOL
);
10253 DoOutputDirect(tempbuf
, 4);
10254 OutputSYMBOL(0, "__INIT_%ld_%s", priority
, BaseName
);
10255 OutputSYMBOL(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
10256 OutputSYMBOL(nameref
, "%sname", ShortBaseName
);
10257 EndPutM32(tempbuf
, 0);
10258 DoOutputDirect(tempbuf
, 4);
10261 EndPutM32(tempbuf
, HUNK_END
);
10262 DoOutputDirect(tempbuf
, 4);
10264 i
= strlen(datahunkname
);
10265 EndPutM32(tempbuf
, HUNK_NAME
);
10266 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
10267 DoOutputDirect(tempbuf
, 8);
10268 DoOutputDirect(datahunkname
, i
);
10269 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10271 EndPutM32(tempbuf
, HUNK_BSS
);
10272 EndPutM32(tempbuf
+4, 1);
10273 DoOutputDirect(tempbuf
, 8);
10275 EndPutM32(tempbuf
, HUNK_EXT
);
10276 DoOutputDirect(tempbuf
, 4);
10277 OutputXDEF(0, "_%s", BaseName
);
10278 EndPutM32(tempbuf
, 0); /* ext end */
10279 DoOutputDirect(tempbuf
, 4);
10281 if(!(Flags
& FLAG_NOSYMBOL
))
10283 EndPutM32(tempbuf
, HUNK_SYMBOL
);
10284 DoOutputDirect(tempbuf
, 4);
10285 OutputSYMBOL(0, "_%s", BaseName
);
10286 EndPutM32(tempbuf
, 0);
10287 DoOutputDirect(tempbuf
, 4);
10290 EndPutM32(tempbuf
, HUNK_END
);
10291 DoOutputDirect(tempbuf
, 4);
10293 sprintf(filename
, "%s_autoopenver", ShortBaseName
);
10294 i
= strlen(filename
);
10295 EndPutM32(tempbuf
, HUNK_UNIT
);
10296 EndPutM32(tempbuf
+4, (i
+3)>>2);
10297 DoOutputDirect(tempbuf
, 8);
10298 DoOutputDirect(filename
, i
);
10299 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10301 i
= strlen(datahunkname
);
10302 EndPutM32(tempbuf
, HUNK_NAME
);
10303 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
10304 DoOutputDirect(tempbuf
, 8);
10305 DoOutputDirect(datahunkname
, i
);
10306 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10308 EndPutM32(tempbuf
, HUNK_BSS
);
10309 EndPutM32(tempbuf
+4, 1);
10310 DoOutputDirect(tempbuf
, 8);
10312 EndPutM32(tempbuf
, HUNK_EXT
);
10313 DoOutputDirect(tempbuf
, 4);
10314 OutputXDEF(0, "_%sVer", BaseName
);
10315 EndPutM32(tempbuf
, 0); /* ext end */
10316 DoOutputDirect(tempbuf
, 4);
10318 if(!(Flags
& FLAG_NOSYMBOL
))
10320 EndPutM32(tempbuf
, HUNK_SYMBOL
);
10321 DoOutputDirect(tempbuf
, 4);
10322 OutputSYMBOL(0, "_%sVer", BaseName
);
10323 EndPutM32(tempbuf
, 0);
10324 DoOutputDirect(tempbuf
, 4);
10327 EndPutM32(tempbuf
, HUNK_END
);
10328 return DoOutputDirect(tempbuf
, 4);
10335 /* ------------------------------------------------------------------ */
10337 static uint32
GetName(struct NameList
*t
, struct ShortListRoot
*p
, uint32 args
)
10339 struct NameList
*p2
= (struct NameList
*) p
->First
;
10340 struct AmiPragma ap
;
10341 memset(&ap
, 0, sizeof(struct AmiPragma
));
10342 ap
.FuncName
= t
->NormName
;
10344 ap
.Args
[0].ArgName
= (args
? "args" : "tags");
10345 if(!MakeTagFunction(&ap
))
10351 while(p2
&& (!p2
->PragName
|| strcmp(p2
->PragName
, ap
.TagName
)))
10352 p2
= (struct NameList
*) p2
->List
.Next
;
10357 t
->Type
= (args
? NTP_ARGS
: NTP_TAGS
);
10358 t
->PragName
= ap
.TagName
;
10359 RemoveItem(p
, (struct ShortList
*) p2
);
10362 printf("GetName: name matches - %s _ %s\n", t
->NormName
, t
->PragName
);
10368 static void OptimizeFDData(struct PragData
*pd
)
10371 printf("OptimizeFDData\n");
10376 if(pd
->NumNames
> 1)
10378 struct ShortListRoot n
= {0,0,0}, p
= {0,0,0};
10379 struct NameList
*t
;
10380 while(pd
->Name
.First
) /* sorts in AmiCall and TagCall */
10382 t
= (struct NameList
*) pd
->Name
.First
;
10384 RemoveItem(&pd
->Name
, (struct ShortList
*) t
);
10385 AddItem(t
->PragName
? &p
: &n
, (struct ShortList
*) t
);
10390 t
= (struct NameList
*) n
.First
;
10391 while(p
.First
&& t
)
10393 if(!GetName(t
, &p
, 0))
10399 struct NameList
*t2
= (struct NameList
*) t
->List
.Next
;
10400 RemoveItem(&n
, (struct ShortList
*)t
);
10401 AddItem(&pd
->Name
, (struct ShortList
*) t
);
10405 t
= (struct NameList
*) t
->List
.Next
;
10411 t
= (struct NameList
*) n
.First
;
10412 t
->PragName
= ((struct NameList
*)(p
.First
))->PragName
;
10413 RemoveItem(&n
, (struct ShortList
*) t
);
10415 printf("OptimizeFDData: names together - %s _ %s\n", t
->NormName
, t
->PragName
);
10417 t
->Type
= NTP_UNKNOWN
;
10423 t
= (struct NameList
*) p
.First
;
10424 i
= strlen(t
->PragName
);
10425 t
->NormName
= DupString(t
->PragName
, i
+1);
10426 t
->NormName
[i
++] = 'A';
10427 t
->NormName
[i
] = 0;
10428 t
->Type
= NTP_TAGS
;
10430 printf("OptimizeFDData: NormName created - %s _ %s\n", t
->NormName
, t
->PragName
);
10434 AddItem(&pd
->Name
, (struct ShortList
*) t
);
10435 RemoveItem(&p
, p
.First
);
10439 AddItem(&pd
->Name
, n
.First
); /* add left NormNames */
10441 pd
= (struct PragData
*) pd
->List
.Next
;
10445 static uint32
MakeFD(struct PragList
*pl
)
10447 struct PragData
*pd
= (struct PragData
*) pl
->Data
.First
;
10451 printf("MakeFD\n");
10455 OptimizeFDData(pd
);
10457 printf("MakeFD: after Optimizing\n");
10459 DoOutput("##base _%s\n##bias %ld\n##public\n", pl
->Basename
, bias
);
10461 while(pd
&& Output_Error
)
10463 struct NameList
*n
= (struct NameList
*) pd
->Name
.First
;
10465 if(bias
!= pd
->Bias
)
10466 DoOutput("##bias %ld\n", (bias
= pd
->Bias
));
10470 strptr lastpar
= "last";
10473 if(n
->Type
== NTP_TAGS
)
10475 else if(n
->Type
== NTP_ARGS
)
10478 DoOutput("%s("/*)*/,n
->NormName
);
10480 DoOutput(/*(*/")()\n");
10483 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
10484 DoOutput("par%ld,",i
+1);
10485 DoOutput(/*(*/"%s)("/*)*/, lastpar
);
10486 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
10487 DoOutput("%s,", RegNames
[pd
->ArgReg
[i
]]);
10488 DoOutput(/*(*/"%s)\n", RegNames
[pd
->ArgReg
[i
]]);
10490 if(n
->Type
== NTP_UNKNOWN
)
10493 for(i
= 0; n
->NormName
[i
] == n
->PragName
[i
]; ++i
)
10495 DoOutput("*tagcall");
10497 DoOutput("-%s", n
->NormName
+i
);
10499 DoOutput("+%s", n
->PragName
+i
);
10504 if((n
= (struct NameList
*) n
->List
.Next
))
10505 DoOutput("##bias %ld\n", pd
->Bias
);
10506 Flags
|= FLAG_DONE
;
10509 pd
= (struct PragData
*)pd
->List
.Next
; bias
+= BIAS_OFFSET
;
10512 DoOutput("##end\n");
10514 return Output_Error
;
10517 static uint32
AddFDData(struct ShortListRoot
*pls
, struct FDData
*fd
)
10519 struct NameList
*t
;
10520 struct PragList
*pl
= (struct PragList
*) pls
->First
;
10521 struct PragData
*pd
;
10523 while(pl
&& strcmp(pl
->Basename
, fd
->Basename
))
10524 pl
= (struct PragList
*) pl
->List
.Next
;
10529 printf("AddFDData: New PragList - %s\n", fd
->Basename
);
10531 if(!(pl
= (struct PragList
*) NewItem(pls
)))
10533 pl
->Basename
= fd
->Basename
;
10534 pl
->Data
.Size
= sizeof(struct PragData
);
10535 AddItem(pls
, (struct ShortList
*) pl
);
10538 if((pd
= (struct PragData
*) pl
->Data
.First
))
10540 while(pd
->List
.Next
&& ((struct PragData
*) pd
->List
.Next
)->Bias
10542 pd
= (struct PragData
*) pd
->List
.Next
;
10545 if(!pd
|| pd
->Bias
!= fd
->Bias
)
10547 struct PragData
*pd2
;
10549 printf("AddFDData: New PragData - %ld, %ld\n", fd
->Bias
, fd
->NumArgs
);
10551 if(!(pd2
= (struct PragData
*) NewItem(&pl
->Data
)))
10553 pd2
->Bias
= fd
->Bias
;
10554 memcpy(pd2
->ArgReg
, fd
->ArgReg
, MAXREG
);
10555 pd2
->NumArgs
= fd
->NumArgs
;
10556 pd2
->Name
.Size
= sizeof(struct NameList
);
10558 AddItem(&pl
->Data
, (struct ShortList
*) pd2
);
10559 else if(pd
->Bias
> fd
->Bias
) /* Insert at start */
10561 pd2
->List
.Next
= pl
->Data
.First
;
10562 pl
->Data
.First
= (struct ShortList
*) pd2
;
10564 else /* Insert the entry */
10566 pd2
->List
.Next
= pd
->List
.Next
;
10567 pd
->List
.Next
= (struct ShortList
*) pd2
;
10573 uint32 i
= fd
->NumArgs
;
10574 if(fd
->NumArgs
!= pd
->NumArgs
)
10577 printf("ArgNum %ld != %ld\n", fd
->NumArgs
, pd
->NumArgs
);
10579 return ERR_DIFFERENT_TO_PREVIOUS
;
10584 if(fd
->ArgReg
[i
] != pd
->ArgReg
[i
])
10587 printf("ArgReg %lx != %lx\n", fd
->ArgReg
[i
], pd
->ArgReg
[i
]);
10589 return ERR_DIFFERENT_TO_PREVIOUS
;
10594 t
= (struct NameList
*) pd
->Name
.First
; /* skips same names */
10595 while(t
&& (!(fd
->Mode
? t
->PragName
: t
->NormName
) ||
10596 strcmp(fd
->Name
, fd
->Mode
? t
->PragName
: t
->NormName
)))
10597 t
= (struct NameList
*) t
->List
.Next
;
10602 if(!(t
= (struct NameList
*) NewItem(&pd
->Name
)))
10605 t
->PragName
= fd
->Name
;
10607 t
->NormName
= fd
->Name
;
10608 AddItem(&pd
->Name
, (struct ShortList
*) t
);
10611 printf("AddFDData: New NameList - %s\n", fd
->Name
);
10616 static string
GetHexValue(string data
)
10619 return (string
) (data
- 'a' + 10);
10620 else if(data
>= 'A')
10621 return (string
) (data
- 'A' + 10);
10623 return (string
) (data
- '0');
10626 static string
GetDoubleHexValue(strptr data
)
10628 return (string
)((GetHexValue(*data
)<<4)+GetHexValue(data
[1]));
10631 static uint32
GetLibData(struct FDData
*fd
)
10634 fd
->Name
= SkipBlanks(in
.pos
);
10635 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
10636 in
.pos
= SkipBlanks(in
.pos
);
10637 fd
->Bias
= strtoul(in
.pos
, 0, 16);
10638 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
)));
10639 if((fd
->NumArgs
= GetHexValue(*(--in
.pos
))) > MAXREGNF
- 2)
10640 return ERR_TO_MUCH_ARGUMENTS
;
10641 --in
.pos
; /* skips return register */
10642 for(i
= 0; i
< fd
->NumArgs
; ++i
)
10644 if((fd
->ArgReg
[i
] = GetHexValue(*(--in
.pos
))) > REG_A5
)
10645 return ERR_EXPECTED_REGISTER_NAME
;
10650 static uint32
GetFlibData(struct FDData
*fd
)
10653 fd
->Name
= SkipBlanks(in
.pos
);
10654 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
10655 in
.pos
= SkipBlanks(in
.pos
);
10656 fd
->Bias
= strtoul(in
.pos
, 0, 16);
10657 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
))) - 2;
10658 if((fd
->NumArgs
= GetDoubleHexValue(in
.pos
)) > MAXREG
-2)
10659 return ERR_TO_MUCH_ARGUMENTS
;
10660 in
.pos
-= 2; /* skips return register */
10661 for(i
= 0; i
< fd
->NumArgs
; ++i
)
10664 if((fd
->ArgReg
[i
] = GetDoubleHexValue(in
.pos
)) >= MAXREG
)
10665 return ERR_EXPECTED_REGISTER_NAME
;
10666 else if(fd
->ArgReg
[i
] >= REG_FP0
&& (Flags
& FLAG_NOFPU
))
10667 return ERR_FLOATARG_NOT_ALLOWED
;
10672 static uint32
GetAmiData(struct FDData
*fd
)
10675 in
.pos
= SkipBlanks(in
.pos
);
10676 if(*in
.pos
!= '('/*)*/)
10677 return ERR_EXPECTED_OPEN_BRACKET
;
10678 fd
->Basename
= ++in
.pos
;
10679 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
10681 return ERR_EXPECTED_COMMA
;
10683 in
.pos
= SkipBlanks(++in
.pos
);
10684 if(!strncmp(in
.pos
, "0x", 2))
10685 fd
->Bias
= strtoul(in
.pos
+2, 0, 16);
10687 fd
->Bias
= strtoul(in
.pos
, 0, 10);
10689 in
.pos
= SkipBlanks(SkipName(in
.pos
));
10691 return ERR_EXPECTED_COMMA
;
10692 fd
->Name
= in
.pos
= SkipBlanks(++in
.pos
);
10693 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
10694 if(*in
.pos
!= '('/*)*/)
10695 return ERR_EXPECTED_OPEN_BRACKET
;
10697 in
.pos
= SkipBlanks(++in
.pos
);
10698 if(*in
.pos
== /*(*/')')
10701 while(*in
.pos
!= /*(*/')')
10704 in
.pos
= SkipBlanks(in
.pos
+1);
10706 for(i
= 0; i
< REG_FP0
; i
++)
10707 if(!strnicmp(RegNames
[i
], in
.pos
, 2))
10711 for(; i
< MAXREG
; i
++)
10712 if(!strnicmp(RegNames
[i
], in
.pos
, 3))
10717 return ERR_EXPECTED_REGISTER_NAME
;
10718 else if(i
>= REG_FP0
&& (Flags
& FLAG_NOFPU
))
10719 return ERR_FLOATARG_NOT_ALLOWED
;
10721 fd
->ArgReg
[fd
->NumArgs
] = i
; ++fd
->NumArgs
;
10723 if(fd
->NumArgs
> MAXREG
-2)
10724 return ERR_TO_MUCH_ARGUMENTS
;
10726 in
.pos
= SkipBlanks(in
.pos
+(i
>= REG_FP0
? 3 : 2));
10728 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
10729 return ERR_EXPECTED_CLOSE_BRACKET
;
10731 in
.pos
= SkipBlanks(in
.pos
+1);
10732 if(*in
.pos
!= /*(*/')')
10733 return ERR_EXPECTED_CLOSE_BRACKET
;
10737 static uint32
CreateFDFile(void)
10739 struct ShortListRoot pl
= {0, 0, sizeof(struct PragList
)};
10740 uint32 linenum
, err
= 0, skip
;
10743 ptr
= p2
= args
.infile
;
10746 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
10750 for(p2
= ptr
; *p2
&& *p2
!= '_' && *p2
!= '.'; ++p2
)
10754 ShortBaseName
= ptr
;
10758 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
10760 in
.pos
= SkipBlanks(in
.pos
);
10761 if(!strncmp("#pragma", in
.pos
, 7))
10766 memset(&fd
, 0, sizeof(struct FDData
));
10768 in
.pos
= SkipBlanks(in
.pos
+7);
10769 if(!strncmp("tagcall", in
.pos
, 7))
10772 in
.pos
= SkipBlanks(in
.pos
+7);
10773 if(*in
.pos
== '(' /*)*/) /* Storm method */
10774 err
= GetAmiData(&fd
);
10775 else /* SAS method */
10777 fd
.Basename
= in
.pos
;
10778 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
10779 err
= GetLibData(&fd
);
10782 else if(!strncmp("amicall", in
.pos
, 7)) /* Storm method */
10785 err
= GetAmiData(&fd
);
10787 else if(!strncmp("libcall", in
.pos
, 7)) /* SAS method */
10789 fd
.Basename
= SkipBlanks(in
.pos
+7);
10790 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
10791 err
= GetLibData(&fd
);
10793 else if(!strncmp("flibcall", in
.pos
, 8)) /* SAS method */
10795 fd
.Basename
= SkipBlanks(in
.pos
+8);
10796 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
10797 err
= GetFlibData(&fd
);
10799 else if(!strncmp("syscall", in
.pos
, 7)) /* SAS method */
10801 fd
.Basename
= "SysBase";
10802 err
= GetLibData(&fd
);
10808 DoError(err
, linenum
);
10811 else if((err
= AddFDData(&pl
, &fd
)))
10814 DoError(err
, linenum
);
10818 while(*(in
.pos
++)) /* jumps to first char of next line */
10824 struct PragList
*p
= (struct PragList
*) pl
.First
;
10832 text
= ShortBaseName
; i
= strlen(text
);
10836 text
= p
->Basename
; i
= strlen(text
)-4;
10839 to
= DupString(text
, i
+ sizeof(FDFILEEXTENSION
) - 1);
10840 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
10855 i
= strlen(p
->Basename
) - 4;
10856 to
= DupString(p
->Basename
, i
+ sizeof(FDFILEEXTENSION
) - 1);
10857 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
10864 p
= (struct PragList
*) p
->List
.Next
;
10872 #ifdef FD2PRAGMA_READARGS
10873 #include <proto/dos.h>
10875 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
10876 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
10877 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
10878 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
10879 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
10881 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
10882 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
10883 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
10884 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
10912 uint32 NOPPCREGNAME
;
10923 uint32 SYSTEMRELEASE
;
10928 static const strptr helptext
=
10929 "INFILE: the input file which should be used\n"
10930 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
10931 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
10932 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
10933 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
10934 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
10935 "\t 6 - pragma for all compilers [default]\n"
10936 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
10937 "\t10 - stub-functions for C - C text\n"
10938 "\t11 - stub-functions for C - assembler text\n"
10939 "\t12 - stub-functions for C - link library\n"
10940 "\t13 - defines and link library for local library base (register call)\n"
10941 "\t14 - defines and link library for local library base (stack call)\n"
10942 "\t15 - stub-functions for Pascal - assembler text\n"
10943 "\t16 - stub-functions for Pascal - link library\n"
10944 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
10945 "\t18 - module for AmigaE\n"
10946 "\t20 - assembler lvo _lvo.i file\n"
10947 "\t21 - assembler lvo _lib.i file\n"
10948 "\t22 - assembler lvo _lvo.i file no XDEF\n"
10949 "\t23 - assembler lvo _lib.i file no XDEF\n"
10950 "\t24 - assembler lvo link library\n"
10951 "\t30 - proto file with pragma/..._lib.h call\n"
10952 "\t31 - proto file with pragma/..._pragmas.h call\n"
10953 "\t32 - proto file with pragmas/..._lib.h call\n"
10954 "\t33 - proto file with pragmas/..._pragmas.h call\n"
10955 "\t34 - proto file with local/..._loc.h call\n"
10956 "\t35 - proto file for all compilers (VBCC stubs)\n"
10957 "\t36 - proto file for GNU-C compiler only\n"
10958 "\t37 - proto file without lib definitions\n"
10959 "\t38 - proto file for all compilers (VBCC inline)\n"
10960 "\t39 - proto file with special PPC related checks\n"
10961 "\t40 - GCC inline file (preprocessor based)\n"
10962 "\t41 - GCC inline file (old type - inline based)\n"
10963 "\t42 - GCC inline file (library stubs)\n"
10964 "\t43 - GCC inline file (new style - macro)\n"
10965 "\t44 - GCC inline file (new style - inline)\n"
10966 "\t45 - GCC inline file (new style - inline with include lines)\n"
10967 "\t46 - GCC inline file (preprocessor based, direct)\n"
10968 "\t47 - GCC inline file (new style, direct)\n"
10969 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
10970 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
10971 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
10972 "\t52 - GCC inline files for PowerUP (library stubs)\n"
10973 "\t53 - SAS-C include file for PowerUP\n"
10974 "\t54 - Proto file for PowerUP\n"
10975 "\t60 - FPC pascal unit text\n"
10976 "\t70 - VBCC inline files\n"
10977 "\t71 - VBCC WOS stub-functions - assembler text\n"
10978 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
10979 "\t73 - VBCC WOS stub-functions - link library\n"
10980 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
10981 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
10982 "\t76 - VBCC PowerUP stub-functions - link library\n"
10983 "\t77 - VBCC WOS inline files\n"
10984 "\t78 - VBCC MorphOS stub-functions - link library\n"
10985 "\t79 - VBCC old inline files\n"
10986 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
10987 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
10988 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
10989 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
10990 "\t90 - stub-functions for C - assembler text (multiple files)\n"
10991 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
10992 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
10993 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
10994 " 100 - PPC assembler lvo file\n"
10995 " 101 - PPC assembler lvo file no XDEF\n"
10996 " 102 - PPC assembler lvo ELF link library\n"
10997 " 103 - PPC assembler lvo EHF link library\n"
10998 " 104 - PPC V.4-ABI assembler file\n"
10999 " 105 - PPC V.4-ABI assembler file no XDEF\n"
11000 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
11001 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
11003 " 111 - CLIB file\n"
11004 " 112 - SFD file\n"
11005 " 120 - VBCC auto libopen files (C source)\n"
11006 " 121 - VBCC auto libopen files (m68k link library)\n"
11007 " 122 - VBCC MorphOS inline files\n"
11008 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
11009 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
11010 " 132 - GCC inline files for MorphOS (library stubs)\n"
11011 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
11012 " 134 - MorphOS gate stubs\n"
11013 " 135 - MorphOS gate stubs (prelib)\n"
11014 " 136 - MorphOS gate stubs (postlib)\n"
11015 " 137 - MorphOS gate stubs (reglib, prelib)\n"
11016 " 138 - MorphOS gate stubs (reglib, postlib)\n"
11017 " 200 - FD file (source is a pragma file!)\n"
11018 "MODE: SPECIAL 1-7:\n"
11019 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
11020 " 2: _PRAGMAS_..._LIB_H definition method\n"
11021 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
11022 " 4: no definition\n"
11023 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,130-138:\n"
11024 " 1: all functions, normal interface\n"
11025 " 2: only tag-functions, tagcall interface\n"
11026 " 3: all functions, normal and tagcall interface [default]\n"
11027 "TO: the destination directory (self creation of filename)\n"
11028 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
11029 "CLIB: name of the prototypes file in clib directory\n"
11030 "COPYRIGHT: the copyright text for CLIB files\n"
11031 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
11032 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
11033 "BASENAME: name of library base without '_'\n"
11034 "LIBNAME: name of the library (.e.g. dos.library)\n"
11035 "LIBTYPE: type of base library structure\n"
11036 "PRIORITY: priority for auto open files\n"
11037 "PREFIX: MorphOS gate prefix\n"
11038 "SUBPREFIX: MorphOS gate sub prefix\n"
11039 "PREMACRO: MorphOS gate file start macro\n"
11041 "AUTOHEADER add the typical automatic generated header\n"
11042 "COMMENT: copy comments found in input file\n"
11043 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
11044 "FPUONLY: work only with functions using FPU register arguments\n"
11045 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
11046 "NOFPU: disable usage of FPU register arguments\n"
11047 "NOPPC: disable usage of PPC-ABI functions\n"
11048 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
11049 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
11050 "ONLYCNAMES: do not create C++ or ASM names\n"
11051 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
11052 "PPCONLY: only use PPC-ABI functions\n"
11053 "PRIVATE: includes private declared functions\n"
11054 "SECTION: add section statements to asm texts\n"
11055 "SMALLCODE: generate small code link libraries or assembler text\n"
11056 "SMALLDATA: generate small data link libraries or assembler text\n"
11057 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
11058 "SORTED: sort generated files by name and not by bias value\n"
11059 "SYSTEMRELEASE: special handling of comments for system includes\n"
11060 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
11061 "VOIDBASE: library bases are of type void *\n";
11063 /* print the help text */
11064 static void printhelp(void)
11066 printf("%s\n%s\n\n%s", version
+6, PARAM
, helptext
);
11070 /* initializes the arguments and starts argument parsing */
11071 static void GetArgs(int argc
, char **argv
)
11073 struct RDArgs
*rda
;
11074 struct AmiArg amiargs
;
11077 if((rda
= (struct RDArgs
*) AllocDosObject(DOS_RDARGS
, 0)))
11079 rda
->RDA_ExtHelp
= helptext
;
11080 memset(&amiargs
, 0, sizeof(struct AmiArg
));
11081 if(ReadArgs(PARAM
, (int32
*) &amiargs
, rda
))
11086 l
= strlen(amiargs
.TO
? amiargs
.TO
: "") + 1
11087 + strlen(amiargs
.CLIB
? amiargs
.CLIB
: "") + 1
11088 + strlen(amiargs
.HEADER
? amiargs
.HEADER
: "") + 1
11089 + strlen(amiargs
.ABI
? amiargs
.ABI
: "") + 1
11090 + strlen(amiargs
.HUNKNAME
? amiargs
.HUNKNAME
: "") + 1
11091 + strlen(amiargs
.BASENAME
? amiargs
.BASENAME
: "") + 1
11092 + strlen(amiargs
.LIBTYPE
? amiargs
.LIBTYPE
: "") + 1
11093 + strlen(amiargs
.LIBNAME
? amiargs
.LIBNAME
: "") + 1
11094 + strlen(amiargs
.COPYRIGHT
? amiargs
.COPYRIGHT
: "") + 1
11095 + strlen(amiargs
.PREFIX
? amiargs
.PREFIX
: "") + 1
11096 + strlen(amiargs
.SUBPREFIX
? amiargs
.SUBPREFIX
: "") + 1
11097 + strlen(amiargs
.PREMACRO
? amiargs
.PREMACRO
: "") + 1
11098 + strlen(amiargs
.INFILE
) + 1;
11099 if((d
= AllocListMem(l
)))
11103 s
= amiargs
.INFILE
;
11104 args
.infile
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11105 if((s
= amiargs
.TO
))
11107 args
.to
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11109 if((s
= amiargs
.HEADER
))
11111 args
.header
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11113 if((s
= amiargs
.CLIB
))
11115 args
.clib
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11117 if((s
= amiargs
.HUNKNAME
))
11119 hunkname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11121 if((s
= amiargs
.BASENAME
))
11123 Flags
|= FLAG_BASENAME
;
11124 BaseName
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11126 if((s
= amiargs
.LIBTYPE
))
11128 Flags2
|= FLAG2_LIBTYPE
;
11129 libtype
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11131 if((s
= amiargs
.LIBNAME
))
11133 Flags2
|= FLAG2_LIBNAME
;
11134 libname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11136 if((s
= amiargs
.PREFIX
))
11138 prefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11140 if((s
= amiargs
.SUBPREFIX
))
11142 subprefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11144 if((s
= amiargs
.PREMACRO
))
11146 premacro
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11148 if((s
= amiargs
.COPYRIGHT
))
11150 Copyright
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
11152 if((s
= amiargs
.ABI
))
11154 defabi
= d
; while(*s
) *(d
++) = *(s
++); *d
= 0;
11156 if(amiargs
.EXTERNC
) Flags
^= FLAG_EXTERNC
;
11157 if(amiargs
.PRIVATE
) Flags
^= FLAG_PRIVATE
;
11158 if(amiargs
.NEWSYNTAX
) Flags
^= FLAG_NEWSYNTAX
;
11159 if(amiargs
.SMALLDATA
) Flags
^= FLAG_SMALLDATA
;
11160 if(amiargs
.SMALLCODE
) Flags2
^= FLAG2_SMALLCODE
;
11161 if(amiargs
.SMALLTYPES
) Flags2
^= FLAG2_SMALLTYPES
;
11162 if(amiargs
.USESYSCALL
) Flags
^= FLAG_SYSCALL
;
11163 if(amiargs
.OPT040
) Flags
^= FLAG_NOMOVEM
;
11164 if(amiargs
.NOFPU
) Flags
^= FLAG_NOFPU
;
11165 if(amiargs
.FPUONLY
) Flags
^= FLAG_FPUONLY
;
11166 if(amiargs
.NOPPC
) Flags
^= FLAG_NOPPC
;
11167 if(amiargs
.NOSYMBOL
) Flags
^= FLAG_NOSYMBOL
;
11168 if(amiargs
.PPCONLY
) Flags
^= FLAG_PPCONLY
;
11169 if(amiargs
.SECTION
) Flags
^= FLAG_ASMSECTION
;
11170 if(amiargs
.COMMENT
) Flags
^= FLAG_DOCOMMENT
;
11171 if(amiargs
.SORTED
) Flags
^= FLAG_SORTED
;
11172 if(amiargs
.ONLYCNAMES
) Flags
^= FLAG_ONLYCNAMES
;
11173 if(amiargs
.SYSTEMRELEASE
) Flags2
^= FLAG2_SYSTEMRELEASE
;
11174 if(amiargs
.VOIDBASE
) Flags2
^= FLAG2_VOIDBASE
;
11175 if(amiargs
.NOPPCREGNAME
) PPCRegPrefix
= "";
11176 if(amiargs
.AUTOHEADER
) Flags2
^= FLAG2_AUTOHEADER
;
11177 if(amiargs
.SPECIAL
)
11178 args
.special
= *amiargs
.SPECIAL
;
11180 args
.mode
= *amiargs
.MODE
;
11181 if(amiargs
.PRIORITY
)
11182 priority
= *amiargs
.PRIORITY
;
11187 PrintFault(IoErr(), 0);
11188 FreeDosObject(DOS_RDARGS
, rda
);
11197 static const strptr helptext
=
11199 " -i,--infile <input filename>\n"
11200 " -s,--special <number>\n"
11201 " -m,--mode <number>\n"
11202 " -t,--to <destination directory>\n"
11203 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
11204 " -c,--clib <clib prototypes filename>\n"
11205 " -d,--header <header file or \"\">\n"
11206 " -i,--libname <name of library>\n"
11207 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
11208 " -b,--basename <name of library base without '_'>\n"
11209 " -l,--libtype <name of base library type>\n"
11210 " -p,--priority <priority for auto open files>\n"
11211 " -r,--copyright<copyright text>\n"
11212 " --prefix <MorphOS gate prefix>\n"
11213 " --subprefix<MorphOS gate sub prefix>\n"
11214 " --premacro <MorphOS gate file start macro>\n"
11217 "--autoheader add the typical automatic generated header\n"
11218 "--comment copy comments found in input file\n"
11219 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
11220 "--fpuonly work only with functions using FPU register arguments\n"
11221 "--newsyntax uses new Motorola syntax for asm files\n"
11222 "--nofpu disable usage of FPU register arguments\n"
11223 "--noppc disable usage of PPC-ABI functions\n"
11224 "--noppcregname do not add 'r' to PPC register names\n"
11225 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
11226 "--onlycnames do not create C++ or ASM names\n"
11227 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
11228 "--ppconly only use PPC-ABI functions\n"
11229 "--private includes private declared functions\n"
11230 "--section add section statements to asm texts\n"
11231 "--smallcode generate small code link libraries or assembler text\n"
11232 "--smalldata generate small data link libraries or assembler text\n"
11233 "--smalltypes allow 8 and 16 bit types in registers\n"
11234 "--sorted sort generated files by name and not by bias value\n"
11235 "--systemrelease special handling of comments for system includes\n"
11236 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
11237 "--voidbase library bases are of type void *\n"
11239 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
11240 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
11241 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
11242 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
11243 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
11244 " 6 - pragma for all compilers [default]\n"
11245 " 7 - all compilers with pragma to inline redirect for GCC\n"
11246 " 10 - stub-functions for C - C text\n"
11247 " 11 - stub-functions for C - assembler text\n"
11248 " 12 - stub-functions for C - link library\n"
11249 " 13 - defines and link library for local library base (register call)\n"
11250 " 14 - defines and link library for local library base (stack call)\n"
11251 " 15 - stub-functions for Pascal - assembler text\n"
11252 " 16 - stub-functions for Pascal - link library\n"
11253 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
11254 " 18 - module for AmigaE\n"
11255 " 20 - assembler lvo _lvo.i file\n"
11256 " 21 - assembler lvo _lib.i file\n"
11257 " 22 - assembler lvo _lvo.i file no XDEF\n"
11258 " 23 - assembler lvo _lib.i file no XDEF\n"
11259 " 24 - assembler lvo link library\n"
11260 " 30 - proto file with pragma/..._lib.h call\n"
11261 " 31 - proto file with pragma/..._pragmas.h call\n"
11262 " 32 - proto file with pragmas/..._lib.h call\n"
11263 " 33 - proto file with pragmas/..._pragmas.h call\n"
11264 " 34 - proto file with local/..._loc.h call\n"
11265 " 35 - proto file for all compilers (VBCC stubs)\n"
11266 " 36 - proto file for GNU-C compiler only\n"
11267 " 37 - proto file without lib definitions\n"
11268 " 38 - proto file for all compilers (VBCC inline)\n"
11269 " 39 - proto file with special PPC related checks\n"
11270 " 40 - GCC inline file (preprocessor based)\n"
11271 " 41 - GCC inline file (old type - inline based)\n"
11272 " 42 - GCC inline file (library stubs)\n"
11273 " 43 - GCC inline file (new style - macro)\n"
11274 " 44 - GCC inline file (new style - inline)\n"
11275 " 45 - GCC inline file (new style - inline with include lines)\n"
11276 " 46 - GCC inline file (preprocessor based, direct)\n"
11277 " 47 - GCC inline file (new style, direct)\n"
11278 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
11279 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
11280 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
11281 " 52 - GCC inline files for PowerUP (library stubs)\n"
11282 " 53 - SAS-C include file for PowerUP\n"
11283 " 54 - Proto file for PowerUP\n"
11284 " 60 - FPC pascal unit text\n"
11285 " 70 - VBCC inline files\n"
11286 " 71 - VBCC WOS stub-functions - assembler text\n"
11287 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
11288 " 73 - VBCC WOS stub-functions - link library\n"
11289 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
11290 " 75 - VBCC PowerUP stub-functions - assembler text\n"
11291 " 76 - VBCC PowerUP stub-functions - link library\n"
11292 " 77 - VBCC WOS inline files\n"
11293 " 78 - VBCC MorphOS stub-functions - link library\n"
11294 " 79 - VBCC old inline files\n"
11295 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
11296 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
11297 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
11298 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
11299 " 90 - stub-functions for C - assembler text (multiple files)\n"
11300 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
11301 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
11302 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
11303 " 100 - PPC assembler lvo file\n"
11304 " 101 - PPC assembler lvo file no XDEF\n"
11305 " 102 - PPC assembler lvo ELF link library\n"
11306 " 103 - PPC assembler lvo EHF link library\n"
11307 " 104 - PPC V.4-ABI assembler file\n"
11308 " 105 - PPC V.4-ABI assembler file no XDEF\n"
11309 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
11310 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
11312 " 111 - CLIB file\n"
11313 " 112 - SFD file\n"
11314 " 120 - VBCC auto libopen files (C source)\n"
11315 " 121 - VBCC auto libopen files (m68k link library)\n"
11316 " 122 - VBCC MorphOS inline files\n"
11317 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
11318 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
11319 " 132 - GCC inline files for MorphOS (library stubs)\n"
11320 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
11321 " 134 - MorphOS gate stubs\n"
11322 " 135 - MorphOS gate stubs (prelib)\n"
11323 " 136 - MorphOS gate stubs (postlib)\n"
11324 " 137 - MorphOS gate stubs (reglib, prelib)\n"
11325 " 138 - MorphOS gate stubs (reglib, postlib)\n"
11326 " 200 - FD file (source is a pragma file!)\n"
11327 "mode: special 1-7\n"
11328 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
11329 " 2 - _PRAGMAS_..._LIB_H definition method\n"
11330 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
11331 " 4 - no definition\n"
11332 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,130-138:\n"
11333 " 1 - all functions, normal interface\n"
11334 " 2 - only tag-functions, tagcall interface\n"
11335 " 3 - all functions, normal and tagcall interface [default]\n";
11337 /* print the help text */
11338 static void printhelp(void)
11340 printf("%s\n%s", version
+6, helptext
);
11353 ARG_HELP
, ARG_INFILE
, ARG_SPECIAL
, ARG_MODE
, ARG_TO
, ARG_CLIB
, ARG_ABI
, ARG_COPYRIGHT
,
11354 ARG_HEADER
, ARG_HUNKNAME
, ARG_BASENAME
, ARG_LIBTYPE
,
11355 ARG_COMMENT
, ARG_EXTERNC
, ARG_FPUONLY
, ARG_NEWSYNTAX
, ARG_NOFPU
, ARG_NOPPC
,
11356 ARG_NOSYMBOL
, ARG_ONLYCNAMES
, ARG_OPT040
, ARG_PPCONLY
, ARG_PRIVATE
, ARG_SECTION
,
11357 ARG_SMALLDATA
, ARG_SORTED
, ARG_USESYSCALL
, ARG_NOPPCREGNAME
,
11358 ARG_SYSTEMRELEASE
, ARG_PRIORITY
, ARG_LIBNAME
, ARG_SMALLCODE
, ARG_VOIDBASE
,
11359 ARG_PREFIX
, ARG_SUBPREFIX
, ARG_PREMACRO
, ARG_SMALLTYPES
, ARG_AUTOHEADER
11362 /* argument definition array */
11363 static const struct ArgData argtexts
[] = {
11364 {"help", 'h', 4, ARG_HELP
},
11365 {"infile", 'i', 6, ARG_INFILE
},
11366 {"special", 's', 7, ARG_SPECIAL
},
11367 {"mode", 'm', 4, ARG_MODE
},
11368 {"to", 't', 2, ARG_TO
},
11369 {"clib", 'c', 4, ARG_CLIB
},
11370 {"abi", 'a', 3, ARG_ABI
},
11371 {"copyright", 'r', 9, ARG_COPYRIGHT
},
11372 {"header", 'd', 6, ARG_HEADER
},
11373 {"hunkname", 'n', 8, ARG_HUNKNAME
},
11374 {"basename", 'b', 8, ARG_BASENAME
},
11375 {"libtype", 'l', 7, ARG_LIBTYPE
},
11376 {"libname", 'i', 7, ARG_LIBNAME
},
11377 {"priority", 'p', 8, ARG_PRIORITY
},
11378 {"autoheader", 0, 10, ARG_AUTOHEADER
},
11379 {"comment", 0, 7, ARG_COMMENT
},
11380 {"externc", 0, 7, ARG_EXTERNC
},
11381 {"fpuonly", 0, 7, ARG_FPUONLY
},
11382 {"newsyntax", 0, 9, ARG_NEWSYNTAX
},
11383 {"nofpu", 0, 5, ARG_NOFPU
},
11384 {"noppc", 0, 5, ARG_NOPPC
},
11385 {"noppcregname", 0, 12, ARG_NOPPCREGNAME
},
11386 {"nosymbol", 0, 8, ARG_NOSYMBOL
},
11387 {"onlycnames", 0, 10, ARG_ONLYCNAMES
},
11388 {"opt040", 0, 6, ARG_OPT040
},
11389 {"ppconly", 0, 7, ARG_PPCONLY
},
11390 {"private", 0, 7, ARG_PRIVATE
},
11391 {"section", 0, 7, ARG_SECTION
},
11392 {"smalldata", 0, 9, ARG_SMALLDATA
},
11393 {"smalltypes", 0, 10, ARG_SMALLTYPES
},
11394 {"smallcode", 0, 9, ARG_SMALLCODE
},
11395 {"sorted", 0, 6, ARG_SORTED
},
11396 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE
},
11397 {"usesyscall", 0, 10, ARG_USESYSCALL
},
11398 {"voidbase", 0, 8, ARG_VOIDBASE
},
11399 {"prefix", 0, 6, ARG_PREFIX
},
11400 {"subprefix", 0, 9, ARG_SUBPREFIX
},
11401 {"premacro", 0, 8, ARG_PREMACRO
},
11402 {0,0,0,0}, /* end marker */
11405 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
11406 static uint32
ParseArgEntry(uint32 argc
, strptr
*argv
)
11408 uint32 numentries
= 1, l
;
11410 const struct ArgData
*ad
;
11412 if((*argv
)[0] != '-' || !(*argv
)[1])
11418 if((*argv
)[1] == ad
->ArgChar
|| ((*argv
)[1] == '-' && !strncmp(ad
->ArgName
, (*argv
)+2, ad
->ArgNameLen
)))
11426 case ARG_HELP
: printhelp(); break;
11427 case ARG_EXTERNC
: Flags
^= FLAG_EXTERNC
; break;
11428 case ARG_PRIVATE
: Flags
^= FLAG_PRIVATE
; break;
11429 case ARG_NEWSYNTAX
: Flags
^= FLAG_NEWSYNTAX
; break;
11430 case ARG_SMALLDATA
: Flags
^= FLAG_SMALLDATA
; break;
11431 case ARG_SMALLCODE
: Flags2
^= FLAG2_SMALLCODE
; break;
11432 case ARG_SMALLTYPES
: Flags2
^= FLAG2_SMALLTYPES
; break;
11433 case ARG_USESYSCALL
: Flags
^= FLAG_SYSCALL
; break;
11434 case ARG_OPT040
: Flags
^= FLAG_NOMOVEM
; break;
11435 case ARG_NOFPU
: Flags
^= FLAG_NOFPU
; break;
11436 case ARG_FPUONLY
: Flags
^= FLAG_FPUONLY
; break;
11437 case ARG_NOPPC
: Flags
^= FLAG_NOPPC
; break;
11438 case ARG_NOSYMBOL
: Flags
^= FLAG_NOSYMBOL
; break;
11439 case ARG_PPCONLY
: Flags
^= FLAG_PPCONLY
; break;
11440 case ARG_SECTION
: Flags
^= FLAG_ASMSECTION
; break;
11441 case ARG_COMMENT
: Flags
^= FLAG_DOCOMMENT
; break;
11442 case ARG_SORTED
: Flags
^= FLAG_SORTED
; break;
11443 case ARG_ONLYCNAMES
: Flags
^= FLAG_ONLYCNAMES
; break;
11444 case ARG_SYSTEMRELEASE
: Flags2
^= FLAG2_SYSTEMRELEASE
; break;
11445 case ARG_VOIDBASE
: Flags2
^= FLAG2_VOIDBASE
; break;
11446 case ARG_AUTOHEADER
: Flags2
^= FLAG2_AUTOHEADER
; break;
11447 case ARG_NOPPCREGNAME
: PPCRegPrefix
= "";
11449 a
= *argv
+((*argv
)[1] == '-' ? ad
->ArgNameLen
+2 : 2);
11452 if(argc
> 1) { a
= argv
[1]; numentries
= 2; }
11453 else { a
= 0; numentries
= 0;}
11463 a
[--l
] = 0; /* remove second " */
11467 case ARG_INFILE
: args
.infile
= a
; break;
11468 case ARG_COPYRIGHT
: Copyright
= a
; break;
11469 case ARG_TO
: args
.to
= a
; break;
11470 case ARG_ABI
: defabi
= a
; break;
11471 case ARG_CLIB
: args
.clib
= a
; break;
11472 case ARG_HEADER
: args
.header
= a
; break;
11473 case ARG_HUNKNAME
: hunkname
= a
; break;
11474 case ARG_PREFIX
: prefix
= a
; break;
11475 case ARG_SUBPREFIX
: subprefix
= a
; break;
11476 case ARG_PREMACRO
: premacro
= a
; break;
11477 case ARG_LIBTYPE
: libtype
= a
; Flags2
|= FLAG2_LIBTYPE
; break;
11478 case ARG_LIBNAME
: libname
= a
; Flags2
|= FLAG2_LIBNAME
; break;
11479 case ARG_BASENAME
: BaseName
= a
; Flags
|= FLAG_BASENAME
; break;
11481 args
.special
= strtoul(a
, &b
, 10);
11486 priority
= strtoul(a
, &b
, 10);
11491 args
.mode
= strtoul(a
, &b
, 10);
11492 if(*b
|| args
.mode
< 1 || args
.mode
> 3)
11501 /* initializes the arguments and starts argument parsing */
11502 static void GetArgs(int argc
, char **argv
)
11507 while(i
< argc
&& res
)
11509 if((j
= ParseArgEntry(argc
-i
, argv
+i
)) < 1)
11514 if(!res
|| !args
.infile
)
11520 static strptr
mygetfile(strptr name
, size_t *len
)
11525 if((infile
= fopen(name
, "rb")))
11527 if(!fseek(infile
, 0, SEEK_END
))
11529 *len
= ftell(infile
);
11530 if(!fseek(infile
, SEEK_SET
, 0))
11532 if((ptr
= AllocListMem(*len
+1)))
11536 printf("mygetfile: '%s' size %ld\n", name
, *len
);
11538 if(fread(ptr
, *len
, 1, infile
) != 1)
11548 int main(int argc
, char **argv
)
11550 uint32 mode
= 0, pragmode
= PRAGMODE_PRAGLIB
, callmode
= TAGMODE_BOTH
;
11551 strptr amicall
= 0, libcall
= 0, amitags
= 0, libtags
= 0;
11553 size_t clibsize
= 0;
11555 GetArgs(argc
, argv
);
11557 if((tempbuf
= (uint8
*) AllocListMem(TEMPSIZE
)))
11559 if(!(in
.pos
= in
.buf
= mygetfile(args
.infile
, &in
.size
)))
11561 if(args
.special
== 200)
11563 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
11568 sprintf((strptr
)tempbuf
, "%s" SFDFILEEXTENSION
, args
.infile
);
11569 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
11571 sprintf((strptr
)tempbuf
, "%s" FDFILEEXTENSION
, args
.infile
);
11572 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
11574 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
11578 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
11581 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
11584 printf("SourceFile: %s\n", args
.infile
);
11586 MakeLines(in
.pos
, in
.size
);
11588 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SORTED
)) /* is not possible to use both */
11590 DoError(ERR_SORTED_COMMENT
, 0);
11591 Flags
&= (~FLAG_SORTED
);
11594 if(args
.special
== 200)
11608 if(Flags2
& FLAG2_SFDMODE
)
11609 DoError(ERR_SFD_AND_CLIB
, 0);
11612 sprintf((strptr
)tempbuf
, "%s_protos.h", args
.clib
);
11613 if(!(clibbuf
= mygetfile(args
.clib
, &clibsize
)) && !(clibbuf
= mygetfile((strptr
)tempbuf
, &clibsize
)))
11615 DoError(ERR_OPEN_FILE
, 0, args
.clib
);
11618 ScanClibFile(clibbuf
, clibbuf
+clibsize
);
11622 if(!MakeShortBaseName())
11624 DoError(ERR_MISSING_SHORTBASENAME
, 0);
11628 /* WARN when requesting obsolete types! */
11629 switch(args
.special
)
11631 case 1: case 2: case 3: case 4: case 5: case 7:
11632 printf("You use obsolete data type %ld, better use type 6!\n", args
.special
);
11634 case 11: case 15: case 71: case 72: case 75:
11635 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
11636 "link libraries!\n", args
.special
);
11638 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
11639 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args
.special
);
11642 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
11646 if(args
.special
< 10) /* the pragma area is up to 9 */
11648 mode
= MODUS_PRAGMA
;
11649 sprintf(filename
, "%s_lib.h", ShortBaseName
);
11651 switch(args
.special
)
11654 case 1: pragmode
= PRAGMODE_PRAGSLIB
; amicall
= ""; break;
11655 case 2: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
11656 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= ""; break;
11657 case 3: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
11658 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= "";
11659 libtags
= "def " TEXT_SAS_60
; break;
11660 case 4: amicall
= ""; break;
11661 case 5: amicall
= amitags
= ""; break;
11662 case 7: Flags
|= FLAG_GNUPRAG
; /* no break ! */
11663 case 6: amicall
= " defined(" TEXT_AZTEC
") || defined("
11664 TEXT_MAXON
") || defined(" TEXT_STORM
")";
11665 libcall
= " defined(" TEXT_DICE
") || defined(" TEXT_SAS
")";
11666 libtags
= "def " TEXT_SAS_60
; amitags
="def " TEXT_STORM
; break;
11667 default: mode
= MODUS_ERROR
; break;
11670 if(args
.mode
> 0 && args
.mode
< 5)
11671 pragmode
= args
.mode
;
11673 else if(args
.special
< 20) /* the misc area is up to 19 */
11675 if(args
.mode
> 0 && args
.mode
< 4)
11676 callmode
= args
.mode
- 1;
11677 switch(args
.special
)
11679 case 10: mode
= MODUS_CSTUB
;
11680 sprintf(filename
, "%s_cstub.h", ShortBaseName
); break;
11681 case 11: mode
= MODUS_STUBTEXT
;
11682 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
11683 case 12: mode
= MODUS_STUBCODE
;
11684 sprintf(filename
, "%s.lib", ShortBaseName
); break;
11685 case 13: Flags
|= FLAG_LOCALREG
; /* no break ! */
11686 case 14: mode
= MODUS_LOCALDATA
;
11687 sprintf(filename
, "%s_loc.h", ShortBaseName
); break;
11688 case 15: mode
= MODUS_STUBTEXT
; callmode
= TAGMODE_NORMAL
;
11689 Flags
^= FLAG_PASCAL
;
11690 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
11691 case 16: mode
= MODUS_STUBCODE
; callmode
= TAGMODE_NORMAL
;
11692 Flags
^= FLAG_PASCAL
;
11693 sprintf(filename
, "%s.lib", ShortBaseName
); break;
11694 case 17: mode
= MODUS_BMAP
; callmode
= TAGMODE_NORMAL
;
11695 sprintf(filename
, "%s.bmap", ShortBaseName
); break;
11696 case 18: mode
= MODUS_EMODULE
;
11697 sprintf(filename
, "%s.m", ShortBaseName
); break;
11698 default: mode
= MODUS_ERROR
; break;
11701 else if(args
.special
< 30) /* the lvo area is up to 29 */
11703 switch(args
.special
)
11705 case 20: case 22: mode
= MODUS_LVO
+args
.special
-20;
11706 sprintf(filename
, "%s_lvo.i", ShortBaseName
); break;
11707 case 21: case 23: mode
= MODUS_LVO
+args
.special
-20;
11708 sprintf(filename
, "%s_lib.i", ShortBaseName
); break;
11709 case 24: mode
= MODUS_LVOLIB
;
11710 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
11711 default: mode
= MODUS_ERROR
; break;
11714 else if(args
.special
< 40) /* the proto area is up to 39 */
11716 if(args
.special
< 40)
11718 mode
= MODUS_PROTO
+args
.special
-30;
11719 sprintf(filename
, "%s.h", ShortBaseName
);
11722 mode
= MODUS_ERROR
;
11724 else if(args
.special
< 50) /* the inline area is up to 49 */
11726 if(args
.mode
> 0 && args
.mode
< 4)
11727 callmode
= args
.mode
- 1;
11729 switch(args
.special
)
11731 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
11733 mode
= MODUS_INLINE
+args
.special
-40;
11734 sprintf(filename
, "%s.h", ShortBaseName
); break;
11736 Flags
|= FLAG_STORMGCC
;
11737 /* the same mode as for 46, but additional flag */
11738 mode
= MODUS_INLINE
+args
.special
-40-2;
11739 sprintf(filename
, "%s.h", ShortBaseName
); break;
11740 default: mode
= MODUS_ERROR
; break;
11743 else if(args
.special
< 60) /* the PowerUP area is up to 59 */
11745 if(args
.mode
> 0 && args
.mode
< 4)
11746 callmode
= args
.mode
- 1;
11748 switch(args
.special
)
11750 case 50: case 51: case 52: mode
= MODUS_INLINE
+args
.special
-50;
11751 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_POWERUP
;
11754 sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
11755 mode
= MODUS_SASPOWER
; break;
11757 sprintf(filename
, "%s.h", ShortBaseName
);
11758 mode
= MODUS_PROTOPOWER
; break;
11759 default: mode
= MODUS_ERROR
; break;
11762 else if(args
.special
< 70) /* the PASCAL stuff */
11764 if(args
.special
== 60)
11766 mode
= MODUS_PASCAL
;
11767 sprintf(filename
, "%s.pas", ShortBaseName
);
11770 mode
= MODUS_ERROR
;
11772 else if(args
.special
< 80) /* the VBCC stuff */
11774 if(args
.mode
> 0 && args
.mode
< 4)
11775 callmode
= args
.mode
- 1;
11777 switch(args
.special
)
11779 case 70: mode
= MODUS_VBCCINLINE
;
11780 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
11781 case 71: case 72: case 75:
11782 mode
= MODUS_VBCC
+args
.special
-71;
11783 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
11785 mode
= MODUS_VBCC
+args
.special
-71;
11786 sprintf(filename
, "%s.lib", ShortBaseName
); break;
11788 mode
= MODUS_VBCCPUPLIB
;
11789 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
11790 case 77: mode
= MODUS_VBCCWOSINLINE
;
11791 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
11792 case 78: mode
= MODUS_VBCCMORPHCODE
;
11793 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
11794 case 79: mode
= MODUS_VBCCINLINE
;
11795 Flags2
|= FLAG2_OLDVBCC
;
11796 callmode
= TAGMODE_NORMAL
;
11797 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
11798 default: mode
= MODUS_ERROR
; break;
11801 else if(args
.special
< 90) /* redirect stuff */
11803 mode
= MODUS_REDIRECT
;
11804 switch(args
.special
)
11806 case 80: sprintf(filename
, "%s_pragmas.h", ShortBaseName
); break;
11807 case 81: sprintf(filename
, "%s_lib.h", ShortBaseName
); break;
11808 case 82: sprintf(filename
, "%s.h", ShortBaseName
); break;
11809 case 83: sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
11810 default: mode
= MODUS_ERROR
; break;
11813 else if(args
.special
< 100) /* multifile stuff */
11815 Flags
|= FLAG_SINGLEFILE
;
11816 switch(args
.special
)
11819 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
11820 mode
= MODUS_ASMTEXTSF
; filenamefmt
= "%s.s";
11823 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
11824 mode
= MODUS_VBCCPUPTEXTSF
; filenamefmt
= "%s.s";
11827 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
11828 mode
= MODUS_VBCCWOSTEXTSF
; filenamefmt
= "%s.s";
11831 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
11832 mode
= MODUS_VBCCMORPHTEXTSF
; filenamefmt
= "%s.s";
11834 default: mode
= MODUS_ERROR
; break;
11837 else if(args
.special
< 110) /* PPC lvo's */
11839 switch(args
.special
)
11841 case 100: case 101: mode
= MODUS_LVOPPC
+args
.special
-100;
11842 sprintf(filename
, "%s_lib.i", ShortBaseName
);
11844 case 104: case 105: mode
= MODUS_LVOPPC
+args
.special
-104;
11845 Flags
|= FLAG_ABIV4
;
11846 sprintf(filename
, "%s_lib.i", ShortBaseName
);
11848 case 103: mode
= MODUS_LVOLIB
;
11849 sprintf(filename
, "%slvo.o", ShortBaseName
);
11851 case 107: mode
= MODUS_LVOLIB
;
11852 Flags
|= FLAG_ABIV4
;
11853 sprintf(filename
, "%slvo.o", ShortBaseName
);
11855 case 102: mode
= MODUS_LVOLIBPPC
;
11856 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
11857 case 106: mode
= MODUS_LVOLIBPPC
;
11858 Flags
|= FLAG_ABIV4
;
11859 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
11860 default: mode
= MODUS_ERROR
; break;
11863 else if(args
.special
< 120) /* different files */
11865 if(args
.mode
> 0 && args
.mode
< 4)
11866 callmode
= args
.mode
- 1;
11868 switch(args
.special
)
11870 case 110: mode
= MODUS_FD
;
11871 sprintf(filename
, "%s_lib.fd", ShortBaseName
);
11872 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
11874 DoError(ERR_SORTED_SFD_FD
, 0);
11875 Flags
&= (~FLAG_SORTED
);
11878 case 111: mode
= MODUS_CLIB
; Flags2
|= FLAG2_CLIBOUT
;
11879 sprintf(filename
, "%s_protos.h", ShortBaseName
);
11881 case 112: mode
= MODUS_SFD
; Flags2
|= FLAG2_SFDOUT
;
11882 sprintf(filename
, "%s_lib.sfd", ShortBaseName
);
11886 DoError(ERR_ONLYTAGMODE_NOTALLOWED
, 0);
11889 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
11891 DoError(ERR_SORTED_SFD_FD
, 0);
11892 Flags
&= (~FLAG_SORTED
);
11895 default: mode
= MODUS_ERROR
; break;
11898 else if(args
.special
< 130) /* auto libopen files */
11900 if(args
.mode
> 0 && args
.mode
< 4) /* for 122 */
11901 callmode
= args
.mode
- 1;
11903 switch(args
.special
)
11905 case 120: mode
= MODUS_GENAUTO
;
11906 sprintf(filename
, "%s_autoopenlib.c", ShortBaseName
);
11908 case 121: mode
= MODUS_GENAUTO
+(args
.special
-120);
11909 sprintf(filename
, "%s_autoopenlib.lib", ShortBaseName
);
11911 case 122: mode
= MODUS_VBCCMORPHINLINE
;
11912 PPCRegPrefix
= ""; /* no "r" allowed */
11913 sprintf(filename
, "%s_protos.h", ShortBaseName
);
11915 default: mode
= MODUS_ERROR
; break;
11918 else if(args
.special
< 140) /* the MorphOS area is up to 139 */
11920 if(args
.mode
> 0 && args
.mode
< 4)
11921 callmode
= args
.mode
- 1;
11923 switch(args
.special
)
11925 case 130: case 131: case 132: mode
= MODUS_INLINE
+args
.special
-130;
11926 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
11928 case 133: mode
= MODUS_INLINE
+2;
11929 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
11930 Flags2
|= FLAG2_DIRECTVARARGS
;
11932 case 134: mode
= MODUS_GATESTUBS
;
11933 sprintf(filename
, "%s_gates.h", ShortBaseName
);
11935 case 135: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
;
11936 sprintf(filename
, "%s_gates.h", ShortBaseName
);
11938 case 136: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
;
11939 sprintf(filename
, "%s_gates.h", ShortBaseName
);
11941 case 137: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
|FLAG2_REGLIB
;
11942 sprintf(filename
, "%s_gates.h", ShortBaseName
);
11944 case 138: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
|FLAG2_REGLIB
;
11945 sprintf(filename
, "%s_gates.h", ShortBaseName
);
11947 default: mode
= MODUS_ERROR
; break;
11951 if(Flags
& FLAG_SORTED
)
11954 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SINGLEFILE
)) /* is not possible to use both */
11956 DoError(ERR_COMMENT_SINGLEFILE
, 0);
11957 Flags
&= (~FLAG_DOCOMMENT
);
11960 if(!mode
|| mode
== MODUS_ERROR
)
11963 /* These modes need BaseName always. */
11964 if(!BaseName
&& (mode
== MODUS_PRAGMA
|| mode
== MODUS_STUBTEXT
||
11965 mode
== MODUS_STUBCODE
|| mode
== MODUS_EMODULE
|| (mode
>= MODUS_GENAUTO
&&
11966 mode
<= MODUS_GENAUTO
+9)))
11968 DoError(ERR_MISSING_BASENAME
, 0);
11972 if(args
.header
&& args
.header
[0] && (args
.header
[0] != '@' || args
.header
[1]))
11974 HEADER
= mygetfile(args
.header
, &headersize
);
11978 if(!(Flags
& FLAG_SINGLEFILE
))
11980 if(!OpenDest(filename
))
11984 /* from here mode is used as return result */
11985 if(mode
>= MODUS_GENAUTO
)
11986 mode
= CreateGenAuto(filename
, mode
-MODUS_GENAUTO
);
11987 else if(mode
>= MODUS_LVOPPC
)
11988 mode
= CreateLVOFilePPC(mode
-MODUS_LVOPPC
);
11989 else if(mode
>= MODUS_VBCC
)
11990 mode
= CreateVBCC(mode
-MODUS_VBCC
, callmode
);
11991 else if(mode
>= MODUS_INLINE
)
11992 mode
= CreateInline(mode
-MODUS_INLINE
, callmode
);
11993 else if(mode
>= MODUS_PROTO
)
11994 mode
= CreateProtoFile(mode
-MODUS_PROTO
+1);
11995 else if(mode
>= MODUS_LVO
)
11996 mode
= CreateLVOFile(mode
-MODUS_LVO
+1);
11997 else if(mode
== MODUS_VBCCMORPHINLINE
)
11998 mode
= CreateVBCCInline(2, callmode
);
11999 else if(mode
== MODUS_GATESTUBS
)
12000 mode
= CreateGateStubs(callmode
);
12001 else if(mode
== MODUS_SFD
)
12002 mode
= CreateSFD(callmode
);
12003 else if(mode
== MODUS_CLIB
)
12004 mode
= CreateClib(callmode
);
12005 else if(mode
== MODUS_FD
)
12007 else if(mode
== MODUS_LVOLIBPPC
)
12008 mode
= CreateLVOLibPPC();
12009 else if(mode
== MODUS_VBCCMORPHCODE
)
12010 mode
= CreateVBCCMorphCode(callmode
);
12011 else if(mode
== MODUS_VBCCMORPHTEXTSF
) /* single files */
12012 mode
= CallFunc(callmode
, "\n%s", FuncVBCCMorphText
);
12013 else if(mode
== MODUS_VBCCWOSINLINE
)
12014 mode
= CreateVBCCInline(1, callmode
);
12015 else if(mode
== MODUS_VBCCWOSTEXTSF
) /* single files */
12016 mode
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
);
12017 else if(mode
== MODUS_VBCCPUPTEXTSF
) /* single files */
12018 mode
= CallFunc(callmode
, "\n%s", FuncVBCCPUPText
);
12019 else if(mode
== MODUS_ASMTEXTSF
) /* single files */
12020 mode
= CallFunc(callmode
, "\n%s", FuncAsmText
);
12021 else if(mode
== MODUS_REDIRECT
)
12022 mode
= CreateProtoRedirect();
12023 else if(mode
== MODUS_EMODULE
)
12024 mode
= CreateEModule(Flags
& FLAG_SORTED
);
12025 else if(mode
== MODUS_LVOLIB
)
12026 mode
= CreateLVOLib();
12027 else if(mode
== MODUS_VBCCPUPLIB
)
12028 mode
= CreateVBCCPUPLib(callmode
);
12029 else if(mode
== MODUS_VBCCINLINE
)
12030 mode
= CreateVBCCInline(0, callmode
);
12031 else if(mode
== MODUS_PASCAL
)
12032 mode
= CreateFPCUnit();
12033 else if(mode
== MODUS_BMAP
)
12034 mode
= CreateBMAP();
12035 else if(mode
== MODUS_PROTOPOWER
)
12036 mode
= CreateProtoPowerUP();
12037 else if(mode
== MODUS_SASPOWER
)
12038 mode
= CreateSASPowerUP(callmode
);
12039 else if(mode
== MODUS_CSTUB
)
12040 mode
= CreateCSTUBSFile();
12041 else if(mode
== MODUS_PRAGMA
)
12042 mode
= CreatePragmaFile(amicall
, libcall
, amitags
, libtags
, pragmode
);
12043 else if(mode
== MODUS_LOCALDATA
)
12044 mode
= CreateLocalData(filename
, callmode
);
12045 else if(mode
) /* MODUS_STUBTEXT starts with 1 */
12046 mode
= CreateAsmStubs(mode
, callmode
);
12048 CloseDest(filename
);
12052 DoError(Output_Error
? ERR_UNKNOWN_ERROR
: ERR_WRITING_FILE
, 0);