Corrected capitalisation.
[AROS.git] / tools / fd2pragma / fd2pragma.c
blob8b61b005ca46d265cdfcf31e6f214e7e62c6964e
1 /* $Id$ */
2 static const char version[] =
3 "$VER: fd2pragma 2.194 (02.01.2011) by Dirk Stoecker <software@dstoecker.de>";
5 /* There are four defines, which alter the result which is produced after
6 compiling this piece of code. */
8 /* turns on usage of Amiga ReadArgs-system (requires <proto/dos.h> include) */
9 /* #define FD2PRAGMA_READARGS */
11 /* enables Amiga style file name (only relevant for fd2pragma.types file) */
12 /* #define FD2PRAGMA_AMIGA */
14 /* debugging output */
15 /* #define DEBUG */
17 /* more debugging output */
18 /* #define DEBUG_OLD */
20 /* Programmheader
22 Name: fd2pragma
23 Author: SDI
24 Distribution: PD
25 Description: creates pragmas files, lvo files, ...
26 Compileropts: -
27 Linkeropts: -
29 1.2 : added pragmas for the Dice compiler. Available via switch "Dice".
30 added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
31 turn on the default (except that Maxon expects pragma files to be
32 called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
33 Dice, except that SAS supports the pragma tagcall.
34 2.0 : Added support for tag functions. See the docs for details.
35 Author until this version:
36 Jochen Wiedmann
37 Am Eisteich 9
38 72555 Metzingen (Germany)
39 Tel. 07123 / 14881
40 2.1 19.08.96 : now made by SDI, added correct __MAXON__ support and
41 support for StormC++, added auto recognition of tagcall functions
42 changed the CLI interface completely
43 2.2 21.08.96 : fixed a lot of errors, added debug code
44 2.3 22.08.96 : little changes
45 2.4 24.08.96 : added proto-file creation
46 2.5 25.08.96 : added syscall and fix for functions ending in ...DMA
47 2.6 26.08.96 : fixed some errors, added CLIB parameter (used later for
48 CSTUBS)
49 2.7 01.09.96 : added correct Storm definition, added CLIB scan
50 2.8 02.09.96 : added assembler stub functions, added first ASM-stub code
51 2.9 04.09.96 : added Comment-Support
52 2.10 05.09.96 : changed CSTUB creation a bit
53 2.11 07.09.96 : speeded up output, reduced number of strndup calls
54 2.12 26.09.96 : pressing CTRL-C in early startup brought a wrong error
55 message - fixed
56 2.13 30.09.96 : made RegNames field to RegNames string - shorter Exe-file
57 2.14 01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
58 2.15 13.10.96 : corrected an error text
59 2.16 14.10.96 : added correct comment support and PRIVATE option
60 2.17 19.10.96 : now Maxon-compiled in Small data mode
61 2.18 22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
62 the texts, again SAS compiled
63 2.19 26.10.96 : added option to create FD files out of pragma files,
64 reworked a lot in the source
65 2.20 27.10.96 : fixed errors of previous version
66 2.21 28.10.96 : fixed error in CLIB scan
67 2.22 27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
68 bug in Tag function stubs
69 2.23 06.12.96 : lib and stub creation still was wrong
70 2.24 31.12.96 : formed stub libs matching C++ file names, corrected CLIB
71 scan errors
72 2.25 04.01.97 : added HEADER option (I was asked for)
73 2.26 05.01.97 : added HEADER scan (in old file) and auto inserting
74 2.27 10.01.97 : stub functions missed register saving, outfuncs skip now,
75 when error occured (makes lots of error checking obsolete)
76 2.28 11.01.97 : forgot to add offset made by register saving
77 2.29 18.01.97 : now libtags and amitags defines only, when at least 1
78 tagfunc
79 2.30 13.02.97 : added local library base functions, rearranged SPECIAL
80 options, fixed some bugs
81 2.31 15.02.97 : corrected bugs inserted in previous version
82 2.32 16.02.97 : and again bug fixes, still didn't work
83 2.33 18.02.97 : corrected texts, added SPECIAL 28
84 2.34 25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
85 2.35 26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
86 2.36 29.03.97 : corrected *tagcall scan a bit
87 2.37 20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
88 2.38 01.07.97 : fixed ##end handling
89 2.39 20.07.97 : added better proto file (__GNUC__ inline and pragma call),
90 removed C++ comments
91 2.40 24.11.97 : added new basenames to the list (devices and resources),
92 added tag-exception name checking (dos, utility libraries)
93 2.41 27.11.97 : fixed little bug with private functions, CSTUBS now
94 special option and no longer commandline arg, SPECIAL 10-15 got
95 numbers 11-16 (Sorry)
96 2.42 28.11.97 : Added two new warnings for CLIB
97 2.43 12.12.97 : faster FD file scan, one new warning
98 2.44 19.12.97 : fixed MODE settings for SPECIAL 15,16
99 2.45 30.01.98 : added function recognition, included inline creation,
100 inline stuff is based on fd2inline 1.11 (incomplete)
101 2.46 31.01.98 : continued inline stuff, fixed clib functions
102 2.47 05.02.98 : completed inline stuff, added alias names for dos functions
103 2.48 06.02.98 : changed Func interface - flags instead of tagmode
104 2.49 10.02.98 : fixed inline generation a bit, added SORTED argument,
105 RegNames got strings again
106 2.50 11.02.98 : bug-fixes, still did not work completely, hopefully got
107 all now
108 2.51 12.02.98 : and bug-fixes again :-(
109 2.52 15.02.98 : changed sorting order of arguments
110 2.53 20.02.98 : some code style changes
111 2.54 25.02.98 : added SMALLDATA model, removed 5 global variables (better
112 style), stub libs use MOVEM when possible, own MemRemember function
113 2.55 26.02.98 : bug fixes
114 2.56 15.03.98 : added FPU support
115 2.57 17.03.98 : added NOFPU keyword
116 2.58 19.03.98 : little fixes
117 2.59 20.03.98 : added enum and external type definitions defines
118 2.60 22.03.98 : added external types file scan
119 2.61 23.03.98 : fixed SAS flibcall, added FPU stubs
120 2.62 28.03.98 : bug fix with NOFPU and new option FPUONLY, total new clib
121 handling
122 2.63 29.03.98 : really lots of bug fixes, There are so much problems.
123 A better definition format would have been wonderful.
124 2.64 05.04.98 : bug fixes
125 2.65 07.04.98 : fixed Enforcer hit
126 2.66 08.04.98 : bug fix with type detection
127 2.67 20.04.98 : added GNU-only stuff
128 2.68 28.04.98 : SPECIAL 8 defaults to SAS-C names now
129 2.69 25.05.98 : added PowerUP stuff support
130 2.70 28.05.98 : added SAS PowerUP stuff, fixed error with function
131 detection in CLIB scan
132 2.71 30.05.98 : added PowerUP Inlines
133 2.72 12.06.98 : sorting turns of COMMENT now
134 2.73 05.07.98 : added first FPC stuff, added HEADER to PowerUP stuff,
135 added PASCAL header scan
136 2.74 06.07.98 : finished FPC stuff
137 2.75 07.07.98 : bug fixes for FPC stuff
138 2.76 09.07.98 : style changes for FPC stuff, bug fixes
139 2.77 11.07.98 : hopefully last FPC bug removed
140 2.78 23.07.98 : style changes and bug fixes for FPC stuff, more comments
141 2.79 10.08.98 : bug fix, when TO was used with a directory, clib got
142 wrong path if it was a relative path description
143 2.80 16.08.98 : now prints better error when filopen failed
144 2.81 26.10.98 : added BMAP files for BASIC, CODE needs to use large mode
145 now :-(
146 2.82 28.10.98 : optimizations and bug fixes
147 2.83 31.12.98 : fixed powerup stuff a bit
148 2.84 05.01.99 : fixed bug in Lib creation, when Dx/Ax and FPx were mixed
149 2.85 06.01.99 : added recognition of names ending in MESA, added notagcall
150 comment support, void functions no longer can be tagcall
151 2.86 10.01.99 : added BGUI special funcs, fixed bug in SPECIAL 42 code
152 2.87 12.01.99 : added asm-text (SECTION), moved 12-17 to 13-18
153 2.88 17.01.99 : better type detection, added some more basenames, some
154 little bug fixes, new makefile reduces file size a lot
155 2.89 17.07.99 : added union support
156 2.90 12.11.99 : added new motorola syntax, opt040 and vbcc inlines
157 2.91 13.11.99 : Now supports changes in OS3.5 includes, why the hell must
158 such changes be? I thought new includes will bring cleanup and not
159 cleandown. And the reported bugs are still unfixed, but there are
160 new ones!, bug-fixes
161 2.92 14.11.99 : added PPC-WOS library text and code, FD-creation moved from
162 80 to 200 (now finally! - there should be enough free number space),
163 added VBCC-PUP text generation
164 2.93 15.11.99 : added CheckError function, moved DisplayInfoHandle to
165 types definition file
166 2.94 16.11.99 : added first VBCC-PowerUP-Lib production stuff, only ELF
167 tables missing
168 2.95 17.11.99 : finished PowerUP stub stuff, startet PPC-ABI stuff
169 2.96 18.11.99 : little bug fixes
170 2.97 19.11.99 : added SECTION keyword, moved 11-18 to 12-17, ahh 3 releases
171 more and we get an anniversary, my first program using third revision
172 digit :-)
173 2.98 20.11.99 : added VBCC-WOS-Code for PPC libs
174 2.99 25.11.99 : bug fixes
175 2.100 17.02.00 : fixed bug for VBCC inlines
176 2.101 29.02.00 : fixed name for VBCC inlines
177 2.102 13.03.00 : added new style GCC inlines
178 2.103 21.03.00 : bug fixed, SPECIAL 35 has VBCC stuff now.
179 2.104 25.03.00 : fixed path lock problem
180 2.105 11.04.00 : library HUNK_UNIT get functionname now
181 2.106 13.07.00 : added E-Modules
182 2.107 06.08.00 : removed VBCC inline support from 35 and moved it to 38, 35
183 does now skip pragma/inline files for VBCC
184 2.108 18.08.00 : added new ppc modification proto file 39, modified protos a
185 bit, support for register types and function pointer args, int got
186 internally type CPP_TYPE_INT
187 2.109 19.08.00 : bug fixes
188 2.110 24.08.00 : fixed SPECIAL 7,40-44, added SPECIAL 80-83
189 2.111 31.08.00 : bug fixes
190 2.112 03.09.00 : FD2Pragma.types scanner no longer accepts multi-word types.
191 2.113 29.12.00 : added extern keword support for return types.
192 2.114 07.01.01 : made FD2Pragma partly portable, removed 4 direct pragma
193 arguments
194 2.115 14.01.01 : lots of bug fixes, renamed from FD2Pragma to fd2pragma
195 2.116 28.01.01 : added internal types, SPECIAL 90, NOCPPNAMES and bug fixes,
196 VBCC inlines fix for data in A-regs
197 2.117 04.02.01 : changed NOCPPNAMES to ONLYCNAMES, added HUNKNAME, LocCode is
198 portable, added BASENAME, added VBCCWOSInlines
199 2.118 07.02.01 : added destination file printout, LIBTYPE, fixes VBCC-PUP-Code
200 2.119 11.02.01 : bug fixes
201 2.120 17.02.01 : added NOPPCREGNAME, bug fixes
202 2.121 04.03.01 : added MorphOS text
203 2.122 11.03.01 : little bug fixes
204 2.123 03.04.01 : now uses EXT_DEXT16 instead of EXT_REF16 also for 68k files
205 2.124 08.04.01 : bug fixes, added MorphOS binary mode, finally full portable
206 2.125 28.04.01 : added LVO's for PPC, started support for SFD format
207 2.126 29.05.01 : fixed PPC LVO's, removed STORMFD Option (auto detection),
208 now handles up to 5 alias names, finished SFD format read, added FD
209 creation, added keyword checks for argument names, lots of optimizations
210 and fixes, which came in hand with SFD inclusion.
211 Thanks Olaf Barthel for making the SFD stuff possible.
212 2.127 30.04.01 : private comments are skipped now, finished SFD production,
213 fixed bugs, removed SPECIAL 8 redirect (is replaced by 80-83)
214 2.128 01.05.01 : bug fixes
215 2.129 03.06.01 : included support for files previous made by vbcc genauto tool
216 2.130 04.06.01 : bug fixes in genauto stuff
217 2.131 11.06.01 : newer types handle cia now correct
218 2.132 27.06.01 : fixed crash caused by illegal interpretation of ANSI-C :-)
219 2.133 28.06.01 : added VOIDBASE argument
220 2.134 01.07.01 : added MorphOS types, fixed PowerUp stuff
221 2.135 28.07.01 : added VBCC inline varargs support
222 2.136 30.07.01 : fixed VBCC inline varargs
223 2.137 18.11.01 : little bug-fix
224 2.138 30.11.01 : fixed CLIB scanning (now a preparser cleans the file a lot)
225 2.139 13.12.01 : fixed ==libname scan and xvsBase
226 2.140 21.12.01 : fixed some uint32 in created files, which have been wrongly
227 introduced in 2.1xx versions when making tool portable
228 2.141 04.01.02 : fixed problem with multiple pointer function args like in
229 "void (**func)(void)"
230 2.142 07.01.02 : started new direct inline types 46 and 47.
231 2.143 08.01.02 : Fixed warnings, bugs, card.resouce entry and added
232 ==copyright directive
233 2.144 09.01.02 : Fixed MUI varargs inlines
234 2.145 03.03.02 : Some bug fixes
235 2.146 20.05.02 : one little bug fix, added support for missing empty () in
236 defective FD files
237 2.147 01.05.02 : now continues when detecting no fd-arg name
238 2.148 09.06.02 : fixed problem with MorphOS stubs, added AUTOHEADER keyword,
239 added auto type defaults to int, fixed bug with STACK type
240 2.149 24.06.02 : fixed lots of problems found when converting amissl includes
241 2.150 08.08.02 : fixed inline files a bit
242 2.151 31.08.02 : fixed SPECIAL 46 files (error when no args, but return value)
243 2.152 01.09.02 : bug-fix with SPECIAL 47
244 2.153 11.09.02 : modified SPECIAL 46 varargs on request of Sebastian Bauer
245 and Olaf Barthel
246 2.154 03.10.02 : added VBCC MorphOS inlines (SPECIAL 122). Thanks Frank Wille
247 for design help.
248 2.155 04.10.02 : optimized VBCC MorphOS text (SPECIAL 93), fixed VBCC MorphOS
249 inlines
250 2.156 06.10.02 : added warning about obsolete types, fixed VBCC MorphOS Code
251 (SPECIAL 78)
252 2.157 12.10.02 : Fixed CLIB scan problem
253 2.158 19.10.02 : added CLIB define in SPECIAL 46
254 2.159 16.11.02 : bugfix with SPECIAL 46 varargs redefine
255 2.160 04.12.02 : fixed bug in MorphOS-vbcc code
256 2.161 15.12.02 : now no longer includes clib files for GCC, the GCC inlines
257 include the needed include lines directly
258 2.162 26.01.03 : bug fixes, added updated fpc code made by Nils Sjöholm (it
259 is not that complicated to do fixes yourself, fd2pragma's inner
260 structure is really easy)
261 2.163 28.01.03 : little fixes
262 2.164 15.02.03 : fixed DirectInline for GCC mode, changed FPC layout
263 2.165 04.01.04 : fixed VBCC TAG inlines (SPECIAL 70), added modified MorphOS
264 FD file types, fixed GCC direct inlines for GCC 3
265 2.166 06.01.04 : added first set of OS4 filetypes
266 2.167 09.01.04 : more OS4 stuff, added library name comment scanning for SFD
267 2.168 19.01.04 : some fixes (a lot of thanks to Frank Wille)
268 2.169 22.01.04 : completed OS4 stuff
269 2.170 28.01.04 : some more VBCC-MOS things
270 2.171 26.02.04 : finished VBCC-MOS text
271 2.172 09.05.04 : (phx) fixed clib-parsing problem with splitted function
272 name and arguments over two lines, more flexible "base,sysv"
273 recognition for MorphOS, never use "Device *" pointer in a proto file
274 - should be "Library *"
275 2.173 10.05.04 : fixed MOS-base,sysv to allow autodetected Tag-Functions
276 2.174 23.05.04 : some fixes for MorphOS and VBCC
277 2.175 11.07.04 : (phx) has to recognize and skip 'extern "C" {', as a
278 result of my modifications in 2.172.
279 2.176 21.09.04 : added new MorphOS VBCC inlines and some other OS4 fixes
280 2.177 23.09.04 : minor bugfix
281 2.178 09.10.04 : (phx) vbcc: use __linearvarargs instead of __aos4varargs
282 2.179 09.11.04 : (phx) make it compile natively under AmigaOS 4.x
283 2.180 07.12.04 : (phx) don't create vbcc inlines for MUI_NewObject &
284 PM_MakeItem - otherwise the preprocessor gets confused
285 2.181 20.12.04 : made test for MUI_NewObject and PM_MakeItem based on a field
286 containing the names - allows easier expansion
287 2.182 16.01.05 : (phx) experimental MorphOS "(sysv)" support, which doesn't
288 need a base-register passed as first argument
289 2.183 24.01.05 : added support for long long types, nevertheless files using
290 that will not produce correct results for now
291 2.184 07.02.05 : (phx) Fixed FuncVBCCWOSCode() (special 73) to read the
292 function ptr from (bias-2) instead from (bias) for PPC0/2-ABI.
293 Picasso96 support.
294 2.185 08.02.05 : (phx) Special 38 (proto with vbcc inline) always generates
295 an inline-include now, and is no longer restricted to MorphOS & 68k.
296 Special Warp3DPPC support.
297 Marked some powerpc.library functions, which were erroneously
298 detected as tag functions.
299 2.186 17.02.05 : fixed PPC0-mode VBCC WOS stubs
300 2.187 26.03.05 : (phx) "(sysv,r12base)" in MorphOS FD-files is supported.
301 I made it identical to (sysv), which both load the library base
302 to r12 (correct in (sysv,r12base) mode and can't hurt in (sysv) mode).
303 Allow "(void)" instead of "()" as parameter list.
304 Function-pointer types can extend over multiple lines now (does
305 this make sense for other types too?).
306 New SDL-types: FPSmanager, Mix_Chunk, Mix_Music, Mix_MusicType,
307 Mix_EffectFunc_t, Mix_EffectDone_t, Mix_Fading, IPaddress,
308 TCPsocket, UDPpacket, UDPsocket, SDLNet_SocketSet,
309 SDLNet_GenericSocket, TTF_Font.
310 Put some of SDL-gfx functions ("...RGBA()") in the exceptions list.
311 2.188 30.03.05 : (phx) Put NewObject() into the NoInline-list.
312 2.189 21.05.05 : (phx) Always include emul/emulregs.h in vbcc/MOS inlines.
313 2.190 23.08.05 : (phx) Use ".file <name>.o" in assembler sources, HUNK_NAME
314 and ELF ST_FILE symbols. It was "<name>.s" before, which is wrong.
315 2.191 01.11.05 : (phx) Rewrote FuncVBCCWOSInline() based on the MOSInline-
316 function, to be able to handle varargs functions correctly.
317 Also fixed WOS-text and -code generation for PPC0-ABI.
318 2.192 06.01.10 : (phx) Do vbcc MorphOS OS-calls with BCTRL instead of BLRL
319 to avoid messing up the LR-stack of more recent PowerPCs (G4+).
320 2.193 18.09.10 : (phx) GLContext type (tinygl).
321 2.194 03.01.11 : (mazze) Fix for building it on CYGWIN.
322 Added AROS support in the proto file.
325 /* A short note, how fd2pragma works.
326 Working mode for SPECIAL 200 is a bit different!
327 The main function parses arguments. Switches are converted into FLAG_XXX
328 values and stored in global "Flags" or "Flags2" variable. SPECIAL numbers
329 are parsed and are used to call a CreateXXX function, with its interface
330 depending on the need of arguments (Some have 2, some none, ...). Before
331 SPECIAL arguments are parsed, fd2pragma loads (S)FD file and scans it using
332 Scan(S)FDFile(). If SORTED is specified, the list gets sorted nearly directly
333 afterwards. IF CLIB argument is given, the clib file is scanned after FD file
334 and a clib list is created. Now SPECIAL is parsed and mode is set to any of
335 the MODUS_XXX values. Also the destination file name is created if not given.
336 The destination file is opened now.
338 The mode variable is used to determine the correct CreateXXX function,
339 which is called afterwards. This function produces file headers and stuff
340 like that and calls CallFunc to process each FD entry.
342 CallFunc gets 3 arguments. First the workmode (TAG, NORMAL, BOTH).
343 Second the comment method (for C it is "/%s *\x2F\n", for ASM it is "\n%s",
344 no comment is reached with 0 argument). The last is most important. It is the
345 function pointer to a function creating the entries. These functions have
346 always the same interface and are called through CallFunc only! They create
347 an entry for the specified function (e.g. FD entry). Parsing special
348 functions, adding comments, checking for tag-functions, ... is done by
349 CallFunc. It is no problem to call CallFunc multiple with different function
350 pointers (as is done for SPECIAL 6 pragmas).
351 This is also the method if information abount the type or number of functions
352 is needed somewhere in the begin of the output file. A special function to
353 collect this data needs to be started before doing real output. Althought I
354 do not like it much, global variables or flags can be used to store that
355 information.
357 The functions can use DoOutput to output texts in printf style or
358 DoOutputDirect to output all data in fwrite style. Buffering is done
359 automatically.
361 fd2pragma has its own memory managment. All memory must be allocated using
362 AllocListMem and is freed automatically. This is especially useful for
363 DupString function, which is used in FD, SFD and CLIB scanner.
365 Normally this source-file is to big and should be splitted into different
366 files compiled alone and linked together. :-) It takes about 20 minutes to
367 compile it on my Amiga system with optimizations turned on.
369 There are lots of different input and output types and some combinations
370 are really useless or wrong. fd2pragma has the mechanisms to catch these
371 cases properly, but not all cases are really checked, as there are too many
372 of them and each new input type increases the number of combinations.
373 Also not all useful combinations me be handled correctly. If you find a
374 case which really matters please inform me. All the others require the
375 users to use their brains :-)
378 #include <ctype.h>
379 #include <stdio.h>
380 #include <stdlib.h>
381 #include <string.h>
382 #include <stdarg.h>
383 #include <time.h>
385 /* These are the only allowed variable types of all related programs! */
386 #ifdef __amigaos4__
387 #include <exec/types.h>
388 #else
389 typedef signed char int8; /* signed 8 bit */
390 typedef unsigned char uint8; /* unsigned 8 bit */
391 typedef signed short int int16; /* signed 16 bit */
392 typedef unsigned short int uint16; /* unsigned 16 bit */
393 typedef signed long int int32; /* signed 32 bit */
394 typedef unsigned long int uint32; /* unsigned 32 bit */
395 #endif
396 typedef float fl32; /* 32 bit IEEE float value */
397 typedef double fl64; /* 64 bit IEEE double value */
398 typedef char string; /* the string datatype [e.g. one character of string!] */
399 typedef char * strptr; /* and an string pointer */
401 #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
402 (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
403 #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
404 #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
405 (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
406 #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
408 #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
409 #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
410 #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
411 #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
413 #define TEXT_SAS "__SASC" /* verified */
414 #define TEXT_SAS_60 "__SASC_60" /* verified */
415 #define TEXT_MAXON "__MAXON__" /* verified */
416 #define TEXT_STORM "__STORM__" /* verified */
417 #define TEXT_DICE "_DCC" /* in 2.0 code */
418 #define TEXT_AZTEC "AZTEC_C" /* verified */
419 #define TEXT_GNUC "__GNUC__" /* verified */
420 #define TEXT_VBCC "__VBCC__" /* verified */
422 #define TEMPSIZE 20480
424 #define FLAG_EXTERNC (1<< 0) /* add externc statements */
425 #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
426 #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
427 #define FLAG_PRIVATE (1<< 3) /* also use private functions */
428 #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
429 #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
430 #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
431 #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
432 #define FLAG_DONE (1<< 8) /* destination file is not empty */
433 #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
434 #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
435 #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
436 #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
437 #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
438 #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
439 #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
440 #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
441 #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
442 #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
443 #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
444 #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
445 #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
446 #define FLAG_STORMGCC (1<<22) /* special workaround for StormGCC */
447 #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
448 #define FLAG_MORPHOS (1<<24) /* create MorphOS files */
449 #define FLAG_SORTED (1<<25) /* sort the functions by name */
450 #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
451 #define FLAG_SINGLEFILE (1<<27) /* create single files */
452 #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
453 #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
454 #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
455 #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
457 #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
458 #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
459 #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
460 #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
461 #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
462 #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
463 #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
464 #define FLAG2_VOIDBASE (1<< 7) /* library base should be of type "void *" */
465 #define FLAG2_INLINEMAC (1<< 8) /* use inline macro instead of function */
466 #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
467 #define FLAG2_PRELIB (1<<10) /* MorphOS gate PRELIB flag */
468 #define FLAG2_POSTLIB (1<<11) /* MorphOS gate POSTLIB flag */
469 #define FLAG2_REGLIB (1<<12) /* MorphOS gate REGLIB flag */
470 #define FLAG2_OLDVBCC (1<<13) /* old VBCC style */
471 #define FLAG2_SMALLTYPES (1<<14) /* allow small data types */
472 #define FLAG2_AUTOHEADER (1<<15) /* creates auto generated header */
473 #define FLAG2_LIBNAMECOM (1<<16) /* libname was specified in SFD comment */
474 #define FLAG2_OS4M68KCSTUB (1<<17) /* OS4 M68K stub needs C */
475 #define FLAG2_SHORTPPCVBCCINLINE (1<<18) /* shorter PPC inline using argument */
477 #define FUNCFLAG_NORMAL (1<<0) /* normal function */
478 #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
479 #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
480 #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
482 /* Different modes the main program uses, one for each different file
483 type (except for those done with one function and flag settings). */
484 #define MODUS_STUBTEXT 1
485 #define MODUS_STUBCODE 2
486 #define MODUS_LOCALDATA 3
487 #define MODUS_PRAGMA 4
488 #define MODUS_CSTUB 5
489 #define MODUS_SASPOWER 6
490 #define MODUS_PROTOPOWER 7
491 #define MODUS_BMAP 8
492 #define MODUS_PASCAL 9
493 #define MODUS_VBCCINLINE 10
494 #define MODUS_VBCCPUPLIB 11
495 #define MODUS_LVOLIB 12
496 #define MODUS_EMODULE 13
497 #define MODUS_REDIRECT 14
498 #define MODUS_ASMTEXTSF 15
499 #define MODUS_VBCCPUPTEXTSF 16
500 #define MODUS_VBCCWOSTEXTSF 17
501 #define MODUS_VBCCWOSINLINE 18
502 #define MODUS_VBCCMORPHTEXTSF 19
503 #define MODUS_VBCCMORPHCODE 20
504 #define MODUS_LVOLIBPPC 21
505 #define MODUS_FD 22
506 #define MODUS_CLIB 23
507 #define MODUS_SFD 24
508 #define MODUS_GATESTUBS 25
509 #define MODUS_VBCCMORPHINLINE 26
510 #define MODUS_XML 27
511 #define MODUS_OS4_PPCSTUBS 28
512 #define MODUS_OS4_68KSTUBS 29
513 #define MODUS_LVO 50 /* and 51 and 52 and 53 */
514 #define MODUS_PROTO 60 /* and 61 to 69 */
515 /* new protos start with 90, but are added to MODUS_PROTO ! */
516 #define MODUS_INLINE 80 /* and 81 to 86 */
517 #define MODUS_VBCC 90 /* and 91 to 94 */
518 #define MODUS_LVOPPC 100 /* and 101 */
519 #define MODUS_GENAUTO 110 /* and 111 to 113 */
520 #define MODUS_ERROR 200
522 enum ABI {ABI_M68K, ABI_PPC, ABI_PPC2, ABI_PPC0};
524 /* call types for CallFunc */
525 #define TAGMODE_NORMAL 0 /* produce normal functions only */
526 #define TAGMODE_TAGS 1 /* produce only tag functions */
527 #define TAGMODE_BOTH 2 /* produce both types */
529 /* types specifying name method for pragma creation */
530 #define PRAGMODE_PRAGLIB 1
531 #define PRAGMODE_PRAGSLIB 2
532 #define PRAGMODE_PRAGSPRAGS 3
533 #define PRAGMODE_NONE 4
535 #define BIAS_START 30 /* the library start offset */
536 #define BIAS_OFFSET 6 /* value to switch from one to next function */
538 #ifndef FD2PRAGMA_AMIGA
539 #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
540 #endif
541 #ifndef EXTTYPESFILE
542 #define EXTTYPESFILE "fd2pragma.types"
543 #endif
544 #ifndef EXTTYPESFILE2
545 #ifdef FD2PRAGMA_AMIGA
546 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
547 #else
548 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
549 #endif
550 #endif
552 #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
554 #define FDFILEEXTENSION "_lib.fd"
555 #define SFDFILEEXTENSION "_lib.sfd"
557 static const strptr RegNames[] = {
558 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
559 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
560 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
563 static const strptr RegNamesUpper[] = {
564 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
565 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
566 "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
569 enum Register_ID {
570 REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
571 REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7,
572 REG_FP0, REG_FP1, REG_FP2, REG_FP3, REG_FP4, REG_FP5, REG_FP6, REG_FP7
574 #define MAXREGPPC 26
575 #define MAXREG 24 /* maximum registers of 68K */
576 #define MAXREGNF 16 /* maximum register number without float regs */
577 #define UNDEFREGISTER 255 /* for type scanner */
579 struct Args {
580 strptr infile;
581 strptr to;
582 strptr clib;
583 strptr header;
584 int32 special;
585 int32 mode;
588 struct ShortList {
589 struct ShortList *Next;
592 struct ShortListRoot {
593 struct ShortList *First;
594 struct ShortList *Last;
595 size_t Size;
598 #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
599 #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
600 #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
601 #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
602 #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
603 #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
604 #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
605 #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
606 #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
607 #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
608 #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
609 #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
610 #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
611 #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
612 #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
613 #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
614 #define AMIPRAGFLAG_MOSSYSV (1<<16) /* MorphOS(sysv) type */
615 #define AMIPRAGFLAG_MOSSYSVR12 (1<<17) /* MorphOS(sysv,r12base) type */
616 #define AMIPRAGFLAG_MOSBASESYSV (1<<18) /* MorphOS(base,sysv) type */
617 #define AMIPRAGFLAG_VARARGS (1<<19) /* last argument is ... */
619 #define AMIPRAGFLAG_MOS_ALL (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12|AMIPRAGFLAG_MOSBASESYSV)
621 struct AmiArgs {
622 strptr ArgName;
623 uint16 ArgReg;
626 #define NUMALIASNAMES 5
628 struct AmiPragma {
629 struct ShortList List;
630 uint32 Line;
631 uint32 Flags;
632 strptr FuncName;
633 strptr TagName;
634 struct Pragma_AliasName * AliasName[NUMALIASNAMES]; /* alias names */
635 uint16 NumArgs; /* register numbers */
636 uint16 CallArgs; /* argument number in fd file */
637 int16 Bias;
638 int8 NumAlias;
639 enum ABI Abi;
640 struct AmiArgs Args[MAXREGPPC];
643 struct Comment {
644 struct ShortList List;
645 strptr Data;
646 int16 Bias;
647 uint16 ReservedNum;
648 uint16 Version;
649 uint8 Private; /* is a flag only */
652 struct Include {
653 struct ShortList List;
654 strptr Include;
657 struct PragList {
658 struct ShortList List;
659 struct ShortListRoot Data; /* contains list of PragData */
660 strptr Basename;
663 struct PragData {
664 struct ShortList List;
665 struct ShortListRoot Name;
666 uint32 NumNames;
667 uint32 Bias;
668 uint32 NumArgs;
669 uint8 ArgReg[MAXREG];
672 struct FDData {
673 strptr Name;
674 strptr Basename;
675 uint32 Bias;
676 uint32 Mode; /* 0 = Normal, != 0 is TagName */
677 uint32 NumArgs;
678 uint8 ArgReg[MAXREG];
681 /* NOTE: string creation for CPP-Functions probably does not work at all
682 at the moment, as every compiler uses different systems which seem to
683 change constantly. */
685 /* These CPP types match the strings used for CPP name creation. The
686 defines are used both for name creation and type specification. */
687 #define CPP_TYPE_VOID 'v' /* void, VOID */
688 #define CPP_TYPE_BYTE 'c' /* char, int8 */
689 #define CPP_TYPE_WORD 's' /* short, int16 */
690 #define CPP_TYPE_LONG 'j' /* long, int32 */
691 #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
692 #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
693 #define CPP_TYPE_INT 'i' /* int */
694 #define CPP_TYPE_STRUCTURE 0
695 #define CPP_TYPE_VARARGS 'e'
696 #define CPP_TYPE_LONGLONG 'l' /* long long, int64 */
698 /* These types are for string creation only. */
699 #define CPP_TYPE_ENUM 'E'
700 #define CPP_TYPE_CONST 'C'
701 #define CPP_TYPE_FUNCTION 'F'
702 #define CPP_TYPE_POINTER 'P'
703 #define CPP_TYPE_UNSIGNED 'U'
704 #define CPP_TYPE_FUNCEND 'p'
705 #define CPP_TYPE_REGISTER 'r'
707 /* Some flags to be used in CPP_NameType->Flags. */
708 #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
709 #define CPP_FLAG_CONST (1<<1) /* type is const */
710 #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
711 #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
712 #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
713 #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
714 #define CPP_FLAG_UNION (1<<6) /* it is a union */
715 #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
716 #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
717 #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
718 #define CPP_FLAG_TYPEDEFNAME (1<<10) /* name is created from typedef */
719 #define CPP_FLAG_ARRAY (1<<11) /* this type is an array */
720 #define CPP_FLAG_LONG (1<<12) /* type is long */
721 /* STRPTR is defined different under C and CPP -> I have to create two
722 names, one time unsigned char *, one time signed char *, when somewhere
723 a STRPTR occurs */
725 #define COPYCPP_PASSES 4
727 struct CPP_NameType { /* structure to describe a argument type */
728 strptr StructureName; /* if a structure or enum only */
729 strptr FuncArgs; /* arguments of function - unterminated */
730 strptr TypeStart; /* start of this type */
731 strptr Replace; /* replacement of type for SFD files */
732 strptr Unknown; /* unknown type handled as int */
733 strptr FunctionName; /* Argument name of function argument */
734 struct ClibData *FuncPtr; /* if it is a function pointer */
735 uint16 StructureLength; /* length of the structure name */
736 uint16 ArgsLength; /* length of FuncArgs */
737 uint16 TypeLength; /* length of this type */
738 uint16 FullLength; /* length of complete type */
739 uint16 PointerDepth; /* number of * in type */
740 uint16 FuncPointerDepth; /* number of * in function pointer */
741 uint16 Flags; /* see above flags */
742 uint8 Type; /* see above defines */
743 uint8 Register; /* register number */
746 struct ClibData { /* structure to describe data in CLIB file */
747 struct ClibData * Next; /* The next entry in this list */
748 strptr FuncName; /* name of the function */
749 struct CPP_NameType ReturnType; /* data for return type */
750 struct CPP_NameType Args[MAXREGPPC+1]; /* data for argument types */
751 uint16 NumArgs; /* number of arguments */
754 struct CPP_ExternNames { /* structure for EXTTYPESFILE data */
755 struct CPP_ExternNames * Next; /* The next entry in this list */
756 strptr Type; /* The unknown type */
757 struct CPP_NameType NameType; /* The replacement */
760 struct CPP_TypeField { /* structure for internal defined types */
761 strptr Text; /* name of the type */
762 uint16 Length; /* length of the name string */
763 uint16 Flags; /* CPP_FLAG flags */
764 uint8 Type; /* CPP_TYPE value */
767 struct CPP_Unknown {
768 struct CPP_Unknown *Next;
769 strptr Unknown;
772 struct Proto_LibType { /* structure to define structure type of base vars */
773 strptr BaseName; /* name of the library base */
774 strptr StructureName; /* name of the structure to be used (0 for default) */
775 strptr LibraryName; /* name of the library (maybe 0 for default method) */
776 strptr ShortBaseName; /* short name of the library base */
779 struct Pragma_ExecpName { /* structure to specify special tagnames */
780 strptr FunctionName; /* function name */
781 strptr TagName; /* tag name to be used for this function */
782 }; /* TagName 0 is valid as well to disable tagfunctions */
784 struct Pragma_AliasName {
785 strptr FunctionName;
786 strptr AliasName;
787 uint32 Type;
790 #define NTP_NORMAL 0 /* no tags/args */
791 #define NTP_TAGS 1 /* TagFunction */
792 #define NTP_ARGS 2 /* ArgFunction */
793 #define NTP_UNKNOWN 3 /* CommentFunction */
795 struct NameList {
796 struct ShortList List;
797 uint32 Type; /* set by OptimizeFDData */
798 strptr NormName;
799 strptr PragName;
802 struct InFile {
803 strptr pos;
804 strptr buf;
805 size_t size;
808 /* EHF definitions! */
809 #define HUNK_PPC_CODE 0x4E9
810 #define HUNK_RELRELOC26 0x4EC
811 #define EXT_RELREF26 229
813 /* ------------------------------------------------------------------ */
814 /* A short set of ELF definitions, see pasm sources in vbcc release for an
815 more complete set of stuff or get elf documentation. These are needed for
816 VBCCPUPCode function. */
817 #define ELFCLASS32 1
818 #define ELFDATA2MSB 2
819 #define EV_CURRENT 1 /* version information */
820 #define ET_REL 1 /* type information */
821 #define EM_POWERPC 20
823 #define SHT_NULL 0 /* inactive */
824 #define SHT_PROGBITS 1 /* program information */
825 #define SHT_SYMTAB 2 /* symbol table */
826 #define SHT_STRTAB 3 /* string table */
827 #define SHT_RELA 4 /* relocation */
829 #define SHF_ALLOC 0x2 /* needs memory when started */
830 #define SHF_EXECINSTR 0x4 /* executable instructions */
832 #define SHN_ABS 0xFFF1
834 #define EI_NIDENT 16
835 #define EI_MAG0 0
836 #define EI_MAG1 1
837 #define EI_MAG2 2
838 #define EI_MAG3 3
839 #define EI_CLASS 4
840 #define EI_DATA 5
841 #define EI_VERSION 6
843 #define STB_LOCAL 0
844 #define STB_GLOBAL 1
845 #define STT_FUNC 2
846 #define STT_NOTYPE 0
847 #define STT_SECTION 3
848 #define STT_FILE 4
849 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
850 #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
852 #define R_PPC_ADDR16_LO 4
853 #define R_PPC_ADDR16_HA 6
854 #define R_PPC_REL24 10
855 #define R_PPC_SDAREL16 32
857 struct ArHeader {
858 string ar_name[16]; /* name */
859 string ar_time[12]; /* modification time */
860 string ar_uid[6]; /* user id */
861 string ar_gid[6]; /* group id */
862 string ar_mode[8]; /* octal file permissions */
863 string ar_size[10]; /* size in bytes */
864 string ar_fmag[2]; /* consistency check */
867 /* AmigaOS hunk structure definitions */
868 #ifdef __amigaos4__
869 #include <dos/doshunks.h>
870 #else
871 #define HUNK_UNIT 999
872 #define HUNK_NAME 1000
873 #define HUNK_CODE 1001
874 #define HUNK_BSS 1003
875 #define HUNK_ABSRELOC32 1004
876 #define HUNK_EXT 1007
877 #define HUNK_SYMBOL 1008
878 #define HUNK_END 1010
879 #define HUNK_DREL16 1016
881 #define EXT_DEF 1 /* normal definition */
882 #define EXT_ABS 2 /* Absolute definition */
883 #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
884 #define EXT_DEXT16 134 /* 16 bit data relative reference */
885 #endif
886 /* ------------------------------------------------------------------ */
888 static struct Args args = {0,0,0,0,6,0};
889 static struct InFile in = {0,0,0};
890 static FILE * outfile;
891 static struct ClibData * clibdata = 0;
892 static struct ShortListRoot AmiPragma = {0,0,sizeof(struct AmiPragma)},
893 Comment = {0,0,sizeof(struct Comment)},
894 Includes = {0,0,sizeof(struct Include)};
895 static struct CPP_ExternNames *extnames = 0;
896 static struct CPP_Unknown *unknown = 0;
897 static strptr BaseName = 0; /* the correct basename */
898 /* the filename part of basename without Base */
899 static strptr ShortBaseName = 0;
900 /* like ShortBaseName, but upper case */
901 static strptr ShortBaseNameUpper = 0;
902 static strptr HEADER = 0;
903 static strptr Copyright = 0;
904 static strptr filenamefmt = 0;
905 static strptr libtype = 0;
906 static strptr libname = 0;
907 static strptr defabi = 0;
908 static strptr hunkname = ".text";
909 static strptr datahunkname = "__MERGED";
910 static strptr PPCRegPrefix = "r";
911 static strptr IDstring = 0;
912 static strptr prefix = "";
913 static strptr subprefix = "";
914 static strptr premacro = "";
915 static uint8 * tempbuf = 0;
916 static size_t headersize = 0;
917 static uint32 Flags = 0;
918 static uint32 Flags2 = 0;
919 /* Output error occured when 0 */
920 static uint32 Output_Error = 1;
921 /* are there some tagfuncs in FD */
922 static uint32 tagfuncs = 0;
923 /* priority for auto libopen */
924 static uint32 priority = 5;
925 /* needed for filename */
926 static string filename[255];
928 /* Only for E-Stuff, FD, SFD, XML creation */
929 static int32 LastBias = 0;
930 /* Only for PPC-LVO Lib's */
931 static uint8 * elfbufpos = 0;
932 /* Only for PPC-LVO Lib's */
933 static uint32 symoffset = 0;
934 /* Only for FD, SFD creation */
935 static enum ABI CurrentABI = ABI_M68K;
937 /* Prototypes for the functions */
938 static strptr DupString(strptr, size_t);
939 static strptr AllocListMem(size_t);
940 static strptr SkipBlanks(strptr);
941 static strptr SkipBlanksRet(strptr);
942 static strptr SkipName(strptr);
943 static uint32 GetTypes(void);
944 static strptr GetBaseType(void);
945 static strptr GetBaseTypeLib(void);
946 static strptr GetLibraryName(void);
947 static strptr GetIFXName(void);
948 static int32 MakeShortBaseName(void);
949 static uint32 OpenDest(strptr);
950 static uint32 CloseDest(strptr);
951 static uint32 MakeTagFunction(struct AmiPragma *);
952 static void MakeLines(strptr, uint32);
953 static uint32 SpecialFuncs(void);
954 static void SortFDList(void);
955 static void AddAliasName(struct AmiPragma *, struct Pragma_AliasName *,
956 uint32);
957 static uint32 CheckNames(struct AmiPragma *);
958 static uint32 ScanSFDFile(enum ABI);
959 static uint32 ScanFDFile(void);
960 static int32 ScanTypes(strptr, uint32);
961 static void FindHeader(void);
962 static uint32 GetRegisterData(struct AmiPragma *);
963 static uint16 GetFRegisterData(struct AmiPragma *);
964 static uint32 OutputXDEF(uint32, strptr, ...);
965 static uint32 OutputXREF(uint32, uint32, strptr, ...);
966 static uint32 OutputXREF2(uint32, uint32, uint32, strptr, ...);
967 static uint32 OutputSYMBOL(uint32, strptr, ...);
968 static uint8 * AsmStackCopy(uint8 *, struct AmiPragma *, uint32, uint32);
969 /* ------------------------------------------------------------------ */
970 static void DoError(uint32, uint32, ...);
971 static uint32 CheckError(struct AmiPragma *, uint32);
972 static uint32 DoOutputDirect(void *, size_t);
974 #if defined(__GNUC__)
975 static uint32 DoOutput(strptr, ...) __attribute__ ((format(printf, 1, 2)));
976 #else
977 static uint32 DoOutput(strptr, ...);
978 #endif
979 /* ------------------------------------------------------------------ */
980 static struct ShortList *NewItem(struct ShortListRoot *);
981 static struct ShortList *RemoveItem(struct ShortListRoot *, struct ShortList *);
982 static void AddItem(struct ShortListRoot *, struct ShortList *);
983 /* ------------------------------------------------------------------ */
984 typedef uint32 (*FuncType)(struct AmiPragma *, uint32, strptr);
986 uint32 FuncAMICALL (struct AmiPragma *, uint32, strptr);
987 uint32 FuncLIBCALL (struct AmiPragma *, uint32, strptr);
988 uint32 FuncAsmText (struct AmiPragma *, uint32, strptr);
989 uint32 FuncAsmCode (struct AmiPragma *, uint32, strptr);
990 uint32 FuncCSTUBS (struct AmiPragma *, uint32, strptr);
991 uint32 FuncLVOXDEF (struct AmiPragma *, uint32, strptr);
992 uint32 FuncLVO (struct AmiPragma *, uint32, strptr);
993 uint32 FuncLVOPPCXDEF (struct AmiPragma *, uint32, strptr);
994 uint32 FuncLVOPPC (struct AmiPragma *, uint32, strptr);
995 uint32 FuncLVOPPCBias (struct AmiPragma *, uint32, strptr);
996 uint32 FuncLVOPPCName (struct AmiPragma *, uint32, strptr);
997 uint32 FuncLVOLib (struct AmiPragma *, uint32, strptr);
998 uint32 FuncLocCode (struct AmiPragma *, uint32, strptr);
999 uint32 FuncLocText (struct AmiPragma *, uint32, strptr);
1000 uint32 FuncInline (struct AmiPragma *, uint32, strptr);
1001 uint32 FuncInlineDirect (struct AmiPragma *, uint32, strptr);
1002 uint32 FuncInlineNS (struct AmiPragma *, uint32, strptr);
1003 uint32 FuncPowerUP (struct AmiPragma *, uint32, strptr);
1004 uint32 FuncFPCUnit (struct AmiPragma *, uint32, strptr);
1005 uint32 FuncFPCType (struct AmiPragma *, uint32, strptr);
1006 uint32 FuncFPCTypeTags (struct AmiPragma *, uint32, strptr);
1007 uint32 FuncFPCTypeTagsUnit (struct AmiPragma *, uint32, strptr);
1008 uint32 FuncBMAP (struct AmiPragma *, uint32, strptr);
1009 uint32 FuncVBCCInline (struct AmiPragma *, uint32, strptr);
1010 uint32 FuncVBCCWOSInline (struct AmiPragma *, uint32, strptr);
1011 uint32 FuncVBCCMorphInline (struct AmiPragma *, uint32, strptr);
1012 uint32 FuncVBCCWOSText (struct AmiPragma *, uint32, strptr);
1013 uint32 FuncVBCCWOSCode (struct AmiPragma *, uint32, strptr);
1014 uint32 FuncVBCCPUPText (struct AmiPragma *, uint32, strptr);
1015 uint32 FuncVBCCPUPCode (struct AmiPragma *, uint32, strptr);
1016 uint32 FuncEModule (struct AmiPragma *, uint32, strptr);
1017 uint32 FuncVBCCMorphText (struct AmiPragma *, uint32, strptr);
1018 uint32 FuncVBCCMorphCode (struct AmiPragma *, uint32, strptr);
1019 uint32 FuncFD (struct AmiPragma *, uint32, strptr);
1020 uint32 FuncClib (struct AmiPragma *, uint32, strptr);
1021 uint32 FuncSFD (struct AmiPragma *, uint32, strptr);
1022 uint32 FuncXML (struct AmiPragma *, uint32, strptr);
1023 uint32 FuncOS4PPC (struct AmiPragma *, uint32, strptr);
1024 uint32 FuncOS4M68KCSTUB (struct AmiPragma *, uint32, strptr);
1025 uint32 FuncOS4M68K (struct AmiPragma *, uint32, strptr);
1026 uint32 FuncOS4M68KVect (struct AmiPragma *, uint32, strptr);
1027 uint32 FuncGateStubs (struct AmiPragma *, uint32, strptr);
1028 static uint32 PrintComment (struct Comment *, strptr);
1029 static uint32 DoCallFunc (struct AmiPragma *, uint32, strptr, FuncType);
1030 static uint32 CallFunc (uint32, strptr, FuncType);
1031 static uint32 PrintIncludes(void);
1032 /* ------------------------------------------------------------------ */
1033 static int32 AddClibEntry(strptr, strptr, uint32);
1034 static int32 ScanClibFile(strptr, strptr);
1035 static int32 IsCPPType(struct CPP_NameType *, uint8);
1036 static uint32 CheckRegisterNum(strptr, struct CPP_NameType *);
1037 static uint32 ParseFuncPtrArgs(strptr, struct CPP_NameType *);
1038 static int32 GetCPPType(struct CPP_NameType *, strptr, uint32, uint32);
1039 static struct ClibData *GetClibFunc(strptr, struct AmiPragma *, uint32);
1040 static int32 CheckKeyword(strptr, strptr, int32);
1041 static uint32 CopyCPPType(strptr, uint32, struct ClibData *, struct AmiArgs *);
1042 static uint32 OutClibType(struct CPP_NameType *, strptr);
1043 static uint32 MakeClibType(strptr, struct CPP_NameType *, strptr);
1044 static uint32 OutPASCALType(struct CPP_NameType *, strptr, uint32);
1045 /* ------------------------------------------------------------------ */
1046 static uint32 CallPrag(uint32, strptr, FuncType);
1047 static uint32 CreatePragmaFile(strptr, strptr, strptr, strptr, uint32);
1048 static uint32 CreateCSTUBSFile(void);
1049 static uint32 CreateLVOFile(uint32);
1050 static uint32 CreateLVOFilePPC(uint32);
1051 static uint32 CreateAsmStubs(uint32, uint32);
1052 static uint32 CreateProtoFile(uint32);
1053 static uint32 CreateLocalData(strptr, uint32);
1054 static uint32 CreateInline(uint32, uint32);
1055 static uint32 CreateGateStubs(uint32);
1056 static uint32 CreateSASPowerUP(uint32);
1057 static uint32 CreateProtoPowerUP(void);
1058 static uint32 CreateFPCUnit(void);
1059 static uint32 CreateBMAP(void);
1060 static uint32 CreateLVOLib(void);
1061 static uint32 CreateLVOLibPPC(void);
1062 static uint32 CreateVBCCInline(uint32, uint32);
1063 static uint32 CreateVBCC(uint32, uint32);
1064 static uint32 CreateVBCCPUPLib(uint32);
1065 static uint32 CreateVBCCMorphCode(uint32);
1066 static uint32 CreateEModule(uint32);
1067 static uint32 CreateProtoRedirect(void);
1068 static uint32 CreateFD(void);
1069 static uint32 CreateSFD(uint32);
1070 static uint32 CreateClib(uint32);
1071 static uint32 CreateGenAuto(strptr, uint32);
1072 static uint32 CreateXML(void);
1073 static uint32 CreateOS4PPC(uint32);
1074 static uint32 CreateOS4M68K(void);
1075 /* ------------------------------------------------------------------ */
1076 static uint32 GetName(struct NameList *, struct ShortListRoot *, uint32);
1077 static uint32 MakeFD(struct PragList *);
1078 static void OptimizeFDData(struct PragData *);
1079 static string GetHexValue(string);
1080 static string GetDoubleHexValue(strptr);
1081 static uint32 AddFDData(struct ShortListRoot *, struct FDData *);
1082 static uint32 GetLibData(struct FDData *);
1083 static uint32 GetFlibData(struct FDData *);
1084 static uint32 GetAmiData(struct FDData *);
1085 static uint32 CreateFDFile(void);
1086 /* ------------------------------------------------------------------ */
1087 static void GetArgs(int argc, char **argv);
1088 static strptr mygetfile(strptr name, size_t *len);
1090 #define ERROFFSET_CLIB (1<<31)
1092 enum {
1093 ERR_TAGFUNC_NEEDS_ARGUMENT,
1094 ERR_CANNOT_CONVERT_PRAGMA_TAGCALL,
1095 ERR_TAG_DEF_WITHOUT_PRAGMA,
1096 ERR_BASENAME_DECLARED_TWICE,
1097 ERR_EXPECTED_SLASH_IN_BASENAME,
1098 ERR_EXPECTED_BASENAME,
1099 ERR_EXPECTED_BIAS_VALUE,
1100 ERR_ASSUMING_POSITIVE_BIAS_VALUE,
1101 ERR_MISSING_FUNCTION_NAME,
1102 ERR_EXPECTED_OPEN_BRACKET,
1103 ERR_TO_MUCH_ARGUMENTS,
1104 ERR_EXPECTED_ARGUMENT_NAME,
1105 ERR_EXPECTED_CLOSE_BRACKET,
1106 ERR_EXPECTED_REGISTER_NAME,
1107 ERR_A7_NOT_ALLOWED,
1108 ERR_REGISTER_USED_TWICE,
1109 ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER,
1110 ERR_ASSUMING_BIAS_OF_30,
1111 ERR_EXTRA_CHARACTERS,
1112 ERR_MISSING_BASENAME,
1113 ERR_WRITING_FILE,
1114 ERR_EXPECTED_COMMA,
1115 ERR_DIFFERENT_TO_PREVIOUS,
1116 ERR_UNKNOWN_VARIABLE_TYPE,
1117 ERR_UNKNOWN_ERROR,
1118 ERR_MISSING_END,
1119 ERR_PROTOTYPE_MISSING,
1120 ERR_NOPROTOTYPES_FILE,
1121 ERR_UNKNOWN_DIRECTIVE,
1122 ERR_INLINE_A4_AND_A5,
1123 ERR_INLINE_D7_AND_A45,
1124 ERR_MISSING_SHORTBASENAME,
1125 ERR_A6_NOT_ALLOWED,
1126 ERR_EMPTY_FILE,
1127 ERR_FLOATARG_NOT_ALLOWED,
1128 ERR_WRONG_TYPES_LINE,
1129 ERR_LONG_DOUBLE,
1130 ERR_CLIB_ARG_COUNT,
1131 ERR_OPEN_FILE,
1132 ERR_A5_NOT_ALLOWED,
1133 ERR_PPC_FUNCTION_NOT_SUPPORTED,
1134 ERR_UNKNOWN_ABI,
1135 ERR_NO_SORTED,
1136 ERR_ILLEGAL_FUNCTION_POSITION,
1137 ERR_SORTED_COMMENT,
1138 ERR_COMMENT_SINGLEFILE,
1139 ERR_NOFD2PRAGMATYPES,
1140 ERR_M68K_FUNCTION_NOT_SUPPORTED,
1141 ERR_UNKNOWN_RETURNVALUE_TYPE,
1142 ERR_SFD_AND_CLIB,
1143 ERR_EXCPECTED_IDSTRING,
1144 ERR_EXPECTED_ID_ENDSIGN,
1145 ERR_MISSING_SFDEND,
1146 ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER,
1147 ERR_IDSTRING_DECLARED_TWICE,
1148 ERR_COMMANDLINE_LIBTYPE,
1149 ERR_COMMANDLINE_BASENAME,
1150 ERR_LIBTYPE_DECLARED_TWICE,
1151 ERR_EXPECTED_LIBTYPE,
1152 ERR_SORTED_SFD_FD,
1153 ERR_EARLY_SHADOW,
1154 ERR_DOUBLE_VARARGS,
1155 ERR_VARARGS_ARGUMENTS_DIFFER,
1156 ERR_UNEXPECTED_FILEEND,
1157 ERR_VARARGS_ALIAS_FIRST,
1158 ERR_ALIASNAMES,
1159 ERR_EXPECTED_STRUCT,
1160 ERR_EXPECTED_POINTERSIGN,
1161 ERR_ARGNAME_KEYWORD_CONFLICT,
1162 ERR_ARGNAME_ARGNAME_CONFLICT,
1163 ERR_ONLYTAGMODE_NOTALLOWED,
1164 ERR_COMMANDLINE_LIBNAME,
1165 ERR_LIBNAME_DECLARED_TWICE,
1166 ERR_EXPECTED_LIBNAME,
1167 ERR_PREFIX,
1168 ERR_MULTIPLEFUNCTION,
1169 ERR_INLINE_AX_SWAPREG,
1170 ERR_SFD_START,
1171 ERR_ILLEGAL_CHARACTER_DETECTED,
1172 ERR_UNKNOWN_VARIABLE_TYPE_INT,
1173 ERR_UNKNOWN_RETURNVALUE_TYPE_INT,
1174 ERR_ILLEGAL_INTERNAL_VALUE,
1175 ERR_MOSBASESYSV_NOT_SUPPORTED,
1176 ERR_ALIASES_NOT_SUPPORTED,
1177 ERR_FUNCTION_NOT_SUPPORTED,
1180 static const struct ErrField {
1181 uint8 Type; /* 0 = Error, 1 = Warning */
1182 uint8 Skip;
1183 strptr Error;
1184 } Errors[] = {
1185 {1, 1, "Tag function must have arguments."},
1186 {1, 1, "Cannot convert pragma name into tag name."},
1187 {1, 1, "Tag definition without preceding Pragma."},
1188 {1, 0, "Basename declared twice."},
1189 {1, 0, "Expected preceding _ in Basename."},
1190 {1, 1, "Expected Basename."},
1191 {1, 0, "Expected Bias value."},
1192 {1, 0, "Assuming positive bias value."},
1193 {1, 1, "Missing function name."},
1194 {1, 1, "Expected '('."},
1195 {1, 1, "Too much arguments."},
1196 {1, 1, "Expected argument name."},
1197 {1, 1, "Expected ')'."},
1198 {1, 1, "Expected register name."},
1199 {1, 1, "A7 not allowed as argument register."},
1200 {1, 1, "Register used twice."},
1201 {1, 0, "Number of arguments != number of registers."},
1202 {1, 0, "Assuming bias of 30."},
1203 {1, 1, "Extra characters."},
1204 {0, 0, "Missing Basename in FD file."},
1205 {0, 0, "Failed to write destination file."},
1206 {1, 1, "Expected ','."},
1207 {0, 1, "Data different to previous given."},
1208 {1, 0, "Unknown type of argument %ld."},
1209 {0, 0, "Unknown problem: program error or corrupt input data."},
1210 {1, 0, "Missing ##end."},
1211 {1, 0, "Prototype for function \"%s\" not found."},
1212 {0, 0, "No prototypes file (CLIB parameter) was specified."},
1213 {1, 1, "Unknown directive '%s' found."},
1214 {1, 0, "Usage of both A4 and A5 is not supported."},
1215 {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
1216 {0, 0, "Missing Basename in FD file and FD filename."},
1217 {1, 0, "A6 not allowed as argument register."},
1218 {1, 0, "Empty or partial file deleted."},
1219 {1, 1, "Floating point arguments not allowed."},
1220 {0, 0, "Wrong definition in external type definition file."},
1221 {1, 0, "Cannot determine if FPU argument is double or single."},
1222 {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
1223 {0, 0, "Could not open file \"%s\"."},
1224 {1, 0, "A5 cannot be used as argument register."},
1225 {1, 0, "Format supports no PPC functions."},
1226 {1, 0, "Unknown ABI '%s' found."},
1227 {0, 0, "SORTED cannot be used with that type."},
1228 {1, 0, "Position of function %s not supported with that type."},
1229 {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
1230 {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
1231 {1, 0, "Missing the types definition file. Using internal defaults."},
1232 {1, 0, "Format supports no M68k functions."},
1233 {1, 0, "Unknown type of return value."},
1234 {1, 0, "With SFD as input CLIB file is ignored."},
1235 {1, 0, "Expected $Id: in ID string."},
1236 {1, 0, "Expected $ at end of ID string."},
1237 {1, 0, "Missing ==end."},
1238 {1, 1, "Expected positive decimal number."},
1239 {1, 0, "ID string declared twice."},
1240 {1, 1, "Library type of commandline overwrites file settings."},
1241 {1, 1, "Basename of commandline overwrites file settings."},
1242 {1, 0, "Library type declared twice."},
1243 {1, 1, "Expected library type definition."},
1244 {1, 1, "SORTED cannot be used with SFD and FD output."},
1245 {1, 0, "Function expected before ##shadow."},
1246 {1, 1, "There is already a varargs function, handling as alias."},
1247 {1, 0, "Varargs function cannot have different arguments."},
1248 {1, 0, "Unexpected end of file."},
1249 {1, 0, "Commands varargs and alias cannot be at file start."},
1250 {1, 0, "Only %d alias names supported."},
1251 {1, 1, "Expected struct keyword in library type."},
1252 {1, 0, "Expected '*' at end of library type definition."},
1253 {1, 1, "Name of argument %d conflicts with keyword '%s'."},
1254 {1, 1, "Name of argument %d conflicts with argument %d."},
1255 {1, 0, "SFD files cannot consist only of varargs functions."},
1256 {1, 1, "Library name of commandline overwrites file settings."},
1257 {1, 0, "Library name declared twice."},
1258 {1, 1, "Expected library name definition."},
1259 {1, 0, "Neither prefix nor subprefix specified."},
1260 {1, 0, "Format supports single function pointer only (void * used)."},
1261 {1, 0, "No swap register left for %s."},
1262 {1, 0, "SFD files should always start with ==id directive."},
1263 {1, 0, "Illegal character detected."},
1264 {1, 0, "Unknown type of argument %ld (%s) handled as int."},
1265 {1, 0, "Unknown type of return value (%s) handled as int."},
1266 {1, 0, "Illegal internal value."},
1267 {1, 0, "Format supports no MorphOS (base,sysv) functions."},
1268 {1, 0, "Format supports no alias names."},
1269 {1, 0, "Format cannot support function %s."},
1272 #ifdef __SASC
1273 __far
1274 #endif
1275 static uint8 InternalTypes[] = {
1276 "IX:struct InputXpression\n"
1277 "Msg:struct ? *\n"
1278 "Class:struct IClass\n"
1279 "BootBlock:struct bootblock\n"
1280 "ValidIDstruct:struct ValidIDstruct\n"
1281 "DisplayInfoHandle:void *\n"
1282 "RESOURCEFILE:void *\n"
1283 "RESOURCEID:unsigned long\n"
1284 "GLvoid:void\n"
1285 "GLbitfield:unsigned long\n"
1286 "GLbyte:signed char\n"
1287 "GLshort:short\n"
1288 "GLint:long\n"
1289 "GLsizei:unsigned long\n"
1290 "GLubyte:unsigned char\n"
1291 "GLushort:unsigned short\n"
1292 "GLuint:unsigned long\n"
1293 "GLfloat:float\n"
1294 "GLclampf:float\n"
1295 "GLdouble:double\n"
1296 "GLclampd:double\n"
1297 "GLboolean:enum ?\n"
1298 "GLenum:enum ?\n"
1299 "GLlookAt:struct GLlookAt\n"
1300 "GLproject:struct GLproject\n"
1301 "GLunProject:struct GLunProject\n"
1302 "GLfrustum:struct GLfrustum\n"
1303 "GLortho:struct GLortho\n"
1304 "GLbitmap:struct GLbitmap\n"
1305 "GLUquadricObj:struct GLUquadricObj\n"
1306 "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
1307 "GLUnurbsObj:struct GLUnurbsObj\n"
1308 "GLvisual:struct gl_visual\n"
1309 "GLframebuffer:struct gl_frame_buffer\n"
1310 "GLcontext:struct gl_context\n"
1311 "GLContext:struct !\n"
1312 "HGIDA_Stack:unsigned long *\n"
1313 "HGIDA_BoundedStack:unsigned long *\n"
1314 "HGIDA_Queue:unsigned long *\n"
1315 "HGIDA_BoundedQueue:unsigned long *\n"
1316 "HGIDA_List:unsigned long *\n"
1317 "HGIDA_ListItem:unsigned long *\n"
1318 "HGIDA_Error:enum ?\n"
1319 "HGIDA_Direction:enum ?\n"
1320 "uid_t:long\n"
1321 "gid_t:long\n"
1322 "mode_t:unsigned short\n"
1323 "pid_t:struct Task *\n"
1324 "fd_set:struct fd_set\n"
1325 "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 "
1326 "unsigned long, register __a1 const unsigned char *, register __a2 struct "
1327 "CSource *, register __a3 struct CSource *)\n"
1328 "pcap_t:struct pcap\n"
1329 "pcap_dumper_t:struct pcap_dumper\n"
1330 "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const "
1331 "unsigned char *)\n"
1332 "u_char:unsigned char\n"
1333 "bpf_u_int32:unsigned long\n"
1334 "Fixed:long\n"
1335 "sposition:long\n"
1336 "MPEGA_STREAM:struct MPEGA_STREAM\n"
1337 "MPEGA_CTRL:struct MPEGA_CTRL\n"
1338 "W3D_Context:struct W3DContext\n"
1339 "W3D_Driver:struct W3DDriver\n"
1340 "W3D_Texture:struct W3DTexture\n"
1341 "W3D_Scissor:struct W3DScissor\n"
1342 "W3D_Line:struct W3D_Line\n"
1343 "W3D_Point:struct W3D_Point\n"
1344 "W3D_Triangle:struct W3D_Triangle\n"
1345 "W3D_Triangles:struct W3D_Triangles\n"
1346 "W3D_Float:float\n"
1347 "W3D_Bitmap:struct W3D_Bitmap\n"
1348 "W3D_Fog:struct W3D_Fog\n"
1349 "W3D_Bool:short\n"
1350 "W3D_Double:double\n"
1351 "W3D_TriangleV:struct W3D_TriangleV\n"
1352 "W3D_TrianglesV:struct W3D_TriangleV\n"
1353 "W3D_ScreenMode:struct W3D_Screenmode\n"
1354 "W3D_Color:struct W3D_Color\n"
1355 "W3D_Lines:struct W3D_Lines\n"
1356 "RGBFTYPE:enum ?\n"
1357 "DITHERINFO:void *\n"
1358 "SLayer:void *\n"
1359 "va_list:char *\n"
1360 "time_t:long\n"
1361 "size_t:unsigned int\n"
1362 "FILE:struct ? *\n"
1363 "uint8:unsigned char\n"
1364 "uint16:unsigned short\n"
1365 "uint32:unsigned long\n"
1366 "int8:char\n"
1367 "int16:short\n"
1368 "int32:long\n"
1369 "AVLKey:void *\n"
1370 "PtrBigNum:struct BigNum *\n"
1371 "BF_KEY:struct bf_key_st\n"
1372 "BF_LONG:unsigned long\n"
1373 "CAST_KEY:struct cast_key_st\n"
1374 "CAST_LONG:unsigned long\n"
1375 "DES_LONG:unsigned long\n"
1376 "des_key_schedule:struct des_ks_struct\n"
1377 "const_des_cblock:unsigned char [8]\n"
1378 "des_cblock:unsigned char [8]\n"
1379 "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
1380 "MD2_CTX:struct MD2state_st\n"
1381 "MD5_CTX:struct MD5state_st\n"
1382 "MDC2_CTX:struct mdc2_ctx_st\n"
1383 "RC2_KEY:struct rc2_key_st\n"
1384 "RC4_KEY:struct rc4_key_st\n"
1385 "RC5_32_KEY:struct rc5_key_st\n"
1386 "RIPEMD160_CTX:struct RIPEMD160state_st\n"
1387 "SHA_CTX:struct SHAstate_st\n"
1388 "ASN1_CTX:struct asn1_ctx_st\n"
1389 "ASN1_OBJECT:struct asn1_object_st\n"
1390 "ASN1_STRING:struct asn1_string_st\n"
1391 "ASN1_TYPE:struct asn1_type_st\n"
1392 "ASN1_METHOD:struct asn1_method_st\n"
1393 "ASN1_HEADER:struct asn1_header_st\n"
1394 "ASN1_INTEGER:struct asn1_string_st\n"
1395 "ASN1_ENUMERATED:struct asn1_string_st\n"
1396 "ASN1_BIT_STRING:struct asn1_string_st\n"
1397 "ASN1_OCTET_STRING:struct asn1_string_st\n"
1398 "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
1399 "ASN1_T61STRING:struct asn1_string_st\n"
1400 "ASN1_IA5STRING:struct asn1_string_st\n"
1401 "ASN1_UTCTIME:struct asn1_string_st\n"
1402 "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
1403 "ASN1_TIME:struct asn1_string_st\n"
1404 "ASN1_GENERALSTRING:struct asn1_string_st\n"
1405 "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
1406 "ASN1_BMPSTRING:struct asn1_string_st\n"
1407 "ASN1_VISIBLESTRING:struct asn1_string_st\n"
1408 "ASN1_UTF8STRING:struct asn1_string_st\n"
1409 "BIO:struct bio_st\n"
1410 "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
1411 "BIO_METHOD:struct bio_method_st\n"
1412 "BIGNUM:struct bignum_st\n"
1413 "BN_CTX:struct bignum_ctx\n"
1414 "BN_ULONG:unsigned long\n"
1415 "BN_MONT_CTX:struct bn_mont_ctx_st\n"
1416 "BN_BLINDING:struct bn_blinding_st\n"
1417 "BN_RECP_CTX:struct bn_recp_ctx_st\n"
1418 "BUF_MEM:struct buf_mem_st\n"
1419 "COMP_METHOD:struct comp_method_st\n"
1420 "COMP_CTX:struct comp_ctx_st\n"
1421 "CONF_VALUE:struct !\n"
1422 "LHASH_NODE:struct lhash_node_st\n"
1423 "LHASH:struct lhash_st\n"
1424 "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
1425 "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
1426 "DH:struct dh_st\n"
1427 "DSA:struct dsa_st\n"
1428 "DSA_SIG:struct DSA_SIG_st\n"
1429 "ERR_STATE:struct err_state_st\n"
1430 "ERR_STRING_DATA:struct ERR_string_data_st\n"
1431 "EVP_PKEY:struct evp_pkey_st\n"
1432 "EVP_MD:struct env_md_st\n"
1433 "EVP_MD_CTX:struct env_md_ctx_st\n"
1434 "EVP_CIPHER:struct evp_cipher_st\n"
1435 "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
1436 "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
1437 "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
1438 "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char "
1439 "*pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st "
1440 "*cipher, struct env_md_st *md, int en_de)\n"
1441 "HMAC_CTX:struct hmac_ctx_st\n"
1442 "OBJ_NAME:struct obj_name_st\n"
1443 "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
1444 "PEM_USER:struct pem_recip_st\n"
1445 "PEM_CTX:struct pem_ctx_st\n"
1446 "PKCS12_MAC_DATA:struct !\n"
1447 "PKCS12:struct !\n"
1448 "PKCS12_SAFEBAG:struct !\n"
1449 "PKCS12_BAGS:struct pkcs12_bag_st\n"
1450 "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
1451 "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
1452 "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
1453 "PKCS7_SIGNED:struct pkcs7_signed_st\n"
1454 "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
1455 "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
1456 "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
1457 "PKCS7_DIGEST:struct pkcs7_digest_st\n"
1458 "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
1459 "PKCS7:struct pkcs7_st\n"
1460 "RAND_METHOD:struct rand_meth_st\n"
1461 "RSA:struct rsa_st\n"
1462 "RSA_METHOD:struct rsa_meth_st\n"
1463 "TXT_DB:struct txt_db_st\n"
1464 "X509_OBJECTS:struct X509_objects_st\n"
1465 "X509_ALGOR:struct X509_algor_st\n"
1466 "X509_VAL:struct X509_val_st\n"
1467 "X509_PUBKEY:struct X509_pubkey_st\n"
1468 "X509_SIG:struct X509_sig_st\n"
1469 "X509_NAME_ENTRY:struct X509_name_entry_st\n"
1470 "X509_NAME:struct X509_name_st\n"
1471 "X509_EXTENSION:struct X509_extension_st\n"
1472 "X509_ATTRIBUTE:struct x509_attributes_st\n"
1473 "X509_REQ_INFO:struct X509_req_info_st\n"
1474 "X509_REQ:struct X509_req_st\n"
1475 "X509_CINF:struct x509_cinf_st\n"
1476 "X509:struct x509_st\n"
1477 "X509_REVOKED:struct X509_revoked_st\n"
1478 "X509_CRL_INFO:struct X509_crl_info_st\n"
1479 "X509_CRL:struct X509_crl_st\n"
1480 "X509_PKEY:struct private_key_st\n"
1481 "X509_INFO:struct X509_info_st\n"
1482 "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
1483 "NETSCAPE_SPKI:struct Netscape_spki_st\n"
1484 "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
1485 "CBC_PARAM:struct CBCParameter_st\n"
1486 "PBEPARAM:struct PBEPARAM_st\n"
1487 "PBE2PARAM:struct PBE2PARAM_st\n"
1488 "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
1489 "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
1490 "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
1491 "X509V3_EXT_METHOD:struct v3_ext_method\n"
1492 "X509V3_CTX:struct v3_ext_ctx\n"
1493 "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
1494 "X509_CERT_FILE_CTX:struct x509_file_st\n"
1495 "X509_OBJECT:struct X509_objects_st\n"
1496 "X509_LOOKUP:struct x509_lookup_st\n"
1497 "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
1498 "X509_STORE_CTX:struct x509_store_state_st\n"
1499 "X509_STORE:struct x509_store_st\n"
1500 "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
1501 "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
1502 "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
1503 "GENERAL_NAME:struct GENERAL_NAME_st\n"
1504 "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
1505 "DIST_POINT:struct DIST_POINT_st\n"
1506 "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
1507 "SXNETID:struct SXNET_ID_st\n"
1508 "SXNET:struct SXNET_st\n"
1509 "NOTICEREF:struct NOTICEREF_st\n"
1510 "USERNOTICE:struct USERNOTICE_st\n"
1511 "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
1512 "POLICYINFO:struct POLICYINFO_st\n"
1513 "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
1514 "SSL_CIPHER:struct ssl_cipher_st\n"
1515 "SSL:struct ssl_st\n"
1516 "SSL_CTX:struct ssl_ctx_st\n"
1517 "SSL_METHOD:struct ssl_method_st\n"
1518 "SSL_SESSION:struct ssl_session_st\n"
1519 "SSL_COMP:struct ssl_comp_st\n"
1520 "SSL2_CTX:struct ssl2_ctx_st\n"
1521 "SSL3_RECORD:struct ssl3_record_st\n"
1522 "SSL3_BUFFER:struct ssl3_buffer_st\n"
1523 "SSL3_CTX:struct ssl3_ctx_st\n"
1524 "CERT_PKEY:struct cert_pkey_st\n"
1525 "CERT:struct cert_st\n"
1526 "SESS_CERT:struct sess_cert_st\n"
1527 "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
1528 "SSL3_COMP:struct ssl3_comp_st\n"
1529 "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
1530 "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
1531 "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
1532 "STACK_OF(X509):struct stack_st_X509\n"
1533 "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
1534 "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
1535 "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
1536 "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
1537 "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
1538 "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
1539 "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
1540 "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
1541 "STACK:struct stack_st\n"
1542 "SDL_bool:enum ?\n"
1543 "Uint8:unsigned char\n"
1544 "Sint8:signed char\n"
1545 "Uint16:unsigned short\n"
1546 "Sint16:signed short\n"
1547 "Uint32:unsigned long\n"
1548 "Sint32:signed long\n"
1549 "Uint64:unsigned long long\n"
1550 "Sint64:signed long long\n"
1551 "SDL_version:struct !\n"
1552 "SDL_RWops:struct SDL_RWops\n"
1553 "SDL_Rect:struct !\n"
1554 "SDL_Color:struct !\n"
1555 "SDL_Palette:struct !\n"
1556 "SDL_PixelFormat:struct SDL_PixelFormat\n"
1557 "SDL_blit:int (*)(struct SDL_Surface *src,void *srcrect,"
1558 "struct SDL_Surface *dst,void *dstrect)\n"
1559 "SDL_Surface:struct SDL_Surface\n"
1560 "SDL_VideoInfo:struct !\n"
1561 "SDL_Overlay:struct SDL_Overlay\n"
1562 "SDL_GLattr:enum ?\n"
1563 "SDL_GrabMode:enum ?\n"
1564 "SDL_audiostatus:enum ?\n"
1565 "SDL_AudioSpec:struct !\n"
1566 "SDL_AudioCVT:struct SDL_AudioCVT\n"
1567 "CDstatus:enum ?\n"
1568 "SDL_CDtrack:struct !\n"
1569 "SDL_CD:struct SDL_CD\n"
1570 "SDL_Joystick:struct _SDL_Joystick\n"
1571 "SDLKey:enum ?\n"
1572 "SDLMod:enum ?\n"
1573 "SDL_keysym:struct !\n"
1574 "SDL_ActiveEvent:struct !\n"
1575 "SDL_KeyboardEvent:struct !\n"
1576 "SDL_MouseMotionEvent:struct !\n"
1577 "SDL_MouseButtonEvent:struct !\n"
1578 "SDL_JoyAxisEvent:struct !\n"
1579 "SDL_JoyBallEvent:struct !\n"
1580 "SDL_JoyHatEvent:struct !\n"
1581 "SDL_JoyButtonEvent:struct !\n"
1582 "SDL_ResizeEvent:struct !\n"
1583 "SDL_ExposeEvent:struct !\n"
1584 "SDL_QuitEvent:struct !\n"
1585 "SDL_UserEvent:struct !\n"
1586 "SDL_SysWMmsg:struct SDL_SysWMmsg\n"
1587 "SDL_SysWMEvent:struct !\n"
1588 "SDL_Event:union ?\n"
1589 "SDL_eventaction:enum ?\n"
1590 "SDL_EventFilter:void *\n"
1591 "WMcursor:struct WMcursor\n"
1592 "SDL_Cursor:struct !\n"
1593 "SDL_mutex:struct SDL_mutex\n"
1594 "SDL_sem:struct SDL_semaphore\n"
1595 "SDL_cond:struct SDL_cond\n"
1596 "SDL_Thread:struct SDL_Thread\n"
1597 "SDL_TimerCallback:unsigned long (*)(unsigned long)\n"
1598 "SDL_NewTimerCallback:unsigned long (*)(unsigned long,void *)\n"
1599 "SDL_TimerID:struct _SDL_TimerID\n"
1600 "SDL_errorcode:enum ?\n"
1601 "FPSmanager:struct !\n"
1602 "Mix_Chunk:struct !\n"
1603 "Mix_Music:struct !\n"
1604 "Mix_MusicType:enum ?\n"
1605 "Mix_EffectFunc_t:void (*)(int,void *,int,void *)\n"
1606 "Mix_EffectDone_t:void (*)(int,void *)\n"
1607 "Mix_Fading:enum ?\n"
1608 "IPaddress:struct !\n"
1609 "TCPsocket:void *\n"
1610 "UDPpacket:struct !\n"
1611 "UDPsocket:void *\n"
1612 "SDLNet_SocketSet:void *\n"
1613 "SDLNet_GenericSocket:void *\n"
1614 "TTF_Font:struct !\n"
1617 static const struct CPP_TypeField CPP_Field[] = {
1618 {"int", 3, 0, CPP_TYPE_INT},
1619 /* long needs special handling due to the fact it is a modifier and a type */
1620 /*{"long", 4, 0, CPP_TYPE_LONG}, */
1621 {"LONG", 4, 0, CPP_TYPE_LONG},
1622 {"BPTR", 4, 0, CPP_TYPE_LONG},
1623 {"BSTR", 4, 0, CPP_TYPE_LONG},
1624 {"CxObj", 5, 0, CPP_TYPE_LONG},
1625 {"CxMsg", 5, 0, CPP_TYPE_LONG},
1626 {"ULONG", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1627 {"LONGBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1628 {"CPTR", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1629 {"Tag", 3, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1630 {"Object", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1631 {"short", 5, 0, CPP_TYPE_WORD},
1632 {"SHORT", 5, 0, CPP_TYPE_WORD},
1633 {"COUNT", 5, 0, CPP_TYPE_WORD},
1634 {"WORD", 4, 0, CPP_TYPE_WORD},
1635 {"USHORT", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1636 {"UWORD", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1637 {"UCOUNT", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1638 {"WORDBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1639 {"RPTR", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1640 {"BOOL", 4, CPP_FLAG_BOOLEAN, CPP_TYPE_WORD},
1641 {"char", 4, 0, CPP_TYPE_BYTE},
1642 {"BYTE", 4, 0, CPP_TYPE_BYTE},
1643 {"UBYTE", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1644 {"TEXT", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1645 {"BYTEBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1646 {"float", 5, 0, CPP_TYPE_FLOAT},
1647 {"FLOAT", 5, 0, CPP_TYPE_FLOAT},
1648 {"double", 6, 0, CPP_TYPE_DOUBLE},
1649 {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE},
1650 {"void", 4, 0, CPP_TYPE_VOID},
1651 {"VOID", 4, 0, CPP_TYPE_VOID},
1652 {"APTR", 4, CPP_FLAG_POINTER, CPP_TYPE_VOID},
1653 {"STRPTR", 6, CPP_FLAG_POINTER|CPP_FLAG_STRPTR, CPP_TYPE_BYTE},
1654 {"CONST_STRPTR",12,CPP_FLAG_POINTER|CPP_FLAG_CONST, CPP_TYPE_BYTE},
1655 {"ClassID", 7, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1656 {"PLANEPTR", 8, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1657 {0,0,0,0},
1660 /* defaults: "Library" shortbname+".library" basename-last 4 chars */
1661 static const struct Proto_LibType Proto_LibTypes[] = {
1662 {"DOSBase", "DosLibrary", 0, 0},
1663 {"SysBase", "ExecBase", 0, 0},
1664 {"ExpansionBase", "ExpansionBase", 0, 0},
1665 {"GfxBase", "GfxBase", "graphics.library", "graphics"},
1666 {"IntuitionBase", "IntuitionBase", 0, 0},
1667 {"LocaleBase", "LocaleBase", 0, 0},
1668 {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
1669 {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
1670 {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
1671 {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
1672 {"RealTimeBase", "RealTimeBase", 0, 0},
1673 {"RexxSysBase", "RxsLib", 0, 0},
1674 {"UtilityBase", "UtilityBase", 0, 0},
1675 {"WorkbenchBase", 0, "workbench.library", "wb"},
1676 /* resources - The Node entries may be correct, but I don't know it. */
1677 {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
1678 {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
1679 {"CardResource", 0/*"Node"*/, "card.resource", "cardres"},
1680 {"DiskBase", "DiskResource", "disk.resource", 0},
1681 {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
1682 {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
1683 /* devices */
1684 {"ConsoleDevice", 0/*"Device"*/, "console.device", "console"},
1685 {"InputBase", 0/*"Device"*/, "input.device", 0},
1686 {"RamdriveDevice", 0/*"Device"*/, "ramdrive.device", "ramdrive"},
1687 {"TimerBase", 0/*"Device"*/, "timer.device", 0},
1688 /* non default Basenames */
1689 {"DatamasterBase", "DatamasterBase", 0, 0},
1690 {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
1691 {"ReqToolsBase", "ReqToolsBase", 0, 0},
1692 {"UnpackBase", "UnpackLibrary", 0, 0},
1693 {"xfdMasterBase", "xfdMasterBase", 0, 0},
1694 {"xadMasterBase", "xadMasterBase", 0, 0},
1695 /*{"xvsBase", "xvsBase", 0, 0}, now completely private */
1696 {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
1697 {"ArpBase", "ArpBase", 0, 0},
1698 {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
1699 {"PowerPCBase", "PPCBase", 0, 0},
1700 {"MC68060Base", 0, "68060.library", "mc68060"},
1701 {"MC68040Base", 0, "68040.library", "mc68040"},
1702 {"MC680x0Base", 0, "680x0.library", "mc680x0"},
1703 {"P96Base", 0, "Picasso96API.library","Picasso96"},
1704 {"Warp3DPPCBase", 0, "Warp3DPPC.library" ,"Warp3D"},
1705 {"CyberGfxBase", 0, "cybergraphics.library", "cybergraphics"},
1706 {0, 0, 0, 0},
1709 /* CachePostDMA, CachePreDMA are done by #?DMA check */
1710 static const struct Pragma_ExecpName Pragma_ExecpNames[] = {
1711 {"VFWritef", "FWritef"},
1712 {"VFPrintf", "FPrintf"},
1713 {"VPrintf", "Printf"},
1714 {"ReadArgs", 0},
1715 {"FreeArgs", 0},
1716 {"CloneTagItems", 0},
1717 {"FindTagItem", 0},
1718 {"FreeTagItems", 0},
1719 {"GetTagData", 0},
1720 {"PackBoolTags", 0},
1721 {"PackStructureTags", 0},
1722 {"UnpackStructureTags", 0},
1723 {"BGUI_PackStructureTags", 0},
1724 {"BGUI_UnpackStructureTags", 0},
1725 {"Inet_NtoA", 0}, /* socket.library */
1726 {"vsyslog", "syslog"},
1727 {"NewPPCStackSwap", 0},
1728 {"FindTagItemPPC", 0},
1729 {"GetTagDataPPC", 0},
1730 {"GetInfo", 0},
1731 {"GetHALInfo", 0},
1732 {"SetScheduling", 0},
1733 {"W3D_CreateContext", "W3D_CreateContextTags"},
1734 {"W3D_RequestMode", "W3D_RequestModeTags"},
1735 {"W3D_AllocTexObj", "W3D_AllocTexObjTags"},
1736 {"W3D_BestModeID", "W3D_BestModeIDTags"},
1737 {0,0},
1740 /* This field contains functions, which should not be created as inlines with
1741 some targets. At the moment these are varargs functions, which are used in
1742 the MUI style using complicated defines. Theses functions are disabled in
1743 certain GCC and VBCC environments. */
1744 static const strptr NoCreateInlineFuncs[] = {
1745 "NewObject",
1746 "MUI_NewObject",
1747 "PM_MakeItem",
1751 /* For double tagcall names (currently only necessary for dos.library and
1752 datatypes.library). Only one alias supported for a function! */
1753 static const struct Pragma_AliasName Pragma_AliasNames[] = {
1754 {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL},
1755 {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL},
1756 {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL},
1757 {"SystemTagList", "System", FUNCFLAG_NORMAL},
1758 {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG},
1759 {0,0,0},
1762 /* special names, which get an x before name in BMAP files */
1763 static const strptr BMAPSpecial[] =
1764 {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
1765 "Translate", "Wait", "Write", 0};
1767 #define FIRST_KNOWN_RELEASE 30
1768 #define LAST_KNOWN_RELEASE 45
1769 static const strptr Release[] =
1771 "Release 1.0", /* V30 */
1772 "Release 1.1", /* V31 */
1773 "Preliminary Release 1.2", /* V32 */
1774 "Release 1.2", /* V33 */
1775 "Release 1.3", /* V34 */
1776 "Release 1.3 A2024", /* V35 */
1777 "Release 2.0", /* V36 */
1778 "Release 2.04", /* V37 */
1779 "Release 2.1", /* V38 */
1780 "Release 3.0", /* V39 */
1781 "Release 3.1", /* V40 */
1782 "Transitional Release 3.2", /* V41 */
1783 "Transitional Release 3.3", /* V42 */
1784 "Transitional Release 3.4", /* V43 */
1785 "Release 3.5", /* V44 */
1786 "Release 3.9", /* V45 */
1789 /* Keywords, which cannot be argument names. They are used case_insensitive to
1790 be sure they make no conflicts in non-C-languages as well.
1791 Currently these are mostly C keywords.
1793 static const strptr Keywords[] =
1795 "and", "and_eq", "asm", "auto", "bitand",
1796 "bitor", "break", "case", "catch", "char",
1797 "class", "compl", "const", "continue", "default",
1798 "delete", "do", "double", "else", "enum",
1799 "extern", "false", "float", "for", "friend",
1800 "goto", "if", "inline", "int", "long",
1801 "new", "not", "not_eq", "operator", "or",
1802 "or_eq", "private", "protected", "public", "register",
1803 "return", "short", "signed", "sizeof", "static",
1804 "struct", "switch", "template", "this", "throw",
1805 "true", "try", "typedef", "union", "unsigned",
1806 "virtual", "void", "volatile", "wchar_t", "while",
1807 "xor", "xor_eq", "RastPort", "Tag",
1811 #if !defined __SASC && !defined __AROS__ && !defined _WIN32 && !defined __CYGWIN__
1812 static int stricmp(const char *a, const char *b)
1814 while(*a && tolower(*a) == tolower(*b))
1816 ++a; ++b;
1818 return (tolower(*a) - tolower(*b));
1821 static int strnicmp(const char *a, const char *b, size_t num)
1823 while(num && *a && tolower(*a) == tolower(*b))
1825 ++a; ++b; --num;
1827 return num ? (tolower(*a) - tolower(*b)) : 0;
1829 #endif
1831 static strptr DupString(strptr Str, size_t Len)
1833 strptr res, r;
1834 if((res = r = AllocListMem(Len+1)))
1836 while(Len-- && *Str)
1837 *(r++) = *(Str++);
1838 *r = '\0';
1840 #ifdef DEBUG_OLD
1841 printf("DupString %s.\n", res);
1842 #endif
1843 return res;
1846 static strptr AllocListMem(size_t size)
1848 strptr a;
1849 #ifdef DEBUG_OLD
1850 printf("AllocListMem Size %d.\n", size);
1851 #endif
1852 if((a = (strptr) malloc(size)))
1853 memset(a, 0, size);
1854 return a;
1857 static strptr SkipBlanks(strptr OldPtr)
1859 while(*OldPtr == ' ' || *OldPtr == '\t')
1860 ++OldPtr;
1861 return OldPtr;
1864 static strptr SkipBlanksRet(strptr OldPtr)
1866 while(*OldPtr == ' ' || *OldPtr == '\t' || *OldPtr == '\n')
1867 ++OldPtr;
1868 return OldPtr;
1872 This function is used to skip over variable names.
1874 Inputs: OldPtr - pointer to the beginning of a string.
1876 Result: Pointer to the first character of the string, that is not one
1877 of a-z, A-Z, 0-9 or the underscore.
1880 static strptr SkipName(strptr OldPtr)
1882 while(isalnum(*OldPtr) || *OldPtr == '_')
1883 ++OldPtr;
1884 return OldPtr;
1887 static int IsNoCreateInlineFunc(const strptr name)
1889 const strptr *a;
1890 for(a = NoCreateInlineFuncs; *a; ++a)
1892 if(!strcmp(name, *a))
1893 return 1;
1895 return 0;
1898 static uint32 GetTypes(void)
1900 strptr ptr;
1901 size_t len;
1902 uint32 i;
1904 if(!(ptr = mygetfile(EXTTYPESFILE, &len)))
1906 #ifdef EXTTYPESFILEHIDDEN
1907 if((ptr = getenv("HOME")))
1909 strptr ptrh = EXTTYPESFILEHIDDEN;
1911 i = strlen(ptr);
1912 ptr = DupString(ptr, i + sizeof(EXTTYPESFILEHIDDEN) + 1);
1913 if(i && ptr[i-1] != '/')
1914 ptr[i++] = '/';
1915 while(*ptrh)
1916 ptr[i++] = *(ptrh++);
1917 ptr[i] = 0;
1918 ptr = mygetfile(ptr, &len);
1920 if(!ptr) /* disabled following if ptr != 0 */
1921 #endif
1922 if(!(ptr = mygetfile(EXTTYPESFILE2, &len)))
1924 DoError(ERR_NOFD2PRAGMATYPES, 0);
1925 ptr = (strptr) InternalTypes;
1926 len = sizeof(InternalTypes)-1;
1929 if((i = ScanTypes(ptr, len)) > 0)
1931 DoError(ERR_WRONG_TYPES_LINE, i);
1932 return 0;
1934 return 1;
1937 static strptr GetBaseType(void)
1939 static strptr basetype = 0;
1940 uint32 i;
1942 if(Flags2 & FLAG2_VOIDBASE)
1943 basetype = "void *";
1944 else if(!basetype)
1946 for(i = 0; !libtype && BaseName && Proto_LibTypes[i].BaseName; ++i)
1948 if(!(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
1950 libtype = Proto_LibTypes[i].StructureName;
1951 break;
1954 if(libtype && (basetype = malloc(strlen(libtype) + 9+1)))
1956 sprintf(basetype, "struct %s *", libtype);
1958 if(!libtype)
1959 basetype = "struct Library *";
1962 return basetype;
1965 static strptr GetBaseTypeLib(void)
1967 uint32 i;
1969 if(libtype)
1970 return libtype;
1972 for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
1974 if(Proto_LibTypes[i].StructureName &&
1975 !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
1977 return Proto_LibTypes[i].StructureName;
1980 return "Library";
1983 static strptr GetLibraryName(void)
1985 uint32 i;
1987 if(libname)
1988 return libname;
1990 for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
1992 if(Proto_LibTypes[i].LibraryName &&
1993 !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
1995 return (libname = Proto_LibTypes[i].LibraryName);
1998 if(!(libname = malloc(strlen(ShortBaseName)+9)))
1999 return 0;
2001 /* auto create name */
2002 for(i = 0; ShortBaseName[i]; ++i)
2003 libname[i] = ShortBaseName[i];
2004 strcpy(libname+i,".library");
2005 return libname;
2008 static strptr GetIFXName(void)
2010 static char IFXName[256];
2011 sprintf(IFXName, "%c%s", toupper(ShortBaseName[0]), ShortBaseName+1);
2012 return IFXName;
2015 static int32 MakeShortBaseName(void)
2017 strptr ptr, p2;
2018 uint32 i;
2020 ptr = p2 = args.infile;
2021 while(*p2)
2023 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
2024 ptr = p2+1;
2025 ++p2;
2028 /* first get name from file */
2030 p2 -= (sizeof(SFDFILEEXTENSION)-1);
2031 if(p2 > ptr && !stricmp(p2, SFDFILEEXTENSION))
2032 ShortBaseName = DupString(ptr, p2-ptr);
2033 p2 += sizeof(SFDFILEEXTENSION)-sizeof(FDFILEEXTENSION);
2034 if(p2 > ptr && !stricmp(p2, FDFILEEXTENSION))
2035 ShortBaseName = DupString(ptr, p2-ptr);
2037 /* then try exceptions (overriding filename) */
2038 if(BaseName)
2040 for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
2042 if(Proto_LibTypes[i].ShortBaseName &&
2043 !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
2045 if(!(ShortBaseName = DupString(Proto_LibTypes[i].ShortBaseName,
2046 strlen(Proto_LibTypes[i].ShortBaseName))))
2047 return 0;
2048 break;
2051 /* and last use default method */
2052 if(!ShortBaseName)
2053 ShortBaseName = DupString(BaseName, strlen(BaseName)-4);
2056 if(!ShortBaseName)
2057 return 0;
2059 ptr = ShortBaseName;
2060 while((*ptr = tolower(*ptr))) /* Convert to lowercase */
2061 ptr++;
2063 if((ShortBaseNameUpper = DupString(ShortBaseName, strlen(ShortBaseName))))
2065 ptr = ShortBaseNameUpper;
2066 while((*ptr = toupper(*ptr))) /* Convert to uppercase */
2067 ptr++;
2069 else
2070 return 0;
2072 return 1;
2075 static uint32 OpenDest(strptr name)
2077 static uint8 printedname = 0;
2078 strptr b, t;
2080 t = (strptr) tempbuf;
2081 if((b = args.to) && *b)
2083 while(*b)
2084 *(t++) = *(b++);
2085 if(*(t-1) != ':' && *(t-1) != '/')
2086 *(t++) = '/';
2088 *t = 0;
2090 if(!(Flags & FLAG_SINGLEFILE))
2091 printf("ResultFile: %s%s\n", tempbuf, name);
2092 else if(!printedname++)
2094 printf("ResultType: %s", tempbuf); printf(filenamefmt, "*");
2095 printf("\n");
2098 while(*name)
2099 *(t++) = *(name++);
2100 *t = 0;
2102 if(args.header)
2104 HEADER = mygetfile((strptr)tempbuf, &headersize);
2105 FindHeader();
2108 if((outfile = fopen((strptr)tempbuf, "wb")))
2109 return 1;
2110 DoError(ERR_OPEN_FILE, 0, tempbuf);
2111 return 0;
2114 static uint32 CloseDest(strptr name)
2116 if(outfile)
2118 fclose(outfile);
2119 outfile = 0;
2121 if(!(Flags & FLAG_DONE) || !Output_Error)
2123 strptr b, t;
2124 if(!Output_Error || !(Flags & FLAG_SINGLEFILE))
2125 DoError(ERR_EMPTY_FILE, 0);
2127 t = (strptr) tempbuf;
2128 if((b = args.to) && *b)
2130 while(*b)
2131 *(t++) = *(b++);
2132 if(*(t-1) != ':' && *(t-1) != '/')
2133 *(t++) = '/';
2135 while(*name)
2136 *(t++) = *(name++);
2137 *t = 0;
2139 remove((strptr)tempbuf);
2140 return 0;
2142 Flags &= ~FLAG_DONE; /* clear the flag */
2144 else
2145 return 0;
2146 return 1;
2149 static uint32 MakeTagFunction(struct AmiPragma *ap)
2151 size_t len = strlen(ap->FuncName);
2152 long i=0;
2154 #ifdef DEBUG_OLD
2155 printf("MakeTagFunction:\n");
2156 #endif
2158 if(!ap->NumArgs || ap->TagName)
2159 return 1;
2161 ++tagfuncs;
2162 ap->Flags |= AMIPRAGFLAG_OWNTAGFUNC;
2164 while(Pragma_ExecpNames[i].FunctionName && /* check the exception names */
2165 strcmp(ap->FuncName, Pragma_ExecpNames[i].FunctionName))
2166 ++i;
2168 if(Pragma_ExecpNames[i].FunctionName)
2170 if(!(ap->TagName = Pragma_ExecpNames[i].TagName))
2172 ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
2173 --tagfuncs;
2176 else if(ap->FuncName[len-1] == 'A')
2178 /* skip names with DMA or MESA at end */
2179 if(!strcmp(ap->FuncName+len-3, "DMA") ||
2180 !strcmp(ap->FuncName+len-4, "MESA") ||
2181 !strcmp(ap->FuncName+len-4, "RGBA") ||
2182 !strcmp(ap->FuncName+len-5, "AMIGA"))
2183 { ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC; --tagfuncs; return 1;}
2184 if(!(ap->TagName = DupString(ap->FuncName, len-1)))
2185 return 0;
2187 else if(!strcmp(ap->FuncName + len-7, "TagList"))
2189 if(!(ap->TagName = DupString(ap->FuncName, len-3)))
2190 return 0;
2191 ap->TagName[len-4] = 's';
2193 else if(!strcmp(ap->FuncName + len-4, "Args"))
2195 if(!(ap->TagName = DupString(ap->FuncName, len-4)))
2196 return 0;
2198 else if(!stricmp(ap->Args[ap->CallArgs-1].ArgName, "tags") ||
2199 !stricmp(ap->Args[ap->CallArgs-1].ArgName, "taglist"))
2201 if(!(ap->TagName = DupString(ap->FuncName, len+4)))
2202 return 0;
2203 memcpy(ap->TagName + len, "Tags", 5);
2205 else if(!stricmp(ap->Args[ap->CallArgs-1].ArgName, "args"))
2207 if(!(ap->TagName = DupString(ap->FuncName, len+4)))
2208 return 0;
2209 memcpy(ap->TagName + len, "Args", 5);
2211 else
2213 ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
2214 --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
2217 #ifdef DEBUG
2218 if(ap->TagName)
2219 printf("MakeTagFunction: %s / %s (...%s)\n", ap->TagName,
2220 ap->FuncName, ap->Args[ap->CallArgs-1].ArgName);
2221 #endif
2223 return 1;
2226 static void MakeLines(strptr buffer, uint32 size)
2228 if(size && buffer)
2230 /* make a real C++ zero string ending line */
2231 while(size--)
2233 if(*buffer == '\n')
2234 *buffer = '\0';
2235 ++buffer;
2237 *buffer = '\0';
2241 /* Do any special functions, which cannot be done with other exception
2242 stuff - currently only dos.library DoPkt function. */
2243 static uint32 SpecialFuncs(void)
2245 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last,
2246 *ap2 = (struct AmiPragma *) AmiPragma.First;
2248 /* first let one more go away, so we can detect if the DoPkt parts are
2249 already inserted in the FD file */
2251 while(ap2 && (struct AmiPragma *)(ap2->List.Next) != ap)
2252 ap2 = (struct AmiPragma *)(ap2->List.Next);
2254 if(ap2 && ap2->Bias == 0xF0 && ap->Bias != 0xF0 &&
2255 !strcmp("DoPkt", ap2->FuncName))
2257 struct AmiPragma *d;
2258 uint32 i;
2260 RemoveItem(&AmiPragma, (struct ShortList *) ap); /* add in correct order */
2261 for(i = 0; i < 5; ++i)
2263 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
2264 return 0;
2265 memcpy(d, ap2, sizeof(struct AmiPragma));
2266 d->FuncName = DupString(ap2->FuncName, 6);
2267 d->FuncName[5] = '0'+i;
2268 d->NumArgs = d->CallArgs = i + 2;
2269 AddItem(&AmiPragma, (struct ShortList *) d);
2271 AddItem(&AmiPragma, (struct ShortList *) ap);
2273 return 1;
2276 static void SortFDList(void)
2278 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.First, *ap2, *ap3;
2279 AmiPragma.First = AmiPragma.Last = 0;
2281 while(ap)
2283 ap3 = 0;
2284 ap2 = (struct AmiPragma *) AmiPragma.First;
2286 /* for FD2Inline style we need to use strcmp instead of stricmp here */
2287 while(ap2 && stricmp(ap2->FuncName, ap->FuncName) < 0)
2289 ap3 = ap2;
2290 ap2 = (struct AmiPragma *) ap2->List.Next;
2293 ap2 = ap;
2294 ap = (struct AmiPragma *) ap->List.Next;
2296 if(ap3)
2298 ap2->List.Next = (struct ShortList *) ap3->List.Next;
2299 ap3->List.Next = (struct ShortList *) ap2;
2301 else
2303 ap2->List.Next = AmiPragma.First;
2304 AmiPragma.First = (struct ShortList *) ap2;
2306 if(ap && !ap->List.Next)
2307 AmiPragma.Last = (struct ShortList *) ap2;
2311 static void AddAliasName(struct AmiPragma *ap, struct Pragma_AliasName *alias,
2312 uint32 linenum)
2314 int8 i;
2316 if(ap->NumAlias > NUMALIASNAMES)
2317 DoError(ERR_ALIASNAMES, linenum, NUMALIASNAMES);
2318 else
2320 /* prevent double names */
2321 for(i = 0; i < ap->NumAlias; ++i)
2323 if(!strcmp(ap->AliasName[i]->AliasName, alias->AliasName))
2324 return;
2326 ap->AliasName[ap->NumAlias++] = alias;
2330 static uint32 CheckNames(struct AmiPragma *ap)
2332 uint32 i, j;
2333 const strptr *k;
2335 #ifdef DEBUG_OLD
2336 printf("CheckNames\n");
2337 #endif
2338 for(i = 0; i < ap->CallArgs; ++i)
2340 if(!ap->Args[i].ArgName)
2342 if(!(ap->Args[i].ArgName = (strptr)
2343 AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
2344 return 0;
2345 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2347 else
2349 for(k = Keywords; *k; ++k)
2351 if(!stricmp(ap->Args[i].ArgName, *k))
2353 DoError(ERR_ARGNAME_KEYWORD_CONFLICT, ap->Line, i, *k);
2354 if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4
2355 +strlen(RegNames[ap->Args[i].ArgReg]))))
2356 return 0;
2357 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2360 for(j = 0; j < i; ++j)
2362 if(!stricmp(ap->Args[i].ArgName, ap->Args[j].ArgName))
2364 DoError(ERR_ARGNAME_ARGNAME_CONFLICT, ap->Line, i+1, j+1);
2365 if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4
2366 +strlen(RegNames[ap->Args[i].ArgReg]))))
2367 return 0;
2368 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2373 /* NOTE: the replaced argument names aren't checked for conflicts */
2374 /* replaced names are of style a0arg */
2375 return 1;
2378 static uint32 ScanSFDFile(enum ABI abi)
2380 uint32 _public = 1;
2381 int32 bias = -1;
2382 uint32 linenum;
2383 uint32 actcom = 0;
2384 uint32 functype = 0;
2386 Flags2 |= FLAG2_SFDMODE;
2388 if(strncmp("==id", in.pos, 4))
2389 DoError(ERR_SFD_START, 1);
2391 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
2393 if(*in.pos == '*')
2395 if(linenum < 5 && in.pos[1] == ' ' && in.pos[2] == '\"')
2397 strptr s;
2398 in.pos += 3;
2399 for(s = in.pos; *s && *s != '"'; ++s)
2401 if(*s) /* library name */
2403 #ifdef DEBUG_OLD
2404 printf("ScanSFDFile: found library name comment\n");
2405 #endif
2406 if(!libname)
2408 libname = in.pos;
2409 *(s++) = 0; /* clear the " */
2410 in.pos = s;
2411 Flags2 |= FLAG2_LIBNAMECOM;
2415 else
2417 if(actcom)
2418 *(in.pos-1) = '\n';
2419 else
2421 struct Comment *d;
2422 if(!(d = (struct Comment *) NewItem(&Comment)))
2423 return 0;
2424 d->Bias = bias;
2425 d->Data = in.pos;
2426 d->ReservedNum = 0;
2427 d->Version = 0;
2428 d->Private = _public ? 0 : 1;
2429 AddItem(&Comment, (struct ShortList *) d);
2430 actcom = 1;
2433 while(*in.pos)
2434 ++in.pos;
2436 else if(*in.pos == '=' && in.pos[1] == '=')
2438 in.pos += 2;
2439 actcom = 0; /* no Comment */
2441 if(!strnicmp(in.pos, "basetype", 8))
2443 #ifdef DEBUG_OLD
2444 printf("ScanSFDFile: found ==basetype\n");
2445 #endif
2446 if(!(Flags2 & FLAG2_LIBTYPE))
2448 if(libtype)
2449 DoError(ERR_LIBTYPE_DECLARED_TWICE, linenum);
2451 in.pos = SkipBlanks(in.pos+8);
2452 if(strncmp(in.pos, "struct", 6))
2453 DoError(ERR_EXPECTED_STRUCT, linenum);
2454 else
2456 in.pos = SkipBlanks(in.pos+6);
2457 if(!*in.pos)
2458 DoError(ERR_EXPECTED_LIBTYPE, linenum);
2459 else
2461 libtype = in.pos;
2462 in.pos = SkipName(libtype);
2463 if(*SkipBlanks(in.pos) != '*')
2464 DoError(ERR_EXPECTED_POINTERSIGN, linenum);
2465 if(*in.pos)
2466 *(in.pos++) = 0;
2470 else
2471 DoError(ERR_COMMANDLINE_LIBTYPE, linenum);
2472 while(*in.pos)
2473 ++in.pos;
2475 else if(!strnicmp(in.pos, "copyright", 9))
2477 Copyright = SkipBlanks(in.pos+9);
2478 while(*in.pos)
2479 ++in.pos;
2481 else if(!strnicmp(in.pos, "libname", 7))
2483 #ifdef DEBUG_OLD
2484 printf("ScanSFDFile: found ==libname\n");
2485 #endif
2486 if(!(Flags2 & FLAG2_LIBNAME))
2488 if(libname && !(Flags2 & FLAG2_LIBNAMECOM))
2489 DoError(ERR_LIBNAME_DECLARED_TWICE, linenum);
2491 in.pos = SkipBlanks(in.pos+7);
2492 if(!*in.pos)
2493 DoError(ERR_EXPECTED_LIBNAME, linenum);
2494 else
2495 in.pos = SkipName(libname = in.pos);
2497 else
2498 DoError(ERR_COMMANDLINE_LIBNAME, linenum);
2499 while(*in.pos)
2500 ++in.pos;
2502 else if(!strnicmp(in.pos, "base", 4))
2504 strptr oldptr;
2506 #ifdef DEBUG_OLD
2507 printf("ScanSFDFile: found ==base\n");
2508 #endif
2509 if(!(Flags & FLAG_BASENAME))
2511 if(BaseName)
2512 DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
2514 in.pos = SkipBlanks(in.pos+4);
2515 if(*in.pos != '_')
2516 DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
2517 else
2518 ++in.pos;
2520 BaseName = oldptr = in.pos;
2521 in.pos = SkipName(in.pos);
2522 if(!(in.pos-oldptr))
2523 DoError(ERR_EXPECTED_BASENAME, linenum);
2525 else
2527 DoError(ERR_COMMANDLINE_BASENAME, linenum);
2528 while(*in.pos)
2529 ++in.pos;
2532 else if(!strnicmp(in.pos, "bias", 4))
2534 strptr ptr;
2535 int32 newbias;
2537 #ifdef DEBUG_OLD
2538 printf("ScanSFDFile: found ==bias\n");
2539 #endif
2540 in.pos += 5;
2541 newbias = strtol(in.pos, &ptr, 10);
2542 if(ptr == in.pos)
2543 DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
2544 else if(newbias < 0)
2546 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
2547 bias = -newbias;
2549 else
2550 bias = newbias;
2551 in.pos = SkipName(in.pos);
2553 else if(!strnicmp(in.pos, "end", 3))
2555 bias = 0; break;
2557 else if(!strnicmp(in.pos, "public", 6))
2559 in.pos += 6;
2560 _public = 1;
2562 else if(!strnicmp(in.pos, "private", 7))
2564 in.pos += 7;
2565 _public = 0;
2567 else if(!strnicmp(in.pos, "abi", 3))
2569 #ifdef DEBUG_OLD
2570 printf("ScanSFDFile: found ==abi\n");
2571 #endif
2572 in.pos = SkipBlanks(in.pos+3);
2573 if(!strnicmp(in.pos, "M68k", 4))
2575 abi = ABI_M68K; in.pos += 4;
2577 else if(!strnicmp(in.pos, "PPC0", 4))
2579 abi = ABI_PPC0; in.pos += 4;
2581 else if(!strnicmp(in.pos, "PPC2", 4))
2583 abi = ABI_PPC2; in.pos += 4;
2585 else if(!strnicmp(in.pos, "PPC", 3))
2587 abi = ABI_PPC; in.pos += 3;
2589 else
2590 DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
2592 else if(!strnicmp(in.pos, "id", 2))
2594 if(IDstring)
2595 DoError(ERR_IDSTRING_DECLARED_TWICE, linenum);
2596 IDstring = in.pos = SkipBlanks(in.pos+2);
2597 if(strncmp(in.pos, "$Id: ", 5))
2599 DoError(ERR_EXCPECTED_IDSTRING, linenum);
2601 while(*in.pos)
2602 ++in.pos;
2603 if(*(in.pos-1) != '$')
2604 DoError(ERR_EXPECTED_ID_ENDSIGN, linenum);
2606 else if(!strnicmp(in.pos, "include", 7))
2608 struct Include *d;
2610 if(!(d = (struct Include *) NewItem(&Includes)))
2611 return 0;
2612 d->Include = SkipBlanks(in.pos+7);
2613 AddItem(&Includes, (struct ShortList *) d);
2614 while(*in.pos)
2615 ++in.pos;
2617 else if(!strnicmp(in.pos, "varargs", 7))
2619 if(bias == -1)
2620 DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
2621 else
2623 if(!functype)
2624 bias -= BIAS_OFFSET;
2625 functype |= FUNCFLAG_TAG;
2627 in.pos += 7;
2629 else if(!strnicmp(in.pos, "alias", 5))
2631 if(bias == -1)
2632 DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
2633 else
2635 if(!functype)
2636 bias -= BIAS_OFFSET;
2637 functype |= FUNCFLAG_ALIAS;
2639 in.pos += 5;
2641 else if(!strnicmp(in.pos, "version", 7))
2643 /* store version entries as comments */
2644 struct Comment *d;
2645 strptr ptr;
2646 int16 v;
2648 in.pos = SkipBlanks(in.pos+7);
2649 v = strtol(in.pos, &ptr, 10);
2650 #ifdef DEBUG_OLD
2651 printf("ScanSFDFile: found ==version %d\n", v);
2652 #endif
2653 if(ptr == in.pos || v < 0)
2654 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
2655 else
2657 if(!(d = (struct Comment *) NewItem(&Comment)))
2658 return 0;
2659 d->Bias = bias;
2660 d->Data = 0;
2661 d->ReservedNum = 0;
2662 d->Version = v;
2663 d->Private = _public ? 0 : 1;
2664 AddItem(&Comment, (struct ShortList *) d);
2665 in.pos = SkipName(in.pos);
2668 else if(!strnicmp(in.pos, "reserve", 7))
2670 /* store reserved entries as comments */
2671 struct Comment *d;
2672 strptr ptr;
2673 int16 v;
2675 in.pos = SkipBlanks(in.pos+7);
2676 v = strtol(in.pos, &ptr, 10);
2677 #ifdef DEBUG_OLD
2678 printf("ScanSFDFile: found ==reserve %d\n", v);
2679 #endif
2680 if(bias == -1)
2682 DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
2683 bias = BIAS_START;
2686 if(ptr == in.pos || v < 0)
2687 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
2688 else
2690 if(!(d = (struct Comment *) NewItem(&Comment)))
2691 return 0;
2692 d->Bias = bias;
2693 d->Data = 0;
2694 d->ReservedNum = v;
2695 d->Version = 0;
2696 d->Private = _public ? 0 : 1;
2697 AddItem(&Comment, (struct ShortList *) d);
2698 in.pos = SkipName(in.pos);
2699 bias += BIAS_OFFSET*v;
2702 else
2703 DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
2705 else /* function */
2707 uint32 ft, startlinenum;
2708 struct AmiPragma ap, *ap2;
2709 struct ClibData d, *f;
2710 strptr oldptr;
2711 uint32 maxreg;
2712 strptr data;
2714 actcom = 0;
2715 maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
2716 /* join lines, if necessary */
2717 startlinenum = linenum;
2718 data = in.pos;
2719 /* first open bracket */
2720 while(*data != '('/*)*/ && data < in.buf + in.size)
2721 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2722 ++data;
2723 ft = 0; /* this is needed for function pointer types, which have own
2724 brackets */
2725 /* first close bracket */
2726 while((*data != /*(*/')' || ft) && data < in.buf + in.size)
2728 if(!*data)
2730 *data = ' ';
2731 ++linenum;
2733 else if(*data == '('/*)*/)
2734 ++ft;
2735 else if(*data == /*(*/')')
2736 --ft;
2737 ++data;
2739 /* second open bracket */
2740 while(*data != '('/*)*/ && data < in.buf + in.size)
2741 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2742 /* second close bracket */
2743 while(*data != /*(*/')' && data < in.buf + in.size)
2744 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2745 if(data == in.buf + in.size)
2747 in.pos = data;
2748 DoError(ERR_UNEXPECTED_FILEEND, linenum);
2749 continue;
2752 ft = functype; functype = 0;
2753 memset(&ap, 0, sizeof(struct AmiPragma));
2754 memset(&d, 0, sizeof(struct ClibData));
2755 if(!GetCPPType(&d.ReturnType, in.pos, 1, 1))
2757 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE, startlinenum);
2758 while(*(in.pos++))
2760 continue;
2762 else if(d.ReturnType.Unknown)
2763 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT, startlinenum,
2764 d.ReturnType.Unknown);
2766 ap.FuncName = d.FuncName = SkipBlanks(d.ReturnType.TypeStart
2767 +d.ReturnType.FullLength);
2768 in.pos = SkipBlanks(SkipName(d.FuncName));
2770 if(*in.pos != '('/*)*/)
2772 DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
2773 ++in.pos;
2774 continue;
2776 *(SkipName(d.FuncName)) = 0;
2777 in.pos = SkipBlanks(++in.pos);
2779 oldptr = 0;
2780 while(*in.pos && *in.pos != /*(*/')')
2782 oldptr = (strptr) 1;
2783 if(d.NumArgs >= maxreg)
2785 DoError(ERR_TO_MUCH_ARGUMENTS, startlinenum);
2786 return 0;
2788 else if(!GetCPPType(&d.Args[d.NumArgs++], in.pos, 0, 0))
2790 DoError(ERR_UNKNOWN_VARIABLE_TYPE, startlinenum, d.NumArgs);
2791 break;
2793 else if(d.Args[d.NumArgs-1].Unknown)
2794 DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT, startlinenum, d.NumArgs,
2795 d.Args[d.NumArgs-1].Unknown);
2797 oldptr = in.pos = SkipBlanks(d.Args[d.NumArgs-1].TypeStart
2798 + d.Args[d.NumArgs-1].FullLength);
2799 if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS)
2801 if(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION)
2803 oldptr = d.Args[d.NumArgs-1].FunctionName;
2804 if(!oldptr)
2806 DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
2807 break;
2809 else if(!(oldptr = DupString(oldptr, SkipName(oldptr)-oldptr)))
2810 return 0;
2811 ap.Args[ap.CallArgs++].ArgName = oldptr;
2813 else
2815 ap.Args[ap.CallArgs++].ArgName = in.pos;
2816 in.pos = SkipName(in.pos);
2818 if(in.pos == oldptr)
2820 DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
2821 break;
2825 else
2826 ++ap.CallArgs;
2828 in.pos = SkipBlanks(in.pos);
2829 if(*in.pos != ',' && *in.pos != /*(*/')')
2831 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2832 break;
2834 if(*in.pos == ')')
2836 in.pos = SkipBlanks(++in.pos);
2837 if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS &&
2838 !(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION))
2839 *(SkipName(oldptr)) = 0;
2840 #ifdef DEBUG_OLD
2841 printf("Added last argument %d (%s) for %s (%d bytes)\n", d.NumArgs,
2842 oldptr, d.FuncName, d.Args[d.NumArgs-1].FullLength);
2843 #endif
2844 oldptr = 0;
2845 break;
2847 else
2849 in.pos = SkipBlanks(++in.pos);
2850 *(SkipName(oldptr)) = 0;
2851 #ifdef DEBUG_OLD
2852 printf("Added argument %d (%s) for %s (%d bytes)\n", d.NumArgs,
2853 oldptr, d.FuncName, d.Args[d.NumArgs-1].FullLength);
2854 #endif
2857 if(*in.pos == /*(*/')')
2858 ++in.pos;
2859 if(!oldptr) /* oldptr == 0 means parsing was valid */
2861 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
2862 return -1;
2864 memcpy(f, &d, sizeof(struct ClibData));
2866 if(!clibdata)
2867 clibdata = f;
2868 else
2870 struct ClibData *e = clibdata;
2871 while(e->Next)
2872 e = e->Next;
2873 e->Next = f;
2876 #ifdef DEBUG_OLD
2877 printf("Added prototype for %s (line %ld) with %d args\n", f->FuncName,
2878 startlinenum, f->NumArgs);
2879 #endif
2880 if(*(in.pos = SkipBlanks(in.pos)) != '('/*)*/)
2882 DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
2883 ++in.pos;
2884 continue;
2887 if(bias == -1)
2889 DoError(ERR_ASSUMING_BIAS_OF_30, startlinenum);
2890 bias = BIAS_START;
2893 ap.Bias = bias;
2894 ap.Abi = abi;
2895 ap.Line = startlinenum;
2896 bias += BIAS_OFFSET;
2898 if(_public)
2899 ap.Flags |= AMIPRAGFLAG_PUBLIC;
2901 if(abi != ABI_M68K)
2903 while(*in.pos && *in.pos != /*(*/')')
2904 ++in.pos;
2905 if(*in.pos != /*(*/')')
2907 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2908 ++in.pos;
2909 continue;
2911 ++in.pos;
2912 ap.NumArgs = ap.CallArgs;
2914 ap.Flags |= AMIPRAGFLAG_PPC;
2915 if(abi == ABI_PPC0)
2916 ap.Flags |= AMIPRAGFLAG_PPC0;
2917 else if(abi == ABI_PPC2)
2918 ap.Flags |= AMIPRAGFLAG_PPC2;
2920 else
2922 uint32 len;
2926 uint32 i;
2928 oldptr = in.pos = SkipBlanks(in.pos+1);
2930 if(*in.pos == /*(*/')' && !ap.NumArgs)
2931 break;
2933 in.pos = SkipName(oldptr);
2934 len = in.pos-oldptr;
2936 for(i = 0; i < MAXREG; ++i)
2937 if(!strnicmp(RegNames[i], oldptr, len))
2938 break;
2940 if(i == MAXREG)
2942 DoError(ERR_EXPECTED_REGISTER_NAME, startlinenum);
2943 break;
2945 else if(i == REG_A6)
2946 ap.Flags |= AMIPRAGFLAG_A6USE;
2947 else if(i == REG_A5)
2948 ap.Flags |= AMIPRAGFLAG_A5USE;
2949 else if(i == REG_A4)
2950 ap.Flags |= AMIPRAGFLAG_A4USE;
2951 else if(i == REG_D7)
2952 ap.Flags |= AMIPRAGFLAG_D7USE;
2953 else if(i == REG_A7)
2955 DoError(ERR_A7_NOT_ALLOWED, startlinenum);
2956 break;
2958 else if(i >= REG_FP0)
2959 ap.Flags |= AMIPRAGFLAG_FLOATARG;
2961 ap.Args[ap.NumArgs].ArgReg = i;
2963 for(i = 0; i < ap.NumArgs; i++)
2965 if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
2967 DoError(ERR_REGISTER_USED_TWICE, startlinenum);
2968 break;
2971 if(i < ap.NumArgs)
2972 break;
2974 ++ap.NumArgs;
2976 in.pos = SkipBlanks(in.pos);
2977 if(*in.pos != ',' && *in.pos != '-' && *in.pos != '/' &&
2978 *in.pos != /*(*/')')
2980 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2981 break;
2983 } while(*in.pos != /*(*/')');
2985 if(*in.pos != /*(*/')')
2987 while(*(in.pos++))
2988 ++in.pos;
2989 continue;
2991 else
2992 ++in.pos;
2994 ap2 = (struct AmiPragma *)(AmiPragma.Last);
2995 if(ft && !(ft & FUNCFLAG_TAG) && ap.NumArgs != ap2->NumArgs)
2996 ft = 0; /* like DoPkt, handle as seperate function */
2997 if(ft) /* handle alias and varargs */
2999 if(ap2->TagName || (ft & FUNCFLAG_ALIAS))
3001 struct Pragma_AliasName *p;
3003 if((p = (struct Pragma_AliasName *)
3004 AllocListMem(sizeof(struct Pragma_AliasName))))
3006 p->FunctionName = ap2->TagName;
3007 p->AliasName = ap.FuncName;
3008 p->Type = (ft & FUNCFLAG_TAG) ? FUNCFLAG_TAG : FUNCFLAG_NORMAL;
3009 AddAliasName(ap2, p, startlinenum);
3011 else
3012 return 0;
3014 else
3016 ap2->TagName = ap.FuncName;
3017 ++tagfuncs;
3019 if(ap.CallArgs != ap2->CallArgs)
3021 if(ap2->CallArgs + 1 == ap.CallArgs && d.Args[d.NumArgs-1].Type
3022 == CPP_TYPE_VARARGS)
3024 --ap.CallArgs;
3025 if(abi != ABI_M68K)
3026 --ap.NumArgs;
3029 if(ap.NumArgs != ap2->NumArgs)
3031 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
3033 else if(abi == ABI_M68K)
3035 uint32 i;
3037 for(i = 0; i < ap2->NumArgs; ++i)
3039 if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
3041 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
3042 break;
3047 else if(abi == ABI_M68K)
3049 if(ap.CallArgs != ap.NumArgs)
3050 { /* this is surely no longer necessary, as there wont be any
3051 varargs functions here */
3052 if(ap.CallArgs == ap.NumArgs+1 && d.Args[d.NumArgs-1].Type
3053 == CPP_TYPE_VARARGS)
3054 --ap.CallArgs;
3055 else
3056 ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
3059 ap.Flags |= AMIPRAGFLAG_M68K;
3061 if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
3062 DoError(ERR_FLOATARG_NOT_ALLOWED, startlinenum);
3063 else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
3064 && !(Flags & FLAG_PPCONLY))
3065 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3066 struct AmiPragma *d;
3067 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3068 return 0;
3069 memcpy(d, &ap, sizeof(struct AmiPragma));
3070 if(!CheckNames(d))
3071 return 0;
3072 AddItem(&AmiPragma, (struct ShortList *) d);
3075 else
3077 if(!(Flags & FLAG_NOPPC))
3079 struct AmiPragma *d;
3080 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3081 return 0;
3082 memcpy(d, &ap, sizeof(struct AmiPragma));
3083 if(!CheckNames(d))
3084 return 0;
3085 AddItem(&AmiPragma, (struct ShortList *) d);
3091 in.pos = SkipBlanks(in.pos);
3092 if(*in.pos)
3093 DoError(ERR_EXTRA_CHARACTERS, linenum);
3094 ++in.pos; /* skip '\0' */
3097 if(bias)
3098 DoError(ERR_MISSING_SFDEND, 0);
3100 return 1;
3103 static uint32 ScanFDFile(void)
3105 uint32 _public = 1;
3106 int32 bias = -1;
3107 uint32 linenum;
3108 size_t len;
3109 uint32 actcom = 0;
3110 uint32 shadowmode = 0;
3111 enum ABI abi = ABI_M68K;
3113 if(defabi)
3115 if(!stricmp(defabi, "M68k"))
3116 abi = ABI_M68K;
3117 else if(!stricmp(defabi, "PPC0"))
3118 abi = ABI_PPC0;
3119 else if(!stricmp(defabi, "PPC2"))
3120 abi = ABI_PPC2;
3121 else if(!stricmp(defabi, "PPC"))
3122 abi = ABI_PPC;
3123 else
3124 DoError(ERR_UNKNOWN_ABI, 0, defabi);
3127 if(in.size > 10 && in.pos[0] == '=' && in.pos[1] == '=')
3128 return ScanSFDFile(abi);
3130 #ifdef DEBUG_OLD
3131 printf("ScanFDFile:\n");
3132 #endif
3134 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
3136 if(*in.pos == '*') /* Comment */
3138 strptr oldpos = in.pos;
3139 #ifdef DEBUG_OLD
3140 printf("ScanFDFile: found a comment\n");
3141 #endif
3142 in.pos = SkipBlanks(in.pos+1);
3143 if(!strnicmp(in.pos, "notagcall", 9))
3145 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last;
3147 if(ap->TagName)
3149 --tagfuncs; ap->TagName = 0;
3150 ap->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
3152 in.pos = SkipBlanks(in.pos + 9);
3154 else if(!strnicmp(in.pos, "tagcall", 7)) /* Tag to create? */
3156 struct AmiPragma *prevpragma = (struct AmiPragma *) AmiPragma.Last;
3158 in.pos = SkipBlanks(in.pos + 7);
3159 if(!prevpragma)
3161 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
3162 ++in.pos;
3163 continue;
3166 if(!prevpragma->NumArgs)
3168 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
3169 ++in.pos;
3170 continue;
3173 /* Get the tag functions name. */
3175 if(!prevpragma->TagName && (_public || (Flags & FLAG_PRIVATE)))
3176 ++tagfuncs;
3178 if(*in.pos)
3180 strptr oldptr, tptr = prevpragma->TagName;
3182 len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
3183 if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len)))
3184 return 0;
3186 if(*in.pos == '-')
3188 strptr removeptr;
3190 oldptr = in.pos = SkipBlanks(in.pos+1);
3191 in.pos = SkipName(in.pos);
3192 if((len = in.pos-oldptr))
3194 removeptr = prevpragma->TagName+strlen(prevpragma->TagName)-len;
3195 if(strncmp(removeptr, oldptr, len))
3197 #ifdef DEBUG_OLD
3198 printf("ScanFDFile: *tagcall -: %s, %s, %d\n", removeptr, oldptr, len);
3199 #endif
3200 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
3201 prevpragma->TagName = tptr;
3202 ++in.pos;
3203 continue;
3206 *removeptr = '\0';
3208 in.pos = SkipBlanks(in.pos);
3210 if(*in.pos == '+')
3211 in.pos = SkipBlanks(in.pos+1);
3212 else
3213 *in.pos = toupper(*in.pos);
3215 in.pos = SkipName((oldptr = in.pos));
3216 len = in.pos-oldptr;
3217 if(len)
3219 uint32 a = strlen(prevpragma->TagName);
3220 memcpy(prevpragma->TagName+a, oldptr, len);
3221 prevpragma->TagName[a+len] = '\0';
3224 else if(!prevpragma->TagName)
3226 len = strlen(prevpragma->FuncName);
3227 if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len+4)))
3228 return 0;
3229 memcpy(prevpragma->TagName + len, "Tags", 5);
3232 else
3234 if(actcom)
3235 *(oldpos-1) = '\n';
3236 else
3238 struct Comment *d;
3239 if(!(d = (struct Comment *) NewItem(&Comment)))
3240 return 0;
3241 d->Bias = bias;
3242 d->Data = oldpos;
3243 d->ReservedNum = 0;
3244 d->Version = 0;
3245 d->Private = _public ? 0 : 1;
3246 AddItem(&Comment, (struct ShortList *) d);
3247 actcom = 1;
3249 while(*in.pos)
3250 ++in.pos;
3253 else if(*in.pos == '#' && in.pos[1] == '#')
3255 in.pos += 2;
3256 actcom = 0; /* no Comment */
3258 if(!strnicmp(in.pos, "base", 4))
3260 strptr oldptr;
3262 #ifdef DEBUG_OLD
3263 printf("ScanFDFile: found ##base\n");
3264 #endif
3265 if(!(Flags & FLAG_BASENAME))
3267 if(BaseName)
3268 DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
3270 in.pos = SkipBlanks(in.pos+4);
3271 if(*in.pos != '_')
3272 DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
3273 else
3274 ++in.pos;
3276 BaseName = oldptr = in.pos;
3277 in.pos = SkipName(in.pos);
3278 if(!(in.pos-oldptr))
3279 DoError(ERR_EXPECTED_BASENAME, linenum);
3281 else
3283 DoError(ERR_COMMANDLINE_BASENAME, linenum);
3284 while(*in.pos)
3285 ++in.pos;
3288 else if(!strnicmp(in.pos, "bias", 4))
3290 strptr ptr;
3291 int32 newbias;
3293 #ifdef DEBUG_OLD
3294 printf("ScanFDFile: found ##bias\n");
3295 #endif
3296 in.pos += 5;
3297 newbias = strtol(in.pos, &ptr, 10);
3298 if(ptr == in.pos)
3299 DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
3300 else if(newbias < 0)
3302 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
3303 bias = -newbias;
3305 else
3306 bias = newbias;
3307 in.pos = SkipName(in.pos);
3309 else if(!strnicmp(in.pos, "end", 3))
3311 bias = 0; break;
3313 else if(!strnicmp(in.pos, "shadow", 6)) /* introduced by Storm */
3315 in.pos += 6;
3316 if(bias == -1 || !AmiPragma.First)
3317 DoError(ERR_EARLY_SHADOW, linenum);
3318 else
3320 bias -= BIAS_OFFSET;
3321 shadowmode = 1;
3324 else if(!strnicmp(in.pos, "public", 6))
3326 in.pos += 6;
3327 _public = 1;
3329 else if(!strnicmp(in.pos, "private", 7))
3331 in.pos += 7;
3332 _public = 0;
3334 else if(!strnicmp(in.pos, "abi", 3))
3336 #ifdef DEBUG_OLD
3337 printf("ScanFDFile: found ##abi\n");
3338 #endif
3339 in.pos = SkipBlanks(in.pos+3);
3340 if(!strnicmp(in.pos, "M68k", 4))
3342 abi = ABI_M68K; in.pos += 4;
3344 else if(!strnicmp(in.pos, "PPC0", 4))
3346 abi = ABI_PPC0; in.pos += 4;
3348 else if(!strnicmp(in.pos, "PPC2", 4))
3350 abi = ABI_PPC2; in.pos += 4;
3352 else if(!strnicmp(in.pos, "PPC", 3))
3354 abi = ABI_PPC; in.pos += 3;
3356 else
3357 DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
3359 else
3360 DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
3362 else
3364 strptr oldptr;
3365 uint32 maxreg;
3366 struct AmiPragma ap, *ap2;
3368 #ifdef DEBUG_OLD
3369 printf("ScanFDFile: scan Function\n");
3370 #endif
3371 memset(&ap, 0, sizeof(struct AmiPragma));
3372 actcom = 0;
3374 oldptr = in.pos = SkipBlanks(in.pos);
3375 in.pos = SkipName(oldptr);
3376 if(!(len = in.pos-oldptr))
3378 DoError(ERR_MISSING_FUNCTION_NAME, linenum);
3379 ++in.pos;
3380 continue;
3383 ap.FuncName = oldptr;
3385 in.pos = SkipBlanks(in.pos);
3386 if(*in.pos != '('/*)*/)
3388 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3389 ++in.pos;
3390 continue;
3393 oldptr[len] = '\0'; /* create c string of FunctionName */
3395 #ifdef DEBUG_OLD
3396 printf("ScanFDFile: found function %s\n", ap.FuncName);
3397 #endif
3399 maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
3402 oldptr = in.pos = SkipBlanks(in.pos+1);
3404 if(*in.pos == '*') /* strange OS3.9 files */
3406 DoError(ERR_ILLEGAL_CHARACTER_DETECTED, linenum);
3407 oldptr = in.pos = SkipBlanks(in.pos+1);
3410 if(*in.pos == /*(*/')' && !ap.CallArgs)
3411 break;
3413 if(ap.CallArgs >= maxreg)
3415 DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
3418 if(!strncmp(in.pos, "void", 4))
3420 /* allows "(void)" instead of ()" */
3421 in.pos = SkipBlanks(in.pos + 4);
3422 if(*in.pos != /*(*/')')
3423 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3424 break;
3427 if(!strncmp(in.pos, "...", 3))
3429 ap.Flags = AMIPRAGFLAG_VARARGS;
3430 ap.Args[ap.CallArgs++].ArgName = 0;
3431 in.pos = SkipBlanks(in.pos+3);
3432 if(*in.pos != /*(*/')')
3433 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3434 break;
3437 in.pos = SkipName(oldptr);
3438 if(*in.pos == '*')
3439 ++in.pos;
3440 if(!(len = in.pos-oldptr))
3442 DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
3443 ap.Args[ap.CallArgs++].ArgName = 0;
3445 else
3447 ap.Args[ap.CallArgs++].ArgName = oldptr;
3448 oldptr = in.pos;
3449 in.pos = SkipBlanks(in.pos);
3451 if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
3453 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3454 break;
3456 if(*in.pos != /*(*/')') /* create c string ending */
3457 *oldptr = '\0';
3458 } while(*in.pos != /*(*/')');
3460 if(*in.pos != /*(*/')')
3462 while(*(in.pos++))
3463 ++in.pos;
3464 continue;
3466 else
3467 *oldptr = '\0'; /* create c string ending for last argument */
3469 if(bias == -1)
3471 DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
3472 bias = BIAS_START;
3475 ap.Bias = bias;
3476 ap.Abi = abi;
3477 ap.Line = linenum;
3478 bias += BIAS_OFFSET;
3480 if(_public)
3481 ap.Flags |= AMIPRAGFLAG_PUBLIC;
3483 in.pos = SkipBlanks(in.pos+1);
3485 if(*in.pos || ap.CallArgs)
3486 /* support for FD's without second empty bracket pair */
3488 if(*in.pos != '('/*)*/)
3490 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3491 ++in.pos;
3492 continue;
3495 if(abi == ABI_M68K)
3499 uint32 i;
3501 oldptr = in.pos = SkipBlanks(in.pos + 1);
3503 if(*in.pos == /*(*/')' && !ap.NumArgs)
3504 break;
3506 if(!strncmp(in.pos, "base", 4))
3508 in.pos = SkipBlanks(in.pos + 4);
3509 if(*in.pos == ',')
3511 in.pos = SkipBlanks(in.pos + 1);
3512 if(!strncmp(in.pos, "sysv",4))
3514 /* MorphOS V.4 with base in r3: (base,sysv) */
3515 ap.Flags |= AMIPRAGFLAG_MOSBASESYSV;
3516 ap.NumArgs = ap.CallArgs;
3517 in.pos = SkipBlanks(in.pos + 4);
3518 if(*in.pos != /*(*/')')
3519 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3520 break;
3524 else if(!strncmp(in.pos, "sysv", 4))
3526 in.pos = SkipBlanks(in.pos + 4);
3527 if(*in.pos == ',')
3529 in.pos = SkipBlanks(in.pos + 1);
3530 if(!strncmp(in.pos, "r12base",7))
3532 /* MorphOS V.4 without passing base: (sysv) */
3533 ap.Flags |= AMIPRAGFLAG_MOSSYSVR12;
3534 ap.NumArgs = ap.CallArgs;
3535 in.pos = SkipBlanks(in.pos + 7);
3536 if(*in.pos != /*(*/')')
3537 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3538 break;
3541 else if (*in.pos == /*(*/')')
3543 /* MorphOS V.4 without passing base: (sysv) */
3544 ap.Flags |= AMIPRAGFLAG_MOSSYSV;
3545 ap.NumArgs = ap.CallArgs;
3546 break;
3548 else
3550 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3551 break;
3555 in.pos = SkipName(oldptr);
3556 len = in.pos-oldptr;
3558 for(i = 0; i < MAXREG; ++i)
3559 if(!strnicmp(RegNames[i], oldptr, len))
3560 break;
3562 if(i == MAXREG)
3564 DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
3565 break;
3567 else if(i == REG_A6)
3568 ap.Flags |= AMIPRAGFLAG_A6USE;
3569 else if(i == REG_A5)
3570 ap.Flags |= AMIPRAGFLAG_A5USE;
3571 else if(i == REG_A4)
3572 ap.Flags |= AMIPRAGFLAG_A4USE;
3573 else if(i == REG_D7)
3574 ap.Flags |= AMIPRAGFLAG_D7USE;
3575 else if(i == REG_A7)
3577 DoError(ERR_A7_NOT_ALLOWED, linenum);
3578 break;
3580 else if(i >= REG_FP0)
3581 ap.Flags |= AMIPRAGFLAG_FLOATARG;
3583 ap.Args[ap.NumArgs].ArgReg = i;
3585 for(i = 0; i < ap.NumArgs; i++)
3587 if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
3589 DoError(ERR_REGISTER_USED_TWICE, linenum);
3590 break;
3593 if(i < ap.NumArgs)
3594 break;
3596 ++ap.NumArgs;
3598 in.pos = SkipBlanks(in.pos);
3599 if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
3601 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3602 break;
3604 } while(*in.pos != /*(*/')');
3606 if(*in.pos != /*(*/')')
3608 while(*(in.pos++))
3609 ++in.pos;
3610 continue;
3612 else
3613 ++in.pos;
3615 else
3617 while(*in.pos && *in.pos != /*(*/')')
3618 ++in.pos;
3619 if(*in.pos != /*(*/')')
3621 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3622 ++in.pos;
3623 continue;
3625 ++in.pos;
3626 ap.NumArgs = ap.CallArgs;
3628 ap.Flags |= AMIPRAGFLAG_PPC;
3629 if(abi == ABI_PPC0)
3630 ap.Flags |= AMIPRAGFLAG_PPC0;
3631 else if(abi == ABI_PPC2)
3632 ap.Flags |= AMIPRAGFLAG_PPC2;
3635 else
3636 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3638 ap2 = (struct AmiPragma *)(AmiPragma.Last);
3639 if(shadowmode)
3641 if(ap2->TagName && !(ap2->Flags & AMIPRAGFLAG_OWNTAGFUNC))
3643 struct Pragma_AliasName *p;
3644 DoError(ERR_DOUBLE_VARARGS, linenum);
3646 if((p = (struct Pragma_AliasName *)
3647 AllocListMem(sizeof(struct Pragma_AliasName))))
3649 p->FunctionName = ap2->TagName;
3650 p->AliasName = ap.FuncName;
3651 p->Type = FUNCFLAG_TAG;
3652 AddAliasName(ap2, p, linenum);
3654 else
3655 return 0;
3656 #ifdef DEBUG_OLD
3657 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2->TagName);
3658 #endif
3660 else
3662 #ifdef DEBUG_OLD
3663 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2->TagName);
3664 #endif
3665 ap2->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
3666 ap2->TagName = ap.FuncName;
3667 ++tagfuncs;
3669 if(ap.NumArgs != ap2->NumArgs)
3670 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3671 else if(abi == ABI_M68K)
3673 uint32 i;
3675 for(i = 0; i < ap2->NumArgs; ++i)
3677 if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
3679 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3680 break;
3685 /* handle them as alias instead seperate */
3686 else if(ap2 && ap2->Bias == ap.Bias && ap2->NumArgs == ap.NumArgs)
3688 struct Pragma_AliasName *p;
3690 if((p = (struct Pragma_AliasName *)
3691 AllocListMem(sizeof(struct Pragma_AliasName))))
3693 p->FunctionName = ap2->TagName;
3694 p->AliasName = ap.FuncName;
3695 p->Type = FUNCFLAG_NORMAL;
3696 AddAliasName(ap2, p, linenum);
3698 if(abi == ABI_M68K)
3700 uint32 i;
3702 for(i = 0; i < ap2->NumArgs; ++i)
3704 if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
3706 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3707 break;
3712 else
3714 if(ap.Flags & AMIPRAGFLAG_VARARGS)
3716 ap.TagName = ap.FuncName;
3717 ap.FuncName = 0;
3719 else if((_public || (Flags & FLAG_PRIVATE)) &&
3720 !MakeTagFunction(&ap))
3721 return 0;
3722 else /* check the alias names */
3724 uint32 i = 0;
3726 while(Pragma_AliasNames[i].FunctionName)
3728 if(!strcmp(ap.FuncName, Pragma_AliasNames[i].FunctionName) ||
3729 (ap.TagName && !strcmp(ap.TagName,
3730 Pragma_AliasNames[i].FunctionName)))
3732 AddAliasName(&ap, (struct Pragma_AliasName *)
3733 &Pragma_AliasNames[i], linenum);
3735 ++i;
3739 if(abi == ABI_M68K)
3741 if(ap.CallArgs != ap.NumArgs)
3742 ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
3744 ap.Flags |= AMIPRAGFLAG_M68K;
3746 if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
3747 DoError(ERR_FLOATARG_NOT_ALLOWED, linenum);
3748 else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
3749 && !(Flags & FLAG_PPCONLY))
3750 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3751 struct AmiPragma *d;
3752 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3753 return 0;
3754 memcpy(d, &ap, sizeof(struct AmiPragma));
3755 if(!CheckNames(d))
3756 return 0;
3757 AddItem(&AmiPragma, (struct ShortList *) d);
3758 if(!SpecialFuncs())
3759 return 0;
3762 else
3764 if(!(Flags & FLAG_NOPPC))
3766 struct AmiPragma *d;
3767 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3768 return 0;
3769 memcpy(d, &ap, sizeof(struct AmiPragma));
3770 if(!CheckNames(d))
3771 return 0;
3772 AddItem(&AmiPragma, (struct ShortList *) d);
3774 if(!SpecialFuncs())
3775 return 0;
3780 shadowmode = 0;
3783 in.pos = SkipBlanks(in.pos);
3784 if(*in.pos)
3785 DoError(ERR_EXTRA_CHARACTERS, linenum);
3786 ++in.pos; /* skip '\0' */
3789 if(bias)
3790 DoError(ERR_MISSING_END, 0);
3792 return 1;
3795 static int32 ScanTypes(strptr ptr, uint32 size)
3797 struct CPP_ExternNames *a = 0, *b = 0;
3798 strptr endptr = ptr+size;
3799 int32 line;
3801 for(line = 1; ptr < endptr; ++line)
3803 struct CPP_ExternNames *n;
3805 if(*ptr == '*') /* skip comments */
3807 while(ptr < endptr && *(ptr++) != '\n')
3810 else if((n = (struct CPP_ExternNames *)
3811 AllocListMem(sizeof(struct CPP_ExternNames))))
3813 strptr wptr;
3815 n->Type = ptr; /* store start */
3817 while(ptr < endptr && *ptr != ':' && *ptr != '\n' && *ptr != '\t'
3818 && *ptr != ' ')
3819 ++ptr;
3820 wptr = SkipBlanks(ptr);
3821 if(*(wptr++) != ':')
3822 return line;
3823 *ptr = 0;
3825 n->NameType.StructureName = n->Type;
3826 n->NameType.StructureLength = ptr-n->Type; /* for struct ! types */
3828 if(!GetCPPType(&n->NameType, (ptr = SkipBlanks(wptr)), 0, 1))
3829 return line;
3830 #ifdef DEBUG_OLD
3831 printf("'%20s', slen %2d, typelen %3d, pntd %d, type %c, sn '%.3s'\n",
3832 n->Type, n->NameType.StructureLength, n->NameType.FullLength,
3833 n->NameType.PointerDepth, n->NameType.Type ? n->NameType.Type : 's',
3834 n->NameType.StructureName ? n->NameType.StructureName : "<e>");
3835 #endif
3836 ptr = SkipBlanks(n->NameType.TypeStart+n->NameType.FullLength);
3837 if(*(ptr++) != '\n')
3839 #ifdef DEBUG_OLD
3840 printf("%.30s\n", ptr);
3841 #endif
3842 return line;
3845 if(!a)
3846 b = n;
3847 else
3848 a->Next = n;
3849 a = n;
3851 else
3852 return -1;
3854 extnames = b; /* now store the list */
3855 return 0;
3858 static void FindHeader(void)
3860 strptr str = HEADER;
3861 uint32 mode = 0;
3865 if(!mode)
3866 HEADER = str;
3868 if(*str == '/')
3870 ++str;
3871 if(*str == '*')
3873 mode = 2; break;
3875 else if(*str == '/')
3876 mode = 1;
3878 else if(*str == '*' || *str == ';')
3879 mode = 1;
3880 else if(*str == '{'/*}*/)
3882 mode = 3; break;
3884 else if(*str == '('/*)*/ && *(++str) == '*')
3886 mode = 4; break;
3888 else if(mode)
3889 break;
3890 while(*str && *(str++) != '\n')
3892 } while(*str);
3894 if(mode == 2)
3896 while(*str && (*(str-1) != '*' || *str != '/'))
3897 ++str;
3898 while(*str && *(str++) != '\n')
3901 else if(mode == 3)
3903 while(*str && *str != /*{*/'}')
3904 ++str;
3905 while(*str && *(str++) != '\n')
3908 else if(mode == 4)
3910 while(*str && (*(str-1) != '*' || *str != /*(*/')'))
3911 ++str;
3912 while(*str && *(str++) != '\n')
3916 if(mode)
3917 headersize = str-HEADER;
3918 else
3920 HEADER = 0; headersize = 0;
3924 /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
3925 static uint32 GetRegisterData(struct AmiPragma *ap)
3927 /* usage of result:
3928 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
3929 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
3931 register uint32 i, data = 0, reg;
3933 for(i = 0; i < ap->NumArgs; ++i)
3935 if((reg = ap->Args[i].ArgReg) <= REG_FP0)
3937 if(reg >= 10 || (reg >= 2 && reg <= 7)) /* A2-A7 and D2-D7 */
3938 data |= (1 << (reg + 16)) + (1 << (15 - reg));
3941 if(data) /* set A6 only when other register used */
3942 data |= 0x40000002;
3943 return data;
3946 static uint16 GetFRegisterData(struct AmiPragma *ap)
3948 /* usage of result:
3949 F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
3950 F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
3952 register uint32 i, reg;
3953 register uint16 data = 0;
3955 for(i = 0; i < ap->NumArgs; ++i)
3957 if((reg = ap->Args[i].ArgReg) >= REG_FP2)
3959 reg -= REG_FP0;
3960 data |= (1 << (reg + 8)) + (1 << (7 - reg));
3963 return data;
3966 static uint32 OutputXDEF(uint32 offset, strptr format, ...)
3968 uint8 buf[150];
3969 va_list a;
3970 size_t i;
3972 va_start(a, format);
3973 i = vsprintf((strptr)(buf+4), format, a);
3974 va_end(a);
3975 while(i&3)
3976 buf[4+i++] = 0;
3977 EndPutM32(buf+4+i, offset); /* the definition offset */
3979 EndPutM32(buf, (EXT_DEF<<24) + (i>>2));
3981 return DoOutputDirect(buf, i+8);
3984 static uint32 OutputXREF(uint32 offset, uint32 type, strptr format, ...)
3986 uint8 buf[150];
3987 va_list a;
3988 size_t i;
3990 va_start(a, format);
3991 i = vsprintf((strptr)(buf+4), format, a);
3992 va_end(a);
3993 while(i&3)
3994 buf[4+i++] = 0;
3995 EndPutM32(buf+4+i, 1); /* 1 reference */
3996 EndPutM32(buf+8+i, offset); /* the definition offset */
3998 EndPutM32(buf, (type << 24) + (i>>2));
4000 return DoOutputDirect(buf, i+12);
4003 static uint32 OutputXREF2(uint32 offset1, uint32 offset2, uint32 type,
4004 strptr format, ...)
4006 uint8 buf[150];
4007 va_list a;
4008 size_t i;
4010 va_start(a, format);
4011 i = vsprintf((strptr)(buf+4), format, a);
4012 va_end(a);
4013 while(i&3)
4014 buf[4+i++] = 0;
4015 EndPutM32(buf+4+i, 2); /* 2 references */
4016 EndPutM32(buf+8+i, offset1); /* the definition offset */
4017 EndPutM32(buf+12+i, offset2); /* the definition offset */
4019 EndPutM32(buf, (type << 24) + (i>>2));
4021 return DoOutputDirect(buf, i+16);
4024 static uint32 OutputSYMBOL(uint32 offset, strptr format, ...)
4026 va_list a;
4027 uint8 buf[150];
4028 size_t i;
4030 va_start(a, format);
4031 i = vsprintf((strptr)(buf+4), format, a);
4032 va_end(a);
4033 while(i&3)
4034 buf[4+i++] = 0;
4035 EndPutM32(buf+4+i, offset);
4037 EndPutM32(buf, (0 << 24) + (i>>2));
4039 return DoOutputDirect(buf, i+8);
4042 static uint8 *AsmStackCopy(uint8 *data, struct AmiPragma *ap, uint32 flags,
4043 uint32 ofs)
4045 uint32 i, j, k, l, tofs;
4047 if(Flags & FLAG_PASCAL)
4049 k = ap->NumArgs;
4051 while(k)
4053 if(ap->Args[k-1].ArgReg >= REG_FP0)
4055 struct ClibData *cd;
4057 cd = GetClibFunc(ap->FuncName, ap, flags);
4058 EndPutM16Inc(data, 0xF22F); /* FMOVE.? offs(A7),FPx */
4060 if(cd && IsCPPType(&cd->Args[k-1], CPP_TYPE_DOUBLE))
4062 EndPutM16Inc(data, 0x5400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
4063 EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
4064 ofs += 2;
4066 else
4068 if(!cd || !IsCPPType(&cd->Args[k-1], CPP_TYPE_FLOAT))
4069 DoError(ERR_LONG_DOUBLE, ap->Line);
4070 EndPutM16Inc(data, 0x4400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
4071 EndPutM16Inc(data, (ofs++) << 2);
4074 else if((k >= 2) && (ap->Args[k-1].ArgReg < ap->Args[k-2].ArgReg)
4075 && ap->Args[k-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4077 l = 0; tofs = ofs;
4080 j = ap->Args[--k].ArgReg;
4082 ++ofs;
4083 l |= 1 << j;
4084 } while(k && j < ap->Args[k-1].ArgReg
4085 && ap->Args[k-1].ArgReg < REG_FP0);
4086 EndPutM16Inc(data, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4087 EndPutM16Inc(data, l);
4088 EndPutM16Inc(data, tofs << 2); /* store start offset */
4090 else
4092 l = 0x202F; /* MOVE.L offs(A7),xxx */
4094 if((j = ap->Args[--k].ArgReg) > 7)
4096 l |= (1<<6); j -= 8; /* set MOVEA bit */
4098 /* set destination register and store */
4099 EndPutM16Inc(data, l | (j << 9));
4100 EndPutM16Inc(data, (ofs++) << 2);
4104 else
4106 i = 0;
4108 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
4110 while(i < k)
4112 if(ap->Args[i].ArgReg >= REG_FP0)
4114 struct ClibData *cd;
4116 cd = GetClibFunc(ap->FuncName, ap, flags);
4117 EndPutM16Inc(data, 0xF22F); /* FMOVE.? offs(A7),FPx */
4119 if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
4121 EndPutM16Inc(data, 0x5400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
4122 EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
4123 ofs += 2;
4125 else
4127 if(!cd || !IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
4128 DoError(ERR_LONG_DOUBLE, ap->Line);
4129 EndPutM16Inc(data, 0x4400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
4130 EndPutM16Inc(data, (ofs++) << 2);
4133 else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg)
4134 && ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4136 l = 0; tofs = ofs;
4139 j = ap->Args[i++].ArgReg;
4141 ++ofs;
4142 l |= 1 << j;
4143 } while(i < k && j < ap->Args[i].ArgReg
4144 && ap->Args[i].ArgReg < REG_FP0);
4145 EndPutM16Inc(data, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4146 EndPutM16Inc(data, l); /* Store MOVEM.L data */
4147 EndPutM16Inc(data, tofs << 2); /* store start offset */
4149 else
4151 l = 0x202F; /* MOVE.L offs(A7),xxx */
4153 if((j = ap->Args[i++].ArgReg) > 7)
4155 l |= (1<<6); j -= 8; /* set MOVEA bit */
4157 /* set destination register and store */
4158 EndPutM16Inc(data, l | (j << 9));
4159 EndPutM16Inc(data, (ofs++) << 2);
4163 if(i < ap->NumArgs)
4165 if((j = ap->Args[i].ArgReg) > 7)
4167 EndPutM16Inc(data, 0x41EF | ((j-8) << 9)); /* LEA xxx(A7),Ax */
4168 EndPutM16Inc(data, ofs << 2);
4170 else if(ofs == 2)
4172 EndPutM16Inc(data, 0x200F | (j << 9)); /* MOVE.L A7,Dx */
4173 EndPutM16Inc(data, 0x5080 | j); /* ADDQ.L #8,Dx */
4175 else
4177 EndPutM16Inc(data, 0x486F); /* PEA xxx(A7) */
4178 EndPutM16Inc(data, ofs << 2);
4179 EndPutM16Inc(data, 0x201F | j << 9); /* MOVE.L offs(A7),Dx */
4184 return data;
4186 /* ------------------------------------------------------------------ */
4188 static void DoError(uint32 errnum, uint32 line, ...)
4190 uint32 err = errnum & 0xFFFF;
4191 va_list a;
4193 if(Flags & FLAG_DIDERROR)
4194 return;
4196 if(!Errors[err].Type)
4197 Flags |= FLAG_DIDERROR;
4199 va_start(a, line);
4200 printf((line ? "%s %ld in line %ld%s: " : "%s %ld : "),
4201 (Errors[err].Type ? "Warning" : "Error"), err, line,
4202 errnum & ERROFFSET_CLIB ? " of clib file" : "");
4203 vprintf(Errors[err].Error, a);
4204 printf("\n");
4205 if(line && Errors[err].Skip)
4207 while(*in.pos)
4208 ++in.pos;
4210 va_end(a);
4213 static uint32 CheckError(struct AmiPragma *ap, uint32 errflags)
4215 errflags &= ap->Flags;
4217 if(errflags & AMIPRAGFLAG_ARGCOUNT)
4219 if(!(ap->Flags & AMIPRAGFLAG_DIDARGWARN))
4221 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
4222 ap->Flags |= AMIPRAGFLAG_DIDARGWARN;
4224 return 1;
4226 else if(errflags & AMIPRAGFLAG_FLOATARG)
4228 if(!(ap->Flags & AMIPRAGFLAG_DIDFLOATWARN))
4230 DoError(ERR_FLOATARG_NOT_ALLOWED, ap->Line);
4231 ap->Flags |= AMIPRAGFLAG_DIDFLOATWARN;
4233 return 1;
4235 else if(errflags & AMIPRAGFLAG_A6USE)
4237 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
4238 return 1;
4240 else if(errflags & AMIPRAGFLAG_A5USE)
4242 DoError(ERR_A5_NOT_ALLOWED, ap->Line);
4243 return 1;
4245 else if(errflags & AMIPRAGFLAG_PPC)
4247 if(!(Flags & FLAG_DIDPPCWARN))
4249 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
4250 Flags |= FLAG_DIDPPCWARN;
4252 return 1;
4254 else if(errflags & AMIPRAGFLAG_M68K)
4256 if(!(Flags & FLAG_DIDM68KWARN))
4258 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
4259 Flags |= FLAG_DIDM68KWARN;
4261 return 1;
4263 else if(errflags & AMIPRAGFLAG_MOSBASESYSV)
4265 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED, ap->Line);
4266 return 1;
4269 return 0;
4272 static uint32 DoOutput(strptr format, ...)
4274 va_list a;
4276 if(!Output_Error)
4277 return 0;
4279 va_start(a, format);
4280 if(vfprintf(outfile, format, a) < 0)
4281 Output_Error = 1;
4282 va_end(a);
4284 return Output_Error;
4287 static uint32 DoOutputDirect(void * data, size_t size)
4289 if(!Output_Error)
4290 return 0;
4291 if(size)
4293 if(fwrite(data, size, 1, outfile) != 1)
4294 Output_Error = 0;
4296 return Output_Error;
4299 /* ------------------------------------------------------------------ */
4301 static struct ShortList *NewItem(struct ShortListRoot *list)
4303 struct ShortList *item;
4304 if(!list || !list->Size)
4305 return 0;
4306 if(!(item = (struct ShortList *) AllocListMem(list->Size)))
4307 return 0;
4308 return item;
4311 static struct ShortList *RemoveItem(struct ShortListRoot *list,
4312 struct ShortList *item)
4314 struct ShortList *n = list->First;
4316 if(n == item)
4317 list->First = item->Next;
4318 else
4320 while(n && n->Next != item)
4321 n = n->Next;
4322 if(!n)
4323 return 0;
4324 if(!(n->Next = item->Next))
4325 list->Last = n;
4327 item->Next = 0;
4328 return item;
4331 static void AddItem(struct ShortListRoot *list, struct ShortList *item)
4333 if(!list->First)
4334 list->First = list->Last = item;
4335 else
4337 list->Last->Next = item;
4338 list->Last = item;
4342 /* ------------------------------------------------------------------ */
4344 uint32 FuncAMICALL(struct AmiPragma *ap, uint32 flags, strptr name)
4346 uint32 i;
4348 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4349 return 1;
4351 Flags |= FLAG_DONE; /* We did something */
4353 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags & FUNCFLAG_TAG ?
4354 "tagcall" : "amicall", BaseName, ap->Bias, name);
4356 for(i = 0; i < ap->NumArgs; ++i)
4358 DoOutput("%s",RegNames[ap->Args[i].ArgReg]);
4359 if(i+1 < ap->NumArgs)
4360 DoOutput(",");
4363 return DoOutput(/*((*/"))\n");
4366 uint32 FuncLIBCALL(struct AmiPragma *ap, uint32 flags, strptr name)
4368 int32 i;
4370 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4371 return 1;
4373 Flags |= FLAG_DONE; /* We did something */
4375 if(ap->Flags & AMIPRAGFLAG_FLOATARG)
4377 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName, name, ap->Bias);
4378 for(i = ap->NumArgs-1; i >= 0; --i)
4379 DoOutput("%02x", ap->Args[i].ArgReg);
4381 return DoOutput("00%02x\n", ap->NumArgs);
4384 if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase") &&
4385 (flags & FUNCFLAG_NORMAL))
4386 DoOutput("#pragma syscall %-22s %03x ", name, ap->Bias);
4387 else
4388 DoOutput("#pragma %s %s %-22s %03x ", (flags & FUNCFLAG_TAG) ?
4389 "tagcall" : "libcall", BaseName, name, ap->Bias);
4391 for(i = ap->NumArgs-1; i >= 0; --i)
4392 DoOutput("%x", ap->Args[i].ArgReg);
4394 return DoOutput("0%x\n", ap->NumArgs);
4397 uint32 FuncAsmText(struct AmiPragma *ap, uint32 flags, strptr name)
4399 int32 i;
4400 uint32 registers;
4401 uint16 fregs;
4402 uint32 offset = 1;
4403 strptr c1, c2;
4404 struct ClibData *cd;
4406 if(CheckError(ap, AMIPRAGFLAG_PPC))
4407 return 1;
4409 Flags |= FLAG_DONE; /* We did something */
4411 c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
4412 c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
4414 if(Flags & FLAG_SINGLEFILE)
4416 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
4418 if(HEADER)
4420 DoOutput("\n");
4421 DoOutputDirect(HEADER, headersize);
4425 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
4427 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
4428 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
4431 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name, name);
4432 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4434 DoOutput("\tXDEF\t%s\n%s:\n",name, name);
4435 if(clibdata)
4437 if(!ap->NumArgs)
4438 DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
4439 else if((cd = GetClibFunc(name, ap, flags)))
4441 string txt[300];
4442 uint32 i;
4444 for(i = 0; i < COPYCPP_PASSES; ++i)
4446 if(CopyCPPType(txt, i, cd, ap->Args))
4447 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name, txt, name, txt);
4453 if((registers = GetRegisterData(ap) >> 16))
4455 if(Flags & FLAG_NOMOVEM)
4457 for(i = 0; i <= 15; ++i)
4459 if(registers & (1 << i))
4461 ++offset;
4462 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper[i]);
4466 else
4468 uint16 l = registers;
4470 DoOutput("\tMOVEM.L\t");
4472 for(i = 0; i <= 15; ++i)
4474 if(l & (1 << i))
4476 ++offset;
4477 l ^= 1 << i;
4478 DoOutput("%s",RegNamesUpper[i]);
4479 if(l)
4480 DoOutput("/");
4483 DoOutput(",-(A7)\n");
4486 else
4488 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
4491 if((fregs = GetFRegisterData(ap) >> 8))
4493 uint8 l = fregs;
4495 DoOutput("\tFMOVEM.X\t");
4497 for(i = 0; i <= 7; ++i)
4499 if(l & (1 << i))
4501 offset += 3;
4502 l ^= 1 << i;
4503 DoOutput("%s",RegNamesUpper[REG_FP0 + i]);
4504 if(l)
4505 DoOutput("/");
4508 DoOutput(",-(A7)\n");
4511 if(Flags & FLAG_SMALLDATA)
4513 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1, BaseName, c2);
4515 else
4516 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName);
4518 if(!(Flags & FLAG_PASCAL))
4520 int32 k;
4522 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
4524 for(i = 0; i < k;)
4526 if(ap->Args[i].ArgReg >= REG_FP0)
4528 uint32 t;
4529 struct ClibData *cd;
4531 cd = GetClibFunc(name, ap, flags);
4532 if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
4533 t = CPP_TYPE_DOUBLE;
4534 else if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
4535 t = CPP_TYPE_FLOAT;
4536 else
4538 DoError(ERR_LONG_DOUBLE, ap->Line);
4539 t = CPP_TYPE_FLOAT;
4542 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE
4543 ? 'D' : 'S', c1, offset<<2, c2, RegNamesUpper[ap->Args[i++].ArgReg]);
4545 if(t == CPP_TYPE_DOUBLE)
4546 ++offset;
4547 ++offset;
4549 else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg) &&
4550 ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4552 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
4553 RegNamesUpper[ap->Args[i++].ArgReg]);
4557 DoOutput("/%s", RegNamesUpper[ap->Args[i++].ArgReg]);
4558 ++offset;
4559 } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg) &&
4560 ap->Args[i].ArgReg < REG_FP0);
4561 DoOutput("\n");
4563 else
4565 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4566 ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
4567 RegNamesUpper[ap->Args[i].ArgReg]);
4568 ++i;
4572 if(i < ap->NumArgs)
4574 if(ap->Args[i].ArgReg > 7)
4575 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1, offset<<2, c2,
4576 RegNamesUpper[ap->Args[i].ArgReg]);
4577 else if(offset <= 2)
4578 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4579 RegNamesUpper[ap->Args[i].ArgReg],offset<<2,
4580 RegNamesUpper[ap->Args[i].ArgReg]);
4581 else
4582 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1,
4583 offset<<2, c2,RegNamesUpper[ap->Args[i].ArgReg]);
4586 else
4588 i = ap->NumArgs;
4590 while(i)
4592 if(ap->Args[i-1].ArgReg >= REG_FP0)
4594 uint32 t;
4595 struct ClibData *cd;
4597 cd = GetClibFunc(name, ap, flags);
4599 if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_DOUBLE))
4600 t = CPP_TYPE_DOUBLE;
4601 else if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_FLOAT))
4602 t = CPP_TYPE_FLOAT;
4603 else
4605 DoError(ERR_LONG_DOUBLE, ap->Line);
4606 t = CPP_TYPE_FLOAT;
4609 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ?
4610 'D' : 'S', c1, offset<<2, c2, RegNamesUpper[ap->Args[--i].ArgReg]);
4611 if(t == CPP_TYPE_DOUBLE)
4612 ++offset;
4613 ++offset;
4615 else if((i >= 2) && (ap->Args[i-1].ArgReg < ap->Args[i-2].ArgReg) &&
4616 ap->Args[i-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4618 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
4619 RegNamesUpper[ap->Args[--i].ArgReg]);
4623 DoOutput("/%s", RegNamesUpper[ap->Args[--i].ArgReg]);
4624 ++offset;
4625 } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg) &&
4626 ap->Args[i-1].ArgReg < REG_FP0);
4627 DoOutput("\n");
4629 else
4631 --i;
4632 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4633 ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
4634 RegNamesUpper[ap->Args[i].ArgReg]);
4639 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1, ap->Bias, c2);
4641 if(fregs)
4643 DoOutput("\tFMOVEM.X\t(A7)+,");
4645 for(i = 0; i <= 7; ++i)
4647 if(fregs & (1 << i))
4649 fregs ^= 1 << i;
4650 DoOutput("%s",RegNamesUpper[REG_FP0 + i]);
4651 if(fregs)
4652 DoOutput("/");
4655 DoOutput("\n");
4658 if(registers)
4660 if(Flags & FLAG_NOMOVEM)
4662 for(i = 15; i >= 0; --i)
4664 if(registers & (1 << i))
4665 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i >= REG_A0 ? "A" : "",
4666 RegNamesUpper[i]);
4669 else
4671 DoOutput("\tMOVEM.L\t(A7)+,");
4673 for(i = 0; i <= 15; ++i)
4675 if(registers & (1 << i))
4677 registers ^= 1 << i;
4678 DoOutput("%s",RegNamesUpper[i]);
4679 if(registers)
4680 DoOutput("/");
4683 DoOutput("\n");
4686 else
4687 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4689 return DoOutput("\tRTS\n");
4692 uint32 FuncAsmCode(struct AmiPragma *ap, uint32 flags, strptr name)
4694 uint32 registers, offset = 1, baseref;
4695 size_t i;
4696 uint8 *data;
4697 uint16 fregs;
4699 if(CheckError(ap, AMIPRAGFLAG_PPC))
4700 return 1;
4702 Flags |= FLAG_DONE; /* We did something */
4704 registers = GetRegisterData(ap);
4705 fregs = GetFRegisterData(ap);
4707 i = strlen(name) + 2;
4708 EndPutM32(tempbuf, HUNK_UNIT);
4709 EndPutM32(tempbuf+4, (i+3)>>2);
4710 DoOutputDirect(tempbuf, 8);
4711 DoOutput("%s.o", name);
4712 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
4714 i = strlen(hunkname);
4715 EndPutM32(tempbuf, HUNK_NAME);
4716 EndPutM32(tempbuf+4, (i + 3)>>2);
4717 DoOutputDirect(tempbuf, 8);
4718 DoOutputDirect(hunkname, i);
4719 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
4721 data = tempbuf+8; /* we need HUNK_CODE + size at start */
4723 if(!registers)
4725 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
4726 ++offset; /* one long more on stack */
4728 else
4730 if(Flags & FLAG_NOMOVEM)
4732 for(i = 0; i <= 15; ++i)
4734 if(registers & (1<< (16+i)))
4736 EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
4737 ++offset;
4741 else
4743 uint32 l;
4744 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
4745 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
4746 for(l = (uint16) registers; l; l >>= 1)
4748 if(l & 1)
4749 ++offset; /* get offset addition */
4754 if(fregs)
4756 uint32 l;
4757 EndPutM16Inc(data, 0xF227); /* FMOVEM.X xxx,-(A7) */
4758 EndPutM16Inc(data, 0xE000 + ((fregs>>8)&0xFF));
4759 for(l = (uint8) fregs; l; l >>= 1)
4761 if(l & 1)
4762 offset+=3; /* get offset addition */
4766 baseref = (data-tempbuf)-8+2; /* one word later (MOVE) - 2 header longs */
4767 if(Flags & FLAG_SMALLDATA)
4769 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
4770 EndPutM16Inc(data, 0); /* place for base reference */
4772 else
4774 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
4775 EndPutM32Inc(data, 0); /* place for base reference */
4778 data = AsmStackCopy(data, ap, flags, offset);
4780 /* here comes the base reference */
4781 EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
4782 EndPutM16Inc(data, -ap->Bias); /* JSR offset */
4784 if(fregs)
4786 EndPutM16Inc(data, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4787 EndPutM16Inc(data, 0xD000 + (fregs&0xFF));
4790 if(registers)
4792 if(Flags & FLAG_NOMOVEM)
4794 int32 i;
4795 for(i = 15; i >= 0; --i)
4797 if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
4798 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
4801 else
4803 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4804 EndPutM16Inc(data, (registers >> 16)); /* store MOVEM.L registers */
4807 else
4808 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
4809 EndPutM16Inc(data, 0x4E75); /* RTS */
4811 EndPutM16Inc(data, 0); /* get longword assignment if not yet */
4813 EndPutM32(tempbuf, HUNK_CODE);
4814 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
4815 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
4817 EndPutM32(tempbuf, HUNK_EXT);
4818 DoOutputDirect(tempbuf, 4);
4820 OutputXREF(baseref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32),
4821 "_%s", BaseName);
4822 /* here come the XDEF name references */
4823 OutputXDEF(0, "_%s", name); /* C name */
4825 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4827 struct ClibData *cd;
4828 OutputXDEF(0, "%s", name); /* ASM name */
4830 if(clibdata)
4832 if(!ap->NumArgs)
4833 OutputXDEF(0, "%s_", name); /* C++ name no parameters */
4834 else if((cd = GetClibFunc(name, ap, flags)))
4836 for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
4838 if(CopyCPPType((strptr)tempbuf, i, cd, ap->Args))
4839 OutputXDEF(0, "%s__%s", name, tempbuf);
4845 EndPutM32(tempbuf, 0);
4846 DoOutputDirect(tempbuf, 4);
4847 if(!(Flags & FLAG_NOSYMBOL))
4849 EndPutM32(tempbuf, HUNK_SYMBOL);
4850 DoOutputDirect(tempbuf, 4);
4851 OutputSYMBOL(0, "_%s", name); /* C name */
4853 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4855 struct ClibData *cd;
4856 OutputSYMBOL(0, "%s", name); /* ASM name */
4858 if(clibdata)
4860 if(!ap->NumArgs)
4861 OutputSYMBOL(0, "%s_", name); /* C++ name no parameters */
4862 else if((cd = GetClibFunc(name, ap, flags)))
4864 for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
4866 if(CopyCPPType((strptr) data, i, cd, ap->Args))
4867 OutputSYMBOL(0, "%s__%s", name, (strptr) data);
4873 EndPutM32(tempbuf, 0);
4874 DoOutputDirect(tempbuf, 4);
4877 EndPutM32(tempbuf, HUNK_END);
4878 return DoOutputDirect(tempbuf, 4);
4881 /* Directly called by FuncInline and FuncInlineDirect also! */
4882 uint32 FuncCSTUBS(struct AmiPragma *ap, uint32 flags, strptr name)
4884 struct ClibData *f, *t;
4885 strptr ret = "return ";
4886 int32 i;
4888 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4889 return 1;
4891 Flags |= FLAG_DONE; /* We did something */
4893 if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
4894 return 1;
4895 t = GetClibFunc(name, ap, flags);
4897 if(flags & FUNCFLAG_EXTENDMODE)
4899 sprintf(tempbuf, "___%s", name);
4900 name = tempbuf;
4903 if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
4904 ret = "";
4906 if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
4907 return 0;
4908 if(flags & FUNCFLAG_EXTENDMODE)
4910 DoOutput("%s %s, ", GetBaseType(), BaseName);
4913 for(i = 0; i < ap->NumArgs-1; i++)
4915 if(!OutClibType(&f->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4916 return 0;
4918 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4920 if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4921 return 0;
4923 else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
4924 return 0;
4926 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret, ap->FuncName))
4927 return 0;
4928 for(i = 0; i < ap->NumArgs-1; i++)
4930 if(!DoOutput("%s, ", ap->Args[i].ArgName))
4931 return 0;
4933 if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
4934 return 0;
4936 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4938 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
4939 return 0;
4941 else if(ap->NumArgs == 1)
4943 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4944 return 0;
4946 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4947 ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(&f->Args[ap->NumArgs-2],0)
4948 || !DoOutput(/*(((*/")));\n}\n\n"))
4949 return 0;
4950 return 1;
4953 uint32 FuncLVOXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
4955 Flags |= FLAG_DONE; /* We did something */
4956 return DoOutput("\t\tXDEF\t_LVO%s\n", name);
4959 uint32 FuncLVO(struct AmiPragma *ap, uint32 flags, strptr name)
4961 Flags |= FLAG_DONE; /* We did something */
4962 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name, ap->Bias);
4965 uint32 FuncLVOPPCXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
4967 Flags |= FLAG_DONE; /* We did something */
4968 return DoOutput("\t.globl\t%sLVO%s\n", Flags & FLAG_ABIV4 ? "" : "_", name);
4971 uint32 FuncLVOPPC(struct AmiPragma *ap, uint32 flags, strptr name)
4973 Flags |= FLAG_DONE; /* We did something */
4974 return DoOutput(".set\t%sLVO%s,-%d\n", Flags & FLAG_ABIV4 ? "" : "_", name,
4975 ap->Bias);
4978 uint32 FuncLVOPPCBias(struct AmiPragma *ap, uint32 flags, strptr name)
4980 Flags |= FLAG_DONE; /* We did something */
4982 EndPutM32Inc(elfbufpos, symoffset); /* st_name */
4983 symoffset += strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1) + 1;
4984 EndPutM32Inc(elfbufpos, -ap->Bias); /* st_value */
4985 EndPutM32Inc(elfbufpos, 0); /* st_size */
4986 *(elfbufpos++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* st_info */
4987 *(elfbufpos++) = 0; /* st_other */
4988 EndPutM16Inc(elfbufpos, SHN_ABS); /* st_shndx */
4990 return 1;
4993 uint32 FuncLVOPPCName(struct AmiPragma *ap, uint32 flags, strptr name)
4995 Flags |= FLAG_DONE; /* We did something */
4996 DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
4997 return DoOutputDirect("", 1);
5000 uint32 FuncLVOLib(struct AmiPragma *ap, uint32 flags, strptr name)
5002 uint32 j;
5004 Flags |= FLAG_DONE; /* We did something */
5005 j = strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1);
5006 EndPutM32(tempbuf, (EXT_ABS << 24) + ((j+3)>>2));
5008 DoOutputDirect(tempbuf, 4);
5009 DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
5010 DoOutputDirect("\0\0\0", ((j+3)&(~3))-j);
5011 EndPutM32(tempbuf, -ap->Bias);
5012 return DoOutputDirect(tempbuf, 4);
5015 uint32 FuncLocCode(struct AmiPragma *ap, uint32 flags, strptr name)
5017 strptr str2 = Flags & FLAG_LOCALREG ? "rE" : "";
5018 uint8 *data;
5019 int32 i;
5020 struct ClibData *cd = 0;
5022 if(CheckError(ap, AMIPRAGFLAG_PPC))
5023 return 1;
5025 Flags |= FLAG_DONE; /* We did something */
5027 i = strlen(name) + 2;
5028 EndPutM32(tempbuf, HUNK_UNIT);
5029 EndPutM32(tempbuf+4, (i+3)>>2);
5030 DoOutputDirect(tempbuf, 8);
5031 DoOutput("%s.o", name);
5032 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
5034 i = strlen(hunkname);
5035 EndPutM32(tempbuf, HUNK_NAME);
5036 EndPutM32(tempbuf+4, (i + 3)>>2);
5037 DoOutputDirect(tempbuf, 8);
5038 DoOutputDirect(hunkname, i);
5039 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
5041 data = tempbuf+8; /* we need HUNK_CODE + size at start */
5043 if(Flags & FLAG_LOCALREG)
5045 if((flags & FUNCFLAG_TAG))
5047 i = ap->Args[ap->NumArgs-1].ArgReg;
5048 EndPutM16Inc(data, 0x2F00 + i); /* MOVE <ea>,-(A7) */
5050 if(i > 7)
5052 EndPutM16Inc(data, 0x41EF | ((i-8) << 9)); /* LEA 8(A7),Ax */
5053 EndPutM16Inc(data, 8);
5055 else
5057 EndPutM16Inc(data, 0x200F | (i << 9)); /* MOVE.L A7,Dx */
5058 EndPutM16Inc(data, 0x5080 | i); /* ADDQ.L #8,Dx */
5061 EndPutM16Inc(data, 0x4EAE);
5062 EndPutM16Inc(data, -ap->Bias); /* JSR instruction */
5064 /* MOVE (A7)+,<ea> */
5065 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
5066 EndPutM16Inc(data, 0x4E75); /* RTS */
5068 else
5070 EndPutM16Inc(data, 0x4EEE);
5071 EndPutM16Inc(data, -ap->Bias); /* JMP instruction */
5074 else
5076 uint32 registers, offset = 1;
5078 registers = GetRegisterData(ap);
5080 if(!registers) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5082 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
5083 ++offset; /* one long more on stack */
5085 else
5087 if(Flags & FLAG_NOMOVEM)
5089 for(i = 0; i <= 15; ++i)
5091 if(registers & (1<< (16+i)))
5093 EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
5094 ++offset;
5098 else
5100 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
5101 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
5102 for(i = registers&0xFFFF; i; i >>= 1)
5104 if(i & 1)
5105 ++offset; /* get offset addition */
5110 if(!(ap->Flags & AMIPRAGFLAG_A6USE)) /* store library base in A6 */
5112 EndPutM16Inc(data, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5113 EndPutM16Inc(data, (offset++) << 2);
5116 data = AsmStackCopy(data, ap, flags, offset);
5118 /* here comes the base reference */
5119 EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
5120 EndPutM16Inc(data, -ap->Bias); /* JSR offset */
5121 if(registers)
5123 if(Flags & FLAG_NOMOVEM)
5125 for(i = 15; i >= 0; --i)
5127 if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
5128 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
5131 else
5133 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5134 EndPutM16Inc(data, registers >> 16); /* store MOVEM.L registers */
5137 else
5138 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
5140 EndPutM16Inc(data, 0x4E75); /* RTS */
5143 EndPutM16Inc(data, 0); /* get longword assignment if not yet */
5145 EndPutM32(tempbuf, HUNK_CODE);
5146 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
5147 DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
5149 EndPutM32(tempbuf, HUNK_EXT);
5150 DoOutputDirect(tempbuf,4);
5152 /* here come the XDEF name references */
5154 if(!(Flags & FLAG_ONLYCNAMES))
5156 OutputXDEF(0, "%s", name); /* ASM names */
5157 OutputXDEF(0, "LOC_%s", name);
5160 OutputXDEF(0, "_%s", name); /* C names */
5161 OutputXDEF(0, "_LOC_%s", name);
5163 if(clibdata && !(Flags & FLAG_ONLYCNAMES))
5165 if(!ap->NumArgs)
5167 /* C++ names no parameters */
5168 OutputXDEF(0, "%s__%sP07Library", name, str2);
5169 OutputXDEF(0, "LOC_%s__%sP07Library", name, str2);
5171 else if((cd = GetClibFunc(name, ap, flags)))
5173 strptr txt;
5175 txt = (strptr) tempbuf;
5177 for(i = 0; i < COPYCPP_PASSES; ++i)
5179 if(CopyCPPType(txt, i, cd, ap->Args))
5180 { /* C++ names with parameters */
5181 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5183 OutputXDEF(0, "%s__%sP07Library%s", name, str2, txt);
5184 OutputXDEF(0, "LOC_%s__%sP07Library%s", name, str2, txt);
5186 else
5188 OutputXDEF(0, "%s__%s", name, txt);
5189 OutputXDEF(0, "LOC_%s__%s", name, txt);
5196 EndPutM32(tempbuf, 0);
5197 DoOutputDirect(tempbuf,4);
5198 if(!(Flags & FLAG_NOSYMBOL))
5200 EndPutM32(tempbuf, HUNK_SYMBOL);
5201 DoOutputDirect(tempbuf,4);
5202 if(!(Flags & FLAG_ONLYCNAMES))
5204 OutputSYMBOL(0, "%s", name); /* ASM names */
5205 OutputSYMBOL(0, "LOC_%s", name);
5208 OutputSYMBOL(0, "_%s", name); /* C names */
5209 OutputSYMBOL(0, "_LOC_%s", name);
5211 if(clibdata && !(Flags & FLAG_ONLYCNAMES))
5213 if(!ap->NumArgs)
5215 /* C++ names no parameters */
5216 OutputSYMBOL(0, "%s__%sP07Library", name, str2);
5217 OutputSYMBOL(0, "LOC_%s__%sP07Library", name, str2);
5219 else if(cd)
5221 strptr txt;
5223 txt = (strptr) tempbuf;
5225 for(i = 0; i < COPYCPP_PASSES; ++i)
5227 if(CopyCPPType(txt, i, cd, ap->Args))
5228 { /* C++ names with parameters */
5229 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5231 OutputSYMBOL(0, "%s__%sP07Library%s", name, str2, txt);
5232 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name, str2, txt);
5234 else
5236 OutputSYMBOL(0, "%s__%s", name, txt);
5237 OutputSYMBOL(0, "LOC_%s__%s", name, txt);
5244 EndPutM32(tempbuf, 0);
5245 DoOutputDirect(tempbuf,4);
5247 EndPutM32(tempbuf, HUNK_END);
5248 return DoOutputDirect(tempbuf,4);
5251 uint32 FuncLocText(struct AmiPragma *ap, uint32 flags, strptr name)
5253 struct ClibData *cd;
5254 int32 i;
5256 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5257 return 1;
5259 Flags |= FLAG_DONE; /* We did something */
5261 if(!(cd = GetClibFunc(name, ap, flags)))
5262 return 1;
5264 OutClibType(&cd->ReturnType, 0);
5265 DoOutput(" LOC_%s("/*)*/, name);
5266 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5268 if(Flags & FLAG_LOCALREG)
5269 DoOutput("register __a6 ");
5270 DoOutput("%s libbase", GetBaseType());
5271 if(ap->NumArgs)
5272 DoOutput(", ");
5275 if(ap->NumArgs)
5277 for(i = 0; i < ap->NumArgs-1; i++)
5279 if(((Flags & FLAG_LOCALREG &&
5280 !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
5281 !OutClibType(&cd->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
5282 return 0;
5285 if(flags & FUNCFLAG_NORMAL)
5287 if(((Flags & FLAG_LOCALREG &&
5288 !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
5289 !OutClibType(&cd->Args[i], ap->Args[i].ArgName) ||
5290 !DoOutput(/*(*/");\n"))
5291 return 0;
5292 if(BaseName)
5294 DoOutput("#define %s("/*)*/, name);
5295 for(i = 0; i < ap->NumArgs-1; ++i)
5296 DoOutput("%c, ", 'a'+(char)i);
5297 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i, name, BaseName);
5298 for(i = 0; i < ap->NumArgs-1; ++i)
5299 DoOutput("%c, ",'a'+(char)i);
5300 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i);
5303 else
5304 return DoOutput(/*(*/"...);\n");
5306 else if(BaseName)
5307 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5308 name, name);
5309 else
5310 return DoOutput(/*(*/");\n");
5311 return 1;
5314 uint32 FuncInlineDirect(struct AmiPragma *ap, uint32 flags, strptr name)
5316 uint32 a4 = 0, a5 = 0;
5317 int32 noret = 0;
5318 int32 i, maxargs, reg=0;
5319 struct ClibData *cd;
5321 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC|AMIPRAGFLAG_VARARGS))
5322 return 1;
5324 Flags |= FLAG_DONE; /* We did something */
5326 if(flags & FUNCFLAG_ALIAS)
5328 if(flags & FUNCFLAG_TAG)
5329 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5330 name, ap->TagName);
5332 DoOutput("#define %s("/*)*/, name);
5333 for(i = 0; i < ap->NumArgs-1; ++i)
5334 DoOutput("%s, ", ap->Args[i].ArgName);
5335 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
5336 for(i = 0; i < ap->NumArgs-1; ++i)
5337 DoOutput("(%s), ", ap->Args[i].ArgName);
5338 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
5341 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5342 return 1;
5344 if(flags & FUNCFLAG_TAG)
5346 /* do not create some strange functions */
5347 if(IsNoCreateInlineFunc(name))
5348 DoOutput("#if !defined(NO_INLINE_STDARG) "
5349 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5350 else
5351 DoOutput("#ifndef NO_INLINE_STDARG\n");
5352 DoOutput("static __inline__ ");
5353 FuncCSTUBS(ap, flags|FUNCFLAG_EXTENDMODE, name);
5355 DoOutput("#define %s("/*)*/, name);
5356 for(i = 0; i < ap->NumArgs-1; ++i)
5358 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->NumArgs-2 ? ", " : "");
5360 if(ap->NumArgs < 2)
5361 DoOutput("tags");
5362 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name, ShortBaseNameUpper);
5363 for(i = 0; i < ap->NumArgs-1; ++i)
5364 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->NumArgs-2 ? ", " : "");
5365 if(ap->NumArgs < 2)
5366 DoOutput("tags");
5367 DoOutput(/*(*/")\n");
5368 return DoOutput("#endif\n\n");
5371 DoOutput("#define %s("/*)*/, name);
5372 if(ap->NumArgs)
5374 for(i = 0; i < ap->NumArgs-1; ++i)
5375 DoOutput("%s, ", ap->Args[i].ArgName);
5376 DoOutput("%s", ap->Args[i].ArgName);
5378 DoOutput(/*(*/") ({ \\\n"/*})*/);
5380 for(i = 0; i < ap->NumArgs; ++i)
5382 sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
5383 DoOutput(" ");
5384 OutClibType(&cd->Args[i], (strptr) tempbuf);
5385 DoOutput(" = (%s); \\\n", ap->Args[i].ArgName);
5388 if(Flags & FLAG_INLINENEW)
5390 if(ap->NumArgs)
5391 DoOutput(" ({ \\\n"/*})*/);
5392 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name);
5393 if(BaseName)
5394 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper);
5395 else
5397 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
5399 if(i == ap->NumArgs)
5400 return 1;
5401 DoOutput("(%s);\\\n", ap->Args[i].ArgName);
5404 DoOutput(" (("/*))*/);
5405 OutClibType(&cd->ReturnType, 0);
5406 DoOutput(" (*)("/*)*/);
5407 if(BaseName)
5409 DoOutput("char * __asm(\"a6\")");
5410 if(ap->NumArgs)
5411 DoOutput(", ");
5413 for(i = 0; i < ap->NumArgs; ++i)
5415 OutClibType(&cd->Args[i], 0);
5416 DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
5417 if(i < ap->NumArgs-1)
5418 DoOutput(", ");
5420 DoOutput(/*((*/")) \\\n");
5421 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name, ap->Bias);
5422 if(BaseName)
5424 DoOutput("_%s__bn", name);
5425 if(ap->NumArgs)
5426 DoOutput(", ");
5428 for(i = 0; i < ap->NumArgs; ++i)
5430 if(ap->Args[i].ArgReg == REG_A6)
5431 DoOutput("_%s__bn", name);
5432 else
5433 DoOutput("_%s_%s", name, ap->Args[i].ArgName);
5434 if(i < ap->NumArgs-1)
5435 DoOutput(", ");
5437 DoOutput(/*(*/"); \\\n");
5438 if(ap->NumArgs)
5439 DoOutput(/*({*/"});");
5441 else
5443 /* do A5 first, as it is more important */
5444 if(ap->Flags & AMIPRAGFLAG_A5USE)
5446 a5 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5447 for(i = 0; i < ap->NumArgs; ++i)
5448 a5 |= 1<<ap->Args[i].ArgReg;
5449 a5 &= 0xFFF;
5450 if(a5 == 0xFFF)
5452 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A5]);
5453 a5 = 0;
5455 else
5457 for(i = 0; (a5 & 1) && a5; ++i)
5458 a5 >>= 1;
5459 a5 = i; /* this is our A5 swap register */
5462 if(ap->Flags & AMIPRAGFLAG_A4USE)
5464 a4 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5465 if(a5)
5466 a4 |= (1<<a5);
5467 for(i = 0; i < ap->NumArgs; ++i)
5468 a4 |= 1<<ap->Args[i].ArgReg;
5469 a4 &= 0xFFF;
5470 if(a4 == 0xFFF)
5472 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A4]);
5473 a4 = 0;
5475 else
5477 for(i = 0; (a4 & 1) && a4; ++i)
5478 a4 >>= 1;
5479 a4 = i; /* this is our A4 swap register */
5482 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5483 noret = 1; /* this is a void function */
5485 if(ap->NumArgs || !noret)
5486 DoOutput(" %s{ \\\n", noret ? "" : "(" /*})*/);
5488 if(noret)
5489 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5490 DoOutput(
5491 " register int _d1 __asm(\"d1\"); \\\n"
5492 " register int _a0 __asm(\"a0\"); \\\n"
5493 " register int _a1 __asm(\"a1\"); \\\n");
5495 if(BaseName)
5496 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5497 GetBaseType(), name, ShortBaseNameUpper);
5499 if(!noret)
5501 sprintf((strptr)tempbuf, "__%s__re", name);
5502 DoOutput(" register ");
5503 OutClibType(&cd->ReturnType, (strptr) tempbuf);
5504 DoOutput(" __asm(\"d0\"); \\\n");
5506 if((maxargs = ap->NumArgs) >= 9 && (Flags & FLAG_STORMGCC))
5507 maxargs = 7;
5508 for(i = 0; i < maxargs; ++i)
5510 reg = ap->Args[i].ArgReg;
5511 if(a5 && reg == REG_A5) reg = a5; /* we need to switch */
5512 if(a4 && reg == REG_A4) reg = a4; /* we need to switch */
5514 sprintf((strptr)tempbuf, "__%s_%s", name, ap->Args[i].ArgName);
5515 DoOutput(" register ");
5516 OutClibType(&cd->Args[i], (strptr) tempbuf);
5517 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames[reg],
5518 (strptr) (tempbuf+1));
5520 if(i != ap->NumArgs) /* StormGCC mode */
5522 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name);
5523 for(i = maxargs; i < ap->NumArgs; ++i)
5525 DoOutput(" ULONG __%s_%s; \\\n", name, ap->Args[i].ArgName);
5526 reg = ap->Args[i].ArgReg;
5527 if(reg == REG_A4)
5529 reg = a4; a4 = 0;
5531 else if(reg == REG_A5)
5533 reg = a5; a5 = 0;
5536 /* reg is now either the last register argument or its a4/a5 redirect */
5537 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name);
5538 for(i = maxargs; i < ap->NumArgs; ++i)
5540 sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
5541 DoOutput("(ULONG)(%s)%s", (strptr)tempbuf, i == ap->NumArgs-1 ?
5542 "" : ", ");
5544 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5545 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name, name,
5546 RegNames[reg], name);
5548 DoOutput(" __asm volatile (\""/*)*/);
5549 if(a5) DoOutput("exg a5,%s\\n\\t", RegNames[a5]);
5550 if(a4) DoOutput("exg a4,%s\\n\\t", RegNames[a4]);
5551 if(maxargs != ap->NumArgs) /* StormGCC mode */
5553 DoOutput("movem.l ");
5554 for(i = maxargs; i < ap->NumArgs; ++i)
5556 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg],
5557 i == ap->NumArgs-1 ? "" : "/");
5559 DoOutput(",-(a7)\\n\\t");
5560 for(i = maxargs; i < ap->NumArgs; ++i)
5562 if(i == maxargs)
5563 DoOutput("move.l (%s),%s\\n\\t", RegNames[reg],
5564 RegNames[ap->Args[i].ArgReg]);
5565 else
5566 DoOutput("move.l %ld(%s),%s\\n\\t", (i-maxargs)*4, RegNames[reg],
5567 RegNames[ap->Args[i].ArgReg]);
5570 DoOutput("jsr a6@(-%d:W)", ap->Bias);
5571 if(maxargs != ap->NumArgs) /* StormGCC mode */
5573 DoOutput("\\n\\tmovem.l (a7)+,");
5574 for(i = maxargs; i < ap->NumArgs; ++i)
5576 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg],
5577 i == ap->NumArgs-1 ? "" : "/");
5580 if(a4) DoOutput("\\n\\texg a4,%s", RegNames[a4]);
5581 if(a5) DoOutput("\\n\\texg a5,%s", RegNames[a5]);
5582 DoOutput("\" \\\n");
5584 if(noret)
5585 DoOutput(" : \"=r\" (_d0)");
5586 else
5587 DoOutput(" : \"=r\"(__%s__re)", name);
5588 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5589 if(BaseName)
5590 DoOutput(" \"r\"(__%s__bn)%s", name, ap->NumArgs ? "," : "");
5591 for(i = 0; i < maxargs; ++i)
5593 DoOutput(" \"rf\"(__%s_%s)", name, ap->Args[i].ArgName);
5594 if(i < ap->NumArgs-1)
5595 DoOutput(",");
5597 if(i != ap->NumArgs) /* StormGCC mode */
5598 DoOutput(" \"r\"(__%s__ArgsPtr)", name);
5599 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5601 if(ap->NumArgs || !noret)
5602 DoOutput(/*({*/" }%s \\\n", noret ? "" : ");");
5605 return DoOutput(/*({*/"})\n\n");
5608 uint32 FuncInline(struct AmiPragma *ap, uint32 flags, strptr name)
5610 uint32 noret = 0, a45 = 0, j;
5611 int32 fp = -1, i;
5612 struct ClibData *cd;
5614 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5615 return 1;
5617 if(!(Flags & FLAG_INLINENEW) && CheckError(ap, AMIPRAGFLAG_MOSBASESYSV))
5618 return 1;
5620 Flags |= FLAG_DONE; /* We did something */
5622 if(flags & FUNCFLAG_ALIAS)
5624 if(flags & FUNCFLAG_TAG)
5625 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5626 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
5628 DoOutput("#define %s("/*)*/, name);
5629 for(i = 0; i < ap->NumArgs-1; ++i)
5630 DoOutput("%s, ", ap->Args[i].ArgName);
5631 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
5632 for(i = 0; i < ap->NumArgs-1; ++i)
5633 DoOutput("(%s), ", ap->Args[i].ArgName);
5634 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
5637 if(!(cd = GetClibFunc(ap->Flags & AMIPRAGFLAG_VARARGS ?
5638 ap->TagName : ap->FuncName, ap, flags)))
5639 return 1;
5641 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5642 noret = 1; /* this is a void function */
5644 if(ap->Flags & AMIPRAGFLAG_A5USE)
5645 a45 = REG_A5;
5646 if(ap->Flags & AMIPRAGFLAG_A4USE)
5648 if(a45)
5650 DoError(ERR_INLINE_A4_AND_A5, ap->Line);
5651 return 1; /* skip this entry */
5653 a45 = REG_A4;
5655 if(a45 && (ap->Flags & AMIPRAGFLAG_D7USE))
5657 DoError(ERR_INLINE_D7_AND_A45, ap->Line);
5658 return 1; /* skip this entry */
5661 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_MOSBASESYSV))
5663 if(Flags & FLAG_INLINENEW)
5665 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5666 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "");
5667 if(IsNoCreateInlineFunc(name))
5669 DoOutput("__inline ");
5670 FuncCSTUBS(ap, flags, name);
5671 /* call CSTUBS, as this equals the method used there */
5673 else
5675 DoOutput("#define %s("/*)*/, name);
5676 for(i = 0; i < ap->NumArgs-1; ++i)
5678 DoOutput("%s, ", ap->Args[i].ArgName);
5680 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5681 ap->FuncName);
5682 for(i = 0; i < ap->NumArgs-1; ++i)
5683 DoOutput("(%s), ", ap->Args[i].ArgName);
5684 DoOutput("("/*)*/);
5685 OutClibType(&cd->Args[i], 0);
5686 DoOutput(/*({((*/") _tags);})\n");
5688 return DoOutput("#endif\n\n");
5690 else if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS))
5691 == (FLAG_INLINESTUB|FLAG_MORPHOS))
5693 int32 n, d, tagl, local;
5695 n = 9-ap->NumArgs;
5696 d = n & 1 ? 4 : 0;
5697 tagl = 8 + (Flags2 & FLAG2_DIRECTVARARGS ? 0 : 64);
5698 local = (n * 4+d+8+15) & ~15; /* size of the stack frame */
5700 /* Stack frame:
5701 * 0- 3: next frame ptr
5702 * 4- 7: save lr
5703 * 8-71: struct Caos
5704 * 72-72+n*4+d+8-1: tag list start
5705 * ?-local-1: padding
5708 DoOutput("asm(\"\n"/*)*/
5709 "\t.align\t2\n"
5710 "\t.globl\t%s\n"
5711 "\t.type\t%s,@function\n"
5712 "%s:\n"
5713 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5714 "\tmflr\t0\n"
5715 "\tstw\t0,%ld(1)\n",
5716 name, name, name, local, local+4);
5718 /* If n is odd, one tag is split between regs and stack.
5719 * Copy its ti_Data together with the ti_Tag. */
5720 if(d)
5721 DoOutput("\tlwz\t0,%ld(1)\n", local+8); /* read ti_Data */
5723 /* Save the registers */
5724 for(i = ap->NumArgs; i <= 8; ++i)
5725 DoOutput("\tstw\t%ld,%ld(1)\n", i+2, (i-ap->NumArgs) * 4+tagl);
5727 if(d)
5728 DoOutput("\tstw\t0,%ld(1)\n", tagl+n * 4); /* write ti_Data */
5730 /* Add TAG_MORE */
5731 DoOutput("\tli\t0,2\n"
5732 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5733 "\taddi\t0,1,%ld\n"
5734 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5735 tagl+n * 4+d, local+8+d, tagl+n * 4+d+4);
5737 if(Flags2 & FLAG2_DIRECTVARARGS)
5739 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5740 "\tbl\t%s\n", ap->NumArgs+2, tagl, name);
5742 else
5745 if(!BaseName)
5747 DoError(ERR_MISSING_BASENAME, ap->Line);
5748 return 1;
5750 /* Caos.Offset = -fD_GetOffset(obj) */
5751 DoOutput("\tli\t0,%d\n"
5752 "\tstw\t0,8(1)\n", -ap->Bias);
5754 /* Save the non-varargs registers in the Caos struct. */
5755 for(i=0; i < ap->NumArgs-1; ++i)
5757 DoOutput("\tstw\t%ld,%d(1)\n", i+3, 8+4+(ap->Args[i].ArgReg * 4));
5760 DoOutput("\taddi\t0,1,%ld\n"
5761 "\tlis\t3,%s@ha\n"
5762 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5763 "\tlwz\t12,%s@l(3)\n"
5764 "\tlwz\t11,88(2)\n"
5765 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5766 "\tmtctr\t11\n"
5767 "\taddi\t3,1,8\n"
5768 "\tbctrl\n", /* EmulCallOS() */
5769 tagl, BaseName, 12+(4 * ap->Args[i].ArgReg), BaseName);
5771 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5772 "\tmtlr\t0\n"
5773 "\taddi\t1,1,%ld\n"
5774 "\tblr\n"
5775 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local+4, local, name, name);
5777 else
5779 DoOutput("%s%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ",
5780 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
5781 return FuncCSTUBS(ap, flags, name);
5782 /* call CSTUBS, as this equals the method used there */
5786 if(Flags & FLAG_INLINENEW) /* new style */
5788 strptr funcpar = "";
5789 DoOutput("#define %s("/*)*/, name);
5791 for(i = 0; i < cd->NumArgs; ++i)
5793 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5794 funcpar = "FP";
5797 if(ap->NumArgs)
5799 for(i = 0; i < ap->NumArgs-1; ++i)
5800 DoOutput("%s, ", ap->Args[i].ArgName);
5801 DoOutput("%s", ap->Args[i].ArgName);
5803 DoOutput(/*(*/") \\\n\t");
5804 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
5806 DoOutput("((("/*)))*/);
5807 OutClibType(&cd->ReturnType, 0);
5808 DoOutput(" (*)("/*)*/);
5809 DoOutput("%s", GetBaseType());
5810 for(i = 0; i < ap->NumArgs; ++i)
5812 DoOutput(", ");
5813 OutClibType(&cd->Args[i], 0);
5815 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5816 "(%s_BASE_NAME",/*)*/
5817 ShortBaseNameUpper, ap->Bias-2, ShortBaseNameUpper);
5819 for(i = 0; i < ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0); ++i)
5820 DoOutput(", %s", ap->Args[i].ArgName);
5821 if(flags & FUNCFLAG_TAG)
5822 DoOutput(", __VA_ARGS__");
5823 return DoOutput(/*((*/"))\n\n");
5825 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap->NumArgs,
5826 (noret ? "NR" : ""), (a45 ? RegNamesUpper[a45] : (strptr) ""),
5827 (BaseName ? "" : "UB"), funcpar, ap->Bias);
5828 if(!noret)
5830 OutClibType(&cd->ReturnType, 0);
5831 DoOutput(", ");
5833 DoOutput("%s, ", name);
5835 for(i = 0; i < ap->NumArgs; ++i)
5837 j = ap->Args[i].ArgReg;
5838 if(a45 && (j == REG_A4 || j == REG_A5))
5839 j = REG_D7;
5840 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5842 if(fp != -1)
5844 DoError(ERR_MULTIPLEFUNCTION, ap->Line);
5845 DoOutput("void *");
5847 else
5849 DoOutput("__fpt"); fp = i;
5852 else
5853 OutClibType(&cd->Args[i], 0);
5855 DoOutput(", %s, %s%s", ap->Args[i].ArgName, RegNames[j],
5856 (i == ap->NumArgs-1 && !BaseName ? "" : ", "));
5859 if(BaseName) /* was "##base" used? */
5860 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper);
5862 if(fp >= 0)
5864 DoOutput(", ");
5865 OutClibType(&cd->Args[fp], "__fpt");
5868 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
5869 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5871 return DoOutput(/*(*/")\n\n");
5874 /* old mode or stubs mode */
5876 if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS)) != (FLAG_INLINESTUB|FLAG_MORPHOS))
5877 DoOutput("%s%s__inline ", Flags & (FLAG_INLINESTUB|FLAG_MORPHOS) ?
5878 "" : "extern ", Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
5879 OutClibType(&cd->ReturnType, 0);
5880 DoOutput("\n%s(%s"/*)*/, name, (BaseName ?
5881 (ap->NumArgs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5883 for(i = 0; i < ap->NumArgs; ++i)
5885 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
5886 if(i < ap->NumArgs-1)
5887 DoOutput(", ");
5890 if(Flags & FLAG_POWERUP)
5892 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5893 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5894 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5895 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5896 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5897 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5898 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5900 if(ap->NumArgs)
5902 for(i = 0; i < ap->NumArgs; ++i)
5904 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5905 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
5909 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
5911 if(BaseName)
5912 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper);
5913 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5914 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5915 else
5917 DoOutput("\treturn(("/*))*/);
5918 OutClibType(&cd->ReturnType, 0);
5919 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5921 return Output_Error;
5923 else if(Flags & FLAG_MORPHOS)
5925 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5927 if(ap->NumArgs)
5929 for(i = 0; i < ap->NumArgs; ++i)
5931 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5932 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
5936 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
5937 if(BaseName)
5938 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5939 ShortBaseNameUpper);
5941 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5942 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5943 else
5945 DoOutput("\treturn(("/*))*/);
5946 OutClibType(&cd->ReturnType, 0);
5947 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5949 return Output_Error;
5952 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName ? " BASE_EXT_DECL\n" : ""));
5954 if(!noret)
5956 DoOutput(" register ");
5957 OutClibType(&cd->ReturnType, "res");
5958 DoOutput(" __asm(\"d0\");\n");
5961 if(BaseName)
5962 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5963 GetBaseType(), ShortBaseNameUpper);
5965 for(i = 0; i < ap->NumArgs; ++i)
5967 j = ap->Args[i].ArgReg;
5968 if(a45 && (j == REG_A4 || j == REG_A5))
5969 j = REG_D7;
5971 DoOutput(" register ");
5972 OutClibType(&cd->Args[i], RegNames[j]);
5973 DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
5976 if(a45)
5978 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
5979 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames[a45],
5980 ap->Bias, RegNames[a45]);
5982 else
5983 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap->Bias);
5985 DoOutput(noret ? " : /* No Output */\n" : " : \"=r\" (res)\n");
5987 DoOutput(" : ");
5988 if(BaseName)
5989 DoOutput("\"r\" (a6)%s", (ap->NumArgs ? ", ": ""));
5991 for(i = 0; i < ap->NumArgs; ++i)
5993 j = ap->Args[i].ArgReg;
5994 if(a45 && (j == REG_A4 || j == REG_A5))
5995 j = REG_D7;
5997 DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
6000 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6002 if(noret)
6003 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6004 else
6005 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6009 /* new style inlines designed by Bernardo Innocenti */
6010 uint32 FuncInlineNS(struct AmiPragma *ap, uint32 flags, strptr name)
6012 int32 i;
6013 struct ClibData *cd;
6015 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6016 return 1;
6018 Flags |= FLAG_DONE; /* We did something */
6020 if(flags & FUNCFLAG_ALIAS)
6022 if(flags & FUNCFLAG_TAG)
6023 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6024 name, ap->TagName);
6026 DoOutput("#define %s("/*)*/, name);
6027 for(i = 0; i < ap->NumArgs-1; ++i)
6028 DoOutput("%s, ", ap->Args[i].ArgName);
6029 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6030 for(i = 0; i < ap->NumArgs-1; ++i)
6031 DoOutput("(%s), ", ap->Args[i].ArgName);
6032 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
6035 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6036 return 1;
6038 if((flags & FUNCFLAG_TAG))
6040 if(!(Flags2 & FLAG2_INLINEMAC))
6042 DoOutput("static __inline ");
6043 return FuncCSTUBS(ap, flags, name);
6044 /* call CSTUBS, as this equals the method used there */
6046 else
6048 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6049 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
6050 for(i = 0; i < ap->NumArgs-1; ++i)
6051 DoOutput("%s, ", ap->Args[i].ArgName);
6052 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6053 ap->FuncName);
6054 for(i = 0; i < ap->NumArgs-1; ++i)
6055 DoOutput("(%s), ", ap->Args[i].ArgName);
6056 DoOutput("("/*)*/);
6057 OutClibType(&cd->Args[i], 0);
6058 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6062 if(Flags2 & FLAG2_INLINEMAC)
6064 DoOutput("#define %s("/*)*/, name);
6065 for(i = 0; i < ap->NumArgs; ++i)
6067 DoOutput("%s", ap->Args[i].ArgName);
6068 if(i < ap->NumArgs-1)
6069 DoOutput(", ");
6071 DoOutput(/*(*/") \\\n\t");
6073 else
6075 DoOutput("static __inline ");
6076 OutClibType(&cd->ReturnType, 0);
6077 DoOutput(" %s("/*)*/, name);
6078 for(i = 0; i < ap->NumArgs; ++i)
6080 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6081 if(i < ap->NumArgs-1)
6082 DoOutput(", ");
6084 DoOutput(/*(*/")\n{\n "/*}*/);
6085 if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6086 DoOutput("return ");
6088 DoOutput("(("/*))*/);
6089 OutClibType(&cd->ReturnType, 0);
6090 DoOutput(" (*)("/*)*/);
6091 for(i = 0; i < ap->NumArgs; ++i)
6093 OutClibType(&cd->Args[i], 0);
6094 DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
6095 if(i < ap->NumArgs-1)
6096 DoOutput(", ");
6098 if(BaseName)
6100 if(ap->NumArgs)
6101 DoOutput(", ");
6102 DoOutput("%s __asm(\"a6\")", GetBaseType());
6104 DoOutput(/*((*/"))");
6105 if(Flags2 & FLAG2_INLINEMAC)
6106 DoOutput(" \\");
6107 if(BaseName)
6108 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6109 ShortBaseNameUpper, ap->Bias);
6110 else
6112 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
6114 if(i == ap->NumArgs)
6115 return 1;
6116 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap->Args[i].ArgName,
6117 ap->Bias);
6119 for(i = 0; i < ap->NumArgs; ++i)
6121 DoOutput("%s", ap->Args[i].ArgName);
6122 if(i < ap->NumArgs-1)
6123 DoOutput(", ");
6125 if(BaseName)
6127 if(ap->NumArgs)
6128 DoOutput(", ");
6129 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
6132 if(Flags2 & FLAG2_INLINEMAC)
6133 DoOutput(/*(*/")\n");
6134 else
6135 DoOutput(/*{(*/");\n}\n");
6137 return DoOutput("\n");
6140 uint32 FuncPowerUP(struct AmiPragma *ap, uint32 flags, strptr name)
6142 int32 i;
6143 struct ClibData *cd;
6145 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6146 return 1;
6148 Flags |= FLAG_DONE; /* We did something */
6150 if(flags & FUNCFLAG_ALIAS)
6152 if(flags & FUNCFLAG_TAG)
6153 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6154 name, ap->TagName);
6156 DoOutput("#define %s("/*)*/, name);
6157 for(i = 0; i < ap->NumArgs-1; ++i)
6158 DoOutput("%s, ", ap->Args[i].ArgName);
6159 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6160 for(i = 0; i < ap->NumArgs-1; ++i)
6161 DoOutput("(%s), ", ap->Args[i].ArgName);
6162 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
6165 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6166 return 1;
6168 if(flags & FUNCFLAG_TAG)
6170 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name);
6171 for(i = 0; i < ap->NumArgs-1; ++i)
6172 DoOutput("%s, ", ap->Args[i].ArgName);
6173 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6174 ap->FuncName);
6175 for(i = 0; i < ap->NumArgs-1; ++i)
6176 DoOutput("(%s), ", ap->Args[i].ArgName);
6177 DoOutput("("/*)*/);
6178 OutClibType(&cd->Args[i], 0);
6179 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6182 DoOutput("#define\t%s("/*)*/, name);
6184 if(ap->NumArgs)
6187 for(i = 0; i < ap->NumArgs-1; ++i)
6188 DoOutput("%s, ", ap->Args[i].ArgName);
6189 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap->Args[i].ArgName, name);
6191 if(BaseName)
6192 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper);
6194 for(i = 0; i < ap->NumArgs-1; ++i)
6195 DoOutput("%s, ", ap->Args[i].ArgName);
6196 DoOutput(/*(*/"%s)\n\n", ap->Args[i].ArgName);
6198 else if(BaseName)
6199 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name, ShortBaseNameUpper);
6200 else
6201 DoOutput(/*(*/")\t_%s()\n\n", name);
6203 DoOutput("static __inline ");
6204 OutClibType(&cd->ReturnType, 0);
6206 DoOutput("\n_%s("/*)*/, name);
6207 if(BaseName)
6208 DoOutput("void * %s%s", BaseName, ap->NumArgs ? ", " : "");
6210 for(i = 0; i < ap->NumArgs; ++i)
6212 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6213 if(i < ap->NumArgs-1)
6214 DoOutput(", ");
6217 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6218 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6219 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6220 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6221 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6222 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6223 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6225 if(ap->NumArgs)
6227 for(i = 0; i < ap->NumArgs; ++i)
6229 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6230 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
6234 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
6236 if(BaseName)
6237 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName);
6238 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6239 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6240 else
6242 DoOutput("\treturn(("/*))*/);
6243 OutClibType(&cd->ReturnType, 0);
6244 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6246 return Output_Error;
6249 uint32 FuncFPCUnit(struct AmiPragma *ap, uint32 flags, strptr name)
6251 int32 i;
6252 struct ClibData *cd;
6254 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6255 return 1;
6256 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6257 return 1;
6259 if(!FuncFPCType(ap, flags, name))
6260 return 0;
6262 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6264 for(i = 0; i < ap->NumArgs; ++i)
6265 DoOutput("\tMOVE%s.L\t%s,%s\n", ap->Args[i].ArgReg >= REG_A0 ? "A" : "",
6266 ap->Args[i].ArgName, RegNamesUpper[ap->Args[i].ArgReg]);
6268 if(BaseName)
6269 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName);
6270 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap->Bias);
6272 if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6274 if(!cd->ReturnType.PointerDepth &&
6275 cd->ReturnType.Flags == CPP_FLAG_BOOLEAN)
6276 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6277 " @end:\tMOVE.B\tD0,@RESULT\n");
6278 else
6279 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6281 return DoOutput(" END;\nEND;\n\n");
6284 uint32 FuncFPCType(struct AmiPragma *ap, uint32 flags, strptr name)
6286 uint32 ret = 1;
6287 int32 i;
6288 struct ClibData *cd;
6290 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6291 return 1;
6292 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6293 return 1;
6295 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6297 ret = 0; DoOutput("PROCEDURE %s", name);
6299 else
6300 DoOutput("FUNCTION %s", name);
6302 if(ap->NumArgs)
6304 DoOutput("("/*)*/);
6305 for(i = 0; i < ap->NumArgs;)
6307 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6308 if(++i != ap->NumArgs)
6309 DoOutput("; ");
6311 DoOutput(/*(*/")");
6314 if(ret)
6315 OutPASCALType(&cd->ReturnType, "", 1);
6317 Flags |= FLAG_DONE; /* We did something */
6319 return DoOutput(";\n");
6322 uint32 FuncFPCTypeTags(struct AmiPragma *ap, uint32 flags, strptr name)
6324 uint32 ret = 1;
6325 int32 i;
6326 struct ClibData *cd;
6328 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6329 return 1;
6330 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6331 return 1;
6333 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6335 ret = 0; DoOutput("PROCEDURE %s", name);
6337 else
6338 DoOutput("FUNCTION %s", name);
6340 if(ap->NumArgs)
6342 DoOutput("("/*)*/);
6343 for(i = 0; i < ap->NumArgs-1;)
6345 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6346 if(++i != ap->NumArgs)
6347 DoOutput("; ");
6349 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
6350 DoOutput(/*(*/")");
6353 if(ret)
6354 OutPASCALType(&cd->ReturnType, "", 1);
6356 Flags |= FLAG_DONE; /* We did something */
6358 return DoOutput(";\n");
6361 uint32 FuncFPCTypeTagsUnit(struct AmiPragma *ap, uint32 flags, strptr name)
6363 uint32 ret = 1;
6364 int32 i;
6365 struct ClibData *cd;
6367 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6368 return 1;
6369 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6370 return 1;
6372 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6374 ret = 0; DoOutput("PROCEDURE %s", name);
6376 else
6377 DoOutput("FUNCTION %s", name);
6379 if(ap->NumArgs)
6381 DoOutput("("/*)*/);
6382 for(i = 0; i < ap->NumArgs-1;)
6384 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6385 if(++i != ap->NumArgs)
6386 DoOutput("; ");
6388 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
6389 DoOutput(/*(*/")");
6392 if(ret)
6393 OutPASCALType(&cd->ReturnType, "", 1);
6395 DoOutput(";\nbegin\n");
6397 if(ret)
6398 DoOutput(" %s := %s",name, ap->FuncName);
6399 else DoOutput(" %s", ap->FuncName);
6401 if(ap->NumArgs)
6403 DoOutput("("/*)*/);
6404 for(i = 0; i < ap->NumArgs-1;)
6406 DoOutput("%s ", ap->Args[i].ArgName);
6407 if(++i != ap->NumArgs)
6408 DoOutput(", ");
6410 DoOutput("readintags(%s)",ap->Args[i].ArgName);
6411 DoOutput(/*(*/");");
6414 DoOutput("\nend");
6416 Flags |= FLAG_DONE; /* We did something */
6418 return DoOutput(";\n\n");
6422 uint32 FuncBMAP(struct AmiPragma *ap, uint32 flags, strptr name)
6424 uint8 reg, i;
6426 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_A5USE
6427 |AMIPRAGFLAG_PPC))
6428 return 1;
6430 Flags |= FLAG_DONE; /* We did something */
6432 for(i = 0; BMAPSpecial[i]; ++i)
6434 if(!stricmp(name, BMAPSpecial[i]))
6436 DoOutput("x"); break;
6440 DoOutput("%s",name);
6441 reg = 0; DoOutputDirect(&reg, 1);
6442 reg = (-ap->Bias)>>8; DoOutputDirect(&reg, 1);
6443 reg = -ap->Bias; DoOutputDirect(&reg, 1);
6444 for(i = 0; i < ap->NumArgs; ++i)
6446 reg = 1+ap->Args[i].ArgReg; DoOutputDirect(&reg, 1);
6448 reg = 0;
6449 return DoOutputDirect(&reg, 1);
6452 uint32 FuncVBCCInline(struct AmiPragma *ap, uint32 flags, strptr name)
6454 struct ClibData *cd;
6455 strptr c1, c2;
6456 int32 i, k;
6458 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6459 return 1;
6461 if(!(cd = GetClibFunc(name, ap, flags)))
6462 return 1;
6464 c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
6465 c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
6467 Flags |= FLAG_DONE; /* We did something */
6469 if(flags & FUNCFLAG_TAG)
6471 if(IsNoCreateInlineFunc(name))
6472 return 1; /* do not create some strange functions */
6473 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6474 "(__STDC_VERSION__ >= 199901L)\n");
6477 if(flags & FUNCFLAG_ALIAS)
6479 DoOutput("#define %s("/*)*/, name);
6480 for(i = 0; i < ap->NumArgs-1; ++i)
6481 DoOutput("%s, ", ap->Args[i].ArgName);
6482 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6483 if(Flags2 & FLAG2_OLDVBCC)
6485 for(i = 0; i < ap->NumArgs; ++i)
6486 DoOutput("(%s), ", ap->Args[i].ArgName);
6487 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6488 "#endif\n" : "");
6490 else
6492 DoOutput("%s", BaseName);
6493 for(i = 0; i < ap->NumArgs; ++i)
6494 DoOutput(", (%s)", ap->Args[i].ArgName);
6495 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ?
6496 "#endif\n" : "");
6500 OutClibType(&cd->ReturnType, 0);
6501 DoOutput(" __%s("/*)*/, name);
6503 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6505 DoOutput("__reg(\"a6\") %s", GetBaseType());
6506 if(ap->NumArgs)
6507 DoOutput(", ");
6510 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
6511 for(i = 0; i < k; ++i)
6513 DoOutput("__reg(\"%s\") ", RegNames[ap->Args[i].ArgReg]);
6514 if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
6515 && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
6517 DoOutput("void * %s", ap->Args[i].ArgName);
6519 else
6520 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6521 if(i < ap->NumArgs-1)
6522 DoOutput(", ");
6525 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6527 if(ap->NumArgs)
6528 DoOutput(", ");
6529 DoOutput("__reg(\"a6\") %s", GetBaseType());
6532 if(flags & FUNCFLAG_TAG)
6534 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6536 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6537 DoOutput(", ");
6539 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6540 RegNames[ap->Args[k].ArgReg]);
6542 if(ap->Args[k].ArgReg > 7)
6543 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1, c2,
6544 RegNames[ap->Args[k].ArgReg]);
6545 else
6546 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6547 RegNames[ap->Args[k].ArgReg], RegNames[ap->Args[k].ArgReg]);
6549 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6550 "\\tmove%s.l\\t(a7)+,%s\";\n", c1, ap->Bias, c2,
6551 ap->Args[k].ArgReg >= REG_A0 ? "a" : "", RegNames[ap->Args[k].ArgReg]);
6553 else
6554 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1, ap->Bias, c2);
6556 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6557 DoOutput("#define %s("/*)*/, name);
6558 for(i = 0; i < k; ++i)
6560 DoOutput("%s", ap->Args[i].ArgName);
6561 if(i < ap->NumArgs-1)
6562 DoOutput(", ");
6564 if(flags & FUNCFLAG_TAG)
6566 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6567 DoOutput("%s, ", ap->Args[k].ArgName);
6568 DoOutput("...");
6570 DoOutput(/*(*/") __%s("/*)*/, name);
6571 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6573 DoOutput("%s", BaseName);
6574 if(ap->NumArgs)
6575 DoOutput(", ");
6577 for(i = 0; i < k; ++i)
6579 if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
6580 && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
6582 DoOutput("(void *)");
6584 DoOutput("(%s)", ap->Args[i].ArgName);
6585 if(i < ap->NumArgs-1)
6586 DoOutput(", ");
6588 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6590 if(ap->NumArgs)
6591 DoOutput(", ");
6592 DoOutput("%s", BaseName);
6594 if(flags & FUNCFLAG_TAG)
6596 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6597 DoOutput("(%s), ", ap->Args[k].ArgName);
6598 DoOutput("__VA_ARGS__");
6601 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6604 uint32 FuncVBCCWOSInline(struct AmiPragma *ap, uint32 flags, strptr name)
6606 struct ClibData *cd;
6607 int32 i, k;
6609 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_M68K))
6610 return 1;
6612 if(!(cd = GetClibFunc(name, ap, flags)))
6613 return 1;
6615 Flags |= FLAG_DONE; /* We did something */
6617 if(flags & FUNCFLAG_TAG)
6619 if(IsNoCreateInlineFunc(name))
6620 return 1; /* do not create some strange functions */
6621 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6622 "(__STDC_VERSION__ >= 199901L)\n");
6625 if(flags & FUNCFLAG_ALIAS)
6627 DoOutput("#define %s("/*)*/, name);
6628 for(i = 0; i < ap->NumArgs-1; ++i)
6629 DoOutput("%s, ", ap->Args[i].ArgName);
6630 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6631 for(i = 0; i < ap->NumArgs; ++i)
6632 DoOutput("(%s), ", ap->Args[i].ArgName);
6633 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6634 "#endif\n" : "");
6637 OutClibType(&cd->ReturnType, 0);
6638 DoOutput(" __%s("/*)*/, name);
6640 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6642 DoOutput("%s", GetBaseType());
6643 if(ap->NumArgs)
6644 DoOutput(", ");
6647 k = ap->NumArgs;
6648 for(i = 0; i < k; ++i)
6650 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6651 if(i < k-1)
6652 DoOutput(", ");
6654 if(flags & FUNCFLAG_TAG)
6655 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6657 DoOutput(/*(*/")=\"");
6658 if(ap->Flags & AMIPRAGFLAG_PPC0)
6660 DoOutput("\\t.extern\\t_%s\\n", BaseName);
6661 if ((flags & FUNCFLAG_TAG) && k>0)
6663 /* save tag1 and load taglist-pointer */
6664 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6665 "\\taddi\\t%s%d,%s1,%d\\n",
6666 PPCRegPrefix, (int)k+2, 20+(int)k*4, PPCRegPrefix, PPCRegPrefix,
6667 (int)k+2, PPCRegPrefix, 20+(int)k*4);
6669 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6670 "\\tlwz\\t%s0,-%d(%s11)\\n"
6671 "\\tmtlr\\t%s0\\n"
6672 "\\tblrl",
6673 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix,
6674 ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6676 else if(ap->Flags & AMIPRAGFLAG_PPC2)
6678 /* @@@ tagcall handling? */
6679 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6680 "\\t.extern\\t_%s\\n"
6681 "\\tlwz\\t%s2,_%s(%s2)\\n"
6682 "\\tlwz\\t%s0,-%d(%s2)\\n"
6683 "\\tmtlr\\t%s0\\n"
6684 "\\tblrl\\n"
6685 "\\tlwz\\t%s2,20(%s1)",
6686 PPCRegPrefix, PPCRegPrefix, BaseName, PPCRegPrefix, BaseName,
6687 PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
6688 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
6690 else
6692 if ((flags & FUNCFLAG_TAG) && k>0)
6694 /* save tag1 and load taglist-pointer */
6695 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6696 "\\taddi\\t%s%d,%s1,%d\\n",
6697 PPCRegPrefix, (int)k+3, 24+(int)k*4, PPCRegPrefix, PPCRegPrefix,
6698 (int)k+3, PPCRegPrefix, 24+(int)k*4);
6700 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6701 "\\tmtlr\\t%s0\\n"
6702 "\\tblrl",
6703 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6705 DoOutput("\";\n");
6707 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6708 DoOutput("#define %s("/*)*/, name);
6709 for(i = 0; i < k; ++i)
6711 DoOutput("%s", ap->Args[i].ArgName);
6712 if(i < ap->NumArgs-1)
6713 DoOutput(", ");
6715 if(flags & FUNCFLAG_TAG)
6717 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6718 DoOutput("%s, ", ap->Args[k].ArgName);
6719 DoOutput("...");
6721 DoOutput(/*(*/") __%s("/*)*/, name);
6722 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6724 DoOutput("%s", BaseName);
6725 if(ap->NumArgs)
6726 DoOutput(", ");
6728 for(i = 0; i < k; ++i)
6730 DoOutput("(%s)", ap->Args[i].ArgName);
6731 if(i < ap->NumArgs-1)
6732 DoOutput(", ");
6734 if(flags & FUNCFLAG_TAG)
6736 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6737 DoOutput("(%s), ", ap->Args[k].ArgName);
6738 DoOutput("__VA_ARGS__");
6741 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6744 uint32 FuncVBCCMorphInline(struct AmiPragma *ap, uint32 flags, strptr name)
6746 struct ClibData *cd;
6747 int32 i, k;
6749 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6750 return 1;
6752 if(!(cd = GetClibFunc(name, ap, flags)))
6753 return 1;
6755 Flags |= FLAG_DONE; /* We did something */
6757 if(flags & FUNCFLAG_TAG)
6759 if(IsNoCreateInlineFunc(name))
6760 return 1; /* do not create some strange functions */
6761 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6762 "(__STDC_VERSION__ >= 199901L)\n");
6765 if(flags & FUNCFLAG_ALIAS)
6767 DoOutput("#define %s("/*)*/, name);
6768 for(i = 0; i < ap->NumArgs-1; ++i)
6769 DoOutput("%s, ", ap->Args[i].ArgName);
6770 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6771 for(i = 0; i < ap->NumArgs; ++i)
6772 DoOutput("(%s), ", ap->Args[i].ArgName);
6773 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6774 "#endif\n" : "");
6777 OutClibType(&cd->ReturnType, 0);
6778 if((flags & FUNCFLAG_TAG) && (Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6779 DoOutput(" __linearvarargs");
6781 DoOutput(" __%s("/*)*/, name);
6783 if(BaseName && !(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12)))
6785 DoOutput("%s", GetBaseType());
6786 if(ap->NumArgs)
6787 DoOutput(", ");
6790 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6792 if((flags & FUNCFLAG_TAG) &&
6793 !(ap->Flags & AMIPRAGFLAG_MOS_ALL))
6795 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6796 DoOutput("long, ");
6800 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
6801 for(i = 0; i < k; ++i)
6803 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6804 if(i < ap->NumArgs-1)
6805 DoOutput(", ");
6808 if(flags & FUNCFLAG_TAG)
6810 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6812 if((ap->Flags & AMIPRAGFLAG_MOS_ALL)
6813 && !(ap->Flags & AMIPRAGFLAG_VARARGS))
6815 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6816 DoOutput("long, ");
6818 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6820 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6821 DoOutput(", ");
6825 DoOutput("...");
6828 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
6830 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6831 PPCRegPrefix, ap->Bias-2, PPCRegPrefix);
6832 if((ap->Flags != AMIPRAGFLAG_VARARGS) && (flags & FUNCFLAG_TAG))
6834 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6835 PPCRegPrefix,3+k+1,PPCRegPrefix);
6837 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6838 "\t\"\\tbctrl\";\n", PPCRegPrefix);
6840 else if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
6842 if (BaseName)
6844 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6845 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6846 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6847 PPCRegPrefix, BaseName,
6848 PPCRegPrefix, BaseName, PPCRegPrefix,
6849 PPCRegPrefix, ap->Bias-2, PPCRegPrefix);
6851 if((ap->Flags != AMIPRAGFLAG_VARARGS) && (flags & FUNCFLAG_TAG))
6853 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6854 PPCRegPrefix,3+k+1,PPCRegPrefix);
6856 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6857 "\t\"\\tbctrl\";\n", PPCRegPrefix);
6859 else
6861 int ofs = 4, fix = 0;
6862 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6863 PPCRegPrefix, PPCRegPrefix);
6864 k = 3;
6865 if(BaseName)
6867 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix, k++,
6868 PPCRegPrefix);
6870 if(Flags2 & FLAG2_SHORTPPCVBCCINLINE)
6872 ofs = 12;
6873 if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
6874 fix = 8+1-i;
6876 else if(flags & FUNCFLAG_TAG)
6878 if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
6879 k += 8+1-i;
6882 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix);
6883 for(i = 0; i < ap->NumArgs; ++i)
6885 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
6887 if(k <= 7+3)
6888 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix, k++);
6889 else
6890 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6891 PPCRegPrefix, 8+(k++-11)*4, PPCRegPrefix, PPCRegPrefix);
6893 else
6895 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6896 PPCRegPrefix, ofs, PPCRegPrefix, (2+k+fix-11)*4, PPCRegPrefix, ofs);
6898 DoOutput("%d(%s2)\\n\"\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
6900 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix,
6901 ap->Bias);
6904 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6905 DoOutput("#define %s("/*)*/, name);
6906 for(i = 0; i < k; ++i)
6908 DoOutput("%s", ap->Args[i].ArgName);
6909 if(i < ap->NumArgs-1)
6910 DoOutput(", ");
6912 if(flags & FUNCFLAG_TAG)
6914 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6915 DoOutput("%s, ", ap->Args[k].ArgName);
6916 DoOutput("...");
6918 DoOutput(/*(*/") __%s("/*)*/, name);
6919 if(BaseName && !(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12)))
6921 DoOutput("%s", BaseName);
6922 if(ap->NumArgs)
6923 DoOutput(", ");
6925 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6927 if(flags & FUNCFLAG_TAG && !(ap->Flags & AMIPRAGFLAG_MOSBASESYSV))
6929 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6930 DoOutput("0, ");
6933 for(i = 0; i < k; ++i)
6935 DoOutput("(%s)", ap->Args[i].ArgName);
6936 if(i < ap->NumArgs-1)
6937 DoOutput(", ");
6939 if(flags & FUNCFLAG_TAG)
6941 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6942 DoOutput("(%s), ", ap->Args[k].ArgName);
6943 DoOutput("__VA_ARGS__");
6946 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6949 uint32 FuncVBCCWOSText(struct AmiPragma *ap, uint32 flags, strptr name)
6951 uint32 i, k, count, ofs;
6952 struct ClibData *cd = 0;
6954 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
6955 return 1;
6957 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&
6958 !(cd = GetClibFunc(name, ap, flags)))
6959 return 1;
6961 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
6962 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) ||
6963 !(Flags & FLAG_WOSLIBBASE)))
6965 DoError(ERR_MISSING_BASENAME, ap->Line);
6966 return 1;
6969 Flags |= FLAG_DONE;
6971 if(Flags & FLAG_SINGLEFILE)
6973 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
6975 if(HEADER)
6977 DoOutput("\n");
6978 DoOutputDirect(HEADER, headersize);
6982 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
6983 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
6985 if(Flags & FLAG_SINGLEFILE)
6986 DoOutput("\t.file\t\"%s.o\"\n", name);
6987 DoOutput("\t.align\t3\n");
6988 if(Flags & FLAG_WOSLIBBASE) /* PPCBase already in r3, LibBase in r4 */
6990 if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
6991 DoOutput("\t.extern _%s\n", BaseName);
6992 DoOutput("\t.global __%s\n__%s:\n", name, name);
6994 else
6996 if(BaseName)
6997 DoOutput("\t.extern _%s\n", BaseName);
6998 if(!(ap->Flags & AMIPRAGFLAG_PPC))
6999 DoOutput("\t.extern _PowerPCBase\n");
7000 DoOutput("\t.global _%s\n_%s:\n", name, name);
7003 if(ap->Flags & AMIPRAGFLAG_PPC2)
7005 DoOutput("\tstw\t%s2,20(%s1)\n"
7006 "\tmflr\t%s0\n"
7007 "\tstw\t%s0,16(%s1)\n"
7008 "\tlwz\t%s2,_%s(%s2)\n"
7009 "\tlwz\t%s0,-%d(%s2)\n"
7010 "\tmtlr\t%s0\n"
7011 "\tblrl\n"
7012 "\tlwz\t%s0,16(%s1)\n"
7013 "\tlwz\t%s2,20(%s1)\n"
7014 "\tmtlr\t%s0\n"
7015 "\tblr\n",
7016 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7017 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2,
7018 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7019 PPCRegPrefix, PPCRegPrefix);
7021 else if(ap->Flags & AMIPRAGFLAG_PPC0)
7023 DoOutput("\tmflr\t%s0\n", PPCRegPrefix);
7024 if((flags & FUNCFLAG_TAG) && ap->NumArgs>0)
7026 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7027 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7028 PPCRegPrefix, (int)ap->NumArgs+2,
7029 20+(int)ap->NumArgs*4, PPCRegPrefix, PPCRegPrefix,
7030 (int)ap->NumArgs+2, PPCRegPrefix, 20+(int)ap->NumArgs*4);
7032 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7033 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7034 "\tlwz\t%s11,_%s(%s2)\n"
7035 "\tlwz\t%s0,-%d(%s11)\n"
7036 "\tmtlr\t%s0\n"
7037 "\tblrl\n"
7038 "\tlwz\t%s0,40(%s1)\n"
7039 "\taddi\t%s1,%s1,32\n"
7040 "\tmtlr\t%s0\n"
7041 "\tblr\n",
7042 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7043 BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
7044 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7045 PPCRegPrefix);
7047 else if(ap->Flags & AMIPRAGFLAG_PPC)
7049 count = ap->NumArgs;
7050 if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
7052 /* init stack frame */
7053 i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
7054 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7055 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
7057 if(count > 8)
7059 /* extra arguments must be passed on the stack */
7060 k = 32-(count-8); /* firstreg */
7062 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7063 PPCRegPrefix, k, 56+(count-8)*4, PPCRegPrefix, PPCRegPrefix, k,
7064 i+56, PPCRegPrefix);
7065 if(flags & FUNCFLAG_TAG)
7066 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
7067 i+20+count*4);
7068 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
7070 else if(flags & FUNCFLAG_TAG)
7072 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
7073 PPCRegPrefix, i+20+count*4);
7074 --count;
7077 else /* Args must be shifted! */
7079 /* init stack frame */
7080 i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
7081 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7082 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
7084 if(count > 7)
7086 /* extra arguments must be passed on the stack */
7087 if(count == 8)
7089 /* special case: move 8th argument into stack frame */
7090 if(flags & FUNCFLAG_TAG)
7091 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
7092 i+20+count*4);
7093 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7095 else
7097 k = 32-(count-7); /* firstreg */
7099 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7100 "\tmr\t%s%ld,%s10\n"
7101 "\tlmw\t%s%ld,%ld(%s1)\n",
7102 PPCRegPrefix, k, 56+(count-7)*4, PPCRegPrefix,
7103 PPCRegPrefix, k, PPCRegPrefix, PPCRegPrefix, k+1,
7104 i+56, PPCRegPrefix);
7105 if(flags & FUNCFLAG_TAG)
7106 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix,
7107 PPCRegPrefix, i+20+count*4);
7108 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
7111 else if(flags & FUNCFLAG_TAG)
7113 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
7114 PPCRegPrefix, i+20+count*4);
7115 --count;
7118 /* shift all arguments into their following register */
7119 for(k=(count<8)?count:7; k > 0; --k)
7120 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix, 3+k, PPCRegPrefix, 2+k);
7122 /* load library base and LVO, then call LVO via LR */
7123 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
7126 /* call LVO */
7127 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix,
7128 ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
7130 /* cleanup stack frame and return */
7131 if(count > 8)
7133 k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
7134 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, 32-(count-k),
7135 56+(count-k)*4, PPCRegPrefix);
7138 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7139 PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7141 else
7143 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7144 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7146 /* clear PP_Flags, PP_Stack and PP_StackSize */
7147 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7148 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7149 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7151 if(Flags & FLAG_WOSLIBBASE)
7152 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7153 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix, ap->Bias, PPCRegPrefix,
7154 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7155 else if(!BaseName)
7156 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix,
7157 ap->Bias, PPCRegPrefix, PPCRegPrefix);
7158 else
7159 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7160 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7161 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias,
7162 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7163 PPCRegPrefix);
7165 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
7166 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
7167 for(i = 0; i < k; ++i)
7169 if(i + ofs <= 7)
7171 if(ap->Args[i].ArgReg == REG_A6)
7172 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix, i+3+ofs,
7173 PPCRegPrefix);
7174 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3+ofs);
7176 else
7178 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix, (i+1+ofs)*4+196,
7179 PPCRegPrefix);
7180 if(ap->Args[i].ArgReg == REG_A6)
7181 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7182 DoOutput("\tstw\t%s11,", PPCRegPrefix);
7184 DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
7186 if(flags & FUNCFLAG_TAG)
7188 if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
7189 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i+3+ofs,
7190 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
7191 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix,
7192 PPCRegPrefix, 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
7193 DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
7196 if(!(Flags & FLAG_WOSLIBBASE))
7197 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix, PPCRegPrefix);
7199 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7200 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7201 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7202 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7203 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7206 if(Flags & FLAG_WOSLIBBASE)
7207 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7208 name, name, name);
7209 else
7210 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7211 name, name, name);
7214 uint32 FuncVBCCWOSCode(struct AmiPragma *ap, uint32 flags, strptr name)
7216 uint32 i, j, k, ofs, count;
7217 uint8 *data, *basepos = 0, *pbasepos = 0;
7218 struct ClibData *cd = 0;
7220 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
7221 return 1;
7223 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&
7224 !(cd = GetClibFunc(name, ap, flags)))
7225 return 1;
7227 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
7228 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) ||
7229 !(Flags & FLAG_WOSLIBBASE)))
7231 DoError(ERR_MISSING_BASENAME, ap->Line);
7232 return 1;
7235 Flags |= FLAG_DONE; /* We did something */
7237 i = strlen(name) + 2;
7238 EndPutM32(tempbuf, HUNK_UNIT);
7239 EndPutM32(tempbuf+4, (i+3)>>2);
7240 DoOutputDirect(tempbuf, 8);
7241 DoOutput("%s.o", name);
7242 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
7244 i = strlen(hunkname);
7245 EndPutM32(tempbuf, HUNK_NAME);
7246 EndPutM32(tempbuf+4, (i + 3)>>2);
7247 DoOutputDirect(tempbuf, 8);
7248 DoOutputDirect(hunkname, i);
7249 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
7251 data = tempbuf+8; /* we need HUNK_PPC_CODE + size at start */
7253 if(ap->Flags & AMIPRAGFLAG_PPC2)
7255 EndPutM32Inc(data, 0x90410014); /* stw r2,20(r1) */
7256 /* mflr r0 = mfspr r0,8 = get link register */
7257 EndPutM32Inc(data, 0x7C0802A6);
7258 EndPutM32Inc(data, 0x90010010); /* stw r0,16(r1) */
7259 basepos = data;
7260 EndPutM32Inc(data, 0x80420000); /* lwz r2,BaseName(r2) */
7261 EndPutM32Inc(data, 0x80030000-(ap->Bias-2));/* lwz r0,-ap->Bias-2(r2) */
7262 /* mtlr r0 = mtspr 8,r0 = restore link register */
7263 EndPutM32Inc(data, 0x7C0803A6);
7264 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7265 EndPutM32Inc(data, 0x80010010); /* lwz r0,16(r1) */
7266 EndPutM32Inc(data, 0x80410014); /* lwz r2,20(r1) */
7267 /* mtlr r0 = mtspr 8,r0 = restore link register */
7268 EndPutM32Inc(data, 0x7C0803A6);
7269 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7271 else if(ap->Flags & AMIPRAGFLAG_PPC0)
7273 basepos = data;
7274 /* mflr r0 = mfspr r0,8 = get link register */
7275 EndPutM32Inc(data, 0x7C0802A6);
7276 if((flags & FUNCFLAG_TAG) && ap->NumArgs>0)
7278 EndPutM32Inc(data, 0x90010000 + (((uint32)ap->NumArgs+2) << 21) +
7279 (uint32)(20+ap->NumArgs*4)); /* stw rN,d(r1) */
7280 EndPutM32Inc(data, 0x38010000 + (((uint32)ap->NumArgs+2) << 21) +
7281 (uint32)(20+ap->NumArgs*4)); /* addi rN,r1,d */
7283 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7284 EndPutM32Inc(data, 0x9421FFCE); /* stwu r1,-32(r1) */
7285 EndPutM32Inc(data, 0x81620000); /* lwz r11,BaseName(r2) */
7286 EndPutM32Inc(data, 0x800C0000-(ap->Bias-2));/* lwz r0,-ap->Bias-2(r11) */
7287 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7288 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7289 EndPutM32Inc(data, 0x80010028); /* lwz r0,40(r1) */
7290 EndPutM32Inc(data, 0x38210020); /* addi r1,r1,32 */
7291 /* mtlr r0 = mtspr 8,r0 = restore link register */
7292 EndPutM32Inc(data, 0x7C0803A6);
7293 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7295 else if(ap->Flags & AMIPRAGFLAG_PPC)
7297 count = ap->NumArgs;
7298 if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
7300 /* init stack frame */
7301 i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
7302 /* mflr r0 = mfspr r0,8 = get link register */
7303 EndPutM32Inc(data, 0x7C0802A6);
7304 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7305 EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
7307 if(count > 8)
7309 /* extra arguments must be passed on the stack */
7310 k = 32-(count-8); /* firstreg */
7311 /* stmw rk,X(r1) */
7312 EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-8)*4));
7313 EndPutM32Inc(data, 0xB8010000 + (k << 21) + (i+56)); /* lmw rk,Y(r1) */
7314 if(flags & FUNCFLAG_TAG)
7315 EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4)); /* addi r31,r1,X */
7316 EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
7318 else if(flags & FUNCFLAG_TAG)
7320 /* addi rX,r1,Y */
7321 EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4));
7322 --count;
7325 else /* Args must be shifted! */
7327 /* init stack frame */
7328 i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
7329 /* mflr r0 = mfspr r0,8 = get link register */
7330 EndPutM32Inc(data, 0x7C0802A6);
7331 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7332 EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
7334 if(count > 7)
7336 /* extra arguments must be passed on the stack */
7337 if(count == 8)
7339 /* special case: move 8th argument into stack frame */
7340 if(flags & FUNCFLAG_TAG)
7341 EndPutM32Inc(data, 0x39410000 + (i+20+count*4)); /* addi r10,r1,X */
7342 EndPutM32Inc(data, 0x91410038); /* stw r10,56(r1) */
7344 else
7346 k = 32-(count-7); /* firstreg */
7348 /* stmw rk,X(r1) */
7349 EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-7)*4));
7350 /* mr rk,r10 = or rk,r10,r10 */
7351 EndPutM32Inc(data, 0x7D405378 + (k<<16));
7352 /* lmw rk,Y(r1) */
7353 EndPutM32Inc(data, 0xB8010000 + ((k+1) << 21) + (i+56));
7354 if(flags & FUNCFLAG_TAG)
7356 /* addi r31,r1,X */
7357 EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4));
7359 EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
7362 else if(flags & FUNCFLAG_TAG)
7364 /* addi rX,r1,Y */
7365 EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4));
7366 --count;
7369 /* shift all arguments into their following register */
7370 for(k=(count<8)?count:7; k > 0; --k)
7371 EndPutM32Inc(data, 0x7C000378 + ((3+k)<<16) + ((2+k)<<21) + ((2+k)<<11)); /* mr rX,rY = or rX,rY,rY */
7373 /* load library base and LVO, then call LVO via LR */
7374 basepos = data;
7375 EndPutM32Inc(data, 0x80620000); /* lwz r3,BaseName(r2) */
7377 /* call LVO */
7378 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7379 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7380 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7383 /* cleanup stack frame and return */
7384 if(count > 8)
7386 k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
7387 EndPutM32Inc(data, 0xB8010000 + ((32-(count-k))<<21) + (56+(count-k)*4)); /* lmw rX,Y(r1) */
7389 EndPutM32Inc(data, 0x38210000 + i); /* addi r1,r1,i */
7390 EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) */
7391 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7392 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7394 else
7396 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7397 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7398 EndPutM32Inc(data, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7400 EndPutM32Inc(data, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7401 EndPutM32Inc(data, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7402 EndPutM32Inc(data, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7403 EndPutM32Inc(data, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7405 if(Flags & FLAG_WOSLIBBASE)
7407 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7408 EndPutM32Inc(data, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7409 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7410 EndPutM32Inc(data, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7412 else if(!BaseName)
7414 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7415 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7417 else
7419 basepos = data;
7420 EndPutM32Inc(data, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7421 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7422 EndPutM32Inc(data, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7423 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7424 EndPutM32Inc(data, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7427 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
7428 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
7429 for(i = 0; i < k; ++i)
7431 j = 0x34+4*ap->Args[i].ArgReg; /* PP_Regs offset */
7432 if(i + ofs <= 7)
7434 if(ap->Args[i].ArgReg == REG_A6)
7435 EndPutM32Inc(data, 0x90010020 + ((i+3+ofs)<<21)); /* stw rX,0x20(r1) */
7436 EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
7438 else
7440 EndPutM32Inc(data, 0x81610000 + ((i+1+ofs)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7441 if(ap->Args[i].ArgReg == REG_A6)
7442 EndPutM32Inc(data, 0x91610020); /* stw r11,0x20(r1) */
7443 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
7446 if(flags & FUNCFLAG_TAG)
7448 j = (ap->NumArgs+ofs)*4+0xC4;
7450 if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
7451 EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
7452 EndPutM32Inc(data, 0x39610000 + j); /* addi r11,r1,j */
7453 EndPutM32Inc(data, 0x91610000 + (0x34+4*ap->Args[i].ArgReg)); /* stw r11,X(r1) */
7456 if(!(Flags & FLAG_WOSLIBBASE))
7458 pbasepos = data; /* store 16BIT reloc offset */
7459 EndPutM32Inc(data, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7461 EndPutM32Inc(data, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7462 EndPutM32Inc(data, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7463 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7464 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7465 EndPutM32Inc(data, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7466 EndPutM32Inc(data, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7467 EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) = get old link register */
7468 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7469 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump back */
7472 EndPutM32(tempbuf, HUNK_PPC_CODE);
7473 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
7474 DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
7476 EndPutM32(tempbuf, HUNK_EXT);
7477 DoOutputDirect(tempbuf,4);
7479 /* here come the XDEF name references */
7481 if(Flags & FLAG_WOSLIBBASE)
7483 if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
7484 OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
7485 OutputXDEF(0, "__%s", name);
7487 else
7489 if(BaseName)
7490 OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
7491 if(!(ap->Flags & AMIPRAGFLAG_PPC))
7492 OutputXREF((pbasepos-tempbuf-8)+2, EXT_DEXT16, "_PowerPCBase");
7493 OutputXDEF(0, "_%s", name);
7495 EndPutM32(tempbuf, 0);
7496 DoOutputDirect(tempbuf,4);
7497 if(!(Flags & FLAG_NOSYMBOL))
7499 EndPutM32(tempbuf, HUNK_SYMBOL);
7500 DoOutputDirect(tempbuf,4);
7501 if(Flags & FLAG_WOSLIBBASE)
7502 OutputSYMBOL(0, "__%s", name);
7503 else
7504 OutputSYMBOL(0, "_%s", name);
7505 EndPutM32(tempbuf, 0);
7506 DoOutputDirect(tempbuf,4);
7508 EndPutM32(tempbuf, HUNK_END);
7510 return DoOutputDirect(tempbuf,4);
7513 uint32 FuncVBCCPUPText(struct AmiPragma *ap, uint32 flags, strptr name)
7515 int32 i;
7517 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7518 return 1;
7520 Flags |= FLAG_DONE;
7522 if(Flags & FLAG_SINGLEFILE)
7524 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7526 if(HEADER)
7528 DoOutput("\n");
7529 DoOutputDirect(HEADER, headersize);
7533 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
7534 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
7536 if(Flags & FLAG_SINGLEFILE)
7537 DoOutput("\t.file\t\"%s.o\"\n", name);
7538 if(BaseName)
7539 DoOutput("\t.global %s\n", BaseName);
7540 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7541 "\t.align\t3\n%s:\n",name, name);
7543 if(flags & FUNCFLAG_TAG)
7545 /* Hack the stack-frame for varargs.
7546 Build stack-frame, but save LR in our own stack-frame,
7547 because we have to overwrite the lower 8 bytes of the
7548 caller's frame. */
7549 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7550 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7552 /* Save the caller's saved SP in our own stack-frame. */
7553 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix,
7554 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7556 /* Store r3-r8 at the top of our stack-frame and r9-r10
7557 at the low 8 bytes of the caller's frame. This way all
7558 arguments will reside in one continuous area. */
7559 for(i=3+ap->NumArgs-1; i <= 10; ++i)
7560 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i, 104+4*(i-3),
7561 PPCRegPrefix);
7563 else
7564 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7565 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7567 for(i = 0; i < ap->NumArgs; ++i)
7569 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
7571 if(i <= 7)
7572 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
7573 else
7574 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
7575 100+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
7577 else
7578 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix,
7579 PPCRegPrefix, 100+ap->NumArgs*4, PPCRegPrefix);
7580 DoOutput("%d(%s1)\n", 36+4*ap->Args[i].ArgReg, PPCRegPrefix);
7583 /* Now place the real function call */
7584 /* store offset in Chaos->caos_Un.Offset */
7585 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7586 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix,
7587 ap->Bias, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7588 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7589 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7591 if(BaseName)
7593 if(Flags & FLAG_SMALLDATA)
7594 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName,
7595 PPCRegPrefix);
7596 else
7597 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix,
7598 BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
7599 /* store basepointer in A6 */
7600 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7603 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix, PPCRegPrefix);
7604 if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
7605 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7606 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7607 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7608 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7609 else
7610 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7611 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7613 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name,
7614 name, name);
7617 uint32 FuncVBCCPUPCode(struct AmiPragma *ap, uint32 flags, strptr name)
7619 int32 i, j=0, k, size;
7620 uint8 *data, *data2, *data3;
7621 struct ArHeader *arh;
7623 data = tempbuf;
7625 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7626 return 1;
7628 Flags |= FLAG_DONE;
7630 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7631 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7632 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7633 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7634 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
7635 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
7636 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
7637 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7638 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7639 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7640 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
7641 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
7642 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
7643 EndPutM32Inc(data, 0); /* eeh->e_entry */
7644 EndPutM32Inc(data, 0); /* eeh->e_phoff */
7645 data2 = data; data += 4;
7646 EndPutM32Inc(data, 0); /* eeh->e_flags */
7647 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
7648 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
7649 EndPutM16Inc(data, 0); /* eeh->e_phnum */
7650 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
7651 EndPutM16Inc(data, 6); /* eeh->e_shnum */
7652 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
7654 data3 = data;
7655 if(flags & FUNCFLAG_TAG)
7657 /* Hack the stack-frame for varargs.
7658 Build stack-frame, but save LR in our own stack-frame,
7659 because we have to overwrite the lower 8 bytes of the
7660 caller's frame. */
7661 EndPutM32Inc(data, 0x9421FF80); /* stwu r1,-128(r1) */
7662 EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7663 EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
7665 /* Save the caller's saved SP in our own stack-frame. */
7666 EndPutM32Inc(data, 0x81610080); /* lwz r11,128(r1) */
7667 EndPutM32Inc(data, 0x91610060); /* stw r11,96(r1) */
7669 /* Store r3-r8 at the top of our stack-frame and r9-r10
7670 at the low 8 bytes of the caller's frame. This way all
7671 arguments will reside in one continuous area. */
7672 for(i=3+ap->NumArgs-1; i <= 10; ++i)
7673 EndPutM32Inc(data, 0x90010000 + (i<<21) + (104+4*(i-3))); /* stw rX,Y(r1) */
7675 else
7677 EndPutM32Inc(data, 0x9421FFA0); /* stwu r1,-96(r1) */
7678 EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7679 EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
7682 for(i = 0; i < ap->NumArgs; ++i)
7684 j = 36+4*ap->Args[i].ArgReg;
7685 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
7687 if(i <= 7)
7689 EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j); /* stw rX,j(r1) */
7691 else
7693 EndPutM32Inc(data, 0x81610000 + (100+(i+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7694 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
7697 else
7699 EndPutM32Inc(data, 0x39610000 + (100+ap->NumArgs*4)); /* addi r11,r1,X */
7700 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,X(r1) */
7704 /* Now place the real function call */
7705 EndPutM32Inc(data, 0x39610000 - ap->Bias); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7706 EndPutM32Inc(data, 0x91610008); /* stw r11,8(r1) */
7707 EndPutM32Inc(data, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7708 EndPutM32Inc(data, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7709 EndPutM32Inc(data, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7711 if(BaseName)
7713 if(Flags & FLAG_SMALLDATA)
7715 j = (data-data3)+2; /* store reloc offset */
7716 EndPutM32Inc(data, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7718 else
7720 j = (data-data3)+2; /* store reloc offset */
7721 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7722 EndPutM32Inc(data, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7724 EndPutM32Inc(data, 0x9161005C); /* stw r11,92(r1) */
7727 EndPutM32Inc(data, 0x38610008); /* addi r3,r1,8 */
7728 k = (data-data3); /* store reloc offset */
7729 EndPutM32Inc(data, 0x48000001); /* bl PPCCallOS */
7730 if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
7732 EndPutM32Inc(data, 0x81610060); /* lwz r11,96(r1) */
7733 EndPutM32Inc(data, 0x91610080); /* stw r11,128(r1) */
7734 EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
7735 EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7736 EndPutM32Inc(data, 0x38210080); /* addi r1,r1,128 */
7738 else
7740 EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
7741 EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7742 EndPutM32Inc(data, 0x38210060); /* addi r1,r1,96 */
7745 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
7747 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7748 data += 44; /* 1 9 17 27 33 */
7750 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
7751 data2 = data-44;
7753 EndPutM32Inc(data, 0); /* esh[0].sh_name */
7754 EndPutM32Inc(data, 0); /* esh[0].sh_type */
7755 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
7756 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
7757 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
7758 EndPutM32Inc(data, 0); /* esh[0].sh_size */
7759 EndPutM32Inc(data, 0); /* esh[0].sh_link */
7760 EndPutM32Inc(data, 0); /* esh[0].sh_info */
7761 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
7762 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
7764 size = data2-data3;
7765 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
7766 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
7767 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
7768 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
7769 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
7770 EndPutM32Inc(data, size); /* esh[1].sh_size */
7771 EndPutM32Inc(data, 0); /* esh[1].sh_link */
7772 EndPutM32Inc(data, 0); /* esh[1].sh_info */
7773 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
7774 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
7776 data3 = data;
7777 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
7778 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
7779 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
7780 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
7781 data += 4; /* esh[2].sh_offset */
7782 data += 4; /* esh[2].sh_size */
7783 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7784 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
7785 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
7786 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7788 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
7789 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
7790 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
7791 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
7792 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
7793 EndPutM32Inc(data, 44); /* esh[3].sh_size */
7794 EndPutM32Inc(data, 0); /* esh[3].sh_link */
7795 EndPutM32Inc(data, 0); /* esh[3].sh_info */
7796 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
7797 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
7799 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
7800 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
7801 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
7802 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
7803 data += 4; /* esh[4].sh_offset */
7804 data += 4; /* esh[4].sh_size */
7805 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
7806 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7807 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
7808 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7810 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
7811 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
7812 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
7813 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
7814 data += 4; /* esh[0].sh_offset */
7815 data += 4; /* esh[0].sh_size */
7816 EndPutM32Inc(data, 0); /* esh[0].sh_link */
7817 EndPutM32Inc(data, 0); /* esh[0].sh_info */
7818 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
7819 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
7821 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
7822 EndPutM32(data3+(2*40)+(5*4), BaseName ? 6*16 : 5*16); /* esh[4].sh_size */
7824 data2 = data;
7825 data += BaseName ? 6*16 : 5*16;
7827 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
7829 i = 0;
7830 EndPutM32Inc(data2, i); /* esym[0].st_name */
7831 EndPutM32Inc(data2, 0); /* esym[0].st_value */
7832 EndPutM32Inc(data2, 0); /* esym[0].st_size */
7833 *(data2++) = 0; /* esym[0].st_info */
7834 *(data2++) = 0; /* esym[0].st_other */
7835 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
7836 data[0] = 0;
7838 i += 1;
7839 EndPutM32Inc(data2, i); /* esym[1].st_name */
7840 EndPutM32Inc(data2, 0); /* esym[1].st_value */
7841 EndPutM32Inc(data2, 0); /* esym[1].st_size */
7842 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
7843 *(data2++) = 0; /* esym[1].st_other */
7844 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
7846 sprintf((strptr)data+i, "%s.o", name); while(data[i++]) ; /* get next store space */
7847 EndPutM32Inc(data2, 0); /* esym[2].st_name */
7848 EndPutM32Inc(data2, 0); /* esym[2].st_value */
7849 EndPutM32Inc(data2, 0); /* esym[2].st_size */
7850 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
7851 *(data2++) = 0; /* esym[2].st_other */
7852 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
7854 EndPutM32Inc(data2, i); /* esym[3].st_name */
7855 EndPutM32Inc(data2, 0); /* esym[3].st_value */
7856 EndPutM32Inc(data2, size); /* esym[3].st_size */
7857 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
7858 *(data2++) = 0; /* esym[3].st_other */
7859 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
7861 sprintf((strptr)data+i, "%s", name); while(data[i++]) ; /* get next store space */
7862 EndPutM32Inc(data2, i); /* esym[4].st_name */
7863 EndPutM32Inc(data2, 0); /* esym[4].st_value */
7864 EndPutM32Inc(data2, 0); /* esym[4].st_size */
7865 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
7866 *(data2++) = 0; /* esym[4].st_other */
7867 EndPutM16Inc(data2, 0); /* esym[4].st_shndx */
7869 sprintf((strptr)data+i, "PPCCallOS"); while(data[i++]) ; /* get next store space */
7870 if(BaseName)
7872 EndPutM32Inc(data2, i); /* esym[5].st_name */
7873 EndPutM32Inc(data2, 0); /* esym[5].st_value */
7874 EndPutM32Inc(data2, 0); /* esym[5].st_size */
7875 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[5].st_info */
7876 *(data2++) = 0; /* esym[5].st_other */
7877 EndPutM16/*Inc*/(data2, 0); /* esym[5].st_shndx */
7879 sprintf((strptr)data+i, "%s", BaseName); while(data[i++]) ; /* get next store space */
7881 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
7882 while(i&3) /* long aligned */
7883 data[i++] = 0;
7884 data += i;
7886 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
7888 data2 = data;
7890 EndPutM32Inc(data, k); /* erel[0].r_offset */
7891 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_REL24)); /* erel[0].r_info - entry 4, type 10 */
7892 EndPutM32Inc(data, 0); /* erel[0].r_addend */
7894 if(BaseName)
7896 if(Flags & FLAG_SMALLDATA)
7898 EndPutM32Inc(data, j); /* erel[1].r_offset */
7899 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_SDAREL16)); /* erel[1].r_info - entry 5, type 32 */
7900 EndPutM32Inc(data, 0); /* erel[1].r_addend */
7902 else
7904 EndPutM32Inc(data, j); /* erel[1].r_offset */
7905 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_HA)); /* erel[1].r_info - entry 5, type 6 */
7906 EndPutM32Inc(data, 0); /* erel[1].r_addend */
7907 EndPutM32Inc(data, j+4); /* erel[2].r_offset */
7908 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_LO)); /* erel[2].r_info - entry 5, type 4 */
7909 EndPutM32Inc(data, 0); /* erel[2].r_addend */
7912 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
7914 /* make ar header and store all */
7915 arh = (struct ArHeader *) (data+20);
7916 memset(arh, ' ', sizeof(struct ArHeader));
7918 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
7919 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
7920 arh->ar_mode[2] = '0';
7921 arh->ar_mode[0] = '6';
7922 arh->ar_fmag[0] = 96;
7923 arh->ar_fmag[1] = '\n';
7925 if((k = strlen(name) + 2) >= 16)
7927 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
7929 else
7931 k = 0;
7932 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
7935 j = k + (data-tempbuf);
7936 for(i = 9; j; --i) /* make decimal number */
7938 data[i] = (j%10)+'0';
7939 j /= 10;
7941 for(j = 0; i < 9; ++j)
7942 arh->ar_size[j] = data[++i];
7944 DoOutputDirect(arh, sizeof(struct ArHeader));
7946 if(k)
7948 DoOutput("%s.o", name);
7949 if(k & 1)
7950 *(data++) = 0x0A; /* alignment byte! */
7953 return DoOutputDirect(tempbuf, data-tempbuf);
7956 uint32 FuncVBCCMorphText(struct AmiPragma *ap, uint32 flags, strptr name)
7958 int32 i, nrcopyar = 0, stcksize = 16, basereg = 12;
7960 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7961 return 1;
7963 Flags |= FLAG_DONE;
7965 if(Flags & FLAG_SINGLEFILE)
7967 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7969 if(HEADER)
7971 DoOutput("\n");
7972 DoOutputDirect(HEADER, headersize);
7976 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
7977 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
7979 if(Flags & FLAG_SINGLEFILE)
7980 DoOutput("\t.file\t\"%s.o\"\n", name);
7981 if(BaseName)
7982 DoOutput("\t.global %s\n", BaseName);
7983 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name, name);
7985 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
7987 if(Flags & FLAG_SMALLDATA)
7988 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
7989 PPCRegPrefix, BaseName, PPCRegPrefix);
7990 else
7991 DoOutput("\tlis\t%s11,%s@ha\n"
7992 "\tlwz\t%s12,%s@l(%s11)\n",
7993 PPCRegPrefix, BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
7995 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
7996 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
7999 else
8001 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8003 if(flags & FUNCFLAG_TAG)
8005 DoOutput(
8006 "\tmflr\t%s0\n"
8007 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8008 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8009 "\tstw\t%s0,4(%s1)\n"
8010 "\tsub\t%s11,%s1,%s12\n"
8011 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8012 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8013 "\tsrwi\t%s12,%s12,2\n"
8014 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8015 "\taddi\t%s12,%s1,4\n"
8016 "\tmr\t%s1,%s11\n" /* new stack frame */
8017 "\taddi\t%s11,%s11,8\n"
8018 "\tmtctr\t%s0\n"
8019 ".copyloop_%s:\n"
8020 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8021 "\tstwu\t%s0,4(%s11)\n"
8022 "\tbdnz\t.copyloop_%s\n"
8023 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8024 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8025 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8026 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8027 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8028 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8029 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8030 PPCRegPrefix, PPCRegPrefix, name,
8031 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8032 name, PPCRegPrefix, PPCRegPrefix);
8034 else if(ap->NumArgs >= 8)
8036 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8037 DoOutput(
8038 "\tmflr\t%s0\n"
8039 "\tstwu\t%s1,-%ld(%s1)\n"
8040 "\tstw\t%s0,%ld(%s1)\n",
8041 PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix,
8042 PPCRegPrefix, stcksize+4, PPCRegPrefix);
8044 basereg = 3;
8046 else if(flags & FUNCFLAG_TAG)
8048 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8049 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8051 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8052 || ap->NumArgs >= 8))
8054 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8055 "\tmflr\t%s0\n",
8056 PPCRegPrefix, stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix);
8059 if(nrcopyar)
8061 /* Hack the stack-frame for varargs.
8062 Build stack-frame, but save LR in our own stack-frame,
8063 because we have to overwrite the lower 8 bytes of the
8064 caller's frame. */
8065 /* Save the caller's saved SP in our own stack-frame. */
8066 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix,
8067 stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix);
8069 /* Store r3-r8 at the top of our stack-frame and r9-r10
8070 at the low 8 bytes of the caller's frame. This way all
8071 arguments will reside in one continuous area.
8072 Only copy the really relevant parts. */
8073 for(i = 10; i > 10-nrcopyar; --i)
8074 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i,
8075 stcksize+4*(i-1+nrcopyar-8),PPCRegPrefix);
8078 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8080 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8082 for(i = ap->NumArgs-1; i; --i)
8084 if(i < 7)
8086 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix, 3+i, PPCRegPrefix,
8087 3+i-1);
8089 else if(i == 7)
8091 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix, PPCRegPrefix);
8093 else
8095 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8096 PPCRegPrefix, stcksize+((i-8)+3)*4, PPCRegPrefix, PPCRegPrefix,
8097 ((i-8)+3)*4, PPCRegPrefix);
8101 else
8103 /* shift all the arguments one field */
8104 for(i = ap->NumArgs+3; i > 3; --i)
8106 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix, i, PPCRegPrefix, i-1);
8111 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8112 || ap->NumArgs >= 8))
8113 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix, stcksize+4, PPCRegPrefix);
8115 if(BaseName)
8117 if(Flags & FLAG_SMALLDATA)
8118 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix, basereg,
8119 BaseName, PPCRegPrefix);
8120 else
8121 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8122 PPCRegPrefix, basereg, BaseName, PPCRegPrefix, basereg, BaseName,
8123 PPCRegPrefix, basereg);
8126 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8128 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8129 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
8131 else
8133 for(i = 0; i < ap->NumArgs; ++i)
8135 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8137 if(i <= 7)
8138 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
8139 else
8140 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
8141 stcksize+(i+2-8)*4, PPCRegPrefix, PPCRegPrefix);
8143 else
8144 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix,
8145 PPCRegPrefix, stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0),
8146 PPCRegPrefix);
8147 DoOutput("%d(%s2)\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
8150 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8151 PPCRegPrefix, PPCRegPrefix);
8153 /* store basepointer in A6 */
8154 if(BaseName)
8155 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix, PPCRegPrefix);
8157 /* Now place the real function call */
8158 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8159 PPCRegPrefix, ap->Bias);
8161 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix);
8164 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8166 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8167 PPCRegPrefix, stcksize, PPCRegPrefix, PPCRegPrefix,
8168 stcksize+nrcopyar*4,PPCRegPrefix);
8171 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8172 || ap->NumArgs >= 8))
8174 if(ap->NumArgs >= 8)
8176 DoOutput(
8177 "\tlwz\t%s0,%ld(%s1)\n"
8178 "\taddi\t%s1,%s1,%ld\n"
8179 "\tmtlr\t%s0\n",
8180 PPCRegPrefix,stcksize+4,PPCRegPrefix,PPCRegPrefix,PPCRegPrefix,
8181 stcksize,PPCRegPrefix);
8183 else
8185 DoOutput(
8186 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8187 "\tlwz\t%s0,4(%s1)\n"
8188 "\tmtlr\t%s0\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8189 PPCRegPrefix, PPCRegPrefix);
8192 else
8194 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8195 "\taddi\t%s1,%s1,%ld\n"
8196 "\tmtlr\t%s0\n",
8197 PPCRegPrefix, stcksize+4, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8198 stcksize+nrcopyar*4, PPCRegPrefix);
8201 DoOutput("\tblr\n");
8204 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8205 name, name, name);
8208 uint32 FuncVBCCMorphCode(struct AmiPragma *ap, uint32 flags, strptr name)
8210 int32 i, j, k=0, size, nrcopyar = 0, stcksize = 16, basereg = 12;
8211 uint8 *data, *data2, *data3;
8212 struct ArHeader *arh;
8214 data = tempbuf;
8216 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
8217 return 1;
8219 Flags |= FLAG_DONE;
8221 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8222 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8223 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8224 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8225 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
8226 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
8227 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
8228 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8229 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8230 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8231 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
8232 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
8233 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
8234 EndPutM32Inc(data, 0); /* eeh->e_entry */
8235 EndPutM32Inc(data, 0); /* eeh->e_phoff */
8236 data2 = data; data += 4;
8237 EndPutM32Inc(data, 0); /* eeh->e_flags */
8238 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
8239 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
8240 EndPutM16Inc(data, 0); /* eeh->e_phnum */
8241 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
8242 EndPutM16Inc(data, 6); /* eeh->e_shnum */
8243 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
8245 data3 = data;
8247 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
8249 if(Flags & FLAG_SMALLDATA)
8251 k = (data-data3)+2; /* store reloc offset */
8252 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8254 else
8256 k = (data-data3)+2; /* store reloc offset */
8257 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8258 EndPutM32Inc(data, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8261 EndPutM32Inc(data, 0x800c0000 - (ap->Bias-2));
8262 EndPutM32Inc(data, 0x7c0903a6); /* mtctr r0 */
8263 EndPutM32Inc(data, 0x4e800420); /* bctr */
8266 else
8268 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8270 if(flags & FUNCFLAG_TAG)
8272 /* mflr r0 = mfspr r0,8 = get link register */
8273 EndPutM32Inc(data, 0x7C0802A6);
8274 /* backchain to next frame: lwz r11,0(r1) */
8275 EndPutM32Inc(data, 0x81610000);
8276 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8277 EndPutM32Inc(data, 0x7D815850);
8278 EndPutM32Inc(data, 0x90010004); /* stw r0,4(r1) */
8279 EndPutM32Inc(data, 0x7D6C0850); /* sub r11,r1,r12 */
8280 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8281 EndPutM32Inc(data, 0x396BFFF0);
8282 EndPutM32Inc(data, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8283 EndPutM32Inc(data, 0x558CF0BE); /* srwi r12,r12,2 */
8284 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8285 EndPutM32Inc(data, 0x380CFFFE);
8286 EndPutM32Inc(data, 0x39810004); /* addi r12,r1,4 */
8287 EndPutM32Inc(data, 0x7D615B78); /* mr r1,r11 - new stack frame */
8288 EndPutM32Inc(data, 0x396B0008); /* addi r11,r11,8 */
8289 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8290 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8291 EndPutM32Inc(data, 0x840C0004);
8292 EndPutM32Inc(data, 0x940B0004); /* stwu r0,4(r11) */
8293 EndPutM32Inc(data, 0x4200FFF8); /* bdnz .l */
8294 /* stw r10,8(r1) - last register into stack */
8295 EndPutM32Inc(data, 0x91410008);
8297 else if(ap->NumArgs >= 8)
8299 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8300 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 */
8301 EndPutM32Inc(data, 0x94220000 - stcksize); /* stwu r1,-X(r1) */
8302 EndPutM32Inc(data, 0x90010000 + stcksize + 4); /* stw r0,Y(r1) */
8304 basereg = 3;
8306 else if(flags & FUNCFLAG_TAG)
8308 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8309 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8312 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8313 || ap->NumArgs >= 8))
8315 EndPutM32Inc(data, 0x94210000+0x10000-(stcksize+nrcopyar*4)); /* stwu r1,-%d(r1) */
8316 /* mflr r0 = mfspr r0,8 = get link register */
8317 EndPutM32Inc(data, 0x7C0802A6);
8320 if(nrcopyar)
8322 /* Hack the stack-frame for varargs.
8323 Build stack-frame, but save LR in our own stack-frame,
8324 because we have to overwrite the lower 8 bytes of the
8325 caller's frame. */
8326 /* Save the caller's saved SP in our own stack-frame. */
8327 EndPutM32Inc(data, 0x81610000+stcksize+nrcopyar*4); /* lwz r11,%d(r1) */
8328 EndPutM32Inc(data, 0x91610000+stcksize); /* stw r11,%d(r1) */
8330 /* Store r3-r8 at the top of our stack-frame and r9-r10
8331 at the low 8 bytes of the caller's frame. This way all
8332 arguments will reside in one continuous area.
8333 Only copy the really relevant parts. */
8334 for(i = 10; i > 10-nrcopyar; --i)
8335 EndPutM32Inc(data, 0x90010000 + (i<<21) + (stcksize+4*(i-1+nrcopyar-8))); /* stw rX,Y(r1) */
8338 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8340 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8342 for(i = ap->NumArgs-1; i; --i)
8344 if(i < 7)
8346 /* mr rX,rY */
8347 EndPutM32Inc(data, 0x7C000378 + ((3+i)<<21) + ((3+i-1)<<16) + ((3+i-1)<<11));
8349 else if(i == 7)
8351 /* stw r10,8(r1) */
8352 EndPutM32Inc(data, 0x91410008);
8354 else
8356 /* lwz r11,X(r1) */
8357 EndPutM32Inc(data, 0x81610000 + (stcksize+((i-8)+3)*4));
8358 EndPutM32Inc(data, 0x91620000 + ((i-8)+3)*4); /* stw r11,j(r1) */
8362 else
8364 /* shift all the arguments one field */
8365 for(i = ap->NumArgs+3; i > 3; --i)
8367 /* mr rX,rY */
8368 EndPutM32Inc(data, 0x7C000378 + (i<<21) + ((i-1)<<16) + ((i-1)<<11));
8373 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8374 || ap->NumArgs >= 8))
8375 EndPutM32Inc(data, 0x90010000+stcksize+4); /* stw r0,%d(r1) */
8377 if(BaseName)
8379 if(Flags & FLAG_SMALLDATA)
8381 k = (data-data3)+2; /* store reloc offset */
8382 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8384 else
8386 k = (data-data3)+2; /* store reloc offset */
8387 EndPutM32Inc(data, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8388 EndPutM32Inc(data, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8392 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8394 /* lwz r0,X(r3) */
8395 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2));
8396 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8397 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8399 else
8401 for(i = 0; i < ap->NumArgs; ++i)
8403 j = 4*ap->Args[i].ArgReg;
8404 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8406 if(i <= 7)
8408 EndPutM32Inc(data, 0x90020000 + ((i+3)<<21) + j); /* stw rX,j(r2) */
8410 else
8412 EndPutM32Inc(data, 0x81610000 + (stcksize+(i+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8413 EndPutM32Inc(data, 0x91620000 + j); /* stw r11,j(r1) */
8416 else
8418 EndPutM32Inc(data, 0x38810000 + (stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0))); /* addi r4,r1,X */
8419 EndPutM32Inc(data, 0x90820000 + j); /* stw r4,X(r2) */
8424 EndPutM32Inc(data, 0x81620064); /* lwz r11,100(r2) */
8426 if(BaseName)
8427 EndPutM32Inc(data, 0x91820038); /* stw r12,56(r2) */
8429 /* Now place the real function call */
8430 EndPutM32Inc(data, 0x38600000 + 0x10000 - ap->Bias); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8432 EndPutM32Inc(data, 0x7D6903A6); /* mtctr r11 */
8433 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8435 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8437 EndPutM32Inc(data, 0x81610000 + stcksize); /* lwz r11,X(r1) */
8438 EndPutM32Inc(data, 0x91610000 + (stcksize+nrcopyar*4)); /* stw r11,Y(r1) */
8441 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8442 || ap->NumArgs >= 8))
8444 if(ap->NumArgs >= 8)
8446 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8447 EndPutM32Inc(data, 0x38210000 + stcksize); /* addi r1,r1,Y */
8448 /* mtlr r0 = mtspr 8,r0 = restore link register */
8449 EndPutM32Inc(data, 0x7C0803A6);
8451 else
8453 /* restore old stack frame: lwz r1,0(r1) */
8454 EndPutM32Inc(data, 0x80210000);
8455 EndPutM32Inc(data, 0x80010004); /* lwz r0,4(r1) */
8456 /* mtlr r0 = mtspr 8,r0 = restore link register */
8457 EndPutM32Inc(data, 0x7C0803A6);
8460 else
8462 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8463 EndPutM32Inc(data, 0x38210000 + (stcksize+nrcopyar*4)); /* addi r1,r1,Y */
8464 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8467 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
8470 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8471 data += 44; /* 1 9 17 27 33 */
8473 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
8474 data2 = data-44;
8476 EndPutM32Inc(data, 0); /* esh[0].sh_name */
8477 EndPutM32Inc(data, 0); /* esh[0].sh_type */
8478 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8479 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8480 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
8481 EndPutM32Inc(data, 0); /* esh[0].sh_size */
8482 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8483 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8484 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
8485 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8487 size = data2-data3;
8488 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
8489 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
8490 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
8491 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
8492 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
8493 EndPutM32Inc(data, size); /* esh[1].sh_size */
8494 EndPutM32Inc(data, 0); /* esh[1].sh_link */
8495 EndPutM32Inc(data, 0); /* esh[1].sh_info */
8496 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
8497 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
8499 data3 = data;
8500 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
8501 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
8502 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
8503 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
8504 data += 4; /* esh[2].sh_offset */
8505 data += 4; /* esh[2].sh_size */
8506 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8507 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
8508 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
8509 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8511 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
8512 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
8513 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
8514 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
8515 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
8516 EndPutM32Inc(data, 44); /* esh[3].sh_size */
8517 EndPutM32Inc(data, 0); /* esh[3].sh_link */
8518 EndPutM32Inc(data, 0); /* esh[3].sh_info */
8519 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
8520 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
8522 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
8523 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
8524 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
8525 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
8526 data += 4; /* esh[4].sh_offset */
8527 data += 4; /* esh[4].sh_size */
8528 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
8529 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8530 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
8531 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8533 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
8534 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
8535 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8536 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8537 data += 4; /* esh[0].sh_offset */
8538 data += 4; /* esh[0].sh_size */
8539 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8540 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8541 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
8542 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8544 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
8545 EndPutM32(data3+(2*40)+(5*4), BaseName ? 5*16 : 4*16); /* esh[4].sh_size */
8547 data2 = data;
8548 data += BaseName ? 5*16 : 4*16;
8550 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
8552 i = 0;
8553 EndPutM32Inc(data2, i); /* esym[0].st_name */
8554 EndPutM32Inc(data2, 0); /* esym[0].st_value */
8555 EndPutM32Inc(data2, 0); /* esym[0].st_size */
8556 *(data2++) = 0; /* esym[0].st_info */
8557 *(data2++) = 0; /* esym[0].st_other */
8558 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
8559 data[0] = 0;
8561 i += 1;
8562 EndPutM32Inc(data2, i); /* esym[1].st_name */
8563 EndPutM32Inc(data2, 0); /* esym[1].st_value */
8564 EndPutM32Inc(data2, 0); /* esym[1].st_size */
8565 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
8566 *(data2++) = 0; /* esym[1].st_other */
8567 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
8569 sprintf((strptr)data+i, "%s.o", name); while(data[i++]) ; /* get next store space */
8570 EndPutM32Inc(data2, 0); /* esym[2].st_name */
8571 EndPutM32Inc(data2, 0); /* esym[2].st_value */
8572 EndPutM32Inc(data2, 0); /* esym[2].st_size */
8573 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
8574 *(data2++) = 0; /* esym[2].st_other */
8575 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
8577 EndPutM32Inc(data2, i); /* esym[3].st_name */
8578 EndPutM32Inc(data2, 0); /* esym[3].st_value */
8579 EndPutM32Inc(data2, size); /* esym[3].st_size */
8580 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
8581 *(data2++) = 0; /* esym[3].st_other */
8582 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
8584 sprintf((strptr)data+i, "%s", name); while(data[i++]) ; /* get next store space */
8585 if(BaseName)
8587 EndPutM32Inc(data2, i); /* esym[4].st_name */
8588 EndPutM32Inc(data2, 0); /* esym[4].st_value */
8589 EndPutM32Inc(data2, 0); /* esym[4].st_size */
8590 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
8591 *(data2++) = 0; /* esym[4].st_other */
8592 EndPutM16/*Inc*/(data2, 0); /* esym[4].st_shndx */
8594 sprintf((strptr)data+i, "%s", BaseName); while(data[i++]) ; /* get next store space */
8596 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
8597 while(i&3) /* long aligned */
8598 data[i++] = 0;
8599 data += i;
8601 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
8603 data2 = data;
8605 if(BaseName)
8607 if(Flags & FLAG_SMALLDATA)
8609 EndPutM32Inc(data, k); /* erel[0].r_offset */
8610 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_SDAREL16)); /* erel[0].r_info - entry 4, type 32 */
8611 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8613 else
8615 EndPutM32Inc(data, k); /* erel[0].r_offset */
8616 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_HA)); /* erel[0].r_info - entry 4, type 6 */
8617 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8618 EndPutM32Inc(data, k+4); /* erel[1].r_offset */
8619 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_LO)); /* erel[1].r_info - entry 4, type 4 */
8620 EndPutM32Inc(data, 0); /* erel[1].r_addend */
8623 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
8625 /* make ar header and store all */
8626 arh = (struct ArHeader *) (data+20);
8627 memset(arh, ' ', sizeof(struct ArHeader));
8629 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
8630 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
8631 arh->ar_mode[2] = '0';
8632 arh->ar_mode[0] = '6';
8633 arh->ar_fmag[0] = 96;
8634 arh->ar_fmag[1] = '\n';
8636 if((k = strlen(name) + 2) >= 16)
8638 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
8640 else
8642 k = 0;
8643 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
8646 j = k + (data-tempbuf);
8647 for(i = 9; j; --i) /* make decimal number */
8649 data[i] = (j%10)+'0';
8650 j /= 10;
8652 for(j = 0; i < 9; ++j)
8653 arh->ar_size[j] = data[++i];
8655 DoOutputDirect(arh, sizeof(struct ArHeader));
8657 if(k)
8659 DoOutput("%s.o", name);
8660 if(k & 1)
8661 *(data++) = 0x0A; /* alignment byte! */
8664 return DoOutputDirect(tempbuf, data-tempbuf);
8667 uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
8669 uint8 i, r;
8671 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
8672 (flags & FUNCFLAG_ALIAS))
8673 return 1;
8675 if(LastBias >= ap->Bias)
8676 DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
8677 else
8679 Flags |= FLAG_DONE; /* We did something */
8681 for(LastBias += BIAS_OFFSET; LastBias < ap->Bias; LastBias += BIAS_OFFSET)
8682 DoOutputDirect("Dum\x10", 4);
8684 DoOutput("%c", toupper(name[0]));
8685 if(name[1])
8687 DoOutput("%c", tolower(name[1]));
8688 if(name[2])
8689 DoOutput("%s", name+2);
8691 if(!ap->NumArgs)
8692 DoOutputDirect("\x10", 1);
8693 else
8695 for(i = 0; i < ap->NumArgs; ++i)
8697 r = ap->Args[i].ArgReg;
8698 DoOutputDirect(&r, 1);
8702 return 1;
8705 uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
8707 int32 i;
8709 Flags |= FLAG_DONE; /* We did something */
8711 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8713 if(Flags & FLAG_ISPRIVATE)
8715 Flags ^= FLAG_ISPRIVATE;
8716 DoOutput("##public\n");
8719 else
8721 if(!(Flags & FLAG_ISPRIVATE))
8722 DoOutput("##private\n");
8723 Flags |= FLAG_ISPRIVATE;
8726 LastBias += BIAS_OFFSET;
8727 if(LastBias != ap->Bias)
8729 DoOutput("##bias %d\n", ap->Bias);
8730 LastBias = ap->Bias;
8733 if(ap->Abi != CurrentABI)
8735 switch(ap->Abi)
8737 case ABI_M68K: DoOutput("##abi M68k\n"); break;
8738 case ABI_PPC0: DoOutput("##abi PPC0\n"); break;
8739 case ABI_PPC2: DoOutput("##abi PPC2\n"); break;
8740 case ABI_PPC: DoOutput("##abi PPC\n"); break;
8742 CurrentABI = ap->Abi;
8745 DoOutput("%s("/*)*/, name);
8746 for(i = 0; i < ap->CallArgs; i++)
8747 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->CallArgs-1 ? "," : "");
8748 DoOutput(/*(*/")("/*)*/);
8750 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8752 for(i = 0; i < ap->CallArgs; i++)
8754 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], i < ap->CallArgs-1 ?
8755 (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg ? "/" : ",") : "");
8758 return DoOutput(/*(*/")\n");
8761 /* called from FuncSFD directly */
8762 uint32 FuncClib(struct AmiPragma *ap, uint32 flags, strptr name)
8764 struct ClibData *cd;
8765 int32 i, s, c;
8767 Flags |= FLAG_DONE; /* We did something */
8769 if(!(cd = GetClibFunc(name, ap, flags)))
8770 return 1;
8772 s = MakeClibType(tempbuf, &cd->ReturnType, 0);
8773 DoOutputDirect(tempbuf, s);
8774 DoOutput(" %s("/*)*/, name);
8776 if(ap->NumArgs)
8778 for(i = 0; i < cd->NumArgs; i++)
8780 c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
8781 if(s+c+2 > 75 && s)
8783 DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
8785 else if(i)
8787 DoOutput(", "); s += 2;
8789 DoOutputDirect(tempbuf, c);
8790 s += c;
8793 else if(Flags2 & FLAG2_CLIBOUT)
8794 DoOutput("void");
8795 return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
8798 uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
8800 struct ClibData *cd;
8801 int32 i, j;
8803 if(!(cd = GetClibFunc(name, ap, flags)))
8804 return 1;
8806 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8808 if(Flags & FLAG_ISPRIVATE)
8810 Flags ^= FLAG_ISPRIVATE;
8811 DoOutput("==public\n");
8814 else
8816 if(!(Flags & FLAG_ISPRIVATE))
8817 DoOutput("==private\n");
8818 Flags |= FLAG_ISPRIVATE;
8821 if(ap->Abi != CurrentABI)
8823 switch(ap->Abi)
8825 case ABI_M68K: DoOutput("==abi M68k\n"); break;
8826 case ABI_PPC0: DoOutput("==abi PPC0\n"); break;
8827 case ABI_PPC2: DoOutput("==abi PPC2\n"); break;
8828 case ABI_PPC: DoOutput("==abi PPC\n"); break;
8830 CurrentABI = ap->Abi;
8833 if(LastBias+BIAS_OFFSET < ap->Bias)
8835 DoOutput("==reserve %ld\n", ((ap->Bias-LastBias)/BIAS_OFFSET)-1);
8836 LastBias = ap->Bias;
8838 else if(flags & FUNCFLAG_TAG)
8839 DoOutput("==varargs\n");
8840 else if((flags & FUNCFLAG_ALIAS) || LastBias == ap->Bias)
8841 DoOutput("==alias\n");
8842 else
8843 LastBias += BIAS_OFFSET;
8845 if(!FuncClib(ap, flags, name))
8846 return 0;
8848 DoOutput(" ("/*)*/);
8849 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8851 strptr s;
8853 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8854 in step one, so the "-" can be placed at proper position. */
8855 for(j = i = 0; i < ap->NumArgs; i++)
8857 if(i == ap->NumArgs-1)
8859 s = ""; j += 2;
8861 else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
8863 s = (j&1) ? "," : "-"; ++j;
8865 else
8867 s = ","; j += 2;
8869 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], s);
8872 return DoOutput(/*(*/")\n");
8875 uint32 FuncOS4PPC(struct AmiPragma *ap, uint32 flags, strptr name)
8877 struct ClibData *cd;
8878 int32 i, noret = 0, registers;
8880 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
8881 return 1;
8883 Flags |= FLAG_DONE; /* We did something */
8885 if(!(cd = GetClibFunc(name, ap, flags)))
8886 return 1;
8888 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
8889 noret = 1; /* this is a void function */
8891 sprintf((strptr)tempbuf, "_%s_%s", GetIFXName(), name);
8892 OutClibType(&cd->ReturnType, (strptr)tempbuf);
8894 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8895 ap->NumArgs ? "," : "");
8896 for(i = 0; i < ap->NumArgs; ++i)
8898 DoOutput(" ");
8899 if(i == ap->NumArgs - 1 && (flags & FUNCFLAG_TAG))
8901 DoOutput("...\n");
8903 else
8905 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
8906 if(i < ap->NumArgs-1)
8907 DoOutput(",\n");
8910 if(flags & FUNCFLAG_TAG)
8912 struct ClibData *cd2;
8914 if(!(cd2 = GetClibFunc(ap->FuncName, ap, flags)))
8915 return 1;
8917 DoOutput(/*(*/")\n{\n"/*}*/
8918 " va_list ap;\n"
8919 " va_startlinear(ap, colorMap);\n"
8920 " ");
8921 if(!noret)
8922 DoOutput("return ");
8923 DoOutput("Self->%s(\n"/*)*/, ap->FuncName);
8924 for(i = 0; i < ap->NumArgs-1; ++i)
8926 DoOutput(" %s,\n", ap->Args[i].ArgName);
8928 DoOutput(" va_getlinearva(ap, "/*)*/);
8929 OutClibType(&cd2->Args[i], 0);
8930 DoOutput(/*((*/"));\n");
8932 else
8934 DoOutput(/*(*/")\n{\n"/*}*/
8935 " struct Library *LibBase = Self->Data.LibBase;\n"
8936 " struct ExecIFace *IExec = (struct ExecIFace *)"
8937 "Self->Data.IExecPrivate;\n");
8939 if(!noret)
8941 DoOutput(" ");
8942 OutClibType(&cd->ReturnType, "retval");
8943 DoOutput(";\n");
8946 DoOutput(
8947 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8948 "->EmuWS);\n");
8949 for(i = 0; i < ap->NumArgs; ++i)
8952 registers = GetRegisterData(ap) | 0x40000002; /* set A6 everytime */
8953 for(i = 0; i <= 15; ++i)
8955 if(registers & (1<< (16+i)))
8956 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames[i], i);
8958 DoOutput("\n ");
8960 if(!noret)
8962 DoOutput("retval = ("/*)*/);
8963 OutClibType(&cd->ReturnType, 0);
8964 DoOutput(/*(*/")");
8967 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
8968 " ET_Offset, -%d,\n"/*)*/,ap->Bias);
8969 for(i = 0; i < ap->NumArgs; ++i)
8971 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper[ap->Args[i].ArgReg],
8972 ap->Args[i].ArgName);
8974 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
8975 for(i = 0; i <= 15; ++i)
8977 if(registers & (1<< (16+i)))
8978 DoOutput(" regs[%ld] = save_%s;\n", i, RegNames[i]);
8981 if(!noret)
8982 DoOutput(" return retval;\n");
8984 return DoOutput(/*{*/"}\n\n");
8987 uint32 FuncOS4M68KCSTUB(struct AmiPragma *ap, uint32 flags, strptr name)
8989 struct ClibData *cd;
8990 int32 i, noret = 0;
8992 if(ap->NumArgs <= 7)
8993 return 1;
8995 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
8996 return 1;
8998 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
8999 return 1;
9001 Flags |= FLAG_DONE; /* We did something */
9003 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9004 noret = 1; /* this is a void function */
9006 sprintf((strptr)tempbuf, "Cstub_%s", name);
9007 OutClibType(&cd->ReturnType, (strptr)tempbuf);
9009 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9010 " struct ExecIFace *IExec = (struct ExecIFace *)"
9011 "Interface->Data.IExecPrivate;\n"
9012 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9013 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9015 if(!noret)
9016 DoOutput("return ");
9018 DoOutput("Interface->%s(\n"/*)*/,(flags & FUNCFLAG_TAG) ? ap->FuncName
9019 : name);
9020 for(i = 0; i < ap->NumArgs; ++i)
9022 DoOutput(" ("/*)*/);
9023 OutClibType(&cd->Args[i], 0);
9024 DoOutput(/*(*/") regarray[%d]", ap->Args[i].ArgReg);
9025 if(i < ap->NumArgs-1)
9026 DoOutput(",\n");
9028 return DoOutput(/*{(*/");\n}\n\n");
9031 uint32 FuncOS4M68K(struct AmiPragma *ap, uint32 flags, strptr name)
9033 struct ClibData *cd;
9034 int i;
9036 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9037 return 1;
9039 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9040 return 1;
9042 Flags |= FLAG_DONE; /* We did something */
9044 DoOutput(
9045 "\t.section .data\n"
9046 "\t.globl\tstub_%s\n"
9047 "\t.type\tstub_%s,@function\n"
9048 "\n"
9049 "stub_%s:\n"
9050 "\t.short\t0x4ef8\n"
9051 "\t.short 0\n"
9052 "\t.short 1\n"
9053 "\t.globl\tstub_%sPPC\n"
9054 "\t.long\tstub_%sPPC\n",name, name, name, name, name);
9056 if(ap->NumArgs > 7)
9058 Flags2 |= FLAG2_OS4M68KCSTUB;
9059 DoOutput(
9060 "\t.byte\t2\n" /* Rest of parameters in C */
9061 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9062 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9064 else
9066 DoOutput(
9067 "\t.byte\t%d\n" /* Rest of parameters in C */
9068 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9069 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9070 ap->NumArgs+2);
9071 for(i = 0; i < ap->NumArgs; ++i)
9073 DoOutput("\t.byte\t%d,REG68K_%s\n",i+4,
9074 RegNamesUpper[ap->Args[i].ArgReg]);
9077 DoOutput(
9078 "\t.section .text\n"
9079 "\t.align\t2\n"
9080 "\n"
9081 "stub_%sPPC:\n"
9082 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9083 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9084 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9085 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9086 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9087 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9088 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9089 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9090 name, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9091 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9092 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9093 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
9095 if(ap->NumArgs > 7)
9097 /* Since this function has 11 arguments, we need a C stub */
9098 DoOutput(
9099 "\t.globl\tCstub_%s\n"
9100 "\tlis\t%s4,Cstub_%s@h\n"
9101 "\tori\t%s4,%s4,Cstub_%s@l\n"
9102 "\tmtlr\t%s4\n"
9103 "\tblrl\n",
9104 name, PPCRegPrefix, name, PPCRegPrefix, PPCRegPrefix, name, PPCRegPrefix);
9106 else
9108 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name);
9110 DoOutput(
9111 "\tlwz\t%s11,12(%s1)\n"
9112 "\tmtlr\t%s11\n"
9113 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9114 "\tblrl\n" /* Return to emulation */
9115 "\n"
9116 "\t.globl\tstub_%s68K\n"
9117 "\t.long\tstub_%s68K\n"
9118 "\t.byte\t0\n", /* Flags */
9119 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, name,
9120 name);
9122 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9124 DoOutput(
9125 "\t.byte\t1\n" /* One register (a7 only) */
9126 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9128 else
9130 DoOutput(
9131 "\t.byte\t2\n"
9132 "\t.byte\t1,REG68K_A7\n"
9133 "\t.byte\t3,REG68K_D0\n");
9136 return DoOutput(
9137 "\t.section .data\n"
9138 "\t.align\t4\n"
9139 "\n"
9140 "stub_%s68K:\n"
9141 "\t.short\t0x4e75\n" /* RTS */
9142 "\n", name);
9145 uint32 FuncOS4M68KVect(struct AmiPragma *ap, uint32 flags, strptr name)
9147 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9148 return 1;
9150 while(LastBias + BIAS_OFFSET < ap->Bias)
9152 DoOutput("\t.long\tstub_Reserved\n");
9153 LastBias += BIAS_OFFSET;
9155 LastBias = ap->Bias;
9157 return DoOutput("\t.long\tstub_%s\n", name);
9160 uint32 FuncXML(struct AmiPragma *ap, uint32 flags, strptr name)
9162 struct ClibData *cd;
9163 int32 i;
9165 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9166 return 1;
9168 if(flags & FUNCFLAG_ALIAS)
9169 DoError(ERR_ALIASES_NOT_SUPPORTED, ap->Line);
9171 Flags |= FLAG_DONE; /* We did something */
9173 if(!(cd = GetClibFunc(name, ap, flags)))
9174 return 1;
9176 while(LastBias+BIAS_OFFSET < ap->Bias)
9178 LastBias += BIAS_OFFSET;
9179 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9180 " status=\"unimplemented\"/>\n", LastBias);
9182 LastBias = ap->Bias;
9184 DoOutput("\t\t<method name=\"%s\" result=\"", name);
9185 OutClibType(&cd->ReturnType, 0);
9186 DoOutput("\">\n");
9187 for(i = 0; i < ap->NumArgs; ++i)
9189 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9190 i == ap->NumArgs-1 && (flags & FUNCFLAG_TAG) ? "var" : "",
9191 ap->Args[i].ArgName);
9192 OutClibType(&cd->Args[i], 0);
9193 DoOutput("\"/>\n");
9195 return DoOutput("\t\t</method>\n");
9198 uint32 FuncGateStubs(struct AmiPragma *ap, uint32 flags, strptr name)
9200 struct ClibData *cd;
9201 strptr ret = "return ";
9202 int32 i;
9204 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
9205 return 1;
9207 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9208 return 1;
9210 Flags |= FLAG_DONE; /* We did something */
9212 if(flags & FUNCFLAG_ALIAS)
9214 if(flags & FUNCFLAG_TAG)
9215 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9216 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
9218 DoOutput("#define %s("/*)*/, name);
9219 for(i = 0; i < ap->NumArgs-1; ++i)
9220 DoOutput("%s, ", ap->Args[i].ArgName);
9221 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
9222 for(i = 0; i < ap->NumArgs-1; ++i)
9223 DoOutput("(%s), ", ap->Args[i].ArgName);
9224 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
9227 if((flags & FUNCFLAG_TAG))
9229 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9230 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
9231 for(i = 0; i < ap->NumArgs-1; ++i)
9233 DoOutput("%s, ", ap->Args[i].ArgName);
9235 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9236 ap->FuncName);
9237 for(i = 0; i < ap->NumArgs-1; ++i)
9238 DoOutput("(%s), ", ap->Args[i].ArgName);
9239 DoOutput("("/*)*/);
9240 OutClibType(&cd->Args[i], 0);
9241 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9244 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9245 ret = "";
9247 if(!OutClibType(&cd->ReturnType, 0))
9248 return 0;
9250 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix, name);
9252 for(i = 0; i < ap->NumArgs; ++i)
9254 DoOutput(" ");
9255 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
9256 DoOutput(" = ("/*)*/);
9257 OutClibType(&cd->Args[i], 0);
9258 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper[ap->Args[i].ArgReg]);
9259 if((Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB)) && (Flags2 & FLAG2_REGLIB))
9260 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9262 DoOutput(" %s%s%s("/*)*/, ret, subprefix, name);
9263 if(ap->NumArgs)
9265 if(Flags2 & FLAG2_PRELIB)
9267 if(Flags2 & FLAG2_REGLIB)
9268 DoOutput("___RegBase,");
9269 else
9270 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper);
9273 for(i = 0; i < ap->NumArgs-1; ++i)
9275 DoOutput("%s, ", ap->Args[i].ArgName);
9277 if(Flags2 & FLAG2_POSTLIB)
9279 if(Flags2 & FLAG2_REGLIB)
9280 DoOutput("%s, ___RegBase", ap->Args[i].ArgName);
9281 else
9282 DoOutput("%s, %s_BASE_NAME", ap->Args[i].ArgName, ShortBaseNameUpper);
9284 else
9285 DoOutput("%s", ap->Args[i].ArgName);
9287 else
9289 if(Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB))
9291 if(Flags2 & FLAG2_REGLIB)
9292 DoOutput("___RegBase");
9293 else
9294 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
9297 return DoOutput(/*(({*/"));\n}\n");
9300 static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
9302 uint32 res;
9304 if(Flags & FLAG_SINGLEFILE)
9306 sprintf(filename, filenamefmt, name);
9307 if(!OpenDest(filename))
9308 return 0;
9310 res = Func(ap, flags, name);
9311 if(Flags & FLAG_SINGLEFILE)
9313 CloseDest(filename);
9315 return res;
9318 static uint32 PrintComment(struct Comment *com, strptr comment)
9320 if(com->Private && !(Flags & FLAG_PRIVATE))
9321 return 1;
9322 else if((Flags2 & FLAG2_SFDOUT) && com->Version)
9324 return DoOutput("==version %d\n", com->Version);
9326 else if((Flags2 & FLAG2_SFDOUT) && com->ReservedNum)
9328 LastBias += BIAS_OFFSET*com->ReservedNum;
9329 return DoOutput("==reserve %d\n", com->ReservedNum);
9331 else if(!(Flags & FLAG_DOCOMMENT) || !comment)
9332 return 1;
9334 if(com->Data)
9336 if(!DoOutput(comment, com->Data))
9337 return 0;
9339 else if(com->ReservedNum)
9341 string temp[256];
9342 sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
9343 com->ReservedNum == 1 ? "" : "s");
9344 if(!DoOutput(comment, temp))
9345 return 0;
9347 else if(com->Version)
9349 string temp[256];
9350 if(com->Version >= FIRST_KNOWN_RELEASE && com->Version <= LAST_KNOWN_RELEASE &&
9351 (Flags2 & FLAG2_SYSTEMRELEASE))
9352 sprintf(temp, "* --- functions in V%u or higher %s ---", com->Version,
9353 Release[com->Version-FIRST_KNOWN_RELEASE]);
9354 else
9355 sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
9357 if(!DoOutput(comment, temp))
9358 return 0;
9360 return 1;
9363 static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
9365 struct Comment *com;
9366 int32 i;
9367 struct AmiPragma *ap;
9369 com = (struct Comment *) Comment.First;
9371 for(ap = (struct AmiPragma *) AmiPragma.First; ap;
9372 ap = (struct AmiPragma *) ap->List.Next)
9374 if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
9376 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
9378 else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
9380 while(com && com->Bias <= ap->Bias)
9382 if(!PrintComment(com, comment))
9383 return 0;
9384 com = (struct Comment *) com->List.Next;
9385 } /* comment loop */
9387 #ifdef DEBUG_OLD
9388 printf("Processing %s - %s\n", ap->FuncName ? ap->FuncName : "",
9389 ap->TagName ? ap->TagName : "");
9390 #endif
9392 if(tagmode != TAGMODE_TAGS)
9394 if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
9395 return 0;
9397 for(i = 0; i < ap->NumAlias; ++i)
9399 if(ap->AliasName[i]->Type & FUNCFLAG_NORMAL)
9401 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9402 return 0;
9407 if(tagmode)
9409 if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
9410 return 0;
9412 for(i = 0; i < ap->NumAlias; ++i)
9414 if(ap->AliasName[i]->Type & FUNCFLAG_TAG)
9416 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9417 return 0;
9423 while(com)
9425 if(!PrintComment(com, comment))
9426 return 0;
9427 com = (struct Comment *) com->List.Next;
9428 } /* comment loop */
9429 return 1;
9432 static uint32 PrintIncludes(void) /* copies the include lines */
9434 struct Include *inc;
9435 strptr s, s2;
9437 inc = (struct Include *) Includes.First;
9439 while(inc)
9441 s2 = (strptr) tempbuf;
9442 for(s = inc->Include; *s; ++s)
9444 switch(*s)
9446 case '<': *(s2++) = ' '; break;
9447 case '/':
9448 case '.': *(s2++) = '_'; break;
9449 case '>': break;
9450 default: *(s2++) = toupper(*s);
9452 *s2 = 0;
9454 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
9455 inc = (struct Include *) inc->List.Next;
9457 if(!Includes.First)
9458 DoOutput("#include <exec/types.h>\n");
9459 return DoOutput("\n");
9462 /* ------------------------------------------------------------------ */
9464 static int32 AddClibEntry(strptr buffer, strptr bufend, uint32 linenum)
9466 strptr buf = buffer;
9467 struct ClibData d, *f;
9469 memset(&d, 0, sizeof(struct ClibData));
9470 buf = SkipBlanksRet(buf);
9471 if(*buf == '#') /* preprocessor lines */
9473 #ifdef DEBUG_OLD
9474 printf("Found non-function bracket in preprocessor line %ld\n", linenum);
9475 #endif
9476 while(buf < bufend && *buf != '\n')
9477 ++buf;
9478 return buf-buffer;
9480 if(!strnicmp(buf, "ASM", 3))
9481 buf = SkipBlanks(buf+3);
9482 /* else if(!strnicmp(buf, "STACK", 5))
9483 buf = SkipBlanks(buf+5);
9485 else if(!strnicmp(buf, "REGS", 4))
9486 buf = SkipBlanks(buf+4);
9488 if(!strnicmp(buf, "extern", 6))
9490 buf = SkipBlanksRet(buf+6);
9491 if(!strnicmp(buf, "\"C\"", 3)) /* CPP: extern "C" */
9493 buf = SkipBlanksRet(buf+3);
9494 if (*buf == '{')
9496 buf = SkipBlanksRet(buf+1);
9501 if(!GetCPPType(&d.ReturnType, buf, 1, 1))
9503 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE, linenum);
9504 return 0;
9506 else if(d.ReturnType.Unknown)
9507 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE_INT, linenum,
9508 d.ReturnType.Unknown);
9510 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9512 strptr r = d.ReturnType.TypeStart;
9513 while(*r != '('/*)*/) ++r;
9514 r = SkipBlanks(++r); /* the bracket */
9515 d.FuncName = SkipBlanks(++r); /* the asterisk */
9517 else
9518 d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
9519 buf = d.FuncName;
9520 while(*(buf++) != '('/*)*/)
9522 *(SkipName(d.FuncName)) = 0;
9523 if(!(*d.FuncName))
9525 #ifdef DEBUG_OLD
9526 printf("Found non-function bracket in line %ld\n", linenum);
9527 #endif
9528 while(buf < bufend && *buf != '\n')
9529 ++buf;
9530 return buf-buffer;
9532 buf = SkipBlanksRet(buf);
9534 while(*buf != /*(*/')' && buf < bufend)
9536 if(d.NumArgs == MAXREGPPC+1)
9538 DoError(ERROFFSET_CLIB | ERR_TO_MUCH_ARGUMENTS, linenum);
9539 return 0;
9541 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0, 1))
9543 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
9544 return 0;
9546 else if(d.Args[d.NumArgs-1].Unknown)
9547 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE_INT, linenum,
9548 d.NumArgs, d.Args[d.NumArgs-1].Unknown);
9550 buf = d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength;
9551 while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
9552 ++buf;
9553 #ifdef DEBUG
9554 printf("Added argument %d for %s (%d bytes)\n", d.NumArgs, d.FuncName,
9555 d.Args[d.NumArgs-1].FullLength);
9556 #endif
9557 if(*buf == ',')
9558 buf = SkipBlanksRet(++buf);
9561 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9562 d.NumArgs = 0; /* void arguments are no arguments */
9564 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9565 return -1;
9567 memcpy(f, &d, sizeof(struct ClibData));
9569 if(!clibdata)
9570 clibdata = f;
9571 else
9573 struct ClibData *e = clibdata;
9574 while(e->Next)
9575 e = e->Next;
9576 e->Next = f;
9578 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9580 int numclose = 2, numopen = 1;
9581 while(buf < bufend && (numclose || numopen > 0))
9583 if(*buf == '('/*)*/) { ++numclose; --numopen; }
9584 else if(*buf == /*(*/')') --numclose;
9585 ++buf;
9589 #ifdef DEBUG
9590 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9591 f->FuncName, linenum, buf-buffer, f->NumArgs);
9592 #endif
9593 return buf-buffer;
9596 static int32 ScanClibFile(strptr buf, strptr bufend)
9598 strptr linestart = buf;
9599 uint32 linenum = 1;
9600 int added = 0;
9602 /* remove comments and other not so nice characters */
9603 while(buf < bufend)
9605 if(*buf == '\t' || *buf == '\r' || *buf == (string)0xA0)
9606 *(buf++) = ' ';
9607 else if(buf[0] == '/' && buf < bufend-1)
9609 if(buf[1] == '*')
9611 while(buf < bufend-1 && (buf[0] != '*' || buf[1] != '/'))
9613 if(*buf != '\n')
9614 *buf = ' ';
9615 ++buf;
9617 *(buf++) = ' ';
9618 *(buf++) = ' ';
9620 else if(buf[1] == '/')
9622 while(buf < bufend && buf[0] != '\n')
9623 *(buf++) = ' ';
9624 ++buf;
9626 else
9627 ++buf;
9629 else if(buf[0] == '#' && strncmp("#include", buf, 8))
9631 while(buf < bufend && buf[0] != '\n')
9632 *(buf++) = ' ';
9633 ++buf;
9635 else
9636 ++buf;
9639 #ifdef DEBUG_OLD
9640 printf("-----------\n%s-----------\n", linestart);
9641 #endif
9643 buf = linestart;
9644 while(buf < bufend)
9646 if(*buf == '\n')
9648 ++buf; ++linenum;
9649 if(added)
9651 linestart = buf;
9652 added = 0;
9655 else if(!strncmp("#include", buf, 8))
9657 struct Include *d;
9659 if(!(d = (struct Include *) NewItem(&Includes)))
9660 return 0;
9661 d->Include = buf = SkipBlanks(buf+8);
9662 AddItem(&Includes, (struct ShortList *) d);
9663 while(*buf && *buf != '>' && *buf != '\n')
9664 ++buf;
9665 if(*buf == '>')
9666 ++buf;
9667 if(*buf == '\n')
9668 ++linenum;
9669 *(buf++) = 0;
9670 #ifdef DEBUG_OLD
9671 printf("Added Include line %s\n", d->Include);
9672 #endif
9673 added = 1;
9675 else if(*buf == '('/*)*/)
9677 int32 i;
9679 if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
9680 return 0;
9681 else if(!i)
9683 while(buf < bufend && *buf != '\n')
9684 ++buf; /* skip this line */
9686 else
9688 i -= buf-linestart;
9689 while(buf < bufend && i-- > 0)
9691 if(*(buf++) == '\n')
9693 linestart = buf;
9694 ++linenum;
9695 } /* skip this function */
9698 added = 1;
9700 else
9701 ++buf;
9702 } /* while */
9703 return 1;
9706 static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
9708 if(!data || data->Flags || data->Type != type || data->PointerDepth)
9709 return 0;
9710 return type;
9713 static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
9715 uint32 i, j;
9717 for(i = 0; i < MAXREG; ++i)
9719 j = strlen(RegNames[i]);
9720 if(!strnicmp(string, RegNames[i], j))
9722 string += j;
9723 if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
9725 data->Register = i;
9726 data->Flags |= CPP_FLAG_REGISTER;
9727 return j;
9731 return 0;
9734 static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
9736 strptr buf = buffer;
9737 struct ClibData d;
9739 memset(&d, 0, sizeof(struct ClibData));
9740 while(*buf != /*(*/')')
9742 if(d.NumArgs == MAXREGPPC+1)
9743 return 0;
9744 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1, 1))
9745 return 0;
9747 buf += d.Args[d.NumArgs-1].FullLength;
9748 while(*buf != ',' && *buf != /*(*/')')
9749 ++buf;
9750 if(*buf == ',')
9751 buf = SkipBlanksRet(++buf);
9754 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9755 d.NumArgs = 0; /* void arguments are no arguments */
9757 if(d.NumArgs) /* no need to allocate structure for nothing */
9759 if(!(data->FuncPtr = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9760 return 0;
9762 memcpy(data->FuncPtr, &d, sizeof(struct ClibData));
9764 return (uint32) (buf+1-buffer);
9767 /* rettype turns on usage of "extern" specifier */
9768 static int32 GetCPPType(struct CPP_NameType *data, strptr start, uint32 rettype, uint32 small)
9770 uint32 ok = 1, j;
9771 strptr u;
9773 data->Unknown = 0;
9774 data->Replace = 0;
9775 data->TypeStart = start = SkipBlanks(start);
9777 if(!strncmp(start, "REG", 3) && (start[3] == ' ' || start[3] == '\t' || start[3] == '\n' || start[3] == '('/*)*/))
9779 u = SkipBlanksRet(start+3);
9780 if(*u == '('/*)*/)
9782 u = SkipBlanks(u+1);
9783 if((j = CheckRegisterNum(u, data)))
9785 u = SkipBlanks(u+j);
9786 if(*u == ')')
9787 start = SkipBlanks(u+1);
9791 data->TypeStart = start;
9795 start = SkipBlanks((u = start));
9796 if(!strncmp("...",start,3))
9798 data->Type = CPP_TYPE_VARARGS;
9799 data->TypeLength = start+3 - (data->TypeStart);
9800 data->FullLength = data->TypeLength;
9801 return 1;
9803 if(CheckKeyword(start, "const", 5) || CheckKeyword(start, "CONST", 5))
9805 data->Flags |= CPP_FLAG_CONST; start += 5;
9807 else if(rettype && CheckKeyword(start, "extern", 6))
9809 start += 6; /* ignore it */
9811 else if(CheckKeyword(start, "long", 4))
9813 if(data->Flags & CPP_FLAG_LONG)
9814 data->Type = CPP_TYPE_LONGLONG;
9815 else
9816 data->Flags |= CPP_FLAG_LONG;
9818 start += 4;
9820 else if(CheckKeyword(start, "signed", 6))
9821 start += 6;
9822 else if(CheckKeyword(start, "unsigned", 8))
9824 data->Flags |= CPP_FLAG_UNSIGNED; start += 8;
9826 else if(CheckKeyword(start, "register", 8))
9828 data->Flags |= CPP_FLAG_REGISTER; start += 8;
9829 data->Register = UNDEFREGISTER;
9831 else if(CheckKeyword(start, "struct", 6))
9833 start = SkipBlanks(start+6);
9834 data->Flags |= CPP_FLAG_STRUCT;
9835 if(*start == '?') /* ? for external types */
9837 data->StructureLength = 0;
9838 data->StructureName = "";
9839 ++start;
9841 else if(*start == '!') /* ! for typedef types */
9843 data->Flags |= CPP_FLAG_TYPEDEFNAME;
9844 ++start;
9845 /* structure name and length already set */
9847 else
9849 start = SkipName((data->StructureName = start));
9850 data->StructureLength = start-data->StructureName;
9853 else if(CheckKeyword(start, "union", 5))
9855 start = SkipBlanks(start+5);
9856 data->Flags |= CPP_FLAG_UNION;
9857 if(*start != '?') /* ? for external types */
9859 start = SkipName((data->StructureName = start));
9860 data->StructureLength = start-data->StructureName;
9862 else
9864 data->StructureLength = 0;
9865 data->StructureName = "";
9866 ++start;
9869 else if(CheckKeyword(start, "enum", 4))
9871 start = SkipBlanks(start+4);
9872 data->Flags |= CPP_FLAG_ENUM;
9873 if(*start != '?') /* ? for external types */
9875 start = SkipName((data->StructureName = start));
9876 data->StructureLength = start-data->StructureName;
9878 else
9880 data->StructureLength = 0;
9881 data->StructureName = "";
9882 ++start;
9885 else if(*start == '*')
9887 ++start; ++data->PointerDepth;
9889 else if(*start == '[')
9891 data->Flags |= CPP_FLAG_ARRAY;
9892 while(*start && *start != ']')
9893 ++start;
9894 if(*start)
9895 ++start;
9897 else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
9898 start += 2 + j;
9899 else if(!data->Type)
9901 uint32 i;
9903 for(i = 0; CPP_Field[i].Text; ++i)
9905 if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length) &&
9906 (start[CPP_Field[i].Length] == ' ' ||
9907 start[CPP_Field[i].Length] == '\t' ||
9908 start[CPP_Field[i].Length] == '\n' ||
9909 start[CPP_Field[i].Length] == ',' ||
9910 start[CPP_Field[i].Length] == /*(*/')' ||
9911 start[CPP_Field[i].Length] == '('/*)*/ ||
9912 start[CPP_Field[i].Length] == '*'))
9914 start += CPP_Field[i].Length;
9915 data->Type = CPP_Field[i].Type;
9916 data->Flags |= CPP_Field[i].Flags;
9917 if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
9918 ++data->PointerDepth;
9919 break;
9922 if(CPP_Field[i].Text)
9923 continue;
9924 else if(extnames)
9926 struct CPP_ExternNames *a = extnames;
9928 while(a)
9930 i = strlen(a->Type);
9931 if(!strncmp(a->Type, start, i) && !isalnum(start[i]) &&
9932 start[i] != '_')
9934 start += i;
9935 data->StructureName = a->NameType.StructureName;
9936 data->FuncPtr = a->NameType.FuncPtr;
9937 data->StructureLength = a->NameType.StructureLength;
9938 data->PointerDepth += a->NameType.PointerDepth;
9939 data->Type = a->NameType.Type;
9940 data->Flags |= a->NameType.Flags;
9941 data->FuncArgs = a->NameType.FuncArgs;
9942 data->ArgsLength = a->NameType.ArgsLength;
9943 break;
9946 /* check types here */
9947 a = a->Next;
9949 if(a)
9950 continue;
9951 else if((!data->Type) && (!data->Flags))
9953 long size;
9954 struct CPP_Unknown *u;
9956 data->Type = CPP_TYPE_INT;
9957 size = SkipName(start)-start;
9958 for(u = unknown; u && strncmp(u->Unknown, start, size); u = u->Next)
9960 if(!u)
9962 data->Unknown = DupString(start, size);
9963 if((u = (struct CPP_Unknown *) AllocListMem(sizeof(struct CPP_Unknown))))
9965 u->Next = unknown;
9966 u->Unknown = data->Unknown;
9967 unknown = u;
9970 start += size;
9971 continue;
9974 break;
9976 else
9977 break;
9978 }while(1);
9980 if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
9981 u = start;
9983 data->TypeLength = u - (data->TypeStart);
9984 data->FullLength = data->TypeLength;
9986 u = SkipBlanks(u);
9988 if(*u == '('/*)*/)
9990 ok = 0;
9991 u = SkipBlanksRet(++u);
9992 if(*u == '*')
9994 while(*u == '*')
9996 ++data->FuncPointerDepth; ++u;
9998 u = SkipBlanksRet(u);
9999 if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
10001 data->Flags |= CPP_FLAG_CONST; u += 6;
10003 u = SkipBlanksRet(u);
10004 if(*u != /*(*/')')
10005 data->FunctionName = u;
10006 u = SkipBlanksRet(SkipName(u));
10007 if(*u == '('/*)*/)
10009 int numclose = 1;
10010 ++u;
10011 while(*u && numclose)
10013 if(*u == '('/*)*/) ++numclose;
10014 else if(*u == /*(*/')') --numclose;
10015 ++u;
10018 if(*u == /*(*/')')
10020 u = SkipBlanksRet(++u);
10021 if(*u == '('/*)*/)
10023 data->Flags |= CPP_FLAG_FUNCTION;
10025 if((j = ParseFuncPtrArgs(u+1, data)))
10026 ok = 1;
10027 data->FuncArgs = u;
10028 data->ArgsLength = j+1;
10029 data->FullLength = u+data->ArgsLength - (data->TypeStart);
10035 if(data->PointerDepth)
10036 data->Flags |= CPP_FLAG_POINTER;
10038 if(!(Flags2 & FLAG2_SMALLTYPES) && !small)
10040 if(!(data->Flags & (CPP_FLAG_STRPTR|CPP_FLAG_POINTER|CPP_FLAG_ENUM
10041 |CPP_FLAG_STRUCT|CPP_FLAG_UNION|CPP_FLAG_FUNCTION|CPP_FLAG_REGISTER)))
10043 if(data->Type == CPP_TYPE_BYTE || data->Type == CPP_TYPE_WORD || data->Type == CPP_TYPE_INT)
10045 if(data->Flags & CPP_FLAG_UNSIGNED)
10046 data->Replace = "const ULONG";
10047 else
10048 data->Replace = "const LONG";
10049 data->Type = CPP_TYPE_LONG;
10050 if(!(data->Flags & CPP_FLAG_CONST))
10051 data->Replace += 6;
10056 if(!data->Type && (data->Flags & CPP_FLAG_LONG))
10057 data->Type = CPP_TYPE_LONG;
10059 if((!data->Type && !data->Flags) || !ok)
10060 return 0;
10061 return 1;
10064 static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
10066 struct ClibData *d = clibdata;
10068 if(!name)
10070 DoError(ERR_ILLEGAL_INTERNAL_VALUE, 0);
10071 return 0;
10074 while(d && strcmp(name, d->FuncName))
10075 d = d->Next;
10077 if(!d)
10079 if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
10081 DoError(ERR_PROTOTYPE_MISSING, 0, name);
10082 ap->Flags |= AMIPRAGFLAG_NOCLIB;
10085 else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
10086 ap->CallArgs+1 != d->NumArgs))
10088 if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDARGWARN)))
10090 DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
10091 ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
10093 return 0;
10096 return d;
10099 static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
10101 if(!strncmp(string, keyword, size))
10103 string += size;
10104 if(*string == ' ' || *string == '\t' || *string == '\n')
10105 return size;
10107 return 0;
10110 /* return nonzero, when usable, zero, when string already emitted */
10111 static uint32 CopyCPPType(strptr buffer, uint32 pass, struct ClibData *cd,
10112 struct AmiArgs *args)
10114 uint32 ret = 0, reg;
10115 uint32 i, j, k = 0;
10117 /* pass 0: signed strptr, MaxonC++ high args */
10118 /* pass 1: unsigned strptr, MaxonC++ high args */
10119 /* pass 2: signed strptr, StormC++ high args */
10120 /* pass 3: unsigned strptr, StormC++ high args */
10122 for(i = 0; i < cd->NumArgs; ++i)
10124 struct CPP_NameType *nt;
10126 nt = &cd->Args[i];
10128 if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
10129 reg = 1 + args[k].ArgReg;
10130 else if((nt->Flags & CPP_FLAG_REGISTER) && nt->Register != UNDEFREGISTER)
10131 reg = 1 + nt->Register;
10132 else
10133 reg = 0;
10135 if(reg--) /* subtract the added 1 */
10137 *(buffer++) = CPP_TYPE_REGISTER;
10138 if(reg >= 10)
10140 if(pass & 2)
10142 *(buffer++) = reg/10 + '0';
10143 *(buffer++) = reg%10 + '0';
10144 ret |= 2;
10146 else
10147 *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
10149 else
10150 *(buffer++) = reg + '0';
10153 if(nt->Flags & CPP_FLAG_FUNCTION)
10155 for(j = 0; j < nt->FuncPointerDepth; ++j)
10156 *(buffer++) = CPP_TYPE_POINTER;
10157 *(buffer++) = CPP_TYPE_FUNCTION;
10159 for(j = 0; j < nt->PointerDepth; ++j)
10160 *(buffer++) = CPP_TYPE_POINTER;
10161 if(nt->Flags & CPP_FLAG_CONST)
10162 *(buffer++) = CPP_TYPE_CONST;
10163 if(nt->Flags & CPP_FLAG_UNSIGNED)
10164 *(buffer++) = CPP_TYPE_UNSIGNED;
10165 else if((nt->Flags & CPP_FLAG_STRPTR) && (pass & 1))
10167 *(buffer++) = CPP_TYPE_UNSIGNED;
10168 ret |= 1; /* we really use this pass */
10170 if(nt->Flags & CPP_FLAG_ENUM)
10171 *(buffer++) = CPP_TYPE_ENUM;
10172 if(nt->Type)
10173 *(buffer++) = cd->Args[i].Type;
10174 else
10176 uint32 i;
10177 sprintf(buffer, "%02lu", (uint32) nt->StructureLength); buffer += 2;
10178 for(i = 0; i < nt->StructureLength; ++i)
10179 *(buffer++) = nt->StructureName[i];
10181 if(nt->Flags & CPP_FLAG_FUNCTION)
10183 if(nt->FuncPtr)
10185 ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
10186 while(*buffer)
10187 ++buffer; /* skip to the new end */
10189 *(buffer++) = CPP_TYPE_FUNCEND;
10191 ++k;
10192 if(IsCPPType(nt, CPP_TYPE_DOUBLE)) /* double needs 2 registers */
10193 ++k;
10196 *(buffer) = 0;
10198 if(ret != pass)
10199 ret = 0;
10200 if(!pass)
10201 ret = 0x80;
10203 return ret; /* return nozero if this pass should be used */
10206 static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
10208 if(nt->Replace)
10209 DoOutput("%s", nt->Replace);
10210 else
10211 DoOutputDirect(nt->TypeStart, nt->TypeLength);
10212 if(nt->Type != CPP_TYPE_VARARGS)
10214 if(nt->Flags & CPP_FLAG_FUNCTION)
10216 uint32 i;
10217 DoOutput(" ("/*)*/);
10218 for(i = 0; i < nt->FuncPointerDepth; ++i)
10219 DoOutput("*");
10220 DoOutput(/*((*/txt ? "%s)" : ")", txt);
10221 if(nt->FuncArgs)
10222 return DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
10223 else
10224 return DoOutput("()");
10226 else if(txt)
10227 return DoOutput(" %s", txt);
10230 return 1;
10233 static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
10235 strptr a;
10237 a = dest;
10238 if(nt->Replace)
10240 uint32 i;
10241 i = strlen(nt->Replace);
10242 memcpy(a, nt->Replace, i);
10243 a += i;
10245 else
10247 memcpy(a, nt->TypeStart, nt->TypeLength);
10248 a += nt->TypeLength;
10251 if(nt->Type != CPP_TYPE_VARARGS)
10253 if(nt->Flags & CPP_FLAG_FUNCTION)
10255 a += sprintf(a, (txt ? " (*%s)" : " (*)"), txt);
10256 if(nt->FuncArgs)
10258 memcpy(a, nt->FuncArgs, nt->ArgsLength);
10259 a += nt->ArgsLength;
10261 else
10262 a += sprintf(a, "()");
10264 else if(txt)
10265 a += sprintf(a, " %s", txt);
10267 return (uint32)(a-dest);
10270 static uint32 OutPASCALType(struct CPP_NameType *t, strptr txt, uint32 ret)
10272 int32 i = t->PointerDepth;
10274 if(t->Flags & CPP_FLAG_CONST)
10275 DoOutput("CONST ");
10276 if(!ret && i == 1 &&
10277 (t->Type == CPP_TYPE_LONG || t->Type == CPP_TYPE_WORD))
10279 DoOutput("VAR "); --i;
10282 DoOutput("%s : ", txt);
10284 if(!i && t->Flags == CPP_FLAG_BOOLEAN)
10285 return DoOutput("BOOLEAN");
10286 else if(i && t->Type == CPP_TYPE_VOID)
10287 return DoOutput("POINTER");
10288 else if(t->Flags & CPP_FLAG_FUNCTION)
10289 return DoOutput("tPROCEDURE");
10291 while(i--)
10292 DoOutput("p");
10294 if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
10296 if(!t->PointerDepth)
10297 DoOutput("t");
10298 return DoOutputDirect(t->StructureName, t->StructureLength);
10301 if(t->Flags & CPP_FLAG_UNSIGNED)
10303 if(t->Type == CPP_TYPE_LONG)
10304 return DoOutput("CARDINAL");
10305 if(t->Type == CPP_TYPE_WORD)
10306 return DoOutput("int16");
10307 if(t->Type == CPP_TYPE_BYTE)
10308 return DoOutput(t->PointerDepth == 1 ? "CHAR" : "int8");
10310 else if(t->Type == CPP_TYPE_WORD)
10311 return DoOutput("INTEGER");
10312 else if(t->Type == CPP_TYPE_BYTE)
10313 return DoOutput("SHORTINT");
10314 return DoOutput("int32INT");
10317 /* ------------------------------------------------------------------ */
10319 static uint32 CallPrag(uint32 tagmode, strptr type, FuncType Func)
10321 if(type)
10322 if((*type && !DoOutput("#if%s\n", type)) ||
10323 !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
10324 (*type && !DoOutput("#endif\n")))
10325 return 0;
10326 return 1;
10329 static uint32 CreatePragmaFile(strptr amicall, strptr libcall, strptr amitags,
10330 strptr libtags, uint32 mode)
10332 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10334 switch(mode)
10336 case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10337 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper,
10338 ShortBaseNameUpper); break;
10339 case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10340 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10341 case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10342 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10343 case PRAGMODE_NONE: break;
10344 default: return 0;
10347 if(HEADER)
10349 DoOutput("\n");
10350 DoOutputDirect(HEADER, headersize);
10353 if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10354 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10355 return 0;
10357 if((Flags & FLAG_EXTERNC) &&
10358 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10359 return 0;
10361 if(Flags & FLAG_GNUPRAG)
10363 DoOutput("#ifdef " TEXT_GNUC "\n#ifdef NO_OBSOLETE\n"
10364 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10365 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName);
10366 Flags |= FLAG_DONE;
10370 !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
10371 !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
10372 return 0;
10374 if(tagfuncs)
10377 !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
10378 !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
10379 return 0;
10382 if((Flags & FLAG_EXTERNC) &&
10383 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10384 return 0;
10386 switch(mode)
10388 case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10389 ShortBaseNameUpper); break;
10390 case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10391 ShortBaseNameUpper); break;
10392 case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10393 ShortBaseNameUpper); break;
10394 case PRAGMODE_NONE: break;
10395 default: return 0;
10397 return Output_Error;
10400 static uint32 CreateCSTUBSFile(void)
10402 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10404 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10405 ShortBaseNameUpper, ShortBaseNameUpper);
10407 if(!clibdata)
10409 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10412 if(HEADER)
10414 DoOutput("\n");
10415 DoOutputDirect(HEADER, headersize);
10418 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10419 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10420 return 0;
10422 if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
10423 return 0;
10425 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10426 ShortBaseNameUpper);
10429 static uint32 CreateLVOFile(uint32 mode)
10431 strptr data = "_LVO_I";
10433 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10435 if(mode == 2 || mode == 4)
10436 data = "_LIB_I";
10438 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10439 ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
10440 (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
10441 (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
10442 !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
10443 !DoOutput("\n\n\t\tENDC\n"))
10444 return 0;
10446 return 1;
10449 static uint32 CreateLVOFilePPC(uint32 mode)
10451 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10453 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10454 ShortBaseNameUpper, ShortBaseNameUpper))
10455 return 0;
10456 if(HEADER)
10458 DoOutput("\n");
10459 DoOutputDirect(HEADER, headersize);
10461 switch(mode)
10463 case 0: CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCXDEF);
10464 case 1: CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVOPPC);
10466 return DoOutput("\n\t.endif\n");
10469 static uint32 CreateAsmStubs(uint32 mode, uint32 callmode)
10471 if(mode == 1 && (Flags2 & FLAG2_AUTOHEADER)) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10473 /* 1 = Text, 2 = Code */
10474 switch(mode)
10476 case 1:
10477 if(HEADER)
10479 DoOutput("\n");
10480 DoOutputDirect(HEADER, headersize);
10483 if(!(Flags & FLAG_ASMSECTION))
10484 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
10485 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
10486 if(!CallFunc(callmode, "\n%s", FuncAsmText))
10487 return 0;
10488 break;
10489 case 2:
10490 if(!CallFunc(callmode, 0, FuncAsmCode))
10491 return 0;
10492 break;
10495 return 1;
10498 static uint32 CreateProtoFile(uint32 Type)
10500 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10502 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
10503 ShortBaseNameUpper);
10505 if(HEADER)
10507 DoOutput("\n");
10508 DoOutputDirect(HEADER, headersize);
10511 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10512 if(Type != 5)
10513 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC ")\n"
10514 "#include <clib/%s_protos.h>\n#endif\n",
10515 ShortBaseNameUpper, ShortBaseName);
10517 if(BaseName)
10519 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10520 if(Type == 7)
10521 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10522 "#endif\n");
10523 DoOutput("%s;\n#endif\n", BaseName);
10526 if(Type != 8)
10528 if(Type >= 6)
10530 DoOutput("\n#ifdef " TEXT_GNUC "\n");
10531 if(Type == 10)
10532 DoOutput("#ifndef __cplusplus\n");
10533 DoOutput("#ifdef __AROS__\n");
10534 DoOutput("#include <defines/%s.h>\n", ShortBaseName);
10535 DoOutput("#else\n");
10536 DoOutput("#include <inline/%s.h>\n", ShortBaseName);
10537 DoOutput("#endif\n");
10538 if(Type == 10)
10539 DoOutput("#endif\n");
10540 if(Type != 7)
10542 if(Type == 9)
10543 DoOutput("#elif defined(" TEXT_VBCC ")\n"
10544 "#include <inline/%s_protos.h>\n#else", ShortBaseName);
10545 else
10546 DoOutput("#elif !defined(" TEXT_VBCC ")");
10549 if(Type == 10)
10550 DoOutput("\n#ifndef __PPC__");
10551 if(Type != 7)
10553 strptr str1 = "pragma", str2 = "lib";
10555 switch(Type)
10557 case 4: str1 = "pragmas"; /* no break; */
10558 case 2: str2 = "pragmas"; break;
10559 case 3: str1 = "pragmas"; break;
10560 case 5: str1 = "local"; str2 = "loc"; break;
10562 DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
10564 if(Type == 10)
10565 DoOutput("#endif\n");
10566 if(Type >= 6)
10567 DoOutput("#endif\n");
10570 Flags |= FLAG_DONE;
10572 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10575 static uint32 CreateLocalData(strptr to, uint32 callmode)
10577 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10579 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10580 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10581 ShortBaseNameUpper, ShortBaseNameUpper);
10583 if(HEADER)
10585 DoOutput("\n");
10586 DoOutputDirect(HEADER, headersize);
10589 DoOutput("\n");
10590 PrintIncludes();
10592 if((Flags & FLAG_EXTERNC) &&
10593 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10594 return 0;
10596 if(!CallFunc(callmode, "/%s */\n", FuncLocText))
10597 return 0;
10599 if((Flags & FLAG_EXTERNC) &&
10600 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10601 return 0;
10603 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper);
10605 sprintf(filename, "%s_loc.lib", ShortBaseName);
10606 if(!CloseDest(to) || !OpenDest(filename))
10607 return 0;
10609 CallFunc(callmode, 0, FuncLocCode);
10611 return CloseDest(filename);
10614 static uint32 CreateInline(uint32 mode, uint32 callmode)
10616 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10618 if(!clibdata)
10620 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10623 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10624 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper,
10625 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10627 if(HEADER)
10629 DoOutput("\n");
10630 DoOutputDirect(HEADER, headersize);
10633 DoOutput("\n");
10635 /* prevent loading of clib-file after inline */
10636 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10637 ShortBaseNameUpper, ShortBaseNameUpper);
10639 if(!mode)
10641 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10642 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10643 "#include <ppcinline/macros.h>\n#endif\n\n");
10644 else
10645 DoOutput("#ifndef __INLINE_MACROS_H\n"
10646 "#include <inline/macros.h>\n#endif\n\n");
10647 Flags |= FLAG_INLINENEW;
10649 else if(mode <= 2)
10651 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10652 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10653 "#include <ppcinline/stubs.h>\n#endif\n\n");
10654 else
10655 DoOutput("#ifndef __INLINE_STUB_H\n"
10656 "#include <inline/stubs.h>\n#endif\n\n");
10657 if(mode == 2)
10658 Flags |= FLAG_INLINESTUB;
10660 else if(mode == 3)
10661 Flags2 |= FLAG2_INLINEMAC;
10663 PrintIncludes();
10665 if((Flags & FLAG_EXTERNC) &&
10666 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10667 return 0;
10669 if(BaseName)
10671 if(mode && mode <= 2)
10673 if(Flags & FLAG_MORPHOS)
10674 DoOutput("#include <emul/emulregs.h>\n");
10675 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10676 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10677 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10678 "#define BASE_PAR_DECL0 void\n#endif\n"
10679 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10680 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10682 else
10683 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10684 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10687 if(mode <= 2)
10689 if(!CallFunc(callmode, "/%s */\n", FuncInline))
10690 return 0;
10692 else if(mode >= 6)
10694 if(mode == 7)
10695 Flags |= FLAG_INLINENEW;
10696 if(!CallFunc(callmode, "/%s */\n", FuncInlineDirect))
10697 return 0;
10699 else
10701 if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
10702 return 0;
10705 if(mode && mode <= 2 && BaseName)
10706 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10707 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper);
10709 if((Flags & FLAG_EXTERNC) &&
10710 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10711 return 0;
10713 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10714 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10717 static uint32 CreateGateStubs(uint32 callmode)
10719 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10721 if(!clibdata)
10723 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10725 if(!prefix[0] && !subprefix[0])
10727 DoError(ERR_PREFIX, 0); return 1;
10730 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10731 ShortBaseNameUpper, ShortBaseNameUpper);
10733 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10734 premacro, ShortBaseName);
10736 if(HEADER)
10738 DoOutput("\n");
10739 DoOutputDirect(HEADER, headersize);
10742 if(BaseName)
10744 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10745 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10746 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10747 "#define BASE_PAR_DECL0 void\n#endif\n"
10748 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10749 "BASE_EXT_DECL0\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10752 DoOutput("\n");
10754 if(!CallFunc(callmode, "/%s */\n", FuncGateStubs))
10755 return 0;
10757 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper);
10760 static uint32 CreateSASPowerUP(uint32 callmode)
10762 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10764 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10765 ShortBaseNameUpper, ShortBaseNameUpper);
10767 if(HEADER)
10769 DoOutput("\n");
10770 DoOutputDirect(HEADER, headersize);
10773 DoOutput("\n#ifdef __GNUC__\n"
10774 "#ifndef _PPCINLINE__%s_H\n"
10775 "#include <ppcinline/%s.h>\n"
10776 "#endif\n"
10777 "#else\n\n"
10778 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10779 "#include <ppclib/interface.h>\n"
10780 "#endif\n\n"
10781 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10782 "#include <gcclib/powerup_protos.h>\n"
10783 "#endif\n\n"
10784 "#ifndef NO_PPCINLINE_STDARG\n"
10785 "#define NO_PPCINLINE_STDARG\n"
10786 "#endif /* SAS-C PPC inlines */\n\n",
10787 ShortBaseNameUpper, ShortBaseName);
10789 if(BaseName)
10791 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10792 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10795 if(!CallFunc(callmode, "/%s */\n", FuncPowerUP))
10796 return 0;
10798 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10799 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper);
10802 static uint32 CreateProtoPowerUP(void)
10804 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10806 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10807 ShortBaseNameUpper, ShortBaseNameUpper);
10809 if(HEADER)
10811 DoOutput("\n");
10812 DoOutputDirect(HEADER, headersize);
10815 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
10817 if(BaseName)
10819 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10820 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10821 "#endif\n%s;\n#endif\n", BaseName);
10824 DoOutput("\n#ifdef " TEXT_GNUC "\n"
10825 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10826 "#else\n#include <inline/%s.h>\n#endif\n"
10827 "#else /* SAS-C */\n"
10828 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10829 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10830 ShortBaseName, ShortBaseName, ShortBaseName, ShortBaseName);
10832 Flags |= FLAG_DONE;
10834 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10837 static uint32 CreateFPCUnit(void)
10840 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT);
10842 if(!clibdata)
10844 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10847 DoOutput("{\n");
10848 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName);
10850 if(HEADER)
10852 DoOutput("\n");
10853 DoOutputDirect(HEADER, headersize);
10856 DoOutput("**********************************************************************}\n\n");
10857 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10858 DoOutput("{$mode objfpc}\n");
10859 DoOutput("{$I useamigasmartlink.inc}\n");
10860 DoOutput("{$ifdef use_amiga_smartlink}\n");
10861 DoOutput(" {$smartlink on}\n");
10862 DoOutput("{$endif use_amiga_smartlink}\n\n");
10864 DoOutput("UNIT %s;\n", ShortBaseNameUpper);
10866 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName, GetBaseTypeLib());
10868 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper,ShortBaseName);
10869 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName);
10870 DoOutput("{$I %s.inc}\n\n",ShortBaseName);
10872 if(!CallFunc(TAGMODE_NORMAL, 0, FuncFPCType))
10873 return 0;
10875 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10876 if(!CallFunc(TAGMODE_TAGS, 0, FuncFPCTypeTags))
10877 return 0;
10879 DoOutput("\n{Here we read how to compile this unit}\n");
10880 DoOutput("{You can remove this include and use a define instead}\n");
10881 DoOutput("{$I useautoopenlib.inc}\n");
10882 DoOutput("{$ifdef use_init_openlib}\n");
10883 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10884 DoOutput("{$endif use_init_openlib}\n");
10885 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10886 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper);
10887 DoOutput("\nIMPLEMENTATION\n\n");
10888 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10889 DoOutput("uses \n");
10890 DoOutput("{$ifndef dont_use_openlib}\n");
10891 DoOutput("msgbox, \n");
10892 DoOutput("{$endif dont_use_openlib}\n");
10893 DoOutput("tagsarray;\n\n");
10895 if(!CallFunc(TAGMODE_NORMAL, "(%s *)\n", FuncFPCUnit))
10896 return 0;
10898 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10899 if(!CallFunc(TAGMODE_TAGS,"(%s *)\n", FuncFPCTypeTagsUnit))
10900 return 0;
10902 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10903 DoOutput(" VERSION : string[2] = '0';\n");
10904 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10906 DoOutput("{$ifdef use_init_openlib}\n");
10907 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName);
10908 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper);
10910 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10911 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10912 DoOutput("begin\n");
10913 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10914 DoOutput(" if %s <> nil then begin\n",BaseName);
10915 DoOutput(" CloseLibrary(%s);\n",BaseName);
10916 DoOutput(" %s := nil;\n",BaseName);
10917 DoOutput(" end;\n");
10918 DoOutput("end;\n\n");
10919 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10920 DoOutput("begin\n %s := nil;\n",BaseName);
10921 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10922 DoOutput(" if %s <> nil then begin\n",BaseName);
10923 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10924 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10925 DoOutput(" end else begin\n");
10926 DoOutput(" MessageBox('FPC Pascal Error',\n");
10927 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10928 DoOutput(" 'Deallocating resources and closing down',\n");
10929 DoOutput(" 'Oops');\n");
10930 DoOutput(" halt(20);\n");
10931 DoOutput(" end;\n");
10932 DoOutput("end;\n\n");
10933 DoOutput("begin\n");
10934 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper);
10935 DoOutput("{$endif use_init_openlib}\n\n");
10937 DoOutput("{$ifdef use_auto_openlib}\n");
10938 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName);
10940 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10941 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10942 DoOutput("begin\n");
10943 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10944 DoOutput(" if %s <> nil then begin\n",BaseName);
10945 DoOutput(" CloseLibrary(%s);\n",BaseName);
10946 DoOutput(" %s := nil;\n",BaseName);
10947 DoOutput(" end;\n");
10948 DoOutput("end;\n\n");
10949 DoOutput("begin\n %s := nil;\n",BaseName);
10950 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10951 DoOutput(" if %s <> nil then begin\n",BaseName);
10952 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10953 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10954 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper);
10955 DoOutput(" end else begin\n");
10956 DoOutput(" MessageBox('FPC Pascal Error',\n");
10957 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10958 DoOutput(" 'Deallocating resources and closing down',\n");
10959 DoOutput(" 'Oops');\n");
10960 DoOutput(" halt(20);\n");
10961 DoOutput(" end;\n\n");
10962 DoOutput("{$endif use_auto_openlib}\n\n");
10964 DoOutput("{$ifdef dont_use_openlib}\n");
10965 DoOutput("begin\n");
10966 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper);
10967 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName);
10968 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName);
10969 DoOutput("{$endif dont_use_openlib}\n\n");
10971 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper);
10974 static uint32 CreateBMAP(void)
10976 return CallFunc(TAGMODE_NORMAL, 0, FuncBMAP);
10979 static uint32 CreateLVOLib(void)
10981 uint32 i;
10983 i = strlen(ShortBaseNameUpper);
10984 EndPutM32(tempbuf, HUNK_UNIT);
10985 EndPutM32(tempbuf+4, (i+3)>>2);
10986 DoOutputDirect(tempbuf, 8);
10987 DoOutputDirect(ShortBaseNameUpper, i);
10988 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
10990 i = strlen(hunkname);
10991 EndPutM32(tempbuf, HUNK_NAME);
10992 EndPutM32(tempbuf+4, (i + 3)>>2);
10993 DoOutputDirect(tempbuf, 8);
10994 DoOutputDirect(hunkname, i);
10995 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
10997 EndPutM32(tempbuf, HUNK_CODE);
10998 EndPutM32(tempbuf+4, 0);
10999 EndPutM32(tempbuf+8, HUNK_EXT);
11000 DoOutputDirect(tempbuf, 12);
11002 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOLib))
11003 return 0;
11005 EndPutM32(tempbuf, 0);
11006 EndPutM32(tempbuf+4, HUNK_END);
11007 return DoOutputDirect(tempbuf, 8);
11010 static uint32 CreateLVOLibPPC(void)
11012 uint8 *data = tempbuf, *data2, *data3;
11014 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11015 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11016 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11017 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11018 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
11019 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
11020 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
11021 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11022 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11023 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11024 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
11025 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
11026 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
11027 EndPutM32Inc(data, 0); /* eeh->e_entry */
11028 EndPutM32Inc(data, 0); /* eeh->e_phoff */
11029 data2 = data; data += 4;
11030 EndPutM32Inc(data, 0); /* eeh->e_flags */
11031 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
11032 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
11033 EndPutM16Inc(data, 0); /* eeh->e_phnum */
11034 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
11035 EndPutM16Inc(data, 4); /* eeh->e_shnum */
11036 EndPutM16Inc(data, 1); /* eeh->e_shstrndx - first table is string table */
11038 data3 = data;
11039 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11040 data += 28; /* 1 9 17*/
11041 EndPutM32(data2, data-tempbuf); /* store the entry */
11043 EndPutM32Inc(data, 0); /* esh[0].sh_name */
11044 EndPutM32Inc(data, 0); /* esh[0].sh_type */
11045 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11046 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11047 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
11048 EndPutM32Inc(data, 0); /* esh[0].sh_size */
11049 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11050 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11051 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
11052 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11054 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
11055 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
11056 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
11057 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
11058 EndPutM32Inc(data, data3-tempbuf); /* esh[3].sh_offset */
11059 EndPutM32Inc(data, 27); /* esh[3].sh_size */
11060 EndPutM32Inc(data, 0); /* esh[3].sh_link */
11061 EndPutM32Inc(data, 0); /* esh[3].sh_info */
11062 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
11063 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
11065 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
11066 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
11067 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
11068 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
11069 data2 = data;
11070 data += 4; /* esh[4].sh_offset */
11071 data += 4; /* esh[4].sh_size */
11072 EndPutM32Inc(data, 3); /* esh[4].sh_link - the third entry is our string table */
11073 EndPutM32Inc(data, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11074 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
11075 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11077 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
11078 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
11079 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11080 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11081 data3 = data;
11082 data += 4; /* esh[0].sh_offset */
11083 data += 4; /* esh[0].sh_size */
11084 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11085 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11086 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
11087 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11089 EndPutM32Inc(data2, data-tempbuf);
11091 EndPutM32Inc(data,0);
11092 EndPutM32Inc(data,0); /* first entry is empty */
11093 EndPutM32Inc(data,0);
11094 EndPutM32Inc(data,0);
11096 symoffset = 1; /* initial value */
11097 elfbufpos = data;
11099 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
11100 return 0;
11101 EndPutM32(data2, elfbufpos-data+16);
11102 EndPutM32Inc(data3, elfbufpos-tempbuf);
11103 EndPutM32(data3, symoffset);
11105 *(elfbufpos++) = 0; /* first sym entry */
11106 if(!DoOutputDirect(tempbuf, elfbufpos-tempbuf))
11107 return 0;
11109 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
11110 return 0;
11112 while((symoffset++)&3)
11114 if(!DoOutputDirect("", 1))
11115 return 0;
11118 return 1;
11121 static uint32 CreateVBCCInline(uint32 mode, uint32 callmode)
11123 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11125 if(!clibdata)
11127 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11130 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11131 ShortBaseNameUpper, ShortBaseNameUpper);
11133 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11134 if (mode == 2)
11136 /* always include emul/emulregs.h in MorphOS inlines,
11137 gcc-based sources might depend on it :| */
11138 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11141 if(HEADER)
11143 DoOutput("\n");
11144 DoOutputDirect(HEADER, headersize);
11147 DoOutput("\n");
11149 if(!CallFunc(callmode, "/%s */\n", mode ? (mode == 2 ? FuncVBCCMorphInline
11150 : FuncVBCCWOSInline) : FuncVBCCInline))
11151 return 0;
11153 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper);
11156 static uint32 CreateVBCC(uint32 mode, uint32 callmode)
11158 uint32 res = 0;
11160 if(mode != 2 && mode != 3)
11162 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11164 if(HEADER)
11166 DoOutput("\n");
11167 DoOutputDirect(HEADER, headersize);
11171 switch(mode)
11173 case 4: res = CallFunc(callmode, 0, FuncVBCCPUPText); break;
11175 case 3: Flags |= FLAG_WOSLIBBASE; /* no break! */
11176 case 2: res = CallFunc(callmode, 0, FuncVBCCWOSCode); break;
11178 case 1: Flags |= FLAG_WOSLIBBASE; /* no break! */
11179 case 0: res = CallFunc(callmode, "\n%s", FuncVBCCWOSText); break;
11181 return res;
11184 static uint32 CreateVBCCPUPLib(uint32 callmode)
11186 /* output header */
11187 DoOutput("!<arch>\n");
11189 return CallFunc(callmode, 0, FuncVBCCPUPCode);
11192 static uint32 CreateVBCCMorphCode(uint32 callmode)
11194 /* output header */
11195 DoOutput("!<arch>\n");
11197 return CallFunc(callmode, 0, FuncVBCCMorphCode);
11200 static uint32 CreateEModule(uint32 sorted)
11202 uint32 res = 0, i;
11203 if(sorted)
11204 DoError(ERR_NO_SORTED, 0);
11205 else
11207 DoOutputDirect("EMOD\0\x06", 6);
11208 for(res = 0; res < 2; ++res)
11210 for(i = 0; BaseName[i]; ++i)
11211 DoOutput("%c", tolower(BaseName[i]));
11212 DoOutputDirect("\x00",1);
11214 LastBias = BIAS_START-BIAS_OFFSET;
11215 CallFunc(TAGMODE_NORMAL, 0, FuncEModule);
11216 res = DoOutputDirect("\xFF",1);
11218 return res;
11221 static uint32 CreateProtoRedirect(void)
11223 Flags |= FLAG_DONE;
11224 return DoOutput("#ifdef NO_OBSOLETE\n"
11225 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11226 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName);
11229 static uint32 CreateSFD(uint32 callmode)
11231 struct Include *inc;
11232 struct AmiPragma *ap;
11233 if(!clibdata)
11235 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11238 if((ap = (struct AmiPragma *) AmiPragma.First))
11239 LastBias = ap->Bias-BIAS_OFFSET;
11240 else /* only security, never used normally */
11241 LastBias = 0;
11242 CurrentABI = ABI_M68K;
11244 if(IDstring)
11245 DoOutput("==id %s\n", IDstring);
11246 else
11248 time_t t;
11249 struct tm * tim;
11251 t = time(&t);
11252 tim = localtime(&t);
11254 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11255 "noname Exp $\n", '$', filename, tim->tm_year+1900, tim->tm_mon+1,
11256 tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec);
11259 if(BaseName)
11260 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11261 GetLibraryName(), BaseName, GetBaseType(), GetLibraryName());
11262 DoOutput("==bias %ld\n==public\n", LastBias+BIAS_OFFSET);
11264 for(inc = (struct Include *) Includes.First; inc; inc = (struct Include *) inc->List.Next)
11265 DoOutput("==include %s\n", inc->Include);
11266 if(!Includes.First)
11267 DoOutput("==include <exec/types.h>\n");
11269 CallFunc(callmode, "%s\n", FuncSFD);
11271 return DoOutput("==end\n");
11274 static uint32 CreateClib(uint32 callmode)
11276 if(!clibdata)
11278 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11281 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11283 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper,
11284 ShortBaseNameUpper);
11286 if(HEADER)
11288 DoOutput("\n");
11289 DoOutputDirect(HEADER, headersize);
11291 else
11293 strptr s = 0;
11294 time_t t;
11295 struct tm * tim;
11297 t = time(&t);
11298 tim = localtime(&t);
11300 if(IDstring)
11302 s = SkipBlanks(IDstring+4);
11303 while(*s && *s != ' ')
11304 ++s;
11305 s=SkipBlanks(s);
11307 if(!s || !*s)
11308 s = "1.0";
11310 if(Flags2 & FLAG2_SYSTEMRELEASE)
11312 DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
11314 else
11316 strptr t;
11318 t = s;
11319 while(*t && *t != ' ')
11320 ++t;
11321 *t = 0;
11323 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename, s,
11324 tim->tm_mday, tim->tm_mon+1, tim->tm_year+1900);
11326 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11327 if(!Copyright || (Copyright && strncmp("Copyright ", Copyright, 10)))
11328 DoOutput("Copyright © %d ", tim->tm_year+1900);
11329 DoOutput("%s\n", Copyright ? Copyright : Flags2 & FLAG2_SYSTEMRELEASE ?
11330 "Amiga, Inc." : "");
11331 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11334 PrintIncludes();
11336 if((Flags & FLAG_EXTERNC) &&
11337 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11338 return 0;
11340 CallFunc(callmode, "\n/%s */\n\n", FuncClib);
11342 if((Flags & FLAG_EXTERNC) &&
11343 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11344 return 0;
11346 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper);
11349 static uint32 CreateFD(void)
11351 LastBias = 0;
11352 CurrentABI = ABI_M68K;
11354 if(BaseName)
11355 DoOutput("##base _%s\n", BaseName);
11356 DoOutput("##public\n");
11358 CallFunc(TAGMODE_NORMAL, "%s\n", FuncFD);
11360 return DoOutput("##end\n");
11363 static uint32 CreateGenAuto(strptr to, uint32 type)
11365 strptr name, btype;
11366 uint8 *data;
11367 uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
11368 if(!(name = GetLibraryName()))
11369 return 0;
11370 btype = GetBaseType();
11372 switch(type)
11374 case 0:
11375 Flags |= FLAG_DONE;
11376 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11377 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11378 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11379 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11380 btype, BaseName, BaseName,
11381 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", name, BaseName,
11382 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", BaseName)))
11383 return 0;
11384 sprintf(filename, "%s_autoopenver.c", ShortBaseName);
11385 if(!CloseDest(to) || !OpenDest(filename))
11386 return 0;
11387 Flags |= FLAG_DONE;
11388 return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
11389 break;
11390 case 1: /* m68k */
11391 Flags |= FLAG_DONE;
11392 i = strlen(filename)-4; /* remove .lib extension */
11393 EndPutM32(tempbuf, HUNK_UNIT);
11394 EndPutM32(tempbuf+4, (i+3)>>2);
11395 DoOutputDirect(tempbuf, 8);
11396 DoOutputDirect(filename, i);
11397 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11399 i = strlen(hunkname);
11400 EndPutM32(tempbuf, HUNK_NAME);
11401 EndPutM32(tempbuf+4, (i + 3)>>2);
11402 DoOutputDirect(tempbuf, 8);
11403 DoOutputDirect(hunkname, i);
11404 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11406 data = tempbuf+8; /* we need HUNK_CODE + size at start */
11407 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11408 /* SysBase */
11409 if(Flags & FLAG_SMALLDATA)
11411 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11412 EndPutM16Inc(data, 0); /* place for sysbase reference */
11414 else
11416 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11417 EndPutM32Inc(data, 0); /* place for sysbase reference */
11419 verref = data-tempbuf-8+2;
11420 if(Flags & FLAG_SMALLDATA)
11422 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11423 EndPutM16Inc(data, 0); /* place for basevers reference */
11425 else
11427 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11428 EndPutM32Inc(data, 0); /* place for basevers reference */
11430 EndPutM32Inc(data, 0x43FA0030 + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2) + ((Flags & FLAG_SMALLDATA) ? 0 : 6));
11431 EndPutM32Inc(data, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11433 rel1 = data-tempbuf-8+2;
11434 if(Flags & FLAG_SMALLDATA)
11436 EndPutM16Inc(data, 0x2940); /* MOVE.L D0,xxx(A4) */
11437 EndPutM16Inc(data, 0);
11439 else
11441 EndPutM16Inc(data, 0x23C0); /* MOVE.L D0,xxx */
11442 EndPutM32Inc(data, 0);
11444 EndPutM16Inc(data, 0x660A + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2)); /* BNE.B .lib */
11445 EndPutM32Inc(data, 0x48780014); /* PEA 20 */
11447 exitfuncref = data-tempbuf-8+2;
11448 if(Flags2 & FLAG2_SMALLCODE)
11450 EndPutM16Inc(data, 0x4EBA); /* JSR _exit(PC) */
11451 EndPutM16Inc(data, 0); /* place for base reference */
11453 else
11455 EndPutM16Inc(data, 0x4EB9); /* JSR _exit */
11456 EndPutM32Inc(data, 0); /* place for base reference */
11458 EndPutM16Inc(data, 0x584F); /* ADDQ.W, #4,A7 */
11459 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11460 EndPutM16Inc(data,0x4E75); /* RTS */
11461 exitref = data-tempbuf-8;
11463 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11464 sysref2 = data-tempbuf-8+2;
11465 /* SysBase */
11466 if(Flags & FLAG_SMALLDATA)
11468 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11469 EndPutM16Inc(data, 0); /* place for sysbase reference */
11471 else
11473 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11474 EndPutM32Inc(data, 0); /* place for sysbase reference */
11476 rel2 = data-tempbuf-8+2;
11477 if(Flags & FLAG_SMALLDATA)
11479 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11480 EndPutM16Inc(data, 0); /* place for base reference */
11482 else
11484 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11485 EndPutM32Inc(data, 0); /* place for base reference */
11487 EndPutM16Inc(data, 0x6606); /* BNE.B .nolib */
11488 EndPutM16Inc(data, 0x2240); /* MOVEA.L D0,A1 */
11490 EndPutM32Inc(data, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11491 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11492 EndPutM16Inc(data,0x4E75); /* RTS */
11493 nameref = data-tempbuf-8;
11494 memcpy(data, name, strlen(name));
11495 data += strlen(name);
11496 do { *(data++) = 0; } while((data-tempbuf)&3);
11498 EndPutM32(tempbuf, HUNK_CODE);
11499 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
11500 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
11502 if(Flags & FLAG_SMALLDATA)
11504 EndPutM32(tempbuf, HUNK_DREL16);
11506 else
11508 EndPutM32(tempbuf, HUNK_ABSRELOC32);
11510 EndPutM32(tempbuf+4, 2); /* 2 entries */
11511 EndPutM32(tempbuf+8, 1); /* to hunk 1 */
11512 EndPutM32(tempbuf+12, rel1); /* address 0 */
11513 EndPutM32(tempbuf+16, rel2); /* address 0 */
11514 EndPutM32(tempbuf+20, 0); /* end of reloc hunk */
11515 DoOutputDirect(tempbuf, 24);
11517 /* extern references */
11518 EndPutM32(tempbuf, HUNK_EXT);
11519 DoOutputDirect(tempbuf, 4);
11521 OutputXREF2(4, sysref2, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_SysBase");
11522 OutputXREF(verref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "__%sVer", BaseName);
11523 OutputXREF(exitfuncref, (Flags2 & FLAG2_SMALLCODE ? EXT_DEXT16 : EXT_REF32), "_exit");
11524 OutputXDEF(0, "__INIT_%ld_%s", priority, BaseName);
11525 OutputXDEF(exitref, "__EXIT_%ld_%s", priority, BaseName);
11526 OutputXDEF(nameref, "%sname", ShortBaseName);
11527 EndPutM32(tempbuf, 0); /* ext end */
11528 DoOutputDirect(tempbuf, 4);
11530 if(!(Flags & FLAG_NOSYMBOL))
11532 EndPutM32(tempbuf, HUNK_SYMBOL);
11533 DoOutputDirect(tempbuf, 4);
11534 OutputSYMBOL(0, "__INIT_%ld_%s", priority, BaseName);
11535 OutputSYMBOL(exitref, "__EXIT_%ld_%s", priority, BaseName);
11536 OutputSYMBOL(nameref, "%sname", ShortBaseName);
11537 EndPutM32(tempbuf, 0);
11538 DoOutputDirect(tempbuf, 4);
11541 EndPutM32(tempbuf, HUNK_END);
11542 DoOutputDirect(tempbuf, 4);
11544 i = strlen(datahunkname);
11545 EndPutM32(tempbuf, HUNK_NAME);
11546 EndPutM32(tempbuf+4, (i + 3)>>2);
11547 DoOutputDirect(tempbuf, 8);
11548 DoOutputDirect(datahunkname, i);
11549 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11551 EndPutM32(tempbuf, HUNK_BSS);
11552 EndPutM32(tempbuf+4, 1);
11553 DoOutputDirect(tempbuf, 8);
11555 EndPutM32(tempbuf, HUNK_EXT);
11556 DoOutputDirect(tempbuf, 4);
11557 OutputXDEF(0, "_%s", BaseName);
11558 EndPutM32(tempbuf, 0); /* ext end */
11559 DoOutputDirect(tempbuf, 4);
11561 if(!(Flags & FLAG_NOSYMBOL))
11563 EndPutM32(tempbuf, HUNK_SYMBOL);
11564 DoOutputDirect(tempbuf, 4);
11565 OutputSYMBOL(0, "_%s", BaseName);
11566 EndPutM32(tempbuf, 0);
11567 DoOutputDirect(tempbuf, 4);
11570 EndPutM32(tempbuf, HUNK_END);
11571 DoOutputDirect(tempbuf, 4);
11573 sprintf(filename, "%s_autoopenver", ShortBaseName);
11574 i = strlen(filename);
11575 EndPutM32(tempbuf, HUNK_UNIT);
11576 EndPutM32(tempbuf+4, (i+3)>>2);
11577 DoOutputDirect(tempbuf, 8);
11578 DoOutputDirect(filename, i);
11579 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11581 i = strlen(datahunkname);
11582 EndPutM32(tempbuf, HUNK_NAME);
11583 EndPutM32(tempbuf+4, (i + 3)>>2);
11584 DoOutputDirect(tempbuf, 8);
11585 DoOutputDirect(datahunkname, i);
11586 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11588 EndPutM32(tempbuf, HUNK_BSS);
11589 EndPutM32(tempbuf+4, 1);
11590 DoOutputDirect(tempbuf, 8);
11592 EndPutM32(tempbuf, HUNK_EXT);
11593 DoOutputDirect(tempbuf, 4);
11594 OutputXDEF(0, "_%sVer", BaseName);
11595 EndPutM32(tempbuf, 0); /* ext end */
11596 DoOutputDirect(tempbuf, 4);
11598 if(!(Flags & FLAG_NOSYMBOL))
11600 EndPutM32(tempbuf, HUNK_SYMBOL);
11601 DoOutputDirect(tempbuf, 4);
11602 OutputSYMBOL(0, "_%sVer", BaseName);
11603 EndPutM32(tempbuf, 0);
11604 DoOutputDirect(tempbuf, 4);
11607 EndPutM32(tempbuf, HUNK_END);
11608 return DoOutputDirect(tempbuf, 4);
11610 break;
11612 return 0;
11615 static uint32 CreateXML(void)
11617 struct Include *inc;
11619 LastBias = 30;
11620 DoOutput(
11621 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11622 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11623 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11624 ShortBaseName, BaseName, GetLibraryName());
11625 if(GetBaseTypeLib() != "Library")
11626 DoOutput(" basetype=\"%s\"", GetBaseTypeLib());
11627 DoOutput(">\n");
11628 for(inc = (struct Include *) Includes.First; inc;
11629 inc = (struct Include *) inc->List.Next)
11630 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc->Include)-2),
11631 inc->Include+1);
11632 if(!Includes.First)
11633 DoOutput("\t<include>exec/types.h</include>\n");
11635 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11636 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11637 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11638 DoOutput(
11639 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11640 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11641 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11642 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11643 " status=\"unimplemented\"/>\n");
11645 CallFunc(TAGMODE_BOTH, 0, FuncXML);
11647 return DoOutput("\t</interface>\n</library>\n");
11650 static uint32 CreateOS4PPC(uint32 callmode)
11652 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11654 if(HEADER)
11656 DoOutput("\n");
11657 DoOutputDirect(HEADER, headersize);
11660 PrintIncludes();
11662 DoOutput(
11663 "#include <stdarg.h>\n"
11664 "#include <exec/types.h>\n"
11665 "#include <exec/interfaces.h>\n"
11666 "#include <exec/emulation.h>\n"
11667 "#include <interfaces/exec.h>\n");
11669 if(!stricmp("exec",ShortBaseName))
11670 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName);
11672 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName);
11674 CallFunc(callmode, "\n/%s */\n\n", FuncOS4PPC);
11676 DoOutput(
11677 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11678 " return Self->Data.RefCount++;\n}\n\n"
11679 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11680 " return Self->Data.RefCount--;\n}\n\n"
11681 "#define LIBNAME \"%s\"\n"
11682 "#define LIBVERSION 0\n"
11683 "#define IFACENAME \"%s.main\"\n\n",
11684 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11685 GetLibraryName(), GetLibraryName());
11687 /* following text is constant */
11688 return DoOutput(
11689 "static void InitFunction(APTR dummy, ULONG SegList, "
11690 "struct ExecBase *ExecBase)\n{\n"
11691 " struct Library *LibBase;\n"
11692 " struct ExecIFace *IExec = (struct ExecIFace *)"
11693 "ExecBase->MainInterface;\n"
11694 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11695 " {\n"
11696 " struct Interface *NewInterface;\n"
11697 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11698 " MIT_VectorTable, main_vectors,\n"
11699 " MIT_Version, 1,\n"
11700 " MIT_Name, IFACENAME,\n"
11701 " TAG_DONE)))\n"
11702 " {\n"
11703 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11704 " IExec->AddInterface(LibBase, NewInterface);\n"
11705 " }\n"
11706 " }\n"
11707 "}\n\n"
11708 "volatile static struct Resident MyResident =\n{\n"
11709 " RTC_MATCHWORD,\n"
11710 " (struct Resident *)&MyResident,\n"
11711 " (APTR)(&MyResident+1),\n"
11712 " RTF_NATIVE,\n"
11713 " LIBVERSION,\n"
11714 " NT_UNKNOWN,\n"
11715 " -120,\n"
11716 " IFACENAME,\n"
11717 " IFACENAME,\n"
11718 " InitFunction\n"
11719 "};\n\n"
11720 "void _start(void)\n"
11721 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11722 "\n}\n");
11725 static uint32 CreateOS4M68K(void)
11727 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11729 if(HEADER)
11731 DoOutput("\n");
11732 DoOutputDirect(HEADER, headersize);
11734 DoOutput(
11735 "#include \"exec/interfaces.i\"\n"
11736 "#include \"exec/libraries.i\"\n"
11737 "#include \"exec/emulation.i\"\n"
11738 "#include \"interfaces/%s.i\"\n\n",ShortBaseName);
11740 DoOutput(
11741 "\t.section .data\n"
11742 "\t.globl\tstub_Open\n"
11743 "\t.type\tstub_Open,@function\n"
11744 "\n"
11745 "stub_Open:\n"
11746 "\t.short\t0x4ef8\n" /* JMP.w */
11747 "\t.short\t0\n" /* Indicate switch */
11748 "\t.short\t1\n" /* Trap type */
11749 "\t.globl\tstub_OpenPPC\n"
11750 "\t.long\tstub_OpenPPC\n"
11751 "\t.byte\t2\n" /* Register mapping */
11752 "\t.byte\t1,REG68K_A7\n"
11753 "\t.byte\t3,REG68K_A6\n"
11754 "\t.section .text\n"
11755 "\t.align\t4\n"
11756 "\n"
11757 "stub_OpenPPC:\n"
11758 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11759 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11760 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11761 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11762 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11763 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11764 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11765 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11766 "\tCallLib\tlmi_Open\n"
11767 "\tlwz\t%s11,%s12(%s1)\n"
11768 "\tmtlr\t%s11\n"
11769 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11770 "\tblrl\n" /* Return to emulation */
11771 "\n"
11772 "\t.globl\tstub_Open68K\n"
11773 "\t.long\tstub_Open68K\n"
11774 "\t.byte\t0\n" /* Flags */
11775 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11776 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11777 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11778 "\t.section .data\n"
11779 "\t.align\t4\n"
11780 "\n"
11781 "stub_Open68K:\n"
11782 "\t.short\t0x4e75\n" /* RTS */
11783 "\n"
11784 "\t.section .data\n"
11785 "\t.globl\tstub_Close\n"
11786 "\t.type\tstub_Close,@function\n"
11787 "\n"
11788 "stub_Close:\n"
11789 "\t.short\t0x4ef8\n" /* JMP.w */
11790 "\t.short\t0\n" /* Indicate switch */
11791 "\t.short\t1\n" /* Trap type */
11792 "\t.globl\tstub_ClosePPC\n"
11793 "\t.long\tstub_ClosePPC\n"
11794 "\t.byte\t2\n" /* Register mapping */
11795 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11796 "\t.byte\t3,REG68K_A6\n"
11797 "\t.section .text\n"
11798 "\t.align\t4\n"
11799 "\n"
11800 "stub_ClosePPC:\n"
11801 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11802 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11803 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11804 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11805 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11806 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11807 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11808 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11809 "\tCallLib\tlmi_Close\n"
11810 "\tlwz\t%s11,12(%s1)\n"
11811 "\tmtlr\t%s11\n"
11812 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11813 "\tblrl\n" /* Return to emulation */
11814 "\n"
11815 "\t.globl\tstub_Close68K\n"
11816 "\t.long\tstub_Close68K\n"
11817 "\t.byte\t0\n" /* Flags */
11818 "\t.byte\t1\n" /* One register (a7 only) */
11819 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11820 "\t.section .data\n"
11821 "\t.align\t4\n"
11822 "\n"
11823 "stub_Close68K:\n"
11824 "\t.short\t0x4e75\n" /* RTS */
11825 "\n"
11826 "\t.section .data\n"
11827 "\t.globl\tstub_Expunge\n"
11828 "\t.type\tstub_Expunge,@function\n"
11829 "\n"
11830 "stub_Expunge:\n"
11831 "\t.short\t0x7000\n" /* moveq #0, d0 */
11832 "\t.short\t0x4e75\n" /* RTS */
11833 "\n"
11834 "\t.section .data\n"
11835 "\t.globl\tstub_Reserved\n"
11836 "\t.type\tstub_Reserved,@function\n"
11837 "\n"
11838 "stub_Reserved:\n"
11839 "\t.short\t0x7000\n" /* moveq #0, d0 */
11840 "\t.short\t0x4e75\n\n", /* RTS */
11841 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11842 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11843 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11844 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11845 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11846 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11847 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11848 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11849 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
11851 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68K);
11852 DoOutput("\n"
11853 "\t.globl\tVector68K\n"
11854 "\t.globl\tVecTable68K\n"
11855 "Vector68K:\n"
11856 "\t.long\tVecTable68K\n"
11857 "VecTable68K:\n"
11858 "\t.long\tstub_Open\n"
11859 "\t.long\tstub_Close\n"
11860 "\t.long\tstub_Expunge\n"
11861 "\t.long\tstub_Reserved\n");
11863 LastBias = 30;
11864 CallFunc(TAGMODE_NORMAL, 0, FuncOS4M68KVect);
11865 DoOutput("\t.long\t-1\n");
11867 CloseDest(filename);
11869 if(Flags2 & FLAG2_OS4M68KCSTUB)
11871 sprintf(filename, "%s_68k.c", ShortBaseName);
11872 if(!OpenDest(filename))
11873 exit(20);
11874 Flags &= ~(FLAG_DONE);
11875 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11877 if(HEADER)
11879 DoOutput("\n");
11880 DoOutputDirect(HEADER, headersize);
11883 DoOutput(
11884 "#ifdef __USE_INLINE__\n"
11885 "#undef __USE_INLINE__\n"
11886 "#endif\n"
11887 "#ifndef __NOGLOBALIFACE__\n"
11888 "#define __NOGLOBALIFACE__\n"
11889 "#endif\n\n"
11890 "#include <exec/interfaces.h>\n"
11891 "#include <exec/libraries.h>\n"
11892 "#include <exec/emulation.h>\n"
11893 "#include <interfaces/exec.h>\n"
11894 "#include <interfaces/%s.h>\n"
11895 "#include <proto/%s.h>\n\n", ShortBaseName, ShortBaseName);
11897 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68KCSTUB);
11899 return Output_Error;
11902 /* ------------------------------------------------------------------ */
11904 static uint32 GetName(struct NameList *t, struct ShortListRoot *p, uint32 args)
11906 struct NameList *p2 = (struct NameList *) p->First;
11907 struct AmiPragma ap;
11908 memset(&ap, 0, sizeof(struct AmiPragma));
11909 ap.FuncName = t->NormName;
11910 ap.NumArgs = 1;
11911 ap.CallArgs = 1;
11912 ap.Args[0].ArgName = (args ? "args" : "tags");
11913 if(!MakeTagFunction(&ap))
11914 return 0;
11916 if(!ap.TagName)
11917 return 0;
11919 while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
11920 p2 = (struct NameList *) p2->List.Next;
11922 if(!p2)
11923 return 0;
11925 t->Type = (args ? NTP_ARGS : NTP_TAGS);
11926 t->PragName = ap.TagName;
11927 RemoveItem(p, (struct ShortList *) p2);
11929 #ifdef DEBUG_OLD
11930 printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
11931 #endif
11933 return 1;
11936 static void OptimizeFDData(struct PragData *pd)
11938 #ifdef DEBUG_OLD
11939 printf("OptimizeFDData\n");
11940 #endif
11942 while(pd)
11944 if(pd->NumNames > 1)
11946 struct ShortListRoot n = {0,0,0}, p = {0,0,0};
11947 struct NameList *t;
11948 while(pd->Name.First) /* sorts in AmiCall and TagCall */
11950 t = (struct NameList *) pd->Name.First;
11952 RemoveItem(&pd->Name, (struct ShortList *) t);
11953 AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
11956 if(p.First)
11958 t = (struct NameList *) n.First;
11959 while(p.First && t)
11961 if(!GetName(t, &p, 0))
11963 GetName(t, &p, 1);
11965 if(t->PragName)
11967 struct NameList *t2 = (struct NameList *) t->List.Next;
11968 RemoveItem(&n, (struct ShortList *)t);
11969 AddItem(&pd->Name, (struct ShortList *) t);
11970 t = t2;
11972 else
11973 t = (struct NameList *) t->List.Next;
11975 while(p.First)
11977 if(n.First)
11979 t = (struct NameList *) n.First;
11980 t->PragName = ((struct NameList *)(p.First))->PragName;
11981 RemoveItem(&n, (struct ShortList *) t);
11982 #ifdef DEBUG_OLD
11983 printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
11984 #endif
11985 t->Type = NTP_UNKNOWN;
11987 else
11989 uint32 i;
11991 t = (struct NameList *) p.First;
11992 i = strlen(t->PragName);
11993 t->NormName = DupString(t->PragName, i+1);
11994 t->NormName[i++] = 'A';
11995 t->NormName[i] = 0;
11996 t->Type = NTP_TAGS;
11997 #ifdef DEBUG_OLD
11998 printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
11999 #endif
12002 AddItem(&pd->Name, (struct ShortList *) t);
12003 RemoveItem(&p, p.First);
12007 AddItem(&pd->Name, n.First); /* add left NormNames */
12009 pd = (struct PragData *) pd->List.Next;
12013 static uint32 MakeFD(struct PragList *pl)
12015 struct PragData *pd = (struct PragData *) pl->Data.First;
12016 uint32 bias;
12018 #ifdef DEBUG_OLD
12019 printf("MakeFD\n");
12020 #endif
12021 bias = pd->Bias;
12023 OptimizeFDData(pd);
12024 #ifdef DEBUG_OLD
12025 printf("MakeFD: after Optimizing\n");
12026 #endif
12027 DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
12029 while(pd && Output_Error)
12031 struct NameList *n = (struct NameList *) pd->Name.First;
12033 if(bias != pd->Bias)
12034 DoOutput("##bias %ld\n", (bias = pd->Bias));
12036 while(n)
12038 strptr lastpar = "last";
12039 uint32 i;
12041 if(n->Type == NTP_TAGS)
12042 lastpar = "tags";
12043 else if(n->Type == NTP_ARGS)
12044 lastpar = "args";
12046 DoOutput("%s("/*)*/,n->NormName);
12047 if(!pd->NumArgs)
12048 DoOutput(/*(*/")()\n");
12049 else
12051 for(i = 0; i < pd->NumArgs-1; ++i)
12052 DoOutput("par%ld,",i+1);
12053 DoOutput(/*(*/"%s)("/*)*/, lastpar);
12054 for(i = 0; i < pd->NumArgs-1; ++i)
12055 DoOutput("%s,", RegNames[pd->ArgReg[i]]);
12056 DoOutput(/*(*/"%s)\n", RegNames[pd->ArgReg[i]]);
12058 if(n->Type == NTP_UNKNOWN)
12060 uint32 i;
12061 for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
12063 DoOutput("*tagcall");
12064 if(n->NormName[i])
12065 DoOutput("-%s", n->NormName+i);
12066 if(n->PragName[i])
12067 DoOutput("+%s", n->PragName+i);
12069 DoOutput("\n");
12072 if((n = (struct NameList *) n->List.Next))
12073 DoOutput("##bias %ld\n", pd->Bias);
12074 Flags |= FLAG_DONE;
12077 pd = (struct PragData *)pd->List.Next; bias += BIAS_OFFSET;
12080 DoOutput("##end\n");
12082 return Output_Error;
12085 static uint32 AddFDData(struct ShortListRoot *pls, struct FDData *fd)
12087 struct NameList *t;
12088 struct PragList *pl = (struct PragList *) pls->First;
12089 struct PragData *pd;
12091 while(pl && strcmp(pl->Basename, fd->Basename))
12092 pl = (struct PragList *) pl->List.Next;
12094 if(!pl)
12096 #ifdef DEBUG_OLD
12097 printf("AddFDData: New PragList - %s\n", fd->Basename);
12098 #endif
12099 if(!(pl = (struct PragList *) NewItem(pls)))
12100 return 100;
12101 pl->Basename = fd->Basename;
12102 pl->Data.Size = sizeof(struct PragData);
12103 AddItem(pls, (struct ShortList *) pl);
12106 if((pd = (struct PragData *) pl->Data.First))
12108 while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
12109 <= fd->Bias)
12110 pd = (struct PragData *) pd->List.Next;
12113 if(!pd || pd->Bias != fd->Bias)
12115 struct PragData *pd2;
12116 #ifdef DEBUG_OLD
12117 printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
12118 #endif
12119 if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
12120 return 100;
12121 pd2->Bias = fd->Bias;
12122 memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
12123 pd2->NumArgs = fd->NumArgs;
12124 pd2->Name.Size = sizeof(struct NameList);
12125 if(!pd)
12126 AddItem(&pl->Data, (struct ShortList *) pd2);
12127 else if(pd->Bias > fd->Bias) /* Insert at start */
12129 pd2->List.Next = pl->Data.First;
12130 pl->Data.First = (struct ShortList *) pd2;
12132 else /* Insert the entry */
12134 pd2->List.Next = pd->List.Next;
12135 pd->List.Next = (struct ShortList *) pd2;
12137 pd = pd2;
12139 else
12141 uint32 i = fd->NumArgs;
12142 if(fd->NumArgs != pd->NumArgs)
12144 #ifdef DEBUG_OLD
12145 printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
12146 #endif
12147 return ERR_DIFFERENT_TO_PREVIOUS;
12150 while(i--)
12152 if(fd->ArgReg[i] != pd->ArgReg[i])
12154 #ifdef DEBUG_OLD
12155 printf("ArgReg %x != %x\n", fd->ArgReg[i], pd->ArgReg[i]);
12156 #endif
12157 return ERR_DIFFERENT_TO_PREVIOUS;
12162 t = (struct NameList *) pd->Name.First; /* skips same names */
12163 while(t && (!(fd->Mode ? t->PragName : t->NormName) ||
12164 strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName)))
12165 t = (struct NameList *) t->List.Next;
12167 if(t)
12168 return 0;
12170 if(!(t = (struct NameList *) NewItem(&pd->Name)))
12171 return 100;
12172 if(fd->Mode)
12173 t->PragName = fd->Name;
12174 else
12175 t->NormName = fd->Name;
12176 AddItem(&pd->Name, (struct ShortList *) t);
12177 ++(pd->NumNames);
12178 #ifdef DEBUG_OLD
12179 printf("AddFDData: New NameList - %s\n", fd->Name);
12180 #endif
12181 return 0;
12184 static string GetHexValue(string data)
12186 if(data >= 'a')
12187 return (string) (data - 'a' + 10);
12188 else if(data >= 'A')
12189 return (string) (data - 'A' + 10);
12190 else
12191 return (string) (data - '0');
12194 static string GetDoubleHexValue(strptr data)
12196 return (string)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
12199 static uint32 GetLibData(struct FDData *fd)
12201 uint32 i;
12202 fd->Name = SkipBlanks(in.pos);
12203 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12204 in.pos = SkipBlanks(in.pos);
12205 fd->Bias = strtoul(in.pos, 0, 16);
12206 in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
12207 if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
12208 return ERR_TO_MUCH_ARGUMENTS;
12209 --in.pos; /* skips return register */
12210 for(i = 0; i < fd->NumArgs; ++i)
12212 if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
12213 return ERR_EXPECTED_REGISTER_NAME;
12215 return 0;
12218 static uint32 GetFlibData(struct FDData *fd)
12220 uint32 i;
12221 fd->Name = SkipBlanks(in.pos);
12222 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12223 in.pos = SkipBlanks(in.pos);
12224 fd->Bias = strtoul(in.pos, 0, 16);
12225 in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
12226 if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
12227 return ERR_TO_MUCH_ARGUMENTS;
12228 in.pos -= 2; /* skips return register */
12229 for(i = 0; i < fd->NumArgs; ++i)
12231 in.pos -= 2;
12232 if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
12233 return ERR_EXPECTED_REGISTER_NAME;
12234 else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
12235 return ERR_FLOATARG_NOT_ALLOWED;
12237 return 0;
12240 static uint32 GetAmiData(struct FDData *fd)
12242 strptr endptr;
12243 in.pos = SkipBlanks(in.pos);
12244 if(*in.pos != '('/*)*/)
12245 return ERR_EXPECTED_OPEN_BRACKET;
12246 fd->Basename = ++in.pos;
12247 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12248 if(*in.pos != ',')
12249 return ERR_EXPECTED_COMMA;
12250 *endptr = 0;
12251 in.pos = SkipBlanks(++in.pos);
12252 if(!strncmp(in.pos, "0x", 2))
12253 fd->Bias = strtoul(in.pos+2, 0, 16);
12254 else
12255 fd->Bias = strtoul(in.pos, 0, 10);
12257 in.pos = SkipBlanks(SkipName(in.pos));
12258 if(*in.pos != ',')
12259 return ERR_EXPECTED_COMMA;
12260 fd->Name = in.pos = SkipBlanks(++in.pos);
12261 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12262 if(*in.pos != '('/*)*/)
12263 return ERR_EXPECTED_OPEN_BRACKET;
12264 *endptr = 0;
12265 in.pos = SkipBlanks(++in.pos);
12266 if(*in.pos == /*(*/')')
12267 return 0;
12268 --in.pos;
12269 while(*in.pos != /*(*/')')
12271 uint32 i;
12272 in.pos = SkipBlanks(in.pos+1);
12274 for(i = 0; i < REG_FP0; i++)
12275 if(!strnicmp(RegNames[i], in.pos, 2))
12276 break;
12277 if(i == REG_FP0)
12279 for(; i < MAXREG; i++)
12280 if(!strnicmp(RegNames[i], in.pos, 3))
12281 break;
12284 if(i == MAXREG)
12285 return ERR_EXPECTED_REGISTER_NAME;
12286 else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
12287 return ERR_FLOATARG_NOT_ALLOWED;
12289 fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
12291 if(fd->NumArgs > MAXREG-2)
12292 return ERR_TO_MUCH_ARGUMENTS;
12294 in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
12296 if(*in.pos != ',' && *in.pos != /*(*/')')
12297 return ERR_EXPECTED_CLOSE_BRACKET;
12299 in.pos = SkipBlanks(in.pos+1);
12300 if(*in.pos != /*(*/')')
12301 return ERR_EXPECTED_CLOSE_BRACKET;
12302 return 0;
12305 static uint32 CreateFDFile(void)
12307 struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
12308 uint32 linenum, err = 0, skip;
12309 strptr ptr, p2;
12311 ptr = p2 = args.infile;
12312 while(*p2)
12314 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
12315 ptr = p2+1;
12316 ++p2;
12318 for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
12320 if(p2 != ptr)
12322 ShortBaseName = ptr;
12323 *p2 = '\0';
12326 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
12328 in.pos = SkipBlanks(in.pos);
12329 if(!strncmp("#pragma", in.pos, 7))
12331 struct FDData fd;
12333 skip = 0;
12334 memset(&fd, 0, sizeof(struct FDData));
12336 in.pos = SkipBlanks(in.pos+7);
12337 if(!strncmp("tagcall", in.pos, 7))
12339 fd.Mode = 1;
12340 in.pos = SkipBlanks(in.pos+7);
12341 if(*in.pos == '(' /*)*/) /* Storm method */
12342 err = GetAmiData(&fd);
12343 else /* SAS method */
12345 fd.Basename = in.pos;
12346 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12347 err = GetLibData(&fd);
12350 else if(!strncmp("amicall", in.pos, 7)) /* Storm method */
12352 in.pos += 7;
12353 err = GetAmiData(&fd);
12355 else if(!strncmp("libcall", in.pos, 7)) /* SAS method */
12357 fd.Basename = SkipBlanks(in.pos+7);
12358 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12359 err = GetLibData(&fd);
12361 else if(!strncmp("flibcall", in.pos, 8)) /* SAS method */
12363 fd.Basename = SkipBlanks(in.pos+8);
12364 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12365 err = GetFlibData(&fd);
12367 else if(!strncmp("syscall", in.pos, 7)) /* SAS method */
12369 fd.Basename = "SysBase";
12370 err = GetLibData(&fd);
12372 else
12373 skip = 1;
12375 if(err)
12376 DoError(err, linenum);
12377 else if(skip)
12379 else if((err = AddFDData(&pl, &fd)))
12381 if(err != 100)
12382 DoError(err, linenum);
12383 return 0;
12386 while(*(in.pos++)) /* jumps to first char of next line */
12390 if(pl.First)
12392 struct PragList *p = (struct PragList *) pl.First;
12393 if(!p->List.Next)
12395 strptr text, to;
12396 uint32 i;
12398 if(ShortBaseName)
12400 text = ShortBaseName; i = strlen(text);
12402 else
12404 text = p->Basename; i = strlen(text)-4;
12407 to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
12408 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12409 if(!OpenDest(to))
12410 return 0;
12412 err = MakeFD(p);
12413 CloseDest(to);
12414 if(!err)
12415 return 0;
12417 else
12419 while(p)
12421 strptr to;
12422 uint32 i;
12423 i = strlen(p->Basename) - 4;
12424 to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
12425 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12426 if(!OpenDest(to))
12427 return 0;
12428 i = MakeFD(p);
12429 CloseDest(to);
12430 if(!i)
12431 return 0;
12432 p = (struct PragList *) p->List.Next;
12437 return 1;
12440 #ifdef FD2PRAGMA_READARGS
12441 #include <proto/dos.h>
12443 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12444 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12445 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12446 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12447 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12448 "NEWSYNTAX/S," \
12449 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12450 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12451 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12452 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12453 "VOIDBASE/S"
12455 struct AmiArg
12457 strptr INFILE;
12458 uint32* SPECIAL;
12459 uint32* MODE;
12460 strptr TO;
12461 strptr ABI;
12462 strptr CLIB;
12463 strptr COPYRIGHT;
12464 strptr HEADER;
12465 strptr HUNKNAME;
12466 strptr BASENAME;
12467 strptr LIBTYPE;
12468 strptr LIBNAME;
12469 uint32* PRIORITY;
12470 strptr PREFIX;
12471 strptr SUBPREFIX;
12472 strptr PREMACRO;
12473 uint32 AUTOHEADER;
12474 uint32 COMMENT;
12475 uint32 EXTERNC;
12476 uint32 FPUONLY;
12477 uint32 NEWSYNTAX;
12478 uint32 NOFPU;
12479 uint32 NOPPC;
12480 uint32 NOPPCREGNAME;
12481 uint32 NOSYMBOL;
12482 uint32 ONLYCNAMES;
12483 uint32 OPT040;
12484 uint32 PPCONLY;
12485 uint32 PRIVATE;
12486 uint32 SECTION;
12487 uint32 SMALLCODE;
12488 uint32 SMALLDATA;
12489 uint32 SMALLTYPES;
12490 uint32 SORTED;
12491 uint32 SYSTEMRELEASE;
12492 uint32 USESYSCALL;
12493 uint32 VOIDBASE;
12496 static const strptr helptext =
12497 "INFILE: the input file which should be used\n"
12498 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12499 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12500 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12501 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12502 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12503 "\t 6 - pragma for all compilers [default]\n"
12504 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12505 "\t10 - stub-functions for C - C text\n"
12506 "\t11 - stub-functions for C - assembler text\n"
12507 "\t12 - stub-functions for C - link library\n"
12508 "\t13 - defines and link library for local library base (register call)\n"
12509 "\t14 - defines and link library for local library base (stack call)\n"
12510 "\t15 - stub-functions for Pascal - assembler text\n"
12511 "\t16 - stub-functions for Pascal - link library\n"
12512 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12513 "\t18 - module for AmigaE\n"
12514 "\t20 - assembler lvo _lvo.i file\n"
12515 "\t21 - assembler lvo _lib.i file\n"
12516 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12517 "\t23 - assembler lvo _lib.i file no XDEF\n"
12518 "\t24 - assembler lvo link library\n"
12519 "\t30 - proto file with pragma/..._lib.h call\n"
12520 "\t31 - proto file with pragma/..._pragmas.h call\n"
12521 "\t32 - proto file with pragmas/..._lib.h call\n"
12522 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12523 "\t34 - proto file with local/..._loc.h call\n"
12524 "\t35 - proto file for all compilers (VBCC stubs)\n"
12525 "\t36 - proto file for GNU-C compiler only\n"
12526 "\t37 - proto file without lib definitions\n"
12527 "\t38 - proto file for all compilers (VBCC inline)\n"
12528 "\t39 - proto file with special PPC related checks\n"
12529 "\t40 - GCC inline file (preprocessor based)\n"
12530 "\t41 - GCC inline file (old type - inline based)\n"
12531 "\t42 - GCC inline file (library stubs)\n"
12532 "\t43 - GCC inline file (new style - macro)\n"
12533 "\t44 - GCC inline file (new style - inline)\n"
12534 "\t45 - GCC inline file (new style - inline with include lines)\n"
12535 "\t46 - GCC inline file (preprocessor based, direct)\n"
12536 "\t47 - GCC inline file (new style, direct)\n"
12537 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12538 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12539 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12540 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12541 "\t53 - SAS-C include file for PowerUP\n"
12542 "\t54 - Proto file for PowerUP\n"
12543 "\t60 - FPC pascal unit text\n"
12544 "\t70 - VBCC inline files\n"
12545 "\t71 - VBCC WOS stub-functions - assembler text\n"
12546 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12547 "\t73 - VBCC WOS stub-functions - link library\n"
12548 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12549 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12550 "\t76 - VBCC PowerUP stub-functions - link library\n"
12551 "\t77 - VBCC WOS inline files\n"
12552 "\t78 - VBCC MorphOS stub-functions - link library\n"
12553 "\t79 - VBCC old inline files\n"
12554 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12555 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12556 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12557 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12558 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12559 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12560 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12561 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12562 " 100 - PPC assembler lvo file\n"
12563 " 101 - PPC assembler lvo file no XDEF\n"
12564 " 102 - PPC assembler lvo ELF link library\n"
12565 " 103 - PPC assembler lvo EHF link library\n"
12566 " 104 - PPC V.4-ABI assembler file\n"
12567 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12568 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12569 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12570 " 110 - FD file\n"
12571 " 111 - CLIB file\n"
12572 " 112 - SFD file\n"
12573 " 120 - VBCC auto libopen files (C source)\n"
12574 " 121 - VBCC auto libopen files (m68k link library)\n"
12575 " 122 - VBCC MorphOS inline files\n"
12576 " 123 - VBCC new MorphOS inline files\n"
12577 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12578 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12579 " 132 - GCC inline files for MorphOS (library stubs)\n"
12580 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12581 " 134 - MorphOS gate stubs\n"
12582 " 135 - MorphOS gate stubs (prelib)\n"
12583 " 136 - MorphOS gate stubs (postlib)\n"
12584 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12585 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12586 " 140 - OS4 XML file\n"
12587 " 141 - OS4 PPC->M68K cross-call stubs\n"
12588 " 142 - OS4 M68K->PPC cross-call stubs\n"
12589 " 200 - FD file (source is a pragma file!)\n"
12590 "MODE: SPECIAL 1-7:\n"
12591 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12592 " 2: _PRAGMAS_..._LIB_H definition method\n"
12593 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12594 " 4: no definition\n"
12595 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12596 " 130-138,141:\n"
12597 " 1: all functions, normal interface\n"
12598 " 2: only tag-functions, tagcall interface\n"
12599 " 3: all functions, normal and tagcall interface [default]\n"
12600 "TO: the destination directory (self creation of filename)\n"
12601 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12602 "CLIB: name of the prototypes file in clib directory\n"
12603 "COPYRIGHT: the copyright text for CLIB files\n"
12604 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12605 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12606 "BASENAME: name of library base without '_'\n"
12607 "LIBNAME: name of the library (.e.g. dos.library)\n"
12608 "LIBTYPE: type of base library structure\n"
12609 "PRIORITY: priority for auto open files\n"
12610 "PREFIX: MorphOS gate prefix\n"
12611 "SUBPREFIX: MorphOS gate sub prefix\n"
12612 "PREMACRO: MorphOS gate file start macro\n"
12613 "Switches:\n"
12614 "AUTOHEADER add the typical automatic generated header\n"
12615 "COMMENT: copy comments found in input file\n"
12616 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12617 "FPUONLY: work only with functions using FPU register arguments\n"
12618 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12619 "NOFPU: disable usage of FPU register arguments\n"
12620 "NOPPC: disable usage of PPC-ABI functions\n"
12621 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12622 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12623 "ONLYCNAMES: do not create C++ or ASM names\n"
12624 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12625 "PPCONLY: only use PPC-ABI functions\n"
12626 "PRIVATE: includes private declared functions\n"
12627 "SECTION: add section statements to asm texts\n"
12628 "SMALLCODE: generate small code link libraries or assembler text\n"
12629 "SMALLDATA: generate small data link libraries or assembler text\n"
12630 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12631 "SORTED: sort generated files by name and not by bias value\n"
12632 "SYSTEMRELEASE: special handling of comments for system includes\n"
12633 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12634 "VOIDBASE: library bases are of type void *\n";
12636 /* print the help text */
12637 static void printhelp(void)
12639 printf("%s\n%s\n\n%s", version+6, PARAM, helptext);
12640 exit(20);
12643 /* initializes the arguments and starts argument parsing */
12644 static void GetArgs(int argc, char **argv)
12646 struct RDArgs *rda;
12647 struct AmiArg amiargs;
12648 int res = 0;
12650 if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
12652 rda->RDA_ExtHelp = helptext;
12653 memset(&amiargs, 0, sizeof(struct AmiArg));
12654 if(ReadArgs(PARAM, (int32 *) &amiargs, rda))
12656 int l;
12657 strptr d, s;
12659 l = strlen(amiargs.TO ? amiargs.TO : "") + 1
12660 + strlen(amiargs.CLIB ? amiargs.CLIB : "") + 1
12661 + strlen(amiargs.HEADER ? amiargs.HEADER : "") + 1
12662 + strlen(amiargs.ABI ? amiargs.ABI : "") + 1
12663 + strlen(amiargs.HUNKNAME ? amiargs.HUNKNAME : "") + 1
12664 + strlen(amiargs.BASENAME ? amiargs.BASENAME : "") + 1
12665 + strlen(amiargs.LIBTYPE ? amiargs.LIBTYPE : "") + 1
12666 + strlen(amiargs.LIBNAME ? amiargs.LIBNAME : "") + 1
12667 + strlen(amiargs.COPYRIGHT ? amiargs.COPYRIGHT : "") + 1
12668 + strlen(amiargs.PREFIX ? amiargs.PREFIX : "") + 1
12669 + strlen(amiargs.SUBPREFIX ? amiargs.SUBPREFIX : "") + 1
12670 + strlen(amiargs.PREMACRO ? amiargs.PREMACRO : "") + 1
12671 + strlen(amiargs.INFILE) + 1;
12672 if((d = AllocListMem(l)))
12674 res = 1;
12676 s = amiargs.INFILE;
12677 args.infile = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12678 if((s = amiargs.TO))
12680 args.to = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12682 if((s = amiargs.HEADER))
12684 args.header = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12686 if((s = amiargs.CLIB))
12688 args.clib = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12690 if((s = amiargs.HUNKNAME))
12692 hunkname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12694 if((s = amiargs.BASENAME))
12696 Flags |= FLAG_BASENAME;
12697 BaseName = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12699 if((s = amiargs.LIBTYPE))
12701 Flags2 |= FLAG2_LIBTYPE;
12702 libtype = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12704 if((s = amiargs.LIBNAME))
12706 Flags2 |= FLAG2_LIBNAME;
12707 libname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12709 if((s = amiargs.PREFIX))
12711 prefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12713 if((s = amiargs.SUBPREFIX))
12715 subprefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12717 if((s = amiargs.PREMACRO))
12719 premacro = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12721 if((s = amiargs.COPYRIGHT))
12723 Copyright = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12725 if((s = amiargs.ABI))
12727 defabi = d; while(*s) *(d++) = *(s++); *d = 0;
12729 if(amiargs.EXTERNC) Flags ^= FLAG_EXTERNC;
12730 if(amiargs.PRIVATE) Flags ^= FLAG_PRIVATE;
12731 if(amiargs.NEWSYNTAX) Flags ^= FLAG_NEWSYNTAX;
12732 if(amiargs.SMALLDATA) Flags ^= FLAG_SMALLDATA;
12733 if(amiargs.SMALLCODE) Flags2 ^= FLAG2_SMALLCODE;
12734 if(amiargs.SMALLTYPES) Flags2 ^= FLAG2_SMALLTYPES;
12735 if(amiargs.USESYSCALL) Flags ^= FLAG_SYSCALL;
12736 if(amiargs.OPT040) Flags ^= FLAG_NOMOVEM;
12737 if(amiargs.NOFPU) Flags ^= FLAG_NOFPU;
12738 if(amiargs.FPUONLY) Flags ^= FLAG_FPUONLY;
12739 if(amiargs.NOPPC) Flags ^= FLAG_NOPPC;
12740 if(amiargs.NOSYMBOL) Flags ^= FLAG_NOSYMBOL;
12741 if(amiargs.PPCONLY) Flags ^= FLAG_PPCONLY;
12742 if(amiargs.SECTION) Flags ^= FLAG_ASMSECTION;
12743 if(amiargs.COMMENT) Flags ^= FLAG_DOCOMMENT;
12744 if(amiargs.SORTED) Flags ^= FLAG_SORTED;
12745 if(amiargs.ONLYCNAMES) Flags ^= FLAG_ONLYCNAMES;
12746 if(amiargs.SYSTEMRELEASE) Flags2 ^= FLAG2_SYSTEMRELEASE;
12747 if(amiargs.VOIDBASE) Flags2 ^= FLAG2_VOIDBASE;
12748 if(amiargs.NOPPCREGNAME) PPCRegPrefix = "";
12749 if(amiargs.AUTOHEADER) Flags2 ^= FLAG2_AUTOHEADER;
12750 if(amiargs.SPECIAL)
12751 args.special = *amiargs.SPECIAL;
12752 if(amiargs.MODE)
12753 args.mode = *amiargs.MODE;
12754 if(amiargs.PRIORITY)
12755 priority = *amiargs.PRIORITY;
12757 FreeArgs(rda);
12759 else
12760 PrintFault(IoErr(), 0);
12761 FreeDosObject(DOS_RDARGS, rda);
12764 if(!res)
12765 /* printhelp(); */
12766 exit(20);
12769 #else
12770 static const strptr helptext =
12771 " -h,--help\n"
12772 " -i,--infile <input filename>\n"
12773 " -s,--special <number>\n"
12774 " -m,--mode <number>\n"
12775 " -t,--to <destination directory>\n"
12776 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12777 " -c,--clib <clib prototypes filename>\n"
12778 " -d,--header <header file or \"\">\n"
12779 " -i,--libname <name of library>\n"
12780 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12781 " -b,--basename <name of library base without '_'>\n"
12782 " -l,--libtype <name of base library type>\n"
12783 " -p,--priority <priority for auto open files>\n"
12784 " -r,--copyright<copyright text>\n"
12785 " --prefix <MorphOS gate prefix>\n"
12786 " --subprefix<MorphOS gate sub prefix>\n"
12787 " --premacro <MorphOS gate file start macro>\n"
12788 "\n"
12789 "Switches:\n"
12790 "--autoheader add the typical automatic generated header\n"
12791 "--comment copy comments found in input file\n"
12792 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12793 "--fpuonly work only with functions using FPU register arguments\n"
12794 "--newsyntax uses new Motorola syntax for asm files\n"
12795 "--nofpu disable usage of FPU register arguments\n"
12796 "--noppc disable usage of PPC-ABI functions\n"
12797 "--noppcregname do not add 'r' to PPC register names\n"
12798 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12799 "--onlycnames do not create C++ or ASM names\n"
12800 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12801 "--ppconly only use PPC-ABI functions\n"
12802 "--private includes private declared functions\n"
12803 "--section add section statements to asm texts\n"
12804 "--smallcode generate small code link libraries or assembler text\n"
12805 "--smalldata generate small data link libraries or assembler text\n"
12806 "--smalltypes allow 8 and 16 bit types in registers\n"
12807 "--sorted sort generated files by name and not by bias value\n"
12808 "--systemrelease special handling of comments for system includes\n"
12809 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12810 "--voidbase library bases are of type void *\n"
12811 "\n"
12812 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12813 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12814 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12815 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12816 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12817 " 6 - pragma for all compilers [default]\n"
12818 " 7 - all compilers with pragma to inline redirect for GCC\n"
12819 " 10 - stub-functions for C - C text\n"
12820 " 11 - stub-functions for C - assembler text\n"
12821 " 12 - stub-functions for C - link library\n"
12822 " 13 - defines and link library for local library base (register call)\n"
12823 " 14 - defines and link library for local library base (stack call)\n"
12824 " 15 - stub-functions for Pascal - assembler text\n"
12825 " 16 - stub-functions for Pascal - link library\n"
12826 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12827 " 18 - module for AmigaE\n"
12828 " 20 - assembler lvo _lvo.i file\n"
12829 " 21 - assembler lvo _lib.i file\n"
12830 " 22 - assembler lvo _lvo.i file no XDEF\n"
12831 " 23 - assembler lvo _lib.i file no XDEF\n"
12832 " 24 - assembler lvo link library\n"
12833 " 30 - proto file with pragma/..._lib.h call\n"
12834 " 31 - proto file with pragma/..._pragmas.h call\n"
12835 " 32 - proto file with pragmas/..._lib.h call\n"
12836 " 33 - proto file with pragmas/..._pragmas.h call\n"
12837 " 34 - proto file with local/..._loc.h call\n"
12838 " 35 - proto file for all compilers (VBCC stubs)\n"
12839 " 36 - proto file for GNU-C compiler only\n"
12840 " 37 - proto file without lib definitions\n"
12841 " 38 - proto file for all compilers (VBCC inline)\n"
12842 " 39 - proto file with special PPC related checks\n"
12843 " 40 - GCC inline file (preprocessor based)\n"
12844 " 41 - GCC inline file (old type - inline based)\n"
12845 " 42 - GCC inline file (library stubs)\n"
12846 " 43 - GCC inline file (new style - macro)\n"
12847 " 44 - GCC inline file (new style - inline)\n"
12848 " 45 - GCC inline file (new style - inline with include lines)\n"
12849 " 46 - GCC inline file (preprocessor based, direct)\n"
12850 " 47 - GCC inline file (new style, direct)\n"
12851 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12852 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12853 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12854 " 52 - GCC inline files for PowerUP (library stubs)\n"
12855 " 53 - SAS-C include file for PowerUP\n"
12856 " 54 - Proto file for PowerUP\n"
12857 " 60 - FPC pascal unit text\n"
12858 " 70 - VBCC inline files\n"
12859 " 71 - VBCC WOS stub-functions - assembler text\n"
12860 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12861 " 73 - VBCC WOS stub-functions - link library\n"
12862 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12863 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12864 " 76 - VBCC PowerUP stub-functions - link library\n"
12865 " 77 - VBCC WOS inline files\n"
12866 " 78 - VBCC MorphOS stub-functions - link library\n"
12867 " 79 - VBCC old inline files\n"
12868 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12869 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12870 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12871 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12872 " 90 - stub-functions for C - assembler text (multiple files)\n"
12873 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12874 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12875 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12876 " 100 - PPC assembler lvo file\n"
12877 " 101 - PPC assembler lvo file no XDEF\n"
12878 " 102 - PPC assembler lvo ELF link library\n"
12879 " 103 - PPC assembler lvo EHF link library\n"
12880 " 104 - PPC V.4-ABI assembler file\n"
12881 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12882 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12883 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12884 " 110 - FD file\n"
12885 " 111 - CLIB file\n"
12886 " 112 - SFD file\n"
12887 " 120 - VBCC auto libopen files (C source)\n"
12888 " 121 - VBCC auto libopen files (m68k link library)\n"
12889 " 122 - VBCC MorphOS inline files\n"
12890 " 123 - VBCC new MorphOS inline files\n"
12891 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12892 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12893 " 132 - GCC inline files for MorphOS (library stubs)\n"
12894 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12895 " 134 - MorphOS gate stubs\n"
12896 " 135 - MorphOS gate stubs (prelib)\n"
12897 " 136 - MorphOS gate stubs (postlib)\n"
12898 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12899 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12900 " 140 - OS4 XML file\n"
12901 " 141 - OS4 PPC->M68K cross-call stubs\n"
12902 " 142 - OS4 M68K->PPC cross-call stubs\n"
12903 " 200 - FD file (source is a pragma file!)\n"
12904 "mode: special 1-7\n"
12905 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12906 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12907 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12908 " 4 - no definition\n"
12909 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12910 " 130-138,141:\n"
12911 " 1 - all functions, normal interface\n"
12912 " 2 - only tag-functions, tagcall interface\n"
12913 " 3 - all functions, normal and tagcall interface [default]\n";
12915 /* print the help text */
12916 static void printhelp(void)
12918 printf("%s\n%s", version+6, helptext);
12919 exit(20);
12922 struct ArgData
12924 strptr ArgName;
12925 uint8 ArgChar;
12926 uint8 ArgNameLen;
12927 uint8 ArgNum;
12930 enum ArgNums {
12931 ARG_HELP, ARG_INFILE, ARG_SPECIAL, ARG_MODE, ARG_TO, ARG_CLIB, ARG_ABI, ARG_COPYRIGHT,
12932 ARG_HEADER, ARG_HUNKNAME, ARG_BASENAME, ARG_LIBTYPE,
12933 ARG_COMMENT, ARG_EXTERNC, ARG_FPUONLY, ARG_NEWSYNTAX, ARG_NOFPU, ARG_NOPPC,
12934 ARG_NOSYMBOL, ARG_ONLYCNAMES, ARG_OPT040, ARG_PPCONLY, ARG_PRIVATE, ARG_SECTION,
12935 ARG_SMALLDATA, ARG_SORTED, ARG_USESYSCALL, ARG_NOPPCREGNAME,
12936 ARG_SYSTEMRELEASE, ARG_PRIORITY, ARG_LIBNAME, ARG_SMALLCODE, ARG_VOIDBASE,
12937 ARG_PREFIX, ARG_SUBPREFIX, ARG_PREMACRO, ARG_SMALLTYPES, ARG_AUTOHEADER
12940 /* argument definition array */
12941 static const struct ArgData argtexts[] = {
12942 {"help", 'h', 4, ARG_HELP},
12943 {"infile", 'i', 6, ARG_INFILE},
12944 {"special", 's', 7, ARG_SPECIAL},
12945 {"mode", 'm', 4, ARG_MODE},
12946 {"to", 't', 2, ARG_TO},
12947 {"clib", 'c', 4, ARG_CLIB},
12948 {"abi", 'a', 3, ARG_ABI},
12949 {"copyright", 'r', 9, ARG_COPYRIGHT},
12950 {"header", 'd', 6, ARG_HEADER},
12951 {"hunkname", 'n', 8, ARG_HUNKNAME},
12952 {"basename", 'b', 8, ARG_BASENAME},
12953 {"libtype", 'l', 7, ARG_LIBTYPE},
12954 {"libname", 'i', 7, ARG_LIBNAME},
12955 {"priority", 'p', 8, ARG_PRIORITY},
12956 {"autoheader", 0, 10, ARG_AUTOHEADER},
12957 {"comment", 0, 7, ARG_COMMENT},
12958 {"externc", 0, 7, ARG_EXTERNC},
12959 {"fpuonly", 0, 7, ARG_FPUONLY},
12960 {"newsyntax", 0, 9, ARG_NEWSYNTAX},
12961 {"nofpu", 0, 5, ARG_NOFPU},
12962 {"noppc", 0, 5, ARG_NOPPC},
12963 {"noppcregname", 0, 12, ARG_NOPPCREGNAME},
12964 {"nosymbol", 0, 8, ARG_NOSYMBOL},
12965 {"onlycnames", 0, 10, ARG_ONLYCNAMES},
12966 {"opt040", 0, 6, ARG_OPT040},
12967 {"ppconly", 0, 7, ARG_PPCONLY},
12968 {"private", 0, 7, ARG_PRIVATE},
12969 {"section", 0, 7, ARG_SECTION},
12970 {"smalldata", 0, 9, ARG_SMALLDATA},
12971 {"smalltypes", 0, 10, ARG_SMALLTYPES},
12972 {"smallcode", 0, 9, ARG_SMALLCODE},
12973 {"sorted", 0, 6, ARG_SORTED},
12974 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE},
12975 {"usesyscall", 0, 10, ARG_USESYSCALL},
12976 {"voidbase", 0, 8, ARG_VOIDBASE},
12977 {"prefix", 0, 6, ARG_PREFIX},
12978 {"subprefix", 0, 9, ARG_SUBPREFIX},
12979 {"premacro", 0, 8, ARG_PREMACRO},
12980 {0,0,0,0}, /* end marker */
12983 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
12984 static uint32 ParseArgEntry(uint32 argc, strptr *argv)
12986 uint32 numentries = 1, l;
12987 strptr a, b;
12988 const struct ArgData *ad;
12990 if((*argv)[0] != '-' || !(*argv)[1])
12991 return 0;
12993 ad = argtexts;
12994 while(ad->ArgName)
12996 if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
12997 break;
12998 ++ad;
13000 if(!ad->ArgName)
13001 return 0;
13002 switch(ad->ArgNum)
13004 case ARG_HELP: printhelp(); break;
13005 case ARG_EXTERNC: Flags ^= FLAG_EXTERNC; break;
13006 case ARG_PRIVATE: Flags ^= FLAG_PRIVATE; break;
13007 case ARG_NEWSYNTAX: Flags ^= FLAG_NEWSYNTAX; break;
13008 case ARG_SMALLDATA: Flags ^= FLAG_SMALLDATA; break;
13009 case ARG_SMALLCODE: Flags2 ^= FLAG2_SMALLCODE; break;
13010 case ARG_SMALLTYPES: Flags2 ^= FLAG2_SMALLTYPES; break;
13011 case ARG_USESYSCALL: Flags ^= FLAG_SYSCALL; break;
13012 case ARG_OPT040: Flags ^= FLAG_NOMOVEM; break;
13013 case ARG_NOFPU: Flags ^= FLAG_NOFPU; break;
13014 case ARG_FPUONLY: Flags ^= FLAG_FPUONLY; break;
13015 case ARG_NOPPC: Flags ^= FLAG_NOPPC; break;
13016 case ARG_NOSYMBOL: Flags ^= FLAG_NOSYMBOL; break;
13017 case ARG_PPCONLY: Flags ^= FLAG_PPCONLY; break;
13018 case ARG_SECTION: Flags ^= FLAG_ASMSECTION; break;
13019 case ARG_COMMENT: Flags ^= FLAG_DOCOMMENT; break;
13020 case ARG_SORTED: Flags ^= FLAG_SORTED; break;
13021 case ARG_ONLYCNAMES: Flags ^= FLAG_ONLYCNAMES; break;
13022 case ARG_SYSTEMRELEASE: Flags2 ^= FLAG2_SYSTEMRELEASE; break;
13023 case ARG_VOIDBASE: Flags2 ^= FLAG2_VOIDBASE; break;
13024 case ARG_AUTOHEADER: Flags2 ^= FLAG2_AUTOHEADER; break;
13025 case ARG_NOPPCREGNAME: PPCRegPrefix = "";
13026 default:
13027 a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
13028 if(!(*a))
13030 if(argc > 1) { a = argv[1]; numentries = 2; }
13031 else { a = 0; numentries = 0;}
13033 else if(*a == '=')
13034 ++a;
13035 if(a)
13037 if(*a == '\"')
13039 l = strlen(++a);
13040 if(a[l-1] == '\"')
13041 a[--l] = 0; /* remove second " */
13043 switch(ad->ArgNum)
13045 case ARG_INFILE: args.infile = a; break;
13046 case ARG_COPYRIGHT: Copyright = a; break;
13047 case ARG_TO: args.to = a; break;
13048 case ARG_ABI: defabi = a; break;
13049 case ARG_CLIB: args.clib = a; break;
13050 case ARG_HEADER: args.header = a; break;
13051 case ARG_HUNKNAME: hunkname = a; break;
13052 case ARG_PREFIX: prefix = a; break;
13053 case ARG_SUBPREFIX: subprefix = a; break;
13054 case ARG_PREMACRO: premacro = a; break;
13055 case ARG_LIBTYPE: libtype = a; Flags2 |= FLAG2_LIBTYPE; break;
13056 case ARG_LIBNAME: libname = a; Flags2 |= FLAG2_LIBNAME; break;
13057 case ARG_BASENAME: BaseName = a; Flags |= FLAG_BASENAME; break;
13058 case ARG_SPECIAL:
13059 args.special = strtoul(a, &b, 10);
13060 if(*b)
13061 numentries = 0;
13062 break;
13063 case ARG_PRIORITY:
13064 priority = strtoul(a, &b, 10);
13065 if(*b)
13066 numentries = 0;
13067 break;
13068 case ARG_MODE:
13069 args.mode = strtoul(a, &b, 10);
13070 if(*b || args.mode < 1 || args.mode > 3)
13071 numentries = 0;
13072 break;
13076 return numentries;
13079 /* initializes the arguments and starts argument parsing */
13080 static void GetArgs(int argc, char **argv)
13082 int res = 1;
13083 int i = 1, j;
13085 while(i < argc && res)
13087 if((j = ParseArgEntry(argc-i, argv+i)) < 1)
13088 res = 0;
13089 else
13090 i += j;
13092 if(!res || !args.infile)
13093 printhelp();
13096 #endif
13098 static strptr mygetfile(strptr name, size_t *len)
13100 strptr ptr = 0;
13101 FILE *infile;
13103 if((infile = fopen(name, "rb")))
13105 if(!fseek(infile, 0, SEEK_END))
13107 *len = ftell(infile);
13108 if(!fseek(infile, 0, SEEK_SET))
13110 if((ptr = AllocListMem(*len+1)))
13112 ptr[*len] = 0;
13113 #ifdef DEBUG_OLD
13114 printf("mygetfile: '%s' size %d\n", name, *len);
13115 #endif
13116 if(fread(ptr, *len, 1, infile) != 1)
13117 ptr = 0;
13121 fclose(infile);
13123 return ptr;
13126 int main(int argc, char **argv)
13128 uint32 mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_BOTH;
13129 strptr amicall = 0, libcall = 0, amitags = 0, libtags = 0;
13130 strptr clibbuf;
13131 size_t clibsize = 0;
13133 GetArgs(argc, argv);
13135 if((tempbuf = (uint8 *) AllocListMem(TEMPSIZE)))
13137 if(!(in.pos = in.buf = mygetfile(args.infile, &in.size)))
13139 if(args.special == 200)
13141 DoError(ERR_OPEN_FILE, 0, args.infile);
13142 exit(20);
13144 else
13146 sprintf((strptr)tempbuf, "%s" SFDFILEEXTENSION, args.infile);
13147 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13149 sprintf((strptr)tempbuf, "%s" FDFILEEXTENSION, args.infile);
13150 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13152 DoError(ERR_OPEN_FILE, 0, args.infile);
13153 exit(20);
13155 else
13156 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13158 else
13159 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13162 printf("SourceFile: %s\n", args.infile);
13164 MakeLines(in.pos, in.size);
13166 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SORTED)) /* is not possible to use both */
13168 DoError(ERR_SORTED_COMMENT, 0);
13169 Flags &= (~FLAG_SORTED);
13172 if(args.special == 200)
13174 CreateFDFile();
13175 exit(0);
13178 if(!GetTypes())
13179 exit(20);
13181 if(!ScanFDFile())
13182 exit(20);
13184 if(args.clib)
13186 if(Flags2 & FLAG2_SFDMODE)
13187 DoError(ERR_SFD_AND_CLIB, 0);
13188 else
13190 sprintf((strptr)tempbuf, "%s_protos.h", args.clib);
13191 if(!(clibbuf = mygetfile(args.clib, &clibsize)) && !(clibbuf = mygetfile((strptr)tempbuf, &clibsize)))
13193 DoError(ERR_OPEN_FILE, 0, args.clib);
13194 exit(20);
13196 ScanClibFile(clibbuf, clibbuf+clibsize);
13200 if(!MakeShortBaseName())
13202 DoError(ERR_MISSING_SHORTBASENAME, 0);
13203 exit(20);
13206 /* WARN when requesting obsolete types! */
13207 switch(args.special)
13209 case 1: case 2: case 3: case 4: case 5: case 7:
13210 printf("You use obsolete data type %ld, better use type 6!\n", args.special);
13211 break;
13212 case 11: case 15: case 71: case 72: case 75:
13213 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13214 "link libraries!\n", args.special);
13215 break;
13216 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13217 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args.special);
13218 break;
13219 case 79:
13220 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13221 break;
13224 if(args.special < 10) /* the pragma area is up to 9 */
13226 mode = MODUS_PRAGMA;
13227 sprintf(filename, "%s_lib.h", ShortBaseName);
13229 switch(args.special)
13231 case 0: break;
13232 case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
13233 case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13234 pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
13235 case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13236 pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
13237 libtags = "def " TEXT_SAS_60; break;
13238 case 4: amicall = ""; break;
13239 case 5: amicall = amitags = ""; break;
13240 case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
13241 case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
13242 TEXT_MAXON ") || defined(" TEXT_STORM ")";
13243 libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
13244 libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
13245 default: mode = MODUS_ERROR; break;
13248 if(args.mode > 0 && args.mode < 5)
13249 pragmode = args.mode;
13251 else if(args.special < 20) /* the misc area is up to 19 */
13253 if(args.mode > 0 && args.mode < 4)
13254 callmode = args.mode - 1;
13255 switch(args.special)
13257 case 10: mode = MODUS_CSTUB;
13258 sprintf(filename, "%s_cstub.h", ShortBaseName); break;
13259 case 11: mode = MODUS_STUBTEXT;
13260 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13261 case 12: mode = MODUS_STUBCODE;
13262 sprintf(filename, "%s.lib", ShortBaseName); break;
13263 case 13: Flags |= FLAG_LOCALREG; /* no break ! */
13264 case 14: mode = MODUS_LOCALDATA;
13265 sprintf(filename, "%s_loc.h", ShortBaseName); break;
13266 case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
13267 Flags ^= FLAG_PASCAL;
13268 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13269 case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
13270 Flags ^= FLAG_PASCAL;
13271 sprintf(filename, "%s.lib", ShortBaseName); break;
13272 case 17: mode = MODUS_BMAP; callmode = TAGMODE_NORMAL;
13273 sprintf(filename, "%s.bmap", ShortBaseName); break;
13274 case 18: mode = MODUS_EMODULE;
13275 sprintf(filename, "%s.m", ShortBaseName); break;
13276 default: mode = MODUS_ERROR; break;
13279 else if(args.special < 30) /* the lvo area is up to 29 */
13281 switch(args.special)
13283 case 20: case 22: mode = MODUS_LVO+args.special-20;
13284 sprintf(filename, "%s_lvo.i", ShortBaseName); break;
13285 case 21: case 23: mode = MODUS_LVO+args.special-20;
13286 sprintf(filename, "%s_lib.i", ShortBaseName); break;
13287 case 24: mode = MODUS_LVOLIB;
13288 sprintf(filename, "%slvo.o", ShortBaseName); break;
13289 default: mode = MODUS_ERROR; break;
13292 else if(args.special < 40) /* the proto area is up to 39 */
13294 if(args.special < 40)
13296 mode = MODUS_PROTO+args.special-30;
13297 sprintf(filename, "%s.h", ShortBaseName);
13299 else
13300 mode = MODUS_ERROR;
13302 else if(args.special < 50) /* the inline area is up to 49 */
13304 if(args.mode > 0 && args.mode < 4)
13305 callmode = args.mode - 1;
13307 switch(args.special)
13309 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13310 case 47:
13311 mode = MODUS_INLINE+args.special-40;
13312 sprintf(filename, "%s.h", ShortBaseName); break;
13313 case 48:
13314 Flags |= FLAG_STORMGCC;
13315 /* the same mode as for 46, but additional flag */
13316 mode = MODUS_INLINE+args.special-40-2;
13317 sprintf(filename, "%s.h", ShortBaseName); break;
13318 default: mode = MODUS_ERROR; break;
13321 else if(args.special < 60) /* the PowerUP area is up to 59 */
13323 if(args.mode > 0 && args.mode < 4)
13324 callmode = args.mode - 1;
13326 switch(args.special)
13328 case 50: case 51: case 52: mode = MODUS_INLINE+args.special-50;
13329 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_POWERUP;
13330 break;
13331 case 53:
13332 sprintf(filename, "%s_pragmas.h", ShortBaseName);
13333 mode = MODUS_SASPOWER; break;
13334 case 54:
13335 sprintf(filename, "%s.h", ShortBaseName);
13336 mode = MODUS_PROTOPOWER; break;
13337 default: mode = MODUS_ERROR; break;
13340 else if(args.special < 70) /* the PASCAL stuff */
13342 if(args.special == 60)
13344 mode = MODUS_PASCAL;
13345 sprintf(filename, "%s.pas", ShortBaseName);
13347 else
13348 mode = MODUS_ERROR;
13350 else if(args.special < 80) /* the VBCC stuff */
13352 if(args.mode > 0 && args.mode < 4)
13353 callmode = args.mode - 1;
13355 switch(args.special)
13357 case 70: mode = MODUS_VBCCINLINE;
13358 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13359 case 71: case 72: case 75:
13360 mode = MODUS_VBCC+args.special-71;
13361 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13362 case 73: case 74:
13363 mode = MODUS_VBCC+args.special-71;
13364 sprintf(filename, "%s.lib", ShortBaseName); break;
13365 case 76:
13366 mode = MODUS_VBCCPUPLIB;
13367 sprintf(filename, "lib%s.a", ShortBaseName); break;
13368 case 77: mode = MODUS_VBCCWOSINLINE;
13369 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13370 case 78: mode = MODUS_VBCCMORPHCODE;
13371 sprintf(filename, "lib%s.a", ShortBaseName); break;
13372 case 79: mode = MODUS_VBCCINLINE;
13373 Flags2 |= FLAG2_OLDVBCC;
13374 callmode = TAGMODE_NORMAL;
13375 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13376 default: mode = MODUS_ERROR; break;
13379 else if(args.special < 90) /* redirect stuff */
13381 mode = MODUS_REDIRECT;
13382 switch(args.special)
13384 case 80: sprintf(filename, "%s_pragmas.h", ShortBaseName); break;
13385 case 81: sprintf(filename, "%s_lib.h", ShortBaseName); break;
13386 case 82: sprintf(filename, "%s.h", ShortBaseName); break;
13387 case 83: sprintf(filename, "%s_protos.h", ShortBaseName); break;
13388 default: mode = MODUS_ERROR; break;
13391 else if(args.special < 100) /* multifile stuff */
13393 Flags |= FLAG_SINGLEFILE;
13394 switch(args.special)
13396 case 90:
13397 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13398 mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
13399 break;
13400 case 91:
13401 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13402 mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
13403 break;
13404 case 92:
13405 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13406 mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
13407 break;
13408 case 93:
13409 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13410 mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
13411 break;
13412 default: mode = MODUS_ERROR; break;
13415 else if(args.special < 110) /* PPC lvo's */
13417 switch(args.special)
13419 case 100: case 101: mode = MODUS_LVOPPC+args.special-100;
13420 sprintf(filename, "%s_lib.i", ShortBaseName);
13421 break;
13422 case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
13423 Flags |= FLAG_ABIV4;
13424 sprintf(filename, "%s_lib.i", ShortBaseName);
13425 break;
13426 case 103: mode = MODUS_LVOLIB;
13427 sprintf(filename, "%slvo.o", ShortBaseName);
13428 break;
13429 case 107: mode = MODUS_LVOLIB;
13430 Flags |= FLAG_ABIV4;
13431 sprintf(filename, "%slvo.o", ShortBaseName);
13432 break;
13433 case 102: mode = MODUS_LVOLIBPPC;
13434 sprintf(filename, "%slvo.o", ShortBaseName); break;
13435 case 106: mode = MODUS_LVOLIBPPC;
13436 Flags |= FLAG_ABIV4;
13437 sprintf(filename, "%slvo.o", ShortBaseName); break;
13438 default: mode = MODUS_ERROR; break;
13441 else if(args.special < 120) /* different files */
13443 if(args.mode > 0 && args.mode < 4)
13444 callmode = args.mode - 1;
13446 switch(args.special)
13448 case 110: mode = MODUS_FD;
13449 sprintf(filename, "%s_lib.fd", ShortBaseName);
13450 if(Flags & FLAG_SORTED) /* is not possible to use here */
13452 DoError(ERR_SORTED_SFD_FD, 0);
13453 Flags &= (~FLAG_SORTED);
13455 break;
13456 case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
13457 sprintf(filename, "%s_protos.h", ShortBaseName);
13458 break;
13459 case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
13460 sprintf(filename, "%s_lib.sfd", ShortBaseName);
13461 if(callmode == 1)
13463 callmode = 2;
13464 DoError(ERR_ONLYTAGMODE_NOTALLOWED, 0);
13467 if(Flags & FLAG_SORTED) /* is not possible to use here */
13469 DoError(ERR_SORTED_SFD_FD, 0);
13470 Flags &= (~FLAG_SORTED);
13472 break;
13473 default: mode = MODUS_ERROR; break;
13476 else if(args.special < 130) /* auto libopen files */
13478 if(args.mode > 0 && args.mode < 4) /* for 122 */
13479 callmode = args.mode - 1;
13481 switch(args.special)
13483 case 120: mode = MODUS_GENAUTO;
13484 sprintf(filename, "%s_autoopenlib.c", ShortBaseName);
13485 break;
13486 case 121: mode = MODUS_GENAUTO+(args.special-120);
13487 sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
13488 break;
13489 case 123: Flags2 |= FLAG2_SHORTPPCVBCCINLINE; /* no break */
13490 case 122: mode = MODUS_VBCCMORPHINLINE;
13491 PPCRegPrefix = ""; /* no "r" allowed */
13492 sprintf(filename, "%s_protos.h", ShortBaseName);
13493 break;
13494 default: mode = MODUS_ERROR; break;
13497 else if(args.special < 140) /* the MorphOS area is up to 139 */
13499 if(args.mode > 0 && args.mode < 4)
13500 callmode = args.mode - 1;
13502 switch(args.special)
13504 case 130: case 131: case 132: mode = MODUS_INLINE+args.special-130;
13505 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13506 break;
13507 case 133: mode = MODUS_INLINE+2;
13508 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13509 Flags2 |= FLAG2_DIRECTVARARGS;
13510 break;
13511 case 134: mode = MODUS_GATESTUBS;
13512 sprintf(filename, "%s_gates.h", ShortBaseName);
13513 break;
13514 case 135: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB;
13515 sprintf(filename, "%s_gates.h", ShortBaseName);
13516 break;
13517 case 136: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB;
13518 sprintf(filename, "%s_gates.h", ShortBaseName);
13519 break;
13520 case 137: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB|FLAG2_REGLIB;
13521 sprintf(filename, "%s_gates.h", ShortBaseName);
13522 break;
13523 case 138: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB|FLAG2_REGLIB;
13524 sprintf(filename, "%s_gates.h", ShortBaseName);
13525 break;
13526 default: mode = MODUS_ERROR; break;
13529 else if(args.special < 150) /* the OS4 area is up to 139 */
13531 if(args.mode > 0 && args.mode < 4)
13532 callmode = args.mode - 1;
13534 switch(args.special)
13536 case 140:
13537 mode = MODUS_XML;
13538 sprintf(filename, "%s.xml", ShortBaseName);
13539 break;
13540 case 141: /* OS4 PPC->M68K cross-call stubs */
13541 mode = MODUS_OS4_PPCSTUBS;
13542 sprintf(filename, "%s.c", ShortBaseName);
13543 break;
13544 case 142: /* OS4 M68K->PPC cross-call stubs */
13545 mode = MODUS_OS4_68KSTUBS;
13546 sprintf(filename, "%s_68k.s", ShortBaseName);
13547 break;
13548 default: mode = MODUS_ERROR; break;
13551 if(Flags & FLAG_SORTED)
13552 SortFDList();
13554 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SINGLEFILE)) /* is not possible to use both */
13556 DoError(ERR_COMMENT_SINGLEFILE, 0);
13557 Flags &= (~FLAG_DOCOMMENT);
13560 if(!mode || mode == MODUS_ERROR)
13561 printhelp();
13563 /* These modes need BaseName always. */
13564 if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
13565 mode == MODUS_STUBCODE || mode == MODUS_EMODULE || (mode >= MODUS_GENAUTO &&
13566 mode <= MODUS_GENAUTO+9)))
13568 DoError(ERR_MISSING_BASENAME, 0);
13569 exit(20);
13572 if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
13574 HEADER = mygetfile(args.header, &headersize);
13575 args.header = 0;
13578 if(!(Flags & FLAG_SINGLEFILE))
13580 if(!OpenDest(filename))
13581 exit(20);
13584 /* from here mode is used as return result */
13585 if(mode >= MODUS_GENAUTO)
13586 mode = CreateGenAuto(filename, mode-MODUS_GENAUTO);
13587 else if(mode >= MODUS_LVOPPC)
13588 mode = CreateLVOFilePPC(mode-MODUS_LVOPPC);
13589 else if(mode >= MODUS_VBCC)
13590 mode = CreateVBCC(mode-MODUS_VBCC, callmode);
13591 else if(mode >= MODUS_INLINE)
13592 mode = CreateInline(mode-MODUS_INLINE, callmode);
13593 else if(mode >= MODUS_PROTO)
13594 mode = CreateProtoFile(mode-MODUS_PROTO+1);
13595 else if(mode >= MODUS_LVO)
13596 mode = CreateLVOFile(mode-MODUS_LVO+1);
13597 else if(mode == MODUS_VBCCMORPHINLINE)
13598 mode = CreateVBCCInline(2, callmode);
13599 else if(mode == MODUS_XML)
13600 mode = CreateXML();
13601 else if(mode == MODUS_OS4_PPCSTUBS)
13602 mode = CreateOS4PPC(callmode);
13603 else if(mode == MODUS_OS4_68KSTUBS)
13604 mode = CreateOS4M68K();
13605 else if(mode == MODUS_GATESTUBS)
13606 mode = CreateGateStubs(callmode);
13607 else if(mode == MODUS_SFD)
13608 mode = CreateSFD(callmode);
13609 else if(mode == MODUS_CLIB)
13610 mode = CreateClib(callmode);
13611 else if(mode == MODUS_FD)
13612 mode = CreateFD();
13613 else if(mode == MODUS_LVOLIBPPC)
13614 mode = CreateLVOLibPPC();
13615 else if(mode == MODUS_VBCCMORPHCODE)
13616 mode = CreateVBCCMorphCode(callmode);
13617 else if(mode == MODUS_VBCCMORPHTEXTSF) /* single files */
13618 mode = CallFunc(callmode, "\n%s", FuncVBCCMorphText);
13619 else if(mode == MODUS_VBCCWOSINLINE)
13620 mode = CreateVBCCInline(1, callmode);
13621 else if(mode == MODUS_VBCCWOSTEXTSF) /* single files */
13622 mode = CallFunc(callmode, "\n%s", FuncVBCCWOSText);
13623 else if(mode == MODUS_VBCCPUPTEXTSF) /* single files */
13624 mode = CallFunc(callmode, "\n%s", FuncVBCCPUPText);
13625 else if(mode == MODUS_ASMTEXTSF) /* single files */
13626 mode = CallFunc(callmode, "\n%s", FuncAsmText);
13627 else if(mode == MODUS_REDIRECT)
13628 mode = CreateProtoRedirect();
13629 else if(mode == MODUS_EMODULE)
13630 mode = CreateEModule(Flags & FLAG_SORTED);
13631 else if(mode == MODUS_LVOLIB)
13632 mode = CreateLVOLib();
13633 else if(mode == MODUS_VBCCPUPLIB)
13634 mode = CreateVBCCPUPLib(callmode);
13635 else if(mode == MODUS_VBCCINLINE)
13636 mode = CreateVBCCInline(0, callmode);
13637 else if(mode == MODUS_PASCAL)
13638 mode = CreateFPCUnit();
13639 else if(mode == MODUS_BMAP)
13640 mode = CreateBMAP();
13641 else if(mode == MODUS_PROTOPOWER)
13642 mode = CreateProtoPowerUP();
13643 else if(mode == MODUS_SASPOWER)
13644 mode = CreateSASPowerUP(callmode);
13645 else if(mode == MODUS_CSTUB)
13646 mode = CreateCSTUBSFile();
13647 else if(mode == MODUS_PRAGMA)
13648 mode = CreatePragmaFile(amicall, libcall, amitags, libtags, pragmode);
13649 else if(mode == MODUS_LOCALDATA)
13650 mode = CreateLocalData(filename, callmode);
13651 else if(mode) /* MODUS_STUBTEXT starts with 1 */
13652 mode = CreateAsmStubs(mode, callmode);
13654 CloseDest(filename);
13656 if(!mode)
13658 DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
13659 exit(20);
13661 free(tempbuf);
13664 return 0;