Synchronized with documentations/db/credits.
[AROS.git] / tools / fd2pragma / fd2pragma.c
blob94a7d18013f0949eb32685171eeea0c23f6fc716
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 if (line)
4202 printf("%s %ld in line %ld%s: ",
4203 (Errors[err].Type ? "Warning" : "Error"),
4204 err, line,
4205 errnum & ERROFFSET_CLIB ? " of clib file" : "");
4207 else
4209 printf("%s %ld : ", (Errors[err].Type ? "Warning" : "Error"), err);
4211 vprintf(Errors[err].Error, a);
4212 printf("\n");
4213 if(line && Errors[err].Skip)
4215 while(*in.pos)
4216 ++in.pos;
4218 va_end(a);
4221 static uint32 CheckError(struct AmiPragma *ap, uint32 errflags)
4223 errflags &= ap->Flags;
4225 if(errflags & AMIPRAGFLAG_ARGCOUNT)
4227 if(!(ap->Flags & AMIPRAGFLAG_DIDARGWARN))
4229 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
4230 ap->Flags |= AMIPRAGFLAG_DIDARGWARN;
4232 return 1;
4234 else if(errflags & AMIPRAGFLAG_FLOATARG)
4236 if(!(ap->Flags & AMIPRAGFLAG_DIDFLOATWARN))
4238 DoError(ERR_FLOATARG_NOT_ALLOWED, ap->Line);
4239 ap->Flags |= AMIPRAGFLAG_DIDFLOATWARN;
4241 return 1;
4243 else if(errflags & AMIPRAGFLAG_A6USE)
4245 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
4246 return 1;
4248 else if(errflags & AMIPRAGFLAG_A5USE)
4250 DoError(ERR_A5_NOT_ALLOWED, ap->Line);
4251 return 1;
4253 else if(errflags & AMIPRAGFLAG_PPC)
4255 if(!(Flags & FLAG_DIDPPCWARN))
4257 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
4258 Flags |= FLAG_DIDPPCWARN;
4260 return 1;
4262 else if(errflags & AMIPRAGFLAG_M68K)
4264 if(!(Flags & FLAG_DIDM68KWARN))
4266 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
4267 Flags |= FLAG_DIDM68KWARN;
4269 return 1;
4271 else if(errflags & AMIPRAGFLAG_MOSBASESYSV)
4273 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED, ap->Line);
4274 return 1;
4277 return 0;
4280 static uint32 DoOutput(strptr format, ...)
4282 va_list a;
4284 if(!Output_Error)
4285 return 0;
4287 va_start(a, format);
4288 if(vfprintf(outfile, format, a) < 0)
4289 Output_Error = 1;
4290 va_end(a);
4292 return Output_Error;
4295 static uint32 DoOutputDirect(void * data, size_t size)
4297 if(!Output_Error)
4298 return 0;
4299 if(size)
4301 if(fwrite(data, size, 1, outfile) != 1)
4302 Output_Error = 0;
4304 return Output_Error;
4307 /* ------------------------------------------------------------------ */
4309 static struct ShortList *NewItem(struct ShortListRoot *list)
4311 struct ShortList *item;
4312 if(!list || !list->Size)
4313 return 0;
4314 if(!(item = (struct ShortList *) AllocListMem(list->Size)))
4315 return 0;
4316 return item;
4319 static struct ShortList *RemoveItem(struct ShortListRoot *list,
4320 struct ShortList *item)
4322 struct ShortList *n = list->First;
4324 if(n == item)
4325 list->First = item->Next;
4326 else
4328 while(n && n->Next != item)
4329 n = n->Next;
4330 if(!n)
4331 return 0;
4332 if(!(n->Next = item->Next))
4333 list->Last = n;
4335 item->Next = 0;
4336 return item;
4339 static void AddItem(struct ShortListRoot *list, struct ShortList *item)
4341 if(!list->First)
4342 list->First = list->Last = item;
4343 else
4345 list->Last->Next = item;
4346 list->Last = item;
4350 /* ------------------------------------------------------------------ */
4352 uint32 FuncAMICALL(struct AmiPragma *ap, uint32 flags, strptr name)
4354 uint32 i;
4356 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4357 return 1;
4359 Flags |= FLAG_DONE; /* We did something */
4361 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags & FUNCFLAG_TAG ?
4362 "tagcall" : "amicall", BaseName, ap->Bias, name);
4364 for(i = 0; i < ap->NumArgs; ++i)
4366 DoOutput("%s",RegNames[ap->Args[i].ArgReg]);
4367 if(i+1 < ap->NumArgs)
4368 DoOutput(",");
4371 return DoOutput(/*((*/"))\n");
4374 uint32 FuncLIBCALL(struct AmiPragma *ap, uint32 flags, strptr name)
4376 int32 i;
4378 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4379 return 1;
4381 Flags |= FLAG_DONE; /* We did something */
4383 if(ap->Flags & AMIPRAGFLAG_FLOATARG)
4385 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName, name, ap->Bias);
4386 for(i = ap->NumArgs-1; i >= 0; --i)
4387 DoOutput("%02x", ap->Args[i].ArgReg);
4389 return DoOutput("00%02x\n", ap->NumArgs);
4392 if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase") &&
4393 (flags & FUNCFLAG_NORMAL))
4394 DoOutput("#pragma syscall %-22s %03x ", name, ap->Bias);
4395 else
4396 DoOutput("#pragma %s %s %-22s %03x ", (flags & FUNCFLAG_TAG) ?
4397 "tagcall" : "libcall", BaseName, name, ap->Bias);
4399 for(i = ap->NumArgs-1; i >= 0; --i)
4400 DoOutput("%x", ap->Args[i].ArgReg);
4402 return DoOutput("0%x\n", ap->NumArgs);
4405 uint32 FuncAsmText(struct AmiPragma *ap, uint32 flags, strptr name)
4407 int32 i;
4408 uint32 registers;
4409 uint16 fregs;
4410 uint32 offset = 1;
4411 strptr c1, c2;
4412 struct ClibData *cd;
4414 if(CheckError(ap, AMIPRAGFLAG_PPC))
4415 return 1;
4417 Flags |= FLAG_DONE; /* We did something */
4419 c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
4420 c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
4422 if(Flags & FLAG_SINGLEFILE)
4424 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
4426 if(HEADER)
4428 DoOutput("\n");
4429 DoOutputDirect(HEADER, headersize);
4433 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
4435 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
4436 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
4439 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name, name);
4440 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4442 DoOutput("\tXDEF\t%s\n%s:\n",name, name);
4443 if(clibdata)
4445 if(!ap->NumArgs)
4446 DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
4447 else if((cd = GetClibFunc(name, ap, flags)))
4449 string txt[300];
4450 uint32 i;
4452 for(i = 0; i < COPYCPP_PASSES; ++i)
4454 if(CopyCPPType(txt, i, cd, ap->Args))
4455 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name, txt, name, txt);
4461 if((registers = GetRegisterData(ap) >> 16))
4463 if(Flags & FLAG_NOMOVEM)
4465 for(i = 0; i <= 15; ++i)
4467 if(registers & (1 << i))
4469 ++offset;
4470 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper[i]);
4474 else
4476 uint16 l = registers;
4478 DoOutput("\tMOVEM.L\t");
4480 for(i = 0; i <= 15; ++i)
4482 if(l & (1 << i))
4484 ++offset;
4485 l ^= 1 << i;
4486 DoOutput("%s",RegNamesUpper[i]);
4487 if(l)
4488 DoOutput("/");
4491 DoOutput(",-(A7)\n");
4494 else
4496 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
4499 if((fregs = GetFRegisterData(ap) >> 8))
4501 uint8 l = fregs;
4503 DoOutput("\tFMOVEM.X\t");
4505 for(i = 0; i <= 7; ++i)
4507 if(l & (1 << i))
4509 offset += 3;
4510 l ^= 1 << i;
4511 DoOutput("%s",RegNamesUpper[REG_FP0 + i]);
4512 if(l)
4513 DoOutput("/");
4516 DoOutput(",-(A7)\n");
4519 if(Flags & FLAG_SMALLDATA)
4521 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1, BaseName, c2);
4523 else
4524 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName);
4526 if(!(Flags & FLAG_PASCAL))
4528 int32 k;
4530 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
4532 for(i = 0; i < k;)
4534 if(ap->Args[i].ArgReg >= REG_FP0)
4536 uint32 t;
4537 struct ClibData *cd;
4539 cd = GetClibFunc(name, ap, flags);
4540 if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
4541 t = CPP_TYPE_DOUBLE;
4542 else if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
4543 t = CPP_TYPE_FLOAT;
4544 else
4546 DoError(ERR_LONG_DOUBLE, ap->Line);
4547 t = CPP_TYPE_FLOAT;
4550 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE
4551 ? 'D' : 'S', c1, offset<<2, c2, RegNamesUpper[ap->Args[i++].ArgReg]);
4553 if(t == CPP_TYPE_DOUBLE)
4554 ++offset;
4555 ++offset;
4557 else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg) &&
4558 ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4560 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
4561 RegNamesUpper[ap->Args[i++].ArgReg]);
4565 DoOutput("/%s", RegNamesUpper[ap->Args[i++].ArgReg]);
4566 ++offset;
4567 } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg) &&
4568 ap->Args[i].ArgReg < REG_FP0);
4569 DoOutput("\n");
4571 else
4573 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4574 ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
4575 RegNamesUpper[ap->Args[i].ArgReg]);
4576 ++i;
4580 if(i < ap->NumArgs)
4582 if(ap->Args[i].ArgReg > 7)
4583 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1, offset<<2, c2,
4584 RegNamesUpper[ap->Args[i].ArgReg]);
4585 else if(offset <= 2)
4586 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4587 RegNamesUpper[ap->Args[i].ArgReg],offset<<2,
4588 RegNamesUpper[ap->Args[i].ArgReg]);
4589 else
4590 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1,
4591 offset<<2, c2,RegNamesUpper[ap->Args[i].ArgReg]);
4594 else
4596 i = ap->NumArgs;
4598 while(i)
4600 if(ap->Args[i-1].ArgReg >= REG_FP0)
4602 uint32 t;
4603 struct ClibData *cd;
4605 cd = GetClibFunc(name, ap, flags);
4607 if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_DOUBLE))
4608 t = CPP_TYPE_DOUBLE;
4609 else if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_FLOAT))
4610 t = CPP_TYPE_FLOAT;
4611 else
4613 DoError(ERR_LONG_DOUBLE, ap->Line);
4614 t = CPP_TYPE_FLOAT;
4617 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ?
4618 'D' : 'S', c1, offset<<2, c2, RegNamesUpper[ap->Args[--i].ArgReg]);
4619 if(t == CPP_TYPE_DOUBLE)
4620 ++offset;
4621 ++offset;
4623 else if((i >= 2) && (ap->Args[i-1].ArgReg < ap->Args[i-2].ArgReg) &&
4624 ap->Args[i-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4626 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
4627 RegNamesUpper[ap->Args[--i].ArgReg]);
4631 DoOutput("/%s", RegNamesUpper[ap->Args[--i].ArgReg]);
4632 ++offset;
4633 } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg) &&
4634 ap->Args[i-1].ArgReg < REG_FP0);
4635 DoOutput("\n");
4637 else
4639 --i;
4640 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4641 ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
4642 RegNamesUpper[ap->Args[i].ArgReg]);
4647 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1, ap->Bias, c2);
4649 if(fregs)
4651 DoOutput("\tFMOVEM.X\t(A7)+,");
4653 for(i = 0; i <= 7; ++i)
4655 if(fregs & (1 << i))
4657 fregs ^= 1 << i;
4658 DoOutput("%s",RegNamesUpper[REG_FP0 + i]);
4659 if(fregs)
4660 DoOutput("/");
4663 DoOutput("\n");
4666 if(registers)
4668 if(Flags & FLAG_NOMOVEM)
4670 for(i = 15; i >= 0; --i)
4672 if(registers & (1 << i))
4673 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i >= REG_A0 ? "A" : "",
4674 RegNamesUpper[i]);
4677 else
4679 DoOutput("\tMOVEM.L\t(A7)+,");
4681 for(i = 0; i <= 15; ++i)
4683 if(registers & (1 << i))
4685 registers ^= 1 << i;
4686 DoOutput("%s",RegNamesUpper[i]);
4687 if(registers)
4688 DoOutput("/");
4691 DoOutput("\n");
4694 else
4695 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4697 return DoOutput("\tRTS\n");
4700 uint32 FuncAsmCode(struct AmiPragma *ap, uint32 flags, strptr name)
4702 uint32 registers, offset = 1, baseref;
4703 size_t i;
4704 uint8 *data;
4705 uint16 fregs;
4707 if(CheckError(ap, AMIPRAGFLAG_PPC))
4708 return 1;
4710 Flags |= FLAG_DONE; /* We did something */
4712 registers = GetRegisterData(ap);
4713 fregs = GetFRegisterData(ap);
4715 i = strlen(name) + 2;
4716 EndPutM32(tempbuf, HUNK_UNIT);
4717 EndPutM32(tempbuf+4, (i+3)>>2);
4718 DoOutputDirect(tempbuf, 8);
4719 DoOutput("%s.o", name);
4720 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
4722 i = strlen(hunkname);
4723 EndPutM32(tempbuf, HUNK_NAME);
4724 EndPutM32(tempbuf+4, (i + 3)>>2);
4725 DoOutputDirect(tempbuf, 8);
4726 DoOutputDirect(hunkname, i);
4727 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
4729 data = tempbuf+8; /* we need HUNK_CODE + size at start */
4731 if(!registers)
4733 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
4734 ++offset; /* one long more on stack */
4736 else
4738 if(Flags & FLAG_NOMOVEM)
4740 for(i = 0; i <= 15; ++i)
4742 if(registers & (1<< (16+i)))
4744 EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
4745 ++offset;
4749 else
4751 uint32 l;
4752 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
4753 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
4754 for(l = (uint16) registers; l; l >>= 1)
4756 if(l & 1)
4757 ++offset; /* get offset addition */
4762 if(fregs)
4764 uint32 l;
4765 EndPutM16Inc(data, 0xF227); /* FMOVEM.X xxx,-(A7) */
4766 EndPutM16Inc(data, 0xE000 + ((fregs>>8)&0xFF));
4767 for(l = (uint8) fregs; l; l >>= 1)
4769 if(l & 1)
4770 offset+=3; /* get offset addition */
4774 baseref = (data-tempbuf)-8+2; /* one word later (MOVE) - 2 header longs */
4775 if(Flags & FLAG_SMALLDATA)
4777 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
4778 EndPutM16Inc(data, 0); /* place for base reference */
4780 else
4782 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
4783 EndPutM32Inc(data, 0); /* place for base reference */
4786 data = AsmStackCopy(data, ap, flags, offset);
4788 /* here comes the base reference */
4789 EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
4790 EndPutM16Inc(data, -ap->Bias); /* JSR offset */
4792 if(fregs)
4794 EndPutM16Inc(data, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4795 EndPutM16Inc(data, 0xD000 + (fregs&0xFF));
4798 if(registers)
4800 if(Flags & FLAG_NOMOVEM)
4802 int32 i;
4803 for(i = 15; i >= 0; --i)
4805 if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
4806 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
4809 else
4811 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4812 EndPutM16Inc(data, (registers >> 16)); /* store MOVEM.L registers */
4815 else
4816 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
4817 EndPutM16Inc(data, 0x4E75); /* RTS */
4819 EndPutM16Inc(data, 0); /* get longword assignment if not yet */
4821 EndPutM32(tempbuf, HUNK_CODE);
4822 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
4823 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
4825 EndPutM32(tempbuf, HUNK_EXT);
4826 DoOutputDirect(tempbuf, 4);
4828 OutputXREF(baseref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32),
4829 "_%s", BaseName);
4830 /* here come the XDEF name references */
4831 OutputXDEF(0, "_%s", name); /* C name */
4833 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4835 struct ClibData *cd;
4836 OutputXDEF(0, "%s", name); /* ASM name */
4838 if(clibdata)
4840 if(!ap->NumArgs)
4841 OutputXDEF(0, "%s_", name); /* C++ name no parameters */
4842 else if((cd = GetClibFunc(name, ap, flags)))
4844 for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
4846 if(CopyCPPType((strptr)tempbuf, i, cd, ap->Args))
4847 OutputXDEF(0, "%s__%s", name, tempbuf);
4853 EndPutM32(tempbuf, 0);
4854 DoOutputDirect(tempbuf, 4);
4855 if(!(Flags & FLAG_NOSYMBOL))
4857 EndPutM32(tempbuf, HUNK_SYMBOL);
4858 DoOutputDirect(tempbuf, 4);
4859 OutputSYMBOL(0, "_%s", name); /* C name */
4861 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4863 struct ClibData *cd;
4864 OutputSYMBOL(0, "%s", name); /* ASM name */
4866 if(clibdata)
4868 if(!ap->NumArgs)
4869 OutputSYMBOL(0, "%s_", name); /* C++ name no parameters */
4870 else if((cd = GetClibFunc(name, ap, flags)))
4872 for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
4874 if(CopyCPPType((strptr) data, i, cd, ap->Args))
4875 OutputSYMBOL(0, "%s__%s", name, (strptr) data);
4881 EndPutM32(tempbuf, 0);
4882 DoOutputDirect(tempbuf, 4);
4885 EndPutM32(tempbuf, HUNK_END);
4886 return DoOutputDirect(tempbuf, 4);
4889 /* Directly called by FuncInline and FuncInlineDirect also! */
4890 uint32 FuncCSTUBS(struct AmiPragma *ap, uint32 flags, strptr name)
4892 struct ClibData *f, *t;
4893 strptr ret = "return ";
4894 int32 i;
4896 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4897 return 1;
4899 Flags |= FLAG_DONE; /* We did something */
4901 if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
4902 return 1;
4903 t = GetClibFunc(name, ap, flags);
4905 if(flags & FUNCFLAG_EXTENDMODE)
4907 sprintf(tempbuf, "___%s", name);
4908 name = tempbuf;
4911 if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
4912 ret = "";
4914 if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
4915 return 0;
4916 if(flags & FUNCFLAG_EXTENDMODE)
4918 DoOutput("%s %s, ", GetBaseType(), BaseName);
4921 for(i = 0; i < ap->NumArgs-1; i++)
4923 if(!OutClibType(&f->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4924 return 0;
4926 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4928 if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4929 return 0;
4931 else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
4932 return 0;
4934 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret, ap->FuncName))
4935 return 0;
4936 for(i = 0; i < ap->NumArgs-1; i++)
4938 if(!DoOutput("%s, ", ap->Args[i].ArgName))
4939 return 0;
4941 if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
4942 return 0;
4944 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4946 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
4947 return 0;
4949 else if(ap->NumArgs == 1)
4951 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4952 return 0;
4954 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4955 ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(&f->Args[ap->NumArgs-2],0)
4956 || !DoOutput(/*(((*/")));\n}\n\n"))
4957 return 0;
4958 return 1;
4961 uint32 FuncLVOXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
4963 Flags |= FLAG_DONE; /* We did something */
4964 return DoOutput("\t\tXDEF\t_LVO%s\n", name);
4967 uint32 FuncLVO(struct AmiPragma *ap, uint32 flags, strptr name)
4969 Flags |= FLAG_DONE; /* We did something */
4970 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name, ap->Bias);
4973 uint32 FuncLVOPPCXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
4975 Flags |= FLAG_DONE; /* We did something */
4976 return DoOutput("\t.globl\t%sLVO%s\n", Flags & FLAG_ABIV4 ? "" : "_", name);
4979 uint32 FuncLVOPPC(struct AmiPragma *ap, uint32 flags, strptr name)
4981 Flags |= FLAG_DONE; /* We did something */
4982 return DoOutput(".set\t%sLVO%s,-%d\n", Flags & FLAG_ABIV4 ? "" : "_", name,
4983 ap->Bias);
4986 uint32 FuncLVOPPCBias(struct AmiPragma *ap, uint32 flags, strptr name)
4988 Flags |= FLAG_DONE; /* We did something */
4990 EndPutM32Inc(elfbufpos, symoffset); /* st_name */
4991 symoffset += strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1) + 1;
4992 EndPutM32Inc(elfbufpos, -ap->Bias); /* st_value */
4993 EndPutM32Inc(elfbufpos, 0); /* st_size */
4994 *(elfbufpos++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* st_info */
4995 *(elfbufpos++) = 0; /* st_other */
4996 EndPutM16Inc(elfbufpos, SHN_ABS); /* st_shndx */
4998 return 1;
5001 uint32 FuncLVOPPCName(struct AmiPragma *ap, uint32 flags, strptr name)
5003 Flags |= FLAG_DONE; /* We did something */
5004 DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
5005 return DoOutputDirect("", 1);
5008 uint32 FuncLVOLib(struct AmiPragma *ap, uint32 flags, strptr name)
5010 uint32 j;
5012 Flags |= FLAG_DONE; /* We did something */
5013 j = strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1);
5014 EndPutM32(tempbuf, (EXT_ABS << 24) + ((j+3)>>2));
5016 DoOutputDirect(tempbuf, 4);
5017 DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
5018 DoOutputDirect("\0\0\0", ((j+3)&(~3))-j);
5019 EndPutM32(tempbuf, -ap->Bias);
5020 return DoOutputDirect(tempbuf, 4);
5023 uint32 FuncLocCode(struct AmiPragma *ap, uint32 flags, strptr name)
5025 strptr str2 = Flags & FLAG_LOCALREG ? "rE" : "";
5026 uint8 *data;
5027 int32 i;
5028 struct ClibData *cd = 0;
5030 if(CheckError(ap, AMIPRAGFLAG_PPC))
5031 return 1;
5033 Flags |= FLAG_DONE; /* We did something */
5035 i = strlen(name) + 2;
5036 EndPutM32(tempbuf, HUNK_UNIT);
5037 EndPutM32(tempbuf+4, (i+3)>>2);
5038 DoOutputDirect(tempbuf, 8);
5039 DoOutput("%s.o", name);
5040 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
5042 i = strlen(hunkname);
5043 EndPutM32(tempbuf, HUNK_NAME);
5044 EndPutM32(tempbuf+4, (i + 3)>>2);
5045 DoOutputDirect(tempbuf, 8);
5046 DoOutputDirect(hunkname, i);
5047 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
5049 data = tempbuf+8; /* we need HUNK_CODE + size at start */
5051 if(Flags & FLAG_LOCALREG)
5053 if((flags & FUNCFLAG_TAG))
5055 i = ap->Args[ap->NumArgs-1].ArgReg;
5056 EndPutM16Inc(data, 0x2F00 + i); /* MOVE <ea>,-(A7) */
5058 if(i > 7)
5060 EndPutM16Inc(data, 0x41EF | ((i-8) << 9)); /* LEA 8(A7),Ax */
5061 EndPutM16Inc(data, 8);
5063 else
5065 EndPutM16Inc(data, 0x200F | (i << 9)); /* MOVE.L A7,Dx */
5066 EndPutM16Inc(data, 0x5080 | i); /* ADDQ.L #8,Dx */
5069 EndPutM16Inc(data, 0x4EAE);
5070 EndPutM16Inc(data, -ap->Bias); /* JSR instruction */
5072 /* MOVE (A7)+,<ea> */
5073 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
5074 EndPutM16Inc(data, 0x4E75); /* RTS */
5076 else
5078 EndPutM16Inc(data, 0x4EEE);
5079 EndPutM16Inc(data, -ap->Bias); /* JMP instruction */
5082 else
5084 uint32 registers, offset = 1;
5086 registers = GetRegisterData(ap);
5088 if(!registers) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5090 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
5091 ++offset; /* one long more on stack */
5093 else
5095 if(Flags & FLAG_NOMOVEM)
5097 for(i = 0; i <= 15; ++i)
5099 if(registers & (1<< (16+i)))
5101 EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
5102 ++offset;
5106 else
5108 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
5109 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
5110 for(i = registers&0xFFFF; i; i >>= 1)
5112 if(i & 1)
5113 ++offset; /* get offset addition */
5118 if(!(ap->Flags & AMIPRAGFLAG_A6USE)) /* store library base in A6 */
5120 EndPutM16Inc(data, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5121 EndPutM16Inc(data, (offset++) << 2);
5124 data = AsmStackCopy(data, ap, flags, offset);
5126 /* here comes the base reference */
5127 EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
5128 EndPutM16Inc(data, -ap->Bias); /* JSR offset */
5129 if(registers)
5131 if(Flags & FLAG_NOMOVEM)
5133 for(i = 15; i >= 0; --i)
5135 if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
5136 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
5139 else
5141 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5142 EndPutM16Inc(data, registers >> 16); /* store MOVEM.L registers */
5145 else
5146 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
5148 EndPutM16Inc(data, 0x4E75); /* RTS */
5151 EndPutM16Inc(data, 0); /* get longword assignment if not yet */
5153 EndPutM32(tempbuf, HUNK_CODE);
5154 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
5155 DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
5157 EndPutM32(tempbuf, HUNK_EXT);
5158 DoOutputDirect(tempbuf,4);
5160 /* here come the XDEF name references */
5162 if(!(Flags & FLAG_ONLYCNAMES))
5164 OutputXDEF(0, "%s", name); /* ASM names */
5165 OutputXDEF(0, "LOC_%s", name);
5168 OutputXDEF(0, "_%s", name); /* C names */
5169 OutputXDEF(0, "_LOC_%s", name);
5171 if(clibdata && !(Flags & FLAG_ONLYCNAMES))
5173 if(!ap->NumArgs)
5175 /* C++ names no parameters */
5176 OutputXDEF(0, "%s__%sP07Library", name, str2);
5177 OutputXDEF(0, "LOC_%s__%sP07Library", name, str2);
5179 else if((cd = GetClibFunc(name, ap, flags)))
5181 strptr txt;
5183 txt = (strptr) tempbuf;
5185 for(i = 0; i < COPYCPP_PASSES; ++i)
5187 if(CopyCPPType(txt, i, cd, ap->Args))
5188 { /* C++ names with parameters */
5189 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5191 OutputXDEF(0, "%s__%sP07Library%s", name, str2, txt);
5192 OutputXDEF(0, "LOC_%s__%sP07Library%s", name, str2, txt);
5194 else
5196 OutputXDEF(0, "%s__%s", name, txt);
5197 OutputXDEF(0, "LOC_%s__%s", name, txt);
5204 EndPutM32(tempbuf, 0);
5205 DoOutputDirect(tempbuf,4);
5206 if(!(Flags & FLAG_NOSYMBOL))
5208 EndPutM32(tempbuf, HUNK_SYMBOL);
5209 DoOutputDirect(tempbuf,4);
5210 if(!(Flags & FLAG_ONLYCNAMES))
5212 OutputSYMBOL(0, "%s", name); /* ASM names */
5213 OutputSYMBOL(0, "LOC_%s", name);
5216 OutputSYMBOL(0, "_%s", name); /* C names */
5217 OutputSYMBOL(0, "_LOC_%s", name);
5219 if(clibdata && !(Flags & FLAG_ONLYCNAMES))
5221 if(!ap->NumArgs)
5223 /* C++ names no parameters */
5224 OutputSYMBOL(0, "%s__%sP07Library", name, str2);
5225 OutputSYMBOL(0, "LOC_%s__%sP07Library", name, str2);
5227 else if(cd)
5229 strptr txt;
5231 txt = (strptr) tempbuf;
5233 for(i = 0; i < COPYCPP_PASSES; ++i)
5235 if(CopyCPPType(txt, i, cd, ap->Args))
5236 { /* C++ names with parameters */
5237 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5239 OutputSYMBOL(0, "%s__%sP07Library%s", name, str2, txt);
5240 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name, str2, txt);
5242 else
5244 OutputSYMBOL(0, "%s__%s", name, txt);
5245 OutputSYMBOL(0, "LOC_%s__%s", name, txt);
5252 EndPutM32(tempbuf, 0);
5253 DoOutputDirect(tempbuf,4);
5255 EndPutM32(tempbuf, HUNK_END);
5256 return DoOutputDirect(tempbuf,4);
5259 uint32 FuncLocText(struct AmiPragma *ap, uint32 flags, strptr name)
5261 struct ClibData *cd;
5262 int32 i;
5264 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5265 return 1;
5267 Flags |= FLAG_DONE; /* We did something */
5269 if(!(cd = GetClibFunc(name, ap, flags)))
5270 return 1;
5272 OutClibType(&cd->ReturnType, 0);
5273 DoOutput(" LOC_%s("/*)*/, name);
5274 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5276 if(Flags & FLAG_LOCALREG)
5277 DoOutput("register __a6 ");
5278 DoOutput("%s libbase", GetBaseType());
5279 if(ap->NumArgs)
5280 DoOutput(", ");
5283 if(ap->NumArgs)
5285 for(i = 0; i < ap->NumArgs-1; i++)
5287 if(((Flags & FLAG_LOCALREG &&
5288 !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
5289 !OutClibType(&cd->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
5290 return 0;
5293 if(flags & FUNCFLAG_NORMAL)
5295 if(((Flags & FLAG_LOCALREG &&
5296 !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
5297 !OutClibType(&cd->Args[i], ap->Args[i].ArgName) ||
5298 !DoOutput(/*(*/");\n"))
5299 return 0;
5300 if(BaseName)
5302 DoOutput("#define %s("/*)*/, name);
5303 for(i = 0; i < ap->NumArgs-1; ++i)
5304 DoOutput("%c, ", 'a'+(char)i);
5305 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i, name, BaseName);
5306 for(i = 0; i < ap->NumArgs-1; ++i)
5307 DoOutput("%c, ",'a'+(char)i);
5308 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i);
5311 else
5312 return DoOutput(/*(*/"...);\n");
5314 else if(BaseName)
5315 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5316 name, name);
5317 else
5318 return DoOutput(/*(*/");\n");
5319 return 1;
5322 uint32 FuncInlineDirect(struct AmiPragma *ap, uint32 flags, strptr name)
5324 uint32 a4 = 0, a5 = 0;
5325 int32 noret = 0;
5326 int32 i, maxargs, reg=0;
5327 struct ClibData *cd;
5329 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC|AMIPRAGFLAG_VARARGS))
5330 return 1;
5332 Flags |= FLAG_DONE; /* We did something */
5334 if(flags & FUNCFLAG_ALIAS)
5336 if(flags & FUNCFLAG_TAG)
5337 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5338 name, ap->TagName);
5340 DoOutput("#define %s("/*)*/, name);
5341 for(i = 0; i < ap->NumArgs-1; ++i)
5342 DoOutput("%s, ", ap->Args[i].ArgName);
5343 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
5344 for(i = 0; i < ap->NumArgs-1; ++i)
5345 DoOutput("(%s), ", ap->Args[i].ArgName);
5346 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
5349 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5350 return 1;
5352 if(flags & FUNCFLAG_TAG)
5354 /* do not create some strange functions */
5355 if(IsNoCreateInlineFunc(name))
5356 DoOutput("#if !defined(NO_INLINE_STDARG) "
5357 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5358 else
5359 DoOutput("#ifndef NO_INLINE_STDARG\n");
5360 DoOutput("static __inline__ ");
5361 FuncCSTUBS(ap, flags|FUNCFLAG_EXTENDMODE, name);
5363 DoOutput("#define %s("/*)*/, name);
5364 for(i = 0; i < ap->NumArgs-1; ++i)
5366 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->NumArgs-2 ? ", " : "");
5368 if(ap->NumArgs < 2)
5369 DoOutput("tags");
5370 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name, ShortBaseNameUpper);
5371 for(i = 0; i < ap->NumArgs-1; ++i)
5372 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->NumArgs-2 ? ", " : "");
5373 if(ap->NumArgs < 2)
5374 DoOutput("tags");
5375 DoOutput(/*(*/")\n");
5376 return DoOutput("#endif\n\n");
5379 DoOutput("#define %s("/*)*/, name);
5380 if(ap->NumArgs)
5382 for(i = 0; i < ap->NumArgs-1; ++i)
5383 DoOutput("%s, ", ap->Args[i].ArgName);
5384 DoOutput("%s", ap->Args[i].ArgName);
5386 DoOutput(/*(*/") ({ \\\n"/*})*/);
5388 for(i = 0; i < ap->NumArgs; ++i)
5390 sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
5391 DoOutput(" ");
5392 OutClibType(&cd->Args[i], (strptr) tempbuf);
5393 DoOutput(" = (%s); \\\n", ap->Args[i].ArgName);
5396 if(Flags & FLAG_INLINENEW)
5398 if(ap->NumArgs)
5399 DoOutput(" ({ \\\n"/*})*/);
5400 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name);
5401 if(BaseName)
5402 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper);
5403 else
5405 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
5407 if(i == ap->NumArgs)
5408 return 1;
5409 DoOutput("(%s);\\\n", ap->Args[i].ArgName);
5412 DoOutput(" (("/*))*/);
5413 OutClibType(&cd->ReturnType, 0);
5414 DoOutput(" (*)("/*)*/);
5415 if(BaseName)
5417 DoOutput("char * __asm(\"a6\")");
5418 if(ap->NumArgs)
5419 DoOutput(", ");
5421 for(i = 0; i < ap->NumArgs; ++i)
5423 OutClibType(&cd->Args[i], 0);
5424 DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
5425 if(i < ap->NumArgs-1)
5426 DoOutput(", ");
5428 DoOutput(/*((*/")) \\\n");
5429 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name, ap->Bias);
5430 if(BaseName)
5432 DoOutput("_%s__bn", name);
5433 if(ap->NumArgs)
5434 DoOutput(", ");
5436 for(i = 0; i < ap->NumArgs; ++i)
5438 if(ap->Args[i].ArgReg == REG_A6)
5439 DoOutput("_%s__bn", name);
5440 else
5441 DoOutput("_%s_%s", name, ap->Args[i].ArgName);
5442 if(i < ap->NumArgs-1)
5443 DoOutput(", ");
5445 DoOutput(/*(*/"); \\\n");
5446 if(ap->NumArgs)
5447 DoOutput(/*({*/"});");
5449 else
5451 /* do A5 first, as it is more important */
5452 if(ap->Flags & AMIPRAGFLAG_A5USE)
5454 a5 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5455 for(i = 0; i < ap->NumArgs; ++i)
5456 a5 |= 1<<ap->Args[i].ArgReg;
5457 a5 &= 0xFFF;
5458 if(a5 == 0xFFF)
5460 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A5]);
5461 a5 = 0;
5463 else
5465 for(i = 0; (a5 & 1) && a5; ++i)
5466 a5 >>= 1;
5467 a5 = i; /* this is our A5 swap register */
5470 if(ap->Flags & AMIPRAGFLAG_A4USE)
5472 a4 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5473 if(a5)
5474 a4 |= (1<<a5);
5475 for(i = 0; i < ap->NumArgs; ++i)
5476 a4 |= 1<<ap->Args[i].ArgReg;
5477 a4 &= 0xFFF;
5478 if(a4 == 0xFFF)
5480 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A4]);
5481 a4 = 0;
5483 else
5485 for(i = 0; (a4 & 1) && a4; ++i)
5486 a4 >>= 1;
5487 a4 = i; /* this is our A4 swap register */
5490 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5491 noret = 1; /* this is a void function */
5493 if(ap->NumArgs || !noret)
5494 DoOutput(" %s{ \\\n", noret ? "" : "(" /*})*/);
5496 if(noret)
5497 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5498 DoOutput(
5499 " register int _d1 __asm(\"d1\"); \\\n"
5500 " register int _a0 __asm(\"a0\"); \\\n"
5501 " register int _a1 __asm(\"a1\"); \\\n");
5503 if(BaseName)
5504 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5505 GetBaseType(), name, ShortBaseNameUpper);
5507 if(!noret)
5509 sprintf((strptr)tempbuf, "__%s__re", name);
5510 DoOutput(" register ");
5511 OutClibType(&cd->ReturnType, (strptr) tempbuf);
5512 DoOutput(" __asm(\"d0\"); \\\n");
5514 if((maxargs = ap->NumArgs) >= 9 && (Flags & FLAG_STORMGCC))
5515 maxargs = 7;
5516 for(i = 0; i < maxargs; ++i)
5518 reg = ap->Args[i].ArgReg;
5519 if(a5 && reg == REG_A5) reg = a5; /* we need to switch */
5520 if(a4 && reg == REG_A4) reg = a4; /* we need to switch */
5522 sprintf((strptr)tempbuf, "__%s_%s", name, ap->Args[i].ArgName);
5523 DoOutput(" register ");
5524 OutClibType(&cd->Args[i], (strptr) tempbuf);
5525 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames[reg],
5526 (strptr) (tempbuf+1));
5528 if(i != ap->NumArgs) /* StormGCC mode */
5530 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name);
5531 for(i = maxargs; i < ap->NumArgs; ++i)
5533 DoOutput(" ULONG __%s_%s; \\\n", name, ap->Args[i].ArgName);
5534 reg = ap->Args[i].ArgReg;
5535 if(reg == REG_A4)
5537 reg = a4; a4 = 0;
5539 else if(reg == REG_A5)
5541 reg = a5; a5 = 0;
5544 /* reg is now either the last register argument or its a4/a5 redirect */
5545 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name);
5546 for(i = maxargs; i < ap->NumArgs; ++i)
5548 sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
5549 DoOutput("(ULONG)(%s)%s", (strptr)tempbuf, i == ap->NumArgs-1 ?
5550 "" : ", ");
5552 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5553 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name, name,
5554 RegNames[reg], name);
5556 DoOutput(" __asm volatile (\""/*)*/);
5557 if(a5) DoOutput("exg a5,%s\\n\\t", RegNames[a5]);
5558 if(a4) DoOutput("exg a4,%s\\n\\t", RegNames[a4]);
5559 if(maxargs != ap->NumArgs) /* StormGCC mode */
5561 DoOutput("movem.l ");
5562 for(i = maxargs; i < ap->NumArgs; ++i)
5564 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg],
5565 i == ap->NumArgs-1 ? "" : "/");
5567 DoOutput(",-(a7)\\n\\t");
5568 for(i = maxargs; i < ap->NumArgs; ++i)
5570 if(i == maxargs)
5571 DoOutput("move.l (%s),%s\\n\\t", RegNames[reg],
5572 RegNames[ap->Args[i].ArgReg]);
5573 else
5574 DoOutput("move.l %ld(%s),%s\\n\\t", (i-maxargs)*4, RegNames[reg],
5575 RegNames[ap->Args[i].ArgReg]);
5578 DoOutput("jsr a6@(-%d:W)", ap->Bias);
5579 if(maxargs != ap->NumArgs) /* StormGCC mode */
5581 DoOutput("\\n\\tmovem.l (a7)+,");
5582 for(i = maxargs; i < ap->NumArgs; ++i)
5584 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg],
5585 i == ap->NumArgs-1 ? "" : "/");
5588 if(a4) DoOutput("\\n\\texg a4,%s", RegNames[a4]);
5589 if(a5) DoOutput("\\n\\texg a5,%s", RegNames[a5]);
5590 DoOutput("\" \\\n");
5592 if(noret)
5593 DoOutput(" : \"=r\" (_d0)");
5594 else
5595 DoOutput(" : \"=r\"(__%s__re)", name);
5596 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5597 if(BaseName)
5598 DoOutput(" \"r\"(__%s__bn)%s", name, ap->NumArgs ? "," : "");
5599 for(i = 0; i < maxargs; ++i)
5601 DoOutput(" \"rf\"(__%s_%s)", name, ap->Args[i].ArgName);
5602 if(i < ap->NumArgs-1)
5603 DoOutput(",");
5605 if(i != ap->NumArgs) /* StormGCC mode */
5606 DoOutput(" \"r\"(__%s__ArgsPtr)", name);
5607 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5609 if(ap->NumArgs || !noret)
5610 DoOutput(/*({*/" }%s \\\n", noret ? "" : ");");
5613 return DoOutput(/*({*/"})\n\n");
5616 uint32 FuncInline(struct AmiPragma *ap, uint32 flags, strptr name)
5618 uint32 noret = 0, a45 = 0, j;
5619 int32 fp = -1, i;
5620 struct ClibData *cd;
5622 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5623 return 1;
5625 if(!(Flags & FLAG_INLINENEW) && CheckError(ap, AMIPRAGFLAG_MOSBASESYSV))
5626 return 1;
5628 Flags |= FLAG_DONE; /* We did something */
5630 if(flags & FUNCFLAG_ALIAS)
5632 if(flags & FUNCFLAG_TAG)
5633 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5634 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
5636 DoOutput("#define %s("/*)*/, name);
5637 for(i = 0; i < ap->NumArgs-1; ++i)
5638 DoOutput("%s, ", ap->Args[i].ArgName);
5639 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
5640 for(i = 0; i < ap->NumArgs-1; ++i)
5641 DoOutput("(%s), ", ap->Args[i].ArgName);
5642 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
5645 if(!(cd = GetClibFunc(ap->Flags & AMIPRAGFLAG_VARARGS ?
5646 ap->TagName : ap->FuncName, ap, flags)))
5647 return 1;
5649 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5650 noret = 1; /* this is a void function */
5652 if(ap->Flags & AMIPRAGFLAG_A5USE)
5653 a45 = REG_A5;
5654 if(ap->Flags & AMIPRAGFLAG_A4USE)
5656 if(a45)
5658 DoError(ERR_INLINE_A4_AND_A5, ap->Line);
5659 return 1; /* skip this entry */
5661 a45 = REG_A4;
5663 if(a45 && (ap->Flags & AMIPRAGFLAG_D7USE))
5665 DoError(ERR_INLINE_D7_AND_A45, ap->Line);
5666 return 1; /* skip this entry */
5669 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_MOSBASESYSV))
5671 if(Flags & FLAG_INLINENEW)
5673 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5674 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "");
5675 if(IsNoCreateInlineFunc(name))
5677 DoOutput("__inline ");
5678 FuncCSTUBS(ap, flags, name);
5679 /* call CSTUBS, as this equals the method used there */
5681 else
5683 DoOutput("#define %s("/*)*/, name);
5684 for(i = 0; i < ap->NumArgs-1; ++i)
5686 DoOutput("%s, ", ap->Args[i].ArgName);
5688 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5689 ap->FuncName);
5690 for(i = 0; i < ap->NumArgs-1; ++i)
5691 DoOutput("(%s), ", ap->Args[i].ArgName);
5692 DoOutput("("/*)*/);
5693 OutClibType(&cd->Args[i], 0);
5694 DoOutput(/*({((*/") _tags);})\n");
5696 return DoOutput("#endif\n\n");
5698 else if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS))
5699 == (FLAG_INLINESTUB|FLAG_MORPHOS))
5701 int32 n, d, tagl, local;
5703 n = 9-ap->NumArgs;
5704 d = n & 1 ? 4 : 0;
5705 tagl = 8 + (Flags2 & FLAG2_DIRECTVARARGS ? 0 : 64);
5706 local = (n * 4+d+8+15) & ~15; /* size of the stack frame */
5708 /* Stack frame:
5709 * 0- 3: next frame ptr
5710 * 4- 7: save lr
5711 * 8-71: struct Caos
5712 * 72-72+n*4+d+8-1: tag list start
5713 * ?-local-1: padding
5716 DoOutput("asm(\"\n"/*)*/
5717 "\t.align\t2\n"
5718 "\t.globl\t%s\n"
5719 "\t.type\t%s,@function\n"
5720 "%s:\n"
5721 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5722 "\tmflr\t0\n"
5723 "\tstw\t0,%ld(1)\n",
5724 name, name, name, local, local+4);
5726 /* If n is odd, one tag is split between regs and stack.
5727 * Copy its ti_Data together with the ti_Tag. */
5728 if(d)
5729 DoOutput("\tlwz\t0,%ld(1)\n", local+8); /* read ti_Data */
5731 /* Save the registers */
5732 for(i = ap->NumArgs; i <= 8; ++i)
5733 DoOutput("\tstw\t%ld,%ld(1)\n", i+2, (i-ap->NumArgs) * 4+tagl);
5735 if(d)
5736 DoOutput("\tstw\t0,%ld(1)\n", tagl+n * 4); /* write ti_Data */
5738 /* Add TAG_MORE */
5739 DoOutput("\tli\t0,2\n"
5740 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5741 "\taddi\t0,1,%ld\n"
5742 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5743 tagl+n * 4+d, local+8+d, tagl+n * 4+d+4);
5745 if(Flags2 & FLAG2_DIRECTVARARGS)
5747 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5748 "\tbl\t%s\n", ap->NumArgs+2, tagl, name);
5750 else
5753 if(!BaseName)
5755 DoError(ERR_MISSING_BASENAME, ap->Line);
5756 return 1;
5758 /* Caos.Offset = -fD_GetOffset(obj) */
5759 DoOutput("\tli\t0,%d\n"
5760 "\tstw\t0,8(1)\n", -ap->Bias);
5762 /* Save the non-varargs registers in the Caos struct. */
5763 for(i=0; i < ap->NumArgs-1; ++i)
5765 DoOutput("\tstw\t%ld,%d(1)\n", i+3, 8+4+(ap->Args[i].ArgReg * 4));
5768 DoOutput("\taddi\t0,1,%ld\n"
5769 "\tlis\t3,%s@ha\n"
5770 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5771 "\tlwz\t12,%s@l(3)\n"
5772 "\tlwz\t11,88(2)\n"
5773 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5774 "\tmtctr\t11\n"
5775 "\taddi\t3,1,8\n"
5776 "\tbctrl\n", /* EmulCallOS() */
5777 tagl, BaseName, 12+(4 * ap->Args[i].ArgReg), BaseName);
5779 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5780 "\tmtlr\t0\n"
5781 "\taddi\t1,1,%ld\n"
5782 "\tblr\n"
5783 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local+4, local, name, name);
5785 else
5787 DoOutput("%s%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ",
5788 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
5789 return FuncCSTUBS(ap, flags, name);
5790 /* call CSTUBS, as this equals the method used there */
5794 if(Flags & FLAG_INLINENEW) /* new style */
5796 strptr funcpar = "";
5797 DoOutput("#define %s("/*)*/, name);
5799 for(i = 0; i < cd->NumArgs; ++i)
5801 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5802 funcpar = "FP";
5805 if(ap->NumArgs)
5807 for(i = 0; i < ap->NumArgs-1; ++i)
5808 DoOutput("%s, ", ap->Args[i].ArgName);
5809 DoOutput("%s", ap->Args[i].ArgName);
5811 DoOutput(/*(*/") \\\n\t");
5812 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
5814 DoOutput("((("/*)))*/);
5815 OutClibType(&cd->ReturnType, 0);
5816 DoOutput(" (*)("/*)*/);
5817 DoOutput("%s", GetBaseType());
5818 for(i = 0; i < ap->NumArgs; ++i)
5820 DoOutput(", ");
5821 OutClibType(&cd->Args[i], 0);
5823 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5824 "(%s_BASE_NAME",/*)*/
5825 ShortBaseNameUpper, ap->Bias-2, ShortBaseNameUpper);
5827 for(i = 0; i < ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0); ++i)
5828 DoOutput(", %s", ap->Args[i].ArgName);
5829 if(flags & FUNCFLAG_TAG)
5830 DoOutput(", __VA_ARGS__");
5831 return DoOutput(/*((*/"))\n\n");
5833 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap->NumArgs,
5834 (noret ? "NR" : ""), (a45 ? RegNamesUpper[a45] : (strptr) ""),
5835 (BaseName ? "" : "UB"), funcpar, ap->Bias);
5836 if(!noret)
5838 OutClibType(&cd->ReturnType, 0);
5839 DoOutput(", ");
5841 DoOutput("%s, ", name);
5843 for(i = 0; i < ap->NumArgs; ++i)
5845 j = ap->Args[i].ArgReg;
5846 if(a45 && (j == REG_A4 || j == REG_A5))
5847 j = REG_D7;
5848 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5850 if(fp != -1)
5852 DoError(ERR_MULTIPLEFUNCTION, ap->Line);
5853 DoOutput("void *");
5855 else
5857 DoOutput("__fpt"); fp = i;
5860 else
5861 OutClibType(&cd->Args[i], 0);
5863 DoOutput(", %s, %s%s", ap->Args[i].ArgName, RegNames[j],
5864 (i == ap->NumArgs-1 && !BaseName ? "" : ", "));
5867 if(BaseName) /* was "##base" used? */
5868 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper);
5870 if(fp >= 0)
5872 DoOutput(", ");
5873 OutClibType(&cd->Args[fp], "__fpt");
5876 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
5877 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5879 return DoOutput(/*(*/")\n\n");
5882 /* old mode or stubs mode */
5884 if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS)) != (FLAG_INLINESTUB|FLAG_MORPHOS))
5885 DoOutput("%s%s__inline ", Flags & (FLAG_INLINESTUB|FLAG_MORPHOS) ?
5886 "" : "extern ", Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
5887 OutClibType(&cd->ReturnType, 0);
5888 DoOutput("\n%s(%s"/*)*/, name, (BaseName ?
5889 (ap->NumArgs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5891 for(i = 0; i < ap->NumArgs; ++i)
5893 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
5894 if(i < ap->NumArgs-1)
5895 DoOutput(", ");
5898 if(Flags & FLAG_POWERUP)
5900 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5901 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5902 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5903 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5904 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5905 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5906 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5908 if(ap->NumArgs)
5910 for(i = 0; i < ap->NumArgs; ++i)
5912 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5913 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
5917 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
5919 if(BaseName)
5920 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper);
5921 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5922 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5923 else
5925 DoOutput("\treturn(("/*))*/);
5926 OutClibType(&cd->ReturnType, 0);
5927 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5929 return Output_Error;
5931 else if(Flags & FLAG_MORPHOS)
5933 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5935 if(ap->NumArgs)
5937 for(i = 0; i < ap->NumArgs; ++i)
5939 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5940 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
5944 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
5945 if(BaseName)
5946 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5947 ShortBaseNameUpper);
5949 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5950 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5951 else
5953 DoOutput("\treturn(("/*))*/);
5954 OutClibType(&cd->ReturnType, 0);
5955 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5957 return Output_Error;
5960 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName ? " BASE_EXT_DECL\n" : ""));
5962 if(!noret)
5964 DoOutput(" register ");
5965 OutClibType(&cd->ReturnType, "res");
5966 DoOutput(" __asm(\"d0\");\n");
5969 if(BaseName)
5970 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5971 GetBaseType(), ShortBaseNameUpper);
5973 for(i = 0; i < ap->NumArgs; ++i)
5975 j = ap->Args[i].ArgReg;
5976 if(a45 && (j == REG_A4 || j == REG_A5))
5977 j = REG_D7;
5979 DoOutput(" register ");
5980 OutClibType(&cd->Args[i], RegNames[j]);
5981 DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
5984 if(a45)
5986 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
5987 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames[a45],
5988 ap->Bias, RegNames[a45]);
5990 else
5991 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap->Bias);
5993 DoOutput(noret ? " : /* No Output */\n" : " : \"=r\" (res)\n");
5995 DoOutput(" : ");
5996 if(BaseName)
5997 DoOutput("\"r\" (a6)%s", (ap->NumArgs ? ", ": ""));
5999 for(i = 0; i < ap->NumArgs; ++i)
6001 j = ap->Args[i].ArgReg;
6002 if(a45 && (j == REG_A4 || j == REG_A5))
6003 j = REG_D7;
6005 DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
6008 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6010 if(noret)
6011 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6012 else
6013 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6017 /* new style inlines designed by Bernardo Innocenti */
6018 uint32 FuncInlineNS(struct AmiPragma *ap, uint32 flags, strptr name)
6020 int32 i;
6021 struct ClibData *cd;
6023 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6024 return 1;
6026 Flags |= FLAG_DONE; /* We did something */
6028 if(flags & FUNCFLAG_ALIAS)
6030 if(flags & FUNCFLAG_TAG)
6031 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6032 name, ap->TagName);
6034 DoOutput("#define %s("/*)*/, name);
6035 for(i = 0; i < ap->NumArgs-1; ++i)
6036 DoOutput("%s, ", ap->Args[i].ArgName);
6037 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6038 for(i = 0; i < ap->NumArgs-1; ++i)
6039 DoOutput("(%s), ", ap->Args[i].ArgName);
6040 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
6043 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6044 return 1;
6046 if((flags & FUNCFLAG_TAG))
6048 if(!(Flags2 & FLAG2_INLINEMAC))
6050 DoOutput("static __inline ");
6051 return FuncCSTUBS(ap, flags, name);
6052 /* call CSTUBS, as this equals the method used there */
6054 else
6056 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6057 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
6058 for(i = 0; i < ap->NumArgs-1; ++i)
6059 DoOutput("%s, ", ap->Args[i].ArgName);
6060 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6061 ap->FuncName);
6062 for(i = 0; i < ap->NumArgs-1; ++i)
6063 DoOutput("(%s), ", ap->Args[i].ArgName);
6064 DoOutput("("/*)*/);
6065 OutClibType(&cd->Args[i], 0);
6066 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6070 if(Flags2 & FLAG2_INLINEMAC)
6072 DoOutput("#define %s("/*)*/, name);
6073 for(i = 0; i < ap->NumArgs; ++i)
6075 DoOutput("%s", ap->Args[i].ArgName);
6076 if(i < ap->NumArgs-1)
6077 DoOutput(", ");
6079 DoOutput(/*(*/") \\\n\t");
6081 else
6083 DoOutput("static __inline ");
6084 OutClibType(&cd->ReturnType, 0);
6085 DoOutput(" %s("/*)*/, name);
6086 for(i = 0; i < ap->NumArgs; ++i)
6088 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6089 if(i < ap->NumArgs-1)
6090 DoOutput(", ");
6092 DoOutput(/*(*/")\n{\n "/*}*/);
6093 if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6094 DoOutput("return ");
6096 DoOutput("(("/*))*/);
6097 OutClibType(&cd->ReturnType, 0);
6098 DoOutput(" (*)("/*)*/);
6099 for(i = 0; i < ap->NumArgs; ++i)
6101 OutClibType(&cd->Args[i], 0);
6102 DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
6103 if(i < ap->NumArgs-1)
6104 DoOutput(", ");
6106 if(BaseName)
6108 if(ap->NumArgs)
6109 DoOutput(", ");
6110 DoOutput("%s __asm(\"a6\")", GetBaseType());
6112 DoOutput(/*((*/"))");
6113 if(Flags2 & FLAG2_INLINEMAC)
6114 DoOutput(" \\");
6115 if(BaseName)
6116 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6117 ShortBaseNameUpper, ap->Bias);
6118 else
6120 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
6122 if(i == ap->NumArgs)
6123 return 1;
6124 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap->Args[i].ArgName,
6125 ap->Bias);
6127 for(i = 0; i < ap->NumArgs; ++i)
6129 DoOutput("%s", ap->Args[i].ArgName);
6130 if(i < ap->NumArgs-1)
6131 DoOutput(", ");
6133 if(BaseName)
6135 if(ap->NumArgs)
6136 DoOutput(", ");
6137 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
6140 if(Flags2 & FLAG2_INLINEMAC)
6141 DoOutput(/*(*/")\n");
6142 else
6143 DoOutput(/*{(*/");\n}\n");
6145 return DoOutput("\n");
6148 uint32 FuncPowerUP(struct AmiPragma *ap, uint32 flags, strptr name)
6150 int32 i;
6151 struct ClibData *cd;
6153 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6154 return 1;
6156 Flags |= FLAG_DONE; /* We did something */
6158 if(flags & FUNCFLAG_ALIAS)
6160 if(flags & FUNCFLAG_TAG)
6161 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6162 name, ap->TagName);
6164 DoOutput("#define %s("/*)*/, name);
6165 for(i = 0; i < ap->NumArgs-1; ++i)
6166 DoOutput("%s, ", ap->Args[i].ArgName);
6167 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6168 for(i = 0; i < ap->NumArgs-1; ++i)
6169 DoOutput("(%s), ", ap->Args[i].ArgName);
6170 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
6173 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6174 return 1;
6176 if(flags & FUNCFLAG_TAG)
6178 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name);
6179 for(i = 0; i < ap->NumArgs-1; ++i)
6180 DoOutput("%s, ", ap->Args[i].ArgName);
6181 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6182 ap->FuncName);
6183 for(i = 0; i < ap->NumArgs-1; ++i)
6184 DoOutput("(%s), ", ap->Args[i].ArgName);
6185 DoOutput("("/*)*/);
6186 OutClibType(&cd->Args[i], 0);
6187 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6190 DoOutput("#define\t%s("/*)*/, name);
6192 if(ap->NumArgs)
6195 for(i = 0; i < ap->NumArgs-1; ++i)
6196 DoOutput("%s, ", ap->Args[i].ArgName);
6197 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap->Args[i].ArgName, name);
6199 if(BaseName)
6200 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper);
6202 for(i = 0; i < ap->NumArgs-1; ++i)
6203 DoOutput("%s, ", ap->Args[i].ArgName);
6204 DoOutput(/*(*/"%s)\n\n", ap->Args[i].ArgName);
6206 else if(BaseName)
6207 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name, ShortBaseNameUpper);
6208 else
6209 DoOutput(/*(*/")\t_%s()\n\n", name);
6211 DoOutput("static __inline ");
6212 OutClibType(&cd->ReturnType, 0);
6214 DoOutput("\n_%s("/*)*/, name);
6215 if(BaseName)
6216 DoOutput("void * %s%s", BaseName, ap->NumArgs ? ", " : "");
6218 for(i = 0; i < ap->NumArgs; ++i)
6220 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6221 if(i < ap->NumArgs-1)
6222 DoOutput(", ");
6225 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6226 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6227 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6228 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6229 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6230 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6231 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6233 if(ap->NumArgs)
6235 for(i = 0; i < ap->NumArgs; ++i)
6237 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6238 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
6242 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
6244 if(BaseName)
6245 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName);
6246 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6247 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6248 else
6250 DoOutput("\treturn(("/*))*/);
6251 OutClibType(&cd->ReturnType, 0);
6252 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6254 return Output_Error;
6257 uint32 FuncFPCUnit(struct AmiPragma *ap, uint32 flags, strptr name)
6259 int32 i;
6260 struct ClibData *cd;
6262 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6263 return 1;
6264 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6265 return 1;
6267 if(!FuncFPCType(ap, flags, name))
6268 return 0;
6270 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6272 for(i = 0; i < ap->NumArgs; ++i)
6273 DoOutput("\tMOVE%s.L\t%s,%s\n", ap->Args[i].ArgReg >= REG_A0 ? "A" : "",
6274 ap->Args[i].ArgName, RegNamesUpper[ap->Args[i].ArgReg]);
6276 if(BaseName)
6277 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName);
6278 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap->Bias);
6280 if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6282 if(!cd->ReturnType.PointerDepth &&
6283 cd->ReturnType.Flags == CPP_FLAG_BOOLEAN)
6284 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6285 " @end:\tMOVE.B\tD0,@RESULT\n");
6286 else
6287 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6289 return DoOutput(" END;\nEND;\n\n");
6292 uint32 FuncFPCType(struct AmiPragma *ap, uint32 flags, strptr name)
6294 uint32 ret = 1;
6295 int32 i;
6296 struct ClibData *cd;
6298 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6299 return 1;
6300 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6301 return 1;
6303 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6305 ret = 0; DoOutput("PROCEDURE %s", name);
6307 else
6308 DoOutput("FUNCTION %s", name);
6310 if(ap->NumArgs)
6312 DoOutput("("/*)*/);
6313 for(i = 0; i < ap->NumArgs;)
6315 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6316 if(++i != ap->NumArgs)
6317 DoOutput("; ");
6319 DoOutput(/*(*/")");
6322 if(ret)
6323 OutPASCALType(&cd->ReturnType, "", 1);
6325 Flags |= FLAG_DONE; /* We did something */
6327 return DoOutput(";\n");
6330 uint32 FuncFPCTypeTags(struct AmiPragma *ap, uint32 flags, strptr name)
6332 uint32 ret = 1;
6333 int32 i;
6334 struct ClibData *cd;
6336 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6337 return 1;
6338 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6339 return 1;
6341 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6343 ret = 0; DoOutput("PROCEDURE %s", name);
6345 else
6346 DoOutput("FUNCTION %s", name);
6348 if(ap->NumArgs)
6350 DoOutput("("/*)*/);
6351 for(i = 0; i < ap->NumArgs-1;)
6353 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6354 if(++i != ap->NumArgs)
6355 DoOutput("; ");
6357 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
6358 DoOutput(/*(*/")");
6361 if(ret)
6362 OutPASCALType(&cd->ReturnType, "", 1);
6364 Flags |= FLAG_DONE; /* We did something */
6366 return DoOutput(";\n");
6369 uint32 FuncFPCTypeTagsUnit(struct AmiPragma *ap, uint32 flags, strptr name)
6371 uint32 ret = 1;
6372 int32 i;
6373 struct ClibData *cd;
6375 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6376 return 1;
6377 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6378 return 1;
6380 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6382 ret = 0; DoOutput("PROCEDURE %s", name);
6384 else
6385 DoOutput("FUNCTION %s", name);
6387 if(ap->NumArgs)
6389 DoOutput("("/*)*/);
6390 for(i = 0; i < ap->NumArgs-1;)
6392 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6393 if(++i != ap->NumArgs)
6394 DoOutput("; ");
6396 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
6397 DoOutput(/*(*/")");
6400 if(ret)
6401 OutPASCALType(&cd->ReturnType, "", 1);
6403 DoOutput(";\nbegin\n");
6405 if(ret)
6406 DoOutput(" %s := %s",name, ap->FuncName);
6407 else DoOutput(" %s", ap->FuncName);
6409 if(ap->NumArgs)
6411 DoOutput("("/*)*/);
6412 for(i = 0; i < ap->NumArgs-1;)
6414 DoOutput("%s ", ap->Args[i].ArgName);
6415 if(++i != ap->NumArgs)
6416 DoOutput(", ");
6418 DoOutput("readintags(%s)",ap->Args[i].ArgName);
6419 DoOutput(/*(*/");");
6422 DoOutput("\nend");
6424 Flags |= FLAG_DONE; /* We did something */
6426 return DoOutput(";\n\n");
6430 uint32 FuncBMAP(struct AmiPragma *ap, uint32 flags, strptr name)
6432 uint8 reg, i;
6434 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_A5USE
6435 |AMIPRAGFLAG_PPC))
6436 return 1;
6438 Flags |= FLAG_DONE; /* We did something */
6440 for(i = 0; BMAPSpecial[i]; ++i)
6442 if(!stricmp(name, BMAPSpecial[i]))
6444 DoOutput("x"); break;
6448 DoOutput("%s",name);
6449 reg = 0; DoOutputDirect(&reg, 1);
6450 reg = (-ap->Bias)>>8; DoOutputDirect(&reg, 1);
6451 reg = -ap->Bias; DoOutputDirect(&reg, 1);
6452 for(i = 0; i < ap->NumArgs; ++i)
6454 reg = 1+ap->Args[i].ArgReg; DoOutputDirect(&reg, 1);
6456 reg = 0;
6457 return DoOutputDirect(&reg, 1);
6460 uint32 FuncVBCCInline(struct AmiPragma *ap, uint32 flags, strptr name)
6462 struct ClibData *cd;
6463 strptr c1, c2;
6464 int32 i, k;
6466 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6467 return 1;
6469 if(!(cd = GetClibFunc(name, ap, flags)))
6470 return 1;
6472 c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
6473 c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
6475 Flags |= FLAG_DONE; /* We did something */
6477 if(flags & FUNCFLAG_TAG)
6479 if(IsNoCreateInlineFunc(name))
6480 return 1; /* do not create some strange functions */
6481 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6482 "(__STDC_VERSION__ >= 199901L)\n");
6485 if(flags & FUNCFLAG_ALIAS)
6487 DoOutput("#define %s("/*)*/, name);
6488 for(i = 0; i < ap->NumArgs-1; ++i)
6489 DoOutput("%s, ", ap->Args[i].ArgName);
6490 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6491 if(Flags2 & FLAG2_OLDVBCC)
6493 for(i = 0; i < ap->NumArgs; ++i)
6494 DoOutput("(%s), ", ap->Args[i].ArgName);
6495 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6496 "#endif\n" : "");
6498 else
6500 DoOutput("%s", BaseName);
6501 for(i = 0; i < ap->NumArgs; ++i)
6502 DoOutput(", (%s)", ap->Args[i].ArgName);
6503 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ?
6504 "#endif\n" : "");
6508 OutClibType(&cd->ReturnType, 0);
6509 DoOutput(" __%s("/*)*/, name);
6511 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6513 DoOutput("__reg(\"a6\") %s", GetBaseType());
6514 if(ap->NumArgs)
6515 DoOutput(", ");
6518 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
6519 for(i = 0; i < k; ++i)
6521 DoOutput("__reg(\"%s\") ", RegNames[ap->Args[i].ArgReg]);
6522 if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
6523 && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
6525 DoOutput("void * %s", ap->Args[i].ArgName);
6527 else
6528 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6529 if(i < ap->NumArgs-1)
6530 DoOutput(", ");
6533 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6535 if(ap->NumArgs)
6536 DoOutput(", ");
6537 DoOutput("__reg(\"a6\") %s", GetBaseType());
6540 if(flags & FUNCFLAG_TAG)
6542 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6544 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6545 DoOutput(", ");
6547 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6548 RegNames[ap->Args[k].ArgReg]);
6550 if(ap->Args[k].ArgReg > 7)
6551 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1, c2,
6552 RegNames[ap->Args[k].ArgReg]);
6553 else
6554 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6555 RegNames[ap->Args[k].ArgReg], RegNames[ap->Args[k].ArgReg]);
6557 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6558 "\\tmove%s.l\\t(a7)+,%s\";\n", c1, ap->Bias, c2,
6559 ap->Args[k].ArgReg >= REG_A0 ? "a" : "", RegNames[ap->Args[k].ArgReg]);
6561 else
6562 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1, ap->Bias, c2);
6564 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6565 DoOutput("#define %s("/*)*/, name);
6566 for(i = 0; i < k; ++i)
6568 DoOutput("%s", ap->Args[i].ArgName);
6569 if(i < ap->NumArgs-1)
6570 DoOutput(", ");
6572 if(flags & FUNCFLAG_TAG)
6574 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6575 DoOutput("%s, ", ap->Args[k].ArgName);
6576 DoOutput("...");
6578 DoOutput(/*(*/") __%s("/*)*/, name);
6579 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6581 DoOutput("%s", BaseName);
6582 if(ap->NumArgs)
6583 DoOutput(", ");
6585 for(i = 0; i < k; ++i)
6587 if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
6588 && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
6590 DoOutput("(void *)");
6592 DoOutput("(%s)", ap->Args[i].ArgName);
6593 if(i < ap->NumArgs-1)
6594 DoOutput(", ");
6596 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6598 if(ap->NumArgs)
6599 DoOutput(", ");
6600 DoOutput("%s", BaseName);
6602 if(flags & FUNCFLAG_TAG)
6604 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6605 DoOutput("(%s), ", ap->Args[k].ArgName);
6606 DoOutput("__VA_ARGS__");
6609 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6612 uint32 FuncVBCCWOSInline(struct AmiPragma *ap, uint32 flags, strptr name)
6614 struct ClibData *cd;
6615 int32 i, k;
6617 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_M68K))
6618 return 1;
6620 if(!(cd = GetClibFunc(name, ap, flags)))
6621 return 1;
6623 Flags |= FLAG_DONE; /* We did something */
6625 if(flags & FUNCFLAG_TAG)
6627 if(IsNoCreateInlineFunc(name))
6628 return 1; /* do not create some strange functions */
6629 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6630 "(__STDC_VERSION__ >= 199901L)\n");
6633 if(flags & FUNCFLAG_ALIAS)
6635 DoOutput("#define %s("/*)*/, name);
6636 for(i = 0; i < ap->NumArgs-1; ++i)
6637 DoOutput("%s, ", ap->Args[i].ArgName);
6638 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6639 for(i = 0; i < ap->NumArgs; ++i)
6640 DoOutput("(%s), ", ap->Args[i].ArgName);
6641 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6642 "#endif\n" : "");
6645 OutClibType(&cd->ReturnType, 0);
6646 DoOutput(" __%s("/*)*/, name);
6648 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6650 DoOutput("%s", GetBaseType());
6651 if(ap->NumArgs)
6652 DoOutput(", ");
6655 k = ap->NumArgs;
6656 for(i = 0; i < k; ++i)
6658 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6659 if(i < k-1)
6660 DoOutput(", ");
6662 if(flags & FUNCFLAG_TAG)
6663 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6665 DoOutput(/*(*/")=\"");
6666 if(ap->Flags & AMIPRAGFLAG_PPC0)
6668 DoOutput("\\t.extern\\t_%s\\n", BaseName);
6669 if ((flags & FUNCFLAG_TAG) && k>0)
6671 /* save tag1 and load taglist-pointer */
6672 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6673 "\\taddi\\t%s%d,%s1,%d\\n",
6674 PPCRegPrefix, (int)k+2, 20+(int)k*4, PPCRegPrefix, PPCRegPrefix,
6675 (int)k+2, PPCRegPrefix, 20+(int)k*4);
6677 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6678 "\\tlwz\\t%s0,-%d(%s11)\\n"
6679 "\\tmtlr\\t%s0\\n"
6680 "\\tblrl",
6681 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix,
6682 ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6684 else if(ap->Flags & AMIPRAGFLAG_PPC2)
6686 /* @@@ tagcall handling? */
6687 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6688 "\\t.extern\\t_%s\\n"
6689 "\\tlwz\\t%s2,_%s(%s2)\\n"
6690 "\\tlwz\\t%s0,-%d(%s2)\\n"
6691 "\\tmtlr\\t%s0\\n"
6692 "\\tblrl\\n"
6693 "\\tlwz\\t%s2,20(%s1)",
6694 PPCRegPrefix, PPCRegPrefix, BaseName, PPCRegPrefix, BaseName,
6695 PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
6696 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
6698 else
6700 if ((flags & FUNCFLAG_TAG) && k>0)
6702 /* save tag1 and load taglist-pointer */
6703 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6704 "\\taddi\\t%s%d,%s1,%d\\n",
6705 PPCRegPrefix, (int)k+3, 24+(int)k*4, PPCRegPrefix, PPCRegPrefix,
6706 (int)k+3, PPCRegPrefix, 24+(int)k*4);
6708 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6709 "\\tmtlr\\t%s0\\n"
6710 "\\tblrl",
6711 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6713 DoOutput("\";\n");
6715 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6716 DoOutput("#define %s("/*)*/, name);
6717 for(i = 0; i < k; ++i)
6719 DoOutput("%s", ap->Args[i].ArgName);
6720 if(i < ap->NumArgs-1)
6721 DoOutput(", ");
6723 if(flags & FUNCFLAG_TAG)
6725 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6726 DoOutput("%s, ", ap->Args[k].ArgName);
6727 DoOutput("...");
6729 DoOutput(/*(*/") __%s("/*)*/, name);
6730 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6732 DoOutput("%s", BaseName);
6733 if(ap->NumArgs)
6734 DoOutput(", ");
6736 for(i = 0; i < k; ++i)
6738 DoOutput("(%s)", ap->Args[i].ArgName);
6739 if(i < ap->NumArgs-1)
6740 DoOutput(", ");
6742 if(flags & FUNCFLAG_TAG)
6744 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6745 DoOutput("(%s), ", ap->Args[k].ArgName);
6746 DoOutput("__VA_ARGS__");
6749 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6752 uint32 FuncVBCCMorphInline(struct AmiPragma *ap, uint32 flags, strptr name)
6754 struct ClibData *cd;
6755 int32 i, k;
6757 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6758 return 1;
6760 if(!(cd = GetClibFunc(name, ap, flags)))
6761 return 1;
6763 Flags |= FLAG_DONE; /* We did something */
6765 if(flags & FUNCFLAG_TAG)
6767 if(IsNoCreateInlineFunc(name))
6768 return 1; /* do not create some strange functions */
6769 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6770 "(__STDC_VERSION__ >= 199901L)\n");
6773 if(flags & FUNCFLAG_ALIAS)
6775 DoOutput("#define %s("/*)*/, name);
6776 for(i = 0; i < ap->NumArgs-1; ++i)
6777 DoOutput("%s, ", ap->Args[i].ArgName);
6778 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6779 for(i = 0; i < ap->NumArgs; ++i)
6780 DoOutput("(%s), ", ap->Args[i].ArgName);
6781 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6782 "#endif\n" : "");
6785 OutClibType(&cd->ReturnType, 0);
6786 if((flags & FUNCFLAG_TAG) && (Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6787 DoOutput(" __linearvarargs");
6789 DoOutput(" __%s("/*)*/, name);
6791 if(BaseName && !(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12)))
6793 DoOutput("%s", GetBaseType());
6794 if(ap->NumArgs)
6795 DoOutput(", ");
6798 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6800 if((flags & FUNCFLAG_TAG) &&
6801 !(ap->Flags & AMIPRAGFLAG_MOS_ALL))
6803 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6804 DoOutput("long, ");
6808 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
6809 for(i = 0; i < k; ++i)
6811 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6812 if(i < ap->NumArgs-1)
6813 DoOutput(", ");
6816 if(flags & FUNCFLAG_TAG)
6818 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6820 if((ap->Flags & AMIPRAGFLAG_MOS_ALL)
6821 && !(ap->Flags & AMIPRAGFLAG_VARARGS))
6823 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6824 DoOutput("long, ");
6826 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6828 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6829 DoOutput(", ");
6833 DoOutput("...");
6836 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
6838 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6839 PPCRegPrefix, ap->Bias-2, PPCRegPrefix);
6840 if((ap->Flags != AMIPRAGFLAG_VARARGS) && (flags & FUNCFLAG_TAG))
6842 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6843 PPCRegPrefix,3+k+1,PPCRegPrefix);
6845 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6846 "\t\"\\tbctrl\";\n", PPCRegPrefix);
6848 else if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
6850 if (BaseName)
6852 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6853 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6854 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6855 PPCRegPrefix, BaseName,
6856 PPCRegPrefix, BaseName, PPCRegPrefix,
6857 PPCRegPrefix, ap->Bias-2, PPCRegPrefix);
6859 if((ap->Flags != AMIPRAGFLAG_VARARGS) && (flags & FUNCFLAG_TAG))
6861 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6862 PPCRegPrefix,3+k+1,PPCRegPrefix);
6864 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6865 "\t\"\\tbctrl\";\n", PPCRegPrefix);
6867 else
6869 int ofs = 4, fix = 0;
6870 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6871 PPCRegPrefix, PPCRegPrefix);
6872 k = 3;
6873 if(BaseName)
6875 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix, k++,
6876 PPCRegPrefix);
6878 if(Flags2 & FLAG2_SHORTPPCVBCCINLINE)
6880 ofs = 12;
6881 if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
6882 fix = 8+1-i;
6884 else if(flags & FUNCFLAG_TAG)
6886 if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
6887 k += 8+1-i;
6890 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix);
6891 for(i = 0; i < ap->NumArgs; ++i)
6893 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
6895 if(k <= 7+3)
6896 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix, k++);
6897 else
6898 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6899 PPCRegPrefix, 8+(k++-11)*4, PPCRegPrefix, PPCRegPrefix);
6901 else
6903 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6904 PPCRegPrefix, ofs, PPCRegPrefix, (2+k+fix-11)*4, PPCRegPrefix, ofs);
6906 DoOutput("%d(%s2)\\n\"\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
6908 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix,
6909 ap->Bias);
6912 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6913 DoOutput("#define %s("/*)*/, name);
6914 for(i = 0; i < k; ++i)
6916 DoOutput("%s", ap->Args[i].ArgName);
6917 if(i < ap->NumArgs-1)
6918 DoOutput(", ");
6920 if(flags & FUNCFLAG_TAG)
6922 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6923 DoOutput("%s, ", ap->Args[k].ArgName);
6924 DoOutput("...");
6926 DoOutput(/*(*/") __%s("/*)*/, name);
6927 if(BaseName && !(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12)))
6929 DoOutput("%s", BaseName);
6930 if(ap->NumArgs)
6931 DoOutput(", ");
6933 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6935 if(flags & FUNCFLAG_TAG && !(ap->Flags & AMIPRAGFLAG_MOSBASESYSV))
6937 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6938 DoOutput("0, ");
6941 for(i = 0; i < k; ++i)
6943 DoOutput("(%s)", ap->Args[i].ArgName);
6944 if(i < ap->NumArgs-1)
6945 DoOutput(", ");
6947 if(flags & FUNCFLAG_TAG)
6949 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6950 DoOutput("(%s), ", ap->Args[k].ArgName);
6951 DoOutput("__VA_ARGS__");
6954 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6957 uint32 FuncVBCCWOSText(struct AmiPragma *ap, uint32 flags, strptr name)
6959 uint32 i, k, count, ofs;
6960 struct ClibData *cd = 0;
6962 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
6963 return 1;
6965 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&
6966 !(cd = GetClibFunc(name, ap, flags)))
6967 return 1;
6969 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
6970 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) ||
6971 !(Flags & FLAG_WOSLIBBASE)))
6973 DoError(ERR_MISSING_BASENAME, ap->Line);
6974 return 1;
6977 Flags |= FLAG_DONE;
6979 if(Flags & FLAG_SINGLEFILE)
6981 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
6983 if(HEADER)
6985 DoOutput("\n");
6986 DoOutputDirect(HEADER, headersize);
6990 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
6991 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
6993 if(Flags & FLAG_SINGLEFILE)
6994 DoOutput("\t.file\t\"%s.o\"\n", name);
6995 DoOutput("\t.align\t3\n");
6996 if(Flags & FLAG_WOSLIBBASE) /* PPCBase already in r3, LibBase in r4 */
6998 if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
6999 DoOutput("\t.extern _%s\n", BaseName);
7000 DoOutput("\t.global __%s\n__%s:\n", name, name);
7002 else
7004 if(BaseName)
7005 DoOutput("\t.extern _%s\n", BaseName);
7006 if(!(ap->Flags & AMIPRAGFLAG_PPC))
7007 DoOutput("\t.extern _PowerPCBase\n");
7008 DoOutput("\t.global _%s\n_%s:\n", name, name);
7011 if(ap->Flags & AMIPRAGFLAG_PPC2)
7013 DoOutput("\tstw\t%s2,20(%s1)\n"
7014 "\tmflr\t%s0\n"
7015 "\tstw\t%s0,16(%s1)\n"
7016 "\tlwz\t%s2,_%s(%s2)\n"
7017 "\tlwz\t%s0,-%d(%s2)\n"
7018 "\tmtlr\t%s0\n"
7019 "\tblrl\n"
7020 "\tlwz\t%s0,16(%s1)\n"
7021 "\tlwz\t%s2,20(%s1)\n"
7022 "\tmtlr\t%s0\n"
7023 "\tblr\n",
7024 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7025 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2,
7026 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7027 PPCRegPrefix, PPCRegPrefix);
7029 else if(ap->Flags & AMIPRAGFLAG_PPC0)
7031 DoOutput("\tmflr\t%s0\n", PPCRegPrefix);
7032 if((flags & FUNCFLAG_TAG) && ap->NumArgs>0)
7034 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7035 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7036 PPCRegPrefix, (int)ap->NumArgs+2,
7037 20+(int)ap->NumArgs*4, PPCRegPrefix, PPCRegPrefix,
7038 (int)ap->NumArgs+2, PPCRegPrefix, 20+(int)ap->NumArgs*4);
7040 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7041 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7042 "\tlwz\t%s11,_%s(%s2)\n"
7043 "\tlwz\t%s0,-%d(%s11)\n"
7044 "\tmtlr\t%s0\n"
7045 "\tblrl\n"
7046 "\tlwz\t%s0,40(%s1)\n"
7047 "\taddi\t%s1,%s1,32\n"
7048 "\tmtlr\t%s0\n"
7049 "\tblr\n",
7050 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7051 BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
7052 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7053 PPCRegPrefix);
7055 else if(ap->Flags & AMIPRAGFLAG_PPC)
7057 count = ap->NumArgs;
7058 if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
7060 /* init stack frame */
7061 i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
7062 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7063 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
7065 if(count > 8)
7067 /* extra arguments must be passed on the stack */
7068 k = 32-(count-8); /* firstreg */
7070 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7071 PPCRegPrefix, k, 56+(count-8)*4, PPCRegPrefix, PPCRegPrefix, k,
7072 i+56, PPCRegPrefix);
7073 if(flags & FUNCFLAG_TAG)
7074 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
7075 i+20+count*4);
7076 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
7078 else if(flags & FUNCFLAG_TAG)
7080 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
7081 PPCRegPrefix, i+20+count*4);
7082 --count;
7085 else /* Args must be shifted! */
7087 /* init stack frame */
7088 i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
7089 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7090 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
7092 if(count > 7)
7094 /* extra arguments must be passed on the stack */
7095 if(count == 8)
7097 /* special case: move 8th argument into stack frame */
7098 if(flags & FUNCFLAG_TAG)
7099 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
7100 i+20+count*4);
7101 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7103 else
7105 k = 32-(count-7); /* firstreg */
7107 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7108 "\tmr\t%s%ld,%s10\n"
7109 "\tlmw\t%s%ld,%ld(%s1)\n",
7110 PPCRegPrefix, k, 56+(count-7)*4, PPCRegPrefix,
7111 PPCRegPrefix, k, PPCRegPrefix, PPCRegPrefix, k+1,
7112 i+56, PPCRegPrefix);
7113 if(flags & FUNCFLAG_TAG)
7114 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix,
7115 PPCRegPrefix, i+20+count*4);
7116 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
7119 else if(flags & FUNCFLAG_TAG)
7121 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
7122 PPCRegPrefix, i+20+count*4);
7123 --count;
7126 /* shift all arguments into their following register */
7127 for(k=(count<8)?count:7; k > 0; --k)
7128 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix, 3+k, PPCRegPrefix, 2+k);
7130 /* load library base and LVO, then call LVO via LR */
7131 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
7134 /* call LVO */
7135 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix,
7136 ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
7138 /* cleanup stack frame and return */
7139 if(count > 8)
7141 k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
7142 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, 32-(count-k),
7143 56+(count-k)*4, PPCRegPrefix);
7146 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7147 PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7149 else
7151 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7152 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7154 /* clear PP_Flags, PP_Stack and PP_StackSize */
7155 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7156 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7157 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7159 if(Flags & FLAG_WOSLIBBASE)
7160 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7161 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix, ap->Bias, PPCRegPrefix,
7162 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7163 else if(!BaseName)
7164 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix,
7165 ap->Bias, PPCRegPrefix, PPCRegPrefix);
7166 else
7167 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7168 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7169 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias,
7170 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7171 PPCRegPrefix);
7173 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
7174 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
7175 for(i = 0; i < k; ++i)
7177 if(i + ofs <= 7)
7179 if(ap->Args[i].ArgReg == REG_A6)
7180 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix, i+3+ofs,
7181 PPCRegPrefix);
7182 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3+ofs);
7184 else
7186 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix, (i+1+ofs)*4+196,
7187 PPCRegPrefix);
7188 if(ap->Args[i].ArgReg == REG_A6)
7189 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7190 DoOutput("\tstw\t%s11,", PPCRegPrefix);
7192 DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
7194 if(flags & FUNCFLAG_TAG)
7196 if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
7197 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i+3+ofs,
7198 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
7199 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix,
7200 PPCRegPrefix, 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
7201 DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
7204 if(!(Flags & FLAG_WOSLIBBASE))
7205 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix, PPCRegPrefix);
7207 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7208 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7209 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7210 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7211 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7214 if(Flags & FLAG_WOSLIBBASE)
7215 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7216 name, name, name);
7217 else
7218 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7219 name, name, name);
7222 uint32 FuncVBCCWOSCode(struct AmiPragma *ap, uint32 flags, strptr name)
7224 uint32 i, j, k, ofs, count;
7225 uint8 *data, *basepos = 0, *pbasepos = 0;
7226 struct ClibData *cd = 0;
7228 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
7229 return 1;
7231 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&
7232 !(cd = GetClibFunc(name, ap, flags)))
7233 return 1;
7235 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
7236 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) ||
7237 !(Flags & FLAG_WOSLIBBASE)))
7239 DoError(ERR_MISSING_BASENAME, ap->Line);
7240 return 1;
7243 Flags |= FLAG_DONE; /* We did something */
7245 i = strlen(name) + 2;
7246 EndPutM32(tempbuf, HUNK_UNIT);
7247 EndPutM32(tempbuf+4, (i+3)>>2);
7248 DoOutputDirect(tempbuf, 8);
7249 DoOutput("%s.o", name);
7250 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
7252 i = strlen(hunkname);
7253 EndPutM32(tempbuf, HUNK_NAME);
7254 EndPutM32(tempbuf+4, (i + 3)>>2);
7255 DoOutputDirect(tempbuf, 8);
7256 DoOutputDirect(hunkname, i);
7257 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
7259 data = tempbuf+8; /* we need HUNK_PPC_CODE + size at start */
7261 if(ap->Flags & AMIPRAGFLAG_PPC2)
7263 EndPutM32Inc(data, 0x90410014); /* stw r2,20(r1) */
7264 /* mflr r0 = mfspr r0,8 = get link register */
7265 EndPutM32Inc(data, 0x7C0802A6);
7266 EndPutM32Inc(data, 0x90010010); /* stw r0,16(r1) */
7267 basepos = data;
7268 EndPutM32Inc(data, 0x80420000); /* lwz r2,BaseName(r2) */
7269 EndPutM32Inc(data, 0x80030000-(ap->Bias-2));/* lwz r0,-ap->Bias-2(r2) */
7270 /* mtlr r0 = mtspr 8,r0 = restore link register */
7271 EndPutM32Inc(data, 0x7C0803A6);
7272 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7273 EndPutM32Inc(data, 0x80010010); /* lwz r0,16(r1) */
7274 EndPutM32Inc(data, 0x80410014); /* lwz r2,20(r1) */
7275 /* mtlr r0 = mtspr 8,r0 = restore link register */
7276 EndPutM32Inc(data, 0x7C0803A6);
7277 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7279 else if(ap->Flags & AMIPRAGFLAG_PPC0)
7281 basepos = data;
7282 /* mflr r0 = mfspr r0,8 = get link register */
7283 EndPutM32Inc(data, 0x7C0802A6);
7284 if((flags & FUNCFLAG_TAG) && ap->NumArgs>0)
7286 EndPutM32Inc(data, 0x90010000 + (((uint32)ap->NumArgs+2) << 21) +
7287 (uint32)(20+ap->NumArgs*4)); /* stw rN,d(r1) */
7288 EndPutM32Inc(data, 0x38010000 + (((uint32)ap->NumArgs+2) << 21) +
7289 (uint32)(20+ap->NumArgs*4)); /* addi rN,r1,d */
7291 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7292 EndPutM32Inc(data, 0x9421FFCE); /* stwu r1,-32(r1) */
7293 EndPutM32Inc(data, 0x81620000); /* lwz r11,BaseName(r2) */
7294 EndPutM32Inc(data, 0x800C0000-(ap->Bias-2));/* lwz r0,-ap->Bias-2(r11) */
7295 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7296 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7297 EndPutM32Inc(data, 0x80010028); /* lwz r0,40(r1) */
7298 EndPutM32Inc(data, 0x38210020); /* addi r1,r1,32 */
7299 /* mtlr r0 = mtspr 8,r0 = restore link register */
7300 EndPutM32Inc(data, 0x7C0803A6);
7301 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7303 else if(ap->Flags & AMIPRAGFLAG_PPC)
7305 count = ap->NumArgs;
7306 if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
7308 /* init stack frame */
7309 i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
7310 /* mflr r0 = mfspr r0,8 = get link register */
7311 EndPutM32Inc(data, 0x7C0802A6);
7312 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7313 EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
7315 if(count > 8)
7317 /* extra arguments must be passed on the stack */
7318 k = 32-(count-8); /* firstreg */
7319 /* stmw rk,X(r1) */
7320 EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-8)*4));
7321 EndPutM32Inc(data, 0xB8010000 + (k << 21) + (i+56)); /* lmw rk,Y(r1) */
7322 if(flags & FUNCFLAG_TAG)
7323 EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4)); /* addi r31,r1,X */
7324 EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
7326 else if(flags & FUNCFLAG_TAG)
7328 /* addi rX,r1,Y */
7329 EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4));
7330 --count;
7333 else /* Args must be shifted! */
7335 /* init stack frame */
7336 i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
7337 /* mflr r0 = mfspr r0,8 = get link register */
7338 EndPutM32Inc(data, 0x7C0802A6);
7339 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7340 EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
7342 if(count > 7)
7344 /* extra arguments must be passed on the stack */
7345 if(count == 8)
7347 /* special case: move 8th argument into stack frame */
7348 if(flags & FUNCFLAG_TAG)
7349 EndPutM32Inc(data, 0x39410000 + (i+20+count*4)); /* addi r10,r1,X */
7350 EndPutM32Inc(data, 0x91410038); /* stw r10,56(r1) */
7352 else
7354 k = 32-(count-7); /* firstreg */
7356 /* stmw rk,X(r1) */
7357 EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-7)*4));
7358 /* mr rk,r10 = or rk,r10,r10 */
7359 EndPutM32Inc(data, 0x7D405378 + (k<<16));
7360 /* lmw rk,Y(r1) */
7361 EndPutM32Inc(data, 0xB8010000 + ((k+1) << 21) + (i+56));
7362 if(flags & FUNCFLAG_TAG)
7364 /* addi r31,r1,X */
7365 EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4));
7367 EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
7370 else if(flags & FUNCFLAG_TAG)
7372 /* addi rX,r1,Y */
7373 EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4));
7374 --count;
7377 /* shift all arguments into their following register */
7378 for(k=(count<8)?count:7; k > 0; --k)
7379 EndPutM32Inc(data, 0x7C000378 + ((3+k)<<16) + ((2+k)<<21) + ((2+k)<<11)); /* mr rX,rY = or rX,rY,rY */
7381 /* load library base and LVO, then call LVO via LR */
7382 basepos = data;
7383 EndPutM32Inc(data, 0x80620000); /* lwz r3,BaseName(r2) */
7385 /* call LVO */
7386 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7387 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7388 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7391 /* cleanup stack frame and return */
7392 if(count > 8)
7394 k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
7395 EndPutM32Inc(data, 0xB8010000 + ((32-(count-k))<<21) + (56+(count-k)*4)); /* lmw rX,Y(r1) */
7397 EndPutM32Inc(data, 0x38210000 + i); /* addi r1,r1,i */
7398 EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) */
7399 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7400 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7402 else
7404 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7405 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7406 EndPutM32Inc(data, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7408 EndPutM32Inc(data, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7409 EndPutM32Inc(data, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7410 EndPutM32Inc(data, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7411 EndPutM32Inc(data, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7413 if(Flags & FLAG_WOSLIBBASE)
7415 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7416 EndPutM32Inc(data, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7417 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7418 EndPutM32Inc(data, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7420 else if(!BaseName)
7422 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7423 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7425 else
7427 basepos = data;
7428 EndPutM32Inc(data, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7429 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7430 EndPutM32Inc(data, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7431 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7432 EndPutM32Inc(data, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7435 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
7436 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
7437 for(i = 0; i < k; ++i)
7439 j = 0x34+4*ap->Args[i].ArgReg; /* PP_Regs offset */
7440 if(i + ofs <= 7)
7442 if(ap->Args[i].ArgReg == REG_A6)
7443 EndPutM32Inc(data, 0x90010020 + ((i+3+ofs)<<21)); /* stw rX,0x20(r1) */
7444 EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
7446 else
7448 EndPutM32Inc(data, 0x81610000 + ((i+1+ofs)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7449 if(ap->Args[i].ArgReg == REG_A6)
7450 EndPutM32Inc(data, 0x91610020); /* stw r11,0x20(r1) */
7451 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
7454 if(flags & FUNCFLAG_TAG)
7456 j = (ap->NumArgs+ofs)*4+0xC4;
7458 if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
7459 EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
7460 EndPutM32Inc(data, 0x39610000 + j); /* addi r11,r1,j */
7461 EndPutM32Inc(data, 0x91610000 + (0x34+4*ap->Args[i].ArgReg)); /* stw r11,X(r1) */
7464 if(!(Flags & FLAG_WOSLIBBASE))
7466 pbasepos = data; /* store 16BIT reloc offset */
7467 EndPutM32Inc(data, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7469 EndPutM32Inc(data, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7470 EndPutM32Inc(data, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7471 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7472 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7473 EndPutM32Inc(data, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7474 EndPutM32Inc(data, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7475 EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) = get old link register */
7476 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7477 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump back */
7480 EndPutM32(tempbuf, HUNK_PPC_CODE);
7481 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
7482 DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
7484 EndPutM32(tempbuf, HUNK_EXT);
7485 DoOutputDirect(tempbuf,4);
7487 /* here come the XDEF name references */
7489 if(Flags & FLAG_WOSLIBBASE)
7491 if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
7492 OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
7493 OutputXDEF(0, "__%s", name);
7495 else
7497 if(BaseName)
7498 OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
7499 if(!(ap->Flags & AMIPRAGFLAG_PPC))
7500 OutputXREF((pbasepos-tempbuf-8)+2, EXT_DEXT16, "_PowerPCBase");
7501 OutputXDEF(0, "_%s", name);
7503 EndPutM32(tempbuf, 0);
7504 DoOutputDirect(tempbuf,4);
7505 if(!(Flags & FLAG_NOSYMBOL))
7507 EndPutM32(tempbuf, HUNK_SYMBOL);
7508 DoOutputDirect(tempbuf,4);
7509 if(Flags & FLAG_WOSLIBBASE)
7510 OutputSYMBOL(0, "__%s", name);
7511 else
7512 OutputSYMBOL(0, "_%s", name);
7513 EndPutM32(tempbuf, 0);
7514 DoOutputDirect(tempbuf,4);
7516 EndPutM32(tempbuf, HUNK_END);
7518 return DoOutputDirect(tempbuf,4);
7521 uint32 FuncVBCCPUPText(struct AmiPragma *ap, uint32 flags, strptr name)
7523 int32 i;
7525 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7526 return 1;
7528 Flags |= FLAG_DONE;
7530 if(Flags & FLAG_SINGLEFILE)
7532 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7534 if(HEADER)
7536 DoOutput("\n");
7537 DoOutputDirect(HEADER, headersize);
7541 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
7542 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
7544 if(Flags & FLAG_SINGLEFILE)
7545 DoOutput("\t.file\t\"%s.o\"\n", name);
7546 if(BaseName)
7547 DoOutput("\t.global %s\n", BaseName);
7548 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7549 "\t.align\t3\n%s:\n",name, name);
7551 if(flags & FUNCFLAG_TAG)
7553 /* Hack the stack-frame for varargs.
7554 Build stack-frame, but save LR in our own stack-frame,
7555 because we have to overwrite the lower 8 bytes of the
7556 caller's frame. */
7557 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7558 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7560 /* Save the caller's saved SP in our own stack-frame. */
7561 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix,
7562 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7564 /* Store r3-r8 at the top of our stack-frame and r9-r10
7565 at the low 8 bytes of the caller's frame. This way all
7566 arguments will reside in one continuous area. */
7567 for(i=3+ap->NumArgs-1; i <= 10; ++i)
7568 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i, 104+4*(i-3),
7569 PPCRegPrefix);
7571 else
7572 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7573 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7575 for(i = 0; i < ap->NumArgs; ++i)
7577 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
7579 if(i <= 7)
7580 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
7581 else
7582 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
7583 100+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
7585 else
7586 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix,
7587 PPCRegPrefix, 100+ap->NumArgs*4, PPCRegPrefix);
7588 DoOutput("%d(%s1)\n", 36+4*ap->Args[i].ArgReg, PPCRegPrefix);
7591 /* Now place the real function call */
7592 /* store offset in Chaos->caos_Un.Offset */
7593 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7594 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix,
7595 ap->Bias, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7596 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7597 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7599 if(BaseName)
7601 if(Flags & FLAG_SMALLDATA)
7602 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName,
7603 PPCRegPrefix);
7604 else
7605 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix,
7606 BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
7607 /* store basepointer in A6 */
7608 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7611 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix, PPCRegPrefix);
7612 if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
7613 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7614 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7615 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7616 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7617 else
7618 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7619 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7621 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name,
7622 name, name);
7625 uint32 FuncVBCCPUPCode(struct AmiPragma *ap, uint32 flags, strptr name)
7627 int32 i, j=0, k, size;
7628 uint8 *data, *data2, *data3;
7629 struct ArHeader *arh;
7631 data = tempbuf;
7633 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7634 return 1;
7636 Flags |= FLAG_DONE;
7638 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7639 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7640 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7641 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7642 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
7643 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
7644 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
7645 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7646 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7647 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7648 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
7649 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
7650 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
7651 EndPutM32Inc(data, 0); /* eeh->e_entry */
7652 EndPutM32Inc(data, 0); /* eeh->e_phoff */
7653 data2 = data; data += 4;
7654 EndPutM32Inc(data, 0); /* eeh->e_flags */
7655 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
7656 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
7657 EndPutM16Inc(data, 0); /* eeh->e_phnum */
7658 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
7659 EndPutM16Inc(data, 6); /* eeh->e_shnum */
7660 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
7662 data3 = data;
7663 if(flags & FUNCFLAG_TAG)
7665 /* Hack the stack-frame for varargs.
7666 Build stack-frame, but save LR in our own stack-frame,
7667 because we have to overwrite the lower 8 bytes of the
7668 caller's frame. */
7669 EndPutM32Inc(data, 0x9421FF80); /* stwu r1,-128(r1) */
7670 EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7671 EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
7673 /* Save the caller's saved SP in our own stack-frame. */
7674 EndPutM32Inc(data, 0x81610080); /* lwz r11,128(r1) */
7675 EndPutM32Inc(data, 0x91610060); /* stw r11,96(r1) */
7677 /* Store r3-r8 at the top of our stack-frame and r9-r10
7678 at the low 8 bytes of the caller's frame. This way all
7679 arguments will reside in one continuous area. */
7680 for(i=3+ap->NumArgs-1; i <= 10; ++i)
7681 EndPutM32Inc(data, 0x90010000 + (i<<21) + (104+4*(i-3))); /* stw rX,Y(r1) */
7683 else
7685 EndPutM32Inc(data, 0x9421FFA0); /* stwu r1,-96(r1) */
7686 EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7687 EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
7690 for(i = 0; i < ap->NumArgs; ++i)
7692 j = 36+4*ap->Args[i].ArgReg;
7693 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
7695 if(i <= 7)
7697 EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j); /* stw rX,j(r1) */
7699 else
7701 EndPutM32Inc(data, 0x81610000 + (100+(i+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7702 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
7705 else
7707 EndPutM32Inc(data, 0x39610000 + (100+ap->NumArgs*4)); /* addi r11,r1,X */
7708 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,X(r1) */
7712 /* Now place the real function call */
7713 EndPutM32Inc(data, 0x39610000 - ap->Bias); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7714 EndPutM32Inc(data, 0x91610008); /* stw r11,8(r1) */
7715 EndPutM32Inc(data, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7716 EndPutM32Inc(data, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7717 EndPutM32Inc(data, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7719 if(BaseName)
7721 if(Flags & FLAG_SMALLDATA)
7723 j = (data-data3)+2; /* store reloc offset */
7724 EndPutM32Inc(data, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7726 else
7728 j = (data-data3)+2; /* store reloc offset */
7729 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7730 EndPutM32Inc(data, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7732 EndPutM32Inc(data, 0x9161005C); /* stw r11,92(r1) */
7735 EndPutM32Inc(data, 0x38610008); /* addi r3,r1,8 */
7736 k = (data-data3); /* store reloc offset */
7737 EndPutM32Inc(data, 0x48000001); /* bl PPCCallOS */
7738 if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
7740 EndPutM32Inc(data, 0x81610060); /* lwz r11,96(r1) */
7741 EndPutM32Inc(data, 0x91610080); /* stw r11,128(r1) */
7742 EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
7743 EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7744 EndPutM32Inc(data, 0x38210080); /* addi r1,r1,128 */
7746 else
7748 EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
7749 EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7750 EndPutM32Inc(data, 0x38210060); /* addi r1,r1,96 */
7753 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
7755 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7756 data += 44; /* 1 9 17 27 33 */
7758 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
7759 data2 = data-44;
7761 EndPutM32Inc(data, 0); /* esh[0].sh_name */
7762 EndPutM32Inc(data, 0); /* esh[0].sh_type */
7763 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
7764 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
7765 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
7766 EndPutM32Inc(data, 0); /* esh[0].sh_size */
7767 EndPutM32Inc(data, 0); /* esh[0].sh_link */
7768 EndPutM32Inc(data, 0); /* esh[0].sh_info */
7769 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
7770 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
7772 size = data2-data3;
7773 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
7774 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
7775 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
7776 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
7777 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
7778 EndPutM32Inc(data, size); /* esh[1].sh_size */
7779 EndPutM32Inc(data, 0); /* esh[1].sh_link */
7780 EndPutM32Inc(data, 0); /* esh[1].sh_info */
7781 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
7782 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
7784 data3 = data;
7785 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
7786 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
7787 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
7788 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
7789 data += 4; /* esh[2].sh_offset */
7790 data += 4; /* esh[2].sh_size */
7791 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7792 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
7793 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
7794 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7796 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
7797 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
7798 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
7799 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
7800 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
7801 EndPutM32Inc(data, 44); /* esh[3].sh_size */
7802 EndPutM32Inc(data, 0); /* esh[3].sh_link */
7803 EndPutM32Inc(data, 0); /* esh[3].sh_info */
7804 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
7805 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
7807 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
7808 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
7809 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
7810 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
7811 data += 4; /* esh[4].sh_offset */
7812 data += 4; /* esh[4].sh_size */
7813 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
7814 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7815 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
7816 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7818 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
7819 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
7820 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
7821 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
7822 data += 4; /* esh[0].sh_offset */
7823 data += 4; /* esh[0].sh_size */
7824 EndPutM32Inc(data, 0); /* esh[0].sh_link */
7825 EndPutM32Inc(data, 0); /* esh[0].sh_info */
7826 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
7827 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
7829 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
7830 EndPutM32(data3+(2*40)+(5*4), BaseName ? 6*16 : 5*16); /* esh[4].sh_size */
7832 data2 = data;
7833 data += BaseName ? 6*16 : 5*16;
7835 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
7837 i = 0;
7838 EndPutM32Inc(data2, i); /* esym[0].st_name */
7839 EndPutM32Inc(data2, 0); /* esym[0].st_value */
7840 EndPutM32Inc(data2, 0); /* esym[0].st_size */
7841 *(data2++) = 0; /* esym[0].st_info */
7842 *(data2++) = 0; /* esym[0].st_other */
7843 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
7844 data[0] = 0;
7846 i += 1;
7847 EndPutM32Inc(data2, i); /* esym[1].st_name */
7848 EndPutM32Inc(data2, 0); /* esym[1].st_value */
7849 EndPutM32Inc(data2, 0); /* esym[1].st_size */
7850 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
7851 *(data2++) = 0; /* esym[1].st_other */
7852 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
7854 sprintf((strptr)data+i, "%s.o", name); while(data[i]) { i++;} ; /* get next store space */
7855 EndPutM32Inc(data2, 0); /* esym[2].st_name */
7856 EndPutM32Inc(data2, 0); /* esym[2].st_value */
7857 EndPutM32Inc(data2, 0); /* esym[2].st_size */
7858 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
7859 *(data2++) = 0; /* esym[2].st_other */
7860 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
7862 EndPutM32Inc(data2, i); /* esym[3].st_name */
7863 EndPutM32Inc(data2, 0); /* esym[3].st_value */
7864 EndPutM32Inc(data2, size); /* esym[3].st_size */
7865 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
7866 *(data2++) = 0; /* esym[3].st_other */
7867 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
7869 sprintf((strptr)data+i, "%s", name); while(data[i]) { i++;} ; /* get next store space */
7870 EndPutM32Inc(data2, i); /* esym[4].st_name */
7871 EndPutM32Inc(data2, 0); /* esym[4].st_value */
7872 EndPutM32Inc(data2, 0); /* esym[4].st_size */
7873 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
7874 *(data2++) = 0; /* esym[4].st_other */
7875 EndPutM16Inc(data2, 0); /* esym[4].st_shndx */
7877 sprintf((strptr)data+i, "PPCCallOS"); while(data[i]) { i++;} ; /* get next store space */
7878 if(BaseName)
7880 EndPutM32Inc(data2, i); /* esym[5].st_name */
7881 EndPutM32Inc(data2, 0); /* esym[5].st_value */
7882 EndPutM32Inc(data2, 0); /* esym[5].st_size */
7883 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[5].st_info */
7884 *(data2++) = 0; /* esym[5].st_other */
7885 EndPutM16/*Inc*/(data2, 0); /* esym[5].st_shndx */
7887 sprintf((strptr)data+i, "%s", BaseName); while(data[i]) { i++;} ; /* get next store space */
7889 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
7890 while(i&3) /* long aligned */
7891 data[i++] = 0;
7892 data += i;
7894 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
7896 data2 = data;
7898 EndPutM32Inc(data, k); /* erel[0].r_offset */
7899 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_REL24)); /* erel[0].r_info - entry 4, type 10 */
7900 EndPutM32Inc(data, 0); /* erel[0].r_addend */
7902 if(BaseName)
7904 if(Flags & FLAG_SMALLDATA)
7906 EndPutM32Inc(data, j); /* erel[1].r_offset */
7907 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_SDAREL16)); /* erel[1].r_info - entry 5, type 32 */
7908 EndPutM32Inc(data, 0); /* erel[1].r_addend */
7910 else
7912 EndPutM32Inc(data, j); /* erel[1].r_offset */
7913 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_HA)); /* erel[1].r_info - entry 5, type 6 */
7914 EndPutM32Inc(data, 0); /* erel[1].r_addend */
7915 EndPutM32Inc(data, j+4); /* erel[2].r_offset */
7916 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_LO)); /* erel[2].r_info - entry 5, type 4 */
7917 EndPutM32Inc(data, 0); /* erel[2].r_addend */
7920 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
7922 /* make ar header and store all */
7923 arh = (struct ArHeader *) (data+20);
7924 memset(arh, ' ', sizeof(struct ArHeader));
7926 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
7927 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
7928 arh->ar_mode[2] = '0';
7929 arh->ar_mode[0] = '6';
7930 arh->ar_fmag[0] = 96;
7931 arh->ar_fmag[1] = '\n';
7933 if((k = strlen(name) + 2) >= 16)
7935 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
7937 else
7939 k = 0;
7940 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
7943 j = k + (data-tempbuf);
7944 for(i = 9; j; --i) /* make decimal number */
7946 data[i] = (j%10)+'0';
7947 j /= 10;
7949 for(j = 0; i < 9; ++j)
7950 arh->ar_size[j] = data[++i];
7952 DoOutputDirect(arh, sizeof(struct ArHeader));
7954 if(k)
7956 DoOutput("%s.o", name);
7957 if(k & 1)
7958 *(data++) = 0x0A; /* alignment byte! */
7961 return DoOutputDirect(tempbuf, data-tempbuf);
7964 uint32 FuncVBCCMorphText(struct AmiPragma *ap, uint32 flags, strptr name)
7966 int32 i, nrcopyar = 0, stcksize = 16, basereg = 12;
7968 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7969 return 1;
7971 Flags |= FLAG_DONE;
7973 if(Flags & FLAG_SINGLEFILE)
7975 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7977 if(HEADER)
7979 DoOutput("\n");
7980 DoOutputDirect(HEADER, headersize);
7984 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
7985 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
7987 if(Flags & FLAG_SINGLEFILE)
7988 DoOutput("\t.file\t\"%s.o\"\n", name);
7989 if(BaseName)
7990 DoOutput("\t.global %s\n", BaseName);
7991 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name, name);
7993 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
7995 if(Flags & FLAG_SMALLDATA)
7996 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
7997 PPCRegPrefix, BaseName, PPCRegPrefix);
7998 else
7999 DoOutput("\tlis\t%s11,%s@ha\n"
8000 "\tlwz\t%s12,%s@l(%s11)\n",
8001 PPCRegPrefix, BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
8003 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
8004 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
8007 else
8009 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8011 if(flags & FUNCFLAG_TAG)
8013 DoOutput(
8014 "\tmflr\t%s0\n"
8015 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8016 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8017 "\tstw\t%s0,4(%s1)\n"
8018 "\tsub\t%s11,%s1,%s12\n"
8019 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8020 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8021 "\tsrwi\t%s12,%s12,2\n"
8022 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8023 "\taddi\t%s12,%s1,4\n"
8024 "\tmr\t%s1,%s11\n" /* new stack frame */
8025 "\taddi\t%s11,%s11,8\n"
8026 "\tmtctr\t%s0\n"
8027 ".copyloop_%s:\n"
8028 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8029 "\tstwu\t%s0,4(%s11)\n"
8030 "\tbdnz\t.copyloop_%s\n"
8031 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8032 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8033 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8034 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8035 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8036 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8037 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8038 PPCRegPrefix, PPCRegPrefix, name,
8039 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8040 name, PPCRegPrefix, PPCRegPrefix);
8042 else if(ap->NumArgs >= 8)
8044 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8045 DoOutput(
8046 "\tmflr\t%s0\n"
8047 "\tstwu\t%s1,-%ld(%s1)\n"
8048 "\tstw\t%s0,%ld(%s1)\n",
8049 PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix,
8050 PPCRegPrefix, stcksize+4, PPCRegPrefix);
8052 basereg = 3;
8054 else if(flags & FUNCFLAG_TAG)
8056 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8057 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8059 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8060 || ap->NumArgs >= 8))
8062 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8063 "\tmflr\t%s0\n",
8064 PPCRegPrefix, stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix);
8067 if(nrcopyar)
8069 /* Hack the stack-frame for varargs.
8070 Build stack-frame, but save LR in our own stack-frame,
8071 because we have to overwrite the lower 8 bytes of the
8072 caller's frame. */
8073 /* Save the caller's saved SP in our own stack-frame. */
8074 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix,
8075 stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix);
8077 /* Store r3-r8 at the top of our stack-frame and r9-r10
8078 at the low 8 bytes of the caller's frame. This way all
8079 arguments will reside in one continuous area.
8080 Only copy the really relevant parts. */
8081 for(i = 10; i > 10-nrcopyar; --i)
8082 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i,
8083 stcksize+4*(i-1+nrcopyar-8),PPCRegPrefix);
8086 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8088 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8090 for(i = ap->NumArgs-1; i; --i)
8092 if(i < 7)
8094 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix, 3+i, PPCRegPrefix,
8095 3+i-1);
8097 else if(i == 7)
8099 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix, PPCRegPrefix);
8101 else
8103 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8104 PPCRegPrefix, stcksize+((i-8)+3)*4, PPCRegPrefix, PPCRegPrefix,
8105 ((i-8)+3)*4, PPCRegPrefix);
8109 else
8111 /* shift all the arguments one field */
8112 for(i = ap->NumArgs+3; i > 3; --i)
8114 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix, i, PPCRegPrefix, i-1);
8119 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8120 || ap->NumArgs >= 8))
8121 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix, stcksize+4, PPCRegPrefix);
8123 if(BaseName)
8125 if(Flags & FLAG_SMALLDATA)
8126 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix, basereg,
8127 BaseName, PPCRegPrefix);
8128 else
8129 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8130 PPCRegPrefix, basereg, BaseName, PPCRegPrefix, basereg, BaseName,
8131 PPCRegPrefix, basereg);
8134 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8136 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8137 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
8139 else
8141 for(i = 0; i < ap->NumArgs; ++i)
8143 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8145 if(i <= 7)
8146 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
8147 else
8148 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
8149 stcksize+(i+2-8)*4, PPCRegPrefix, PPCRegPrefix);
8151 else
8152 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix,
8153 PPCRegPrefix, stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0),
8154 PPCRegPrefix);
8155 DoOutput("%d(%s2)\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
8158 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8159 PPCRegPrefix, PPCRegPrefix);
8161 /* store basepointer in A6 */
8162 if(BaseName)
8163 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix, PPCRegPrefix);
8165 /* Now place the real function call */
8166 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8167 PPCRegPrefix, ap->Bias);
8169 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix);
8172 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8174 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8175 PPCRegPrefix, stcksize, PPCRegPrefix, PPCRegPrefix,
8176 stcksize+nrcopyar*4,PPCRegPrefix);
8179 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8180 || ap->NumArgs >= 8))
8182 if(ap->NumArgs >= 8)
8184 DoOutput(
8185 "\tlwz\t%s0,%ld(%s1)\n"
8186 "\taddi\t%s1,%s1,%ld\n"
8187 "\tmtlr\t%s0\n",
8188 PPCRegPrefix,stcksize+4,PPCRegPrefix,PPCRegPrefix,PPCRegPrefix,
8189 stcksize,PPCRegPrefix);
8191 else
8193 DoOutput(
8194 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8195 "\tlwz\t%s0,4(%s1)\n"
8196 "\tmtlr\t%s0\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8197 PPCRegPrefix, PPCRegPrefix);
8200 else
8202 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8203 "\taddi\t%s1,%s1,%ld\n"
8204 "\tmtlr\t%s0\n",
8205 PPCRegPrefix, stcksize+4, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8206 stcksize+nrcopyar*4, PPCRegPrefix);
8209 DoOutput("\tblr\n");
8212 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8213 name, name, name);
8216 uint32 FuncVBCCMorphCode(struct AmiPragma *ap, uint32 flags, strptr name)
8218 int32 i, j, k=0, size, nrcopyar = 0, stcksize = 16;
8219 int basereg __attribute__ ((unused)) = 12;
8220 uint8 *data, *data2, *data3;
8221 struct ArHeader *arh;
8223 data = tempbuf;
8225 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
8226 return 1;
8228 Flags |= FLAG_DONE;
8230 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8231 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8232 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8233 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8234 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
8235 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
8236 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
8237 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8238 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8239 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8240 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
8241 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
8242 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
8243 EndPutM32Inc(data, 0); /* eeh->e_entry */
8244 EndPutM32Inc(data, 0); /* eeh->e_phoff */
8245 data2 = data; data += 4;
8246 EndPutM32Inc(data, 0); /* eeh->e_flags */
8247 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
8248 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
8249 EndPutM16Inc(data, 0); /* eeh->e_phnum */
8250 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
8251 EndPutM16Inc(data, 6); /* eeh->e_shnum */
8252 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
8254 data3 = data;
8256 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
8258 if(Flags & FLAG_SMALLDATA)
8260 k = (data-data3)+2; /* store reloc offset */
8261 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8263 else
8265 k = (data-data3)+2; /* store reloc offset */
8266 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8267 EndPutM32Inc(data, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8270 EndPutM32Inc(data, 0x800c0000 - (ap->Bias-2));
8271 EndPutM32Inc(data, 0x7c0903a6); /* mtctr r0 */
8272 EndPutM32Inc(data, 0x4e800420); /* bctr */
8275 else
8277 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8279 if(flags & FUNCFLAG_TAG)
8281 /* mflr r0 = mfspr r0,8 = get link register */
8282 EndPutM32Inc(data, 0x7C0802A6);
8283 /* backchain to next frame: lwz r11,0(r1) */
8284 EndPutM32Inc(data, 0x81610000);
8285 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8286 EndPutM32Inc(data, 0x7D815850);
8287 EndPutM32Inc(data, 0x90010004); /* stw r0,4(r1) */
8288 EndPutM32Inc(data, 0x7D6C0850); /* sub r11,r1,r12 */
8289 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8290 EndPutM32Inc(data, 0x396BFFF0);
8291 EndPutM32Inc(data, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8292 EndPutM32Inc(data, 0x558CF0BE); /* srwi r12,r12,2 */
8293 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8294 EndPutM32Inc(data, 0x380CFFFE);
8295 EndPutM32Inc(data, 0x39810004); /* addi r12,r1,4 */
8296 EndPutM32Inc(data, 0x7D615B78); /* mr r1,r11 - new stack frame */
8297 EndPutM32Inc(data, 0x396B0008); /* addi r11,r11,8 */
8298 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8299 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8300 EndPutM32Inc(data, 0x840C0004);
8301 EndPutM32Inc(data, 0x940B0004); /* stwu r0,4(r11) */
8302 EndPutM32Inc(data, 0x4200FFF8); /* bdnz .l */
8303 /* stw r10,8(r1) - last register into stack */
8304 EndPutM32Inc(data, 0x91410008);
8306 else if(ap->NumArgs >= 8)
8308 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8309 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 */
8310 EndPutM32Inc(data, 0x94220000 - stcksize); /* stwu r1,-X(r1) */
8311 EndPutM32Inc(data, 0x90010000 + stcksize + 4); /* stw r0,Y(r1) */
8313 basereg = 3;
8315 else if(flags & FUNCFLAG_TAG)
8317 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8318 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8321 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8322 || ap->NumArgs >= 8))
8324 EndPutM32Inc(data, 0x94210000+0x10000-(stcksize+nrcopyar*4)); /* stwu r1,-%d(r1) */
8325 /* mflr r0 = mfspr r0,8 = get link register */
8326 EndPutM32Inc(data, 0x7C0802A6);
8329 if(nrcopyar)
8331 /* Hack the stack-frame for varargs.
8332 Build stack-frame, but save LR in our own stack-frame,
8333 because we have to overwrite the lower 8 bytes of the
8334 caller's frame. */
8335 /* Save the caller's saved SP in our own stack-frame. */
8336 EndPutM32Inc(data, 0x81610000+stcksize+nrcopyar*4); /* lwz r11,%d(r1) */
8337 EndPutM32Inc(data, 0x91610000+stcksize); /* stw r11,%d(r1) */
8339 /* Store r3-r8 at the top of our stack-frame and r9-r10
8340 at the low 8 bytes of the caller's frame. This way all
8341 arguments will reside in one continuous area.
8342 Only copy the really relevant parts. */
8343 for(i = 10; i > 10-nrcopyar; --i)
8344 EndPutM32Inc(data, 0x90010000 + (i<<21) + (stcksize+4*(i-1+nrcopyar-8))); /* stw rX,Y(r1) */
8347 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8349 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8351 for(i = ap->NumArgs-1; i; --i)
8353 if(i < 7)
8355 /* mr rX,rY */
8356 EndPutM32Inc(data, 0x7C000378 + ((3+i)<<21) + ((3+i-1)<<16) + ((3+i-1)<<11));
8358 else if(i == 7)
8360 /* stw r10,8(r1) */
8361 EndPutM32Inc(data, 0x91410008);
8363 else
8365 /* lwz r11,X(r1) */
8366 EndPutM32Inc(data, 0x81610000 + (stcksize+((i-8)+3)*4));
8367 EndPutM32Inc(data, 0x91620000 + ((i-8)+3)*4); /* stw r11,j(r1) */
8371 else
8373 /* shift all the arguments one field */
8374 for(i = ap->NumArgs+3; i > 3; --i)
8376 /* mr rX,rY */
8377 EndPutM32Inc(data, 0x7C000378 + (i<<21) + ((i-1)<<16) + ((i-1)<<11));
8382 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8383 || ap->NumArgs >= 8))
8384 EndPutM32Inc(data, 0x90010000+stcksize+4); /* stw r0,%d(r1) */
8386 if(BaseName)
8388 if(Flags & FLAG_SMALLDATA)
8390 k = (data-data3)+2; /* store reloc offset */
8391 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8393 else
8395 k = (data-data3)+2; /* store reloc offset */
8396 EndPutM32Inc(data, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8397 EndPutM32Inc(data, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8401 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8403 /* lwz r0,X(r3) */
8404 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2));
8405 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8406 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8408 else
8410 for(i = 0; i < ap->NumArgs; ++i)
8412 j = 4*ap->Args[i].ArgReg;
8413 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8415 if(i <= 7)
8417 EndPutM32Inc(data, 0x90020000 + ((i+3)<<21) + j); /* stw rX,j(r2) */
8419 else
8421 EndPutM32Inc(data, 0x81610000 + (stcksize+(i+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8422 EndPutM32Inc(data, 0x91620000 + j); /* stw r11,j(r1) */
8425 else
8427 EndPutM32Inc(data, 0x38810000 + (stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0))); /* addi r4,r1,X */
8428 EndPutM32Inc(data, 0x90820000 + j); /* stw r4,X(r2) */
8433 EndPutM32Inc(data, 0x81620064); /* lwz r11,100(r2) */
8435 if(BaseName)
8436 EndPutM32Inc(data, 0x91820038); /* stw r12,56(r2) */
8438 /* Now place the real function call */
8439 EndPutM32Inc(data, 0x38600000 + 0x10000 - ap->Bias); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8441 EndPutM32Inc(data, 0x7D6903A6); /* mtctr r11 */
8442 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8444 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8446 EndPutM32Inc(data, 0x81610000 + stcksize); /* lwz r11,X(r1) */
8447 EndPutM32Inc(data, 0x91610000 + (stcksize+nrcopyar*4)); /* stw r11,Y(r1) */
8450 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8451 || ap->NumArgs >= 8))
8453 if(ap->NumArgs >= 8)
8455 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8456 EndPutM32Inc(data, 0x38210000 + stcksize); /* addi r1,r1,Y */
8457 /* mtlr r0 = mtspr 8,r0 = restore link register */
8458 EndPutM32Inc(data, 0x7C0803A6);
8460 else
8462 /* restore old stack frame: lwz r1,0(r1) */
8463 EndPutM32Inc(data, 0x80210000);
8464 EndPutM32Inc(data, 0x80010004); /* lwz r0,4(r1) */
8465 /* mtlr r0 = mtspr 8,r0 = restore link register */
8466 EndPutM32Inc(data, 0x7C0803A6);
8469 else
8471 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8472 EndPutM32Inc(data, 0x38210000 + (stcksize+nrcopyar*4)); /* addi r1,r1,Y */
8473 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8476 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
8479 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8480 data += 44; /* 1 9 17 27 33 */
8482 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
8483 data2 = data-44;
8485 EndPutM32Inc(data, 0); /* esh[0].sh_name */
8486 EndPutM32Inc(data, 0); /* esh[0].sh_type */
8487 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8488 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8489 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
8490 EndPutM32Inc(data, 0); /* esh[0].sh_size */
8491 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8492 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8493 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
8494 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8496 size = data2-data3;
8497 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
8498 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
8499 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
8500 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
8501 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
8502 EndPutM32Inc(data, size); /* esh[1].sh_size */
8503 EndPutM32Inc(data, 0); /* esh[1].sh_link */
8504 EndPutM32Inc(data, 0); /* esh[1].sh_info */
8505 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
8506 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
8508 data3 = data;
8509 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
8510 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
8511 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
8512 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
8513 data += 4; /* esh[2].sh_offset */
8514 data += 4; /* esh[2].sh_size */
8515 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8516 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
8517 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
8518 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8520 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
8521 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
8522 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
8523 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
8524 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
8525 EndPutM32Inc(data, 44); /* esh[3].sh_size */
8526 EndPutM32Inc(data, 0); /* esh[3].sh_link */
8527 EndPutM32Inc(data, 0); /* esh[3].sh_info */
8528 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
8529 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
8531 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
8532 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
8533 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
8534 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
8535 data += 4; /* esh[4].sh_offset */
8536 data += 4; /* esh[4].sh_size */
8537 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
8538 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8539 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
8540 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8542 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
8543 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
8544 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8545 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8546 data += 4; /* esh[0].sh_offset */
8547 data += 4; /* esh[0].sh_size */
8548 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8549 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8550 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
8551 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8553 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
8554 EndPutM32(data3+(2*40)+(5*4), BaseName ? 5*16 : 4*16); /* esh[4].sh_size */
8556 data2 = data;
8557 data += BaseName ? 5*16 : 4*16;
8559 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
8561 i = 0;
8562 EndPutM32Inc(data2, i); /* esym[0].st_name */
8563 EndPutM32Inc(data2, 0); /* esym[0].st_value */
8564 EndPutM32Inc(data2, 0); /* esym[0].st_size */
8565 *(data2++) = 0; /* esym[0].st_info */
8566 *(data2++) = 0; /* esym[0].st_other */
8567 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
8568 data[0] = 0;
8570 i += 1;
8571 EndPutM32Inc(data2, i); /* esym[1].st_name */
8572 EndPutM32Inc(data2, 0); /* esym[1].st_value */
8573 EndPutM32Inc(data2, 0); /* esym[1].st_size */
8574 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
8575 *(data2++) = 0; /* esym[1].st_other */
8576 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
8578 sprintf((strptr)data+i, "%s.o", name); while(data[i]) { i++;} ; /* get next store space */
8579 EndPutM32Inc(data2, 0); /* esym[2].st_name */
8580 EndPutM32Inc(data2, 0); /* esym[2].st_value */
8581 EndPutM32Inc(data2, 0); /* esym[2].st_size */
8582 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
8583 *(data2++) = 0; /* esym[2].st_other */
8584 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
8586 EndPutM32Inc(data2, i); /* esym[3].st_name */
8587 EndPutM32Inc(data2, 0); /* esym[3].st_value */
8588 EndPutM32Inc(data2, size); /* esym[3].st_size */
8589 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
8590 *(data2++) = 0; /* esym[3].st_other */
8591 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
8593 sprintf((strptr)data+i, "%s", name); while(data[i]) { i++;} ; /* get next store space */
8594 if(BaseName)
8596 EndPutM32Inc(data2, i); /* esym[4].st_name */
8597 EndPutM32Inc(data2, 0); /* esym[4].st_value */
8598 EndPutM32Inc(data2, 0); /* esym[4].st_size */
8599 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
8600 *(data2++) = 0; /* esym[4].st_other */
8601 EndPutM16/*Inc*/(data2, 0); /* esym[4].st_shndx */
8603 sprintf((strptr)data+i, "%s", BaseName); while(data[i]) { i++;} ; /* get next store space */
8605 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
8606 while(i&3) /* long aligned */
8607 data[i++] = 0;
8608 data += i;
8610 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
8612 data2 = data;
8614 if(BaseName)
8616 if(Flags & FLAG_SMALLDATA)
8618 EndPutM32Inc(data, k); /* erel[0].r_offset */
8619 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_SDAREL16)); /* erel[0].r_info - entry 4, type 32 */
8620 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8622 else
8624 EndPutM32Inc(data, k); /* erel[0].r_offset */
8625 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_HA)); /* erel[0].r_info - entry 4, type 6 */
8626 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8627 EndPutM32Inc(data, k+4); /* erel[1].r_offset */
8628 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_LO)); /* erel[1].r_info - entry 4, type 4 */
8629 EndPutM32Inc(data, 0); /* erel[1].r_addend */
8632 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
8634 /* make ar header and store all */
8635 arh = (struct ArHeader *) (data+20);
8636 memset(arh, ' ', sizeof(struct ArHeader));
8638 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
8639 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
8640 arh->ar_mode[2] = '0';
8641 arh->ar_mode[0] = '6';
8642 arh->ar_fmag[0] = 96;
8643 arh->ar_fmag[1] = '\n';
8645 if((k = strlen(name) + 2) >= 16)
8647 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
8649 else
8651 k = 0;
8652 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
8655 j = k + (data-tempbuf);
8656 for(i = 9; j; --i) /* make decimal number */
8658 data[i] = (j%10)+'0';
8659 j /= 10;
8661 for(j = 0; i < 9; ++j)
8662 arh->ar_size[j] = data[++i];
8664 DoOutputDirect(arh, sizeof(struct ArHeader));
8666 if(k)
8668 DoOutput("%s.o", name);
8669 if(k & 1)
8670 *(data++) = 0x0A; /* alignment byte! */
8673 return DoOutputDirect(tempbuf, data-tempbuf);
8676 uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
8678 uint8 i, r;
8680 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
8681 (flags & FUNCFLAG_ALIAS))
8682 return 1;
8684 if(LastBias >= ap->Bias)
8685 DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
8686 else
8688 Flags |= FLAG_DONE; /* We did something */
8690 for(LastBias += BIAS_OFFSET; LastBias < ap->Bias; LastBias += BIAS_OFFSET)
8691 DoOutputDirect("Dum\x10", 4);
8693 DoOutput("%c", toupper(name[0]));
8694 if(name[1])
8696 DoOutput("%c", tolower(name[1]));
8697 if(name[2])
8698 DoOutput("%s", name+2);
8700 if(!ap->NumArgs)
8701 DoOutputDirect("\x10", 1);
8702 else
8704 for(i = 0; i < ap->NumArgs; ++i)
8706 r = ap->Args[i].ArgReg;
8707 DoOutputDirect(&r, 1);
8711 return 1;
8714 uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
8716 int32 i;
8718 Flags |= FLAG_DONE; /* We did something */
8720 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8722 if(Flags & FLAG_ISPRIVATE)
8724 Flags ^= FLAG_ISPRIVATE;
8725 DoOutput("##public\n");
8728 else
8730 if(!(Flags & FLAG_ISPRIVATE))
8731 DoOutput("##private\n");
8732 Flags |= FLAG_ISPRIVATE;
8735 LastBias += BIAS_OFFSET;
8736 if(LastBias != ap->Bias)
8738 DoOutput("##bias %d\n", ap->Bias);
8739 LastBias = ap->Bias;
8742 if(ap->Abi != CurrentABI)
8744 switch(ap->Abi)
8746 case ABI_M68K: DoOutput("##abi M68k\n"); break;
8747 case ABI_PPC0: DoOutput("##abi PPC0\n"); break;
8748 case ABI_PPC2: DoOutput("##abi PPC2\n"); break;
8749 case ABI_PPC: DoOutput("##abi PPC\n"); break;
8751 CurrentABI = ap->Abi;
8754 DoOutput("%s("/*)*/, name);
8755 for(i = 0; i < ap->CallArgs; i++)
8756 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->CallArgs-1 ? "," : "");
8757 DoOutput(/*(*/")("/*)*/);
8759 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8761 for(i = 0; i < ap->CallArgs; i++)
8763 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], i < ap->CallArgs-1 ?
8764 (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg ? "/" : ",") : "");
8767 return DoOutput(/*(*/")\n");
8770 /* called from FuncSFD directly */
8771 uint32 FuncClib(struct AmiPragma *ap, uint32 flags, strptr name)
8773 struct ClibData *cd;
8774 int32 i, s, c;
8776 Flags |= FLAG_DONE; /* We did something */
8778 if(!(cd = GetClibFunc(name, ap, flags)))
8779 return 1;
8781 s = MakeClibType(tempbuf, &cd->ReturnType, 0);
8782 DoOutputDirect(tempbuf, s);
8783 DoOutput(" %s("/*)*/, name);
8785 if(ap->NumArgs)
8787 for(i = 0; i < cd->NumArgs; i++)
8789 c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
8790 if(s+c+2 > 75 && s)
8792 DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
8794 else if(i)
8796 DoOutput(", "); s += 2;
8798 DoOutputDirect(tempbuf, c);
8799 s += c;
8802 else if(Flags2 & FLAG2_CLIBOUT)
8803 DoOutput("void");
8804 return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
8807 uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
8809 struct ClibData *cd;
8810 int32 i, j;
8812 if(!(cd = GetClibFunc(name, ap, flags)))
8813 return 1;
8815 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8817 if(Flags & FLAG_ISPRIVATE)
8819 Flags ^= FLAG_ISPRIVATE;
8820 DoOutput("==public\n");
8823 else
8825 if(!(Flags & FLAG_ISPRIVATE))
8826 DoOutput("==private\n");
8827 Flags |= FLAG_ISPRIVATE;
8830 if(ap->Abi != CurrentABI)
8832 switch(ap->Abi)
8834 case ABI_M68K: DoOutput("==abi M68k\n"); break;
8835 case ABI_PPC0: DoOutput("==abi PPC0\n"); break;
8836 case ABI_PPC2: DoOutput("==abi PPC2\n"); break;
8837 case ABI_PPC: DoOutput("==abi PPC\n"); break;
8839 CurrentABI = ap->Abi;
8842 if(LastBias+BIAS_OFFSET < ap->Bias)
8844 DoOutput("==reserve %ld\n", ((ap->Bias-LastBias)/BIAS_OFFSET)-1);
8845 LastBias = ap->Bias;
8847 else if(flags & FUNCFLAG_TAG)
8848 DoOutput("==varargs\n");
8849 else if((flags & FUNCFLAG_ALIAS) || LastBias == ap->Bias)
8850 DoOutput("==alias\n");
8851 else
8852 LastBias += BIAS_OFFSET;
8854 if(!FuncClib(ap, flags, name))
8855 return 0;
8857 DoOutput(" ("/*)*/);
8858 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8860 strptr s;
8862 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8863 in step one, so the "-" can be placed at proper position. */
8864 for(j = i = 0; i < ap->NumArgs; i++)
8866 if(i == ap->NumArgs-1)
8868 s = ""; j += 2;
8870 else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
8872 s = (j&1) ? "," : "-"; ++j;
8874 else
8876 s = ","; j += 2;
8878 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], s);
8881 return DoOutput(/*(*/")\n");
8884 uint32 FuncOS4PPC(struct AmiPragma *ap, uint32 flags, strptr name)
8886 struct ClibData *cd;
8887 int32 i, noret = 0, registers;
8889 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
8890 return 1;
8892 Flags |= FLAG_DONE; /* We did something */
8894 if(!(cd = GetClibFunc(name, ap, flags)))
8895 return 1;
8897 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
8898 noret = 1; /* this is a void function */
8900 sprintf((strptr)tempbuf, "_%s_%s", GetIFXName(), name);
8901 OutClibType(&cd->ReturnType, (strptr)tempbuf);
8903 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8904 ap->NumArgs ? "," : "");
8905 for(i = 0; i < ap->NumArgs; ++i)
8907 DoOutput(" ");
8908 if(i == ap->NumArgs - 1 && (flags & FUNCFLAG_TAG))
8910 DoOutput("...\n");
8912 else
8914 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
8915 if(i < ap->NumArgs-1)
8916 DoOutput(",\n");
8919 if(flags & FUNCFLAG_TAG)
8921 struct ClibData *cd2;
8923 if(!(cd2 = GetClibFunc(ap->FuncName, ap, flags)))
8924 return 1;
8926 DoOutput(/*(*/")\n{\n"/*}*/
8927 " va_list ap;\n"
8928 " va_startlinear(ap, colorMap);\n"
8929 " ");
8930 if(!noret)
8931 DoOutput("return ");
8932 DoOutput("Self->%s(\n"/*)*/, ap->FuncName);
8933 for(i = 0; i < ap->NumArgs-1; ++i)
8935 DoOutput(" %s,\n", ap->Args[i].ArgName);
8937 DoOutput(" va_getlinearva(ap, "/*)*/);
8938 OutClibType(&cd2->Args[i], 0);
8939 DoOutput(/*((*/"));\n");
8941 else
8943 DoOutput(/*(*/")\n{\n"/*}*/
8944 " struct Library *LibBase = Self->Data.LibBase;\n"
8945 " struct ExecIFace *IExec = (struct ExecIFace *)"
8946 "Self->Data.IExecPrivate;\n");
8948 if(!noret)
8950 DoOutput(" ");
8951 OutClibType(&cd->ReturnType, "retval");
8952 DoOutput(";\n");
8955 DoOutput(
8956 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8957 "->EmuWS);\n");
8958 for(i = 0; i < ap->NumArgs; ++i)
8961 registers = GetRegisterData(ap) | 0x40000002; /* set A6 everytime */
8962 for(i = 0; i <= 15; ++i)
8964 if(registers & (1<< (16+i)))
8965 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames[i], i);
8967 DoOutput("\n ");
8969 if(!noret)
8971 DoOutput("retval = ("/*)*/);
8972 OutClibType(&cd->ReturnType, 0);
8973 DoOutput(/*(*/")");
8976 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
8977 " ET_Offset, -%d,\n"/*)*/,ap->Bias);
8978 for(i = 0; i < ap->NumArgs; ++i)
8980 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper[ap->Args[i].ArgReg],
8981 ap->Args[i].ArgName);
8983 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
8984 for(i = 0; i <= 15; ++i)
8986 if(registers & (1<< (16+i)))
8987 DoOutput(" regs[%ld] = save_%s;\n", i, RegNames[i]);
8990 if(!noret)
8991 DoOutput(" return retval;\n");
8993 return DoOutput(/*{*/"}\n\n");
8996 uint32 FuncOS4M68KCSTUB(struct AmiPragma *ap, uint32 flags, strptr name)
8998 struct ClibData *cd;
8999 int32 i, noret = 0;
9001 if(ap->NumArgs <= 7)
9002 return 1;
9004 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9005 return 1;
9007 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9008 return 1;
9010 Flags |= FLAG_DONE; /* We did something */
9012 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9013 noret = 1; /* this is a void function */
9015 sprintf((strptr)tempbuf, "Cstub_%s", name);
9016 OutClibType(&cd->ReturnType, (strptr)tempbuf);
9018 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9019 " struct ExecIFace *IExec = (struct ExecIFace *)"
9020 "Interface->Data.IExecPrivate;\n"
9021 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9022 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9024 if(!noret)
9025 DoOutput("return ");
9027 DoOutput("Interface->%s(\n"/*)*/,(flags & FUNCFLAG_TAG) ? ap->FuncName
9028 : name);
9029 for(i = 0; i < ap->NumArgs; ++i)
9031 DoOutput(" ("/*)*/);
9032 OutClibType(&cd->Args[i], 0);
9033 DoOutput(/*(*/") regarray[%d]", ap->Args[i].ArgReg);
9034 if(i < ap->NumArgs-1)
9035 DoOutput(",\n");
9037 return DoOutput(/*{(*/");\n}\n\n");
9040 uint32 FuncOS4M68K(struct AmiPragma *ap, uint32 flags, strptr name)
9042 struct ClibData *cd;
9043 int i;
9045 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9046 return 1;
9048 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9049 return 1;
9051 Flags |= FLAG_DONE; /* We did something */
9053 DoOutput(
9054 "\t.section .data\n"
9055 "\t.globl\tstub_%s\n"
9056 "\t.type\tstub_%s,@function\n"
9057 "\n"
9058 "stub_%s:\n"
9059 "\t.short\t0x4ef8\n"
9060 "\t.short 0\n"
9061 "\t.short 1\n"
9062 "\t.globl\tstub_%sPPC\n"
9063 "\t.long\tstub_%sPPC\n",name, name, name, name, name);
9065 if(ap->NumArgs > 7)
9067 Flags2 |= FLAG2_OS4M68KCSTUB;
9068 DoOutput(
9069 "\t.byte\t2\n" /* Rest of parameters in C */
9070 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9071 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9073 else
9075 DoOutput(
9076 "\t.byte\t%d\n" /* Rest of parameters in C */
9077 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9078 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9079 ap->NumArgs+2);
9080 for(i = 0; i < ap->NumArgs; ++i)
9082 DoOutput("\t.byte\t%d,REG68K_%s\n",i+4,
9083 RegNamesUpper[ap->Args[i].ArgReg]);
9086 DoOutput(
9087 "\t.section .text\n"
9088 "\t.align\t2\n"
9089 "\n"
9090 "stub_%sPPC:\n"
9091 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9092 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9093 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9094 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9095 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9096 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9097 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9098 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9099 name, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9100 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9101 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9102 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
9104 if(ap->NumArgs > 7)
9106 /* Since this function has 11 arguments, we need a C stub */
9107 DoOutput(
9108 "\t.globl\tCstub_%s\n"
9109 "\tlis\t%s4,Cstub_%s@h\n"
9110 "\tori\t%s4,%s4,Cstub_%s@l\n"
9111 "\tmtlr\t%s4\n"
9112 "\tblrl\n",
9113 name, PPCRegPrefix, name, PPCRegPrefix, PPCRegPrefix, name, PPCRegPrefix);
9115 else
9117 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name);
9119 DoOutput(
9120 "\tlwz\t%s11,12(%s1)\n"
9121 "\tmtlr\t%s11\n"
9122 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9123 "\tblrl\n" /* Return to emulation */
9124 "\n"
9125 "\t.globl\tstub_%s68K\n"
9126 "\t.long\tstub_%s68K\n"
9127 "\t.byte\t0\n", /* Flags */
9128 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, name,
9129 name);
9131 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9133 DoOutput(
9134 "\t.byte\t1\n" /* One register (a7 only) */
9135 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9137 else
9139 DoOutput(
9140 "\t.byte\t2\n"
9141 "\t.byte\t1,REG68K_A7\n"
9142 "\t.byte\t3,REG68K_D0\n");
9145 return DoOutput(
9146 "\t.section .data\n"
9147 "\t.align\t4\n"
9148 "\n"
9149 "stub_%s68K:\n"
9150 "\t.short\t0x4e75\n" /* RTS */
9151 "\n", name);
9154 uint32 FuncOS4M68KVect(struct AmiPragma *ap, uint32 flags, strptr name)
9156 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9157 return 1;
9159 while(LastBias + BIAS_OFFSET < ap->Bias)
9161 DoOutput("\t.long\tstub_Reserved\n");
9162 LastBias += BIAS_OFFSET;
9164 LastBias = ap->Bias;
9166 return DoOutput("\t.long\tstub_%s\n", name);
9169 uint32 FuncXML(struct AmiPragma *ap, uint32 flags, strptr name)
9171 struct ClibData *cd;
9172 int32 i;
9174 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9175 return 1;
9177 if(flags & FUNCFLAG_ALIAS)
9178 DoError(ERR_ALIASES_NOT_SUPPORTED, ap->Line);
9180 Flags |= FLAG_DONE; /* We did something */
9182 if(!(cd = GetClibFunc(name, ap, flags)))
9183 return 1;
9185 while(LastBias+BIAS_OFFSET < ap->Bias)
9187 LastBias += BIAS_OFFSET;
9188 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9189 " status=\"unimplemented\"/>\n", LastBias);
9191 LastBias = ap->Bias;
9193 DoOutput("\t\t<method name=\"%s\" result=\"", name);
9194 OutClibType(&cd->ReturnType, 0);
9195 DoOutput("\">\n");
9196 for(i = 0; i < ap->NumArgs; ++i)
9198 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9199 i == ap->NumArgs-1 && (flags & FUNCFLAG_TAG) ? "var" : "",
9200 ap->Args[i].ArgName);
9201 OutClibType(&cd->Args[i], 0);
9202 DoOutput("\"/>\n");
9204 return DoOutput("\t\t</method>\n");
9207 uint32 FuncGateStubs(struct AmiPragma *ap, uint32 flags, strptr name)
9209 struct ClibData *cd;
9210 strptr ret = "return ";
9211 int32 i;
9213 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
9214 return 1;
9216 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9217 return 1;
9219 Flags |= FLAG_DONE; /* We did something */
9221 if(flags & FUNCFLAG_ALIAS)
9223 if(flags & FUNCFLAG_TAG)
9224 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9225 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
9227 DoOutput("#define %s("/*)*/, name);
9228 for(i = 0; i < ap->NumArgs-1; ++i)
9229 DoOutput("%s, ", ap->Args[i].ArgName);
9230 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
9231 for(i = 0; i < ap->NumArgs-1; ++i)
9232 DoOutput("(%s), ", ap->Args[i].ArgName);
9233 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
9236 if((flags & FUNCFLAG_TAG))
9238 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9239 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
9240 for(i = 0; i < ap->NumArgs-1; ++i)
9242 DoOutput("%s, ", ap->Args[i].ArgName);
9244 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9245 ap->FuncName);
9246 for(i = 0; i < ap->NumArgs-1; ++i)
9247 DoOutput("(%s), ", ap->Args[i].ArgName);
9248 DoOutput("("/*)*/);
9249 OutClibType(&cd->Args[i], 0);
9250 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9253 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9254 ret = "";
9256 if(!OutClibType(&cd->ReturnType, 0))
9257 return 0;
9259 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix, name);
9261 for(i = 0; i < ap->NumArgs; ++i)
9263 DoOutput(" ");
9264 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
9265 DoOutput(" = ("/*)*/);
9266 OutClibType(&cd->Args[i], 0);
9267 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper[ap->Args[i].ArgReg]);
9268 if((Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB)) && (Flags2 & FLAG2_REGLIB))
9269 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9271 DoOutput(" %s%s%s("/*)*/, ret, subprefix, name);
9272 if(ap->NumArgs)
9274 if(Flags2 & FLAG2_PRELIB)
9276 if(Flags2 & FLAG2_REGLIB)
9277 DoOutput("___RegBase,");
9278 else
9279 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper);
9282 for(i = 0; i < ap->NumArgs-1; ++i)
9284 DoOutput("%s, ", ap->Args[i].ArgName);
9286 if(Flags2 & FLAG2_POSTLIB)
9288 if(Flags2 & FLAG2_REGLIB)
9289 DoOutput("%s, ___RegBase", ap->Args[i].ArgName);
9290 else
9291 DoOutput("%s, %s_BASE_NAME", ap->Args[i].ArgName, ShortBaseNameUpper);
9293 else
9294 DoOutput("%s", ap->Args[i].ArgName);
9296 else
9298 if(Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB))
9300 if(Flags2 & FLAG2_REGLIB)
9301 DoOutput("___RegBase");
9302 else
9303 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
9306 return DoOutput(/*(({*/"));\n}\n");
9309 static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
9311 uint32 res;
9313 if(Flags & FLAG_SINGLEFILE)
9315 sprintf(filename, filenamefmt, name);
9316 if(!OpenDest(filename))
9317 return 0;
9319 res = Func(ap, flags, name);
9320 if(Flags & FLAG_SINGLEFILE)
9322 CloseDest(filename);
9324 return res;
9327 static uint32 PrintComment(struct Comment *com, strptr comment)
9329 if(com->Private && !(Flags & FLAG_PRIVATE))
9330 return 1;
9331 else if((Flags2 & FLAG2_SFDOUT) && com->Version)
9333 return DoOutput("==version %d\n", com->Version);
9335 else if((Flags2 & FLAG2_SFDOUT) && com->ReservedNum)
9337 LastBias += BIAS_OFFSET*com->ReservedNum;
9338 return DoOutput("==reserve %d\n", com->ReservedNum);
9340 else if(!(Flags & FLAG_DOCOMMENT) || !comment)
9341 return 1;
9343 if(com->Data)
9345 if(!DoOutput(comment, com->Data))
9346 return 0;
9348 else if(com->ReservedNum)
9350 string temp[256];
9351 sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
9352 com->ReservedNum == 1 ? "" : "s");
9353 if(!DoOutput(comment, temp))
9354 return 0;
9356 else if(com->Version)
9358 string temp[256];
9359 if(com->Version >= FIRST_KNOWN_RELEASE && com->Version <= LAST_KNOWN_RELEASE &&
9360 (Flags2 & FLAG2_SYSTEMRELEASE))
9361 sprintf(temp, "* --- functions in V%u or higher %s ---", com->Version,
9362 Release[com->Version-FIRST_KNOWN_RELEASE]);
9363 else
9364 sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
9366 if(!DoOutput(comment, temp))
9367 return 0;
9369 return 1;
9372 static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
9374 struct Comment *com;
9375 int32 i;
9376 struct AmiPragma *ap;
9378 com = (struct Comment *) Comment.First;
9380 for(ap = (struct AmiPragma *) AmiPragma.First; ap;
9381 ap = (struct AmiPragma *) ap->List.Next)
9383 if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
9385 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
9387 else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
9389 while(com && com->Bias <= ap->Bias)
9391 if(!PrintComment(com, comment))
9392 return 0;
9393 com = (struct Comment *) com->List.Next;
9394 } /* comment loop */
9396 #ifdef DEBUG_OLD
9397 printf("Processing %s - %s\n", ap->FuncName ? ap->FuncName : "",
9398 ap->TagName ? ap->TagName : "");
9399 #endif
9401 if(tagmode != TAGMODE_TAGS)
9403 if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
9404 return 0;
9406 for(i = 0; i < ap->NumAlias; ++i)
9408 if(ap->AliasName[i]->Type & FUNCFLAG_NORMAL)
9410 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9411 return 0;
9416 if(tagmode)
9418 if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
9419 return 0;
9421 for(i = 0; i < ap->NumAlias; ++i)
9423 if(ap->AliasName[i]->Type & FUNCFLAG_TAG)
9425 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9426 return 0;
9432 while(com)
9434 if(!PrintComment(com, comment))
9435 return 0;
9436 com = (struct Comment *) com->List.Next;
9437 } /* comment loop */
9438 return 1;
9441 static uint32 PrintIncludes(void) /* copies the include lines */
9443 struct Include *inc;
9444 strptr s, s2;
9446 inc = (struct Include *) Includes.First;
9448 while(inc)
9450 s2 = (strptr) tempbuf;
9451 for(s = inc->Include; *s; ++s)
9453 switch(*s)
9455 case '<': *(s2++) = ' '; break;
9456 case '/':
9457 case '.': *(s2++) = '_'; break;
9458 case '>': break;
9459 default: *(s2++) = toupper(*s);
9461 *s2 = 0;
9463 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
9464 inc = (struct Include *) inc->List.Next;
9466 if(!Includes.First)
9467 DoOutput("#include <exec/types.h>\n");
9468 return DoOutput("\n");
9471 /* ------------------------------------------------------------------ */
9473 static int32 AddClibEntry(strptr buffer, strptr bufend, uint32 linenum)
9475 strptr buf = buffer;
9476 struct ClibData d, *f;
9478 memset(&d, 0, sizeof(struct ClibData));
9479 buf = SkipBlanksRet(buf);
9480 if(*buf == '#') /* preprocessor lines */
9482 #ifdef DEBUG_OLD
9483 printf("Found non-function bracket in preprocessor line %ld\n", linenum);
9484 #endif
9485 while(buf < bufend && *buf != '\n')
9486 ++buf;
9487 return buf-buffer;
9489 if(!strnicmp(buf, "ASM", 3))
9490 buf = SkipBlanks(buf+3);
9491 /* else if(!strnicmp(buf, "STACK", 5))
9492 buf = SkipBlanks(buf+5);
9494 else if(!strnicmp(buf, "REGS", 4))
9495 buf = SkipBlanks(buf+4);
9497 if(!strnicmp(buf, "extern", 6))
9499 buf = SkipBlanksRet(buf+6);
9500 if(!strnicmp(buf, "\"C\"", 3)) /* CPP: extern "C" */
9502 buf = SkipBlanksRet(buf+3);
9503 if (*buf == '{')
9505 buf = SkipBlanksRet(buf+1);
9510 if(!GetCPPType(&d.ReturnType, buf, 1, 1))
9512 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE, linenum);
9513 return 0;
9515 else if(d.ReturnType.Unknown)
9516 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE_INT, linenum,
9517 d.ReturnType.Unknown);
9519 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9521 strptr r = d.ReturnType.TypeStart;
9522 while(*r != '('/*)*/) ++r;
9523 r = SkipBlanks(++r); /* the bracket */
9524 d.FuncName = SkipBlanks(++r); /* the asterisk */
9526 else
9527 d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
9528 buf = d.FuncName;
9529 while(*(buf++) != '('/*)*/)
9531 *(SkipName(d.FuncName)) = 0;
9532 if(!(*d.FuncName))
9534 #ifdef DEBUG_OLD
9535 printf("Found non-function bracket in line %ld\n", linenum);
9536 #endif
9537 while(buf < bufend && *buf != '\n')
9538 ++buf;
9539 return buf-buffer;
9541 buf = SkipBlanksRet(buf);
9543 while(*buf != /*(*/')' && buf < bufend)
9545 if(d.NumArgs == MAXREGPPC+1)
9547 DoError(ERROFFSET_CLIB | ERR_TO_MUCH_ARGUMENTS, linenum);
9548 return 0;
9550 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0, 1))
9552 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
9553 return 0;
9555 else if(d.Args[d.NumArgs-1].Unknown)
9556 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE_INT, linenum,
9557 d.NumArgs, d.Args[d.NumArgs-1].Unknown);
9559 buf = d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength;
9560 while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
9561 ++buf;
9562 #ifdef DEBUG
9563 printf("Added argument %d for %s (%d bytes)\n", d.NumArgs, d.FuncName,
9564 d.Args[d.NumArgs-1].FullLength);
9565 #endif
9566 if(*buf == ',')
9567 buf = SkipBlanksRet(++buf);
9570 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9571 d.NumArgs = 0; /* void arguments are no arguments */
9573 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9574 return -1;
9576 memcpy(f, &d, sizeof(struct ClibData));
9578 if(!clibdata)
9579 clibdata = f;
9580 else
9582 struct ClibData *e = clibdata;
9583 while(e->Next)
9584 e = e->Next;
9585 e->Next = f;
9587 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9589 int numclose = 2, numopen = 1;
9590 while(buf < bufend && (numclose || numopen > 0))
9592 if(*buf == '('/*)*/) { ++numclose; --numopen; }
9593 else if(*buf == /*(*/')') --numclose;
9594 ++buf;
9598 #ifdef DEBUG
9599 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9600 f->FuncName, linenum, buf-buffer, f->NumArgs);
9601 #endif
9602 return buf-buffer;
9605 static int32 ScanClibFile(strptr buf, strptr bufend)
9607 strptr linestart = buf;
9608 uint32 linenum = 1;
9609 int added = 0;
9611 /* remove comments and other not so nice characters */
9612 while(buf < bufend)
9614 if(*buf == '\t' || *buf == '\r' || *buf == (string)0xA0)
9615 *(buf++) = ' ';
9616 else if(buf[0] == '/' && buf < bufend-1)
9618 if(buf[1] == '*')
9620 while(buf < bufend-1 && (buf[0] != '*' || buf[1] != '/'))
9622 if(*buf != '\n')
9623 *buf = ' ';
9624 ++buf;
9626 *(buf++) = ' ';
9627 *(buf++) = ' ';
9629 else if(buf[1] == '/')
9631 while(buf < bufend && buf[0] != '\n')
9632 *(buf++) = ' ';
9633 ++buf;
9635 else
9636 ++buf;
9638 else if(buf[0] == '#' && strncmp("#include", buf, 8))
9640 while(buf < bufend && buf[0] != '\n')
9641 *(buf++) = ' ';
9642 ++buf;
9644 else
9645 ++buf;
9648 #ifdef DEBUG_OLD
9649 printf("-----------\n%s-----------\n", linestart);
9650 #endif
9652 buf = linestart;
9653 while(buf < bufend)
9655 if(*buf == '\n')
9657 ++buf; ++linenum;
9658 if(added)
9660 linestart = buf;
9661 added = 0;
9664 else if(!strncmp("#include", buf, 8))
9666 struct Include *d;
9668 if(!(d = (struct Include *) NewItem(&Includes)))
9669 return 0;
9670 d->Include = buf = SkipBlanks(buf+8);
9671 AddItem(&Includes, (struct ShortList *) d);
9672 while(*buf && *buf != '>' && *buf != '\n')
9673 ++buf;
9674 if(*buf == '>')
9675 ++buf;
9676 if(*buf == '\n')
9677 ++linenum;
9678 *(buf++) = 0;
9679 #ifdef DEBUG_OLD
9680 printf("Added Include line %s\n", d->Include);
9681 #endif
9682 added = 1;
9684 else if(*buf == '('/*)*/)
9686 int32 i;
9688 if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
9689 return 0;
9690 else if(!i)
9692 while(buf < bufend && *buf != '\n')
9693 ++buf; /* skip this line */
9695 else
9697 i -= buf-linestart;
9698 while(buf < bufend && i-- > 0)
9700 if(*(buf++) == '\n')
9702 linestart = buf;
9703 ++linenum;
9704 } /* skip this function */
9707 added = 1;
9709 else
9710 ++buf;
9711 } /* while */
9712 return 1;
9715 static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
9717 if(!data || data->Flags || data->Type != type || data->PointerDepth)
9718 return 0;
9719 return type;
9722 static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
9724 uint32 i, j;
9726 for(i = 0; i < MAXREG; ++i)
9728 j = strlen(RegNames[i]);
9729 if(!strnicmp(string, RegNames[i], j))
9731 string += j;
9732 if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
9734 data->Register = i;
9735 data->Flags |= CPP_FLAG_REGISTER;
9736 return j;
9740 return 0;
9743 static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
9745 strptr buf = buffer;
9746 struct ClibData d;
9748 memset(&d, 0, sizeof(struct ClibData));
9749 while(*buf != /*(*/')')
9751 if(d.NumArgs == MAXREGPPC+1)
9752 return 0;
9753 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1, 1))
9754 return 0;
9756 buf += d.Args[d.NumArgs-1].FullLength;
9757 while(*buf != ',' && *buf != /*(*/')')
9758 ++buf;
9759 if(*buf == ',')
9760 buf = SkipBlanksRet(++buf);
9763 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9764 d.NumArgs = 0; /* void arguments are no arguments */
9766 if(d.NumArgs) /* no need to allocate structure for nothing */
9768 if(!(data->FuncPtr = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9769 return 0;
9771 memcpy(data->FuncPtr, &d, sizeof(struct ClibData));
9773 return (uint32) (buf+1-buffer);
9776 /* rettype turns on usage of "extern" specifier */
9777 static int32 GetCPPType(struct CPP_NameType *data, strptr start, uint32 rettype, uint32 small)
9779 uint32 ok = 1, j;
9780 strptr u;
9782 data->Unknown = 0;
9783 data->Replace = 0;
9784 data->TypeStart = start = SkipBlanks(start);
9786 if(!strncmp(start, "REG", 3) && (start[3] == ' ' || start[3] == '\t' || start[3] == '\n' || start[3] == '('/*)*/))
9788 u = SkipBlanksRet(start+3);
9789 if(*u == '('/*)*/)
9791 u = SkipBlanks(u+1);
9792 if((j = CheckRegisterNum(u, data)))
9794 u = SkipBlanks(u+j);
9795 if(*u == ')')
9796 start = SkipBlanks(u+1);
9800 data->TypeStart = start;
9804 start = SkipBlanks((u = start));
9805 if(!strncmp("...",start,3))
9807 data->Type = CPP_TYPE_VARARGS;
9808 data->TypeLength = start+3 - (data->TypeStart);
9809 data->FullLength = data->TypeLength;
9810 return 1;
9812 if(CheckKeyword(start, "const", 5) || CheckKeyword(start, "CONST", 5))
9814 data->Flags |= CPP_FLAG_CONST; start += 5;
9816 else if(rettype && CheckKeyword(start, "extern", 6))
9818 start += 6; /* ignore it */
9820 else if(CheckKeyword(start, "long", 4))
9822 if(data->Flags & CPP_FLAG_LONG)
9823 data->Type = CPP_TYPE_LONGLONG;
9824 else
9825 data->Flags |= CPP_FLAG_LONG;
9827 start += 4;
9829 else if(CheckKeyword(start, "signed", 6))
9830 start += 6;
9831 else if(CheckKeyword(start, "unsigned", 8))
9833 data->Flags |= CPP_FLAG_UNSIGNED; start += 8;
9835 else if(CheckKeyword(start, "register", 8))
9837 data->Flags |= CPP_FLAG_REGISTER; start += 8;
9838 data->Register = UNDEFREGISTER;
9840 else if(CheckKeyword(start, "struct", 6))
9842 start = SkipBlanks(start+6);
9843 data->Flags |= CPP_FLAG_STRUCT;
9844 if(*start == '?') /* ? for external types */
9846 data->StructureLength = 0;
9847 data->StructureName = "";
9848 ++start;
9850 else if(*start == '!') /* ! for typedef types */
9852 data->Flags |= CPP_FLAG_TYPEDEFNAME;
9853 ++start;
9854 /* structure name and length already set */
9856 else
9858 start = SkipName((data->StructureName = start));
9859 data->StructureLength = start-data->StructureName;
9862 else if(CheckKeyword(start, "union", 5))
9864 start = SkipBlanks(start+5);
9865 data->Flags |= CPP_FLAG_UNION;
9866 if(*start != '?') /* ? for external types */
9868 start = SkipName((data->StructureName = start));
9869 data->StructureLength = start-data->StructureName;
9871 else
9873 data->StructureLength = 0;
9874 data->StructureName = "";
9875 ++start;
9878 else if(CheckKeyword(start, "enum", 4))
9880 start = SkipBlanks(start+4);
9881 data->Flags |= CPP_FLAG_ENUM;
9882 if(*start != '?') /* ? for external types */
9884 start = SkipName((data->StructureName = start));
9885 data->StructureLength = start-data->StructureName;
9887 else
9889 data->StructureLength = 0;
9890 data->StructureName = "";
9891 ++start;
9894 else if(*start == '*')
9896 ++start; ++data->PointerDepth;
9898 else if(*start == '[')
9900 data->Flags |= CPP_FLAG_ARRAY;
9901 while(*start && *start != ']')
9902 ++start;
9903 if(*start)
9904 ++start;
9906 else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
9907 start += 2 + j;
9908 else if(!data->Type)
9910 uint32 i;
9912 for(i = 0; CPP_Field[i].Text; ++i)
9914 if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length) &&
9915 (start[CPP_Field[i].Length] == ' ' ||
9916 start[CPP_Field[i].Length] == '\t' ||
9917 start[CPP_Field[i].Length] == '\n' ||
9918 start[CPP_Field[i].Length] == ',' ||
9919 start[CPP_Field[i].Length] == /*(*/')' ||
9920 start[CPP_Field[i].Length] == '('/*)*/ ||
9921 start[CPP_Field[i].Length] == '*'))
9923 start += CPP_Field[i].Length;
9924 data->Type = CPP_Field[i].Type;
9925 data->Flags |= CPP_Field[i].Flags;
9926 if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
9927 ++data->PointerDepth;
9928 break;
9931 if(CPP_Field[i].Text)
9932 continue;
9933 else if(extnames)
9935 struct CPP_ExternNames *a = extnames;
9937 while(a)
9939 i = strlen(a->Type);
9940 if(!strncmp(a->Type, start, i) && !isalnum(start[i]) &&
9941 start[i] != '_')
9943 start += i;
9944 data->StructureName = a->NameType.StructureName;
9945 data->FuncPtr = a->NameType.FuncPtr;
9946 data->StructureLength = a->NameType.StructureLength;
9947 data->PointerDepth += a->NameType.PointerDepth;
9948 data->Type = a->NameType.Type;
9949 data->Flags |= a->NameType.Flags;
9950 data->FuncArgs = a->NameType.FuncArgs;
9951 data->ArgsLength = a->NameType.ArgsLength;
9952 break;
9955 /* check types here */
9956 a = a->Next;
9958 if(a)
9959 continue;
9960 else if((!data->Type) && (!data->Flags))
9962 long size;
9963 struct CPP_Unknown *u;
9965 data->Type = CPP_TYPE_INT;
9966 size = SkipName(start)-start;
9967 for(u = unknown; u && strncmp(u->Unknown, start, size); u = u->Next)
9969 if(!u)
9971 data->Unknown = DupString(start, size);
9972 if((u = (struct CPP_Unknown *) AllocListMem(sizeof(struct CPP_Unknown))))
9974 u->Next = unknown;
9975 u->Unknown = data->Unknown;
9976 unknown = u;
9979 start += size;
9980 continue;
9983 break;
9985 else
9986 break;
9987 }while(1);
9989 if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
9990 u = start;
9992 data->TypeLength = u - (data->TypeStart);
9993 data->FullLength = data->TypeLength;
9995 u = SkipBlanks(u);
9997 if(*u == '('/*)*/)
9999 ok = 0;
10000 u = SkipBlanksRet(++u);
10001 if(*u == '*')
10003 while(*u == '*')
10005 ++data->FuncPointerDepth; ++u;
10007 u = SkipBlanksRet(u);
10008 if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
10010 data->Flags |= CPP_FLAG_CONST; u += 6;
10012 u = SkipBlanksRet(u);
10013 if(*u != /*(*/')')
10014 data->FunctionName = u;
10015 u = SkipBlanksRet(SkipName(u));
10016 if(*u == '('/*)*/)
10018 int numclose = 1;
10019 ++u;
10020 while(*u && numclose)
10022 if(*u == '('/*)*/) ++numclose;
10023 else if(*u == /*(*/')') --numclose;
10024 ++u;
10027 if(*u == /*(*/')')
10029 u = SkipBlanksRet(++u);
10030 if(*u == '('/*)*/)
10032 data->Flags |= CPP_FLAG_FUNCTION;
10034 if((j = ParseFuncPtrArgs(u+1, data)))
10035 ok = 1;
10036 data->FuncArgs = u;
10037 data->ArgsLength = j+1;
10038 data->FullLength = u+data->ArgsLength - (data->TypeStart);
10044 if(data->PointerDepth)
10045 data->Flags |= CPP_FLAG_POINTER;
10047 if(!(Flags2 & FLAG2_SMALLTYPES) && !small)
10049 if(!(data->Flags & (CPP_FLAG_STRPTR|CPP_FLAG_POINTER|CPP_FLAG_ENUM
10050 |CPP_FLAG_STRUCT|CPP_FLAG_UNION|CPP_FLAG_FUNCTION|CPP_FLAG_REGISTER)))
10052 if(data->Type == CPP_TYPE_BYTE || data->Type == CPP_TYPE_WORD || data->Type == CPP_TYPE_INT)
10054 if(data->Flags & CPP_FLAG_UNSIGNED)
10055 data->Replace = "const ULONG";
10056 else
10057 data->Replace = "const LONG";
10058 data->Type = CPP_TYPE_LONG;
10059 if(!(data->Flags & CPP_FLAG_CONST))
10060 data->Replace += 6;
10065 if(!data->Type && (data->Flags & CPP_FLAG_LONG))
10066 data->Type = CPP_TYPE_LONG;
10068 if((!data->Type && !data->Flags) || !ok)
10069 return 0;
10070 return 1;
10073 static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
10075 struct ClibData *d = clibdata;
10077 if(!name)
10079 DoError(ERR_ILLEGAL_INTERNAL_VALUE, 0);
10080 return 0;
10083 while(d && strcmp(name, d->FuncName))
10084 d = d->Next;
10086 if(!d)
10088 if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
10090 DoError(ERR_PROTOTYPE_MISSING, 0, name);
10091 ap->Flags |= AMIPRAGFLAG_NOCLIB;
10094 else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
10095 ap->CallArgs+1 != d->NumArgs))
10097 if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDARGWARN)))
10099 DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
10100 ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
10102 return 0;
10105 return d;
10108 static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
10110 if(!strncmp(string, keyword, size))
10112 string += size;
10113 if(*string == ' ' || *string == '\t' || *string == '\n')
10114 return size;
10116 return 0;
10119 /* return nonzero, when usable, zero, when string already emitted */
10120 static uint32 CopyCPPType(strptr buffer, uint32 pass, struct ClibData *cd,
10121 struct AmiArgs *args)
10123 uint32 ret = 0, reg;
10124 uint32 i, j, k = 0;
10126 /* pass 0: signed strptr, MaxonC++ high args */
10127 /* pass 1: unsigned strptr, MaxonC++ high args */
10128 /* pass 2: signed strptr, StormC++ high args */
10129 /* pass 3: unsigned strptr, StormC++ high args */
10131 for(i = 0; i < cd->NumArgs; ++i)
10133 struct CPP_NameType *nt;
10135 nt = &cd->Args[i];
10137 if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
10138 reg = 1 + args[k].ArgReg;
10139 else if((nt->Flags & CPP_FLAG_REGISTER) && nt->Register != UNDEFREGISTER)
10140 reg = 1 + nt->Register;
10141 else
10142 reg = 0;
10144 if(reg--) /* subtract the added 1 */
10146 *(buffer++) = CPP_TYPE_REGISTER;
10147 if(reg >= 10)
10149 if(pass & 2)
10151 *(buffer++) = reg/10 + '0';
10152 *(buffer++) = reg%10 + '0';
10153 ret |= 2;
10155 else
10156 *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
10158 else
10159 *(buffer++) = reg + '0';
10162 if(nt->Flags & CPP_FLAG_FUNCTION)
10164 for(j = 0; j < nt->FuncPointerDepth; ++j)
10165 *(buffer++) = CPP_TYPE_POINTER;
10166 *(buffer++) = CPP_TYPE_FUNCTION;
10168 for(j = 0; j < nt->PointerDepth; ++j)
10169 *(buffer++) = CPP_TYPE_POINTER;
10170 if(nt->Flags & CPP_FLAG_CONST)
10171 *(buffer++) = CPP_TYPE_CONST;
10172 if(nt->Flags & CPP_FLAG_UNSIGNED)
10173 *(buffer++) = CPP_TYPE_UNSIGNED;
10174 else if((nt->Flags & CPP_FLAG_STRPTR) && (pass & 1))
10176 *(buffer++) = CPP_TYPE_UNSIGNED;
10177 ret |= 1; /* we really use this pass */
10179 if(nt->Flags & CPP_FLAG_ENUM)
10180 *(buffer++) = CPP_TYPE_ENUM;
10181 if(nt->Type)
10182 *(buffer++) = cd->Args[i].Type;
10183 else
10185 uint32 i;
10186 sprintf(buffer, "%02lu", (uint32) nt->StructureLength); buffer += 2;
10187 for(i = 0; i < nt->StructureLength; ++i)
10188 *(buffer++) = nt->StructureName[i];
10190 if(nt->Flags & CPP_FLAG_FUNCTION)
10192 if(nt->FuncPtr)
10194 ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
10195 while(*buffer)
10196 ++buffer; /* skip to the new end */
10198 *(buffer++) = CPP_TYPE_FUNCEND;
10200 ++k;
10201 if(IsCPPType(nt, CPP_TYPE_DOUBLE)) /* double needs 2 registers */
10202 ++k;
10205 *(buffer) = 0;
10207 if(ret != pass)
10208 ret = 0;
10209 if(!pass)
10210 ret = 0x80;
10212 return ret; /* return nozero if this pass should be used */
10215 static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
10217 if(nt->Replace)
10218 DoOutput("%s", nt->Replace);
10219 else
10220 DoOutputDirect(nt->TypeStart, nt->TypeLength);
10221 if(nt->Type != CPP_TYPE_VARARGS)
10223 if(nt->Flags & CPP_FLAG_FUNCTION)
10225 uint32 i;
10226 DoOutput(" ("/*)*/);
10227 for(i = 0; i < nt->FuncPointerDepth; ++i)
10228 DoOutput("*");
10229 if (txt)
10230 DoOutput("%s)", txt);
10231 else
10232 DoOutput(")");
10233 if(nt->FuncArgs)
10234 return DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
10235 else
10236 return DoOutput("()");
10238 else if(txt)
10239 return DoOutput(" %s", txt);
10242 return 1;
10245 static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
10247 strptr a;
10249 a = dest;
10250 if(nt->Replace)
10252 uint32 i;
10253 i = strlen(nt->Replace);
10254 memcpy(a, nt->Replace, i);
10255 a += i;
10257 else
10259 memcpy(a, nt->TypeStart, nt->TypeLength);
10260 a += nt->TypeLength;
10263 if(nt->Type != CPP_TYPE_VARARGS)
10265 if(nt->Flags & CPP_FLAG_FUNCTION)
10267 if (txt)
10268 a += sprintf(a, " (*%s)", txt);
10269 else
10270 a += sprintf(a, " (*)");
10271 if(nt->FuncArgs)
10273 memcpy(a, nt->FuncArgs, nt->ArgsLength);
10274 a += nt->ArgsLength;
10276 else
10277 a += sprintf(a, "()");
10279 else if(txt)
10280 a += sprintf(a, " %s", txt);
10282 return (uint32)(a-dest);
10285 static uint32 OutPASCALType(struct CPP_NameType *t, strptr txt, uint32 ret)
10287 int32 i = t->PointerDepth;
10289 if(t->Flags & CPP_FLAG_CONST)
10290 DoOutput("CONST ");
10291 if(!ret && i == 1 &&
10292 (t->Type == CPP_TYPE_LONG || t->Type == CPP_TYPE_WORD))
10294 DoOutput("VAR "); --i;
10297 DoOutput("%s : ", txt);
10299 if(!i && t->Flags == CPP_FLAG_BOOLEAN)
10300 return DoOutput("BOOLEAN");
10301 else if(i && t->Type == CPP_TYPE_VOID)
10302 return DoOutput("POINTER");
10303 else if(t->Flags & CPP_FLAG_FUNCTION)
10304 return DoOutput("tPROCEDURE");
10306 while(i--)
10307 DoOutput("p");
10309 if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
10311 if(!t->PointerDepth)
10312 DoOutput("t");
10313 return DoOutputDirect(t->StructureName, t->StructureLength);
10316 if(t->Flags & CPP_FLAG_UNSIGNED)
10318 if(t->Type == CPP_TYPE_LONG)
10319 return DoOutput("CARDINAL");
10320 if(t->Type == CPP_TYPE_WORD)
10321 return DoOutput("int16");
10322 if(t->Type == CPP_TYPE_BYTE)
10323 return DoOutput(t->PointerDepth == 1 ? "CHAR" : "int8");
10325 else if(t->Type == CPP_TYPE_WORD)
10326 return DoOutput("INTEGER");
10327 else if(t->Type == CPP_TYPE_BYTE)
10328 return DoOutput("SHORTINT");
10329 return DoOutput("int32INT");
10332 /* ------------------------------------------------------------------ */
10334 static uint32 CallPrag(uint32 tagmode, strptr type, FuncType Func)
10336 if(type)
10337 if((*type && !DoOutput("#if%s\n", type)) ||
10338 !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
10339 (*type && !DoOutput("#endif\n")))
10340 return 0;
10341 return 1;
10344 static uint32 CreatePragmaFile(strptr amicall, strptr libcall, strptr amitags,
10345 strptr libtags, uint32 mode)
10347 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10349 switch(mode)
10351 case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10352 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper,
10353 ShortBaseNameUpper); break;
10354 case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10355 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10356 case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10357 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10358 case PRAGMODE_NONE: break;
10359 default: return 0;
10362 if(HEADER)
10364 DoOutput("\n");
10365 DoOutputDirect(HEADER, headersize);
10368 if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10369 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10370 return 0;
10372 if((Flags & FLAG_EXTERNC) &&
10373 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10374 return 0;
10376 if(Flags & FLAG_GNUPRAG)
10378 DoOutput("#ifdef " TEXT_GNUC "\n#ifdef NO_OBSOLETE\n"
10379 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10380 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName);
10381 Flags |= FLAG_DONE;
10385 !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
10386 !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
10387 return 0;
10389 if(tagfuncs)
10392 !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
10393 !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
10394 return 0;
10397 if((Flags & FLAG_EXTERNC) &&
10398 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10399 return 0;
10401 switch(mode)
10403 case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10404 ShortBaseNameUpper); break;
10405 case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10406 ShortBaseNameUpper); break;
10407 case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10408 ShortBaseNameUpper); break;
10409 case PRAGMODE_NONE: break;
10410 default: return 0;
10412 return Output_Error;
10415 static uint32 CreateCSTUBSFile(void)
10417 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10419 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10420 ShortBaseNameUpper, ShortBaseNameUpper);
10422 if(!clibdata)
10424 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10427 if(HEADER)
10429 DoOutput("\n");
10430 DoOutputDirect(HEADER, headersize);
10433 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10434 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10435 return 0;
10437 if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
10438 return 0;
10440 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10441 ShortBaseNameUpper);
10444 static uint32 CreateLVOFile(uint32 mode)
10446 strptr data = "_LVO_I";
10448 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10450 if(mode == 2 || mode == 4)
10451 data = "_LIB_I";
10453 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10454 ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
10455 (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
10456 (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
10457 !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
10458 !DoOutput("\n\n\t\tENDC\n"))
10459 return 0;
10461 return 1;
10464 static uint32 CreateLVOFilePPC(uint32 mode)
10466 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10468 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10469 ShortBaseNameUpper, ShortBaseNameUpper))
10470 return 0;
10471 if(HEADER)
10473 DoOutput("\n");
10474 DoOutputDirect(HEADER, headersize);
10476 switch(mode)
10478 case 0: CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCXDEF);
10479 case 1: CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVOPPC);
10481 return DoOutput("\n\t.endif\n");
10484 static uint32 CreateAsmStubs(uint32 mode, uint32 callmode)
10486 if(mode == 1 && (Flags2 & FLAG2_AUTOHEADER)) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10488 /* 1 = Text, 2 = Code */
10489 switch(mode)
10491 case 1:
10492 if(HEADER)
10494 DoOutput("\n");
10495 DoOutputDirect(HEADER, headersize);
10498 if(!(Flags & FLAG_ASMSECTION))
10499 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
10500 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
10501 if(!CallFunc(callmode, "\n%s", FuncAsmText))
10502 return 0;
10503 break;
10504 case 2:
10505 if(!CallFunc(callmode, 0, FuncAsmCode))
10506 return 0;
10507 break;
10510 return 1;
10513 static uint32 CreateProtoFile(uint32 Type)
10515 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10517 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
10518 ShortBaseNameUpper);
10520 if(HEADER)
10522 DoOutput("\n");
10523 DoOutputDirect(HEADER, headersize);
10526 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10527 if(Type != 5)
10528 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC ")\n"
10529 "#include <clib/%s_protos.h>\n#endif\n",
10530 ShortBaseNameUpper, ShortBaseName);
10532 if(BaseName)
10534 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10535 if(Type == 7)
10536 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10537 "#endif\n");
10538 DoOutput("%s;\n#endif\n", BaseName);
10541 if(Type != 8)
10543 if(Type >= 6)
10545 DoOutput("\n#ifdef " TEXT_GNUC "\n");
10546 if(Type == 10)
10547 DoOutput("#ifndef __cplusplus\n");
10548 DoOutput("#ifdef __AROS__\n");
10549 DoOutput("#include <defines/%s.h>\n", ShortBaseName);
10550 DoOutput("#else\n");
10551 DoOutput("#include <inline/%s.h>\n", ShortBaseName);
10552 DoOutput("#endif\n");
10553 if(Type == 10)
10554 DoOutput("#endif\n");
10555 if(Type != 7)
10557 if(Type == 9)
10558 DoOutput("#elif defined(" TEXT_VBCC ")\n"
10559 "#include <inline/%s_protos.h>\n#else", ShortBaseName);
10560 else
10561 DoOutput("#elif !defined(" TEXT_VBCC ")");
10564 if(Type == 10)
10565 DoOutput("\n#ifndef __PPC__");
10566 if(Type != 7)
10568 strptr str1 = "pragma", str2 = "lib";
10570 switch(Type)
10572 case 4: str1 = "pragmas"; /* no break; */
10573 case 2: str2 = "pragmas"; break;
10574 case 3: str1 = "pragmas"; break;
10575 case 5: str1 = "local"; str2 = "loc"; break;
10577 DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
10579 if(Type == 10)
10580 DoOutput("#endif\n");
10581 if(Type >= 6)
10582 DoOutput("#endif\n");
10585 Flags |= FLAG_DONE;
10587 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10590 static uint32 CreateLocalData(strptr to, uint32 callmode)
10592 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10594 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10595 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10596 ShortBaseNameUpper, ShortBaseNameUpper);
10598 if(HEADER)
10600 DoOutput("\n");
10601 DoOutputDirect(HEADER, headersize);
10604 DoOutput("\n");
10605 PrintIncludes();
10607 if((Flags & FLAG_EXTERNC) &&
10608 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10609 return 0;
10611 if(!CallFunc(callmode, "/%s */\n", FuncLocText))
10612 return 0;
10614 if((Flags & FLAG_EXTERNC) &&
10615 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10616 return 0;
10618 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper);
10620 sprintf(filename, "%s_loc.lib", ShortBaseName);
10621 if(!CloseDest(to) || !OpenDest(filename))
10622 return 0;
10624 CallFunc(callmode, 0, FuncLocCode);
10626 return CloseDest(filename);
10629 static uint32 CreateInline(uint32 mode, uint32 callmode)
10631 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10633 if(!clibdata)
10635 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10638 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10639 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper,
10640 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10642 if(HEADER)
10644 DoOutput("\n");
10645 DoOutputDirect(HEADER, headersize);
10648 DoOutput("\n");
10650 /* prevent loading of clib-file after inline */
10651 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10652 ShortBaseNameUpper, ShortBaseNameUpper);
10654 if(!mode)
10656 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10657 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10658 "#include <ppcinline/macros.h>\n#endif\n\n");
10659 else
10660 DoOutput("#ifndef __INLINE_MACROS_H\n"
10661 "#include <inline/macros.h>\n#endif\n\n");
10662 Flags |= FLAG_INLINENEW;
10664 else if(mode <= 2)
10666 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10667 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10668 "#include <ppcinline/stubs.h>\n#endif\n\n");
10669 else
10670 DoOutput("#ifndef __INLINE_STUB_H\n"
10671 "#include <inline/stubs.h>\n#endif\n\n");
10672 if(mode == 2)
10673 Flags |= FLAG_INLINESTUB;
10675 else if(mode == 3)
10676 Flags2 |= FLAG2_INLINEMAC;
10678 PrintIncludes();
10680 if((Flags & FLAG_EXTERNC) &&
10681 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10682 return 0;
10684 if(BaseName)
10686 if(mode && mode <= 2)
10688 if(Flags & FLAG_MORPHOS)
10689 DoOutput("#include <emul/emulregs.h>\n");
10690 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10691 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10692 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10693 "#define BASE_PAR_DECL0 void\n#endif\n"
10694 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10695 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10697 else
10698 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10699 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10702 if(mode <= 2)
10704 if(!CallFunc(callmode, "/%s */\n", FuncInline))
10705 return 0;
10707 else if(mode >= 6)
10709 if(mode == 7)
10710 Flags |= FLAG_INLINENEW;
10711 if(!CallFunc(callmode, "/%s */\n", FuncInlineDirect))
10712 return 0;
10714 else
10716 if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
10717 return 0;
10720 if(mode && mode <= 2 && BaseName)
10721 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10722 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper);
10724 if((Flags & FLAG_EXTERNC) &&
10725 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10726 return 0;
10728 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10729 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10732 static uint32 CreateGateStubs(uint32 callmode)
10734 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10736 if(!clibdata)
10738 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10740 if(!prefix[0] && !subprefix[0])
10742 DoError(ERR_PREFIX, 0); return 1;
10745 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10746 ShortBaseNameUpper, ShortBaseNameUpper);
10748 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10749 premacro, ShortBaseName);
10751 if(HEADER)
10753 DoOutput("\n");
10754 DoOutputDirect(HEADER, headersize);
10757 if(BaseName)
10759 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10760 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10761 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10762 "#define BASE_PAR_DECL0 void\n#endif\n"
10763 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10764 "BASE_EXT_DECL0\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10767 DoOutput("\n");
10769 if(!CallFunc(callmode, "/%s */\n", FuncGateStubs))
10770 return 0;
10772 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper);
10775 static uint32 CreateSASPowerUP(uint32 callmode)
10777 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10779 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10780 ShortBaseNameUpper, ShortBaseNameUpper);
10782 if(HEADER)
10784 DoOutput("\n");
10785 DoOutputDirect(HEADER, headersize);
10788 DoOutput("\n#ifdef __GNUC__\n"
10789 "#ifndef _PPCINLINE__%s_H\n"
10790 "#include <ppcinline/%s.h>\n"
10791 "#endif\n"
10792 "#else\n\n"
10793 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10794 "#include <ppclib/interface.h>\n"
10795 "#endif\n\n"
10796 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10797 "#include <gcclib/powerup_protos.h>\n"
10798 "#endif\n\n"
10799 "#ifndef NO_PPCINLINE_STDARG\n"
10800 "#define NO_PPCINLINE_STDARG\n"
10801 "#endif /* SAS-C PPC inlines */\n\n",
10802 ShortBaseNameUpper, ShortBaseName);
10804 if(BaseName)
10806 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10807 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10810 if(!CallFunc(callmode, "/%s */\n", FuncPowerUP))
10811 return 0;
10813 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10814 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper);
10817 static uint32 CreateProtoPowerUP(void)
10819 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10821 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10822 ShortBaseNameUpper, ShortBaseNameUpper);
10824 if(HEADER)
10826 DoOutput("\n");
10827 DoOutputDirect(HEADER, headersize);
10830 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
10832 if(BaseName)
10834 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10835 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10836 "#endif\n%s;\n#endif\n", BaseName);
10839 DoOutput("\n#ifdef " TEXT_GNUC "\n"
10840 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10841 "#else\n#include <inline/%s.h>\n#endif\n"
10842 "#else /* SAS-C */\n"
10843 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10844 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10845 ShortBaseName, ShortBaseName, ShortBaseName, ShortBaseName);
10847 Flags |= FLAG_DONE;
10849 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10852 static uint32 CreateFPCUnit(void)
10855 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT);
10857 if(!clibdata)
10859 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10862 DoOutput("{\n");
10863 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName);
10865 if(HEADER)
10867 DoOutput("\n");
10868 DoOutputDirect(HEADER, headersize);
10871 DoOutput("**********************************************************************}\n\n");
10872 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10873 DoOutput("{$mode objfpc}\n");
10874 DoOutput("{$I useamigasmartlink.inc}\n");
10875 DoOutput("{$ifdef use_amiga_smartlink}\n");
10876 DoOutput(" {$smartlink on}\n");
10877 DoOutput("{$endif use_amiga_smartlink}\n\n");
10879 DoOutput("UNIT %s;\n", ShortBaseNameUpper);
10881 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName, GetBaseTypeLib());
10883 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper,ShortBaseName);
10884 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName);
10885 DoOutput("{$I %s.inc}\n\n",ShortBaseName);
10887 if(!CallFunc(TAGMODE_NORMAL, 0, FuncFPCType))
10888 return 0;
10890 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10891 if(!CallFunc(TAGMODE_TAGS, 0, FuncFPCTypeTags))
10892 return 0;
10894 DoOutput("\n{Here we read how to compile this unit}\n");
10895 DoOutput("{You can remove this include and use a define instead}\n");
10896 DoOutput("{$I useautoopenlib.inc}\n");
10897 DoOutput("{$ifdef use_init_openlib}\n");
10898 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10899 DoOutput("{$endif use_init_openlib}\n");
10900 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10901 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper);
10902 DoOutput("\nIMPLEMENTATION\n\n");
10903 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10904 DoOutput("uses \n");
10905 DoOutput("{$ifndef dont_use_openlib}\n");
10906 DoOutput("msgbox, \n");
10907 DoOutput("{$endif dont_use_openlib}\n");
10908 DoOutput("tagsarray;\n\n");
10910 if(!CallFunc(TAGMODE_NORMAL, "(%s *)\n", FuncFPCUnit))
10911 return 0;
10913 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10914 if(!CallFunc(TAGMODE_TAGS,"(%s *)\n", FuncFPCTypeTagsUnit))
10915 return 0;
10917 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10918 DoOutput(" VERSION : string[2] = '0';\n");
10919 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10921 DoOutput("{$ifdef use_init_openlib}\n");
10922 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName);
10923 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper);
10925 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10926 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10927 DoOutput("begin\n");
10928 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10929 DoOutput(" if %s <> nil then begin\n",BaseName);
10930 DoOutput(" CloseLibrary(%s);\n",BaseName);
10931 DoOutput(" %s := nil;\n",BaseName);
10932 DoOutput(" end;\n");
10933 DoOutput("end;\n\n");
10934 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10935 DoOutput("begin\n %s := nil;\n",BaseName);
10936 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10937 DoOutput(" if %s <> nil then begin\n",BaseName);
10938 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10939 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10940 DoOutput(" end else begin\n");
10941 DoOutput(" MessageBox('FPC Pascal Error',\n");
10942 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10943 DoOutput(" 'Deallocating resources and closing down',\n");
10944 DoOutput(" 'Oops');\n");
10945 DoOutput(" halt(20);\n");
10946 DoOutput(" end;\n");
10947 DoOutput("end;\n\n");
10948 DoOutput("begin\n");
10949 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper);
10950 DoOutput("{$endif use_init_openlib}\n\n");
10952 DoOutput("{$ifdef use_auto_openlib}\n");
10953 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName);
10955 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10956 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10957 DoOutput("begin\n");
10958 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10959 DoOutput(" if %s <> nil then begin\n",BaseName);
10960 DoOutput(" CloseLibrary(%s);\n",BaseName);
10961 DoOutput(" %s := nil;\n",BaseName);
10962 DoOutput(" end;\n");
10963 DoOutput("end;\n\n");
10964 DoOutput("begin\n %s := nil;\n",BaseName);
10965 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10966 DoOutput(" if %s <> nil then begin\n",BaseName);
10967 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10968 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10969 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper);
10970 DoOutput(" end else begin\n");
10971 DoOutput(" MessageBox('FPC Pascal Error',\n");
10972 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10973 DoOutput(" 'Deallocating resources and closing down',\n");
10974 DoOutput(" 'Oops');\n");
10975 DoOutput(" halt(20);\n");
10976 DoOutput(" end;\n\n");
10977 DoOutput("{$endif use_auto_openlib}\n\n");
10979 DoOutput("{$ifdef dont_use_openlib}\n");
10980 DoOutput("begin\n");
10981 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper);
10982 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName);
10983 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName);
10984 DoOutput("{$endif dont_use_openlib}\n\n");
10986 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper);
10989 static uint32 CreateBMAP(void)
10991 return CallFunc(TAGMODE_NORMAL, 0, FuncBMAP);
10994 static uint32 CreateLVOLib(void)
10996 uint32 i;
10998 i = strlen(ShortBaseNameUpper);
10999 EndPutM32(tempbuf, HUNK_UNIT);
11000 EndPutM32(tempbuf+4, (i+3)>>2);
11001 DoOutputDirect(tempbuf, 8);
11002 DoOutputDirect(ShortBaseNameUpper, i);
11003 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11005 i = strlen(hunkname);
11006 EndPutM32(tempbuf, HUNK_NAME);
11007 EndPutM32(tempbuf+4, (i + 3)>>2);
11008 DoOutputDirect(tempbuf, 8);
11009 DoOutputDirect(hunkname, i);
11010 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11012 EndPutM32(tempbuf, HUNK_CODE);
11013 EndPutM32(tempbuf+4, 0);
11014 EndPutM32(tempbuf+8, HUNK_EXT);
11015 DoOutputDirect(tempbuf, 12);
11017 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOLib))
11018 return 0;
11020 EndPutM32(tempbuf, 0);
11021 EndPutM32(tempbuf+4, HUNK_END);
11022 return DoOutputDirect(tempbuf, 8);
11025 static uint32 CreateLVOLibPPC(void)
11027 uint8 *data = tempbuf, *data2, *data3;
11029 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11030 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11031 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11032 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11033 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
11034 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
11035 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
11036 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11037 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11038 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11039 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
11040 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
11041 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
11042 EndPutM32Inc(data, 0); /* eeh->e_entry */
11043 EndPutM32Inc(data, 0); /* eeh->e_phoff */
11044 data2 = data; data += 4;
11045 EndPutM32Inc(data, 0); /* eeh->e_flags */
11046 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
11047 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
11048 EndPutM16Inc(data, 0); /* eeh->e_phnum */
11049 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
11050 EndPutM16Inc(data, 4); /* eeh->e_shnum */
11051 EndPutM16Inc(data, 1); /* eeh->e_shstrndx - first table is string table */
11053 data3 = data;
11054 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11055 data += 28; /* 1 9 17*/
11056 EndPutM32(data2, data-tempbuf); /* store the entry */
11058 EndPutM32Inc(data, 0); /* esh[0].sh_name */
11059 EndPutM32Inc(data, 0); /* esh[0].sh_type */
11060 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11061 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11062 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
11063 EndPutM32Inc(data, 0); /* esh[0].sh_size */
11064 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11065 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11066 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
11067 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11069 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
11070 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
11071 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
11072 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
11073 EndPutM32Inc(data, data3-tempbuf); /* esh[3].sh_offset */
11074 EndPutM32Inc(data, 27); /* esh[3].sh_size */
11075 EndPutM32Inc(data, 0); /* esh[3].sh_link */
11076 EndPutM32Inc(data, 0); /* esh[3].sh_info */
11077 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
11078 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
11080 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
11081 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
11082 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
11083 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
11084 data2 = data;
11085 data += 4; /* esh[4].sh_offset */
11086 data += 4; /* esh[4].sh_size */
11087 EndPutM32Inc(data, 3); /* esh[4].sh_link - the third entry is our string table */
11088 EndPutM32Inc(data, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11089 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
11090 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11092 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
11093 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
11094 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11095 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11096 data3 = data;
11097 data += 4; /* esh[0].sh_offset */
11098 data += 4; /* esh[0].sh_size */
11099 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11100 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11101 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
11102 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11104 EndPutM32Inc(data2, data-tempbuf);
11106 EndPutM32Inc(data,0);
11107 EndPutM32Inc(data,0); /* first entry is empty */
11108 EndPutM32Inc(data,0);
11109 EndPutM32Inc(data,0);
11111 symoffset = 1; /* initial value */
11112 elfbufpos = data;
11114 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
11115 return 0;
11116 EndPutM32(data2, elfbufpos-data+16);
11117 EndPutM32Inc(data3, elfbufpos-tempbuf);
11118 EndPutM32(data3, symoffset);
11120 *(elfbufpos++) = 0; /* first sym entry */
11121 if(!DoOutputDirect(tempbuf, elfbufpos-tempbuf))
11122 return 0;
11124 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
11125 return 0;
11127 while((symoffset++)&3)
11129 if(!DoOutputDirect("", 1))
11130 return 0;
11133 return 1;
11136 static uint32 CreateVBCCInline(uint32 mode, uint32 callmode)
11138 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11140 if(!clibdata)
11142 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11145 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11146 ShortBaseNameUpper, ShortBaseNameUpper);
11148 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11149 if (mode == 2)
11151 /* always include emul/emulregs.h in MorphOS inlines,
11152 gcc-based sources might depend on it :| */
11153 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11156 if(HEADER)
11158 DoOutput("\n");
11159 DoOutputDirect(HEADER, headersize);
11162 DoOutput("\n");
11164 if(!CallFunc(callmode, "/%s */\n", mode ? (mode == 2 ? FuncVBCCMorphInline
11165 : FuncVBCCWOSInline) : FuncVBCCInline))
11166 return 0;
11168 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper);
11171 static uint32 CreateVBCC(uint32 mode, uint32 callmode)
11173 uint32 res = 0;
11175 if(mode != 2 && mode != 3)
11177 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11179 if(HEADER)
11181 DoOutput("\n");
11182 DoOutputDirect(HEADER, headersize);
11186 switch(mode)
11188 case 4: res = CallFunc(callmode, 0, FuncVBCCPUPText); break;
11190 case 3: Flags |= FLAG_WOSLIBBASE; /* no break! */
11191 case 2: res = CallFunc(callmode, 0, FuncVBCCWOSCode); break;
11193 case 1: Flags |= FLAG_WOSLIBBASE; /* no break! */
11194 case 0: res = CallFunc(callmode, "\n%s", FuncVBCCWOSText); break;
11196 return res;
11199 static uint32 CreateVBCCPUPLib(uint32 callmode)
11201 /* output header */
11202 DoOutput("!<arch>\n");
11204 return CallFunc(callmode, 0, FuncVBCCPUPCode);
11207 static uint32 CreateVBCCMorphCode(uint32 callmode)
11209 /* output header */
11210 DoOutput("!<arch>\n");
11212 return CallFunc(callmode, 0, FuncVBCCMorphCode);
11215 static uint32 CreateEModule(uint32 sorted)
11217 uint32 res = 0, i;
11218 if(sorted)
11219 DoError(ERR_NO_SORTED, 0);
11220 else
11222 DoOutputDirect("EMOD\0\x06", 6);
11223 for(res = 0; res < 2; ++res)
11225 for(i = 0; BaseName[i]; ++i)
11226 DoOutput("%c", tolower(BaseName[i]));
11227 DoOutputDirect("\x00",1);
11229 LastBias = BIAS_START-BIAS_OFFSET;
11230 CallFunc(TAGMODE_NORMAL, 0, FuncEModule);
11231 res = DoOutputDirect("\xFF",1);
11233 return res;
11236 static uint32 CreateProtoRedirect(void)
11238 Flags |= FLAG_DONE;
11239 return DoOutput("#ifdef NO_OBSOLETE\n"
11240 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11241 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName);
11244 static uint32 CreateSFD(uint32 callmode)
11246 struct Include *inc;
11247 struct AmiPragma *ap;
11248 if(!clibdata)
11250 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11253 if((ap = (struct AmiPragma *) AmiPragma.First))
11254 LastBias = ap->Bias-BIAS_OFFSET;
11255 else /* only security, never used normally */
11256 LastBias = 0;
11257 CurrentABI = ABI_M68K;
11259 if(IDstring)
11260 DoOutput("==id %s\n", IDstring);
11261 else
11263 time_t t;
11264 struct tm * tim;
11266 t = time(&t);
11267 tim = localtime(&t);
11269 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11270 "noname Exp $\n", '$', filename, tim->tm_year+1900, tim->tm_mon+1,
11271 tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec);
11274 if(BaseName)
11275 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11276 GetLibraryName(), BaseName, GetBaseType(), GetLibraryName());
11277 DoOutput("==bias %ld\n==public\n", LastBias+BIAS_OFFSET);
11279 for(inc = (struct Include *) Includes.First; inc; inc = (struct Include *) inc->List.Next)
11280 DoOutput("==include %s\n", inc->Include);
11281 if(!Includes.First)
11282 DoOutput("==include <exec/types.h>\n");
11284 CallFunc(callmode, "%s\n", FuncSFD);
11286 return DoOutput("==end\n");
11289 static uint32 CreateClib(uint32 callmode)
11291 if(!clibdata)
11293 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11296 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11298 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper,
11299 ShortBaseNameUpper);
11301 if(HEADER)
11303 DoOutput("\n");
11304 DoOutputDirect(HEADER, headersize);
11306 else
11308 strptr s = 0;
11309 time_t t;
11310 struct tm * tim;
11312 t = time(&t);
11313 tim = localtime(&t);
11315 if(IDstring)
11317 s = SkipBlanks(IDstring+4);
11318 while(*s && *s != ' ')
11319 ++s;
11320 s=SkipBlanks(s);
11322 if(!s || !*s)
11323 s = "1.0";
11325 if(Flags2 & FLAG2_SYSTEMRELEASE)
11327 DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
11329 else
11331 strptr t;
11333 t = s;
11334 while(*t && *t != ' ')
11335 ++t;
11336 *t = 0;
11338 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename, s,
11339 tim->tm_mday, tim->tm_mon+1, tim->tm_year+1900);
11341 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11342 if(!Copyright || (Copyright && strncmp("Copyright ", Copyright, 10)))
11343 DoOutput("Copyright %c %d ", 0xa9, tim->tm_year+1900);
11344 DoOutput("%s\n", Copyright ? Copyright : Flags2 & FLAG2_SYSTEMRELEASE ?
11345 "Amiga, Inc." : "");
11346 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11349 PrintIncludes();
11351 if((Flags & FLAG_EXTERNC) &&
11352 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11353 return 0;
11355 CallFunc(callmode, "\n/%s */\n\n", FuncClib);
11357 if((Flags & FLAG_EXTERNC) &&
11358 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11359 return 0;
11361 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper);
11364 static uint32 CreateFD(void)
11366 LastBias = 0;
11367 CurrentABI = ABI_M68K;
11369 if(BaseName)
11370 DoOutput("##base _%s\n", BaseName);
11371 DoOutput("##public\n");
11373 CallFunc(TAGMODE_NORMAL, "%s\n", FuncFD);
11375 return DoOutput("##end\n");
11378 static uint32 CreateGenAuto(strptr to, uint32 type)
11380 strptr name, btype;
11381 uint8 *data;
11382 uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
11383 if(!(name = GetLibraryName()))
11384 return 0;
11385 btype = GetBaseType();
11387 switch(type)
11389 case 0:
11390 Flags |= FLAG_DONE;
11391 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11392 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11393 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11394 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11395 btype, BaseName, BaseName,
11396 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", name, BaseName,
11397 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", BaseName)))
11398 return 0;
11399 sprintf(filename, "%s_autoopenver.c", ShortBaseName);
11400 if(!CloseDest(to) || !OpenDest(filename))
11401 return 0;
11402 Flags |= FLAG_DONE;
11403 return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
11404 break;
11405 case 1: /* m68k */
11406 Flags |= FLAG_DONE;
11407 i = strlen(filename)-4; /* remove .lib extension */
11408 EndPutM32(tempbuf, HUNK_UNIT);
11409 EndPutM32(tempbuf+4, (i+3)>>2);
11410 DoOutputDirect(tempbuf, 8);
11411 DoOutputDirect(filename, i);
11412 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11414 i = strlen(hunkname);
11415 EndPutM32(tempbuf, HUNK_NAME);
11416 EndPutM32(tempbuf+4, (i + 3)>>2);
11417 DoOutputDirect(tempbuf, 8);
11418 DoOutputDirect(hunkname, i);
11419 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11421 data = tempbuf+8; /* we need HUNK_CODE + size at start */
11422 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11423 /* SysBase */
11424 if(Flags & FLAG_SMALLDATA)
11426 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11427 EndPutM16Inc(data, 0); /* place for sysbase reference */
11429 else
11431 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11432 EndPutM32Inc(data, 0); /* place for sysbase reference */
11434 verref = data-tempbuf-8+2;
11435 if(Flags & FLAG_SMALLDATA)
11437 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11438 EndPutM16Inc(data, 0); /* place for basevers reference */
11440 else
11442 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11443 EndPutM32Inc(data, 0); /* place for basevers reference */
11445 EndPutM32Inc(data, 0x43FA0030 + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2) + ((Flags & FLAG_SMALLDATA) ? 0 : 6));
11446 EndPutM32Inc(data, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11448 rel1 = data-tempbuf-8+2;
11449 if(Flags & FLAG_SMALLDATA)
11451 EndPutM16Inc(data, 0x2940); /* MOVE.L D0,xxx(A4) */
11452 EndPutM16Inc(data, 0);
11454 else
11456 EndPutM16Inc(data, 0x23C0); /* MOVE.L D0,xxx */
11457 EndPutM32Inc(data, 0);
11459 EndPutM16Inc(data, 0x660A + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2)); /* BNE.B .lib */
11460 EndPutM32Inc(data, 0x48780014); /* PEA 20 */
11462 exitfuncref = data-tempbuf-8+2;
11463 if(Flags2 & FLAG2_SMALLCODE)
11465 EndPutM16Inc(data, 0x4EBA); /* JSR _exit(PC) */
11466 EndPutM16Inc(data, 0); /* place for base reference */
11468 else
11470 EndPutM16Inc(data, 0x4EB9); /* JSR _exit */
11471 EndPutM32Inc(data, 0); /* place for base reference */
11473 EndPutM16Inc(data, 0x584F); /* ADDQ.W, #4,A7 */
11474 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11475 EndPutM16Inc(data,0x4E75); /* RTS */
11476 exitref = data-tempbuf-8;
11478 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11479 sysref2 = data-tempbuf-8+2;
11480 /* SysBase */
11481 if(Flags & FLAG_SMALLDATA)
11483 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11484 EndPutM16Inc(data, 0); /* place for sysbase reference */
11486 else
11488 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11489 EndPutM32Inc(data, 0); /* place for sysbase reference */
11491 rel2 = data-tempbuf-8+2;
11492 if(Flags & FLAG_SMALLDATA)
11494 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11495 EndPutM16Inc(data, 0); /* place for base reference */
11497 else
11499 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11500 EndPutM32Inc(data, 0); /* place for base reference */
11502 EndPutM16Inc(data, 0x6606); /* BNE.B .nolib */
11503 EndPutM16Inc(data, 0x2240); /* MOVEA.L D0,A1 */
11505 EndPutM32Inc(data, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11506 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11507 EndPutM16Inc(data,0x4E75); /* RTS */
11508 nameref = data-tempbuf-8;
11509 memcpy(data, name, strlen(name));
11510 data += strlen(name);
11511 do { *(data++) = 0; } while((data-tempbuf)&3);
11513 EndPutM32(tempbuf, HUNK_CODE);
11514 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
11515 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
11517 if(Flags & FLAG_SMALLDATA)
11519 EndPutM32(tempbuf, HUNK_DREL16);
11521 else
11523 EndPutM32(tempbuf, HUNK_ABSRELOC32);
11525 EndPutM32(tempbuf+4, 2); /* 2 entries */
11526 EndPutM32(tempbuf+8, 1); /* to hunk 1 */
11527 EndPutM32(tempbuf+12, rel1); /* address 0 */
11528 EndPutM32(tempbuf+16, rel2); /* address 0 */
11529 EndPutM32(tempbuf+20, 0); /* end of reloc hunk */
11530 DoOutputDirect(tempbuf, 24);
11532 /* extern references */
11533 EndPutM32(tempbuf, HUNK_EXT);
11534 DoOutputDirect(tempbuf, 4);
11536 OutputXREF2(4, sysref2, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_SysBase");
11537 OutputXREF(verref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "__%sVer", BaseName);
11538 OutputXREF(exitfuncref, (Flags2 & FLAG2_SMALLCODE ? EXT_DEXT16 : EXT_REF32), "_exit");
11539 OutputXDEF(0, "__INIT_%ld_%s", priority, BaseName);
11540 OutputXDEF(exitref, "__EXIT_%ld_%s", priority, BaseName);
11541 OutputXDEF(nameref, "%sname", ShortBaseName);
11542 EndPutM32(tempbuf, 0); /* ext end */
11543 DoOutputDirect(tempbuf, 4);
11545 if(!(Flags & FLAG_NOSYMBOL))
11547 EndPutM32(tempbuf, HUNK_SYMBOL);
11548 DoOutputDirect(tempbuf, 4);
11549 OutputSYMBOL(0, "__INIT_%ld_%s", priority, BaseName);
11550 OutputSYMBOL(exitref, "__EXIT_%ld_%s", priority, BaseName);
11551 OutputSYMBOL(nameref, "%sname", ShortBaseName);
11552 EndPutM32(tempbuf, 0);
11553 DoOutputDirect(tempbuf, 4);
11556 EndPutM32(tempbuf, HUNK_END);
11557 DoOutputDirect(tempbuf, 4);
11559 i = strlen(datahunkname);
11560 EndPutM32(tempbuf, HUNK_NAME);
11561 EndPutM32(tempbuf+4, (i + 3)>>2);
11562 DoOutputDirect(tempbuf, 8);
11563 DoOutputDirect(datahunkname, i);
11564 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11566 EndPutM32(tempbuf, HUNK_BSS);
11567 EndPutM32(tempbuf+4, 1);
11568 DoOutputDirect(tempbuf, 8);
11570 EndPutM32(tempbuf, HUNK_EXT);
11571 DoOutputDirect(tempbuf, 4);
11572 OutputXDEF(0, "_%s", BaseName);
11573 EndPutM32(tempbuf, 0); /* ext end */
11574 DoOutputDirect(tempbuf, 4);
11576 if(!(Flags & FLAG_NOSYMBOL))
11578 EndPutM32(tempbuf, HUNK_SYMBOL);
11579 DoOutputDirect(tempbuf, 4);
11580 OutputSYMBOL(0, "_%s", BaseName);
11581 EndPutM32(tempbuf, 0);
11582 DoOutputDirect(tempbuf, 4);
11585 EndPutM32(tempbuf, HUNK_END);
11586 DoOutputDirect(tempbuf, 4);
11588 sprintf(filename, "%s_autoopenver", ShortBaseName);
11589 i = strlen(filename);
11590 EndPutM32(tempbuf, HUNK_UNIT);
11591 EndPutM32(tempbuf+4, (i+3)>>2);
11592 DoOutputDirect(tempbuf, 8);
11593 DoOutputDirect(filename, i);
11594 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11596 i = strlen(datahunkname);
11597 EndPutM32(tempbuf, HUNK_NAME);
11598 EndPutM32(tempbuf+4, (i + 3)>>2);
11599 DoOutputDirect(tempbuf, 8);
11600 DoOutputDirect(datahunkname, i);
11601 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11603 EndPutM32(tempbuf, HUNK_BSS);
11604 EndPutM32(tempbuf+4, 1);
11605 DoOutputDirect(tempbuf, 8);
11607 EndPutM32(tempbuf, HUNK_EXT);
11608 DoOutputDirect(tempbuf, 4);
11609 OutputXDEF(0, "_%sVer", BaseName);
11610 EndPutM32(tempbuf, 0); /* ext end */
11611 DoOutputDirect(tempbuf, 4);
11613 if(!(Flags & FLAG_NOSYMBOL))
11615 EndPutM32(tempbuf, HUNK_SYMBOL);
11616 DoOutputDirect(tempbuf, 4);
11617 OutputSYMBOL(0, "_%sVer", BaseName);
11618 EndPutM32(tempbuf, 0);
11619 DoOutputDirect(tempbuf, 4);
11622 EndPutM32(tempbuf, HUNK_END);
11623 return DoOutputDirect(tempbuf, 4);
11625 break;
11627 return 0;
11630 static uint32 CreateXML(void)
11632 struct Include *inc;
11633 char *basetypelib;
11635 LastBias = 30;
11636 DoOutput(
11637 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11638 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11639 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11640 ShortBaseName, BaseName, GetLibraryName());
11641 basetypelib = GetBaseTypeLib();
11642 if(basetypelib && (strcmp(basetypelib, "Library") != 0))
11643 DoOutput(" basetype=\"%s\"", basetypelib);
11644 DoOutput(">\n");
11645 for(inc = (struct Include *) Includes.First; inc;
11646 inc = (struct Include *) inc->List.Next)
11647 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc->Include)-2),
11648 inc->Include+1);
11649 if(!Includes.First)
11650 DoOutput("\t<include>exec/types.h</include>\n");
11652 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11653 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11654 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11655 DoOutput(
11656 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11657 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11658 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11659 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11660 " status=\"unimplemented\"/>\n");
11662 CallFunc(TAGMODE_BOTH, 0, FuncXML);
11664 return DoOutput("\t</interface>\n</library>\n");
11667 static uint32 CreateOS4PPC(uint32 callmode)
11669 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11671 if(HEADER)
11673 DoOutput("\n");
11674 DoOutputDirect(HEADER, headersize);
11677 PrintIncludes();
11679 DoOutput(
11680 "#include <stdarg.h>\n"
11681 "#include <exec/types.h>\n"
11682 "#include <exec/interfaces.h>\n"
11683 "#include <exec/emulation.h>\n"
11684 "#include <interfaces/exec.h>\n");
11686 if(!stricmp("exec",ShortBaseName))
11687 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName);
11689 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName);
11691 CallFunc(callmode, "\n/%s */\n\n", FuncOS4PPC);
11693 DoOutput(
11694 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11695 " return Self->Data.RefCount++;\n}\n\n"
11696 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11697 " return Self->Data.RefCount--;\n}\n\n"
11698 "#define LIBNAME \"%s\"\n"
11699 "#define LIBVERSION 0\n"
11700 "#define IFACENAME \"%s.main\"\n\n",
11701 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11702 GetLibraryName(), GetLibraryName());
11704 /* following text is constant */
11705 return DoOutput(
11706 "static void InitFunction(APTR dummy, ULONG SegList, "
11707 "struct ExecBase *ExecBase)\n{\n"
11708 " struct Library *LibBase;\n"
11709 " struct ExecIFace *IExec = (struct ExecIFace *)"
11710 "ExecBase->MainInterface;\n"
11711 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11712 " {\n"
11713 " struct Interface *NewInterface;\n"
11714 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11715 " MIT_VectorTable, main_vectors,\n"
11716 " MIT_Version, 1,\n"
11717 " MIT_Name, IFACENAME,\n"
11718 " TAG_DONE)))\n"
11719 " {\n"
11720 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11721 " IExec->AddInterface(LibBase, NewInterface);\n"
11722 " }\n"
11723 " }\n"
11724 "}\n\n"
11725 "volatile static struct Resident MyResident =\n{\n"
11726 " RTC_MATCHWORD,\n"
11727 " (struct Resident *)&MyResident,\n"
11728 " (APTR)(&MyResident+1),\n"
11729 " RTF_NATIVE,\n"
11730 " LIBVERSION,\n"
11731 " NT_UNKNOWN,\n"
11732 " -120,\n"
11733 " IFACENAME,\n"
11734 " IFACENAME,\n"
11735 " InitFunction\n"
11736 "};\n\n"
11737 "void _start(void)\n"
11738 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11739 "\n}\n");
11742 static uint32 CreateOS4M68K(void)
11744 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11746 if(HEADER)
11748 DoOutput("\n");
11749 DoOutputDirect(HEADER, headersize);
11751 DoOutput(
11752 "#include \"exec/interfaces.i\"\n"
11753 "#include \"exec/libraries.i\"\n"
11754 "#include \"exec/emulation.i\"\n"
11755 "#include \"interfaces/%s.i\"\n\n",ShortBaseName);
11757 DoOutput(
11758 "\t.section .data\n"
11759 "\t.globl\tstub_Open\n"
11760 "\t.type\tstub_Open,@function\n"
11761 "\n"
11762 "stub_Open:\n"
11763 "\t.short\t0x4ef8\n" /* JMP.w */
11764 "\t.short\t0\n" /* Indicate switch */
11765 "\t.short\t1\n" /* Trap type */
11766 "\t.globl\tstub_OpenPPC\n"
11767 "\t.long\tstub_OpenPPC\n"
11768 "\t.byte\t2\n" /* Register mapping */
11769 "\t.byte\t1,REG68K_A7\n"
11770 "\t.byte\t3,REG68K_A6\n"
11771 "\t.section .text\n"
11772 "\t.align\t4\n"
11773 "\n"
11774 "stub_OpenPPC:\n"
11775 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11776 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11777 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11778 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11779 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11780 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11781 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11782 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11783 "\tCallLib\tlmi_Open\n"
11784 "\tlwz\t%s11,%s12(%s1)\n"
11785 "\tmtlr\t%s11\n"
11786 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11787 "\tblrl\n" /* Return to emulation */
11788 "\n"
11789 "\t.globl\tstub_Open68K\n"
11790 "\t.long\tstub_Open68K\n"
11791 "\t.byte\t0\n" /* Flags */
11792 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11793 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11794 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11795 "\t.section .data\n"
11796 "\t.align\t4\n"
11797 "\n"
11798 "stub_Open68K:\n"
11799 "\t.short\t0x4e75\n" /* RTS */
11800 "\n"
11801 "\t.section .data\n"
11802 "\t.globl\tstub_Close\n"
11803 "\t.type\tstub_Close,@function\n"
11804 "\n"
11805 "stub_Close:\n"
11806 "\t.short\t0x4ef8\n" /* JMP.w */
11807 "\t.short\t0\n" /* Indicate switch */
11808 "\t.short\t1\n" /* Trap type */
11809 "\t.globl\tstub_ClosePPC\n"
11810 "\t.long\tstub_ClosePPC\n"
11811 "\t.byte\t2\n" /* Register mapping */
11812 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11813 "\t.byte\t3,REG68K_A6\n"
11814 "\t.section .text\n"
11815 "\t.align\t4\n"
11816 "\n"
11817 "stub_ClosePPC:\n"
11818 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11819 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11820 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11821 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11822 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11823 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11824 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11825 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11826 "\tCallLib\tlmi_Close\n"
11827 "\tlwz\t%s11,12(%s1)\n"
11828 "\tmtlr\t%s11\n"
11829 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11830 "\tblrl\n" /* Return to emulation */
11831 "\n"
11832 "\t.globl\tstub_Close68K\n"
11833 "\t.long\tstub_Close68K\n"
11834 "\t.byte\t0\n" /* Flags */
11835 "\t.byte\t1\n" /* One register (a7 only) */
11836 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11837 "\t.section .data\n"
11838 "\t.align\t4\n"
11839 "\n"
11840 "stub_Close68K:\n"
11841 "\t.short\t0x4e75\n" /* RTS */
11842 "\n"
11843 "\t.section .data\n"
11844 "\t.globl\tstub_Expunge\n"
11845 "\t.type\tstub_Expunge,@function\n"
11846 "\n"
11847 "stub_Expunge:\n"
11848 "\t.short\t0x7000\n" /* moveq #0, d0 */
11849 "\t.short\t0x4e75\n" /* RTS */
11850 "\n"
11851 "\t.section .data\n"
11852 "\t.globl\tstub_Reserved\n"
11853 "\t.type\tstub_Reserved,@function\n"
11854 "\n"
11855 "stub_Reserved:\n"
11856 "\t.short\t0x7000\n" /* moveq #0, d0 */
11857 "\t.short\t0x4e75\n\n", /* RTS */
11858 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11859 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11860 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11861 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11862 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11863 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11864 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11865 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11866 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
11868 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68K);
11869 DoOutput("\n"
11870 "\t.globl\tVector68K\n"
11871 "\t.globl\tVecTable68K\n"
11872 "Vector68K:\n"
11873 "\t.long\tVecTable68K\n"
11874 "VecTable68K:\n"
11875 "\t.long\tstub_Open\n"
11876 "\t.long\tstub_Close\n"
11877 "\t.long\tstub_Expunge\n"
11878 "\t.long\tstub_Reserved\n");
11880 LastBias = 30;
11881 CallFunc(TAGMODE_NORMAL, 0, FuncOS4M68KVect);
11882 DoOutput("\t.long\t-1\n");
11884 CloseDest(filename);
11886 if(Flags2 & FLAG2_OS4M68KCSTUB)
11888 sprintf(filename, "%s_68k.c", ShortBaseName);
11889 if(!OpenDest(filename))
11890 exit(20);
11891 Flags &= ~(FLAG_DONE);
11892 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11894 if(HEADER)
11896 DoOutput("\n");
11897 DoOutputDirect(HEADER, headersize);
11900 DoOutput(
11901 "#ifdef __USE_INLINE__\n"
11902 "#undef __USE_INLINE__\n"
11903 "#endif\n"
11904 "#ifndef __NOGLOBALIFACE__\n"
11905 "#define __NOGLOBALIFACE__\n"
11906 "#endif\n\n"
11907 "#include <exec/interfaces.h>\n"
11908 "#include <exec/libraries.h>\n"
11909 "#include <exec/emulation.h>\n"
11910 "#include <interfaces/exec.h>\n"
11911 "#include <interfaces/%s.h>\n"
11912 "#include <proto/%s.h>\n\n", ShortBaseName, ShortBaseName);
11914 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68KCSTUB);
11916 return Output_Error;
11919 /* ------------------------------------------------------------------ */
11921 static uint32 GetName(struct NameList *t, struct ShortListRoot *p, uint32 args)
11923 struct NameList *p2 = (struct NameList *) p->First;
11924 struct AmiPragma ap;
11925 memset(&ap, 0, sizeof(struct AmiPragma));
11926 ap.FuncName = t->NormName;
11927 ap.NumArgs = 1;
11928 ap.CallArgs = 1;
11929 ap.Args[0].ArgName = (args ? "args" : "tags");
11930 if(!MakeTagFunction(&ap))
11931 return 0;
11933 if(!ap.TagName)
11934 return 0;
11936 while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
11937 p2 = (struct NameList *) p2->List.Next;
11939 if(!p2)
11940 return 0;
11942 t->Type = (args ? NTP_ARGS : NTP_TAGS);
11943 t->PragName = ap.TagName;
11944 RemoveItem(p, (struct ShortList *) p2);
11946 #ifdef DEBUG_OLD
11947 printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
11948 #endif
11950 return 1;
11953 static void OptimizeFDData(struct PragData *pd)
11955 #ifdef DEBUG_OLD
11956 printf("OptimizeFDData\n");
11957 #endif
11959 while(pd)
11961 if(pd->NumNames > 1)
11963 struct ShortListRoot n = {0,0,0}, p = {0,0,0};
11964 struct NameList *t;
11965 while(pd->Name.First) /* sorts in AmiCall and TagCall */
11967 t = (struct NameList *) pd->Name.First;
11969 RemoveItem(&pd->Name, (struct ShortList *) t);
11970 AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
11973 if(p.First)
11975 t = (struct NameList *) n.First;
11976 while(p.First && t)
11978 if(!GetName(t, &p, 0))
11980 GetName(t, &p, 1);
11982 if(t->PragName)
11984 struct NameList *t2 = (struct NameList *) t->List.Next;
11985 RemoveItem(&n, (struct ShortList *)t);
11986 AddItem(&pd->Name, (struct ShortList *) t);
11987 t = t2;
11989 else
11990 t = (struct NameList *) t->List.Next;
11992 while(p.First)
11994 if(n.First)
11996 t = (struct NameList *) n.First;
11997 t->PragName = ((struct NameList *)(p.First))->PragName;
11998 RemoveItem(&n, (struct ShortList *) t);
11999 #ifdef DEBUG_OLD
12000 printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
12001 #endif
12002 t->Type = NTP_UNKNOWN;
12004 else
12006 uint32 i;
12008 t = (struct NameList *) p.First;
12009 i = strlen(t->PragName);
12010 t->NormName = DupString(t->PragName, i+1);
12011 t->NormName[i++] = 'A';
12012 t->NormName[i] = 0;
12013 t->Type = NTP_TAGS;
12014 #ifdef DEBUG_OLD
12015 printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
12016 #endif
12019 AddItem(&pd->Name, (struct ShortList *) t);
12020 RemoveItem(&p, p.First);
12024 AddItem(&pd->Name, n.First); /* add left NormNames */
12026 pd = (struct PragData *) pd->List.Next;
12030 static uint32 MakeFD(struct PragList *pl)
12032 struct PragData *pd = (struct PragData *) pl->Data.First;
12033 uint32 bias;
12035 #ifdef DEBUG_OLD
12036 printf("MakeFD\n");
12037 #endif
12038 bias = pd->Bias;
12040 OptimizeFDData(pd);
12041 #ifdef DEBUG_OLD
12042 printf("MakeFD: after Optimizing\n");
12043 #endif
12044 DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
12046 while(pd && Output_Error)
12048 struct NameList *n = (struct NameList *) pd->Name.First;
12050 if(bias != pd->Bias)
12051 DoOutput("##bias %ld\n", (bias = pd->Bias));
12053 while(n)
12055 strptr lastpar = "last";
12056 uint32 i;
12058 if(n->Type == NTP_TAGS)
12059 lastpar = "tags";
12060 else if(n->Type == NTP_ARGS)
12061 lastpar = "args";
12063 DoOutput("%s("/*)*/,n->NormName);
12064 if(!pd->NumArgs)
12065 DoOutput(/*(*/")()\n");
12066 else
12068 for(i = 0; i < pd->NumArgs-1; ++i)
12069 DoOutput("par%ld,",i+1);
12070 DoOutput(/*(*/"%s)("/*)*/, lastpar);
12071 for(i = 0; i < pd->NumArgs-1; ++i)
12072 DoOutput("%s,", RegNames[pd->ArgReg[i]]);
12073 DoOutput(/*(*/"%s)\n", RegNames[pd->ArgReg[i]]);
12075 if(n->Type == NTP_UNKNOWN)
12077 uint32 i;
12078 for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
12080 DoOutput("*tagcall");
12081 if(n->NormName[i])
12082 DoOutput("-%s", n->NormName+i);
12083 if(n->PragName[i])
12084 DoOutput("+%s", n->PragName+i);
12086 DoOutput("\n");
12089 if((n = (struct NameList *) n->List.Next))
12090 DoOutput("##bias %ld\n", pd->Bias);
12091 Flags |= FLAG_DONE;
12094 pd = (struct PragData *)pd->List.Next; bias += BIAS_OFFSET;
12097 DoOutput("##end\n");
12099 return Output_Error;
12102 static uint32 AddFDData(struct ShortListRoot *pls, struct FDData *fd)
12104 struct NameList *t;
12105 struct PragList *pl = (struct PragList *) pls->First;
12106 struct PragData *pd;
12108 while(pl && strcmp(pl->Basename, fd->Basename))
12109 pl = (struct PragList *) pl->List.Next;
12111 if(!pl)
12113 #ifdef DEBUG_OLD
12114 printf("AddFDData: New PragList - %s\n", fd->Basename);
12115 #endif
12116 if(!(pl = (struct PragList *) NewItem(pls)))
12117 return 100;
12118 pl->Basename = fd->Basename;
12119 pl->Data.Size = sizeof(struct PragData);
12120 AddItem(pls, (struct ShortList *) pl);
12123 if((pd = (struct PragData *) pl->Data.First))
12125 while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
12126 <= fd->Bias)
12127 pd = (struct PragData *) pd->List.Next;
12130 if(!pd || pd->Bias != fd->Bias)
12132 struct PragData *pd2;
12133 #ifdef DEBUG_OLD
12134 printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
12135 #endif
12136 if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
12137 return 100;
12138 pd2->Bias = fd->Bias;
12139 memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
12140 pd2->NumArgs = fd->NumArgs;
12141 pd2->Name.Size = sizeof(struct NameList);
12142 if(!pd)
12143 AddItem(&pl->Data, (struct ShortList *) pd2);
12144 else if(pd->Bias > fd->Bias) /* Insert at start */
12146 pd2->List.Next = pl->Data.First;
12147 pl->Data.First = (struct ShortList *) pd2;
12149 else /* Insert the entry */
12151 pd2->List.Next = pd->List.Next;
12152 pd->List.Next = (struct ShortList *) pd2;
12154 pd = pd2;
12156 else
12158 uint32 i = fd->NumArgs;
12159 if(fd->NumArgs != pd->NumArgs)
12161 #ifdef DEBUG_OLD
12162 printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
12163 #endif
12164 return ERR_DIFFERENT_TO_PREVIOUS;
12167 while(i--)
12169 if(fd->ArgReg[i] != pd->ArgReg[i])
12171 #ifdef DEBUG_OLD
12172 printf("ArgReg %x != %x\n", fd->ArgReg[i], pd->ArgReg[i]);
12173 #endif
12174 return ERR_DIFFERENT_TO_PREVIOUS;
12179 t = (struct NameList *) pd->Name.First; /* skips same names */
12180 while(t && (!(fd->Mode ? t->PragName : t->NormName) ||
12181 strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName)))
12182 t = (struct NameList *) t->List.Next;
12184 if(t)
12185 return 0;
12187 if(!(t = (struct NameList *) NewItem(&pd->Name)))
12188 return 100;
12189 if(fd->Mode)
12190 t->PragName = fd->Name;
12191 else
12192 t->NormName = fd->Name;
12193 AddItem(&pd->Name, (struct ShortList *) t);
12194 ++(pd->NumNames);
12195 #ifdef DEBUG_OLD
12196 printf("AddFDData: New NameList - %s\n", fd->Name);
12197 #endif
12198 return 0;
12201 static string GetHexValue(string data)
12203 if(data >= 'a')
12204 return (string) (data - 'a' + 10);
12205 else if(data >= 'A')
12206 return (string) (data - 'A' + 10);
12207 else
12208 return (string) (data - '0');
12211 static string GetDoubleHexValue(strptr data)
12213 return (string)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
12216 static uint32 GetLibData(struct FDData *fd)
12218 uint32 i;
12219 fd->Name = SkipBlanks(in.pos);
12220 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12221 in.pos = SkipBlanks(in.pos);
12222 fd->Bias = strtoul(in.pos, 0, 16);
12223 in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
12224 if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
12225 return ERR_TO_MUCH_ARGUMENTS;
12226 --in.pos; /* skips return register */
12227 for(i = 0; i < fd->NumArgs; ++i)
12229 if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
12230 return ERR_EXPECTED_REGISTER_NAME;
12232 return 0;
12235 static uint32 GetFlibData(struct FDData *fd)
12237 uint32 i;
12238 fd->Name = SkipBlanks(in.pos);
12239 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12240 in.pos = SkipBlanks(in.pos);
12241 fd->Bias = strtoul(in.pos, 0, 16);
12242 in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
12243 if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
12244 return ERR_TO_MUCH_ARGUMENTS;
12245 in.pos -= 2; /* skips return register */
12246 for(i = 0; i < fd->NumArgs; ++i)
12248 in.pos -= 2;
12249 if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
12250 return ERR_EXPECTED_REGISTER_NAME;
12251 else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
12252 return ERR_FLOATARG_NOT_ALLOWED;
12254 return 0;
12257 static uint32 GetAmiData(struct FDData *fd)
12259 strptr endptr;
12260 in.pos = SkipBlanks(in.pos);
12261 if(*in.pos != '('/*)*/)
12262 return ERR_EXPECTED_OPEN_BRACKET;
12263 fd->Basename = ++in.pos;
12264 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12265 if(*in.pos != ',')
12266 return ERR_EXPECTED_COMMA;
12267 *endptr = 0;
12268 in.pos = SkipBlanks(++in.pos);
12269 if(!strncmp(in.pos, "0x", 2))
12270 fd->Bias = strtoul(in.pos+2, 0, 16);
12271 else
12272 fd->Bias = strtoul(in.pos, 0, 10);
12274 in.pos = SkipBlanks(SkipName(in.pos));
12275 if(*in.pos != ',')
12276 return ERR_EXPECTED_COMMA;
12277 fd->Name = in.pos = SkipBlanks(++in.pos);
12278 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12279 if(*in.pos != '('/*)*/)
12280 return ERR_EXPECTED_OPEN_BRACKET;
12281 *endptr = 0;
12282 in.pos = SkipBlanks(++in.pos);
12283 if(*in.pos == /*(*/')')
12284 return 0;
12285 --in.pos;
12286 while(*in.pos != /*(*/')')
12288 uint32 i;
12289 in.pos = SkipBlanks(in.pos+1);
12291 for(i = 0; i < REG_FP0; i++)
12292 if(!strnicmp(RegNames[i], in.pos, 2))
12293 break;
12294 if(i == REG_FP0)
12296 for(; i < MAXREG; i++)
12297 if(!strnicmp(RegNames[i], in.pos, 3))
12298 break;
12301 if(i == MAXREG)
12302 return ERR_EXPECTED_REGISTER_NAME;
12303 else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
12304 return ERR_FLOATARG_NOT_ALLOWED;
12306 fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
12308 if(fd->NumArgs > MAXREG-2)
12309 return ERR_TO_MUCH_ARGUMENTS;
12311 in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
12313 if(*in.pos != ',' && *in.pos != /*(*/')')
12314 return ERR_EXPECTED_CLOSE_BRACKET;
12316 in.pos = SkipBlanks(in.pos+1);
12317 if(*in.pos != /*(*/')')
12318 return ERR_EXPECTED_CLOSE_BRACKET;
12319 return 0;
12322 static uint32 CreateFDFile(void)
12324 struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
12325 uint32 linenum, err = 0, skip;
12326 strptr ptr, p2;
12328 ptr = p2 = args.infile;
12329 while(*p2)
12331 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
12332 ptr = p2+1;
12333 ++p2;
12335 for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
12337 if(p2 != ptr)
12339 ShortBaseName = ptr;
12340 *p2 = '\0';
12343 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
12345 in.pos = SkipBlanks(in.pos);
12346 if(!strncmp("#pragma", in.pos, 7))
12348 struct FDData fd;
12350 skip = 0;
12351 memset(&fd, 0, sizeof(struct FDData));
12353 in.pos = SkipBlanks(in.pos+7);
12354 if(!strncmp("tagcall", in.pos, 7))
12356 fd.Mode = 1;
12357 in.pos = SkipBlanks(in.pos+7);
12358 if(*in.pos == '(' /*)*/) /* Storm method */
12359 err = GetAmiData(&fd);
12360 else /* SAS method */
12362 fd.Basename = in.pos;
12363 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12364 err = GetLibData(&fd);
12367 else if(!strncmp("amicall", in.pos, 7)) /* Storm method */
12369 in.pos += 7;
12370 err = GetAmiData(&fd);
12372 else if(!strncmp("libcall", in.pos, 7)) /* SAS method */
12374 fd.Basename = SkipBlanks(in.pos+7);
12375 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12376 err = GetLibData(&fd);
12378 else if(!strncmp("flibcall", in.pos, 8)) /* SAS method */
12380 fd.Basename = SkipBlanks(in.pos+8);
12381 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12382 err = GetFlibData(&fd);
12384 else if(!strncmp("syscall", in.pos, 7)) /* SAS method */
12386 fd.Basename = "SysBase";
12387 err = GetLibData(&fd);
12389 else
12390 skip = 1;
12392 if(err)
12393 DoError(err, linenum);
12394 else if(skip)
12396 else if((err = AddFDData(&pl, &fd)))
12398 if(err != 100)
12399 DoError(err, linenum);
12400 return 0;
12403 while(*(in.pos++)) /* jumps to first char of next line */
12407 if(pl.First)
12409 struct PragList *p = (struct PragList *) pl.First;
12410 if(!p->List.Next)
12412 strptr text, to;
12413 uint32 i;
12415 if(ShortBaseName)
12417 text = ShortBaseName; i = strlen(text);
12419 else
12421 text = p->Basename; i = strlen(text)-4;
12424 to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
12425 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12426 if(!OpenDest(to))
12427 return 0;
12429 err = MakeFD(p);
12430 CloseDest(to);
12431 if(!err)
12432 return 0;
12434 else
12436 while(p)
12438 strptr to;
12439 uint32 i;
12440 i = strlen(p->Basename) - 4;
12441 to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
12442 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12443 if(!OpenDest(to))
12444 return 0;
12445 i = MakeFD(p);
12446 CloseDest(to);
12447 if(!i)
12448 return 0;
12449 p = (struct PragList *) p->List.Next;
12454 return 1;
12457 #ifdef FD2PRAGMA_READARGS
12458 #include <proto/dos.h>
12460 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12461 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12462 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12463 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12464 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12465 "NEWSYNTAX/S," \
12466 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12467 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12468 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12469 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12470 "VOIDBASE/S"
12472 struct AmiArg
12474 strptr INFILE;
12475 uint32* SPECIAL;
12476 uint32* MODE;
12477 strptr TO;
12478 strptr ABI;
12479 strptr CLIB;
12480 strptr COPYRIGHT;
12481 strptr HEADER;
12482 strptr HUNKNAME;
12483 strptr BASENAME;
12484 strptr LIBTYPE;
12485 strptr LIBNAME;
12486 uint32* PRIORITY;
12487 strptr PREFIX;
12488 strptr SUBPREFIX;
12489 strptr PREMACRO;
12490 uint32 AUTOHEADER;
12491 uint32 COMMENT;
12492 uint32 EXTERNC;
12493 uint32 FPUONLY;
12494 uint32 NEWSYNTAX;
12495 uint32 NOFPU;
12496 uint32 NOPPC;
12497 uint32 NOPPCREGNAME;
12498 uint32 NOSYMBOL;
12499 uint32 ONLYCNAMES;
12500 uint32 OPT040;
12501 uint32 PPCONLY;
12502 uint32 PRIVATE;
12503 uint32 SECTION;
12504 uint32 SMALLCODE;
12505 uint32 SMALLDATA;
12506 uint32 SMALLTYPES;
12507 uint32 SORTED;
12508 uint32 SYSTEMRELEASE;
12509 uint32 USESYSCALL;
12510 uint32 VOIDBASE;
12513 static const strptr helptext =
12514 "INFILE: the input file which should be used\n"
12515 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12516 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12517 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12518 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12519 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12520 "\t 6 - pragma for all compilers [default]\n"
12521 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12522 "\t10 - stub-functions for C - C text\n"
12523 "\t11 - stub-functions for C - assembler text\n"
12524 "\t12 - stub-functions for C - link library\n"
12525 "\t13 - defines and link library for local library base (register call)\n"
12526 "\t14 - defines and link library for local library base (stack call)\n"
12527 "\t15 - stub-functions for Pascal - assembler text\n"
12528 "\t16 - stub-functions for Pascal - link library\n"
12529 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12530 "\t18 - module for AmigaE\n"
12531 "\t20 - assembler lvo _lvo.i file\n"
12532 "\t21 - assembler lvo _lib.i file\n"
12533 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12534 "\t23 - assembler lvo _lib.i file no XDEF\n"
12535 "\t24 - assembler lvo link library\n"
12536 "\t30 - proto file with pragma/..._lib.h call\n"
12537 "\t31 - proto file with pragma/..._pragmas.h call\n"
12538 "\t32 - proto file with pragmas/..._lib.h call\n"
12539 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12540 "\t34 - proto file with local/..._loc.h call\n"
12541 "\t35 - proto file for all compilers (VBCC stubs)\n"
12542 "\t36 - proto file for GNU-C compiler only\n"
12543 "\t37 - proto file without lib definitions\n"
12544 "\t38 - proto file for all compilers (VBCC inline)\n"
12545 "\t39 - proto file with special PPC related checks\n"
12546 "\t40 - GCC inline file (preprocessor based)\n"
12547 "\t41 - GCC inline file (old type - inline based)\n"
12548 "\t42 - GCC inline file (library stubs)\n"
12549 "\t43 - GCC inline file (new style - macro)\n"
12550 "\t44 - GCC inline file (new style - inline)\n"
12551 "\t45 - GCC inline file (new style - inline with include lines)\n"
12552 "\t46 - GCC inline file (preprocessor based, direct)\n"
12553 "\t47 - GCC inline file (new style, direct)\n"
12554 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12555 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12556 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12557 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12558 "\t53 - SAS-C include file for PowerUP\n"
12559 "\t54 - Proto file for PowerUP\n"
12560 "\t60 - FPC pascal unit text\n"
12561 "\t70 - VBCC inline files\n"
12562 "\t71 - VBCC WOS stub-functions - assembler text\n"
12563 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12564 "\t73 - VBCC WOS stub-functions - link library\n"
12565 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12566 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12567 "\t76 - VBCC PowerUP stub-functions - link library\n"
12568 "\t77 - VBCC WOS inline files\n"
12569 "\t78 - VBCC MorphOS stub-functions - link library\n"
12570 "\t79 - VBCC old inline files\n"
12571 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12572 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12573 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12574 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12575 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12576 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12577 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12578 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12579 " 100 - PPC assembler lvo file\n"
12580 " 101 - PPC assembler lvo file no XDEF\n"
12581 " 102 - PPC assembler lvo ELF link library\n"
12582 " 103 - PPC assembler lvo EHF link library\n"
12583 " 104 - PPC V.4-ABI assembler file\n"
12584 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12585 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12586 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12587 " 110 - FD file\n"
12588 " 111 - CLIB file\n"
12589 " 112 - SFD file\n"
12590 " 120 - VBCC auto libopen files (C source)\n"
12591 " 121 - VBCC auto libopen files (m68k link library)\n"
12592 " 122 - VBCC MorphOS inline files\n"
12593 " 123 - VBCC new MorphOS inline files\n"
12594 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12595 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12596 " 132 - GCC inline files for MorphOS (library stubs)\n"
12597 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12598 " 134 - MorphOS gate stubs\n"
12599 " 135 - MorphOS gate stubs (prelib)\n"
12600 " 136 - MorphOS gate stubs (postlib)\n"
12601 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12602 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12603 " 140 - OS4 XML file\n"
12604 " 141 - OS4 PPC->M68K cross-call stubs\n"
12605 " 142 - OS4 M68K->PPC cross-call stubs\n"
12606 " 200 - FD file (source is a pragma file!)\n"
12607 "MODE: SPECIAL 1-7:\n"
12608 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12609 " 2: _PRAGMAS_..._LIB_H definition method\n"
12610 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12611 " 4: no definition\n"
12612 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12613 " 130-138,141:\n"
12614 " 1: all functions, normal interface\n"
12615 " 2: only tag-functions, tagcall interface\n"
12616 " 3: all functions, normal and tagcall interface [default]\n"
12617 "TO: the destination directory (self creation of filename)\n"
12618 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12619 "CLIB: name of the prototypes file in clib directory\n"
12620 "COPYRIGHT: the copyright text for CLIB files\n"
12621 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12622 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12623 "BASENAME: name of library base without '_'\n"
12624 "LIBNAME: name of the library (.e.g. dos.library)\n"
12625 "LIBTYPE: type of base library structure\n"
12626 "PRIORITY: priority for auto open files\n"
12627 "PREFIX: MorphOS gate prefix\n"
12628 "SUBPREFIX: MorphOS gate sub prefix\n"
12629 "PREMACRO: MorphOS gate file start macro\n"
12630 "Switches:\n"
12631 "AUTOHEADER add the typical automatic generated header\n"
12632 "COMMENT: copy comments found in input file\n"
12633 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12634 "FPUONLY: work only with functions using FPU register arguments\n"
12635 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12636 "NOFPU: disable usage of FPU register arguments\n"
12637 "NOPPC: disable usage of PPC-ABI functions\n"
12638 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12639 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12640 "ONLYCNAMES: do not create C++ or ASM names\n"
12641 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12642 "PPCONLY: only use PPC-ABI functions\n"
12643 "PRIVATE: includes private declared functions\n"
12644 "SECTION: add section statements to asm texts\n"
12645 "SMALLCODE: generate small code link libraries or assembler text\n"
12646 "SMALLDATA: generate small data link libraries or assembler text\n"
12647 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12648 "SORTED: sort generated files by name and not by bias value\n"
12649 "SYSTEMRELEASE: special handling of comments for system includes\n"
12650 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12651 "VOIDBASE: library bases are of type void *\n";
12653 /* print the help text */
12654 static void printhelp(void)
12656 printf("%s\n%s\n\n%s", version+6, PARAM, helptext);
12657 exit(20);
12660 /* initializes the arguments and starts argument parsing */
12661 static void GetArgs(int argc, char **argv)
12663 struct RDArgs *rda;
12664 struct AmiArg amiargs;
12665 int res = 0;
12667 if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
12669 rda->RDA_ExtHelp = helptext;
12670 memset(&amiargs, 0, sizeof(struct AmiArg));
12671 if(ReadArgs(PARAM, (int32 *) &amiargs, rda))
12673 int l;
12674 strptr d, s;
12676 l = strlen(amiargs.TO ? amiargs.TO : "") + 1
12677 + strlen(amiargs.CLIB ? amiargs.CLIB : "") + 1
12678 + strlen(amiargs.HEADER ? amiargs.HEADER : "") + 1
12679 + strlen(amiargs.ABI ? amiargs.ABI : "") + 1
12680 + strlen(amiargs.HUNKNAME ? amiargs.HUNKNAME : "") + 1
12681 + strlen(amiargs.BASENAME ? amiargs.BASENAME : "") + 1
12682 + strlen(amiargs.LIBTYPE ? amiargs.LIBTYPE : "") + 1
12683 + strlen(amiargs.LIBNAME ? amiargs.LIBNAME : "") + 1
12684 + strlen(amiargs.COPYRIGHT ? amiargs.COPYRIGHT : "") + 1
12685 + strlen(amiargs.PREFIX ? amiargs.PREFIX : "") + 1
12686 + strlen(amiargs.SUBPREFIX ? amiargs.SUBPREFIX : "") + 1
12687 + strlen(amiargs.PREMACRO ? amiargs.PREMACRO : "") + 1
12688 + strlen(amiargs.INFILE) + 1;
12689 if((d = AllocListMem(l)))
12691 res = 1;
12693 s = amiargs.INFILE;
12694 args.infile = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12695 if((s = amiargs.TO))
12697 args.to = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12699 if((s = amiargs.HEADER))
12701 args.header = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12703 if((s = amiargs.CLIB))
12705 args.clib = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12707 if((s = amiargs.HUNKNAME))
12709 hunkname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12711 if((s = amiargs.BASENAME))
12713 Flags |= FLAG_BASENAME;
12714 BaseName = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12716 if((s = amiargs.LIBTYPE))
12718 Flags2 |= FLAG2_LIBTYPE;
12719 libtype = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12721 if((s = amiargs.LIBNAME))
12723 Flags2 |= FLAG2_LIBNAME;
12724 libname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12726 if((s = amiargs.PREFIX))
12728 prefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12730 if((s = amiargs.SUBPREFIX))
12732 subprefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12734 if((s = amiargs.PREMACRO))
12736 premacro = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12738 if((s = amiargs.COPYRIGHT))
12740 Copyright = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12742 if((s = amiargs.ABI))
12744 defabi = d; while(*s) *(d++) = *(s++); *d = 0;
12746 if(amiargs.EXTERNC) Flags ^= FLAG_EXTERNC;
12747 if(amiargs.PRIVATE) Flags ^= FLAG_PRIVATE;
12748 if(amiargs.NEWSYNTAX) Flags ^= FLAG_NEWSYNTAX;
12749 if(amiargs.SMALLDATA) Flags ^= FLAG_SMALLDATA;
12750 if(amiargs.SMALLCODE) Flags2 ^= FLAG2_SMALLCODE;
12751 if(amiargs.SMALLTYPES) Flags2 ^= FLAG2_SMALLTYPES;
12752 if(amiargs.USESYSCALL) Flags ^= FLAG_SYSCALL;
12753 if(amiargs.OPT040) Flags ^= FLAG_NOMOVEM;
12754 if(amiargs.NOFPU) Flags ^= FLAG_NOFPU;
12755 if(amiargs.FPUONLY) Flags ^= FLAG_FPUONLY;
12756 if(amiargs.NOPPC) Flags ^= FLAG_NOPPC;
12757 if(amiargs.NOSYMBOL) Flags ^= FLAG_NOSYMBOL;
12758 if(amiargs.PPCONLY) Flags ^= FLAG_PPCONLY;
12759 if(amiargs.SECTION) Flags ^= FLAG_ASMSECTION;
12760 if(amiargs.COMMENT) Flags ^= FLAG_DOCOMMENT;
12761 if(amiargs.SORTED) Flags ^= FLAG_SORTED;
12762 if(amiargs.ONLYCNAMES) Flags ^= FLAG_ONLYCNAMES;
12763 if(amiargs.SYSTEMRELEASE) Flags2 ^= FLAG2_SYSTEMRELEASE;
12764 if(amiargs.VOIDBASE) Flags2 ^= FLAG2_VOIDBASE;
12765 if(amiargs.NOPPCREGNAME) PPCRegPrefix = "";
12766 if(amiargs.AUTOHEADER) Flags2 ^= FLAG2_AUTOHEADER;
12767 if(amiargs.SPECIAL)
12768 args.special = *amiargs.SPECIAL;
12769 if(amiargs.MODE)
12770 args.mode = *amiargs.MODE;
12771 if(amiargs.PRIORITY)
12772 priority = *amiargs.PRIORITY;
12774 FreeArgs(rda);
12776 else
12777 PrintFault(IoErr(), 0);
12778 FreeDosObject(DOS_RDARGS, rda);
12781 if(!res)
12782 /* printhelp(); */
12783 exit(20);
12786 #else
12787 static const strptr helptext =
12788 " -h,--help\n"
12789 " -i,--infile <input filename>\n"
12790 " -s,--special <number>\n"
12791 " -m,--mode <number>\n"
12792 " -t,--to <destination directory>\n"
12793 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12794 " -c,--clib <clib prototypes filename>\n"
12795 " -d,--header <header file or \"\">\n"
12796 " -i,--libname <name of library>\n"
12797 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12798 " -b,--basename <name of library base without '_'>\n"
12799 " -l,--libtype <name of base library type>\n"
12800 " -p,--priority <priority for auto open files>\n"
12801 " -r,--copyright<copyright text>\n"
12802 " --prefix <MorphOS gate prefix>\n"
12803 " --subprefix<MorphOS gate sub prefix>\n"
12804 " --premacro <MorphOS gate file start macro>\n"
12805 "\n"
12806 "Switches:\n"
12807 "--autoheader add the typical automatic generated header\n"
12808 "--comment copy comments found in input file\n"
12809 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12810 "--fpuonly work only with functions using FPU register arguments\n"
12811 "--newsyntax uses new Motorola syntax for asm files\n"
12812 "--nofpu disable usage of FPU register arguments\n"
12813 "--noppc disable usage of PPC-ABI functions\n"
12814 "--noppcregname do not add 'r' to PPC register names\n"
12815 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12816 "--onlycnames do not create C++ or ASM names\n"
12817 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12818 "--ppconly only use PPC-ABI functions\n"
12819 "--private includes private declared functions\n"
12820 "--section add section statements to asm texts\n"
12821 "--smallcode generate small code link libraries or assembler text\n"
12822 "--smalldata generate small data link libraries or assembler text\n"
12823 "--smalltypes allow 8 and 16 bit types in registers\n"
12824 "--sorted sort generated files by name and not by bias value\n"
12825 "--systemrelease special handling of comments for system includes\n"
12826 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12827 "--voidbase library bases are of type void *\n"
12828 "\n"
12829 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12830 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12831 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12832 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12833 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12834 " 6 - pragma for all compilers [default]\n"
12835 " 7 - all compilers with pragma to inline redirect for GCC\n"
12836 " 10 - stub-functions for C - C text\n"
12837 " 11 - stub-functions for C - assembler text\n"
12838 " 12 - stub-functions for C - link library\n"
12839 " 13 - defines and link library for local library base (register call)\n"
12840 " 14 - defines and link library for local library base (stack call)\n"
12841 " 15 - stub-functions for Pascal - assembler text\n"
12842 " 16 - stub-functions for Pascal - link library\n"
12843 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12844 " 18 - module for AmigaE\n"
12845 " 20 - assembler lvo _lvo.i file\n"
12846 " 21 - assembler lvo _lib.i file\n"
12847 " 22 - assembler lvo _lvo.i file no XDEF\n"
12848 " 23 - assembler lvo _lib.i file no XDEF\n"
12849 " 24 - assembler lvo link library\n"
12850 " 30 - proto file with pragma/..._lib.h call\n"
12851 " 31 - proto file with pragma/..._pragmas.h call\n"
12852 " 32 - proto file with pragmas/..._lib.h call\n"
12853 " 33 - proto file with pragmas/..._pragmas.h call\n"
12854 " 34 - proto file with local/..._loc.h call\n"
12855 " 35 - proto file for all compilers (VBCC stubs)\n"
12856 " 36 - proto file for GNU-C compiler only\n"
12857 " 37 - proto file without lib definitions\n"
12858 " 38 - proto file for all compilers (VBCC inline)\n"
12859 " 39 - proto file with special PPC related checks\n"
12860 " 40 - GCC inline file (preprocessor based)\n"
12861 " 41 - GCC inline file (old type - inline based)\n"
12862 " 42 - GCC inline file (library stubs)\n"
12863 " 43 - GCC inline file (new style - macro)\n"
12864 " 44 - GCC inline file (new style - inline)\n"
12865 " 45 - GCC inline file (new style - inline with include lines)\n"
12866 " 46 - GCC inline file (preprocessor based, direct)\n"
12867 " 47 - GCC inline file (new style, direct)\n"
12868 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12869 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12870 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12871 " 52 - GCC inline files for PowerUP (library stubs)\n"
12872 " 53 - SAS-C include file for PowerUP\n"
12873 " 54 - Proto file for PowerUP\n"
12874 " 60 - FPC pascal unit text\n"
12875 " 70 - VBCC inline files\n"
12876 " 71 - VBCC WOS stub-functions - assembler text\n"
12877 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12878 " 73 - VBCC WOS stub-functions - link library\n"
12879 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12880 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12881 " 76 - VBCC PowerUP stub-functions - link library\n"
12882 " 77 - VBCC WOS inline files\n"
12883 " 78 - VBCC MorphOS stub-functions - link library\n"
12884 " 79 - VBCC old inline files\n"
12885 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12886 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12887 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12888 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12889 " 90 - stub-functions for C - assembler text (multiple files)\n"
12890 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12891 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12892 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12893 " 100 - PPC assembler lvo file\n"
12894 " 101 - PPC assembler lvo file no XDEF\n"
12895 " 102 - PPC assembler lvo ELF link library\n"
12896 " 103 - PPC assembler lvo EHF link library\n"
12897 " 104 - PPC V.4-ABI assembler file\n"
12898 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12899 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12900 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12901 " 110 - FD file\n"
12902 " 111 - CLIB file\n"
12903 " 112 - SFD file\n"
12904 " 120 - VBCC auto libopen files (C source)\n"
12905 " 121 - VBCC auto libopen files (m68k link library)\n"
12906 " 122 - VBCC MorphOS inline files\n"
12907 " 123 - VBCC new MorphOS inline files\n"
12908 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12909 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12910 " 132 - GCC inline files for MorphOS (library stubs)\n"
12911 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12912 " 134 - MorphOS gate stubs\n"
12913 " 135 - MorphOS gate stubs (prelib)\n"
12914 " 136 - MorphOS gate stubs (postlib)\n"
12915 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12916 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12917 " 140 - OS4 XML file\n"
12918 " 141 - OS4 PPC->M68K cross-call stubs\n"
12919 " 142 - OS4 M68K->PPC cross-call stubs\n"
12920 " 200 - FD file (source is a pragma file!)\n"
12921 "mode: special 1-7\n"
12922 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12923 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12924 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12925 " 4 - no definition\n"
12926 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12927 " 130-138,141:\n"
12928 " 1 - all functions, normal interface\n"
12929 " 2 - only tag-functions, tagcall interface\n"
12930 " 3 - all functions, normal and tagcall interface [default]\n";
12932 /* print the help text */
12933 static void printhelp(void)
12935 printf("%s\n%s", version+6, helptext);
12936 exit(20);
12939 struct ArgData
12941 strptr ArgName;
12942 uint8 ArgChar;
12943 uint8 ArgNameLen;
12944 uint8 ArgNum;
12947 enum ArgNums {
12948 ARG_HELP, ARG_INFILE, ARG_SPECIAL, ARG_MODE, ARG_TO, ARG_CLIB, ARG_ABI, ARG_COPYRIGHT,
12949 ARG_HEADER, ARG_HUNKNAME, ARG_BASENAME, ARG_LIBTYPE,
12950 ARG_COMMENT, ARG_EXTERNC, ARG_FPUONLY, ARG_NEWSYNTAX, ARG_NOFPU, ARG_NOPPC,
12951 ARG_NOSYMBOL, ARG_ONLYCNAMES, ARG_OPT040, ARG_PPCONLY, ARG_PRIVATE, ARG_SECTION,
12952 ARG_SMALLDATA, ARG_SORTED, ARG_USESYSCALL, ARG_NOPPCREGNAME,
12953 ARG_SYSTEMRELEASE, ARG_PRIORITY, ARG_LIBNAME, ARG_SMALLCODE, ARG_VOIDBASE,
12954 ARG_PREFIX, ARG_SUBPREFIX, ARG_PREMACRO, ARG_SMALLTYPES, ARG_AUTOHEADER
12957 /* argument definition array */
12958 static const struct ArgData argtexts[] = {
12959 {"help", 'h', 4, ARG_HELP},
12960 {"infile", 'i', 6, ARG_INFILE},
12961 {"special", 's', 7, ARG_SPECIAL},
12962 {"mode", 'm', 4, ARG_MODE},
12963 {"to", 't', 2, ARG_TO},
12964 {"clib", 'c', 4, ARG_CLIB},
12965 {"abi", 'a', 3, ARG_ABI},
12966 {"copyright", 'r', 9, ARG_COPYRIGHT},
12967 {"header", 'd', 6, ARG_HEADER},
12968 {"hunkname", 'n', 8, ARG_HUNKNAME},
12969 {"basename", 'b', 8, ARG_BASENAME},
12970 {"libtype", 'l', 7, ARG_LIBTYPE},
12971 {"libname", 'i', 7, ARG_LIBNAME},
12972 {"priority", 'p', 8, ARG_PRIORITY},
12973 {"autoheader", 0, 10, ARG_AUTOHEADER},
12974 {"comment", 0, 7, ARG_COMMENT},
12975 {"externc", 0, 7, ARG_EXTERNC},
12976 {"fpuonly", 0, 7, ARG_FPUONLY},
12977 {"newsyntax", 0, 9, ARG_NEWSYNTAX},
12978 {"nofpu", 0, 5, ARG_NOFPU},
12979 {"noppc", 0, 5, ARG_NOPPC},
12980 {"noppcregname", 0, 12, ARG_NOPPCREGNAME},
12981 {"nosymbol", 0, 8, ARG_NOSYMBOL},
12982 {"onlycnames", 0, 10, ARG_ONLYCNAMES},
12983 {"opt040", 0, 6, ARG_OPT040},
12984 {"ppconly", 0, 7, ARG_PPCONLY},
12985 {"private", 0, 7, ARG_PRIVATE},
12986 {"section", 0, 7, ARG_SECTION},
12987 {"smalldata", 0, 9, ARG_SMALLDATA},
12988 {"smalltypes", 0, 10, ARG_SMALLTYPES},
12989 {"smallcode", 0, 9, ARG_SMALLCODE},
12990 {"sorted", 0, 6, ARG_SORTED},
12991 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE},
12992 {"usesyscall", 0, 10, ARG_USESYSCALL},
12993 {"voidbase", 0, 8, ARG_VOIDBASE},
12994 {"prefix", 0, 6, ARG_PREFIX},
12995 {"subprefix", 0, 9, ARG_SUBPREFIX},
12996 {"premacro", 0, 8, ARG_PREMACRO},
12997 {0,0,0,0}, /* end marker */
13000 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
13001 static uint32 ParseArgEntry(uint32 argc, strptr *argv)
13003 uint32 numentries = 1, l;
13004 strptr a, b;
13005 const struct ArgData *ad;
13007 if((*argv)[0] != '-' || !(*argv)[1])
13008 return 0;
13010 ad = argtexts;
13011 while(ad->ArgName)
13013 if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
13014 break;
13015 ++ad;
13017 if(!ad->ArgName)
13018 return 0;
13019 switch(ad->ArgNum)
13021 case ARG_HELP: printhelp(); break;
13022 case ARG_EXTERNC: Flags ^= FLAG_EXTERNC; break;
13023 case ARG_PRIVATE: Flags ^= FLAG_PRIVATE; break;
13024 case ARG_NEWSYNTAX: Flags ^= FLAG_NEWSYNTAX; break;
13025 case ARG_SMALLDATA: Flags ^= FLAG_SMALLDATA; break;
13026 case ARG_SMALLCODE: Flags2 ^= FLAG2_SMALLCODE; break;
13027 case ARG_SMALLTYPES: Flags2 ^= FLAG2_SMALLTYPES; break;
13028 case ARG_USESYSCALL: Flags ^= FLAG_SYSCALL; break;
13029 case ARG_OPT040: Flags ^= FLAG_NOMOVEM; break;
13030 case ARG_NOFPU: Flags ^= FLAG_NOFPU; break;
13031 case ARG_FPUONLY: Flags ^= FLAG_FPUONLY; break;
13032 case ARG_NOPPC: Flags ^= FLAG_NOPPC; break;
13033 case ARG_NOSYMBOL: Flags ^= FLAG_NOSYMBOL; break;
13034 case ARG_PPCONLY: Flags ^= FLAG_PPCONLY; break;
13035 case ARG_SECTION: Flags ^= FLAG_ASMSECTION; break;
13036 case ARG_COMMENT: Flags ^= FLAG_DOCOMMENT; break;
13037 case ARG_SORTED: Flags ^= FLAG_SORTED; break;
13038 case ARG_ONLYCNAMES: Flags ^= FLAG_ONLYCNAMES; break;
13039 case ARG_SYSTEMRELEASE: Flags2 ^= FLAG2_SYSTEMRELEASE; break;
13040 case ARG_VOIDBASE: Flags2 ^= FLAG2_VOIDBASE; break;
13041 case ARG_AUTOHEADER: Flags2 ^= FLAG2_AUTOHEADER; break;
13042 case ARG_NOPPCREGNAME: PPCRegPrefix = "";
13043 default:
13044 a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
13045 if(!(*a))
13047 if(argc > 1) { a = argv[1]; numentries = 2; }
13048 else { a = 0; numentries = 0;}
13050 else if(*a == '=')
13051 ++a;
13052 if(a)
13054 if(*a == '\"')
13056 l = strlen(++a);
13057 if(a[l-1] == '\"')
13058 a[--l] = 0; /* remove second " */
13060 switch(ad->ArgNum)
13062 case ARG_INFILE: args.infile = a; break;
13063 case ARG_COPYRIGHT: Copyright = a; break;
13064 case ARG_TO: args.to = a; break;
13065 case ARG_ABI: defabi = a; break;
13066 case ARG_CLIB: args.clib = a; break;
13067 case ARG_HEADER: args.header = a; break;
13068 case ARG_HUNKNAME: hunkname = a; break;
13069 case ARG_PREFIX: prefix = a; break;
13070 case ARG_SUBPREFIX: subprefix = a; break;
13071 case ARG_PREMACRO: premacro = a; break;
13072 case ARG_LIBTYPE: libtype = a; Flags2 |= FLAG2_LIBTYPE; break;
13073 case ARG_LIBNAME: libname = a; Flags2 |= FLAG2_LIBNAME; break;
13074 case ARG_BASENAME: BaseName = a; Flags |= FLAG_BASENAME; break;
13075 case ARG_SPECIAL:
13076 args.special = strtoul(a, &b, 10);
13077 if(*b)
13078 numentries = 0;
13079 break;
13080 case ARG_PRIORITY:
13081 priority = strtoul(a, &b, 10);
13082 if(*b)
13083 numentries = 0;
13084 break;
13085 case ARG_MODE:
13086 args.mode = strtoul(a, &b, 10);
13087 if(*b || args.mode < 1 || args.mode > 3)
13088 numentries = 0;
13089 break;
13093 return numentries;
13096 /* initializes the arguments and starts argument parsing */
13097 static void GetArgs(int argc, char **argv)
13099 int res = 1;
13100 int i = 1, j;
13102 while(i < argc && res)
13104 if((j = ParseArgEntry(argc-i, argv+i)) < 1)
13105 res = 0;
13106 else
13107 i += j;
13109 if(!res || !args.infile)
13110 printhelp();
13113 #endif
13115 static strptr mygetfile(strptr name, size_t *len)
13117 strptr ptr = 0;
13118 FILE *infile;
13120 if((infile = fopen(name, "rb")))
13122 if(!fseek(infile, 0, SEEK_END))
13124 *len = ftell(infile);
13125 if(!fseek(infile, 0, SEEK_SET))
13127 if((ptr = AllocListMem(*len+1)))
13129 ptr[*len] = 0;
13130 #ifdef DEBUG_OLD
13131 printf("mygetfile: '%s' size %d\n", name, *len);
13132 #endif
13133 if(fread(ptr, *len, 1, infile) != 1)
13134 ptr = 0;
13138 fclose(infile);
13140 return ptr;
13143 int main(int argc, char **argv)
13145 uint32 mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_BOTH;
13146 strptr amicall = 0, libcall = 0, amitags = 0, libtags = 0;
13147 strptr clibbuf;
13148 size_t clibsize = 0;
13150 GetArgs(argc, argv);
13152 if((tempbuf = (uint8 *) AllocListMem(TEMPSIZE)))
13154 if(!(in.pos = in.buf = mygetfile(args.infile, &in.size)))
13156 if(args.special == 200)
13158 DoError(ERR_OPEN_FILE, 0, args.infile);
13159 exit(20);
13161 else
13163 sprintf((strptr)tempbuf, "%s" SFDFILEEXTENSION, args.infile);
13164 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13166 sprintf((strptr)tempbuf, "%s" FDFILEEXTENSION, args.infile);
13167 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13169 DoError(ERR_OPEN_FILE, 0, args.infile);
13170 exit(20);
13172 else
13173 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13175 else
13176 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13179 printf("SourceFile: %s\n", args.infile);
13181 MakeLines(in.pos, in.size);
13183 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SORTED)) /* is not possible to use both */
13185 DoError(ERR_SORTED_COMMENT, 0);
13186 Flags &= (~FLAG_SORTED);
13189 if(args.special == 200)
13191 CreateFDFile();
13192 exit(0);
13195 if(!GetTypes())
13196 exit(20);
13198 if(!ScanFDFile())
13199 exit(20);
13201 if(args.clib)
13203 if(Flags2 & FLAG2_SFDMODE)
13204 DoError(ERR_SFD_AND_CLIB, 0);
13205 else
13207 sprintf((strptr)tempbuf, "%s_protos.h", args.clib);
13208 if(!(clibbuf = mygetfile(args.clib, &clibsize)) && !(clibbuf = mygetfile((strptr)tempbuf, &clibsize)))
13210 DoError(ERR_OPEN_FILE, 0, args.clib);
13211 exit(20);
13213 ScanClibFile(clibbuf, clibbuf+clibsize);
13217 if(!MakeShortBaseName())
13219 DoError(ERR_MISSING_SHORTBASENAME, 0);
13220 exit(20);
13223 /* WARN when requesting obsolete types! */
13224 switch(args.special)
13226 case 1: case 2: case 3: case 4: case 5: case 7:
13227 printf("You use obsolete data type %ld, better use type 6!\n", args.special);
13228 break;
13229 case 11: case 15: case 71: case 72: case 75:
13230 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13231 "link libraries!\n", args.special);
13232 break;
13233 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13234 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args.special);
13235 break;
13236 case 79:
13237 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13238 break;
13241 if(args.special < 10) /* the pragma area is up to 9 */
13243 mode = MODUS_PRAGMA;
13244 sprintf(filename, "%s_lib.h", ShortBaseName);
13246 switch(args.special)
13248 case 0: break;
13249 case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
13250 case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13251 pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
13252 case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13253 pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
13254 libtags = "def " TEXT_SAS_60; break;
13255 case 4: amicall = ""; break;
13256 case 5: amicall = amitags = ""; break;
13257 case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
13258 case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
13259 TEXT_MAXON ") || defined(" TEXT_STORM ")";
13260 libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
13261 libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
13262 default: mode = MODUS_ERROR; break;
13265 if(args.mode > 0 && args.mode < 5)
13266 pragmode = args.mode;
13268 else if(args.special < 20) /* the misc area is up to 19 */
13270 if(args.mode > 0 && args.mode < 4)
13271 callmode = args.mode - 1;
13272 switch(args.special)
13274 case 10: mode = MODUS_CSTUB;
13275 sprintf(filename, "%s_cstub.h", ShortBaseName); break;
13276 case 11: mode = MODUS_STUBTEXT;
13277 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13278 case 12: mode = MODUS_STUBCODE;
13279 sprintf(filename, "%s.lib", ShortBaseName); break;
13280 case 13: Flags |= FLAG_LOCALREG; /* no break ! */
13281 case 14: mode = MODUS_LOCALDATA;
13282 sprintf(filename, "%s_loc.h", ShortBaseName); break;
13283 case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
13284 Flags ^= FLAG_PASCAL;
13285 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13286 case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
13287 Flags ^= FLAG_PASCAL;
13288 sprintf(filename, "%s.lib", ShortBaseName); break;
13289 case 17: mode = MODUS_BMAP; callmode = TAGMODE_NORMAL;
13290 sprintf(filename, "%s.bmap", ShortBaseName); break;
13291 case 18: mode = MODUS_EMODULE;
13292 sprintf(filename, "%s.m", ShortBaseName); break;
13293 default: mode = MODUS_ERROR; break;
13296 else if(args.special < 30) /* the lvo area is up to 29 */
13298 switch(args.special)
13300 case 20: case 22: mode = MODUS_LVO+args.special-20;
13301 sprintf(filename, "%s_lvo.i", ShortBaseName); break;
13302 case 21: case 23: mode = MODUS_LVO+args.special-20;
13303 sprintf(filename, "%s_lib.i", ShortBaseName); break;
13304 case 24: mode = MODUS_LVOLIB;
13305 sprintf(filename, "%slvo.o", ShortBaseName); break;
13306 default: mode = MODUS_ERROR; break;
13309 else if(args.special < 40) /* the proto area is up to 39 */
13311 if(args.special < 40)
13313 mode = MODUS_PROTO+args.special-30;
13314 sprintf(filename, "%s.h", ShortBaseName);
13316 else
13317 mode = MODUS_ERROR;
13319 else if(args.special < 50) /* the inline area is up to 49 */
13321 if(args.mode > 0 && args.mode < 4)
13322 callmode = args.mode - 1;
13324 switch(args.special)
13326 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13327 case 47:
13328 mode = MODUS_INLINE+args.special-40;
13329 sprintf(filename, "%s.h", ShortBaseName); break;
13330 case 48:
13331 Flags |= FLAG_STORMGCC;
13332 /* the same mode as for 46, but additional flag */
13333 mode = MODUS_INLINE+args.special-40-2;
13334 sprintf(filename, "%s.h", ShortBaseName); break;
13335 default: mode = MODUS_ERROR; break;
13338 else if(args.special < 60) /* the PowerUP area is up to 59 */
13340 if(args.mode > 0 && args.mode < 4)
13341 callmode = args.mode - 1;
13343 switch(args.special)
13345 case 50: case 51: case 52: mode = MODUS_INLINE+args.special-50;
13346 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_POWERUP;
13347 break;
13348 case 53:
13349 sprintf(filename, "%s_pragmas.h", ShortBaseName);
13350 mode = MODUS_SASPOWER; break;
13351 case 54:
13352 sprintf(filename, "%s.h", ShortBaseName);
13353 mode = MODUS_PROTOPOWER; break;
13354 default: mode = MODUS_ERROR; break;
13357 else if(args.special < 70) /* the PASCAL stuff */
13359 if(args.special == 60)
13361 mode = MODUS_PASCAL;
13362 sprintf(filename, "%s.pas", ShortBaseName);
13364 else
13365 mode = MODUS_ERROR;
13367 else if(args.special < 80) /* the VBCC stuff */
13369 if(args.mode > 0 && args.mode < 4)
13370 callmode = args.mode - 1;
13372 switch(args.special)
13374 case 70: mode = MODUS_VBCCINLINE;
13375 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13376 case 71: case 72: case 75:
13377 mode = MODUS_VBCC+args.special-71;
13378 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13379 case 73: case 74:
13380 mode = MODUS_VBCC+args.special-71;
13381 sprintf(filename, "%s.lib", ShortBaseName); break;
13382 case 76:
13383 mode = MODUS_VBCCPUPLIB;
13384 sprintf(filename, "lib%s.a", ShortBaseName); break;
13385 case 77: mode = MODUS_VBCCWOSINLINE;
13386 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13387 case 78: mode = MODUS_VBCCMORPHCODE;
13388 sprintf(filename, "lib%s.a", ShortBaseName); break;
13389 case 79: mode = MODUS_VBCCINLINE;
13390 Flags2 |= FLAG2_OLDVBCC;
13391 callmode = TAGMODE_NORMAL;
13392 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13393 default: mode = MODUS_ERROR; break;
13396 else if(args.special < 90) /* redirect stuff */
13398 mode = MODUS_REDIRECT;
13399 switch(args.special)
13401 case 80: sprintf(filename, "%s_pragmas.h", ShortBaseName); break;
13402 case 81: sprintf(filename, "%s_lib.h", ShortBaseName); break;
13403 case 82: sprintf(filename, "%s.h", ShortBaseName); break;
13404 case 83: sprintf(filename, "%s_protos.h", ShortBaseName); break;
13405 default: mode = MODUS_ERROR; break;
13408 else if(args.special < 100) /* multifile stuff */
13410 Flags |= FLAG_SINGLEFILE;
13411 switch(args.special)
13413 case 90:
13414 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13415 mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
13416 break;
13417 case 91:
13418 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13419 mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
13420 break;
13421 case 92:
13422 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13423 mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
13424 break;
13425 case 93:
13426 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13427 mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
13428 break;
13429 default: mode = MODUS_ERROR; break;
13432 else if(args.special < 110) /* PPC lvo's */
13434 switch(args.special)
13436 case 100: case 101: mode = MODUS_LVOPPC+args.special-100;
13437 sprintf(filename, "%s_lib.i", ShortBaseName);
13438 break;
13439 case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
13440 Flags |= FLAG_ABIV4;
13441 sprintf(filename, "%s_lib.i", ShortBaseName);
13442 break;
13443 case 103: mode = MODUS_LVOLIB;
13444 sprintf(filename, "%slvo.o", ShortBaseName);
13445 break;
13446 case 107: mode = MODUS_LVOLIB;
13447 Flags |= FLAG_ABIV4;
13448 sprintf(filename, "%slvo.o", ShortBaseName);
13449 break;
13450 case 102: mode = MODUS_LVOLIBPPC;
13451 sprintf(filename, "%slvo.o", ShortBaseName); break;
13452 case 106: mode = MODUS_LVOLIBPPC;
13453 Flags |= FLAG_ABIV4;
13454 sprintf(filename, "%slvo.o", ShortBaseName); break;
13455 default: mode = MODUS_ERROR; break;
13458 else if(args.special < 120) /* different files */
13460 if(args.mode > 0 && args.mode < 4)
13461 callmode = args.mode - 1;
13463 switch(args.special)
13465 case 110: mode = MODUS_FD;
13466 sprintf(filename, "%s_lib.fd", ShortBaseName);
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 case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
13474 sprintf(filename, "%s_protos.h", ShortBaseName);
13475 break;
13476 case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
13477 sprintf(filename, "%s_lib.sfd", ShortBaseName);
13478 if(callmode == 1)
13480 callmode = 2;
13481 DoError(ERR_ONLYTAGMODE_NOTALLOWED, 0);
13484 if(Flags & FLAG_SORTED) /* is not possible to use here */
13486 DoError(ERR_SORTED_SFD_FD, 0);
13487 Flags &= (~FLAG_SORTED);
13489 break;
13490 default: mode = MODUS_ERROR; break;
13493 else if(args.special < 130) /* auto libopen files */
13495 if(args.mode > 0 && args.mode < 4) /* for 122 */
13496 callmode = args.mode - 1;
13498 switch(args.special)
13500 case 120: mode = MODUS_GENAUTO;
13501 sprintf(filename, "%s_autoopenlib.c", ShortBaseName);
13502 break;
13503 case 121: mode = MODUS_GENAUTO+(args.special-120);
13504 sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
13505 break;
13506 case 123: Flags2 |= FLAG2_SHORTPPCVBCCINLINE; /* no break */
13507 case 122: mode = MODUS_VBCCMORPHINLINE;
13508 PPCRegPrefix = ""; /* no "r" allowed */
13509 sprintf(filename, "%s_protos.h", ShortBaseName);
13510 break;
13511 default: mode = MODUS_ERROR; break;
13514 else if(args.special < 140) /* the MorphOS area is up to 139 */
13516 if(args.mode > 0 && args.mode < 4)
13517 callmode = args.mode - 1;
13519 switch(args.special)
13521 case 130: case 131: case 132: mode = MODUS_INLINE+args.special-130;
13522 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13523 break;
13524 case 133: mode = MODUS_INLINE+2;
13525 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13526 Flags2 |= FLAG2_DIRECTVARARGS;
13527 break;
13528 case 134: mode = MODUS_GATESTUBS;
13529 sprintf(filename, "%s_gates.h", ShortBaseName);
13530 break;
13531 case 135: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB;
13532 sprintf(filename, "%s_gates.h", ShortBaseName);
13533 break;
13534 case 136: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB;
13535 sprintf(filename, "%s_gates.h", ShortBaseName);
13536 break;
13537 case 137: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB|FLAG2_REGLIB;
13538 sprintf(filename, "%s_gates.h", ShortBaseName);
13539 break;
13540 case 138: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB|FLAG2_REGLIB;
13541 sprintf(filename, "%s_gates.h", ShortBaseName);
13542 break;
13543 default: mode = MODUS_ERROR; break;
13546 else if(args.special < 150) /* the OS4 area is up to 139 */
13548 if(args.mode > 0 && args.mode < 4)
13549 callmode = args.mode - 1;
13551 switch(args.special)
13553 case 140:
13554 mode = MODUS_XML;
13555 sprintf(filename, "%s.xml", ShortBaseName);
13556 break;
13557 case 141: /* OS4 PPC->M68K cross-call stubs */
13558 mode = MODUS_OS4_PPCSTUBS;
13559 sprintf(filename, "%s.c", ShortBaseName);
13560 break;
13561 case 142: /* OS4 M68K->PPC cross-call stubs */
13562 mode = MODUS_OS4_68KSTUBS;
13563 sprintf(filename, "%s_68k.s", ShortBaseName);
13564 break;
13565 default: mode = MODUS_ERROR; break;
13568 if(Flags & FLAG_SORTED)
13569 SortFDList();
13571 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SINGLEFILE)) /* is not possible to use both */
13573 DoError(ERR_COMMENT_SINGLEFILE, 0);
13574 Flags &= (~FLAG_DOCOMMENT);
13577 if(!mode || mode == MODUS_ERROR)
13578 printhelp();
13580 /* These modes need BaseName always. */
13581 if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
13582 mode == MODUS_STUBCODE || mode == MODUS_EMODULE || (mode >= MODUS_GENAUTO &&
13583 mode <= MODUS_GENAUTO+9)))
13585 DoError(ERR_MISSING_BASENAME, 0);
13586 exit(20);
13589 if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
13591 HEADER = mygetfile(args.header, &headersize);
13592 args.header = 0;
13595 if(!(Flags & FLAG_SINGLEFILE))
13597 if(!OpenDest(filename))
13598 exit(20);
13601 /* from here mode is used as return result */
13602 if(mode >= MODUS_GENAUTO)
13603 mode = CreateGenAuto(filename, mode-MODUS_GENAUTO);
13604 else if(mode >= MODUS_LVOPPC)
13605 mode = CreateLVOFilePPC(mode-MODUS_LVOPPC);
13606 else if(mode >= MODUS_VBCC)
13607 mode = CreateVBCC(mode-MODUS_VBCC, callmode);
13608 else if(mode >= MODUS_INLINE)
13609 mode = CreateInline(mode-MODUS_INLINE, callmode);
13610 else if(mode >= MODUS_PROTO)
13611 mode = CreateProtoFile(mode-MODUS_PROTO+1);
13612 else if(mode >= MODUS_LVO)
13613 mode = CreateLVOFile(mode-MODUS_LVO+1);
13614 else if(mode == MODUS_VBCCMORPHINLINE)
13615 mode = CreateVBCCInline(2, callmode);
13616 else if(mode == MODUS_XML)
13617 mode = CreateXML();
13618 else if(mode == MODUS_OS4_PPCSTUBS)
13619 mode = CreateOS4PPC(callmode);
13620 else if(mode == MODUS_OS4_68KSTUBS)
13621 mode = CreateOS4M68K();
13622 else if(mode == MODUS_GATESTUBS)
13623 mode = CreateGateStubs(callmode);
13624 else if(mode == MODUS_SFD)
13625 mode = CreateSFD(callmode);
13626 else if(mode == MODUS_CLIB)
13627 mode = CreateClib(callmode);
13628 else if(mode == MODUS_FD)
13629 mode = CreateFD();
13630 else if(mode == MODUS_LVOLIBPPC)
13631 mode = CreateLVOLibPPC();
13632 else if(mode == MODUS_VBCCMORPHCODE)
13633 mode = CreateVBCCMorphCode(callmode);
13634 else if(mode == MODUS_VBCCMORPHTEXTSF) /* single files */
13635 mode = CallFunc(callmode, "\n%s", FuncVBCCMorphText);
13636 else if(mode == MODUS_VBCCWOSINLINE)
13637 mode = CreateVBCCInline(1, callmode);
13638 else if(mode == MODUS_VBCCWOSTEXTSF) /* single files */
13639 mode = CallFunc(callmode, "\n%s", FuncVBCCWOSText);
13640 else if(mode == MODUS_VBCCPUPTEXTSF) /* single files */
13641 mode = CallFunc(callmode, "\n%s", FuncVBCCPUPText);
13642 else if(mode == MODUS_ASMTEXTSF) /* single files */
13643 mode = CallFunc(callmode, "\n%s", FuncAsmText);
13644 else if(mode == MODUS_REDIRECT)
13645 mode = CreateProtoRedirect();
13646 else if(mode == MODUS_EMODULE)
13647 mode = CreateEModule(Flags & FLAG_SORTED);
13648 else if(mode == MODUS_LVOLIB)
13649 mode = CreateLVOLib();
13650 else if(mode == MODUS_VBCCPUPLIB)
13651 mode = CreateVBCCPUPLib(callmode);
13652 else if(mode == MODUS_VBCCINLINE)
13653 mode = CreateVBCCInline(0, callmode);
13654 else if(mode == MODUS_PASCAL)
13655 mode = CreateFPCUnit();
13656 else if(mode == MODUS_BMAP)
13657 mode = CreateBMAP();
13658 else if(mode == MODUS_PROTOPOWER)
13659 mode = CreateProtoPowerUP();
13660 else if(mode == MODUS_SASPOWER)
13661 mode = CreateSASPowerUP(callmode);
13662 else if(mode == MODUS_CSTUB)
13663 mode = CreateCSTUBSFile();
13664 else if(mode == MODUS_PRAGMA)
13665 mode = CreatePragmaFile(amicall, libcall, amitags, libtags, pragmode);
13666 else if(mode == MODUS_LOCALDATA)
13667 mode = CreateLocalData(filename, callmode);
13668 else if(mode) /* MODUS_STUBTEXT starts with 1 */
13669 mode = CreateAsmStubs(mode, callmode);
13671 CloseDest(filename);
13673 if(!mode)
13675 DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
13676 exit(20);
13678 free(tempbuf);
13681 return 0;