added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / tools / fd2pragma / fd2pragma.c
blobf38bef06b3b20d6eb6a96a3db3552e5c19c0a5ae
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 */
4 /* #define DEBUG */
5 /* #define DEBUG_OLD */
7 /* Programmheader
9 Name: fd2pragma
10 Author: SDI
11 Distribution: PD
12 Description: creates pragmas files, lvo files, ...
13 Compileropts: -
14 Linkeropts: -
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:
23 Jochen Wiedmann
24 Am Eisteich 9
25 72555 Metzingen (Germany)
26 Tel. 07123 / 14881
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
35 CSTUBS)
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
42 message - fixed
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
58 scan errors
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
65 tagfunc
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),
77 removed C++ comments
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
82 numbers 11-16 (Sorry)
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
94 all now
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
108 handling
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
132 now :-(
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
147 new ones!, bug-fixes
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
154 tables missing
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
159 digit :-)
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
222 defective FD files
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
231 and Olaf Barthel
232 2.154 03.10.02 : added VBCC MorphOS inlines (SPECIAL 122). Thanks Frank Wille
233 for design help.
234 2.155 04.10.02 : optimized VBCC MorphOS text (SPECIAL 93), fixed VBCC MorphOS
235 inlines
236 2.156 06.10.02 : added warning about obsolete types, fixed VBCC MorphOS Code
237 (SPECIAL 78)
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
278 information.
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
282 automatically.
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.
293 #include <ctype.h>
294 #include <stdio.h>
295 #include <stdlib.h>
296 #include <string.h>
297 #include <stdarg.h>
298 #include <time.h>
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
399 #define MODUS_BMAP 8
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
413 #define MODUS_FD 22
414 #define MODUS_CLIB 23
415 #define MODUS_SFD 24
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
427 #define ABI_M68K 1
428 #define ABI_PPC 2
429 #define ABI_PPC2 3
430 #define ABI_PPC0 4
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"
448 #endif
449 #ifndef EXTTYPESFILE
450 #define EXTTYPESFILE "fd2pragma.types"
451 #endif
452 #ifndef EXTTYPESFILE2
453 #ifdef FD2PRAGMA_AMIGA
454 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
455 #else
456 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
457 #endif
458 #endif
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",
477 enum Register_ID {
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
482 #define MAXREGPPC 26
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 */
487 struct Args {
488 strptr infile;
489 strptr to;
490 strptr clib;
491 strptr header;
492 int32 special;
493 int32 mode;
496 struct ShortList {
497 struct ShortList *Next;
500 struct ShortListRoot {
501 struct ShortList *First;
502 struct ShortList *Last;
503 size_t Size;
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 */
523 struct AmiArgs {
524 strptr ArgName;
525 uint16 ArgReg;
528 #define NUMALIASNAMES 5
530 struct AmiPragma {
531 struct ShortList List;
532 uint32 Line;
533 uint32 Flags;
534 strptr FuncName;
535 strptr TagName;
536 struct Pragma_AliasName * AliasName[NUMALIASNAMES]; /* possible alias names */
537 uint16 NumArgs; /* register numbers */
538 uint16 CallArgs; /* argument number in fd file */
539 int16 Bias;
540 int8 NumAlias;
541 int8 Abi;
542 struct AmiArgs Args[MAXREGPPC];
545 struct Comment {
546 struct ShortList List;
547 strptr Data;
548 int16 Bias;
549 uint16 ReservedNum;
550 uint16 Version;
551 uint8 Private; /* is a flag only */
554 struct Include {
555 struct ShortList List;
556 strptr Include;
559 struct PragList {
560 struct ShortList List;
561 struct ShortListRoot Data; /* contains list of PragData */
562 strptr Basename;
565 struct PragData {
566 struct ShortList List;
567 struct ShortListRoot Name;
568 uint32 NumNames;
569 uint32 Bias;
570 uint32 NumArgs;
571 uint8 ArgReg[MAXREG];
574 struct FDData {
575 strptr Name;
576 strptr Basename;
577 uint32 Bias;
578 uint32 Mode; /* 0 = Normal, != 0 is TagName */
579 uint32 NumArgs;
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
619 a STRPTR occurs */
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 */
663 struct CPP_Unknown {
664 struct CPP_Unknown *Next;
665 strptr Unknown;
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 {
681 strptr FunctionName;
682 strptr AliasName;
683 uint32 Type;
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 */
691 struct NameList {
692 struct ShortList List;
693 uint32 Type; /* set by OptimizeFDData */
694 strptr NormName;
695 strptr PragName;
698 struct InFile {
699 strptr pos;
700 strptr buf;
701 size_t size;
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. */
713 #define ELFCLASS32 1
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
730 #define EI_NIDENT 16
731 #define EI_MAG0 0
732 #define EI_MAG1 1
733 #define EI_MAG2 2
734 #define EI_MAG3 3
735 #define EI_CLASS 4
736 #define EI_DATA 5
737 #define EI_VERSION 6
739 #define STB_LOCAL 0
740 #define STB_GLOBAL 1
741 #define STT_FUNC 2
742 #define STT_NOTYPE 0
743 #define STT_SECTION 3
744 #define STT_FILE 4
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
753 struct ArHeader {
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)));
856 #else
857 static uint32 DoOutput(strptr, ...);
858 #endif
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)
964 enum {
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,
979 ERR_A7_NOT_ALLOWED,
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,
985 ERR_WRITING_FILE,
986 ERR_EXPECTED_COMMA,
987 ERR_DIFFERENT_TO_PREVIOUS,
988 ERR_UNKNOWN_VARIABLE_TYPE,
989 ERR_UNKNOWN_ERROR,
990 ERR_MISSING_END,
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,
997 ERR_A6_NOT_ALLOWED,
998 ERR_EMPTY_FILE,
999 ERR_FLOATARG_NOT_ALLOWED,
1000 ERR_WRONG_TYPES_LINE,
1001 ERR_LONG_DOUBLE,
1002 ERR_CLIB_ARG_COUNT,
1003 ERR_OPEN_FILE,
1004 ERR_A5_NOT_ALLOWED,
1005 ERR_PPC_FUNCTION_NOT_SUPPORTED,
1006 ERR_UNKNOWN_ABI,
1007 ERR_NO_SORTED,
1008 ERR_ILLEGAL_FUNCTION_POSITION,
1009 ERR_SORTED_COMMENT,
1010 ERR_COMMENT_SINGLEFILE,
1011 ERR_NOFD2PRAGMATYPES,
1012 ERR_M68K_FUNCTION_NOT_SUPPORTED,
1013 ERR_UNKNOWN_RETURNVALUE_TYPE,
1014 ERR_SFD_AND_CLIB,
1015 ERR_EXCPECTED_IDSTRING,
1016 ERR_EXPECTED_ID_ENDSIGN,
1017 ERR_MISSING_SFDEND,
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,
1024 ERR_SORTED_SFD_FD,
1025 ERR_EARLY_SHADOW,
1026 ERR_DOUBLE_VARARGS,
1027 ERR_VARARGS_ARGUMENTS_DIFFER,
1028 ERR_UNEXPECTED_FILEEND,
1029 ERR_VARARGS_ALIAS_FIRST,
1030 ERR_ALIASNAMES,
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,
1039 ERR_PREFIX,
1040 ERR_MULTIPLEFUNCTION,
1041 ERR_INLINE_AX_SWAPREG,
1042 ERR_SFD_START,
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 */
1050 uint8 Skip;
1051 strptr Error;
1052 } Errors[] = {
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."},
1136 #ifdef __SASC
1137 __far
1138 #endif
1139 static uint8 InternalTypes[] = {
1140 "IX:struct InputXpression\n"
1141 "Msg:struct ? *\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"
1148 "GLvoid:void\n"
1149 "GLbitfield:unsigned long\n"
1150 "GLbyte:signed char\n"
1151 "GLshort:short\n"
1152 "GLint:long\n"
1153 "GLsizei:unsigned long\n"
1154 "GLubyte:unsigned char\n"
1155 "GLushort:unsigned short\n"
1156 "GLuint:unsigned long\n"
1157 "GLfloat:float\n"
1158 "GLclampf:float\n"
1159 "GLdouble:double\n"
1160 "GLclampd:double\n"
1161 "GLboolean:enum ?\n"
1162 "GLenum: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"
1183 "uid_t:long\n"
1184 "gid_t:long\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"
1194 "Fixed:long\n"
1195 "sposition: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"
1206 "W3D_Float:float\n"
1207 "W3D_Bitmap:struct W3D_Bitmap\n"
1208 "W3D_Fog:struct W3D_Fog\n"
1209 "W3D_Bool:short\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"
1216 "RGBFTYPE:enum ?\n"
1217 "DITHERINFO:void *\n"
1218 "SLayer:void *\n"
1219 "va_list:char *\n"
1220 "time_t:long\n"
1221 "size_t:unsigned int\n"
1222 "uint8:unsigned char\n"
1223 "uint16:unsigned short\n"
1224 "uint32:unsigned long\n"
1225 "int8:char\n"
1226 "int16:short\n"
1227 "int32:long\n"
1228 "AVLKey:void *\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"
1285 "DH:struct dh_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"
1304 "PKCS12: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},
1440 {0,0,0,0},
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},
1466 /* devices */
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"},
1486 {0, 0},
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"},
1494 {"ReadArgs", 0},
1495 {"FreeArgs", 0},
1496 {"CloneTagItems", 0},
1497 {"FindTagItem", 0},
1498 {"FreeTagItems", 0},
1499 {"GetTagData", 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},
1508 {0,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},
1519 {0,0,0},
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",
1571 #ifndef __SASC
1572 static int stricmp(const char *a, const char *b)
1574 while(*a && tolower(*a) == tolower(*b))
1576 ++a; ++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))
1585 ++a; ++b; --num;
1587 return num ? (tolower(*a) - tolower(*b)) : 0;
1589 #endif
1591 static strptr DupString(strptr Str, size_t Len)
1593 strptr res, r;
1594 if((res = r = AllocListMem(Len+1)))
1596 while(Len-- && *Str)
1597 *(r++) = *(Str++);
1598 *r = '\0';
1600 #ifdef DEBUG_OLD
1601 printf("DupString %s.\n", res);
1602 #endif
1603 return res;
1606 static strptr AllocListMem(size_t size)
1608 strptr a;
1609 #ifdef DEBUG_OLD
1610 printf("AllocListMem Size %ld.\n", size);
1611 #endif
1612 if((a = (strptr) malloc(size)))
1613 memset(a, 0, size);
1614 return a;
1617 static strptr SkipBlanks(strptr OldPtr)
1619 while(*OldPtr == ' ' || *OldPtr == '\t')
1620 ++OldPtr;
1621 return OldPtr;
1624 static strptr SkipBlanksRet(strptr OldPtr)
1626 while(*OldPtr == ' ' || *OldPtr == '\t' || *OldPtr == '\n')
1627 ++OldPtr;
1628 return OldPtr;
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 == '_')
1643 ++OldPtr;
1644 return OldPtr;
1647 static uint32 GetTypes(void)
1649 strptr ptr;
1650 size_t len;
1651 uint32 i;
1653 if(!(ptr = mygetfile(EXTTYPESFILE, &len)))
1655 #ifdef EXTTYPESFILEHIDDEN
1656 if((ptr = getenv("HOME")))
1658 strptr ptrh = EXTTYPESFILEHIDDEN;
1660 i = strlen(ptr);
1661 ptr = DupString(ptr, i + sizeof(EXTTYPESFILEHIDDEN) + 1);
1662 if(i && ptr[i-1] != '/')
1663 ptr[i++] = '/';
1664 while(*ptrh)
1665 ptr[i++] = *(ptrh++);
1666 ptr[i] = 0;
1667 ptr = mygetfile(ptr, &len);
1669 if(!ptr) /* disabled following if ptr != 0 */
1670 #endif
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);
1681 return 0;
1683 return 1;
1686 static strptr GetBaseType(void)
1688 static strptr basetype = 0;
1689 uint32 i;
1691 if(Flags2 & FLAG2_VOIDBASE)
1692 basetype = "void *";
1693 else if(!basetype)
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);
1706 if(!libtype)
1707 basetype = "struct Library *";
1710 return basetype;
1713 static strptr GetBaseTypeLib(void)
1715 uint32 i;
1717 if(libtype)
1718 return libtype;
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;
1727 return "Library";
1730 static strptr GetLibraryName(void)
1732 uint32 i;
1734 if(libname)
1735 return libname;
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)))
1745 return 0;
1747 /* auto create name */
1748 for(i = 0; ShortBaseName[i]; ++i)
1749 libname[i] = ShortBaseName[i];
1750 strcpy(libname+i,".library");
1751 return libname;
1754 static int32 MakeShortBaseName(void)
1756 strptr ptr, p2;
1757 uint32 i;
1759 ptr = p2 = args.infile;
1760 while(*p2)
1762 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
1763 ptr = p2+1;
1764 ++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) */
1777 if(BaseName)
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))))
1785 return 0;
1786 break;
1789 /* and last use default method */
1790 if(!ShortBaseName)
1791 ShortBaseName = DupString(BaseName, strlen(BaseName)-4);
1794 if(!ShortBaseName)
1795 return 0;
1797 ptr = ShortBaseName;
1798 while((*ptr = tolower(*ptr))) /* Convert to lowercase */
1799 ptr++;
1801 if((ShortBaseNameUpper = DupString(ShortBaseName, strlen(ShortBaseName))))
1803 ptr = ShortBaseNameUpper;
1804 while((*ptr = toupper(*ptr))) /* Convert to uppercase */
1805 ptr++;
1807 else
1808 return 0;
1810 return 1;
1813 static uint32 OpenDest(strptr name)
1815 static uint8 printedname = 0;
1816 strptr b, t;
1818 t = (strptr) tempbuf;
1819 if((b = args.to) && *b)
1821 while(*b)
1822 *(t++) = *(b++);
1823 if(*(t-1) != ':' && *(t-1) != '/')
1824 *(t++) = '/';
1826 *t = 0;
1828 if(!(Flags & FLAG_SINGLEFILE))
1829 printf("ResultFile: %s%s\n", tempbuf, name);
1830 else if(!printedname++)
1832 printf("ResultType: %s", tempbuf); printf(filenamefmt, "*");
1833 printf("\n");
1836 while(*name)
1837 *(t++) = *(name++);
1838 *t = 0;
1840 if(args.header)
1842 HEADER = mygetfile((strptr)tempbuf, &headersize);
1843 FindHeader();
1846 if((outfile = fopen((strptr)tempbuf, "wb")))
1847 return 1;
1848 DoError(ERR_OPEN_FILE, 0, tempbuf);
1849 return 0;
1852 static uint32 CloseDest(strptr name)
1854 if(outfile)
1856 fclose(outfile);
1857 outfile = 0;
1859 if(!(Flags & FLAG_DONE) || !Output_Error)
1861 strptr b, t;
1862 if(!Output_Error || !(Flags & FLAG_SINGLEFILE))
1863 DoError(ERR_EMPTY_FILE, 0);
1865 t = (strptr) tempbuf;
1866 if((b = args.to) && *b)
1868 while(*b)
1869 *(t++) = *(b++);
1870 if(*(t-1) != ':' && *(t-1) != '/')
1871 *(t++) = '/';
1873 while(*name)
1874 *(t++) = *(name++);
1875 *t = 0;
1877 remove((strptr)tempbuf);
1878 return 0;
1880 Flags &= ~FLAG_DONE; /* clear the flag */
1882 else
1883 return 0;
1884 return 1;
1887 static uint32 MakeTagFunction(struct AmiPragma *ap)
1889 size_t len = strlen(ap->FuncName);
1890 long i=0;
1892 #ifdef DEBUG_OLD
1893 printf("MakeTagFunction:\n");
1894 #endif
1896 if(!ap->NumArgs || ap->TagName)
1897 return 1;
1899 ++tagfuncs;
1900 ap->Flags |= AMIPRAGFLAG_OWNTAGFUNC;
1902 while(Pragma_ExecpNames[i].FunctionName && /* check the exception names */
1903 strcmp(ap->FuncName, Pragma_ExecpNames[i].FunctionName))
1904 ++i;
1906 if(Pragma_ExecpNames[i].FunctionName)
1908 if(!(ap->TagName = Pragma_ExecpNames[i].TagName))
1910 ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
1911 --tagfuncs;
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)))
1920 return 0;
1922 else if(!strcmp(ap->FuncName + len-7, "TagList"))
1924 if(!(ap->TagName = DupString(ap->FuncName, len-3)))
1925 return 0;
1926 ap->TagName[len-4] = 's';
1928 else if(!strcmp(ap->FuncName + len-4, "Args"))
1930 if(!(ap->TagName = DupString(ap->FuncName, len-4)))
1931 return 0;
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)))
1937 return 0;
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)))
1943 return 0;
1944 memcpy(ap->TagName + len, "Args", 5);
1946 else
1948 ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
1949 --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
1952 return 1;
1955 static void MakeLines(strptr buffer, uint32 size)
1957 if(size && buffer)
1959 /* make a real C++ zero string ending line */
1960 while(size--)
1962 if(*buffer == '\n')
1963 *buffer = '\0';
1964 ++buffer;
1966 *buffer = '\0';
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;
1985 uint32 i;
1987 RemoveItem(&AmiPragma, (struct ShortList *) ap); /* add in correct order */
1988 for(i = 0; i < 5; ++i)
1990 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
1991 return 0;
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);
2000 return 1;
2003 static void SortFDList(void)
2005 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.First, *ap2, *ap3;
2006 AmiPragma.First = AmiPragma.Last = 0;
2008 while(ap)
2010 ap3 = 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)
2016 ap3 = ap2;
2017 ap2 = (struct AmiPragma *) ap2->List.Next;
2020 ap2 = ap;
2021 ap = (struct AmiPragma *) ap->List.Next;
2023 if(ap3)
2025 ap2->List.Next = (struct ShortList *) ap3->List.Next;
2026 ap3->List.Next = (struct ShortList *) ap2;
2028 else
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)
2040 uint32 i;
2042 if(ap->NumAlias > NUMALIASNAMES)
2043 DoError(ERR_ALIASNAMES, linenum, NUMALIASNAMES);
2044 else
2046 /* prevent double names */
2047 for(i = 0; i < ap->NumAlias; ++i)
2049 if(!strcmp(ap->AliasName[i]->AliasName, alias->AliasName))
2050 return;
2052 ap->AliasName[ap->NumAlias++] = alias;
2056 static uint32 CheckNames(struct AmiPragma *ap)
2058 uint32 i, j;
2059 const strptr *k;
2061 #ifdef DEBUG_OLD
2062 printf("CheckNames\n");
2063 #endif
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]))))
2069 return 0;
2070 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2072 else
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]))))
2080 return 0;
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]))))
2090 return 0;
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 */
2098 return 1;
2101 static uint32 ScanSFDFile(uint32 abi)
2103 uint32 _public = 1;
2104 int32 bias = -1;
2105 uint32 linenum;
2106 uint32 actcom = 0;
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)
2116 if(*in.pos == '*')
2118 if(actcom)
2119 *(in.pos-1) = '\n';
2120 else
2122 struct Comment *d;
2123 if(!(d = (struct Comment *) NewItem(&Comment)))
2124 return 0;
2125 d->Bias = bias;
2126 d->Data = in.pos;
2127 d->ReservedNum = 0;
2128 d->Version = 0;
2129 d->Private = _public ? 0 : 1;
2130 AddItem(&Comment, (struct ShortList *) d);
2131 actcom = 1;
2133 while(*in.pos)
2134 ++in.pos;
2136 else if(*in.pos == '=' && in.pos[1] == '=')
2138 in.pos += 2;
2139 actcom = 0; /* no Comment */
2141 if(!strnicmp(in.pos, "basetype", 8))
2143 #ifdef DEBUG_OLD
2144 printf("ScanSFDFile: found ==basetype\n");
2145 #endif
2146 if(!(Flags2 & FLAG2_LIBTYPE))
2148 if(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);
2154 else
2156 in.pos = SkipBlanks(in.pos+6);
2157 if(!*in.pos)
2158 DoError(ERR_EXPECTED_LIBTYPE, linenum);
2159 else
2161 libtype = in.pos;
2162 in.pos = SkipName(libtype);
2163 if(*SkipBlanks(in.pos) != '*')
2164 DoError(ERR_EXPECTED_POINTERSIGN, linenum);
2165 if(*in.pos)
2166 *(in.pos++) = 0;
2170 else
2171 DoError(ERR_COMMANDLINE_LIBTYPE, linenum);
2172 while(*in.pos)
2173 ++in.pos;
2175 else if(!strnicmp(in.pos, "copyright", 9))
2177 Copyright = SkipBlanks(in.pos+9);
2178 while(*in.pos)
2179 ++in.pos;
2181 else if(!strnicmp(in.pos, "libname", 7))
2183 #ifdef DEBUG_OLD
2184 printf("ScanSFDFile: found ==libname\n");
2185 #endif
2186 if(!(Flags2 & FLAG2_LIBNAME))
2188 if(libname)
2189 DoError(ERR_LIBNAME_DECLARED_TWICE, linenum);
2191 in.pos = SkipBlanks(in.pos+7);
2192 if(!*in.pos)
2193 DoError(ERR_EXPECTED_LIBNAME, linenum);
2194 else
2195 in.pos = SkipName(libname = in.pos);
2197 else
2198 DoError(ERR_COMMANDLINE_LIBNAME, linenum);
2199 while(*in.pos)
2200 ++in.pos;
2202 else if(!strnicmp(in.pos, "base", 4))
2204 strptr oldptr;
2206 #ifdef DEBUG_OLD
2207 printf("ScanSFDFile: found ==base\n");
2208 #endif
2209 if(!(Flags & FLAG_BASENAME))
2211 if(BaseName)
2212 DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
2214 in.pos = SkipBlanks(in.pos+4);
2215 if(*in.pos != '_')
2216 DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
2217 else
2218 ++in.pos;
2220 BaseName = oldptr = in.pos;
2221 in.pos = SkipName(in.pos);
2222 if(!(in.pos-oldptr))
2223 DoError(ERR_EXPECTED_BASENAME, linenum);
2225 else
2227 DoError(ERR_COMMANDLINE_BASENAME, linenum);
2228 while(*in.pos)
2229 ++in.pos;
2232 else if(!strnicmp(in.pos, "bias", 4))
2234 strptr ptr;
2235 int32 newbias;
2237 #ifdef DEBUG_OLD
2238 printf("ScanSFDFile: found ==bias\n");
2239 #endif
2240 in.pos += 5;
2241 newbias = strtol(in.pos, &ptr, 10);
2242 if(ptr == in.pos)
2243 DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
2244 else if(newbias < 0)
2246 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
2247 bias = -newbias;
2249 else
2250 bias = newbias;
2251 in.pos = SkipName(in.pos);
2253 else if(!strnicmp(in.pos, "end", 3))
2255 bias = 0; break;
2257 else if(!strnicmp(in.pos, "public", 6))
2259 in.pos += 6;
2260 _public = 1;
2262 else if(!strnicmp(in.pos, "private", 7))
2264 in.pos += 7;
2265 _public = 0;
2267 else if(!strnicmp(in.pos, "abi", 3))
2269 #ifdef DEBUG_OLD
2270 printf("ScanSFDFile: found ==abi\n");
2271 #endif
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;
2289 else
2290 DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
2292 else if(!strnicmp(in.pos, "id", 2))
2294 if(IDstring)
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);
2301 while(*in.pos)
2302 ++in.pos;
2303 if(*(in.pos-1) != '$')
2304 DoError(ERR_EXPECTED_ID_ENDSIGN, linenum);
2306 else if(!strnicmp(in.pos, "include", 7))
2308 struct Include *d;
2310 if(!(d = (struct Include *) NewItem(&Includes)))
2311 return 0;
2312 d->Include = SkipBlanks(in.pos+7);
2313 AddItem(&Includes, (struct ShortList *) d);
2314 while(*in.pos)
2315 ++in.pos;
2317 else if(!strnicmp(in.pos, "varargs", 7))
2319 if(bias == -1)
2320 DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
2321 else
2323 if(!functype)
2324 bias -= BIAS_OFFSET;
2325 functype |= FUNCFLAG_TAG;
2327 in.pos += 7;
2329 else if(!strnicmp(in.pos, "alias", 5))
2331 if(bias == -1)
2332 DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
2333 else
2335 if(!functype)
2336 bias -= BIAS_OFFSET;
2337 functype |= FUNCFLAG_ALIAS;
2339 in.pos += 5;
2341 else if(!strnicmp(in.pos, "version", 7))
2343 /* store version entries as comments */
2344 struct Comment *d;
2345 strptr ptr;
2346 int16 v;
2348 in.pos = SkipBlanks(in.pos+7);
2349 v = strtol(in.pos, &ptr, 10);
2350 #ifdef DEBUG_OLD
2351 printf("ScanSFDFile: found ==version %d\n", v);
2352 #endif
2353 if(ptr == in.pos || v < 0)
2354 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
2355 else
2357 if(!(d = (struct Comment *) NewItem(&Comment)))
2358 return 0;
2359 d->Bias = bias;
2360 d->Data = 0;
2361 d->ReservedNum = 0;
2362 d->Version = v;
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 */
2371 struct Comment *d;
2372 strptr ptr;
2373 int16 v;
2375 in.pos = SkipBlanks(in.pos+7);
2376 v = strtol(in.pos, &ptr, 10);
2377 #ifdef DEBUG_OLD
2378 printf("ScanSFDFile: found ==reserve %d\n", v);
2379 #endif
2380 if(bias == -1)
2382 DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
2383 bias = BIAS_START;
2386 if(ptr == in.pos || v < 0)
2387 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
2388 else
2390 if(!(d = (struct Comment *) NewItem(&Comment)))
2391 return 0;
2392 d->Bias = bias;
2393 d->Data = 0;
2394 d->ReservedNum = v;
2395 d->Version = 0;
2396 d->Private = _public ? 0 : 1;
2397 AddItem(&Comment, (struct ShortList *) d);
2398 in.pos = SkipName(in.pos);
2399 bias += BIAS_OFFSET*v;
2402 else
2403 DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
2405 else /* function */
2407 uint32 ft, startlinenum;
2408 struct AmiPragma ap, *ap2;
2409 struct ClibData d, *f;
2410 strptr oldptr;
2411 uint32 maxreg;
2412 strptr data;
2414 actcom = 0;
2415 maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
2416 /* join lines, if necessary */
2417 startlinenum = linenum;
2418 data = in.pos;
2419 while(*data != '('/*)*/ && data < in.buf + in.size) /* first open bracket */
2420 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2421 ++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 */
2425 if(!*data)
2427 *data = ' ';
2428 ++linenum;
2430 else if(*data == '('/*)*/)
2431 ++ft;
2432 else if(*data == /*(*/')')
2433 --ft;
2434 ++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)
2442 in.pos = data;
2443 DoError(ERR_UNEXPECTED_FILEEND, linenum);
2444 continue;
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);
2453 while(*(in.pos++))
2455 continue;
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);
2467 ++in.pos;
2468 continue;
2470 *(SkipName(d.FuncName)) = 0;
2471 in.pos = SkipBlanks(++in.pos);
2473 oldptr = 0;
2474 while(*in.pos && *in.pos != /*(*/')')
2476 oldptr = (strptr) 1;
2477 if(d.NumArgs >= maxreg)
2479 DoError(ERR_TO_MUCH_ARGUMENTS, startlinenum);
2480 return 0;
2482 else if(!GetCPPType(&d.Args[d.NumArgs++], in.pos, 0, 0))
2484 DoError(ERR_UNKNOWN_VARIABLE_TYPE, startlinenum, d.NumArgs);
2485 break;
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;
2497 if(!oldptr)
2499 DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
2500 break;
2502 else if(!(oldptr = DupString(oldptr, SkipName(oldptr)-oldptr)))
2503 return 0;
2504 ap.Args[ap.CallArgs++].ArgName = oldptr;
2506 else
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);
2514 break;
2518 else
2519 ++ap.CallArgs;
2521 in.pos = SkipBlanks(in.pos);
2522 if(*in.pos != ',' && *in.pos != /*(*/')')
2524 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2525 break;
2527 if(*in.pos == ')')
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;
2532 #ifdef DEBUG_OLD
2533 printf("Added last argument %ld (%s) for %s (%ld bytes)\n", d.NumArgs, oldptr, d.FuncName,
2534 d.Args[d.NumArgs-1].FullLength);
2535 #endif
2536 oldptr = 0;
2537 break;
2539 else
2541 in.pos = SkipBlanks(++in.pos);
2542 *(SkipName(oldptr)) = 0;
2543 #ifdef DEBUG_OLD
2544 printf("Added argument %ld (%s) for %s (%ld bytes)\n", d.NumArgs, oldptr, d.FuncName,
2545 d.Args[d.NumArgs-1].FullLength);
2546 #endif
2549 if(*in.pos == /*(*/')')
2550 ++in.pos;
2551 if(!oldptr) /* oldptr == 0 means parsing was valid */
2553 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
2554 return -1;
2556 memcpy(f, &d, sizeof(struct ClibData));
2558 if(!clibdata)
2559 clibdata = f;
2560 else
2562 struct ClibData *e = clibdata;
2563 while(e->Next)
2564 e = e->Next;
2565 e->Next = f;
2568 #ifdef DEBUG_OLD
2569 printf("Added prototype for %s (line %ld) with %ld args\n", f->FuncName, startlinenum, f->NumArgs);
2570 #endif
2571 if(*(in.pos = SkipBlanks(in.pos)) != '('/*)*/)
2573 DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
2574 ++in.pos;
2575 continue;
2578 if(bias == -1)
2580 DoError(ERR_ASSUMING_BIAS_OF_30, startlinenum);
2581 bias = BIAS_START;
2584 ap.Bias = bias;
2585 ap.Abi = abi;
2586 ap.Line = startlinenum;
2587 bias += BIAS_OFFSET;
2589 if(_public)
2590 ap.Flags |= AMIPRAGFLAG_PUBLIC;
2592 if(abi != ABI_M68K)
2594 while(*in.pos && *in.pos != /*(*/')')
2595 ++in.pos;
2596 if(*in.pos != /*(*/')')
2598 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2599 ++in.pos;
2600 continue;
2602 ++in.pos;
2603 ap.NumArgs = ap.CallArgs;
2605 ap.Flags |= AMIPRAGFLAG_PPC;
2606 if(abi == ABI_PPC0)
2607 ap.Flags |= AMIPRAGFLAG_PPC0;
2608 else if(abi == ABI_PPC2)
2609 ap.Flags |= AMIPRAGFLAG_PPC2;
2611 else
2613 uint32 len;
2617 uint32 i;
2619 oldptr = in.pos = SkipBlanks(in.pos+1);
2621 if(*in.pos == /*(*/')' && !ap.NumArgs)
2622 break;
2624 in.pos = SkipName(oldptr);
2625 len = in.pos-oldptr;
2627 for(i = 0; i < MAXREG; ++i)
2628 if(!strnicmp(RegNames[i], oldptr, len))
2629 break;
2631 if(i == MAXREG)
2633 DoError(ERR_EXPECTED_REGISTER_NAME, startlinenum);
2634 break;
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);
2647 break;
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);
2659 break;
2662 if(i < ap.NumArgs)
2663 break;
2665 ++ap.NumArgs;
2667 in.pos = SkipBlanks(in.pos);
2668 if(*in.pos != ',' && *in.pos != '-' && *in.pos != '/' && *in.pos != /*(*/')')
2670 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2671 break;
2673 } while(*in.pos != /*(*/')');
2675 if(*in.pos != /*(*/')')
2677 while(*(in.pos++))
2678 ++in.pos;
2679 continue;
2681 else
2682 ++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);
2700 else
2701 return 0;
2703 else
2705 ap2->TagName = ap.FuncName;
2706 ++tagfuncs;
2708 if(ap.CallArgs != ap2->CallArgs)
2710 if(ap2->CallArgs + 1 == ap.CallArgs && d.Args[d.NumArgs-1].Type == CPP_TYPE_VARARGS)
2712 --ap.CallArgs;
2713 if(abi != ABI_M68K)
2714 --ap.NumArgs;
2717 if(ap.NumArgs != ap2->NumArgs)
2719 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
2721 else if(abi == ABI_M68K)
2723 uint32 i;
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);
2730 break;
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)
2740 --ap.CallArgs;
2741 else
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)))
2754 return 0;
2755 memcpy(d, &ap, sizeof(struct AmiPragma));
2756 if(!CheckNames(d))
2757 return 0;
2758 AddItem(&AmiPragma, (struct ShortList *) d);
2761 else
2763 if(!(Flags & FLAG_NOPPC))
2765 struct AmiPragma *d;
2766 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
2767 return 0;
2768 memcpy(d, &ap, sizeof(struct AmiPragma));
2769 if(!CheckNames(d))
2770 return 0;
2771 AddItem(&AmiPragma, (struct ShortList *) d);
2777 in.pos = SkipBlanks(in.pos);
2778 if(*in.pos)
2779 DoError(ERR_EXTRA_CHARACTERS, linenum);
2780 ++in.pos; /* skip '\0' */
2783 if(bias)
2784 DoError(ERR_MISSING_SFDEND, 0);
2786 return 1;
2789 static uint32 ScanFDFile(void)
2791 uint32 _public = 1;
2792 int32 bias = -1;
2793 uint32 linenum;
2794 size_t len;
2795 uint32 actcom = 0;
2796 uint32 shadowmode = 0;
2797 uint32 abi = ABI_M68K;
2799 if(defabi)
2801 if(!stricmp(defabi, "M68k"))
2802 abi = ABI_M68K;
2803 else if(!stricmp(defabi, "PPC0"))
2804 abi = ABI_PPC0;
2805 else if(!stricmp(defabi, "PPC2"))
2806 abi = ABI_PPC2;
2807 else if(!stricmp(defabi, "PPC"))
2808 abi = ABI_PPC;
2809 else
2810 DoError(ERR_UNKNOWN_ABI, 0, defabi);
2813 if(in.size > 10 && in.pos[0] == '=' && in.pos[1] == '=')
2814 return ScanSFDFile(abi);
2816 #ifdef DEBUG_OLD
2817 printf("ScanFDFile:\n");
2818 #endif
2820 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
2822 if(*in.pos == '*') /* Comment */
2824 strptr oldpos = in.pos;
2825 #ifdef DEBUG_OLD
2826 printf("ScanFDFile: found a comment\n");
2827 #endif
2828 in.pos = SkipBlanks(in.pos+1);
2829 if(!strnicmp(in.pos, "notagcall", 9))
2831 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last;
2833 if(ap->TagName)
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);
2845 if(!prevpragma)
2847 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
2848 ++in.pos;
2849 continue;
2852 if(!prevpragma->NumArgs)
2854 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
2855 ++in.pos;
2856 continue;
2859 /* Get the tag functions name. */
2861 if(!prevpragma->TagName && (_public || (Flags & FLAG_PRIVATE)))
2862 ++tagfuncs;
2864 if(*in.pos)
2866 strptr oldptr, tptr = prevpragma->TagName;
2868 len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
2869 if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len)))
2870 return 0;
2872 if(*in.pos == '-')
2874 strptr removeptr;
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))
2883 #ifdef DEBUG_OLD
2884 printf("ScanFDFile: *tagcall -: %s, %s, %ld\n", removeptr, oldptr, len);
2885 #endif
2886 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
2887 prevpragma->TagName = tptr;
2888 ++in.pos;
2889 continue;
2892 *removeptr = '\0';
2894 in.pos = SkipBlanks(in.pos);
2896 if(*in.pos == '+')
2897 in.pos = SkipBlanks(in.pos+1);
2898 else
2899 *in.pos = toupper(*in.pos);
2901 in.pos = SkipName((oldptr = in.pos));
2902 len = in.pos-oldptr;
2903 if(len)
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)))
2914 return 0;
2915 memcpy(prevpragma->TagName + len, "Tags", 5);
2918 else
2920 if(actcom)
2921 *(oldpos-1) = '\n';
2922 else
2924 struct Comment *d;
2925 if(!(d = (struct Comment *) NewItem(&Comment)))
2926 return 0;
2927 d->Bias = bias;
2928 d->Data = oldpos;
2929 d->ReservedNum = 0;
2930 d->Version = 0;
2931 d->Private = _public ? 0 : 1;
2932 AddItem(&Comment, (struct ShortList *) d);
2933 actcom = 1;
2935 while(*in.pos)
2936 ++in.pos;
2939 else if(*in.pos == '#' && in.pos[1] == '#')
2941 in.pos += 2;
2942 actcom = 0; /* no Comment */
2944 if(!strnicmp(in.pos, "base", 4))
2946 strptr oldptr;
2948 #ifdef DEBUG_OLD
2949 printf("ScanFDFile: found ##base\n");
2950 #endif
2951 if(!(Flags & FLAG_BASENAME))
2953 if(BaseName)
2954 DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
2956 in.pos = SkipBlanks(in.pos+4);
2957 if(*in.pos != '_')
2958 DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
2959 else
2960 ++in.pos;
2962 BaseName = oldptr = in.pos;
2963 in.pos = SkipName(in.pos);
2964 if(!(in.pos-oldptr))
2965 DoError(ERR_EXPECTED_BASENAME, linenum);
2967 else
2969 DoError(ERR_COMMANDLINE_BASENAME, linenum);
2970 while(*in.pos)
2971 ++in.pos;
2974 else if(!strnicmp(in.pos, "bias", 4))
2976 strptr ptr;
2977 int32 newbias;
2979 #ifdef DEBUG_OLD
2980 printf("ScanFDFile: found ##bias\n");
2981 #endif
2982 in.pos += 5;
2983 newbias = strtol(in.pos, &ptr, 10);
2984 if(ptr == in.pos)
2985 DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
2986 else if(newbias < 0)
2988 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
2989 bias = -newbias;
2991 else
2992 bias = newbias;
2993 in.pos = SkipName(in.pos);
2995 else if(!strnicmp(in.pos, "end", 3))
2997 bias = 0; break;
2999 else if(!strnicmp(in.pos, "shadow", 6)) /* introduced by Storm */
3001 in.pos += 6;
3002 if(bias == -1 || !AmiPragma.First)
3003 DoError(ERR_EARLY_SHADOW, linenum);
3004 else
3006 bias -= BIAS_OFFSET;
3007 shadowmode = 1;
3010 else if(!strnicmp(in.pos, "public", 6))
3012 in.pos += 6;
3013 _public = 1;
3015 else if(!strnicmp(in.pos, "private", 7))
3017 in.pos += 7;
3018 _public = 0;
3020 else if(!strnicmp(in.pos, "abi", 3))
3022 #ifdef DEBUG_OLD
3023 printf("ScanFDFile: found ##abi\n");
3024 #endif
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;
3042 else
3043 DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
3045 else
3046 DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
3048 else
3050 strptr oldptr;
3051 uint32 maxreg;
3052 struct AmiPragma ap, *ap2;
3054 #ifdef DEBUG_OLD
3055 printf("ScanFDFile: scan Function\n");
3056 #endif
3057 memset(&ap, 0, sizeof(struct AmiPragma));
3058 actcom = 0;
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);
3065 ++in.pos;
3066 continue;
3069 ap.FuncName = oldptr;
3071 in.pos = SkipBlanks(in.pos);
3072 if(*in.pos != '('/*)*/)
3074 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3075 ++in.pos;
3076 continue;
3079 oldptr[len] = '\0'; /* create c string of FunctionName */
3081 #ifdef DEBUG_OLD
3082 printf("ScanFDFile: found function %s\n", ap.FuncName);
3083 #endif
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)
3097 break;
3099 if(ap.CallArgs >= maxreg)
3101 DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
3104 in.pos = SkipName(oldptr);
3105 if(*in.pos == '*')
3106 ++in.pos;
3107 if(!(len = in.pos-oldptr))
3109 DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
3110 ap.Args[ap.CallArgs++].ArgName = 0;
3112 else
3114 ap.Args[ap.CallArgs++].ArgName = oldptr;
3115 oldptr = in.pos;
3116 in.pos = SkipBlanks(in.pos);
3118 if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
3120 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3121 break;
3123 if(*in.pos != /*(*/')') /* create c string ending */
3124 *oldptr = '\0';
3125 } while(*in.pos != /*(*/')');
3127 if(*in.pos != /*(*/')')
3129 while(*(in.pos++))
3130 ++in.pos;
3131 continue;
3133 else
3134 *oldptr = '\0'; /* create c string ending for last argument */
3136 if(bias == -1)
3138 DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
3139 bias = BIAS_START;
3142 ap.Bias = bias;
3143 ap.Abi = abi;
3144 ap.Line = linenum;
3145 bias += BIAS_OFFSET;
3147 if(_public)
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);
3158 ++in.pos;
3159 continue;
3162 if(abi == ABI_M68K)
3166 uint32 i;
3168 oldptr = in.pos = SkipBlanks(in.pos + 1);
3170 if(*in.pos == /*(*/')' && !ap.NumArgs)
3171 break;
3173 in.pos = SkipName(oldptr);
3174 len = in.pos-oldptr;
3176 for(i = 0; i < MAXREG; ++i)
3177 if(!strnicmp(RegNames[i], oldptr, len))
3178 break;
3180 if(i == MAXREG)
3182 DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
3183 break;
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);
3196 break;
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);
3208 break;
3211 if(i < ap.NumArgs)
3212 break;
3214 ++ap.NumArgs;
3216 in.pos = SkipBlanks(in.pos);
3217 if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
3219 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3220 break;
3222 } while(*in.pos != /*(*/')');
3224 if(*in.pos != /*(*/')')
3226 while(*(in.pos++))
3227 ++in.pos;
3228 continue;
3230 else
3231 ++in.pos;
3233 else
3235 while(*in.pos && *in.pos != /*(*/')')
3236 ++in.pos;
3237 if(*in.pos != /*(*/')')
3239 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3240 ++in.pos;
3241 continue;
3243 ++in.pos;
3244 ap.NumArgs = ap.CallArgs;
3246 ap.Flags |= AMIPRAGFLAG_PPC;
3247 if(abi == ABI_PPC0)
3248 ap.Flags |= AMIPRAGFLAG_PPC0;
3249 else if(abi == ABI_PPC2)
3250 ap.Flags |= AMIPRAGFLAG_PPC2;
3253 else
3254 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3256 ap2 = (struct AmiPragma *)(AmiPragma.Last);
3257 if(shadowmode)
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);
3271 else
3272 return 0;
3273 #ifdef DEBUG_OLD
3274 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2->TagName);
3275 #endif
3277 else
3279 #ifdef DEBUG_OLD
3280 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2->TagName);
3281 #endif
3282 ap2->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
3283 ap2->TagName = ap.FuncName;
3284 ++tagfuncs;
3286 if(ap.NumArgs != ap2->NumArgs)
3287 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3288 else if(abi == ABI_M68K)
3290 uint32 i;
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);
3297 break;
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);
3313 if(abi == ABI_M68K)
3315 uint32 i;
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);
3322 break;
3327 else
3329 if((_public || (Flags & FLAG_PRIVATE)) && !MakeTagFunction(&ap))
3330 return 0;
3331 else /* check the alias names */
3333 uint32 i = 0;
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);
3342 ++i;
3346 if(abi == ABI_M68K)
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)))
3360 return 0;
3361 memcpy(d, &ap, sizeof(struct AmiPragma));
3362 if(!CheckNames(d))
3363 return 0;
3364 AddItem(&AmiPragma, (struct ShortList *) d);
3365 if(!SpecialFuncs())
3366 return 0;
3369 else
3371 if(!(Flags & FLAG_NOPPC))
3373 struct AmiPragma *d;
3374 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3375 return 0;
3376 memcpy(d, &ap, sizeof(struct AmiPragma));
3377 if(!CheckNames(d))
3378 return 0;
3379 AddItem(&AmiPragma, (struct ShortList *) d);
3381 if(!SpecialFuncs())
3382 return 0;
3387 shadowmode = 0;
3390 in.pos = SkipBlanks(in.pos);
3391 if(*in.pos)
3392 DoError(ERR_EXTRA_CHARACTERS, linenum);
3393 ++in.pos; /* skip '\0' */
3396 if(bias)
3397 DoError(ERR_MISSING_END, 0);
3399 return 1;
3402 static int32 ScanTypes(strptr ptr, uint32 size)
3404 struct CPP_ExternNames *a = 0, *b = 0;
3405 strptr endptr = ptr+size;
3406 int32 line;
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))))
3420 strptr wptr;
3422 n->Type = ptr; /* store start */
3424 while(ptr < endptr && *ptr != ':' && *ptr != '\n' && *ptr != '\t' && *ptr != ' ')
3425 ++ptr;
3426 wptr = SkipBlanks(ptr);
3427 if(*(wptr++) != ':')
3428 return line;
3429 *ptr = 0;
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))
3435 return line;
3436 #ifdef DEBUG_OLD
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>");
3441 #endif
3442 ptr = SkipBlanks(n->NameType.TypeStart+n->NameType.FullLength);
3443 if(*(ptr++) != '\n')
3445 #ifdef DEBUG_OLD
3446 printf("%.30s\n", ptr);
3447 #endif
3448 return line;
3451 if(!a)
3452 b = n;
3453 else
3454 a->Next = n;
3455 a = n;
3457 else
3458 return -1;
3460 extnames = b; /* now store the list */
3461 return 0;
3464 static void FindHeader(void)
3466 strptr str = HEADER;
3467 uint32 mode = 0;
3471 if(!mode)
3472 HEADER = str;
3474 if(*str == '/')
3476 ++str;
3477 if(*str == '*')
3479 mode = 2; break;
3481 else if(*str == '/')
3482 mode = 1;
3484 else if(*str == '*' || *str == ';')
3485 mode = 1;
3486 else if(*str == '{'/*}*/)
3488 mode = 3; break;
3490 else if(*str == '('/*)*/ && *(++str) == '*')
3492 mode = 4; break;
3494 else if(mode)
3495 break;
3496 while(*str && *(str++) != '\n')
3498 } while(*str);
3500 if(mode == 2)
3502 while(*str && (*(str-1) != '*' || *str != '/'))
3503 ++str;
3504 while(*str && *(str++) != '\n')
3507 else if(mode == 3)
3509 while(*str && *str != /*{*/'}')
3510 ++str;
3511 while(*str && *(str++) != '\n')
3514 else if(mode == 4)
3516 while(*str && (*(str-1) != '*' || *str != /*(*/')'))
3517 ++str;
3518 while(*str && *(str++) != '\n')
3522 if(mode)
3523 headersize = str-HEADER;
3524 else
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)
3533 /* usage of result:
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 */
3548 data |= 0x40000002;
3549 return data;
3552 static uint16 GetFRegisterData(struct AmiPragma *ap)
3554 /* usage of result:
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)
3565 reg -= REG_FP0;
3566 data |= (1 << (reg + 8)) + (1 << (7 - reg));
3569 return data;
3572 static uint32 OutputXDEF(uint32 offset, strptr format, ...)
3574 uint8 buf[150];
3575 va_list a;
3576 size_t i;
3578 va_start(a, format);
3579 i = vsprintf((strptr)(buf+4), format, a);
3580 va_end(a);
3581 while(i&3)
3582 buf[4+i++] = 0;
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, ...)
3592 uint8 buf[150];
3593 va_list a;
3594 size_t i;
3596 va_start(a, format);
3597 i = vsprintf((strptr)(buf+4), format, a);
3598 va_end(a);
3599 while(i&3)
3600 buf[4+i++] = 0;
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, ...)
3611 uint8 buf[150];
3612 va_list a;
3613 size_t i;
3615 va_start(a, format);
3616 i = vsprintf((strptr)(buf+4), format, a);
3617 va_end(a);
3618 while(i&3)
3619 buf[4+i++] = 0;
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, ...)
3631 va_list a;
3632 uint8 buf[150];
3633 size_t i;
3635 va_start(a, format);
3636 i = vsprintf((strptr)(buf+4), format, a);
3637 va_end(a);
3638 while(i&3)
3639 buf[4+i++] = 0;
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)
3653 k = ap->NumArgs;
3655 while(k)
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 */
3668 ofs += 2;
3670 else
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))
3681 l = 0; tofs = ofs;
3684 j = ap->Args[--k].ArgReg;
3686 ++ofs;
3687 l |= 1 << j;
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 */
3693 else
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);
3706 else
3708 i = 0;
3710 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
3712 while(i < k)
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 */
3725 ofs += 2;
3727 else
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))
3738 l = 0; tofs = ofs;
3741 j = ap->Args[i++].ArgReg;
3743 ++ofs;
3744 l |= 1 << j;
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 */
3750 else
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);
3763 if(i < ap->NumArgs)
3765 if((j = ap->Args[i].ArgReg) > 7)
3767 EndPutM16Inc(data, 0x41EF | ((j-8) << 9)); /* LEA xxx(A7),Ax */
3768 EndPutM16Inc(data, ofs << 2);
3770 else if(ofs == 2)
3772 EndPutM16Inc(data, 0x200F | (j << 9)); /* MOVE.L A7,Dx */
3773 EndPutM16Inc(data, 0x5080 | j); /* ADDQ.L #8,Dx */
3775 else
3777 EndPutM16Inc(data, 0x486F); /* PEA xxx(A7) */
3778 EndPutM16Inc(data, ofs << 2);
3779 EndPutM16Inc(data, 0x201F | j << 9); /* MOVE.L offs(A7),Dx */
3784 return data;
3786 /* ------------------------------------------------------------------ */
3788 static void DoError(uint32 errnum, uint32 line, ...)
3790 uint32 err = errnum & 0xFFFF;
3791 va_list a;
3793 if(Flags & FLAG_DIDERROR)
3794 return;
3796 if(!Errors[err].Type)
3797 Flags |= FLAG_DIDERROR;
3799 va_start(a, line);
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);
3804 printf("\n");
3805 if(line && Errors[err].Skip)
3807 while(*in.pos)
3808 ++in.pos;
3810 va_end(a);
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;
3824 return 1;
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;
3833 return 1;
3835 else if(errflags & AMIPRAGFLAG_A6USE)
3837 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
3838 return 1;
3840 else if(errflags & AMIPRAGFLAG_A5USE)
3842 DoError(ERR_A5_NOT_ALLOWED, ap->Line);
3843 return 1;
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;
3852 return 1;
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;
3861 return 1;
3864 return 0;
3867 static uint32 DoOutput(strptr format, ...)
3869 va_list a;
3871 if(!Output_Error)
3872 return 0;
3874 va_start(a, format);
3875 if(vfprintf(outfile, format, a) < 0)
3876 Output_Error = 1;
3877 va_end(a);
3879 return Output_Error;
3882 static uint32 DoOutputDirect(void * data, size_t size)
3884 if(!Output_Error)
3885 return 0;
3886 if(size)
3888 if(fwrite(data, size, 1, outfile) != 1)
3889 Output_Error = 0;
3891 return Output_Error;
3894 /* ------------------------------------------------------------------ */
3896 static struct ShortList *NewItem(struct ShortListRoot *list)
3898 struct ShortList *item;
3899 if(!list || !list->Size)
3900 return 0;
3901 if(!(item = (struct ShortList *) AllocListMem(list->Size)))
3902 return 0;
3903 return item;
3906 static struct ShortList *RemoveItem(struct ShortListRoot *list,
3907 struct ShortList *item)
3909 struct ShortList *n = list->First;
3911 if(n == item)
3912 list->First = item->Next;
3913 else
3915 while(n && n->Next != item)
3916 n = n->Next;
3917 if(!n)
3918 return 0;
3919 if(!(n->Next = item->Next))
3920 list->Last = n;
3922 item->Next = 0;
3923 return item;
3926 static void AddItem(struct ShortListRoot *list, struct ShortList *item)
3928 if(!list->First)
3929 list->First = list->Last = item;
3930 else
3932 list->Last->Next = item;
3933 list->Last = item;
3937 /* ------------------------------------------------------------------ */
3939 uint32 FuncAMICALL(struct AmiPragma *ap, uint32 flags, strptr name)
3941 uint32 i;
3943 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
3944 return 1;
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)
3955 DoOutput(",");
3958 return DoOutput(/*((*/"))\n");
3961 uint32 FuncLIBCALL(struct AmiPragma *ap, uint32 flags, strptr name)
3963 int32 i;
3965 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
3966 return 1;
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);
3982 else
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)
3994 int32 i;
3995 uint32 registers;
3996 uint16 fregs;
3997 uint32 offset = 1;
3998 strptr c1, c2;
3999 struct ClibData *cd;
4001 if(CheckError(ap, AMIPRAGFLAG_PPC))
4002 return 1;
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);
4013 if(HEADER)
4015 DoOutput("\n");
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);
4030 if(clibdata)
4032 if(!ap->NumArgs)
4033 DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
4034 else if((cd = GetClibFunc(name, ap, flags)))
4036 string txt[300];
4037 uint32 i;
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))
4056 ++offset;
4057 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper[i]);
4061 else
4063 uint16 l = registers;
4065 DoOutput("\tMOVEM.L\t");
4067 for(i = 0; i <= 15; ++i)
4069 if(l & (1 << i))
4071 ++offset;
4072 l ^= 1 << i;
4073 DoOutput(RegNamesUpper[i]);
4074 if(l)
4075 DoOutput("/");
4078 DoOutput(",-(A7)\n");
4081 else
4083 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
4086 if((fregs = GetFRegisterData(ap) >> 8))
4088 uint8 l = fregs;
4090 DoOutput("\tFMOVEM.X\t");
4092 for(i = 0; i <= 7; ++i)
4094 if(l & (1 << i))
4096 offset += 3;
4097 l ^= 1 << i;
4098 DoOutput(RegNamesUpper[REG_FP0 + i]);
4099 if(l)
4100 DoOutput("/");
4103 DoOutput(",-(A7)\n");
4106 if(Flags & FLAG_SMALLDATA)
4108 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1, BaseName, c2);
4110 else
4111 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName);
4113 if(!(Flags & FLAG_PASCAL))
4115 int32 k;
4117 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
4119 for(i = 0; i < k;)
4121 if(ap->Args[i].ArgReg >= REG_FP0)
4123 uint32 t;
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))
4130 t = CPP_TYPE_FLOAT;
4131 else
4133 DoError(ERR_LONG_DOUBLE, ap->Line);
4134 t = CPP_TYPE_FLOAT;
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)
4141 ++offset;
4142 ++offset;
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]);
4153 ++offset;
4154 } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg) &&
4155 ap->Args[i].ArgReg < REG_FP0);
4156 DoOutput("\n");
4158 else
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]);
4163 ++i;
4167 if(i < ap->NumArgs)
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]);
4176 else
4177 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1,
4178 offset<<2, c2,RegNamesUpper[ap->Args[i].ArgReg]);
4181 else
4183 i = ap->NumArgs;
4185 while(i)
4187 if(ap->Args[i-1].ArgReg >= REG_FP0)
4189 uint32 t;
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))
4197 t = CPP_TYPE_FLOAT;
4198 else
4200 DoError(ERR_LONG_DOUBLE, ap->Line);
4201 t = CPP_TYPE_FLOAT;
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)
4207 ++offset;
4208 ++offset;
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]);
4219 ++offset;
4220 } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg) &&
4221 ap->Args[i-1].ArgReg < REG_FP0);
4222 DoOutput("\n");
4224 else
4226 --i;
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);
4236 if(fregs)
4238 DoOutput("\tFMOVEM.X\t(A7)+,");
4240 for(i = 0; i <= 7; ++i)
4242 if(fregs & (1 << i))
4244 fregs ^= 1 << i;
4245 DoOutput(RegNamesUpper[REG_FP0 + i]);
4246 if(fregs)
4247 DoOutput("/");
4250 DoOutput("\n");
4253 if(registers)
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]);
4263 else
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]);
4273 if(registers)
4274 DoOutput("/");
4277 DoOutput("\n");
4280 else
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;
4289 size_t i;
4290 uint8 *data;
4291 uint16 fregs;
4293 if(CheckError(ap, AMIPRAGFLAG_PPC))
4294 return 1;
4296 Flags |= FLAG_DONE; /* We did something */
4298 registers = GetRegisterData(ap);
4299 fregs = GetFRegisterData(ap);
4301 i = strlen(name);
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 */
4317 if(!registers)
4319 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
4320 ++offset; /* one long more on stack */
4322 else
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) */
4331 ++offset;
4335 else
4337 uint32 l;
4338 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
4339 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
4340 for(l = (uint16) registers; l; l >>= 1)
4342 if(l & 1)
4343 ++offset; /* get offset addition */
4348 if(fregs)
4350 uint32 l;
4351 EndPutM16Inc(data, 0xF227); /* FMOVEM.X xxx,-(A7) */
4352 EndPutM16Inc(data, 0xE000 + ((fregs>>8)&0xFF));
4353 for(l = (uint8) fregs; l; l >>= 1)
4355 if(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 */
4366 else
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 */
4378 if(fregs)
4380 EndPutM16Inc(data, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4381 EndPutM16Inc(data, 0xD000 + (fregs&0xFF));
4384 if(registers)
4386 if(Flags & FLAG_NOMOVEM)
4388 int32 i;
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));
4395 else
4397 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4398 EndPutM16Inc(data, (registers >> 16)); /* store MOVEM.L registers */
4401 else
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 */
4423 if(clibdata)
4425 if(!ap->NumArgs)
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 */
4451 if(clibdata)
4453 if(!ap->NumArgs)
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 ";
4479 int32 i;
4481 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4482 return 1;
4484 Flags |= FLAG_DONE; /* We did something */
4486 if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
4487 return 1;
4488 t = GetClibFunc(name, ap, flags);
4490 if(flags & FUNCFLAG_EXTENDMODE)
4492 sprintf(tempbuf, "___%s", name);
4493 name = tempbuf;
4496 if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
4497 ret = "";
4499 if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
4500 return 0;
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(", "))
4509 return 0;
4511 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4513 if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4514 return 0;
4516 else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
4517 return 0;
4519 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret, ap->FuncName))
4520 return 0;
4521 for(i = 0; i < ap->NumArgs-1; i++)
4523 if(!DoOutput("%s, ", ap->Args[i].ArgName))
4524 return 0;
4526 if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
4527 return 0;
4529 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4531 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
4532 return 0;
4534 else if(ap->NumArgs == 1)
4536 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4537 return 0;
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"))
4542 return 0;
4543 return 1;
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 */
4582 return 1;
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)
4594 uint32 j;
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" : "";
4610 uint8 *data;
4611 int32 i;
4612 struct ClibData *cd = 0;
4614 if(CheckError(ap, AMIPRAGFLAG_PPC))
4615 return 1;
4617 Flags |= FLAG_DONE; /* We did something */
4619 i = strlen(name);
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) */
4642 if(i > 7)
4644 EndPutM16Inc(data, 0x41EF | ((i-8) << 9)); /* LEA 8(A7),Ax */
4645 EndPutM16Inc(data, 8);
4647 else
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 */
4659 else
4661 EndPutM16Inc(data, 0x4EEE);
4662 EndPutM16Inc(data, -ap->Bias); /* JMP instruction */
4665 else
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 */
4676 else
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) */
4685 ++offset;
4689 else
4691 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
4692 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
4693 for(i = registers&0xFFFF; i; i >>= 1)
4695 if(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 */
4712 if(registers)
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));
4722 else
4724 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4725 EndPutM16Inc(data, registers >> 16); /* store MOVEM.L registers */
4728 else
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))
4756 if(!ap->NumArgs)
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)))
4763 strptr txt;
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);
4776 else
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))
4803 if(!ap->NumArgs)
4805 OutputSYMBOL(0, "%s__%sP07Library", name, str2); /* C++ names no parameters */
4806 OutputSYMBOL(0, "LOC_%s__%sP07Library", name, str2);
4808 else if(cd)
4810 strptr txt;
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);
4823 else
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;
4843 int32 i;
4845 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4846 return 1;
4848 Flags |= FLAG_DONE; /* We did something */
4850 if(!(cd = GetClibFunc(name, ap, flags)))
4851 return 1;
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());
4860 if(ap->NumArgs)
4861 DoOutput(", ");
4864 if(ap->NumArgs)
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(", "))
4871 return 0;
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"))
4880 return 0;
4881 if(BaseName)
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);
4892 else
4893 return DoOutput(/*(*/"...);\n");
4895 else if(BaseName)
4896 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
4897 name, name);
4898 else
4899 return DoOutput(/*(*/");\n");
4900 return 1;
4903 uint32 FuncInlineDirect(struct AmiPragma *ap, uint32 flags, strptr name)
4905 uint32 a4 = 0, a5 = 0;
4906 int32 noret = 0;
4907 int32 i, maxargs, reg=0;
4908 struct ClibData *cd;
4910 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4911 return 1;
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",
4919 name, ap->TagName);
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)))
4931 return 1;
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");
4938 else
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 ? ", " : "");
4948 if(ap->NumArgs < 2)
4949 DoOutput("tags");
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 ? ", " : "");
4953 if(ap->NumArgs < 2)
4954 DoOutput("tags");
4955 DoOutput(/*(*/")\n");
4956 return DoOutput("#endif\n\n");
4959 DoOutput("#define %s("/*)*/, name);
4960 if(ap->NumArgs)
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);
4971 DoOutput(" ");
4972 OutClibType(&cd->Args[i], (strptr) tempbuf);
4973 DoOutput(" = (%s); \\\n", ap->Args[i].ArgName);
4975 if(Flags & FLAG_INLINENEW)
4977 if(ap->NumArgs)
4978 DoOutput(" ({ \\\n"/*})*/);
4979 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name);
4980 if(BaseName)
4981 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper);
4982 else
4984 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
4986 if(i == ap->NumArgs)
4987 return 1;
4988 DoOutput("(%s);\\\n", ap->Args[i].ArgName);
4991 DoOutput(" (("/*))*/);
4992 OutClibType(&cd->ReturnType, 0);
4993 DoOutput(" (*)("/*)*/);
4994 if(BaseName)
4996 DoOutput("char * __asm(\"a6\")");
4997 if(ap->NumArgs)
4998 DoOutput(", ");
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)
5005 DoOutput(", ");
5007 DoOutput(/*((*/")) \\\n");
5008 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name, ap->Bias);
5009 if(BaseName)
5011 DoOutput("_%s__bn", name);
5012 if(ap->NumArgs)
5013 DoOutput(", ");
5015 for(i = 0; i < ap->NumArgs; ++i)
5017 if(ap->Args[i].ArgReg == REG_A6)
5018 DoOutput("_%s__bn", name);
5019 else
5020 DoOutput("_%s_%s", name, ap->Args[i].ArgName);
5021 if(i < ap->NumArgs-1)
5022 DoOutput(", ");
5024 DoOutput(/*(*/"); \\\n");
5025 if(ap->NumArgs)
5026 DoOutput(/*({*/"});");
5028 else
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;
5036 a5 &= 0xFFF;
5037 if(a5 == 0xFFF)
5039 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A5]);
5040 a5 = 0;
5042 else
5044 for(i = 0; (a5 & 1) && a5; ++i)
5045 a5 >>= 1;
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 */
5052 if(a5)
5053 a4 |= (1<<a5);
5054 for(i = 0; i < ap->NumArgs; ++i)
5055 a4 |= 1<<ap->Args[i].ArgReg;
5056 a4 &= 0xFFF;
5057 if(a4 == 0xFFF)
5059 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A4]);
5060 a4 = 0;
5062 else
5064 for(i = 0; (a4 & 1) && a4; ++i)
5065 a4 >>= 1;
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 */
5071 else
5073 sprintf((strptr)tempbuf, "_%s__re", name);
5074 DoOutput(" ");
5075 OutClibType(&cd->ReturnType, (strptr) tempbuf);
5076 DoOutput(" = \\\n");
5078 if(ap->NumArgs || !noret)
5079 DoOutput(" %s{ \\\n", noret ? "" : "(" /*})*/);
5080 if(BaseName)
5081 DoOutput(" register %s const __%s__bn __asm(\"a6\") = (%s) (%s_BASE_NAME);\\\n",
5082 GetBaseType(), name, GetBaseType(), ShortBaseNameUpper);
5084 if(!noret)
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))
5092 maxargs = 7;
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;
5111 if(reg == REG_A4)
5113 reg = a4; a4 = 0;
5115 else if(reg == REG_A5)
5117 reg = a5; a5 = 0;
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)
5144 if(i == maxargs)
5145 DoOutput("move.l (%s),%s\\n\\t", RegNames[reg],
5146 RegNames[ap->Args[i].ArgReg]);
5147 else
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");
5166 if(noret)
5167 DoOutput(" : \\\n");
5168 else
5169 DoOutput(" : \"=r\"(__%s__re) \\\n", name);
5170 DoOutput(" :");
5171 if(BaseName)
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)
5177 DoOutput(",");
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\", " : "");
5184 if(!noret)
5185 DoOutput(" __%s__re; \\\n", name);
5187 if(ap->NumArgs || !noret)
5188 DoOutput(/*({*/" }%s \\\n", noret ? "" : ");");
5190 if(!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;
5200 int32 fp = -1, i;
5201 struct ClibData *cd;
5203 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5204 return 1;
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)))
5224 return 1;
5226 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5227 noret = 1; /* this is a void function */
5229 if(ap->Flags & AMIPRAGFLAG_A5USE)
5230 a45 = REG_A5;
5231 if(ap->Flags & AMIPRAGFLAG_A4USE)
5233 if(a45)
5235 DoError(ERR_INLINE_A4_AND_A5, ap->Line);
5236 return 1; /* skip this entry */
5238 a45 = REG_A4;
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 */
5258 else
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("/*}))*/,
5266 ap->FuncName);
5267 for(i = 0; i < ap->NumArgs-1; ++i)
5268 DoOutput("(%s), ", ap->Args[i].ArgName);
5269 DoOutput("("/*)*/);
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;
5279 n = 9-ap->NumArgs;
5280 d = n & 1 ? 4 : 0;
5281 tagl = 8 + (Flags2 & FLAG2_DIRECTVARARGS ? 0 : 64);
5282 local = (n * 4+d+8+15) & ~15; /* size of the stack frame */
5284 /* Stack frame:
5285 * 0- 3: next frame ptr
5286 * 4- 7: save lr
5287 * 8-71: struct Caos
5288 * 72-72+n*4+d+8-1: tag list start
5289 * ?-local-1: padding
5292 DoOutput("asm(\"\n"/*)*/
5293 "\t.align\t2\n"
5294 "\t.globl\t%s\n"
5295 "\t.type\t%s,@function\n"
5296 "%s:\n"
5297 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5298 "\tmflr\t0\n"
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. */
5304 if(d)
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);
5311 if(d)
5312 DoOutput("\tstw\t0,%ld(1)\n", tagl+n * 4); /* write ti_Data */
5314 /* Add TAG_MORE */
5315 DoOutput("\tli\t0,2\n"
5316 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5317 "\taddi\t0,1,%ld\n"
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);
5326 else
5329 if(!BaseName)
5331 DoError(ERR_MISSING_BASENAME, ap->Line);
5332 return 1;
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"
5345 "\tlis\t3,%s@ha\n"
5346 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5347 "\tlwz\t12,%s@l(3)\n"
5348 "\tlwz\t11,88(2)\n"
5349 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5350 "\tmtctr\t11\n"
5351 "\taddi\t3,1,8\n"
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 */
5356 "\tmtlr\t0\n"
5357 "\taddi\t1,1,%ld\n"
5358 "\tblr\n"
5359 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local+4, local, name, name);
5361 else
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)
5378 funcpar = "FP";
5381 if(ap->NumArgs)
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);
5390 if(!noret)
5392 OutClibType(&cd->ReturnType, 0);
5393 DoOutput(", ");
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))
5401 j = REG_D7;
5402 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5404 if(fp != -1)
5406 DoError(ERR_MULTIPLEFUNCTION, ap->Line);
5407 DoOutput("void *");
5409 else
5411 DoOutput("__fpt"); fp = i;
5414 else
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);
5424 if(fp >= 0)
5426 DoOutput(", ");
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)
5449 DoOutput(", ");
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");
5462 if(ap->NumArgs)
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);
5473 if(BaseName)
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");
5477 else
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"/*}*/);
5489 if(ap->NumArgs)
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);
5499 if(BaseName)
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");
5504 else
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" : ""));
5515 if(!noret)
5517 DoOutput(" register ");
5518 OutClibType(&cd->ReturnType, "res");
5519 DoOutput(" __asm(\"d0\");\n");
5522 if(BaseName)
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))
5529 j = REG_D7;
5531 DoOutput(" register ");
5532 OutClibType(&cd->Args[i], RegNames[j]);
5533 DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
5536 if(a45)
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]);
5542 else
5543 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap->Bias);
5545 DoOutput(noret ? " : /* No Output */\n" : " : \"=r\" (res)\n");
5547 DoOutput(" : ");
5548 if(BaseName)
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))
5555 j = REG_D7;
5557 DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
5560 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
5562 if(noret)
5563 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
5564 else
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)
5572 int32 i;
5573 struct ClibData *cd;
5575 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5576 return 1;
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)))
5595 return 1;
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 */
5605 else
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("/*}))*/,
5611 ap->FuncName);
5612 for(i = 0; i < ap->NumArgs-1; ++i)
5613 DoOutput("(%s), ", ap->Args[i].ArgName);
5614 DoOutput("("/*)*/);
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)
5627 DoOutput(", ");
5629 DoOutput(/*(*/") \\\n\t");
5631 else
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)
5640 DoOutput(", ");
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)
5654 DoOutput(", ");
5656 if(BaseName)
5658 if(ap->NumArgs)
5659 DoOutput(", ");
5660 DoOutput("%s __asm(\"a6\")", GetBaseType());
5662 DoOutput(/*((*/"))");
5663 if(Flags2 & FLAG2_INLINEMAC)
5664 DoOutput(" \\");
5665 if(BaseName)
5666 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/, ShortBaseNameUpper, ap->Bias);
5667 else
5669 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
5671 if(i == ap->NumArgs)
5672 return 1;
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)
5679 DoOutput(", ");
5681 if(BaseName)
5683 if(ap->NumArgs)
5684 DoOutput(", ");
5685 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
5688 if(Flags2 & FLAG2_INLINEMAC)
5689 DoOutput(/*(*/")\n");
5690 else
5691 DoOutput(/*{(*/");\n}\n");
5693 return DoOutput("\n");
5696 uint32 FuncPowerUP(struct AmiPragma *ap, uint32 flags, strptr name)
5698 int32 i;
5699 struct ClibData *cd;
5701 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5702 return 1;
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)))
5721 return 1;
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("/*)})*/,
5729 ap->FuncName);
5730 for(i = 0; i < ap->NumArgs-1; ++i)
5731 DoOutput("(%s), ", ap->Args[i].ArgName);
5732 DoOutput("("/*)*/);
5733 OutClibType(&cd->Args[i], 0);
5734 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
5737 DoOutput("#define\t%s("/*)*/, name);
5739 if(ap->NumArgs)
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);
5746 if(BaseName)
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);
5753 else if(BaseName)
5754 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name, ShortBaseNameUpper);
5755 else
5756 DoOutput(/*(*/")\t_%s()\n\n", name);
5758 DoOutput("static __inline ");
5759 OutClibType(&cd->ReturnType, 0);
5761 DoOutput("\n_%s("/*)*/, name);
5762 if(BaseName)
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)
5769 DoOutput(", ");
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");
5780 if(ap->NumArgs)
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);
5791 if(BaseName)
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");
5795 else
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)
5806 int32 i;
5807 struct ClibData *cd;
5809 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
5810 return 1;
5811 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5812 return 1;
5814 if(!FuncFPCType(ap, flags, name))
5815 return 0;
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]);
5823 if(BaseName)
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");
5833 else
5834 DoOutput("\tMOVE.L\tD0,@RESULT\n");
5836 return DoOutput(" END;\nEND;\n\n");
5839 uint32 FuncFPCType(struct AmiPragma *ap, uint32 flags, strptr name)
5841 uint32 ret = 1;
5842 int32 i;
5843 struct ClibData *cd;
5845 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
5846 return 1;
5847 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5848 return 1;
5850 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5852 ret = 0; DoOutput("PROCEDURE %s", name);
5854 else
5855 DoOutput("FUNCTION %s", name);
5857 if(ap->NumArgs)
5859 DoOutput("("/*)*/);
5860 for(i = 0; i < ap->NumArgs;)
5862 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
5863 if(++i != ap->NumArgs)
5864 DoOutput("; ");
5866 DoOutput(/*(*/")");
5869 if(ret)
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)
5879 uint32 ret = 1;
5880 int32 i;
5881 struct ClibData *cd;
5883 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
5884 return 1;
5885 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5886 return 1;
5888 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5890 ret = 0; DoOutput("PROCEDURE %s", name);
5892 else
5893 DoOutput("FUNCTION %s", name);
5895 if(ap->NumArgs)
5897 DoOutput("("/*)*/);
5898 for(i = 0; i < ap->NumArgs-1;)
5900 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
5901 if(++i != ap->NumArgs)
5902 DoOutput("; ");
5904 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
5905 DoOutput(/*(*/")");
5908 if(ret)
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)
5918 uint32 ret = 1;
5919 int32 i;
5920 struct ClibData *cd;
5922 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
5923 return 1;
5924 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5925 return 1;
5927 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5929 ret = 0; DoOutput("PROCEDURE %s", name);
5931 else
5932 DoOutput("FUNCTION %s", name);
5934 if(ap->NumArgs)
5936 DoOutput("("/*)*/);
5937 for(i = 0; i < ap->NumArgs-1;)
5939 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
5940 if(++i != ap->NumArgs)
5941 DoOutput("; ");
5943 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
5944 DoOutput(/*(*/")");
5947 if(ret)
5948 OutPASCALType(&cd->ReturnType, "", 1);
5950 DoOutput(";\nbegin\n");
5952 if(ret)
5953 DoOutput(" %s := %s",name, ap->FuncName);
5954 else DoOutput(" %s", ap->FuncName);
5956 if(ap->NumArgs)
5958 DoOutput("("/*)*/);
5959 for(i = 0; i < ap->NumArgs-1;)
5961 DoOutput("%s ", ap->Args[i].ArgName);
5962 if(++i != ap->NumArgs)
5963 DoOutput(", ");
5965 DoOutput("readintags(%s)",ap->Args[i].ArgName);
5966 DoOutput(/*(*/");");
5969 DoOutput("\nend");
5971 Flags |= FLAG_DONE; /* We did something */
5973 return DoOutput(";\n\n");
5977 uint32 FuncBMAP(struct AmiPragma *ap, uint32 flags, strptr name)
5979 uint8 reg, i;
5981 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_A5USE|AMIPRAGFLAG_PPC))
5982 return 1;
5984 Flags |= FLAG_DONE; /* We did something */
5986 for(i = 0; BMAPSpecial[i]; ++i)
5988 if(!stricmp(name, BMAPSpecial[i]))
5990 DoOutput("x"); break;
5994 DoOutput(name);
5995 reg = 0; DoOutputDirect(&reg, 1);
5996 reg = (-ap->Bias)>>8; DoOutputDirect(&reg, 1);
5997 reg = -ap->Bias; DoOutputDirect(&reg, 1);
5998 for(i = 0; i < ap->NumArgs; ++i)
6000 reg = 1+ap->Args[i].ArgReg; DoOutputDirect(&reg, 1);
6002 reg = 0;
6003 return DoOutputDirect(&reg, 1);
6006 uint32 FuncVBCCInline(struct AmiPragma *ap, uint32 flags, strptr name)
6008 struct ClibData *cd;
6009 strptr c1, c2;
6010 int32 i, k;
6012 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6013 return 1;
6015 if(!(cd = GetClibFunc(name, ap, flags)))
6016 return 1;
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());
6053 if(ap->NumArgs)
6054 DoOutput(", ");
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);
6066 else
6067 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6068 if(i < ap->NumArgs-1)
6069 DoOutput(", ");
6072 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6074 if(ap->NumArgs)
6075 DoOutput(", ");
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);
6084 DoOutput(", ");
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,
6088 ap->Bias, c2);
6090 else
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)
6099 DoOutput(", ");
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);
6105 DoOutput("...");
6107 DoOutput(/*(*/") __%s("/*)*/, name);
6108 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6110 DoOutput("%s", BaseName);
6111 if(ap->NumArgs)
6112 DoOutput(", ");
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)
6123 DoOutput(", ");
6125 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6127 if(ap->NumArgs)
6128 DoOutput(", ");
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;
6144 int32 i;
6146 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_M68K))
6147 return 1;
6149 if(!(cd = GetClibFunc(name, ap, flags)))
6150 return 1;
6152 if(!BaseName)
6154 DoError(ERR_MISSING_BASENAME, ap->Line);
6155 return 1;
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());
6168 if(ap->NumArgs)
6169 DoOutput(", ");
6172 for(i = 0; i < ap->NumArgs; ++i)
6174 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6175 if(i < ap->NumArgs-1)
6176 DoOutput(", ");
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"
6185 "\\tmtlr\\t%s0\\n"
6186 "\\tblrl",
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"
6196 "\\tmtlr\\t%s0\\n"
6197 "\\tblrl\\n"
6198 "\\tlwz\\t%s2,20(%s1)",
6199 PPCRegPrefix, PPCRegPrefix, BaseName, PPCRegPrefix, BaseName,
6200 PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix,
6201 PPCRegPrefix, PPCRegPrefix);
6203 else
6205 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6206 "\\tmtlr\\t%s0\\n"
6207 "\\tblrl",
6208 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6211 DoOutput("\";\n");
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)
6219 DoOutput(", ");
6221 DoOutput(/*(*/") __%s("/*)*/, ap->FuncName);
6222 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6224 DoOutput("%s", BaseName);
6225 if(ap->NumArgs)
6226 DoOutput(", ");
6228 for(i = 0; i < ap->NumArgs; ++i)
6230 DoOutput("(%s)", ap->Args[i].ArgName);
6231 if(i < ap->NumArgs-1)
6232 DoOutput(", ");
6235 return DoOutput(/*(*/")\n\n");
6238 uint32 FuncVBCCMorphInline(struct AmiPragma *ap, uint32 flags, strptr name)
6240 struct ClibData *cd;
6241 int32 i, k;
6243 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6244 return 1;
6246 if(!(cd = GetClibFunc(name, ap, flags)))
6247 return 1;
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);
6270 if(BaseName)
6272 DoOutput("%s", GetBaseType());
6273 if(ap->NumArgs)
6274 DoOutput(", ");
6277 if(flags & FUNCFLAG_TAG)
6279 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6280 DoOutput("long, ");
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)
6288 DoOutput(", ");
6291 if(flags & FUNCFLAG_TAG)
6293 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6295 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6296 DoOutput(", ");
6298 DoOutput("...");
6301 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6302 PPCRegPrefix, PPCRegPrefix);
6303 k = 3;
6304 if(BaseName)
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)
6309 k += 8+1-i;
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)
6317 if(k <= 7+3)
6318 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix, k++);
6319 else
6320 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,", PPCRegPrefix,
6321 8+(k++-11)*4, PPCRegPrefix, PPCRegPrefix);
6323 else
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)
6336 DoOutput(", ");
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);
6342 DoOutput("...");
6344 DoOutput(/*(*/") __%s("/*)*/, name);
6345 if(BaseName)
6347 DoOutput("%s", BaseName);
6348 if(ap->NumArgs)
6349 DoOutput(", ");
6351 if(flags & FUNCFLAG_TAG)
6353 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6354 DoOutput("0, ");
6356 for(i = 0; i < k; ++i)
6358 DoOutput("(%s)", ap->Args[i].ArgName);
6359 if(i < ap->NumArgs-1)
6360 DoOutput(", ");
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))
6378 return 1;
6380 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&!(cd = GetClibFunc(name, ap, flags)))
6381 return 1;
6383 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
6384 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) || !(Flags & FLAG_WOSLIBBASE)))
6386 DoError(ERR_MISSING_BASENAME, ap->Line);
6387 return 1;
6390 Flags |= FLAG_DONE;
6392 if(Flags & FLAG_SINGLEFILE)
6394 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
6396 if(HEADER)
6398 DoOutput("\n");
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);
6415 else
6417 if(BaseName)
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"
6427 "\tmflr\t%s0\n"
6428 "\tstw\t%s0,16(%s1)\n"
6429 "\tlwz\t%s2,_%s(%s2)\n"
6430 "\tlwz\t%s0,-%d(%s2)\n"
6431 "\tmtlr\t%s0\n"
6432 "\tblrl\n"
6433 "\tlwz\t%s0,16(%s1)\n"
6434 "\tlwz\t%s2,20(%s1)\n"
6435 "\tmtlr\t%s0\n"
6436 "\tblr\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);
6456 if(count > 8)
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,
6466 i+20+count*4);
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);
6473 --count;
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);
6483 if(count > 7)
6485 /* extra arguments must be passed on the stack */
6486 if(count == 8)
6488 /* special case: move 8th argument into stack frame */
6489 if(flags & FUNCFLAG_TAG)
6490 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
6491 i+20+count*4);
6492 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix, PPCRegPrefix);
6494 else
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);
6514 --count;
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);
6525 /* call LVO */
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 */
6530 if(count > 8)
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);
6540 else
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);
6554 else if(!BaseName)
6555 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix,
6556 ap->Bias, PPCRegPrefix, PPCRegPrefix);
6557 else
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,
6562 PPCRegPrefix);
6564 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
6565 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
6566 for(i = 0; i < k; ++i)
6568 if(i + ofs <= 7)
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);
6574 else
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",
6604 name, name, name);
6605 else
6606 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
6607 name, name, name);
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))
6617 return 1;
6619 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) && !(cd = GetClibFunc(name, ap, flags)))
6620 return 1;
6622 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
6623 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) || !(Flags & FLAG_WOSLIBBASE)))
6625 DoError(ERR_MISSING_BASENAME, ap->Line);
6626 return 1;
6629 Flags |= FLAG_DONE; /* We did something */
6631 i = strlen(name);
6632 if(Flags & FLAG_WOSLIBBASE)
6633 ++i;
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) */
6654 basepos = data;
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)
6666 basepos = data;
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) */
6683 if(count > 8)
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 */
6696 --count;
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) */
6707 if(count > 7)
6709 /* extra arguments must be passed on the stack */
6710 if(count == 8)
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) */
6717 else
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 */
6732 --count;
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 */
6740 basepos = data;
6741 EndPutM32Inc(data, 0x80620000); /* lwz r3,BaseName(r2) */
6743 /* call LVO */
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 */
6750 if(count > 8)
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 */
6760 else
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 */
6778 else if(!BaseName)
6780 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
6781 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
6783 else
6785 basepos = data;
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 */
6798 if(i + ofs <= 7)
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) */
6804 else
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);
6853 else
6855 if(BaseName)
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);
6869 else
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)
6881 int32 i;
6883 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6884 return 1;
6886 Flags |= FLAG_DONE;
6888 if(Flags & FLAG_SINGLEFILE)
6890 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
6892 if(HEADER)
6894 DoOutput("\n");
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);
6904 if(BaseName)
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
6914 caller's frame. */
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),
6927 PPCRegPrefix);
6929 else
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)
6937 if(i <= 7)
6938 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
6939 else
6940 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
6941 100+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
6943 else
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 */
6956 if(BaseName)
6958 if(Flags & FLAG_SMALLDATA)
6959 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
6960 else
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);
6972 else
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;
6985 data = tempbuf;
6987 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6988 return 1;
6990 Flags |= FLAG_DONE;
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 */
7016 data3 = data;
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
7022 caller's frame. */
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) */
7037 else
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)
7049 if(i <= 7)
7051 EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j); /* stw rX,j(r1) */
7053 else
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) */
7059 else
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 */
7073 if(BaseName)
7075 if(Flags & FLAG_SMALLDATA)
7077 j = (data-data3)+2; /* store reloc offset */
7078 EndPutM32Inc(data, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7080 else
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 */
7100 else
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 */
7113 data2 = data-44;
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 */
7126 size = data2-data3;
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 */
7138 data3 = data;
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 */
7186 data2 = data;
7187 data += BaseName ? 6*16 : 5*16;
7189 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
7191 i = 0;
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 */
7198 data[0] = 0;
7200 i += 1;
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 */
7232 if(BaseName)
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 */
7245 data[i++] = 0;
7246 data += i;
7248 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
7250 data2 = data;
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 */
7256 if(BaseName)
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 */
7264 else
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)] = ' ';
7291 else
7293 k = 0;
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';
7301 j /= 10;
7303 for(j = 0; i < 9; ++j)
7304 arh->ar_size[j] = data[++i];
7306 DoOutputDirect(arh, sizeof(struct ArHeader));
7308 if(k)
7310 DoOutput("%s.o", name);
7311 if(k & 1)
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))
7323 return 1;
7325 Flags |= FLAG_DONE;
7327 if(Flags & FLAG_SINGLEFILE)
7329 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7331 if(HEADER)
7333 DoOutput("\n");
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);
7343 if(BaseName)
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"
7354 "\tmflr\t%s0\n",
7355 PPCRegPrefix, stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix);
7357 if(nrcopyar)
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
7362 caller's frame. */
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);
7376 if(BaseName)
7378 if(Flags & FLAG_SMALLDATA)
7379 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
7380 else
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)
7391 if(i <= 7)
7392 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
7393 else
7394 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
7395 stcksize+(i+2-8)*4, PPCRegPrefix, PPCRegPrefix);
7397 else
7398 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix,
7399 PPCRegPrefix, stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0),
7400 PPCRegPrefix);
7401 DoOutput("%d(%s2)\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
7404 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
7405 PPCRegPrefix, PPCRegPrefix);
7407 if(BaseName)
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"
7425 "\tmtlr\t%s0\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;
7438 data = tempbuf;
7440 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7441 return 1;
7443 Flags |= FLAG_DONE;
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 */
7469 data3 = data;
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 */
7480 if(nrcopyar)
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
7485 caller's frame. */
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) */
7498 if(BaseName)
7500 if(Flags & FLAG_SMALLDATA)
7502 k = (data-data3)+2; /* store reloc offset */
7503 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
7505 else
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)
7520 if(i <= 7)
7522 EndPutM32Inc(data, 0x90020000 + ((i+3)<<21) + j); /* stw rX,j(r2) */
7524 else
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) */
7530 else
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) */
7539 if(BaseName)
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 */
7564 data2 = data-44;
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 */
7577 size = data2-data3;
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 */
7589 data3 = data;
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 */
7637 data2 = data;
7638 data += BaseName ? 5*16 : 4*16;
7640 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
7642 i = 0;
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 */
7649 data[0] = 0;
7651 i += 1;
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 */
7675 if(BaseName)
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 */
7688 data[i++] = 0;
7689 data += i;
7691 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
7693 data2 = data;
7695 if(BaseName)
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 */
7703 else
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)] = ' ';
7730 else
7732 k = 0;
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';
7740 j /= 10;
7742 for(j = 0; i < 9; ++j)
7743 arh->ar_size[j] = data[++i];
7745 DoOutputDirect(arh, sizeof(struct ArHeader));
7747 if(k)
7749 DoOutput("%s.o", name);
7750 if(k & 1)
7751 *(data++) = 0x0A; /* alignment byte! */
7754 return DoOutputDirect(tempbuf, data-tempbuf);
7757 uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
7759 uint8 i, r;
7761 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
7762 (flags & FUNCFLAG_ALIAS))
7763 return 1;
7765 if(LastBias >= ap->Bias)
7766 DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
7767 else
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]));
7775 if(name[1])
7777 DoOutput("%c", tolower(name[1]));
7778 if(name[2])
7779 DoOutput("%s", name+2);
7781 if(!ap->NumArgs)
7782 DoOutputDirect("\x10", 1);
7783 else
7785 for(i = 0; i < ap->NumArgs; ++i)
7787 r = ap->Args[i].ArgReg;
7788 DoOutputDirect(&r, 1);
7792 return 1;
7795 uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
7797 int32 i;
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");
7809 else
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)
7825 switch(ap->Abi)
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;
7855 int32 i, s, c;
7857 Flags |= FLAG_DONE; /* We did something */
7859 if(!(cd = GetClibFunc(name, ap, flags)))
7860 return 1;
7862 s = MakeClibType(tempbuf, &cd->ReturnType, 0);
7863 DoOutputDirect(tempbuf, s);
7864 DoOutput(" %s("/*)*/, name);
7866 if(ap->NumArgs)
7868 for(i = 0; i < cd->NumArgs; i++)
7870 c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
7871 if(s+c+2 > 75 && s)
7873 DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
7875 else if(i)
7877 DoOutput(", "); s += 2;
7879 DoOutputDirect(tempbuf, c);
7880 s += c;
7883 else if(Flags2 & FLAG2_CLIBOUT)
7884 DoOutput("void");
7885 return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
7888 uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
7890 struct ClibData *cd;
7891 int32 i, j;
7893 if(!(cd = GetClibFunc(name, ap, flags)))
7894 return 1;
7896 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
7898 if(Flags & FLAG_ISPRIVATE)
7900 Flags ^= FLAG_ISPRIVATE;
7901 DoOutput("==public\n");
7904 else
7906 if(!(Flags & FLAG_ISPRIVATE))
7907 DoOutput("==private\n");
7908 Flags |= FLAG_ISPRIVATE;
7911 if(ap->Abi != CurrentABI)
7913 switch(ap->Abi)
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");
7932 else
7933 LastBias += BIAS_OFFSET;
7935 if(!FuncClib(ap, flags, name))
7936 return 0;
7938 DoOutput(" ("/*)*/);
7939 if(!(ap->Flags & AMIPRAGFLAG_PPC))
7941 strptr s;
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)
7949 s = ""; j += 2;
7951 else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
7953 s = (j&1) ? "," : "-"; ++j;
7955 else
7957 s = ","; j += 2;
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 ";
7969 int32 i;
7971 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
7972 return 1;
7974 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
7975 return 1;
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("/*}))*/,
8003 ap->FuncName);
8004 for(i = 0; i < ap->NumArgs-1; ++i)
8005 DoOutput("(%s), ", ap->Args[i].ArgName);
8006 DoOutput("("/*)*/);
8007 OutClibType(&cd->Args[i], 0);
8008 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
8011 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
8012 ret = "";
8014 if(!OutClibType(&cd->ReturnType, 0))
8015 return 0;
8017 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix, name);
8019 for(i = 0; i < ap->NumArgs; ++i)
8021 DoOutput(" ");
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);
8030 if(ap->NumArgs)
8032 if(Flags2 & FLAG2_PRELIB)
8034 if(Flags2 & FLAG2_REGLIB)
8035 DoOutput("___RegBase,");
8036 else
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);
8048 else
8049 DoOutput("%s, %s_BASE_NAME", ap->Args[i].ArgName, ShortBaseNameUpper);
8051 else
8052 DoOutput("%s", ap->Args[i].ArgName);
8054 else
8056 if(Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB))
8058 if(Flags2 & FLAG2_REGLIB)
8059 DoOutput("___RegBase");
8060 else
8061 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
8064 return DoOutput(/*(({*/"));\n}\n");
8067 static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
8069 uint32 res;
8071 if(Flags & FLAG_SINGLEFILE)
8073 sprintf(filename, filenamefmt, name);
8074 if(!OpenDest(filename))
8075 return 0;
8077 res = Func(ap, flags, name);
8078 if(Flags & FLAG_SINGLEFILE)
8080 CloseDest(filename);
8082 return res;
8085 static uint32 PrintComment(struct Comment *com, strptr comment)
8087 if(com->Private && !(Flags & FLAG_PRIVATE))
8088 return 1;
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)
8099 return 1;
8101 if(com->Data)
8103 if(!DoOutput(comment, com->Data))
8104 return 0;
8106 else if(com->ReservedNum)
8108 string temp[256];
8109 sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
8110 com->ReservedNum == 1 ? "" : "s");
8111 if(!DoOutput(comment, temp))
8112 return 0;
8114 else if(com->Version)
8116 string temp[256];
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]);
8121 else
8122 sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
8124 if(!DoOutput(comment, temp))
8125 return 0;
8127 return 1;
8130 static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
8132 struct Comment *com;
8133 uint32 i;
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))
8150 return 0;
8151 com = (struct Comment *) com->List.Next;
8152 } /* comment loop */
8154 #ifdef DEBUG_OLD
8155 printf("Processing %s\n", ap->FuncName);
8156 #endif
8158 if(tagmode != TAGMODE_TAGS)
8160 if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
8161 return 0;
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))
8168 return 0;
8173 if(tagmode)
8175 if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
8176 return 0;
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))
8183 return 0;
8189 while(com)
8191 if(!PrintComment(com, comment))
8192 return 0;
8193 com = (struct Comment *) com->List.Next;
8194 } /* comment loop */
8195 return 1;
8198 static uint32 PrintIncludes(void) /* copies the include lines */
8200 struct Include *inc;
8201 strptr s, s2;
8203 inc = (struct Include *) Includes.First;
8205 while(inc)
8207 s2 = (strptr) tempbuf;
8208 for(s = inc->Include; *s; ++s)
8210 switch(*s)
8212 case '<': *(s2++) = ' '; break;
8213 case '/':
8214 case '.': *(s2++) = '_'; break;
8215 case '>': break;
8216 default: *(s2++) = toupper(*s);
8218 *s2 = 0;
8220 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
8221 inc = (struct Include *) inc->List.Next;
8223 if(!Includes.First)
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 */
8239 #ifdef DEBUG_OLD
8240 printf("Found non-function bracket in preprozessor line %ld\n", linenum);
8241 #endif
8242 while(buf < bufend && *buf != '\n')
8243 ++buf;
8244 return buf-buffer;
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);
8260 return 0;
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 */
8273 else
8274 d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
8275 buf = d.FuncName;
8276 while(*(buf++) != '('/*)*/)
8278 *(SkipName(d.FuncName)) = 0;
8279 if(!(*d.FuncName))
8281 #ifdef DEBUG_OLD
8282 printf("Found non-function bracket in line %ld\n", linenum);
8283 #endif
8284 while(buf < bufend && *buf != '\n')
8285 ++buf;
8286 return buf-buffer;
8288 buf = SkipBlanksRet(buf);
8290 while(*buf != /*(*/')' && buf < bufend)
8292 if(d.NumArgs == MAXREGPPC+1)
8294 DoError(ERROFFSET_CLIB | ERR_TO_MUCH_ARGUMENTS, linenum);
8295 return 0;
8297 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0, 1))
8299 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
8300 return 0;
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)
8308 ++buf;
8309 #ifdef DEBUG
8310 printf("Added argument %ld for %s (%ld bytes)\n", d.NumArgs, d.FuncName,
8311 d.Args[d.NumArgs-1].FullLength);
8312 #endif
8313 if(*buf == ',')
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))))
8321 return -1;
8323 memcpy(f, &d, sizeof(struct ClibData));
8325 if(!clibdata)
8326 clibdata = f;
8327 else
8329 struct ClibData *e = clibdata;
8330 while(e->Next)
8331 e = e->Next;
8332 e->Next = f;
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;
8341 ++buf;
8345 #ifdef DEBUG
8346 printf("Added prototype for %s (line %ld, %ld bytes) with %ld args\n",
8347 f->FuncName, linenum, buf-buffer, f->NumArgs);
8348 #endif
8349 return buf-buffer;
8352 static int32 ScanClibFile(strptr buf, strptr bufend)
8354 strptr linestart = buf;
8355 uint32 linenum = 1;
8357 /* remove comments and other not so nice characters */
8358 while(buf < bufend)
8360 if(*buf == '\t' || *buf == '\r' || *buf == (string)0xA0)
8361 *(buf++) = ' ';
8362 else if(buf[0] == '/' && buf < bufend-1)
8364 if(buf[1] == '*')
8366 while(buf < bufend-1 && (buf[0] != '*' || buf[1] != '/'))
8368 if(*buf != '\n')
8369 *buf = ' ';
8370 ++buf;
8372 *(buf++) = ' ';
8373 *(buf++) = ' ';
8375 else if(buf[1] == '/')
8377 while(buf < bufend && buf[0] != '\n')
8378 *(buf++) = ' ';
8379 ++buf;
8381 else
8382 ++buf;
8384 else if(buf[0] == '#' && strncmp("#include", buf, 8))
8386 while(buf < bufend && buf[0] != '\n')
8387 *(buf++) = ' ';
8388 ++buf;
8390 else
8391 ++buf;
8394 #ifdef DEBUG_OLD
8395 printf("-----------\n%s-----------\n", linestart);
8396 #endif
8398 buf = linestart;
8399 while(buf < bufend)
8401 if(*buf == '\n')
8403 linestart = ++buf; ++linenum;
8405 else if(!strncmp("#include", buf, 8))
8407 struct Include *d;
8409 if(!(d = (struct Include *) NewItem(&Includes)))
8410 return 0;
8411 d->Include = buf = SkipBlanks(buf+8);
8412 AddItem(&Includes, (struct ShortList *) d);
8413 while(*buf && *buf != '>' && *buf != '\n')
8414 ++buf;
8415 if(*buf == '>')
8416 ++buf;
8417 if(*buf == '\n')
8418 ++linenum;
8419 *(buf++) = 0;
8420 #ifdef DEBUG_OLD
8421 printf("Added Include line %s\n", d->Include);
8422 #endif
8424 else if(*buf == '('/*)*/)
8426 int32 i;
8428 if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
8429 return 0;
8430 else if(!i)
8432 while(buf < bufend && *buf != '\n')
8433 ++buf; /* skip this line */
8435 else
8437 i -= buf-linestart;
8438 while(buf < bufend && i-- > 0)
8440 if(*(buf++) == '\n')
8442 linestart = buf;
8443 ++linenum;
8444 } /* skip this function */
8448 else
8449 ++buf;
8450 } /* while */
8451 return 1;
8454 static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
8456 if(!data || data->Flags || data->Type != type || data->PointerDepth)
8457 return 0;
8458 return type;
8461 static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
8463 uint32 i, j;
8465 for(i = 0; i < MAXREG; ++i)
8467 j = strlen(RegNames[i]);
8468 if(!strnicmp(string, RegNames[i], j))
8470 string += j;
8471 if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
8473 data->Register = i;
8474 data->Flags |= CPP_FLAG_REGISTER;
8475 return j;
8479 return 0;
8482 static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
8484 strptr buf = buffer;
8485 struct ClibData d;
8487 memset(&d, 0, sizeof(struct ClibData));
8488 while(*buf != /*(*/')')
8490 if(d.NumArgs == MAXREGPPC+1)
8491 return 0;
8492 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1, 1))
8493 return 0;
8495 buf += d.Args[d.NumArgs-1].FullLength;
8496 while(*buf != ',' && *buf != /*(*/')')
8497 ++buf;
8498 if(*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))))
8508 return 0;
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)
8518 uint32 ok = 1, j;
8519 strptr u;
8521 data->Unknown = 0;
8522 data->Replace = 0;
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);
8528 if(*u == '('/*)*/)
8530 u = SkipBlanks(u+1);
8531 if((j = CheckRegisterNum(u, data)))
8533 u = SkipBlanks(u+j);
8534 if(*u == ')')
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;
8549 return 1;
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))
8560 start += 7;
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 = "";
8578 ++start;
8580 else if(*start == '!') /* ! for typedef types */
8582 data->Flags |= CPP_FLAG_TYPEDEFNAME;
8583 ++start;
8584 /* structure name and length already set */
8586 else
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;
8601 else
8603 data->StructureLength = 0;
8604 data->StructureName = "";
8605 ++start;
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;
8617 else
8619 data->StructureLength = 0;
8620 data->StructureName = "";
8621 ++start;
8624 else if(*start == '*')
8626 ++start; ++data->PointerDepth;
8628 else if(*start == '[')
8630 data->Flags |= CPP_FLAG_ARRAY;
8631 while(*start && *start != ']')
8632 ++start;
8633 if(*start)
8634 ++start;
8636 else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
8637 start += 2 + j;
8638 else if(!data->Type)
8640 uint32 i;
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;
8658 break;
8661 if(CPP_Field[i].Text)
8662 continue;
8663 else if(extnames)
8665 struct CPP_ExternNames *a = extnames;
8667 while(a)
8669 i = strlen(a->Type);
8670 if(!strncmp(a->Type, start, i) && !isalnum(start[i]) &&
8671 start[i] != '_')
8673 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;
8682 break;
8685 /* check types here */
8686 a = a->Next;
8688 if(a)
8689 continue;
8690 else if((!data->Type) && (!data->Flags))
8692 long size;
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)
8699 if(!u)
8701 data->Unknown = DupString(start, size);
8702 if((u = (struct CPP_Unknown *) AllocListMem(sizeof(struct CPP_Unknown))))
8704 u->Next = unknown;
8705 u->Unknown = data->Unknown;
8706 unknown = u;
8709 start += size;
8710 continue;
8713 break;
8715 else
8716 break;
8717 }while(1);
8719 if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
8720 u = start;
8722 data->TypeLength = u - (data->TypeStart);
8723 data->FullLength = data->TypeLength;
8725 u = SkipBlanks(u);
8727 if(*u == '('/*)*/)
8729 ok = 0;
8730 u = SkipBlanks(++u);
8731 if(*u == '*')
8733 while(*u == '*')
8735 ++data->FuncPointerDepth; ++u;
8737 u = SkipBlanks(u);
8738 if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
8740 data->Flags |= CPP_FLAG_CONST; u += 6;
8742 u = SkipBlanks(u);
8743 if(*u != /*(*/')')
8744 data->FunctionName = u;
8745 u = SkipBlanks(SkipName(u));
8746 if(*u == '('/*)*/)
8748 int numclose = 1;
8749 ++u;
8750 while(*u && numclose)
8752 if(*u == '('/*)*/) ++numclose;
8753 else if(*u == /*(*/')') --numclose;
8754 ++u;
8757 if(*u == /*(*/')')
8759 u = SkipBlanks(++u);
8760 if(*u == '('/*)*/)
8762 data->Flags |= CPP_FLAG_FUNCTION;
8764 if((j = ParseFuncPtrArgs(u+1, data)))
8765 ok = 1;
8766 data->FuncArgs = u;
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";
8786 else
8787 data->Replace = "const LONG";
8788 data->Type = CPP_TYPE_LONG;
8789 if(!(data->Flags & CPP_FLAG_CONST))
8790 data->Replace += 6;
8795 if((!data->Type && !data->Flags) || !ok)
8796 return 0;
8797 return 1;
8800 static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
8802 struct ClibData *d = clibdata;
8804 while(d && strcmp(name, d->FuncName))
8805 d = d->Next;
8807 if(!d)
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;
8823 return 0;
8826 return d;
8829 static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
8831 if(!strncmp(string, keyword, size))
8833 string += size;
8834 if(*string == ' ' || *string == '\t' || *string == '\n')
8835 return size;
8837 return 0;
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;
8845 uint32 i, j, k = 0;
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;
8856 nt = &cd->Args[i];
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;
8862 else
8863 reg = 0;
8865 if(reg--) /* subtract the added 1 */
8867 *(buffer++) = CPP_TYPE_REGISTER;
8868 if(reg >= 10)
8870 if(pass & 2)
8872 *(buffer++) = reg/10 + '0';
8873 *(buffer++) = reg%10 + '0';
8874 ret |= 2;
8876 else
8877 *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
8879 else
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;
8902 if(nt->Type)
8903 *(buffer++) = cd->Args[i].Type;
8904 else
8906 uint32 i;
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)
8913 if(nt->FuncPtr)
8915 ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
8916 while(*buffer)
8917 ++buffer; /* skip to the new end */
8919 *(buffer++) = CPP_TYPE_FUNCEND;
8921 ++k;
8922 if(IsCPPType(nt, CPP_TYPE_DOUBLE)) /* double needs 2 registers */
8923 ++k;
8926 *(buffer) = 0;
8928 if(ret != pass)
8929 ret = 0;
8930 if(!pass)
8931 ret = 0x80;
8933 return ret; /* return nozero if this pass should be used */
8936 static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
8938 if(nt->Replace)
8939 DoOutput("%s", nt->Replace);
8940 else
8941 DoOutputDirect(nt->TypeStart, nt->TypeLength);
8942 if(nt->Type != CPP_TYPE_VARARGS)
8944 if(nt->Flags & CPP_FLAG_FUNCTION)
8946 uint32 i;
8947 DoOutput(" ("/*)*/);
8948 for(i = 0; i < nt->FuncPointerDepth; ++i)
8949 DoOutput("*");
8950 DoOutput(/*((*/txt ? "%s)" : ")", txt);
8951 if(nt->FuncArgs)
8952 return DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
8953 else
8954 return DoOutput("()");
8956 else if(txt)
8957 return DoOutput(" %s", txt);
8960 return 1;
8963 static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
8965 strptr a;
8967 a = dest;
8968 if(nt->Replace)
8970 uint32 i;
8971 i = strlen(nt->Replace);
8972 memcpy(a, nt->Replace, i);
8973 a += i;
8975 else
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);
8986 if(nt->FuncArgs)
8988 memcpy(a, nt->FuncArgs, nt->ArgsLength);
8989 a += nt->ArgsLength;
8991 else
8992 a += sprintf(a, "()");
8994 else if(txt)
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)
9005 DoOutput("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");
9021 while(i--)
9022 DoOutput("p");
9024 if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
9026 if(!t->PointerDepth)
9027 DoOutput("t");
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)
9051 if(type)
9052 if((*type && !DoOutput("#if%s\n", type)) ||
9053 !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
9054 (*type && !DoOutput("#endif\n")))
9055 return 0;
9056 return 1;
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);
9064 switch(mode)
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;
9074 default: return 0;
9077 if(HEADER)
9079 DoOutput("\n");
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))
9085 return 0;
9087 if((Flags & FLAG_EXTERNC) &&
9088 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
9089 return 0;
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);
9096 Flags |= FLAG_DONE;
9100 !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
9101 !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
9102 return 0;
9104 if(tagfuncs)
9107 !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
9108 !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
9109 return 0;
9112 if((Flags & FLAG_EXTERNC) &&
9113 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
9114 return 0;
9116 switch(mode)
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;
9125 default: return 0;
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);
9137 if(!clibdata)
9139 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
9142 if(HEADER)
9144 DoOutput("\n");
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))
9150 return 0;
9152 if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
9153 return 0;
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)
9166 data = "_LIB_I";
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"))
9174 return 0;
9176 return 1;
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))
9185 return 0;
9186 if(HEADER)
9188 DoOutput("\n");
9189 DoOutputDirect(HEADER, headersize);
9191 switch(mode)
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 */
9204 switch(mode)
9206 case 1:
9207 if(HEADER)
9209 DoOutput("\n");
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))
9217 return 0;
9218 break;
9219 case 2:
9220 if(!CallFunc(callmode, 0, FuncAsmCode))
9221 return 0;
9222 break;
9225 return 1;
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);
9235 if(HEADER)
9237 DoOutput("\n");
9238 DoOutputDirect(HEADER, headersize);
9241 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
9242 if(Type != 5)
9243 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC ")\n"
9244 "#include <clib/%s_protos.h>\n#endif\n",
9245 ShortBaseNameUpper, ShortBaseName);
9247 if(BaseName)
9249 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
9250 if(Type == 7)
9251 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
9252 "#endif\n");
9253 DoOutput("%s;\n#endif\n", BaseName);
9256 if(Type != 8)
9258 if(Type >= 6)
9260 DoOutput("\n#ifdef " TEXT_GNUC "\n");
9261 if(Type == 10)
9262 DoOutput("#ifndef __cplusplus\n");
9263 DoOutput("#include <inline/%s.h>\n", ShortBaseName);
9264 if(Type == 10)
9265 DoOutput("#endif\n");
9266 if(Type != 7)
9268 if(Type == 9)
9269 DoOutput("#elif defined(" TEXT_VBCC ")\n#if defined(__MORPHOS__) || !defined(__PPC__)\n"
9270 "#include <inline/%s_protos.h>\n#endif\n#else", ShortBaseName);
9271 else
9272 DoOutput("#elif !defined(" TEXT_VBCC ")");
9275 if(Type == 10)
9276 DoOutput("\n#ifndef __PPC__");
9277 if(Type != 7)
9279 strptr str1 = "pragma", str2 = "lib";
9281 switch(Type)
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);
9290 if(Type == 10)
9291 DoOutput("#endif\n");
9292 if(Type >= 6)
9293 DoOutput("#endif\n");
9296 Flags |= FLAG_DONE;
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);
9309 if(HEADER)
9311 DoOutput("\n");
9312 DoOutputDirect(HEADER, headersize);
9315 DoOutput("\n");
9316 PrintIncludes();
9318 if((Flags & FLAG_EXTERNC) &&
9319 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
9320 return 0;
9322 if(!CallFunc(callmode, "/%s */\n", FuncLocText))
9323 return 0;
9325 if((Flags & FLAG_EXTERNC) &&
9326 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
9327 return 0;
9329 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper);
9331 sprintf(filename, "%s_loc.lib", ShortBaseName);
9332 if(!CloseDest(to) || !OpenDest(filename))
9333 return 0;
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);
9344 if(!clibdata)
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);
9353 if(HEADER)
9355 DoOutput("\n");
9356 DoOutputDirect(HEADER, headersize);
9359 DoOutput("\n");
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);
9365 if(!mode)
9367 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
9368 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
9369 "#include <ppcinline/macros.h>\n#endif\n\n");
9370 else
9371 DoOutput("#ifndef __INLINE_MACROS_H\n"
9372 "#include <inline/macros.h>\n#endif\n\n");
9373 Flags |= FLAG_INLINENEW;
9375 else if(mode <= 2)
9377 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
9378 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
9379 "#include <ppcinline/stubs.h>\n#endif\n\n");
9380 else
9381 DoOutput("#ifndef __INLINE_STUB_H\n"
9382 "#include <inline/stubs.h>\n#endif\n\n");
9383 if(mode == 2)
9384 Flags |= FLAG_INLINESTUB;
9386 else if(mode == 3)
9387 Flags2 |= FLAG2_INLINEMAC;
9389 PrintIncludes();
9391 if((Flags & FLAG_EXTERNC) &&
9392 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
9393 return 0;
9395 if(BaseName)
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);
9408 else
9409 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
9410 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
9413 if(mode <= 2)
9415 if(!CallFunc(callmode, "/%s */\n", FuncInline))
9416 return 0;
9418 else if(mode >= 6)
9420 if(mode == 7)
9421 Flags |= FLAG_INLINENEW;
9422 if(!CallFunc(callmode, "/%s */\n", FuncInlineDirect))
9423 return 0;
9425 else
9427 if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
9428 return 0;
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"))
9437 return 0;
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);
9447 if(!clibdata)
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);
9462 if(HEADER)
9464 DoOutput("\n");
9465 DoOutputDirect(HEADER, headersize);
9468 if(BaseName)
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);
9478 DoOutput("\n");
9480 if(!CallFunc(callmode, "/%s */\n", FuncGateStubs))
9481 return 0;
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);
9493 if(HEADER)
9495 DoOutput("\n");
9496 DoOutputDirect(HEADER, headersize);
9499 DoOutput("\n#ifdef __GNUC__\n"
9500 "#ifndef _PPCINLINE__%s_H\n"
9501 "#include <ppcinline/%s.h>\n"
9502 "#endif\n"
9503 "#else\n\n"
9504 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
9505 "#include <ppclib/interface.h>\n"
9506 "#endif\n\n"
9507 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
9508 "#include <gcclib/powerup_protos.h>\n"
9509 "#endif\n\n"
9510 "#ifndef NO_PPCINLINE_STDARG\n"
9511 "#define NO_PPCINLINE_STDARG\n"
9512 "#endif /* SAS-C PPC inlines */\n\n",
9513 ShortBaseNameUpper, ShortBaseName);
9515 if(BaseName)
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))
9522 return 0;
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);
9535 if(HEADER)
9537 DoOutput("\n");
9538 DoOutputDirect(HEADER, headersize);
9541 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
9543 if(BaseName)
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);
9558 Flags |= FLAG_DONE;
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);
9568 if(!clibdata)
9570 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
9573 DoOutput("{\n");
9574 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName);
9576 if(HEADER)
9578 DoOutput("\n");
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))
9599 return 0;
9601 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
9602 if(!CallFunc(TAGMODE_TAGS, 0, FuncFPCTypeTags))
9603 return 0;
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))
9622 return 0;
9624 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
9625 if(!CallFunc(TAGMODE_TAGS,"(%s *)\n", FuncFPCTypeTagsUnit))
9626 return 0;
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)
9707 uint32 i;
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))
9729 return 0;
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 */
9764 data3 = data;
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 */
9795 data2 = data;
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 */
9807 data3 = data;
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 */
9823 elfbufpos = data;
9825 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
9826 return 0;
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))
9833 return 0;
9835 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
9836 return 0;
9838 while((symoffset++)&3)
9840 if(!DoOutputDirect("", 1))
9841 return 0;
9844 return 1;
9847 static uint32 CreateVBCCInline(uint32 mode, uint32 callmode)
9849 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
9851 if(!clibdata)
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");
9861 if(HEADER)
9863 DoOutput("\n");
9864 DoOutputDirect(HEADER, headersize);
9867 DoOutput("\n");
9869 if(!CallFunc(callmode, "/%s */\n", mode ? (mode == 2 ? FuncVBCCMorphInline
9870 : FuncVBCCWOSInline) : FuncVBCCInline))
9871 return 0;
9873 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper);
9876 static uint32 CreateVBCC(uint32 mode, uint32 callmode)
9878 uint32 res = 0;
9880 if(mode != 2 && mode != 3)
9882 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
9884 if(HEADER)
9886 DoOutput("\n");
9887 DoOutputDirect(HEADER, headersize);
9891 switch(mode)
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;
9901 return res;
9904 static uint32 CreateVBCCPUPLib(uint32 callmode)
9906 /* output header */
9907 DoOutput("!<arch>\n");
9909 return CallFunc(callmode, 0, FuncVBCCPUPCode);
9912 static uint32 CreateVBCCMorphCode(uint32 callmode)
9914 /* output header */
9915 DoOutput("!<arch>\n");
9917 return CallFunc(callmode, 0, FuncVBCCMorphCode);
9920 static uint32 CreateEModule(uint32 sorted)
9922 uint32 res = 0, i;
9923 if(sorted)
9924 DoError(ERR_NO_SORTED, 0);
9925 else
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);
9938 return res;
9941 static uint32 CreateProtoRedirect(void)
9943 Flags |= FLAG_DONE;
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;
9953 if(!clibdata)
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 */
9961 LastBias = 0;
9962 CurrentABI = ABI_M68K;
9964 if(IDstring)
9965 DoOutput("==id %s\n", IDstring);
9966 else
9968 time_t t;
9969 struct tm * tim;
9971 t = time(&t);
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,
9976 tim->tm_sec);
9979 if(BaseName)
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);
9986 if(!Includes.First)
9987 DoOutput("==include <exec/types.h>\n");
9989 CallFunc(callmode, "%s\n", FuncSFD);
9991 return DoOutput("==end\n");
9994 static uint32 CreateClib(uint32 callmode)
9996 if(!clibdata)
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);
10006 if(HEADER)
10008 DoOutput("\n");
10009 DoOutputDirect(HEADER, headersize);
10011 else
10013 strptr s = 0;
10014 time_t t;
10015 struct tm * tim;
10017 t = time(&t);
10018 tim = localtime(&t);
10020 if(IDstring)
10022 s = SkipBlanks(IDstring+4);
10023 while(*s && *s != ' ')
10024 ++s;
10025 s=SkipBlanks(s);
10027 if(!s || !*s)
10028 s = "1.0";
10030 if(Flags2 & FLAG2_SYSTEMRELEASE)
10032 DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
10034 else
10036 strptr t;
10038 t = s;
10039 while(*t && *t != ' ')
10040 ++t;
10041 *t = 0;
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");
10054 PrintIncludes();
10056 if((Flags & FLAG_EXTERNC) &&
10057 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10058 return 0;
10060 CallFunc(callmode, "\n/%s */\n\n", FuncClib);
10062 if((Flags & FLAG_EXTERNC) &&
10063 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10064 return 0;
10066 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper);
10069 static uint32 CreateFD(void)
10071 LastBias = 0;
10072 CurrentABI = ABI_M68K;
10074 if(BaseName)
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;
10086 uint8 *data;
10087 uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
10088 if(!(name = GetLibraryName()))
10089 return 0;
10090 btype = GetBaseType();
10092 switch(type)
10094 case 0:
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)))
10103 return 0;
10104 sprintf(filename, "%s_autoopenver.c", ShortBaseName);
10105 if(!CloseDest(to) || !OpenDest(filename))
10106 return 0;
10107 Flags |= FLAG_DONE;
10108 return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
10109 break;
10110 case 1: /* m68k */
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) */
10128 /* SysBase */
10129 if(Flags & FLAG_SMALLDATA)
10131 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
10132 EndPutM16Inc(data, 0); /* place for sysbase reference */
10134 else
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 */
10145 else
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);
10159 else
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 */
10173 else
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;
10185 /* SysBase */
10186 if(Flags & FLAG_SMALLDATA)
10188 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
10189 EndPutM16Inc(data, 0); /* place for sysbase reference */
10191 else
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 */
10202 else
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);
10226 else
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);
10330 break;
10332 return 0;
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;
10343 ap.NumArgs = 1;
10344 ap.Args[0].ArgName = (args ? "args" : "tags");
10345 if(!MakeTagFunction(&ap))
10346 return 0;
10348 if(!ap.TagName)
10349 return 0;
10351 while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
10352 p2 = (struct NameList *) p2->List.Next;
10354 if(!p2)
10355 return 0;
10357 t->Type = (args ? NTP_ARGS : NTP_TAGS);
10358 t->PragName = ap.TagName;
10359 RemoveItem(p, (struct ShortList *) p2);
10361 #ifdef DEBUG_OLD
10362 printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
10363 #endif
10365 return 1;
10368 static void OptimizeFDData(struct PragData *pd)
10370 #ifdef DEBUG_OLD
10371 printf("OptimizeFDData\n");
10372 #endif
10374 while(pd)
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);
10388 if(p.First)
10390 t = (struct NameList *) n.First;
10391 while(p.First && t)
10393 if(!GetName(t, &p, 0))
10395 GetName(t, &p, 1);
10397 if(t->PragName)
10399 struct NameList *t2 = (struct NameList *) t->List.Next;
10400 RemoveItem(&n, (struct ShortList *)t);
10401 AddItem(&pd->Name, (struct ShortList *) t);
10402 t = t2;
10404 else
10405 t = (struct NameList *) t->List.Next;
10407 while(p.First)
10409 if(n.First)
10411 t = (struct NameList *) n.First;
10412 t->PragName = ((struct NameList *)(p.First))->PragName;
10413 RemoveItem(&n, (struct ShortList *) t);
10414 #ifdef DEBUG_OLD
10415 printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
10416 #endif
10417 t->Type = NTP_UNKNOWN;
10419 else
10421 uint32 i;
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;
10429 #ifdef DEBUG_OLD
10430 printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
10431 #endif
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;
10448 uint32 bias;
10450 #ifdef DEBUG_OLD
10451 printf("MakeFD\n");
10452 #endif
10453 bias = pd->Bias;
10455 OptimizeFDData(pd);
10456 #ifdef DEBUG_OLD
10457 printf("MakeFD: after Optimizing\n");
10458 #endif
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));
10468 while(n)
10470 strptr lastpar = "last";
10471 uint32 i;
10473 if(n->Type == NTP_TAGS)
10474 lastpar = "tags";
10475 else if(n->Type == NTP_ARGS)
10476 lastpar = "args";
10478 DoOutput("%s("/*)*/,n->NormName);
10479 if(!pd->NumArgs)
10480 DoOutput(/*(*/")()\n");
10481 else
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)
10492 uint32 i;
10493 for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
10495 DoOutput("*tagcall");
10496 if(n->NormName[i])
10497 DoOutput("-%s", n->NormName+i);
10498 if(n->PragName[i])
10499 DoOutput("+%s", n->PragName+i);
10501 DoOutput("\n");
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;
10526 if(!pl)
10528 #ifdef DEBUG_OLD
10529 printf("AddFDData: New PragList - %s\n", fd->Basename);
10530 #endif
10531 if(!(pl = (struct PragList *) NewItem(pls)))
10532 return 100;
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
10541 <= fd->Bias)
10542 pd = (struct PragData *) pd->List.Next;
10545 if(!pd || pd->Bias != fd->Bias)
10547 struct PragData *pd2;
10548 #ifdef DEBUG_OLD
10549 printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
10550 #endif
10551 if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
10552 return 100;
10553 pd2->Bias = fd->Bias;
10554 memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
10555 pd2->NumArgs = fd->NumArgs;
10556 pd2->Name.Size = sizeof(struct NameList);
10557 if(!pd)
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;
10569 pd = pd2;
10571 else
10573 uint32 i = fd->NumArgs;
10574 if(fd->NumArgs != pd->NumArgs)
10576 #ifdef DEBUG_OLD
10577 printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
10578 #endif
10579 return ERR_DIFFERENT_TO_PREVIOUS;
10582 while(i--)
10584 if(fd->ArgReg[i] != pd->ArgReg[i])
10586 #ifdef DEBUG_OLD
10587 printf("ArgReg %lx != %lx\n", fd->ArgReg[i], pd->ArgReg[i]);
10588 #endif
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;
10599 if(t)
10600 return 0;
10602 if(!(t = (struct NameList *) NewItem(&pd->Name)))
10603 return 100;
10604 if(fd->Mode)
10605 t->PragName = fd->Name;
10606 else
10607 t->NormName = fd->Name;
10608 AddItem(&pd->Name, (struct ShortList *) t);
10609 ++(pd->NumNames);
10610 #ifdef DEBUG_OLD
10611 printf("AddFDData: New NameList - %s\n", fd->Name);
10612 #endif
10613 return 0;
10616 static string GetHexValue(string data)
10618 if(data >= 'a')
10619 return (string) (data - 'a' + 10);
10620 else if(data >= 'A')
10621 return (string) (data - 'A' + 10);
10622 else
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)
10633 uint32 i;
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;
10647 return 0;
10650 static uint32 GetFlibData(struct FDData *fd)
10652 uint32 i;
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)
10663 in.pos -= 2;
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;
10669 return 0;
10672 static uint32 GetAmiData(struct FDData *fd)
10674 strptr endptr;
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));
10680 if(*in.pos != ',')
10681 return ERR_EXPECTED_COMMA;
10682 *endptr = 0;
10683 in.pos = SkipBlanks(++in.pos);
10684 if(!strncmp(in.pos, "0x", 2))
10685 fd->Bias = strtoul(in.pos+2, 0, 16);
10686 else
10687 fd->Bias = strtoul(in.pos, 0, 10);
10689 in.pos = SkipBlanks(SkipName(in.pos));
10690 if(*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;
10696 *endptr = 0;
10697 in.pos = SkipBlanks(++in.pos);
10698 if(*in.pos == /*(*/')')
10699 return 0;
10700 --in.pos;
10701 while(*in.pos != /*(*/')')
10703 uint32 i;
10704 in.pos = SkipBlanks(in.pos+1);
10706 for(i = 0; i < REG_FP0; i++)
10707 if(!strnicmp(RegNames[i], in.pos, 2))
10708 break;
10709 if(i == REG_FP0)
10711 for(; i < MAXREG; i++)
10712 if(!strnicmp(RegNames[i], in.pos, 3))
10713 break;
10716 if(i == MAXREG)
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;
10734 return 0;
10737 static uint32 CreateFDFile(void)
10739 struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
10740 uint32 linenum, err = 0, skip;
10741 strptr ptr, p2;
10743 ptr = p2 = args.infile;
10744 while(*p2)
10746 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
10747 ptr = p2+1;
10748 ++p2;
10750 for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
10752 if(p2 != ptr)
10754 ShortBaseName = ptr;
10755 *p2 = '\0';
10758 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
10760 in.pos = SkipBlanks(in.pos);
10761 if(!strncmp("#pragma", in.pos, 7))
10763 struct FDData fd;
10765 skip = 0;
10766 memset(&fd, 0, sizeof(struct FDData));
10768 in.pos = SkipBlanks(in.pos+7);
10769 if(!strncmp("tagcall", in.pos, 7))
10771 fd.Mode = 1;
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 */
10784 in.pos += 7;
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);
10804 else
10805 skip = 1;
10807 if(err)
10808 DoError(err, linenum);
10809 else if(skip)
10811 else if((err = AddFDData(&pl, &fd)))
10813 if(err != 100)
10814 DoError(err, linenum);
10815 return 0;
10818 while(*(in.pos++)) /* jumps to first char of next line */
10822 if(pl.First)
10824 struct PragList *p = (struct PragList *) pl.First;
10825 if(!p->List.Next)
10827 strptr text, to;
10828 uint32 i;
10830 if(ShortBaseName)
10832 text = ShortBaseName; i = strlen(text);
10834 else
10836 text = p->Basename; i = strlen(text)-4;
10839 to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
10840 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
10841 if(!OpenDest(to))
10842 return 0;
10844 err = MakeFD(p);
10845 CloseDest(to);
10846 if(!err)
10847 return 0;
10849 else
10851 while(p)
10853 strptr to;
10854 uint32 i;
10855 i = strlen(p->Basename) - 4;
10856 to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
10857 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
10858 if(!OpenDest(to))
10859 return 0;
10860 i = MakeFD(p);
10861 CloseDest(to);
10862 if(!i)
10863 return 0;
10864 p = (struct PragList *) p->List.Next;
10869 return 1;
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," \
10880 "NEWSYNTAX/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," \
10885 "VOIDBASE/S"
10887 struct AmiArg
10889 strptr INFILE;
10890 uint32* SPECIAL;
10891 uint32* MODE;
10892 strptr TO;
10893 strptr ABI;
10894 strptr CLIB;
10895 strptr COPYRIGHT;
10896 strptr HEADER;
10897 strptr HUNKNAME;
10898 strptr BASENAME;
10899 strptr LIBTYPE;
10900 strptr LIBNAME;
10901 uint32* PRIORITY;
10902 strptr PREFIX;
10903 strptr SUBPREFIX;
10904 strptr PREMACRO;
10905 uint32 AUTOHEADER;
10906 uint32 COMMENT;
10907 uint32 EXTERNC;
10908 uint32 FPUONLY;
10909 uint32 NEWSYNTAX;
10910 uint32 NOFPU;
10911 uint32 NOPPC;
10912 uint32 NOPPCREGNAME;
10913 uint32 NOSYMBOL;
10914 uint32 ONLYCNAMES;
10915 uint32 OPT040;
10916 uint32 PPCONLY;
10917 uint32 PRIVATE;
10918 uint32 SECTION;
10919 uint32 SMALLCODE;
10920 uint32 SMALLDATA;
10921 uint32 SMALLTYPES;
10922 uint32 SORTED;
10923 uint32 SYSTEMRELEASE;
10924 uint32 USESYSCALL;
10925 uint32 VOIDBASE;
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"
11002 " 110 - FD file\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"
11040 "Switches:\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);
11067 exit(20);
11070 /* initializes the arguments and starts argument parsing */
11071 static void GetArgs(int argc, char **argv)
11073 struct RDArgs *rda;
11074 struct AmiArg amiargs;
11075 int res = 0;
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))
11083 int l;
11084 strptr d, s;
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)))
11101 res = 1;
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;
11179 if(amiargs.MODE)
11180 args.mode = *amiargs.MODE;
11181 if(amiargs.PRIORITY)
11182 priority = *amiargs.PRIORITY;
11184 FreeArgs(rda);
11186 else
11187 PrintFault(IoErr(), 0);
11188 FreeDosObject(DOS_RDARGS, rda);
11191 if(!res)
11192 /* printhelp(); */
11193 exit(20);
11196 #else
11197 static const strptr helptext =
11198 " -h,--help\n"
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"
11215 "\n"
11216 "Switches:\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"
11238 "\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"
11311 " 110 - FD file\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);
11341 exit(20);
11344 struct ArgData
11346 strptr ArgName;
11347 uint8 ArgChar;
11348 uint8 ArgNameLen;
11349 uint8 ArgNum;
11352 enum ArgNums {
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;
11409 strptr a, b;
11410 const struct ArgData *ad;
11412 if((*argv)[0] != '-' || !(*argv)[1])
11413 return 0;
11415 ad = argtexts;
11416 while(ad->ArgName)
11418 if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
11419 break;
11420 ++ad;
11422 if(!ad->ArgName)
11423 return 0;
11424 switch(ad->ArgNum)
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 = "";
11448 default:
11449 a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
11450 if(!(*a))
11452 if(argc > 1) { a = argv[1]; numentries = 2; }
11453 else { a = 0; numentries = 0;}
11455 else if(*a == '=')
11456 ++a;
11457 if(a)
11459 if(*a == '\"')
11461 l = strlen(++a);
11462 if(a[l-1] == '\"')
11463 a[--l] = 0; /* remove second " */
11465 switch(ad->ArgNum)
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;
11480 case ARG_SPECIAL:
11481 args.special = strtoul(a, &b, 10);
11482 if(*b)
11483 numentries = 0;
11484 break;
11485 case ARG_PRIORITY:
11486 priority = strtoul(a, &b, 10);
11487 if(*b)
11488 numentries = 0;
11489 break;
11490 case ARG_MODE:
11491 args.mode = strtoul(a, &b, 10);
11492 if(*b || args.mode < 1 || args.mode > 3)
11493 numentries = 0;
11494 break;
11498 return numentries;
11501 /* initializes the arguments and starts argument parsing */
11502 static void GetArgs(int argc, char **argv)
11504 int res = 1;
11505 int i = 1, j;
11507 while(i < argc && res)
11509 if((j = ParseArgEntry(argc-i, argv+i)) < 1)
11510 res = 0;
11511 else
11512 i += j;
11514 if(!res || !args.infile)
11515 printhelp();
11518 #endif
11520 static strptr mygetfile(strptr name, size_t *len)
11522 strptr ptr = 0;
11523 FILE *infile;
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)))
11534 ptr[*len] = 0;
11535 #ifdef DEBUG_OLD
11536 printf("mygetfile: '%s' size %ld\n", name, *len);
11537 #endif
11538 if(fread(ptr, *len, 1, infile) != 1)
11539 ptr = 0;
11543 fclose(infile);
11545 return ptr;
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;
11552 strptr clibbuf;
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);
11564 exit(20);
11566 else
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);
11575 exit(20);
11577 else
11578 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
11580 else
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)
11596 CreateFDFile();
11597 exit(0);
11600 if(!GetTypes())
11601 exit(20);
11603 if(!ScanFDFile())
11604 exit(20);
11606 if(args.clib)
11608 if(Flags2 & FLAG2_SFDMODE)
11609 DoError(ERR_SFD_AND_CLIB, 0);
11610 else
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);
11616 exit(20);
11618 ScanClibFile(clibbuf, clibbuf+clibsize);
11622 if(!MakeShortBaseName())
11624 DoError(ERR_MISSING_SHORTBASENAME, 0);
11625 exit(20);
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);
11633 break;
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);
11637 break;
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);
11640 break;
11641 case 79:
11642 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
11643 break;
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)
11653 case 0: break;
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);
11721 else
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:
11732 case 47:
11733 mode = MODUS_INLINE+args.special-40;
11734 sprintf(filename, "%s.h", ShortBaseName); break;
11735 case 48:
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;
11752 break;
11753 case 53:
11754 sprintf(filename, "%s_pragmas.h", ShortBaseName);
11755 mode = MODUS_SASPOWER; break;
11756 case 54:
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);
11769 else
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;
11784 case 73: case 74:
11785 mode = MODUS_VBCC+args.special-71;
11786 sprintf(filename, "%s.lib", ShortBaseName); break;
11787 case 76:
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)
11818 case 90:
11819 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
11820 mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
11821 break;
11822 case 91:
11823 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
11824 mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
11825 break;
11826 case 92:
11827 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
11828 mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
11829 break;
11830 case 93:
11831 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
11832 mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
11833 break;
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);
11843 break;
11844 case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
11845 Flags |= FLAG_ABIV4;
11846 sprintf(filename, "%s_lib.i", ShortBaseName);
11847 break;
11848 case 103: mode = MODUS_LVOLIB;
11849 sprintf(filename, "%slvo.o", ShortBaseName);
11850 break;
11851 case 107: mode = MODUS_LVOLIB;
11852 Flags |= FLAG_ABIV4;
11853 sprintf(filename, "%slvo.o", ShortBaseName);
11854 break;
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);
11877 break;
11878 case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
11879 sprintf(filename, "%s_protos.h", ShortBaseName);
11880 break;
11881 case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
11882 sprintf(filename, "%s_lib.sfd", ShortBaseName);
11883 if(callmode == 1)
11885 callmode = 2;
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);
11894 break;
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);
11907 break;
11908 case 121: mode = MODUS_GENAUTO+(args.special-120);
11909 sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
11910 break;
11911 case 122: mode = MODUS_VBCCMORPHINLINE;
11912 PPCRegPrefix = ""; /* no "r" allowed */
11913 sprintf(filename, "%s_protos.h", ShortBaseName);
11914 break;
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;
11927 break;
11928 case 133: mode = MODUS_INLINE+2;
11929 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
11930 Flags2 |= FLAG2_DIRECTVARARGS;
11931 break;
11932 case 134: mode = MODUS_GATESTUBS;
11933 sprintf(filename, "%s_gates.h", ShortBaseName);
11934 break;
11935 case 135: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB;
11936 sprintf(filename, "%s_gates.h", ShortBaseName);
11937 break;
11938 case 136: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB;
11939 sprintf(filename, "%s_gates.h", ShortBaseName);
11940 break;
11941 case 137: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB|FLAG2_REGLIB;
11942 sprintf(filename, "%s_gates.h", ShortBaseName);
11943 break;
11944 case 138: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB|FLAG2_REGLIB;
11945 sprintf(filename, "%s_gates.h", ShortBaseName);
11946 break;
11947 default: mode = MODUS_ERROR; break;
11951 if(Flags & FLAG_SORTED)
11952 SortFDList();
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)
11961 printhelp();
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);
11969 exit(20);
11972 if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
11974 HEADER = mygetfile(args.header, &headersize);
11975 args.header = 0;
11978 if(!(Flags & FLAG_SINGLEFILE))
11980 if(!OpenDest(filename))
11981 exit(20);
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)
12006 mode = CreateFD();
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);
12050 if(!mode)
12052 DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
12053 exit(20);
12055 free(tempbuf);
12058 return 0;