updated to grub2-git 20150201. host's using clang can now build pc-x86 based aros...
[AROS.git] / tools / fd2pragma / fd2pragma.c
blob0271e7dffd6bb4e03069223d70a70a7823b19acf
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, basereg = 12;
8219 uint8 *data, *data2, *data3;
8220 struct ArHeader *arh;
8222 data = tempbuf;
8224 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
8225 return 1;
8227 Flags |= FLAG_DONE;
8229 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8230 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8231 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8232 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8233 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
8234 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
8235 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
8236 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8237 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8238 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8239 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
8240 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
8241 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
8242 EndPutM32Inc(data, 0); /* eeh->e_entry */
8243 EndPutM32Inc(data, 0); /* eeh->e_phoff */
8244 data2 = data; data += 4;
8245 EndPutM32Inc(data, 0); /* eeh->e_flags */
8246 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
8247 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
8248 EndPutM16Inc(data, 0); /* eeh->e_phnum */
8249 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
8250 EndPutM16Inc(data, 6); /* eeh->e_shnum */
8251 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
8253 data3 = data;
8255 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
8257 if(Flags & FLAG_SMALLDATA)
8259 k = (data-data3)+2; /* store reloc offset */
8260 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8262 else
8264 k = (data-data3)+2; /* store reloc offset */
8265 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8266 EndPutM32Inc(data, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8269 EndPutM32Inc(data, 0x800c0000 - (ap->Bias-2));
8270 EndPutM32Inc(data, 0x7c0903a6); /* mtctr r0 */
8271 EndPutM32Inc(data, 0x4e800420); /* bctr */
8274 else
8276 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8278 if(flags & FUNCFLAG_TAG)
8280 /* mflr r0 = mfspr r0,8 = get link register */
8281 EndPutM32Inc(data, 0x7C0802A6);
8282 /* backchain to next frame: lwz r11,0(r1) */
8283 EndPutM32Inc(data, 0x81610000);
8284 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8285 EndPutM32Inc(data, 0x7D815850);
8286 EndPutM32Inc(data, 0x90010004); /* stw r0,4(r1) */
8287 EndPutM32Inc(data, 0x7D6C0850); /* sub r11,r1,r12 */
8288 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8289 EndPutM32Inc(data, 0x396BFFF0);
8290 EndPutM32Inc(data, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8291 EndPutM32Inc(data, 0x558CF0BE); /* srwi r12,r12,2 */
8292 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8293 EndPutM32Inc(data, 0x380CFFFE);
8294 EndPutM32Inc(data, 0x39810004); /* addi r12,r1,4 */
8295 EndPutM32Inc(data, 0x7D615B78); /* mr r1,r11 - new stack frame */
8296 EndPutM32Inc(data, 0x396B0008); /* addi r11,r11,8 */
8297 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8298 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8299 EndPutM32Inc(data, 0x840C0004);
8300 EndPutM32Inc(data, 0x940B0004); /* stwu r0,4(r11) */
8301 EndPutM32Inc(data, 0x4200FFF8); /* bdnz .l */
8302 /* stw r10,8(r1) - last register into stack */
8303 EndPutM32Inc(data, 0x91410008);
8305 else if(ap->NumArgs >= 8)
8307 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8308 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 */
8309 EndPutM32Inc(data, 0x94220000 - stcksize); /* stwu r1,-X(r1) */
8310 EndPutM32Inc(data, 0x90010000 + stcksize + 4); /* stw r0,Y(r1) */
8312 basereg = 3;
8314 else if(flags & FUNCFLAG_TAG)
8316 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8317 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8320 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8321 || ap->NumArgs >= 8))
8323 EndPutM32Inc(data, 0x94210000+0x10000-(stcksize+nrcopyar*4)); /* stwu r1,-%d(r1) */
8324 /* mflr r0 = mfspr r0,8 = get link register */
8325 EndPutM32Inc(data, 0x7C0802A6);
8328 if(nrcopyar)
8330 /* Hack the stack-frame for varargs.
8331 Build stack-frame, but save LR in our own stack-frame,
8332 because we have to overwrite the lower 8 bytes of the
8333 caller's frame. */
8334 /* Save the caller's saved SP in our own stack-frame. */
8335 EndPutM32Inc(data, 0x81610000+stcksize+nrcopyar*4); /* lwz r11,%d(r1) */
8336 EndPutM32Inc(data, 0x91610000+stcksize); /* stw r11,%d(r1) */
8338 /* Store r3-r8 at the top of our stack-frame and r9-r10
8339 at the low 8 bytes of the caller's frame. This way all
8340 arguments will reside in one continuous area.
8341 Only copy the really relevant parts. */
8342 for(i = 10; i > 10-nrcopyar; --i)
8343 EndPutM32Inc(data, 0x90010000 + (i<<21) + (stcksize+4*(i-1+nrcopyar-8))); /* stw rX,Y(r1) */
8346 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8348 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8350 for(i = ap->NumArgs-1; i; --i)
8352 if(i < 7)
8354 /* mr rX,rY */
8355 EndPutM32Inc(data, 0x7C000378 + ((3+i)<<21) + ((3+i-1)<<16) + ((3+i-1)<<11));
8357 else if(i == 7)
8359 /* stw r10,8(r1) */
8360 EndPutM32Inc(data, 0x91410008);
8362 else
8364 /* lwz r11,X(r1) */
8365 EndPutM32Inc(data, 0x81610000 + (stcksize+((i-8)+3)*4));
8366 EndPutM32Inc(data, 0x91620000 + ((i-8)+3)*4); /* stw r11,j(r1) */
8370 else
8372 /* shift all the arguments one field */
8373 for(i = ap->NumArgs+3; i > 3; --i)
8375 /* mr rX,rY */
8376 EndPutM32Inc(data, 0x7C000378 + (i<<21) + ((i-1)<<16) + ((i-1)<<11));
8381 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8382 || ap->NumArgs >= 8))
8383 EndPutM32Inc(data, 0x90010000+stcksize+4); /* stw r0,%d(r1) */
8385 if(BaseName)
8387 if(Flags & FLAG_SMALLDATA)
8389 k = (data-data3)+2; /* store reloc offset */
8390 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8392 else
8394 k = (data-data3)+2; /* store reloc offset */
8395 EndPutM32Inc(data, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8396 EndPutM32Inc(data, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8400 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8402 /* lwz r0,X(r3) */
8403 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2));
8404 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8405 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8407 else
8409 for(i = 0; i < ap->NumArgs; ++i)
8411 j = 4*ap->Args[i].ArgReg;
8412 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8414 if(i <= 7)
8416 EndPutM32Inc(data, 0x90020000 + ((i+3)<<21) + j); /* stw rX,j(r2) */
8418 else
8420 EndPutM32Inc(data, 0x81610000 + (stcksize+(i+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8421 EndPutM32Inc(data, 0x91620000 + j); /* stw r11,j(r1) */
8424 else
8426 EndPutM32Inc(data, 0x38810000 + (stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0))); /* addi r4,r1,X */
8427 EndPutM32Inc(data, 0x90820000 + j); /* stw r4,X(r2) */
8432 EndPutM32Inc(data, 0x81620064); /* lwz r11,100(r2) */
8434 if(BaseName)
8435 EndPutM32Inc(data, 0x91820038); /* stw r12,56(r2) */
8437 /* Now place the real function call */
8438 EndPutM32Inc(data, 0x38600000 + 0x10000 - ap->Bias); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8440 EndPutM32Inc(data, 0x7D6903A6); /* mtctr r11 */
8441 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8443 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8445 EndPutM32Inc(data, 0x81610000 + stcksize); /* lwz r11,X(r1) */
8446 EndPutM32Inc(data, 0x91610000 + (stcksize+nrcopyar*4)); /* stw r11,Y(r1) */
8449 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8450 || ap->NumArgs >= 8))
8452 if(ap->NumArgs >= 8)
8454 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8455 EndPutM32Inc(data, 0x38210000 + stcksize); /* addi r1,r1,Y */
8456 /* mtlr r0 = mtspr 8,r0 = restore link register */
8457 EndPutM32Inc(data, 0x7C0803A6);
8459 else
8461 /* restore old stack frame: lwz r1,0(r1) */
8462 EndPutM32Inc(data, 0x80210000);
8463 EndPutM32Inc(data, 0x80010004); /* lwz r0,4(r1) */
8464 /* mtlr r0 = mtspr 8,r0 = restore link register */
8465 EndPutM32Inc(data, 0x7C0803A6);
8468 else
8470 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8471 EndPutM32Inc(data, 0x38210000 + (stcksize+nrcopyar*4)); /* addi r1,r1,Y */
8472 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8475 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
8478 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8479 data += 44; /* 1 9 17 27 33 */
8481 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
8482 data2 = data-44;
8484 EndPutM32Inc(data, 0); /* esh[0].sh_name */
8485 EndPutM32Inc(data, 0); /* esh[0].sh_type */
8486 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8487 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8488 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
8489 EndPutM32Inc(data, 0); /* esh[0].sh_size */
8490 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8491 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8492 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
8493 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8495 size = data2-data3;
8496 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
8497 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
8498 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
8499 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
8500 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
8501 EndPutM32Inc(data, size); /* esh[1].sh_size */
8502 EndPutM32Inc(data, 0); /* esh[1].sh_link */
8503 EndPutM32Inc(data, 0); /* esh[1].sh_info */
8504 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
8505 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
8507 data3 = data;
8508 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
8509 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
8510 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
8511 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
8512 data += 4; /* esh[2].sh_offset */
8513 data += 4; /* esh[2].sh_size */
8514 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8515 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
8516 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
8517 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8519 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
8520 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
8521 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
8522 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
8523 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
8524 EndPutM32Inc(data, 44); /* esh[3].sh_size */
8525 EndPutM32Inc(data, 0); /* esh[3].sh_link */
8526 EndPutM32Inc(data, 0); /* esh[3].sh_info */
8527 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
8528 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
8530 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
8531 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
8532 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
8533 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
8534 data += 4; /* esh[4].sh_offset */
8535 data += 4; /* esh[4].sh_size */
8536 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
8537 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8538 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
8539 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8541 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
8542 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
8543 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8544 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8545 data += 4; /* esh[0].sh_offset */
8546 data += 4; /* esh[0].sh_size */
8547 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8548 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8549 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
8550 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8552 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
8553 EndPutM32(data3+(2*40)+(5*4), BaseName ? 5*16 : 4*16); /* esh[4].sh_size */
8555 data2 = data;
8556 data += BaseName ? 5*16 : 4*16;
8558 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
8560 i = 0;
8561 EndPutM32Inc(data2, i); /* esym[0].st_name */
8562 EndPutM32Inc(data2, 0); /* esym[0].st_value */
8563 EndPutM32Inc(data2, 0); /* esym[0].st_size */
8564 *(data2++) = 0; /* esym[0].st_info */
8565 *(data2++) = 0; /* esym[0].st_other */
8566 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
8567 data[0] = 0;
8569 i += 1;
8570 EndPutM32Inc(data2, i); /* esym[1].st_name */
8571 EndPutM32Inc(data2, 0); /* esym[1].st_value */
8572 EndPutM32Inc(data2, 0); /* esym[1].st_size */
8573 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
8574 *(data2++) = 0; /* esym[1].st_other */
8575 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
8577 sprintf((strptr)data+i, "%s.o", name); while(data[i]) { i++;} ; /* get next store space */
8578 EndPutM32Inc(data2, 0); /* esym[2].st_name */
8579 EndPutM32Inc(data2, 0); /* esym[2].st_value */
8580 EndPutM32Inc(data2, 0); /* esym[2].st_size */
8581 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
8582 *(data2++) = 0; /* esym[2].st_other */
8583 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
8585 EndPutM32Inc(data2, i); /* esym[3].st_name */
8586 EndPutM32Inc(data2, 0); /* esym[3].st_value */
8587 EndPutM32Inc(data2, size); /* esym[3].st_size */
8588 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
8589 *(data2++) = 0; /* esym[3].st_other */
8590 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
8592 sprintf((strptr)data+i, "%s", name); while(data[i]) { i++;} ; /* get next store space */
8593 if(BaseName)
8595 EndPutM32Inc(data2, i); /* esym[4].st_name */
8596 EndPutM32Inc(data2, 0); /* esym[4].st_value */
8597 EndPutM32Inc(data2, 0); /* esym[4].st_size */
8598 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
8599 *(data2++) = 0; /* esym[4].st_other */
8600 EndPutM16/*Inc*/(data2, 0); /* esym[4].st_shndx */
8602 sprintf((strptr)data+i, "%s", BaseName); while(data[i]) { i++;} ; /* get next store space */
8604 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
8605 while(i&3) /* long aligned */
8606 data[i++] = 0;
8607 data += i;
8609 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
8611 data2 = data;
8613 if(BaseName)
8615 if(Flags & FLAG_SMALLDATA)
8617 EndPutM32Inc(data, k); /* erel[0].r_offset */
8618 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_SDAREL16)); /* erel[0].r_info - entry 4, type 32 */
8619 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8621 else
8623 EndPutM32Inc(data, k); /* erel[0].r_offset */
8624 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_HA)); /* erel[0].r_info - entry 4, type 6 */
8625 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8626 EndPutM32Inc(data, k+4); /* erel[1].r_offset */
8627 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_LO)); /* erel[1].r_info - entry 4, type 4 */
8628 EndPutM32Inc(data, 0); /* erel[1].r_addend */
8631 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
8633 /* make ar header and store all */
8634 arh = (struct ArHeader *) (data+20);
8635 memset(arh, ' ', sizeof(struct ArHeader));
8637 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
8638 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
8639 arh->ar_mode[2] = '0';
8640 arh->ar_mode[0] = '6';
8641 arh->ar_fmag[0] = 96;
8642 arh->ar_fmag[1] = '\n';
8644 if((k = strlen(name) + 2) >= 16)
8646 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
8648 else
8650 k = 0;
8651 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
8654 j = k + (data-tempbuf);
8655 for(i = 9; j; --i) /* make decimal number */
8657 data[i] = (j%10)+'0';
8658 j /= 10;
8660 for(j = 0; i < 9; ++j)
8661 arh->ar_size[j] = data[++i];
8663 DoOutputDirect(arh, sizeof(struct ArHeader));
8665 if(k)
8667 DoOutput("%s.o", name);
8668 if(k & 1)
8669 *(data++) = 0x0A; /* alignment byte! */
8672 return DoOutputDirect(tempbuf, data-tempbuf);
8675 uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
8677 uint8 i, r;
8679 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
8680 (flags & FUNCFLAG_ALIAS))
8681 return 1;
8683 if(LastBias >= ap->Bias)
8684 DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
8685 else
8687 Flags |= FLAG_DONE; /* We did something */
8689 for(LastBias += BIAS_OFFSET; LastBias < ap->Bias; LastBias += BIAS_OFFSET)
8690 DoOutputDirect("Dum\x10", 4);
8692 DoOutput("%c", toupper(name[0]));
8693 if(name[1])
8695 DoOutput("%c", tolower(name[1]));
8696 if(name[2])
8697 DoOutput("%s", name+2);
8699 if(!ap->NumArgs)
8700 DoOutputDirect("\x10", 1);
8701 else
8703 for(i = 0; i < ap->NumArgs; ++i)
8705 r = ap->Args[i].ArgReg;
8706 DoOutputDirect(&r, 1);
8710 return 1;
8713 uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
8715 int32 i;
8717 Flags |= FLAG_DONE; /* We did something */
8719 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8721 if(Flags & FLAG_ISPRIVATE)
8723 Flags ^= FLAG_ISPRIVATE;
8724 DoOutput("##public\n");
8727 else
8729 if(!(Flags & FLAG_ISPRIVATE))
8730 DoOutput("##private\n");
8731 Flags |= FLAG_ISPRIVATE;
8734 LastBias += BIAS_OFFSET;
8735 if(LastBias != ap->Bias)
8737 DoOutput("##bias %d\n", ap->Bias);
8738 LastBias = ap->Bias;
8741 if(ap->Abi != CurrentABI)
8743 switch(ap->Abi)
8745 case ABI_M68K: DoOutput("##abi M68k\n"); break;
8746 case ABI_PPC0: DoOutput("##abi PPC0\n"); break;
8747 case ABI_PPC2: DoOutput("##abi PPC2\n"); break;
8748 case ABI_PPC: DoOutput("##abi PPC\n"); break;
8750 CurrentABI = ap->Abi;
8753 DoOutput("%s("/*)*/, name);
8754 for(i = 0; i < ap->CallArgs; i++)
8755 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->CallArgs-1 ? "," : "");
8756 DoOutput(/*(*/")("/*)*/);
8758 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8760 for(i = 0; i < ap->CallArgs; i++)
8762 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], i < ap->CallArgs-1 ?
8763 (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg ? "/" : ",") : "");
8766 return DoOutput(/*(*/")\n");
8769 /* called from FuncSFD directly */
8770 uint32 FuncClib(struct AmiPragma *ap, uint32 flags, strptr name)
8772 struct ClibData *cd;
8773 int32 i, s, c;
8775 Flags |= FLAG_DONE; /* We did something */
8777 if(!(cd = GetClibFunc(name, ap, flags)))
8778 return 1;
8780 s = MakeClibType(tempbuf, &cd->ReturnType, 0);
8781 DoOutputDirect(tempbuf, s);
8782 DoOutput(" %s("/*)*/, name);
8784 if(ap->NumArgs)
8786 for(i = 0; i < cd->NumArgs; i++)
8788 c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
8789 if(s+c+2 > 75 && s)
8791 DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
8793 else if(i)
8795 DoOutput(", "); s += 2;
8797 DoOutputDirect(tempbuf, c);
8798 s += c;
8801 else if(Flags2 & FLAG2_CLIBOUT)
8802 DoOutput("void");
8803 return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
8806 uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
8808 struct ClibData *cd;
8809 int32 i, j;
8811 if(!(cd = GetClibFunc(name, ap, flags)))
8812 return 1;
8814 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8816 if(Flags & FLAG_ISPRIVATE)
8818 Flags ^= FLAG_ISPRIVATE;
8819 DoOutput("==public\n");
8822 else
8824 if(!(Flags & FLAG_ISPRIVATE))
8825 DoOutput("==private\n");
8826 Flags |= FLAG_ISPRIVATE;
8829 if(ap->Abi != CurrentABI)
8831 switch(ap->Abi)
8833 case ABI_M68K: DoOutput("==abi M68k\n"); break;
8834 case ABI_PPC0: DoOutput("==abi PPC0\n"); break;
8835 case ABI_PPC2: DoOutput("==abi PPC2\n"); break;
8836 case ABI_PPC: DoOutput("==abi PPC\n"); break;
8838 CurrentABI = ap->Abi;
8841 if(LastBias+BIAS_OFFSET < ap->Bias)
8843 DoOutput("==reserve %ld\n", ((ap->Bias-LastBias)/BIAS_OFFSET)-1);
8844 LastBias = ap->Bias;
8846 else if(flags & FUNCFLAG_TAG)
8847 DoOutput("==varargs\n");
8848 else if((flags & FUNCFLAG_ALIAS) || LastBias == ap->Bias)
8849 DoOutput("==alias\n");
8850 else
8851 LastBias += BIAS_OFFSET;
8853 if(!FuncClib(ap, flags, name))
8854 return 0;
8856 DoOutput(" ("/*)*/);
8857 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8859 strptr s;
8861 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8862 in step one, so the "-" can be placed at proper position. */
8863 for(j = i = 0; i < ap->NumArgs; i++)
8865 if(i == ap->NumArgs-1)
8867 s = ""; j += 2;
8869 else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
8871 s = (j&1) ? "," : "-"; ++j;
8873 else
8875 s = ","; j += 2;
8877 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], s);
8880 return DoOutput(/*(*/")\n");
8883 uint32 FuncOS4PPC(struct AmiPragma *ap, uint32 flags, strptr name)
8885 struct ClibData *cd;
8886 int32 i, noret = 0, registers;
8888 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
8889 return 1;
8891 Flags |= FLAG_DONE; /* We did something */
8893 if(!(cd = GetClibFunc(name, ap, flags)))
8894 return 1;
8896 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
8897 noret = 1; /* this is a void function */
8899 sprintf((strptr)tempbuf, "_%s_%s", GetIFXName(), name);
8900 OutClibType(&cd->ReturnType, (strptr)tempbuf);
8902 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8903 ap->NumArgs ? "," : "");
8904 for(i = 0; i < ap->NumArgs; ++i)
8906 DoOutput(" ");
8907 if(i == ap->NumArgs - 1 && (flags & FUNCFLAG_TAG))
8909 DoOutput("...\n");
8911 else
8913 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
8914 if(i < ap->NumArgs-1)
8915 DoOutput(",\n");
8918 if(flags & FUNCFLAG_TAG)
8920 struct ClibData *cd2;
8922 if(!(cd2 = GetClibFunc(ap->FuncName, ap, flags)))
8923 return 1;
8925 DoOutput(/*(*/")\n{\n"/*}*/
8926 " va_list ap;\n"
8927 " va_startlinear(ap, colorMap);\n"
8928 " ");
8929 if(!noret)
8930 DoOutput("return ");
8931 DoOutput("Self->%s(\n"/*)*/, ap->FuncName);
8932 for(i = 0; i < ap->NumArgs-1; ++i)
8934 DoOutput(" %s,\n", ap->Args[i].ArgName);
8936 DoOutput(" va_getlinearva(ap, "/*)*/);
8937 OutClibType(&cd2->Args[i], 0);
8938 DoOutput(/*((*/"));\n");
8940 else
8942 DoOutput(/*(*/")\n{\n"/*}*/
8943 " struct Library *LibBase = Self->Data.LibBase;\n"
8944 " struct ExecIFace *IExec = (struct ExecIFace *)"
8945 "Self->Data.IExecPrivate;\n");
8947 if(!noret)
8949 DoOutput(" ");
8950 OutClibType(&cd->ReturnType, "retval");
8951 DoOutput(";\n");
8954 DoOutput(
8955 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8956 "->EmuWS);\n");
8957 for(i = 0; i < ap->NumArgs; ++i)
8960 registers = GetRegisterData(ap) | 0x40000002; /* set A6 everytime */
8961 for(i = 0; i <= 15; ++i)
8963 if(registers & (1<< (16+i)))
8964 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames[i], i);
8966 DoOutput("\n ");
8968 if(!noret)
8970 DoOutput("retval = ("/*)*/);
8971 OutClibType(&cd->ReturnType, 0);
8972 DoOutput(/*(*/")");
8975 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
8976 " ET_Offset, -%d,\n"/*)*/,ap->Bias);
8977 for(i = 0; i < ap->NumArgs; ++i)
8979 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper[ap->Args[i].ArgReg],
8980 ap->Args[i].ArgName);
8982 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
8983 for(i = 0; i <= 15; ++i)
8985 if(registers & (1<< (16+i)))
8986 DoOutput(" regs[%ld] = save_%s;\n", i, RegNames[i]);
8989 if(!noret)
8990 DoOutput(" return retval;\n");
8992 return DoOutput(/*{*/"}\n\n");
8995 uint32 FuncOS4M68KCSTUB(struct AmiPragma *ap, uint32 flags, strptr name)
8997 struct ClibData *cd;
8998 int32 i, noret = 0;
9000 if(ap->NumArgs <= 7)
9001 return 1;
9003 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9004 return 1;
9006 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9007 return 1;
9009 Flags |= FLAG_DONE; /* We did something */
9011 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9012 noret = 1; /* this is a void function */
9014 sprintf((strptr)tempbuf, "Cstub_%s", name);
9015 OutClibType(&cd->ReturnType, (strptr)tempbuf);
9017 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9018 " struct ExecIFace *IExec = (struct ExecIFace *)"
9019 "Interface->Data.IExecPrivate;\n"
9020 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9021 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9023 if(!noret)
9024 DoOutput("return ");
9026 DoOutput("Interface->%s(\n"/*)*/,(flags & FUNCFLAG_TAG) ? ap->FuncName
9027 : name);
9028 for(i = 0; i < ap->NumArgs; ++i)
9030 DoOutput(" ("/*)*/);
9031 OutClibType(&cd->Args[i], 0);
9032 DoOutput(/*(*/") regarray[%d]", ap->Args[i].ArgReg);
9033 if(i < ap->NumArgs-1)
9034 DoOutput(",\n");
9036 return DoOutput(/*{(*/");\n}\n\n");
9039 uint32 FuncOS4M68K(struct AmiPragma *ap, uint32 flags, strptr name)
9041 struct ClibData *cd;
9042 int i;
9044 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9045 return 1;
9047 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9048 return 1;
9050 Flags |= FLAG_DONE; /* We did something */
9052 DoOutput(
9053 "\t.section .data\n"
9054 "\t.globl\tstub_%s\n"
9055 "\t.type\tstub_%s,@function\n"
9056 "\n"
9057 "stub_%s:\n"
9058 "\t.short\t0x4ef8\n"
9059 "\t.short 0\n"
9060 "\t.short 1\n"
9061 "\t.globl\tstub_%sPPC\n"
9062 "\t.long\tstub_%sPPC\n",name, name, name, name, name);
9064 if(ap->NumArgs > 7)
9066 Flags2 |= FLAG2_OS4M68KCSTUB;
9067 DoOutput(
9068 "\t.byte\t2\n" /* Rest of parameters in C */
9069 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9070 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9072 else
9074 DoOutput(
9075 "\t.byte\t%d\n" /* Rest of parameters in C */
9076 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9077 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9078 ap->NumArgs+2);
9079 for(i = 0; i < ap->NumArgs; ++i)
9081 DoOutput("\t.byte\t%d,REG68K_%s\n",i+4,
9082 RegNamesUpper[ap->Args[i].ArgReg]);
9085 DoOutput(
9086 "\t.section .text\n"
9087 "\t.align\t2\n"
9088 "\n"
9089 "stub_%sPPC:\n"
9090 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9091 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9092 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9093 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9094 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9095 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9096 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9097 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9098 name, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9099 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9100 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9101 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
9103 if(ap->NumArgs > 7)
9105 /* Since this function has 11 arguments, we need a C stub */
9106 DoOutput(
9107 "\t.globl\tCstub_%s\n"
9108 "\tlis\t%s4,Cstub_%s@h\n"
9109 "\tori\t%s4,%s4,Cstub_%s@l\n"
9110 "\tmtlr\t%s4\n"
9111 "\tblrl\n",
9112 name, PPCRegPrefix, name, PPCRegPrefix, PPCRegPrefix, name, PPCRegPrefix);
9114 else
9116 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name);
9118 DoOutput(
9119 "\tlwz\t%s11,12(%s1)\n"
9120 "\tmtlr\t%s11\n"
9121 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9122 "\tblrl\n" /* Return to emulation */
9123 "\n"
9124 "\t.globl\tstub_%s68K\n"
9125 "\t.long\tstub_%s68K\n"
9126 "\t.byte\t0\n", /* Flags */
9127 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, name,
9128 name);
9130 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9132 DoOutput(
9133 "\t.byte\t1\n" /* One register (a7 only) */
9134 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9136 else
9138 DoOutput(
9139 "\t.byte\t2\n"
9140 "\t.byte\t1,REG68K_A7\n"
9141 "\t.byte\t3,REG68K_D0\n");
9144 return DoOutput(
9145 "\t.section .data\n"
9146 "\t.align\t4\n"
9147 "\n"
9148 "stub_%s68K:\n"
9149 "\t.short\t0x4e75\n" /* RTS */
9150 "\n", name);
9153 uint32 FuncOS4M68KVect(struct AmiPragma *ap, uint32 flags, strptr name)
9155 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9156 return 1;
9158 while(LastBias + BIAS_OFFSET < ap->Bias)
9160 DoOutput("\t.long\tstub_Reserved\n");
9161 LastBias += BIAS_OFFSET;
9163 LastBias = ap->Bias;
9165 return DoOutput("\t.long\tstub_%s\n", name);
9168 uint32 FuncXML(struct AmiPragma *ap, uint32 flags, strptr name)
9170 struct ClibData *cd;
9171 int32 i;
9173 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9174 return 1;
9176 if(flags & FUNCFLAG_ALIAS)
9177 DoError(ERR_ALIASES_NOT_SUPPORTED, ap->Line);
9179 Flags |= FLAG_DONE; /* We did something */
9181 if(!(cd = GetClibFunc(name, ap, flags)))
9182 return 1;
9184 while(LastBias+BIAS_OFFSET < ap->Bias)
9186 LastBias += BIAS_OFFSET;
9187 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9188 " status=\"unimplemented\"/>\n", LastBias);
9190 LastBias = ap->Bias;
9192 DoOutput("\t\t<method name=\"%s\" result=\"", name);
9193 OutClibType(&cd->ReturnType, 0);
9194 DoOutput("\">\n");
9195 for(i = 0; i < ap->NumArgs; ++i)
9197 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9198 i == ap->NumArgs-1 && (flags & FUNCFLAG_TAG) ? "var" : "",
9199 ap->Args[i].ArgName);
9200 OutClibType(&cd->Args[i], 0);
9201 DoOutput("\"/>\n");
9203 return DoOutput("\t\t</method>\n");
9206 uint32 FuncGateStubs(struct AmiPragma *ap, uint32 flags, strptr name)
9208 struct ClibData *cd;
9209 strptr ret = "return ";
9210 int32 i;
9212 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
9213 return 1;
9215 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9216 return 1;
9218 Flags |= FLAG_DONE; /* We did something */
9220 if(flags & FUNCFLAG_ALIAS)
9222 if(flags & FUNCFLAG_TAG)
9223 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9224 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
9226 DoOutput("#define %s("/*)*/, name);
9227 for(i = 0; i < ap->NumArgs-1; ++i)
9228 DoOutput("%s, ", ap->Args[i].ArgName);
9229 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
9230 for(i = 0; i < ap->NumArgs-1; ++i)
9231 DoOutput("(%s), ", ap->Args[i].ArgName);
9232 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
9235 if((flags & FUNCFLAG_TAG))
9237 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9238 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
9239 for(i = 0; i < ap->NumArgs-1; ++i)
9241 DoOutput("%s, ", ap->Args[i].ArgName);
9243 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9244 ap->FuncName);
9245 for(i = 0; i < ap->NumArgs-1; ++i)
9246 DoOutput("(%s), ", ap->Args[i].ArgName);
9247 DoOutput("("/*)*/);
9248 OutClibType(&cd->Args[i], 0);
9249 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9252 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9253 ret = "";
9255 if(!OutClibType(&cd->ReturnType, 0))
9256 return 0;
9258 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix, name);
9260 for(i = 0; i < ap->NumArgs; ++i)
9262 DoOutput(" ");
9263 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
9264 DoOutput(" = ("/*)*/);
9265 OutClibType(&cd->Args[i], 0);
9266 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper[ap->Args[i].ArgReg]);
9267 if((Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB)) && (Flags2 & FLAG2_REGLIB))
9268 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9270 DoOutput(" %s%s%s("/*)*/, ret, subprefix, name);
9271 if(ap->NumArgs)
9273 if(Flags2 & FLAG2_PRELIB)
9275 if(Flags2 & FLAG2_REGLIB)
9276 DoOutput("___RegBase,");
9277 else
9278 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper);
9281 for(i = 0; i < ap->NumArgs-1; ++i)
9283 DoOutput("%s, ", ap->Args[i].ArgName);
9285 if(Flags2 & FLAG2_POSTLIB)
9287 if(Flags2 & FLAG2_REGLIB)
9288 DoOutput("%s, ___RegBase", ap->Args[i].ArgName);
9289 else
9290 DoOutput("%s, %s_BASE_NAME", ap->Args[i].ArgName, ShortBaseNameUpper);
9292 else
9293 DoOutput("%s", ap->Args[i].ArgName);
9295 else
9297 if(Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB))
9299 if(Flags2 & FLAG2_REGLIB)
9300 DoOutput("___RegBase");
9301 else
9302 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
9305 return DoOutput(/*(({*/"));\n}\n");
9308 static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
9310 uint32 res;
9312 if(Flags & FLAG_SINGLEFILE)
9314 sprintf(filename, filenamefmt, name);
9315 if(!OpenDest(filename))
9316 return 0;
9318 res = Func(ap, flags, name);
9319 if(Flags & FLAG_SINGLEFILE)
9321 CloseDest(filename);
9323 return res;
9326 static uint32 PrintComment(struct Comment *com, strptr comment)
9328 if(com->Private && !(Flags & FLAG_PRIVATE))
9329 return 1;
9330 else if((Flags2 & FLAG2_SFDOUT) && com->Version)
9332 return DoOutput("==version %d\n", com->Version);
9334 else if((Flags2 & FLAG2_SFDOUT) && com->ReservedNum)
9336 LastBias += BIAS_OFFSET*com->ReservedNum;
9337 return DoOutput("==reserve %d\n", com->ReservedNum);
9339 else if(!(Flags & FLAG_DOCOMMENT) || !comment)
9340 return 1;
9342 if(com->Data)
9344 if(!DoOutput(comment, com->Data))
9345 return 0;
9347 else if(com->ReservedNum)
9349 string temp[256];
9350 sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
9351 com->ReservedNum == 1 ? "" : "s");
9352 if(!DoOutput(comment, temp))
9353 return 0;
9355 else if(com->Version)
9357 string temp[256];
9358 if(com->Version >= FIRST_KNOWN_RELEASE && com->Version <= LAST_KNOWN_RELEASE &&
9359 (Flags2 & FLAG2_SYSTEMRELEASE))
9360 sprintf(temp, "* --- functions in V%u or higher %s ---", com->Version,
9361 Release[com->Version-FIRST_KNOWN_RELEASE]);
9362 else
9363 sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
9365 if(!DoOutput(comment, temp))
9366 return 0;
9368 return 1;
9371 static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
9373 struct Comment *com;
9374 int32 i;
9375 struct AmiPragma *ap;
9377 com = (struct Comment *) Comment.First;
9379 for(ap = (struct AmiPragma *) AmiPragma.First; ap;
9380 ap = (struct AmiPragma *) ap->List.Next)
9382 if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
9384 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
9386 else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
9388 while(com && com->Bias <= ap->Bias)
9390 if(!PrintComment(com, comment))
9391 return 0;
9392 com = (struct Comment *) com->List.Next;
9393 } /* comment loop */
9395 #ifdef DEBUG_OLD
9396 printf("Processing %s - %s\n", ap->FuncName ? ap->FuncName : "",
9397 ap->TagName ? ap->TagName : "");
9398 #endif
9400 if(tagmode != TAGMODE_TAGS)
9402 if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
9403 return 0;
9405 for(i = 0; i < ap->NumAlias; ++i)
9407 if(ap->AliasName[i]->Type & FUNCFLAG_NORMAL)
9409 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9410 return 0;
9415 if(tagmode)
9417 if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
9418 return 0;
9420 for(i = 0; i < ap->NumAlias; ++i)
9422 if(ap->AliasName[i]->Type & FUNCFLAG_TAG)
9424 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9425 return 0;
9431 while(com)
9433 if(!PrintComment(com, comment))
9434 return 0;
9435 com = (struct Comment *) com->List.Next;
9436 } /* comment loop */
9437 return 1;
9440 static uint32 PrintIncludes(void) /* copies the include lines */
9442 struct Include *inc;
9443 strptr s, s2;
9445 inc = (struct Include *) Includes.First;
9447 while(inc)
9449 s2 = (strptr) tempbuf;
9450 for(s = inc->Include; *s; ++s)
9452 switch(*s)
9454 case '<': *(s2++) = ' '; break;
9455 case '/':
9456 case '.': *(s2++) = '_'; break;
9457 case '>': break;
9458 default: *(s2++) = toupper(*s);
9460 *s2 = 0;
9462 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
9463 inc = (struct Include *) inc->List.Next;
9465 if(!Includes.First)
9466 DoOutput("#include <exec/types.h>\n");
9467 return DoOutput("\n");
9470 /* ------------------------------------------------------------------ */
9472 static int32 AddClibEntry(strptr buffer, strptr bufend, uint32 linenum)
9474 strptr buf = buffer;
9475 struct ClibData d, *f;
9477 memset(&d, 0, sizeof(struct ClibData));
9478 buf = SkipBlanksRet(buf);
9479 if(*buf == '#') /* preprocessor lines */
9481 #ifdef DEBUG_OLD
9482 printf("Found non-function bracket in preprocessor line %ld\n", linenum);
9483 #endif
9484 while(buf < bufend && *buf != '\n')
9485 ++buf;
9486 return buf-buffer;
9488 if(!strnicmp(buf, "ASM", 3))
9489 buf = SkipBlanks(buf+3);
9490 /* else if(!strnicmp(buf, "STACK", 5))
9491 buf = SkipBlanks(buf+5);
9493 else if(!strnicmp(buf, "REGS", 4))
9494 buf = SkipBlanks(buf+4);
9496 if(!strnicmp(buf, "extern", 6))
9498 buf = SkipBlanksRet(buf+6);
9499 if(!strnicmp(buf, "\"C\"", 3)) /* CPP: extern "C" */
9501 buf = SkipBlanksRet(buf+3);
9502 if (*buf == '{')
9504 buf = SkipBlanksRet(buf+1);
9509 if(!GetCPPType(&d.ReturnType, buf, 1, 1))
9511 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE, linenum);
9512 return 0;
9514 else if(d.ReturnType.Unknown)
9515 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE_INT, linenum,
9516 d.ReturnType.Unknown);
9518 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9520 strptr r = d.ReturnType.TypeStart;
9521 while(*r != '('/*)*/) ++r;
9522 r = SkipBlanks(++r); /* the bracket */
9523 d.FuncName = SkipBlanks(++r); /* the asterisk */
9525 else
9526 d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
9527 buf = d.FuncName;
9528 while(*(buf++) != '('/*)*/)
9530 *(SkipName(d.FuncName)) = 0;
9531 if(!(*d.FuncName))
9533 #ifdef DEBUG_OLD
9534 printf("Found non-function bracket in line %ld\n", linenum);
9535 #endif
9536 while(buf < bufend && *buf != '\n')
9537 ++buf;
9538 return buf-buffer;
9540 buf = SkipBlanksRet(buf);
9542 while(*buf != /*(*/')' && buf < bufend)
9544 if(d.NumArgs == MAXREGPPC+1)
9546 DoError(ERROFFSET_CLIB | ERR_TO_MUCH_ARGUMENTS, linenum);
9547 return 0;
9549 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0, 1))
9551 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
9552 return 0;
9554 else if(d.Args[d.NumArgs-1].Unknown)
9555 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE_INT, linenum,
9556 d.NumArgs, d.Args[d.NumArgs-1].Unknown);
9558 buf = d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength;
9559 while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
9560 ++buf;
9561 #ifdef DEBUG
9562 printf("Added argument %d for %s (%d bytes)\n", d.NumArgs, d.FuncName,
9563 d.Args[d.NumArgs-1].FullLength);
9564 #endif
9565 if(*buf == ',')
9566 buf = SkipBlanksRet(++buf);
9569 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9570 d.NumArgs = 0; /* void arguments are no arguments */
9572 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9573 return -1;
9575 memcpy(f, &d, sizeof(struct ClibData));
9577 if(!clibdata)
9578 clibdata = f;
9579 else
9581 struct ClibData *e = clibdata;
9582 while(e->Next)
9583 e = e->Next;
9584 e->Next = f;
9586 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9588 int numclose = 2, numopen = 1;
9589 while(buf < bufend && (numclose || numopen > 0))
9591 if(*buf == '('/*)*/) { ++numclose; --numopen; }
9592 else if(*buf == /*(*/')') --numclose;
9593 ++buf;
9597 #ifdef DEBUG
9598 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9599 f->FuncName, linenum, buf-buffer, f->NumArgs);
9600 #endif
9601 return buf-buffer;
9604 static int32 ScanClibFile(strptr buf, strptr bufend)
9606 strptr linestart = buf;
9607 uint32 linenum = 1;
9608 int added = 0;
9610 /* remove comments and other not so nice characters */
9611 while(buf < bufend)
9613 if(*buf == '\t' || *buf == '\r' || *buf == (string)0xA0)
9614 *(buf++) = ' ';
9615 else if(buf[0] == '/' && buf < bufend-1)
9617 if(buf[1] == '*')
9619 while(buf < bufend-1 && (buf[0] != '*' || buf[1] != '/'))
9621 if(*buf != '\n')
9622 *buf = ' ';
9623 ++buf;
9625 *(buf++) = ' ';
9626 *(buf++) = ' ';
9628 else if(buf[1] == '/')
9630 while(buf < bufend && buf[0] != '\n')
9631 *(buf++) = ' ';
9632 ++buf;
9634 else
9635 ++buf;
9637 else if(buf[0] == '#' && strncmp("#include", buf, 8))
9639 while(buf < bufend && buf[0] != '\n')
9640 *(buf++) = ' ';
9641 ++buf;
9643 else
9644 ++buf;
9647 #ifdef DEBUG_OLD
9648 printf("-----------\n%s-----------\n", linestart);
9649 #endif
9651 buf = linestart;
9652 while(buf < bufend)
9654 if(*buf == '\n')
9656 ++buf; ++linenum;
9657 if(added)
9659 linestart = buf;
9660 added = 0;
9663 else if(!strncmp("#include", buf, 8))
9665 struct Include *d;
9667 if(!(d = (struct Include *) NewItem(&Includes)))
9668 return 0;
9669 d->Include = buf = SkipBlanks(buf+8);
9670 AddItem(&Includes, (struct ShortList *) d);
9671 while(*buf && *buf != '>' && *buf != '\n')
9672 ++buf;
9673 if(*buf == '>')
9674 ++buf;
9675 if(*buf == '\n')
9676 ++linenum;
9677 *(buf++) = 0;
9678 #ifdef DEBUG_OLD
9679 printf("Added Include line %s\n", d->Include);
9680 #endif
9681 added = 1;
9683 else if(*buf == '('/*)*/)
9685 int32 i;
9687 if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
9688 return 0;
9689 else if(!i)
9691 while(buf < bufend && *buf != '\n')
9692 ++buf; /* skip this line */
9694 else
9696 i -= buf-linestart;
9697 while(buf < bufend && i-- > 0)
9699 if(*(buf++) == '\n')
9701 linestart = buf;
9702 ++linenum;
9703 } /* skip this function */
9706 added = 1;
9708 else
9709 ++buf;
9710 } /* while */
9711 return 1;
9714 static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
9716 if(!data || data->Flags || data->Type != type || data->PointerDepth)
9717 return 0;
9718 return type;
9721 static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
9723 uint32 i, j;
9725 for(i = 0; i < MAXREG; ++i)
9727 j = strlen(RegNames[i]);
9728 if(!strnicmp(string, RegNames[i], j))
9730 string += j;
9731 if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
9733 data->Register = i;
9734 data->Flags |= CPP_FLAG_REGISTER;
9735 return j;
9739 return 0;
9742 static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
9744 strptr buf = buffer;
9745 struct ClibData d;
9747 memset(&d, 0, sizeof(struct ClibData));
9748 while(*buf != /*(*/')')
9750 if(d.NumArgs == MAXREGPPC+1)
9751 return 0;
9752 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1, 1))
9753 return 0;
9755 buf += d.Args[d.NumArgs-1].FullLength;
9756 while(*buf != ',' && *buf != /*(*/')')
9757 ++buf;
9758 if(*buf == ',')
9759 buf = SkipBlanksRet(++buf);
9762 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9763 d.NumArgs = 0; /* void arguments are no arguments */
9765 if(d.NumArgs) /* no need to allocate structure for nothing */
9767 if(!(data->FuncPtr = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9768 return 0;
9770 memcpy(data->FuncPtr, &d, sizeof(struct ClibData));
9772 return (uint32) (buf+1-buffer);
9775 /* rettype turns on usage of "extern" specifier */
9776 static int32 GetCPPType(struct CPP_NameType *data, strptr start, uint32 rettype, uint32 small)
9778 uint32 ok = 1, j;
9779 strptr u;
9781 data->Unknown = 0;
9782 data->Replace = 0;
9783 data->TypeStart = start = SkipBlanks(start);
9785 if(!strncmp(start, "REG", 3) && (start[3] == ' ' || start[3] == '\t' || start[3] == '\n' || start[3] == '('/*)*/))
9787 u = SkipBlanksRet(start+3);
9788 if(*u == '('/*)*/)
9790 u = SkipBlanks(u+1);
9791 if((j = CheckRegisterNum(u, data)))
9793 u = SkipBlanks(u+j);
9794 if(*u == ')')
9795 start = SkipBlanks(u+1);
9799 data->TypeStart = start;
9803 start = SkipBlanks((u = start));
9804 if(!strncmp("...",start,3))
9806 data->Type = CPP_TYPE_VARARGS;
9807 data->TypeLength = start+3 - (data->TypeStart);
9808 data->FullLength = data->TypeLength;
9809 return 1;
9811 if(CheckKeyword(start, "const", 5) || CheckKeyword(start, "CONST", 5))
9813 data->Flags |= CPP_FLAG_CONST; start += 5;
9815 else if(rettype && CheckKeyword(start, "extern", 6))
9817 start += 6; /* ignore it */
9819 else if(CheckKeyword(start, "long", 4))
9821 if(data->Flags & CPP_FLAG_LONG)
9822 data->Type = CPP_TYPE_LONGLONG;
9823 else
9824 data->Flags |= CPP_FLAG_LONG;
9826 start += 4;
9828 else if(CheckKeyword(start, "signed", 6))
9829 start += 6;
9830 else if(CheckKeyword(start, "unsigned", 8))
9832 data->Flags |= CPP_FLAG_UNSIGNED; start += 8;
9834 else if(CheckKeyword(start, "register", 8))
9836 data->Flags |= CPP_FLAG_REGISTER; start += 8;
9837 data->Register = UNDEFREGISTER;
9839 else if(CheckKeyword(start, "struct", 6))
9841 start = SkipBlanks(start+6);
9842 data->Flags |= CPP_FLAG_STRUCT;
9843 if(*start == '?') /* ? for external types */
9845 data->StructureLength = 0;
9846 data->StructureName = "";
9847 ++start;
9849 else if(*start == '!') /* ! for typedef types */
9851 data->Flags |= CPP_FLAG_TYPEDEFNAME;
9852 ++start;
9853 /* structure name and length already set */
9855 else
9857 start = SkipName((data->StructureName = start));
9858 data->StructureLength = start-data->StructureName;
9861 else if(CheckKeyword(start, "union", 5))
9863 start = SkipBlanks(start+5);
9864 data->Flags |= CPP_FLAG_UNION;
9865 if(*start != '?') /* ? for external types */
9867 start = SkipName((data->StructureName = start));
9868 data->StructureLength = start-data->StructureName;
9870 else
9872 data->StructureLength = 0;
9873 data->StructureName = "";
9874 ++start;
9877 else if(CheckKeyword(start, "enum", 4))
9879 start = SkipBlanks(start+4);
9880 data->Flags |= CPP_FLAG_ENUM;
9881 if(*start != '?') /* ? for external types */
9883 start = SkipName((data->StructureName = start));
9884 data->StructureLength = start-data->StructureName;
9886 else
9888 data->StructureLength = 0;
9889 data->StructureName = "";
9890 ++start;
9893 else if(*start == '*')
9895 ++start; ++data->PointerDepth;
9897 else if(*start == '[')
9899 data->Flags |= CPP_FLAG_ARRAY;
9900 while(*start && *start != ']')
9901 ++start;
9902 if(*start)
9903 ++start;
9905 else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
9906 start += 2 + j;
9907 else if(!data->Type)
9909 uint32 i;
9911 for(i = 0; CPP_Field[i].Text; ++i)
9913 if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length) &&
9914 (start[CPP_Field[i].Length] == ' ' ||
9915 start[CPP_Field[i].Length] == '\t' ||
9916 start[CPP_Field[i].Length] == '\n' ||
9917 start[CPP_Field[i].Length] == ',' ||
9918 start[CPP_Field[i].Length] == /*(*/')' ||
9919 start[CPP_Field[i].Length] == '('/*)*/ ||
9920 start[CPP_Field[i].Length] == '*'))
9922 start += CPP_Field[i].Length;
9923 data->Type = CPP_Field[i].Type;
9924 data->Flags |= CPP_Field[i].Flags;
9925 if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
9926 ++data->PointerDepth;
9927 break;
9930 if(CPP_Field[i].Text)
9931 continue;
9932 else if(extnames)
9934 struct CPP_ExternNames *a = extnames;
9936 while(a)
9938 i = strlen(a->Type);
9939 if(!strncmp(a->Type, start, i) && !isalnum(start[i]) &&
9940 start[i] != '_')
9942 start += i;
9943 data->StructureName = a->NameType.StructureName;
9944 data->FuncPtr = a->NameType.FuncPtr;
9945 data->StructureLength = a->NameType.StructureLength;
9946 data->PointerDepth += a->NameType.PointerDepth;
9947 data->Type = a->NameType.Type;
9948 data->Flags |= a->NameType.Flags;
9949 data->FuncArgs = a->NameType.FuncArgs;
9950 data->ArgsLength = a->NameType.ArgsLength;
9951 break;
9954 /* check types here */
9955 a = a->Next;
9957 if(a)
9958 continue;
9959 else if((!data->Type) && (!data->Flags))
9961 long size;
9962 struct CPP_Unknown *u;
9964 data->Type = CPP_TYPE_INT;
9965 size = SkipName(start)-start;
9966 for(u = unknown; u && strncmp(u->Unknown, start, size); u = u->Next)
9968 if(!u)
9970 data->Unknown = DupString(start, size);
9971 if((u = (struct CPP_Unknown *) AllocListMem(sizeof(struct CPP_Unknown))))
9973 u->Next = unknown;
9974 u->Unknown = data->Unknown;
9975 unknown = u;
9978 start += size;
9979 continue;
9982 break;
9984 else
9985 break;
9986 }while(1);
9988 if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
9989 u = start;
9991 data->TypeLength = u - (data->TypeStart);
9992 data->FullLength = data->TypeLength;
9994 u = SkipBlanks(u);
9996 if(*u == '('/*)*/)
9998 ok = 0;
9999 u = SkipBlanksRet(++u);
10000 if(*u == '*')
10002 while(*u == '*')
10004 ++data->FuncPointerDepth; ++u;
10006 u = SkipBlanksRet(u);
10007 if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
10009 data->Flags |= CPP_FLAG_CONST; u += 6;
10011 u = SkipBlanksRet(u);
10012 if(*u != /*(*/')')
10013 data->FunctionName = u;
10014 u = SkipBlanksRet(SkipName(u));
10015 if(*u == '('/*)*/)
10017 int numclose = 1;
10018 ++u;
10019 while(*u && numclose)
10021 if(*u == '('/*)*/) ++numclose;
10022 else if(*u == /*(*/')') --numclose;
10023 ++u;
10026 if(*u == /*(*/')')
10028 u = SkipBlanksRet(++u);
10029 if(*u == '('/*)*/)
10031 data->Flags |= CPP_FLAG_FUNCTION;
10033 if((j = ParseFuncPtrArgs(u+1, data)))
10034 ok = 1;
10035 data->FuncArgs = u;
10036 data->ArgsLength = j+1;
10037 data->FullLength = u+data->ArgsLength - (data->TypeStart);
10043 if(data->PointerDepth)
10044 data->Flags |= CPP_FLAG_POINTER;
10046 if(!(Flags2 & FLAG2_SMALLTYPES) && !small)
10048 if(!(data->Flags & (CPP_FLAG_STRPTR|CPP_FLAG_POINTER|CPP_FLAG_ENUM
10049 |CPP_FLAG_STRUCT|CPP_FLAG_UNION|CPP_FLAG_FUNCTION|CPP_FLAG_REGISTER)))
10051 if(data->Type == CPP_TYPE_BYTE || data->Type == CPP_TYPE_WORD || data->Type == CPP_TYPE_INT)
10053 if(data->Flags & CPP_FLAG_UNSIGNED)
10054 data->Replace = "const ULONG";
10055 else
10056 data->Replace = "const LONG";
10057 data->Type = CPP_TYPE_LONG;
10058 if(!(data->Flags & CPP_FLAG_CONST))
10059 data->Replace += 6;
10064 if(!data->Type && (data->Flags & CPP_FLAG_LONG))
10065 data->Type = CPP_TYPE_LONG;
10067 if((!data->Type && !data->Flags) || !ok)
10068 return 0;
10069 return 1;
10072 static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
10074 struct ClibData *d = clibdata;
10076 if(!name)
10078 DoError(ERR_ILLEGAL_INTERNAL_VALUE, 0);
10079 return 0;
10082 while(d && strcmp(name, d->FuncName))
10083 d = d->Next;
10085 if(!d)
10087 if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
10089 DoError(ERR_PROTOTYPE_MISSING, 0, name);
10090 ap->Flags |= AMIPRAGFLAG_NOCLIB;
10093 else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
10094 ap->CallArgs+1 != d->NumArgs))
10096 if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDARGWARN)))
10098 DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
10099 ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
10101 return 0;
10104 return d;
10107 static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
10109 if(!strncmp(string, keyword, size))
10111 string += size;
10112 if(*string == ' ' || *string == '\t' || *string == '\n')
10113 return size;
10115 return 0;
10118 /* return nonzero, when usable, zero, when string already emitted */
10119 static uint32 CopyCPPType(strptr buffer, uint32 pass, struct ClibData *cd,
10120 struct AmiArgs *args)
10122 uint32 ret = 0, reg;
10123 uint32 i, j, k = 0;
10125 /* pass 0: signed strptr, MaxonC++ high args */
10126 /* pass 1: unsigned strptr, MaxonC++ high args */
10127 /* pass 2: signed strptr, StormC++ high args */
10128 /* pass 3: unsigned strptr, StormC++ high args */
10130 for(i = 0; i < cd->NumArgs; ++i)
10132 struct CPP_NameType *nt;
10134 nt = &cd->Args[i];
10136 if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
10137 reg = 1 + args[k].ArgReg;
10138 else if((nt->Flags & CPP_FLAG_REGISTER) && nt->Register != UNDEFREGISTER)
10139 reg = 1 + nt->Register;
10140 else
10141 reg = 0;
10143 if(reg--) /* subtract the added 1 */
10145 *(buffer++) = CPP_TYPE_REGISTER;
10146 if(reg >= 10)
10148 if(pass & 2)
10150 *(buffer++) = reg/10 + '0';
10151 *(buffer++) = reg%10 + '0';
10152 ret |= 2;
10154 else
10155 *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
10157 else
10158 *(buffer++) = reg + '0';
10161 if(nt->Flags & CPP_FLAG_FUNCTION)
10163 for(j = 0; j < nt->FuncPointerDepth; ++j)
10164 *(buffer++) = CPP_TYPE_POINTER;
10165 *(buffer++) = CPP_TYPE_FUNCTION;
10167 for(j = 0; j < nt->PointerDepth; ++j)
10168 *(buffer++) = CPP_TYPE_POINTER;
10169 if(nt->Flags & CPP_FLAG_CONST)
10170 *(buffer++) = CPP_TYPE_CONST;
10171 if(nt->Flags & CPP_FLAG_UNSIGNED)
10172 *(buffer++) = CPP_TYPE_UNSIGNED;
10173 else if((nt->Flags & CPP_FLAG_STRPTR) && (pass & 1))
10175 *(buffer++) = CPP_TYPE_UNSIGNED;
10176 ret |= 1; /* we really use this pass */
10178 if(nt->Flags & CPP_FLAG_ENUM)
10179 *(buffer++) = CPP_TYPE_ENUM;
10180 if(nt->Type)
10181 *(buffer++) = cd->Args[i].Type;
10182 else
10184 uint32 i;
10185 sprintf(buffer, "%02lu", (uint32) nt->StructureLength); buffer += 2;
10186 for(i = 0; i < nt->StructureLength; ++i)
10187 *(buffer++) = nt->StructureName[i];
10189 if(nt->Flags & CPP_FLAG_FUNCTION)
10191 if(nt->FuncPtr)
10193 ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
10194 while(*buffer)
10195 ++buffer; /* skip to the new end */
10197 *(buffer++) = CPP_TYPE_FUNCEND;
10199 ++k;
10200 if(IsCPPType(nt, CPP_TYPE_DOUBLE)) /* double needs 2 registers */
10201 ++k;
10204 *(buffer) = 0;
10206 if(ret != pass)
10207 ret = 0;
10208 if(!pass)
10209 ret = 0x80;
10211 return ret; /* return nozero if this pass should be used */
10214 static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
10216 if(nt->Replace)
10217 DoOutput("%s", nt->Replace);
10218 else
10219 DoOutputDirect(nt->TypeStart, nt->TypeLength);
10220 if(nt->Type != CPP_TYPE_VARARGS)
10222 if(nt->Flags & CPP_FLAG_FUNCTION)
10224 uint32 i;
10225 DoOutput(" ("/*)*/);
10226 for(i = 0; i < nt->FuncPointerDepth; ++i)
10227 DoOutput("*");
10228 if (txt)
10229 DoOutput("%s)", txt);
10230 else
10231 DoOutput(")");
10232 if(nt->FuncArgs)
10233 return DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
10234 else
10235 return DoOutput("()");
10237 else if(txt)
10238 return DoOutput(" %s", txt);
10241 return 1;
10244 static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
10246 strptr a;
10248 a = dest;
10249 if(nt->Replace)
10251 uint32 i;
10252 i = strlen(nt->Replace);
10253 memcpy(a, nt->Replace, i);
10254 a += i;
10256 else
10258 memcpy(a, nt->TypeStart, nt->TypeLength);
10259 a += nt->TypeLength;
10262 if(nt->Type != CPP_TYPE_VARARGS)
10264 if(nt->Flags & CPP_FLAG_FUNCTION)
10266 if (txt)
10267 a += sprintf(a, " (*%s)", txt);
10268 else
10269 a += sprintf(a, " (*)");
10270 if(nt->FuncArgs)
10272 memcpy(a, nt->FuncArgs, nt->ArgsLength);
10273 a += nt->ArgsLength;
10275 else
10276 a += sprintf(a, "()");
10278 else if(txt)
10279 a += sprintf(a, " %s", txt);
10281 return (uint32)(a-dest);
10284 static uint32 OutPASCALType(struct CPP_NameType *t, strptr txt, uint32 ret)
10286 int32 i = t->PointerDepth;
10288 if(t->Flags & CPP_FLAG_CONST)
10289 DoOutput("CONST ");
10290 if(!ret && i == 1 &&
10291 (t->Type == CPP_TYPE_LONG || t->Type == CPP_TYPE_WORD))
10293 DoOutput("VAR "); --i;
10296 DoOutput("%s : ", txt);
10298 if(!i && t->Flags == CPP_FLAG_BOOLEAN)
10299 return DoOutput("BOOLEAN");
10300 else if(i && t->Type == CPP_TYPE_VOID)
10301 return DoOutput("POINTER");
10302 else if(t->Flags & CPP_FLAG_FUNCTION)
10303 return DoOutput("tPROCEDURE");
10305 while(i--)
10306 DoOutput("p");
10308 if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
10310 if(!t->PointerDepth)
10311 DoOutput("t");
10312 return DoOutputDirect(t->StructureName, t->StructureLength);
10315 if(t->Flags & CPP_FLAG_UNSIGNED)
10317 if(t->Type == CPP_TYPE_LONG)
10318 return DoOutput("CARDINAL");
10319 if(t->Type == CPP_TYPE_WORD)
10320 return DoOutput("int16");
10321 if(t->Type == CPP_TYPE_BYTE)
10322 return DoOutput(t->PointerDepth == 1 ? "CHAR" : "int8");
10324 else if(t->Type == CPP_TYPE_WORD)
10325 return DoOutput("INTEGER");
10326 else if(t->Type == CPP_TYPE_BYTE)
10327 return DoOutput("SHORTINT");
10328 return DoOutput("int32INT");
10331 /* ------------------------------------------------------------------ */
10333 static uint32 CallPrag(uint32 tagmode, strptr type, FuncType Func)
10335 if(type)
10336 if((*type && !DoOutput("#if%s\n", type)) ||
10337 !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
10338 (*type && !DoOutput("#endif\n")))
10339 return 0;
10340 return 1;
10343 static uint32 CreatePragmaFile(strptr amicall, strptr libcall, strptr amitags,
10344 strptr libtags, uint32 mode)
10346 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10348 switch(mode)
10350 case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10351 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper,
10352 ShortBaseNameUpper); break;
10353 case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10354 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10355 case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10356 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10357 case PRAGMODE_NONE: break;
10358 default: return 0;
10361 if(HEADER)
10363 DoOutput("\n");
10364 DoOutputDirect(HEADER, headersize);
10367 if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10368 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10369 return 0;
10371 if((Flags & FLAG_EXTERNC) &&
10372 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10373 return 0;
10375 if(Flags & FLAG_GNUPRAG)
10377 DoOutput("#ifdef " TEXT_GNUC "\n#ifdef NO_OBSOLETE\n"
10378 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10379 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName);
10380 Flags |= FLAG_DONE;
10384 !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
10385 !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
10386 return 0;
10388 if(tagfuncs)
10391 !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
10392 !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
10393 return 0;
10396 if((Flags & FLAG_EXTERNC) &&
10397 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10398 return 0;
10400 switch(mode)
10402 case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10403 ShortBaseNameUpper); break;
10404 case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10405 ShortBaseNameUpper); break;
10406 case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10407 ShortBaseNameUpper); break;
10408 case PRAGMODE_NONE: break;
10409 default: return 0;
10411 return Output_Error;
10414 static uint32 CreateCSTUBSFile(void)
10416 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10418 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10419 ShortBaseNameUpper, ShortBaseNameUpper);
10421 if(!clibdata)
10423 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10426 if(HEADER)
10428 DoOutput("\n");
10429 DoOutputDirect(HEADER, headersize);
10432 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10433 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10434 return 0;
10436 if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
10437 return 0;
10439 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10440 ShortBaseNameUpper);
10443 static uint32 CreateLVOFile(uint32 mode)
10445 strptr data = "_LVO_I";
10447 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10449 if(mode == 2 || mode == 4)
10450 data = "_LIB_I";
10452 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10453 ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
10454 (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
10455 (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
10456 !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
10457 !DoOutput("\n\n\t\tENDC\n"))
10458 return 0;
10460 return 1;
10463 static uint32 CreateLVOFilePPC(uint32 mode)
10465 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10467 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10468 ShortBaseNameUpper, ShortBaseNameUpper))
10469 return 0;
10470 if(HEADER)
10472 DoOutput("\n");
10473 DoOutputDirect(HEADER, headersize);
10475 switch(mode)
10477 case 0: CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCXDEF);
10478 case 1: CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVOPPC);
10480 return DoOutput("\n\t.endif\n");
10483 static uint32 CreateAsmStubs(uint32 mode, uint32 callmode)
10485 if(mode == 1 && (Flags2 & FLAG2_AUTOHEADER)) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10487 /* 1 = Text, 2 = Code */
10488 switch(mode)
10490 case 1:
10491 if(HEADER)
10493 DoOutput("\n");
10494 DoOutputDirect(HEADER, headersize);
10497 if(!(Flags & FLAG_ASMSECTION))
10498 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
10499 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
10500 if(!CallFunc(callmode, "\n%s", FuncAsmText))
10501 return 0;
10502 break;
10503 case 2:
10504 if(!CallFunc(callmode, 0, FuncAsmCode))
10505 return 0;
10506 break;
10509 return 1;
10512 static uint32 CreateProtoFile(uint32 Type)
10514 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10516 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
10517 ShortBaseNameUpper);
10519 if(HEADER)
10521 DoOutput("\n");
10522 DoOutputDirect(HEADER, headersize);
10525 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10526 if(Type != 5)
10527 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC ")\n"
10528 "#include <clib/%s_protos.h>\n#endif\n",
10529 ShortBaseNameUpper, ShortBaseName);
10531 if(BaseName)
10533 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10534 if(Type == 7)
10535 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10536 "#endif\n");
10537 DoOutput("%s;\n#endif\n", BaseName);
10540 if(Type != 8)
10542 if(Type >= 6)
10544 DoOutput("\n#ifdef " TEXT_GNUC "\n");
10545 if(Type == 10)
10546 DoOutput("#ifndef __cplusplus\n");
10547 DoOutput("#ifdef __AROS__\n");
10548 DoOutput("#include <defines/%s.h>\n", ShortBaseName);
10549 DoOutput("#else\n");
10550 DoOutput("#include <inline/%s.h>\n", ShortBaseName);
10551 DoOutput("#endif\n");
10552 if(Type == 10)
10553 DoOutput("#endif\n");
10554 if(Type != 7)
10556 if(Type == 9)
10557 DoOutput("#elif defined(" TEXT_VBCC ")\n"
10558 "#include <inline/%s_protos.h>\n#else", ShortBaseName);
10559 else
10560 DoOutput("#elif !defined(" TEXT_VBCC ")");
10563 if(Type == 10)
10564 DoOutput("\n#ifndef __PPC__");
10565 if(Type != 7)
10567 strptr str1 = "pragma", str2 = "lib";
10569 switch(Type)
10571 case 4: str1 = "pragmas"; /* no break; */
10572 case 2: str2 = "pragmas"; break;
10573 case 3: str1 = "pragmas"; break;
10574 case 5: str1 = "local"; str2 = "loc"; break;
10576 DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
10578 if(Type == 10)
10579 DoOutput("#endif\n");
10580 if(Type >= 6)
10581 DoOutput("#endif\n");
10584 Flags |= FLAG_DONE;
10586 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10589 static uint32 CreateLocalData(strptr to, uint32 callmode)
10591 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10593 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10594 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10595 ShortBaseNameUpper, ShortBaseNameUpper);
10597 if(HEADER)
10599 DoOutput("\n");
10600 DoOutputDirect(HEADER, headersize);
10603 DoOutput("\n");
10604 PrintIncludes();
10606 if((Flags & FLAG_EXTERNC) &&
10607 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10608 return 0;
10610 if(!CallFunc(callmode, "/%s */\n", FuncLocText))
10611 return 0;
10613 if((Flags & FLAG_EXTERNC) &&
10614 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10615 return 0;
10617 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper);
10619 sprintf(filename, "%s_loc.lib", ShortBaseName);
10620 if(!CloseDest(to) || !OpenDest(filename))
10621 return 0;
10623 CallFunc(callmode, 0, FuncLocCode);
10625 return CloseDest(filename);
10628 static uint32 CreateInline(uint32 mode, uint32 callmode)
10630 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10632 if(!clibdata)
10634 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10637 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10638 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper,
10639 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10641 if(HEADER)
10643 DoOutput("\n");
10644 DoOutputDirect(HEADER, headersize);
10647 DoOutput("\n");
10649 /* prevent loading of clib-file after inline */
10650 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10651 ShortBaseNameUpper, ShortBaseNameUpper);
10653 if(!mode)
10655 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10656 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10657 "#include <ppcinline/macros.h>\n#endif\n\n");
10658 else
10659 DoOutput("#ifndef __INLINE_MACROS_H\n"
10660 "#include <inline/macros.h>\n#endif\n\n");
10661 Flags |= FLAG_INLINENEW;
10663 else if(mode <= 2)
10665 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10666 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10667 "#include <ppcinline/stubs.h>\n#endif\n\n");
10668 else
10669 DoOutput("#ifndef __INLINE_STUB_H\n"
10670 "#include <inline/stubs.h>\n#endif\n\n");
10671 if(mode == 2)
10672 Flags |= FLAG_INLINESTUB;
10674 else if(mode == 3)
10675 Flags2 |= FLAG2_INLINEMAC;
10677 PrintIncludes();
10679 if((Flags & FLAG_EXTERNC) &&
10680 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10681 return 0;
10683 if(BaseName)
10685 if(mode && mode <= 2)
10687 if(Flags & FLAG_MORPHOS)
10688 DoOutput("#include <emul/emulregs.h>\n");
10689 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10690 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10691 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10692 "#define BASE_PAR_DECL0 void\n#endif\n"
10693 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10694 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10696 else
10697 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10698 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10701 if(mode <= 2)
10703 if(!CallFunc(callmode, "/%s */\n", FuncInline))
10704 return 0;
10706 else if(mode >= 6)
10708 if(mode == 7)
10709 Flags |= FLAG_INLINENEW;
10710 if(!CallFunc(callmode, "/%s */\n", FuncInlineDirect))
10711 return 0;
10713 else
10715 if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
10716 return 0;
10719 if(mode && mode <= 2 && BaseName)
10720 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10721 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper);
10723 if((Flags & FLAG_EXTERNC) &&
10724 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10725 return 0;
10727 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10728 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10731 static uint32 CreateGateStubs(uint32 callmode)
10733 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10735 if(!clibdata)
10737 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10739 if(!prefix[0] && !subprefix[0])
10741 DoError(ERR_PREFIX, 0); return 1;
10744 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10745 ShortBaseNameUpper, ShortBaseNameUpper);
10747 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10748 premacro, ShortBaseName);
10750 if(HEADER)
10752 DoOutput("\n");
10753 DoOutputDirect(HEADER, headersize);
10756 if(BaseName)
10758 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10759 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10760 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10761 "#define BASE_PAR_DECL0 void\n#endif\n"
10762 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10763 "BASE_EXT_DECL0\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10766 DoOutput("\n");
10768 if(!CallFunc(callmode, "/%s */\n", FuncGateStubs))
10769 return 0;
10771 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper);
10774 static uint32 CreateSASPowerUP(uint32 callmode)
10776 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10778 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10779 ShortBaseNameUpper, ShortBaseNameUpper);
10781 if(HEADER)
10783 DoOutput("\n");
10784 DoOutputDirect(HEADER, headersize);
10787 DoOutput("\n#ifdef __GNUC__\n"
10788 "#ifndef _PPCINLINE__%s_H\n"
10789 "#include <ppcinline/%s.h>\n"
10790 "#endif\n"
10791 "#else\n\n"
10792 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10793 "#include <ppclib/interface.h>\n"
10794 "#endif\n\n"
10795 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10796 "#include <gcclib/powerup_protos.h>\n"
10797 "#endif\n\n"
10798 "#ifndef NO_PPCINLINE_STDARG\n"
10799 "#define NO_PPCINLINE_STDARG\n"
10800 "#endif /* SAS-C PPC inlines */\n\n",
10801 ShortBaseNameUpper, ShortBaseName);
10803 if(BaseName)
10805 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10806 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10809 if(!CallFunc(callmode, "/%s */\n", FuncPowerUP))
10810 return 0;
10812 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10813 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper);
10816 static uint32 CreateProtoPowerUP(void)
10818 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10820 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10821 ShortBaseNameUpper, ShortBaseNameUpper);
10823 if(HEADER)
10825 DoOutput("\n");
10826 DoOutputDirect(HEADER, headersize);
10829 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
10831 if(BaseName)
10833 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10834 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10835 "#endif\n%s;\n#endif\n", BaseName);
10838 DoOutput("\n#ifdef " TEXT_GNUC "\n"
10839 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10840 "#else\n#include <inline/%s.h>\n#endif\n"
10841 "#else /* SAS-C */\n"
10842 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10843 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10844 ShortBaseName, ShortBaseName, ShortBaseName, ShortBaseName);
10846 Flags |= FLAG_DONE;
10848 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10851 static uint32 CreateFPCUnit(void)
10854 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT);
10856 if(!clibdata)
10858 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10861 DoOutput("{\n");
10862 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName);
10864 if(HEADER)
10866 DoOutput("\n");
10867 DoOutputDirect(HEADER, headersize);
10870 DoOutput("**********************************************************************}\n\n");
10871 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10872 DoOutput("{$mode objfpc}\n");
10873 DoOutput("{$I useamigasmartlink.inc}\n");
10874 DoOutput("{$ifdef use_amiga_smartlink}\n");
10875 DoOutput(" {$smartlink on}\n");
10876 DoOutput("{$endif use_amiga_smartlink}\n\n");
10878 DoOutput("UNIT %s;\n", ShortBaseNameUpper);
10880 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName, GetBaseTypeLib());
10882 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper,ShortBaseName);
10883 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName);
10884 DoOutput("{$I %s.inc}\n\n",ShortBaseName);
10886 if(!CallFunc(TAGMODE_NORMAL, 0, FuncFPCType))
10887 return 0;
10889 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10890 if(!CallFunc(TAGMODE_TAGS, 0, FuncFPCTypeTags))
10891 return 0;
10893 DoOutput("\n{Here we read how to compile this unit}\n");
10894 DoOutput("{You can remove this include and use a define instead}\n");
10895 DoOutput("{$I useautoopenlib.inc}\n");
10896 DoOutput("{$ifdef use_init_openlib}\n");
10897 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10898 DoOutput("{$endif use_init_openlib}\n");
10899 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10900 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper);
10901 DoOutput("\nIMPLEMENTATION\n\n");
10902 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10903 DoOutput("uses \n");
10904 DoOutput("{$ifndef dont_use_openlib}\n");
10905 DoOutput("msgbox, \n");
10906 DoOutput("{$endif dont_use_openlib}\n");
10907 DoOutput("tagsarray;\n\n");
10909 if(!CallFunc(TAGMODE_NORMAL, "(%s *)\n", FuncFPCUnit))
10910 return 0;
10912 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10913 if(!CallFunc(TAGMODE_TAGS,"(%s *)\n", FuncFPCTypeTagsUnit))
10914 return 0;
10916 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10917 DoOutput(" VERSION : string[2] = '0';\n");
10918 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10920 DoOutput("{$ifdef use_init_openlib}\n");
10921 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName);
10922 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper);
10924 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10925 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10926 DoOutput("begin\n");
10927 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10928 DoOutput(" if %s <> nil then begin\n",BaseName);
10929 DoOutput(" CloseLibrary(%s);\n",BaseName);
10930 DoOutput(" %s := nil;\n",BaseName);
10931 DoOutput(" end;\n");
10932 DoOutput("end;\n\n");
10933 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10934 DoOutput("begin\n %s := nil;\n",BaseName);
10935 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10936 DoOutput(" if %s <> nil then begin\n",BaseName);
10937 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10938 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10939 DoOutput(" end else begin\n");
10940 DoOutput(" MessageBox('FPC Pascal Error',\n");
10941 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10942 DoOutput(" 'Deallocating resources and closing down',\n");
10943 DoOutput(" 'Oops');\n");
10944 DoOutput(" halt(20);\n");
10945 DoOutput(" end;\n");
10946 DoOutput("end;\n\n");
10947 DoOutput("begin\n");
10948 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper);
10949 DoOutput("{$endif use_init_openlib}\n\n");
10951 DoOutput("{$ifdef use_auto_openlib}\n");
10952 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName);
10954 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10955 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10956 DoOutput("begin\n");
10957 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10958 DoOutput(" if %s <> nil then begin\n",BaseName);
10959 DoOutput(" CloseLibrary(%s);\n",BaseName);
10960 DoOutput(" %s := nil;\n",BaseName);
10961 DoOutput(" end;\n");
10962 DoOutput("end;\n\n");
10963 DoOutput("begin\n %s := nil;\n",BaseName);
10964 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10965 DoOutput(" if %s <> nil then begin\n",BaseName);
10966 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10967 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10968 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper);
10969 DoOutput(" end else begin\n");
10970 DoOutput(" MessageBox('FPC Pascal Error',\n");
10971 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10972 DoOutput(" 'Deallocating resources and closing down',\n");
10973 DoOutput(" 'Oops');\n");
10974 DoOutput(" halt(20);\n");
10975 DoOutput(" end;\n\n");
10976 DoOutput("{$endif use_auto_openlib}\n\n");
10978 DoOutput("{$ifdef dont_use_openlib}\n");
10979 DoOutput("begin\n");
10980 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper);
10981 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName);
10982 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName);
10983 DoOutput("{$endif dont_use_openlib}\n\n");
10985 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper);
10988 static uint32 CreateBMAP(void)
10990 return CallFunc(TAGMODE_NORMAL, 0, FuncBMAP);
10993 static uint32 CreateLVOLib(void)
10995 uint32 i;
10997 i = strlen(ShortBaseNameUpper);
10998 EndPutM32(tempbuf, HUNK_UNIT);
10999 EndPutM32(tempbuf+4, (i+3)>>2);
11000 DoOutputDirect(tempbuf, 8);
11001 DoOutputDirect(ShortBaseNameUpper, i);
11002 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11004 i = strlen(hunkname);
11005 EndPutM32(tempbuf, HUNK_NAME);
11006 EndPutM32(tempbuf+4, (i + 3)>>2);
11007 DoOutputDirect(tempbuf, 8);
11008 DoOutputDirect(hunkname, i);
11009 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11011 EndPutM32(tempbuf, HUNK_CODE);
11012 EndPutM32(tempbuf+4, 0);
11013 EndPutM32(tempbuf+8, HUNK_EXT);
11014 DoOutputDirect(tempbuf, 12);
11016 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOLib))
11017 return 0;
11019 EndPutM32(tempbuf, 0);
11020 EndPutM32(tempbuf+4, HUNK_END);
11021 return DoOutputDirect(tempbuf, 8);
11024 static uint32 CreateLVOLibPPC(void)
11026 uint8 *data = tempbuf, *data2, *data3;
11028 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11029 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11030 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11031 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11032 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
11033 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
11034 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
11035 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11036 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11037 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11038 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
11039 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
11040 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
11041 EndPutM32Inc(data, 0); /* eeh->e_entry */
11042 EndPutM32Inc(data, 0); /* eeh->e_phoff */
11043 data2 = data; data += 4;
11044 EndPutM32Inc(data, 0); /* eeh->e_flags */
11045 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
11046 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
11047 EndPutM16Inc(data, 0); /* eeh->e_phnum */
11048 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
11049 EndPutM16Inc(data, 4); /* eeh->e_shnum */
11050 EndPutM16Inc(data, 1); /* eeh->e_shstrndx - first table is string table */
11052 data3 = data;
11053 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11054 data += 28; /* 1 9 17*/
11055 EndPutM32(data2, data-tempbuf); /* store the entry */
11057 EndPutM32Inc(data, 0); /* esh[0].sh_name */
11058 EndPutM32Inc(data, 0); /* esh[0].sh_type */
11059 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11060 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11061 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
11062 EndPutM32Inc(data, 0); /* esh[0].sh_size */
11063 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11064 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11065 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
11066 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11068 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
11069 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
11070 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
11071 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
11072 EndPutM32Inc(data, data3-tempbuf); /* esh[3].sh_offset */
11073 EndPutM32Inc(data, 27); /* esh[3].sh_size */
11074 EndPutM32Inc(data, 0); /* esh[3].sh_link */
11075 EndPutM32Inc(data, 0); /* esh[3].sh_info */
11076 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
11077 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
11079 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
11080 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
11081 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
11082 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
11083 data2 = data;
11084 data += 4; /* esh[4].sh_offset */
11085 data += 4; /* esh[4].sh_size */
11086 EndPutM32Inc(data, 3); /* esh[4].sh_link - the third entry is our string table */
11087 EndPutM32Inc(data, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11088 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
11089 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11091 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
11092 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
11093 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11094 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11095 data3 = data;
11096 data += 4; /* esh[0].sh_offset */
11097 data += 4; /* esh[0].sh_size */
11098 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11099 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11100 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
11101 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11103 EndPutM32Inc(data2, data-tempbuf);
11105 EndPutM32Inc(data,0);
11106 EndPutM32Inc(data,0); /* first entry is empty */
11107 EndPutM32Inc(data,0);
11108 EndPutM32Inc(data,0);
11110 symoffset = 1; /* initial value */
11111 elfbufpos = data;
11113 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
11114 return 0;
11115 EndPutM32(data2, elfbufpos-data+16);
11116 EndPutM32Inc(data3, elfbufpos-tempbuf);
11117 EndPutM32(data3, symoffset);
11119 *(elfbufpos++) = 0; /* first sym entry */
11120 if(!DoOutputDirect(tempbuf, elfbufpos-tempbuf))
11121 return 0;
11123 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
11124 return 0;
11126 while((symoffset++)&3)
11128 if(!DoOutputDirect("", 1))
11129 return 0;
11132 return 1;
11135 static uint32 CreateVBCCInline(uint32 mode, uint32 callmode)
11137 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11139 if(!clibdata)
11141 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11144 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11145 ShortBaseNameUpper, ShortBaseNameUpper);
11147 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11148 if (mode == 2)
11150 /* always include emul/emulregs.h in MorphOS inlines,
11151 gcc-based sources might depend on it :| */
11152 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11155 if(HEADER)
11157 DoOutput("\n");
11158 DoOutputDirect(HEADER, headersize);
11161 DoOutput("\n");
11163 if(!CallFunc(callmode, "/%s */\n", mode ? (mode == 2 ? FuncVBCCMorphInline
11164 : FuncVBCCWOSInline) : FuncVBCCInline))
11165 return 0;
11167 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper);
11170 static uint32 CreateVBCC(uint32 mode, uint32 callmode)
11172 uint32 res = 0;
11174 if(mode != 2 && mode != 3)
11176 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11178 if(HEADER)
11180 DoOutput("\n");
11181 DoOutputDirect(HEADER, headersize);
11185 switch(mode)
11187 case 4: res = CallFunc(callmode, 0, FuncVBCCPUPText); break;
11189 case 3: Flags |= FLAG_WOSLIBBASE; /* no break! */
11190 case 2: res = CallFunc(callmode, 0, FuncVBCCWOSCode); break;
11192 case 1: Flags |= FLAG_WOSLIBBASE; /* no break! */
11193 case 0: res = CallFunc(callmode, "\n%s", FuncVBCCWOSText); break;
11195 return res;
11198 static uint32 CreateVBCCPUPLib(uint32 callmode)
11200 /* output header */
11201 DoOutput("!<arch>\n");
11203 return CallFunc(callmode, 0, FuncVBCCPUPCode);
11206 static uint32 CreateVBCCMorphCode(uint32 callmode)
11208 /* output header */
11209 DoOutput("!<arch>\n");
11211 return CallFunc(callmode, 0, FuncVBCCMorphCode);
11214 static uint32 CreateEModule(uint32 sorted)
11216 uint32 res = 0, i;
11217 if(sorted)
11218 DoError(ERR_NO_SORTED, 0);
11219 else
11221 DoOutputDirect("EMOD\0\x06", 6);
11222 for(res = 0; res < 2; ++res)
11224 for(i = 0; BaseName[i]; ++i)
11225 DoOutput("%c", tolower(BaseName[i]));
11226 DoOutputDirect("\x00",1);
11228 LastBias = BIAS_START-BIAS_OFFSET;
11229 CallFunc(TAGMODE_NORMAL, 0, FuncEModule);
11230 res = DoOutputDirect("\xFF",1);
11232 return res;
11235 static uint32 CreateProtoRedirect(void)
11237 Flags |= FLAG_DONE;
11238 return DoOutput("#ifdef NO_OBSOLETE\n"
11239 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11240 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName);
11243 static uint32 CreateSFD(uint32 callmode)
11245 struct Include *inc;
11246 struct AmiPragma *ap;
11247 if(!clibdata)
11249 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11252 if((ap = (struct AmiPragma *) AmiPragma.First))
11253 LastBias = ap->Bias-BIAS_OFFSET;
11254 else /* only security, never used normally */
11255 LastBias = 0;
11256 CurrentABI = ABI_M68K;
11258 if(IDstring)
11259 DoOutput("==id %s\n", IDstring);
11260 else
11262 time_t t;
11263 struct tm * tim;
11265 t = time(&t);
11266 tim = localtime(&t);
11268 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11269 "noname Exp $\n", '$', filename, tim->tm_year+1900, tim->tm_mon+1,
11270 tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec);
11273 if(BaseName)
11274 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11275 GetLibraryName(), BaseName, GetBaseType(), GetLibraryName());
11276 DoOutput("==bias %ld\n==public\n", LastBias+BIAS_OFFSET);
11278 for(inc = (struct Include *) Includes.First; inc; inc = (struct Include *) inc->List.Next)
11279 DoOutput("==include %s\n", inc->Include);
11280 if(!Includes.First)
11281 DoOutput("==include <exec/types.h>\n");
11283 CallFunc(callmode, "%s\n", FuncSFD);
11285 return DoOutput("==end\n");
11288 static uint32 CreateClib(uint32 callmode)
11290 if(!clibdata)
11292 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11295 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11297 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper,
11298 ShortBaseNameUpper);
11300 if(HEADER)
11302 DoOutput("\n");
11303 DoOutputDirect(HEADER, headersize);
11305 else
11307 strptr s = 0;
11308 time_t t;
11309 struct tm * tim;
11311 t = time(&t);
11312 tim = localtime(&t);
11314 if(IDstring)
11316 s = SkipBlanks(IDstring+4);
11317 while(*s && *s != ' ')
11318 ++s;
11319 s=SkipBlanks(s);
11321 if(!s || !*s)
11322 s = "1.0";
11324 if(Flags2 & FLAG2_SYSTEMRELEASE)
11326 DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
11328 else
11330 strptr t;
11332 t = s;
11333 while(*t && *t != ' ')
11334 ++t;
11335 *t = 0;
11337 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename, s,
11338 tim->tm_mday, tim->tm_mon+1, tim->tm_year+1900);
11340 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11341 if(!Copyright || (Copyright && strncmp("Copyright ", Copyright, 10)))
11342 DoOutput("Copyright %c %d ", 0xa9, tim->tm_year+1900);
11343 DoOutput("%s\n", Copyright ? Copyright : Flags2 & FLAG2_SYSTEMRELEASE ?
11344 "Amiga, Inc." : "");
11345 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11348 PrintIncludes();
11350 if((Flags & FLAG_EXTERNC) &&
11351 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11352 return 0;
11354 CallFunc(callmode, "\n/%s */\n\n", FuncClib);
11356 if((Flags & FLAG_EXTERNC) &&
11357 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11358 return 0;
11360 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper);
11363 static uint32 CreateFD(void)
11365 LastBias = 0;
11366 CurrentABI = ABI_M68K;
11368 if(BaseName)
11369 DoOutput("##base _%s\n", BaseName);
11370 DoOutput("##public\n");
11372 CallFunc(TAGMODE_NORMAL, "%s\n", FuncFD);
11374 return DoOutput("##end\n");
11377 static uint32 CreateGenAuto(strptr to, uint32 type)
11379 strptr name, btype;
11380 uint8 *data;
11381 uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
11382 if(!(name = GetLibraryName()))
11383 return 0;
11384 btype = GetBaseType();
11386 switch(type)
11388 case 0:
11389 Flags |= FLAG_DONE;
11390 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11391 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11392 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11393 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11394 btype, BaseName, BaseName,
11395 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", name, BaseName,
11396 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", BaseName)))
11397 return 0;
11398 sprintf(filename, "%s_autoopenver.c", ShortBaseName);
11399 if(!CloseDest(to) || !OpenDest(filename))
11400 return 0;
11401 Flags |= FLAG_DONE;
11402 return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
11403 break;
11404 case 1: /* m68k */
11405 Flags |= FLAG_DONE;
11406 i = strlen(filename)-4; /* remove .lib extension */
11407 EndPutM32(tempbuf, HUNK_UNIT);
11408 EndPutM32(tempbuf+4, (i+3)>>2);
11409 DoOutputDirect(tempbuf, 8);
11410 DoOutputDirect(filename, i);
11411 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11413 i = strlen(hunkname);
11414 EndPutM32(tempbuf, HUNK_NAME);
11415 EndPutM32(tempbuf+4, (i + 3)>>2);
11416 DoOutputDirect(tempbuf, 8);
11417 DoOutputDirect(hunkname, i);
11418 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11420 data = tempbuf+8; /* we need HUNK_CODE + size at start */
11421 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11422 /* SysBase */
11423 if(Flags & FLAG_SMALLDATA)
11425 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11426 EndPutM16Inc(data, 0); /* place for sysbase reference */
11428 else
11430 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11431 EndPutM32Inc(data, 0); /* place for sysbase reference */
11433 verref = data-tempbuf-8+2;
11434 if(Flags & FLAG_SMALLDATA)
11436 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11437 EndPutM16Inc(data, 0); /* place for basevers reference */
11439 else
11441 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11442 EndPutM32Inc(data, 0); /* place for basevers reference */
11444 EndPutM32Inc(data, 0x43FA0030 + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2) + ((Flags & FLAG_SMALLDATA) ? 0 : 6));
11445 EndPutM32Inc(data, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11447 rel1 = data-tempbuf-8+2;
11448 if(Flags & FLAG_SMALLDATA)
11450 EndPutM16Inc(data, 0x2940); /* MOVE.L D0,xxx(A4) */
11451 EndPutM16Inc(data, 0);
11453 else
11455 EndPutM16Inc(data, 0x23C0); /* MOVE.L D0,xxx */
11456 EndPutM32Inc(data, 0);
11458 EndPutM16Inc(data, 0x660A + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2)); /* BNE.B .lib */
11459 EndPutM32Inc(data, 0x48780014); /* PEA 20 */
11461 exitfuncref = data-tempbuf-8+2;
11462 if(Flags2 & FLAG2_SMALLCODE)
11464 EndPutM16Inc(data, 0x4EBA); /* JSR _exit(PC) */
11465 EndPutM16Inc(data, 0); /* place for base reference */
11467 else
11469 EndPutM16Inc(data, 0x4EB9); /* JSR _exit */
11470 EndPutM32Inc(data, 0); /* place for base reference */
11472 EndPutM16Inc(data, 0x584F); /* ADDQ.W, #4,A7 */
11473 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11474 EndPutM16Inc(data,0x4E75); /* RTS */
11475 exitref = data-tempbuf-8;
11477 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11478 sysref2 = data-tempbuf-8+2;
11479 /* SysBase */
11480 if(Flags & FLAG_SMALLDATA)
11482 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11483 EndPutM16Inc(data, 0); /* place for sysbase reference */
11485 else
11487 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11488 EndPutM32Inc(data, 0); /* place for sysbase reference */
11490 rel2 = data-tempbuf-8+2;
11491 if(Flags & FLAG_SMALLDATA)
11493 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11494 EndPutM16Inc(data, 0); /* place for base reference */
11496 else
11498 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11499 EndPutM32Inc(data, 0); /* place for base reference */
11501 EndPutM16Inc(data, 0x6606); /* BNE.B .nolib */
11502 EndPutM16Inc(data, 0x2240); /* MOVEA.L D0,A1 */
11504 EndPutM32Inc(data, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11505 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11506 EndPutM16Inc(data,0x4E75); /* RTS */
11507 nameref = data-tempbuf-8;
11508 memcpy(data, name, strlen(name));
11509 data += strlen(name);
11510 do { *(data++) = 0; } while((data-tempbuf)&3);
11512 EndPutM32(tempbuf, HUNK_CODE);
11513 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
11514 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
11516 if(Flags & FLAG_SMALLDATA)
11518 EndPutM32(tempbuf, HUNK_DREL16);
11520 else
11522 EndPutM32(tempbuf, HUNK_ABSRELOC32);
11524 EndPutM32(tempbuf+4, 2); /* 2 entries */
11525 EndPutM32(tempbuf+8, 1); /* to hunk 1 */
11526 EndPutM32(tempbuf+12, rel1); /* address 0 */
11527 EndPutM32(tempbuf+16, rel2); /* address 0 */
11528 EndPutM32(tempbuf+20, 0); /* end of reloc hunk */
11529 DoOutputDirect(tempbuf, 24);
11531 /* extern references */
11532 EndPutM32(tempbuf, HUNK_EXT);
11533 DoOutputDirect(tempbuf, 4);
11535 OutputXREF2(4, sysref2, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_SysBase");
11536 OutputXREF(verref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "__%sVer", BaseName);
11537 OutputXREF(exitfuncref, (Flags2 & FLAG2_SMALLCODE ? EXT_DEXT16 : EXT_REF32), "_exit");
11538 OutputXDEF(0, "__INIT_%ld_%s", priority, BaseName);
11539 OutputXDEF(exitref, "__EXIT_%ld_%s", priority, BaseName);
11540 OutputXDEF(nameref, "%sname", ShortBaseName);
11541 EndPutM32(tempbuf, 0); /* ext end */
11542 DoOutputDirect(tempbuf, 4);
11544 if(!(Flags & FLAG_NOSYMBOL))
11546 EndPutM32(tempbuf, HUNK_SYMBOL);
11547 DoOutputDirect(tempbuf, 4);
11548 OutputSYMBOL(0, "__INIT_%ld_%s", priority, BaseName);
11549 OutputSYMBOL(exitref, "__EXIT_%ld_%s", priority, BaseName);
11550 OutputSYMBOL(nameref, "%sname", ShortBaseName);
11551 EndPutM32(tempbuf, 0);
11552 DoOutputDirect(tempbuf, 4);
11555 EndPutM32(tempbuf, HUNK_END);
11556 DoOutputDirect(tempbuf, 4);
11558 i = strlen(datahunkname);
11559 EndPutM32(tempbuf, HUNK_NAME);
11560 EndPutM32(tempbuf+4, (i + 3)>>2);
11561 DoOutputDirect(tempbuf, 8);
11562 DoOutputDirect(datahunkname, i);
11563 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11565 EndPutM32(tempbuf, HUNK_BSS);
11566 EndPutM32(tempbuf+4, 1);
11567 DoOutputDirect(tempbuf, 8);
11569 EndPutM32(tempbuf, HUNK_EXT);
11570 DoOutputDirect(tempbuf, 4);
11571 OutputXDEF(0, "_%s", BaseName);
11572 EndPutM32(tempbuf, 0); /* ext end */
11573 DoOutputDirect(tempbuf, 4);
11575 if(!(Flags & FLAG_NOSYMBOL))
11577 EndPutM32(tempbuf, HUNK_SYMBOL);
11578 DoOutputDirect(tempbuf, 4);
11579 OutputSYMBOL(0, "_%s", BaseName);
11580 EndPutM32(tempbuf, 0);
11581 DoOutputDirect(tempbuf, 4);
11584 EndPutM32(tempbuf, HUNK_END);
11585 DoOutputDirect(tempbuf, 4);
11587 sprintf(filename, "%s_autoopenver", ShortBaseName);
11588 i = strlen(filename);
11589 EndPutM32(tempbuf, HUNK_UNIT);
11590 EndPutM32(tempbuf+4, (i+3)>>2);
11591 DoOutputDirect(tempbuf, 8);
11592 DoOutputDirect(filename, i);
11593 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11595 i = strlen(datahunkname);
11596 EndPutM32(tempbuf, HUNK_NAME);
11597 EndPutM32(tempbuf+4, (i + 3)>>2);
11598 DoOutputDirect(tempbuf, 8);
11599 DoOutputDirect(datahunkname, i);
11600 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11602 EndPutM32(tempbuf, HUNK_BSS);
11603 EndPutM32(tempbuf+4, 1);
11604 DoOutputDirect(tempbuf, 8);
11606 EndPutM32(tempbuf, HUNK_EXT);
11607 DoOutputDirect(tempbuf, 4);
11608 OutputXDEF(0, "_%sVer", BaseName);
11609 EndPutM32(tempbuf, 0); /* ext end */
11610 DoOutputDirect(tempbuf, 4);
11612 if(!(Flags & FLAG_NOSYMBOL))
11614 EndPutM32(tempbuf, HUNK_SYMBOL);
11615 DoOutputDirect(tempbuf, 4);
11616 OutputSYMBOL(0, "_%sVer", BaseName);
11617 EndPutM32(tempbuf, 0);
11618 DoOutputDirect(tempbuf, 4);
11621 EndPutM32(tempbuf, HUNK_END);
11622 return DoOutputDirect(tempbuf, 4);
11624 break;
11626 return 0;
11629 static uint32 CreateXML(void)
11631 struct Include *inc;
11632 char *basetypelib;
11634 LastBias = 30;
11635 DoOutput(
11636 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11637 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11638 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11639 ShortBaseName, BaseName, GetLibraryName());
11640 basetypelib = GetBaseTypeLib();
11641 if(basetypelib && (strcmp(basetypelib, "Library") != 0))
11642 DoOutput(" basetype=\"%s\"", basetypelib);
11643 DoOutput(">\n");
11644 for(inc = (struct Include *) Includes.First; inc;
11645 inc = (struct Include *) inc->List.Next)
11646 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc->Include)-2),
11647 inc->Include+1);
11648 if(!Includes.First)
11649 DoOutput("\t<include>exec/types.h</include>\n");
11651 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11652 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11653 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11654 DoOutput(
11655 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11656 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11657 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11658 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11659 " status=\"unimplemented\"/>\n");
11661 CallFunc(TAGMODE_BOTH, 0, FuncXML);
11663 return DoOutput("\t</interface>\n</library>\n");
11666 static uint32 CreateOS4PPC(uint32 callmode)
11668 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11670 if(HEADER)
11672 DoOutput("\n");
11673 DoOutputDirect(HEADER, headersize);
11676 PrintIncludes();
11678 DoOutput(
11679 "#include <stdarg.h>\n"
11680 "#include <exec/types.h>\n"
11681 "#include <exec/interfaces.h>\n"
11682 "#include <exec/emulation.h>\n"
11683 "#include <interfaces/exec.h>\n");
11685 if(!stricmp("exec",ShortBaseName))
11686 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName);
11688 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName);
11690 CallFunc(callmode, "\n/%s */\n\n", FuncOS4PPC);
11692 DoOutput(
11693 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11694 " return Self->Data.RefCount++;\n}\n\n"
11695 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11696 " return Self->Data.RefCount--;\n}\n\n"
11697 "#define LIBNAME \"%s\"\n"
11698 "#define LIBVERSION 0\n"
11699 "#define IFACENAME \"%s.main\"\n\n",
11700 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11701 GetLibraryName(), GetLibraryName());
11703 /* following text is constant */
11704 return DoOutput(
11705 "static void InitFunction(APTR dummy, ULONG SegList, "
11706 "struct ExecBase *ExecBase)\n{\n"
11707 " struct Library *LibBase;\n"
11708 " struct ExecIFace *IExec = (struct ExecIFace *)"
11709 "ExecBase->MainInterface;\n"
11710 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11711 " {\n"
11712 " struct Interface *NewInterface;\n"
11713 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11714 " MIT_VectorTable, main_vectors,\n"
11715 " MIT_Version, 1,\n"
11716 " MIT_Name, IFACENAME,\n"
11717 " TAG_DONE)))\n"
11718 " {\n"
11719 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11720 " IExec->AddInterface(LibBase, NewInterface);\n"
11721 " }\n"
11722 " }\n"
11723 "}\n\n"
11724 "volatile static struct Resident MyResident =\n{\n"
11725 " RTC_MATCHWORD,\n"
11726 " (struct Resident *)&MyResident,\n"
11727 " (APTR)(&MyResident+1),\n"
11728 " RTF_NATIVE,\n"
11729 " LIBVERSION,\n"
11730 " NT_UNKNOWN,\n"
11731 " -120,\n"
11732 " IFACENAME,\n"
11733 " IFACENAME,\n"
11734 " InitFunction\n"
11735 "};\n\n"
11736 "void _start(void)\n"
11737 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11738 "\n}\n");
11741 static uint32 CreateOS4M68K(void)
11743 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11745 if(HEADER)
11747 DoOutput("\n");
11748 DoOutputDirect(HEADER, headersize);
11750 DoOutput(
11751 "#include \"exec/interfaces.i\"\n"
11752 "#include \"exec/libraries.i\"\n"
11753 "#include \"exec/emulation.i\"\n"
11754 "#include \"interfaces/%s.i\"\n\n",ShortBaseName);
11756 DoOutput(
11757 "\t.section .data\n"
11758 "\t.globl\tstub_Open\n"
11759 "\t.type\tstub_Open,@function\n"
11760 "\n"
11761 "stub_Open:\n"
11762 "\t.short\t0x4ef8\n" /* JMP.w */
11763 "\t.short\t0\n" /* Indicate switch */
11764 "\t.short\t1\n" /* Trap type */
11765 "\t.globl\tstub_OpenPPC\n"
11766 "\t.long\tstub_OpenPPC\n"
11767 "\t.byte\t2\n" /* Register mapping */
11768 "\t.byte\t1,REG68K_A7\n"
11769 "\t.byte\t3,REG68K_A6\n"
11770 "\t.section .text\n"
11771 "\t.align\t4\n"
11772 "\n"
11773 "stub_OpenPPC:\n"
11774 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11775 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11776 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11777 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11778 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11779 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11780 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11781 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11782 "\tCallLib\tlmi_Open\n"
11783 "\tlwz\t%s11,%s12(%s1)\n"
11784 "\tmtlr\t%s11\n"
11785 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11786 "\tblrl\n" /* Return to emulation */
11787 "\n"
11788 "\t.globl\tstub_Open68K\n"
11789 "\t.long\tstub_Open68K\n"
11790 "\t.byte\t0\n" /* Flags */
11791 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11792 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11793 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11794 "\t.section .data\n"
11795 "\t.align\t4\n"
11796 "\n"
11797 "stub_Open68K:\n"
11798 "\t.short\t0x4e75\n" /* RTS */
11799 "\n"
11800 "\t.section .data\n"
11801 "\t.globl\tstub_Close\n"
11802 "\t.type\tstub_Close,@function\n"
11803 "\n"
11804 "stub_Close:\n"
11805 "\t.short\t0x4ef8\n" /* JMP.w */
11806 "\t.short\t0\n" /* Indicate switch */
11807 "\t.short\t1\n" /* Trap type */
11808 "\t.globl\tstub_ClosePPC\n"
11809 "\t.long\tstub_ClosePPC\n"
11810 "\t.byte\t2\n" /* Register mapping */
11811 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11812 "\t.byte\t3,REG68K_A6\n"
11813 "\t.section .text\n"
11814 "\t.align\t4\n"
11815 "\n"
11816 "stub_ClosePPC:\n"
11817 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11818 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11819 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11820 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11821 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11822 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11823 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11824 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11825 "\tCallLib\tlmi_Close\n"
11826 "\tlwz\t%s11,12(%s1)\n"
11827 "\tmtlr\t%s11\n"
11828 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11829 "\tblrl\n" /* Return to emulation */
11830 "\n"
11831 "\t.globl\tstub_Close68K\n"
11832 "\t.long\tstub_Close68K\n"
11833 "\t.byte\t0\n" /* Flags */
11834 "\t.byte\t1\n" /* One register (a7 only) */
11835 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11836 "\t.section .data\n"
11837 "\t.align\t4\n"
11838 "\n"
11839 "stub_Close68K:\n"
11840 "\t.short\t0x4e75\n" /* RTS */
11841 "\n"
11842 "\t.section .data\n"
11843 "\t.globl\tstub_Expunge\n"
11844 "\t.type\tstub_Expunge,@function\n"
11845 "\n"
11846 "stub_Expunge:\n"
11847 "\t.short\t0x7000\n" /* moveq #0, d0 */
11848 "\t.short\t0x4e75\n" /* RTS */
11849 "\n"
11850 "\t.section .data\n"
11851 "\t.globl\tstub_Reserved\n"
11852 "\t.type\tstub_Reserved,@function\n"
11853 "\n"
11854 "stub_Reserved:\n"
11855 "\t.short\t0x7000\n" /* moveq #0, d0 */
11856 "\t.short\t0x4e75\n\n", /* RTS */
11857 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
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);
11867 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68K);
11868 DoOutput("\n"
11869 "\t.globl\tVector68K\n"
11870 "\t.globl\tVecTable68K\n"
11871 "Vector68K:\n"
11872 "\t.long\tVecTable68K\n"
11873 "VecTable68K:\n"
11874 "\t.long\tstub_Open\n"
11875 "\t.long\tstub_Close\n"
11876 "\t.long\tstub_Expunge\n"
11877 "\t.long\tstub_Reserved\n");
11879 LastBias = 30;
11880 CallFunc(TAGMODE_NORMAL, 0, FuncOS4M68KVect);
11881 DoOutput("\t.long\t-1\n");
11883 CloseDest(filename);
11885 if(Flags2 & FLAG2_OS4M68KCSTUB)
11887 sprintf(filename, "%s_68k.c", ShortBaseName);
11888 if(!OpenDest(filename))
11889 exit(20);
11890 Flags &= ~(FLAG_DONE);
11891 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11893 if(HEADER)
11895 DoOutput("\n");
11896 DoOutputDirect(HEADER, headersize);
11899 DoOutput(
11900 "#ifdef __USE_INLINE__\n"
11901 "#undef __USE_INLINE__\n"
11902 "#endif\n"
11903 "#ifndef __NOGLOBALIFACE__\n"
11904 "#define __NOGLOBALIFACE__\n"
11905 "#endif\n\n"
11906 "#include <exec/interfaces.h>\n"
11907 "#include <exec/libraries.h>\n"
11908 "#include <exec/emulation.h>\n"
11909 "#include <interfaces/exec.h>\n"
11910 "#include <interfaces/%s.h>\n"
11911 "#include <proto/%s.h>\n\n", ShortBaseName, ShortBaseName);
11913 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68KCSTUB);
11915 return Output_Error;
11918 /* ------------------------------------------------------------------ */
11920 static uint32 GetName(struct NameList *t, struct ShortListRoot *p, uint32 args)
11922 struct NameList *p2 = (struct NameList *) p->First;
11923 struct AmiPragma ap;
11924 memset(&ap, 0, sizeof(struct AmiPragma));
11925 ap.FuncName = t->NormName;
11926 ap.NumArgs = 1;
11927 ap.CallArgs = 1;
11928 ap.Args[0].ArgName = (args ? "args" : "tags");
11929 if(!MakeTagFunction(&ap))
11930 return 0;
11932 if(!ap.TagName)
11933 return 0;
11935 while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
11936 p2 = (struct NameList *) p2->List.Next;
11938 if(!p2)
11939 return 0;
11941 t->Type = (args ? NTP_ARGS : NTP_TAGS);
11942 t->PragName = ap.TagName;
11943 RemoveItem(p, (struct ShortList *) p2);
11945 #ifdef DEBUG_OLD
11946 printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
11947 #endif
11949 return 1;
11952 static void OptimizeFDData(struct PragData *pd)
11954 #ifdef DEBUG_OLD
11955 printf("OptimizeFDData\n");
11956 #endif
11958 while(pd)
11960 if(pd->NumNames > 1)
11962 struct ShortListRoot n = {0,0,0}, p = {0,0,0};
11963 struct NameList *t;
11964 while(pd->Name.First) /* sorts in AmiCall and TagCall */
11966 t = (struct NameList *) pd->Name.First;
11968 RemoveItem(&pd->Name, (struct ShortList *) t);
11969 AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
11972 if(p.First)
11974 t = (struct NameList *) n.First;
11975 while(p.First && t)
11977 if(!GetName(t, &p, 0))
11979 GetName(t, &p, 1);
11981 if(t->PragName)
11983 struct NameList *t2 = (struct NameList *) t->List.Next;
11984 RemoveItem(&n, (struct ShortList *)t);
11985 AddItem(&pd->Name, (struct ShortList *) t);
11986 t = t2;
11988 else
11989 t = (struct NameList *) t->List.Next;
11991 while(p.First)
11993 if(n.First)
11995 t = (struct NameList *) n.First;
11996 t->PragName = ((struct NameList *)(p.First))->PragName;
11997 RemoveItem(&n, (struct ShortList *) t);
11998 #ifdef DEBUG_OLD
11999 printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
12000 #endif
12001 t->Type = NTP_UNKNOWN;
12003 else
12005 uint32 i;
12007 t = (struct NameList *) p.First;
12008 i = strlen(t->PragName);
12009 t->NormName = DupString(t->PragName, i+1);
12010 t->NormName[i++] = 'A';
12011 t->NormName[i] = 0;
12012 t->Type = NTP_TAGS;
12013 #ifdef DEBUG_OLD
12014 printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
12015 #endif
12018 AddItem(&pd->Name, (struct ShortList *) t);
12019 RemoveItem(&p, p.First);
12023 AddItem(&pd->Name, n.First); /* add left NormNames */
12025 pd = (struct PragData *) pd->List.Next;
12029 static uint32 MakeFD(struct PragList *pl)
12031 struct PragData *pd = (struct PragData *) pl->Data.First;
12032 uint32 bias;
12034 #ifdef DEBUG_OLD
12035 printf("MakeFD\n");
12036 #endif
12037 bias = pd->Bias;
12039 OptimizeFDData(pd);
12040 #ifdef DEBUG_OLD
12041 printf("MakeFD: after Optimizing\n");
12042 #endif
12043 DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
12045 while(pd && Output_Error)
12047 struct NameList *n = (struct NameList *) pd->Name.First;
12049 if(bias != pd->Bias)
12050 DoOutput("##bias %ld\n", (bias = pd->Bias));
12052 while(n)
12054 strptr lastpar = "last";
12055 uint32 i;
12057 if(n->Type == NTP_TAGS)
12058 lastpar = "tags";
12059 else if(n->Type == NTP_ARGS)
12060 lastpar = "args";
12062 DoOutput("%s("/*)*/,n->NormName);
12063 if(!pd->NumArgs)
12064 DoOutput(/*(*/")()\n");
12065 else
12067 for(i = 0; i < pd->NumArgs-1; ++i)
12068 DoOutput("par%ld,",i+1);
12069 DoOutput(/*(*/"%s)("/*)*/, lastpar);
12070 for(i = 0; i < pd->NumArgs-1; ++i)
12071 DoOutput("%s,", RegNames[pd->ArgReg[i]]);
12072 DoOutput(/*(*/"%s)\n", RegNames[pd->ArgReg[i]]);
12074 if(n->Type == NTP_UNKNOWN)
12076 uint32 i;
12077 for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
12079 DoOutput("*tagcall");
12080 if(n->NormName[i])
12081 DoOutput("-%s", n->NormName+i);
12082 if(n->PragName[i])
12083 DoOutput("+%s", n->PragName+i);
12085 DoOutput("\n");
12088 if((n = (struct NameList *) n->List.Next))
12089 DoOutput("##bias %ld\n", pd->Bias);
12090 Flags |= FLAG_DONE;
12093 pd = (struct PragData *)pd->List.Next; bias += BIAS_OFFSET;
12096 DoOutput("##end\n");
12098 return Output_Error;
12101 static uint32 AddFDData(struct ShortListRoot *pls, struct FDData *fd)
12103 struct NameList *t;
12104 struct PragList *pl = (struct PragList *) pls->First;
12105 struct PragData *pd;
12107 while(pl && strcmp(pl->Basename, fd->Basename))
12108 pl = (struct PragList *) pl->List.Next;
12110 if(!pl)
12112 #ifdef DEBUG_OLD
12113 printf("AddFDData: New PragList - %s\n", fd->Basename);
12114 #endif
12115 if(!(pl = (struct PragList *) NewItem(pls)))
12116 return 100;
12117 pl->Basename = fd->Basename;
12118 pl->Data.Size = sizeof(struct PragData);
12119 AddItem(pls, (struct ShortList *) pl);
12122 if((pd = (struct PragData *) pl->Data.First))
12124 while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
12125 <= fd->Bias)
12126 pd = (struct PragData *) pd->List.Next;
12129 if(!pd || pd->Bias != fd->Bias)
12131 struct PragData *pd2;
12132 #ifdef DEBUG_OLD
12133 printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
12134 #endif
12135 if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
12136 return 100;
12137 pd2->Bias = fd->Bias;
12138 memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
12139 pd2->NumArgs = fd->NumArgs;
12140 pd2->Name.Size = sizeof(struct NameList);
12141 if(!pd)
12142 AddItem(&pl->Data, (struct ShortList *) pd2);
12143 else if(pd->Bias > fd->Bias) /* Insert at start */
12145 pd2->List.Next = pl->Data.First;
12146 pl->Data.First = (struct ShortList *) pd2;
12148 else /* Insert the entry */
12150 pd2->List.Next = pd->List.Next;
12151 pd->List.Next = (struct ShortList *) pd2;
12153 pd = pd2;
12155 else
12157 uint32 i = fd->NumArgs;
12158 if(fd->NumArgs != pd->NumArgs)
12160 #ifdef DEBUG_OLD
12161 printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
12162 #endif
12163 return ERR_DIFFERENT_TO_PREVIOUS;
12166 while(i--)
12168 if(fd->ArgReg[i] != pd->ArgReg[i])
12170 #ifdef DEBUG_OLD
12171 printf("ArgReg %x != %x\n", fd->ArgReg[i], pd->ArgReg[i]);
12172 #endif
12173 return ERR_DIFFERENT_TO_PREVIOUS;
12178 t = (struct NameList *) pd->Name.First; /* skips same names */
12179 while(t && (!(fd->Mode ? t->PragName : t->NormName) ||
12180 strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName)))
12181 t = (struct NameList *) t->List.Next;
12183 if(t)
12184 return 0;
12186 if(!(t = (struct NameList *) NewItem(&pd->Name)))
12187 return 100;
12188 if(fd->Mode)
12189 t->PragName = fd->Name;
12190 else
12191 t->NormName = fd->Name;
12192 AddItem(&pd->Name, (struct ShortList *) t);
12193 ++(pd->NumNames);
12194 #ifdef DEBUG_OLD
12195 printf("AddFDData: New NameList - %s\n", fd->Name);
12196 #endif
12197 return 0;
12200 static string GetHexValue(string data)
12202 if(data >= 'a')
12203 return (string) (data - 'a' + 10);
12204 else if(data >= 'A')
12205 return (string) (data - 'A' + 10);
12206 else
12207 return (string) (data - '0');
12210 static string GetDoubleHexValue(strptr data)
12212 return (string)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
12215 static uint32 GetLibData(struct FDData *fd)
12217 uint32 i;
12218 fd->Name = SkipBlanks(in.pos);
12219 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12220 in.pos = SkipBlanks(in.pos);
12221 fd->Bias = strtoul(in.pos, 0, 16);
12222 in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
12223 if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
12224 return ERR_TO_MUCH_ARGUMENTS;
12225 --in.pos; /* skips return register */
12226 for(i = 0; i < fd->NumArgs; ++i)
12228 if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
12229 return ERR_EXPECTED_REGISTER_NAME;
12231 return 0;
12234 static uint32 GetFlibData(struct FDData *fd)
12236 uint32 i;
12237 fd->Name = SkipBlanks(in.pos);
12238 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12239 in.pos = SkipBlanks(in.pos);
12240 fd->Bias = strtoul(in.pos, 0, 16);
12241 in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
12242 if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
12243 return ERR_TO_MUCH_ARGUMENTS;
12244 in.pos -= 2; /* skips return register */
12245 for(i = 0; i < fd->NumArgs; ++i)
12247 in.pos -= 2;
12248 if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
12249 return ERR_EXPECTED_REGISTER_NAME;
12250 else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
12251 return ERR_FLOATARG_NOT_ALLOWED;
12253 return 0;
12256 static uint32 GetAmiData(struct FDData *fd)
12258 strptr endptr;
12259 in.pos = SkipBlanks(in.pos);
12260 if(*in.pos != '('/*)*/)
12261 return ERR_EXPECTED_OPEN_BRACKET;
12262 fd->Basename = ++in.pos;
12263 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12264 if(*in.pos != ',')
12265 return ERR_EXPECTED_COMMA;
12266 *endptr = 0;
12267 in.pos = SkipBlanks(++in.pos);
12268 if(!strncmp(in.pos, "0x", 2))
12269 fd->Bias = strtoul(in.pos+2, 0, 16);
12270 else
12271 fd->Bias = strtoul(in.pos, 0, 10);
12273 in.pos = SkipBlanks(SkipName(in.pos));
12274 if(*in.pos != ',')
12275 return ERR_EXPECTED_COMMA;
12276 fd->Name = in.pos = SkipBlanks(++in.pos);
12277 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12278 if(*in.pos != '('/*)*/)
12279 return ERR_EXPECTED_OPEN_BRACKET;
12280 *endptr = 0;
12281 in.pos = SkipBlanks(++in.pos);
12282 if(*in.pos == /*(*/')')
12283 return 0;
12284 --in.pos;
12285 while(*in.pos != /*(*/')')
12287 uint32 i;
12288 in.pos = SkipBlanks(in.pos+1);
12290 for(i = 0; i < REG_FP0; i++)
12291 if(!strnicmp(RegNames[i], in.pos, 2))
12292 break;
12293 if(i == REG_FP0)
12295 for(; i < MAXREG; i++)
12296 if(!strnicmp(RegNames[i], in.pos, 3))
12297 break;
12300 if(i == MAXREG)
12301 return ERR_EXPECTED_REGISTER_NAME;
12302 else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
12303 return ERR_FLOATARG_NOT_ALLOWED;
12305 fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
12307 if(fd->NumArgs > MAXREG-2)
12308 return ERR_TO_MUCH_ARGUMENTS;
12310 in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
12312 if(*in.pos != ',' && *in.pos != /*(*/')')
12313 return ERR_EXPECTED_CLOSE_BRACKET;
12315 in.pos = SkipBlanks(in.pos+1);
12316 if(*in.pos != /*(*/')')
12317 return ERR_EXPECTED_CLOSE_BRACKET;
12318 return 0;
12321 static uint32 CreateFDFile(void)
12323 struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
12324 uint32 linenum, err = 0, skip;
12325 strptr ptr, p2;
12327 ptr = p2 = args.infile;
12328 while(*p2)
12330 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
12331 ptr = p2+1;
12332 ++p2;
12334 for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
12336 if(p2 != ptr)
12338 ShortBaseName = ptr;
12339 *p2 = '\0';
12342 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
12344 in.pos = SkipBlanks(in.pos);
12345 if(!strncmp("#pragma", in.pos, 7))
12347 struct FDData fd;
12349 skip = 0;
12350 memset(&fd, 0, sizeof(struct FDData));
12352 in.pos = SkipBlanks(in.pos+7);
12353 if(!strncmp("tagcall", in.pos, 7))
12355 fd.Mode = 1;
12356 in.pos = SkipBlanks(in.pos+7);
12357 if(*in.pos == '(' /*)*/) /* Storm method */
12358 err = GetAmiData(&fd);
12359 else /* SAS method */
12361 fd.Basename = in.pos;
12362 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12363 err = GetLibData(&fd);
12366 else if(!strncmp("amicall", in.pos, 7)) /* Storm method */
12368 in.pos += 7;
12369 err = GetAmiData(&fd);
12371 else if(!strncmp("libcall", in.pos, 7)) /* SAS method */
12373 fd.Basename = SkipBlanks(in.pos+7);
12374 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12375 err = GetLibData(&fd);
12377 else if(!strncmp("flibcall", in.pos, 8)) /* SAS method */
12379 fd.Basename = SkipBlanks(in.pos+8);
12380 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12381 err = GetFlibData(&fd);
12383 else if(!strncmp("syscall", in.pos, 7)) /* SAS method */
12385 fd.Basename = "SysBase";
12386 err = GetLibData(&fd);
12388 else
12389 skip = 1;
12391 if(err)
12392 DoError(err, linenum);
12393 else if(skip)
12395 else if((err = AddFDData(&pl, &fd)))
12397 if(err != 100)
12398 DoError(err, linenum);
12399 return 0;
12402 while(*(in.pos++)) /* jumps to first char of next line */
12406 if(pl.First)
12408 struct PragList *p = (struct PragList *) pl.First;
12409 if(!p->List.Next)
12411 strptr text, to;
12412 uint32 i;
12414 if(ShortBaseName)
12416 text = ShortBaseName; i = strlen(text);
12418 else
12420 text = p->Basename; i = strlen(text)-4;
12423 to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
12424 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12425 if(!OpenDest(to))
12426 return 0;
12428 err = MakeFD(p);
12429 CloseDest(to);
12430 if(!err)
12431 return 0;
12433 else
12435 while(p)
12437 strptr to;
12438 uint32 i;
12439 i = strlen(p->Basename) - 4;
12440 to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
12441 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12442 if(!OpenDest(to))
12443 return 0;
12444 i = MakeFD(p);
12445 CloseDest(to);
12446 if(!i)
12447 return 0;
12448 p = (struct PragList *) p->List.Next;
12453 return 1;
12456 #ifdef FD2PRAGMA_READARGS
12457 #include <proto/dos.h>
12459 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12460 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12461 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12462 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12463 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12464 "NEWSYNTAX/S," \
12465 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12466 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12467 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12468 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12469 "VOIDBASE/S"
12471 struct AmiArg
12473 strptr INFILE;
12474 uint32* SPECIAL;
12475 uint32* MODE;
12476 strptr TO;
12477 strptr ABI;
12478 strptr CLIB;
12479 strptr COPYRIGHT;
12480 strptr HEADER;
12481 strptr HUNKNAME;
12482 strptr BASENAME;
12483 strptr LIBTYPE;
12484 strptr LIBNAME;
12485 uint32* PRIORITY;
12486 strptr PREFIX;
12487 strptr SUBPREFIX;
12488 strptr PREMACRO;
12489 uint32 AUTOHEADER;
12490 uint32 COMMENT;
12491 uint32 EXTERNC;
12492 uint32 FPUONLY;
12493 uint32 NEWSYNTAX;
12494 uint32 NOFPU;
12495 uint32 NOPPC;
12496 uint32 NOPPCREGNAME;
12497 uint32 NOSYMBOL;
12498 uint32 ONLYCNAMES;
12499 uint32 OPT040;
12500 uint32 PPCONLY;
12501 uint32 PRIVATE;
12502 uint32 SECTION;
12503 uint32 SMALLCODE;
12504 uint32 SMALLDATA;
12505 uint32 SMALLTYPES;
12506 uint32 SORTED;
12507 uint32 SYSTEMRELEASE;
12508 uint32 USESYSCALL;
12509 uint32 VOIDBASE;
12512 static const strptr helptext =
12513 "INFILE: the input file which should be used\n"
12514 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12515 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12516 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12517 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12518 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12519 "\t 6 - pragma for all compilers [default]\n"
12520 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12521 "\t10 - stub-functions for C - C text\n"
12522 "\t11 - stub-functions for C - assembler text\n"
12523 "\t12 - stub-functions for C - link library\n"
12524 "\t13 - defines and link library for local library base (register call)\n"
12525 "\t14 - defines and link library for local library base (stack call)\n"
12526 "\t15 - stub-functions for Pascal - assembler text\n"
12527 "\t16 - stub-functions for Pascal - link library\n"
12528 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12529 "\t18 - module for AmigaE\n"
12530 "\t20 - assembler lvo _lvo.i file\n"
12531 "\t21 - assembler lvo _lib.i file\n"
12532 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12533 "\t23 - assembler lvo _lib.i file no XDEF\n"
12534 "\t24 - assembler lvo link library\n"
12535 "\t30 - proto file with pragma/..._lib.h call\n"
12536 "\t31 - proto file with pragma/..._pragmas.h call\n"
12537 "\t32 - proto file with pragmas/..._lib.h call\n"
12538 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12539 "\t34 - proto file with local/..._loc.h call\n"
12540 "\t35 - proto file for all compilers (VBCC stubs)\n"
12541 "\t36 - proto file for GNU-C compiler only\n"
12542 "\t37 - proto file without lib definitions\n"
12543 "\t38 - proto file for all compilers (VBCC inline)\n"
12544 "\t39 - proto file with special PPC related checks\n"
12545 "\t40 - GCC inline file (preprocessor based)\n"
12546 "\t41 - GCC inline file (old type - inline based)\n"
12547 "\t42 - GCC inline file (library stubs)\n"
12548 "\t43 - GCC inline file (new style - macro)\n"
12549 "\t44 - GCC inline file (new style - inline)\n"
12550 "\t45 - GCC inline file (new style - inline with include lines)\n"
12551 "\t46 - GCC inline file (preprocessor based, direct)\n"
12552 "\t47 - GCC inline file (new style, direct)\n"
12553 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12554 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12555 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12556 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12557 "\t53 - SAS-C include file for PowerUP\n"
12558 "\t54 - Proto file for PowerUP\n"
12559 "\t60 - FPC pascal unit text\n"
12560 "\t70 - VBCC inline files\n"
12561 "\t71 - VBCC WOS stub-functions - assembler text\n"
12562 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12563 "\t73 - VBCC WOS stub-functions - link library\n"
12564 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12565 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12566 "\t76 - VBCC PowerUP stub-functions - link library\n"
12567 "\t77 - VBCC WOS inline files\n"
12568 "\t78 - VBCC MorphOS stub-functions - link library\n"
12569 "\t79 - VBCC old inline files\n"
12570 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12571 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12572 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12573 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12574 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12575 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12576 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12577 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12578 " 100 - PPC assembler lvo file\n"
12579 " 101 - PPC assembler lvo file no XDEF\n"
12580 " 102 - PPC assembler lvo ELF link library\n"
12581 " 103 - PPC assembler lvo EHF link library\n"
12582 " 104 - PPC V.4-ABI assembler file\n"
12583 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12584 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12585 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12586 " 110 - FD file\n"
12587 " 111 - CLIB file\n"
12588 " 112 - SFD file\n"
12589 " 120 - VBCC auto libopen files (C source)\n"
12590 " 121 - VBCC auto libopen files (m68k link library)\n"
12591 " 122 - VBCC MorphOS inline files\n"
12592 " 123 - VBCC new MorphOS inline files\n"
12593 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12594 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12595 " 132 - GCC inline files for MorphOS (library stubs)\n"
12596 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12597 " 134 - MorphOS gate stubs\n"
12598 " 135 - MorphOS gate stubs (prelib)\n"
12599 " 136 - MorphOS gate stubs (postlib)\n"
12600 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12601 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12602 " 140 - OS4 XML file\n"
12603 " 141 - OS4 PPC->M68K cross-call stubs\n"
12604 " 142 - OS4 M68K->PPC cross-call stubs\n"
12605 " 200 - FD file (source is a pragma file!)\n"
12606 "MODE: SPECIAL 1-7:\n"
12607 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12608 " 2: _PRAGMAS_..._LIB_H definition method\n"
12609 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12610 " 4: no definition\n"
12611 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12612 " 130-138,141:\n"
12613 " 1: all functions, normal interface\n"
12614 " 2: only tag-functions, tagcall interface\n"
12615 " 3: all functions, normal and tagcall interface [default]\n"
12616 "TO: the destination directory (self creation of filename)\n"
12617 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12618 "CLIB: name of the prototypes file in clib directory\n"
12619 "COPYRIGHT: the copyright text for CLIB files\n"
12620 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12621 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12622 "BASENAME: name of library base without '_'\n"
12623 "LIBNAME: name of the library (.e.g. dos.library)\n"
12624 "LIBTYPE: type of base library structure\n"
12625 "PRIORITY: priority for auto open files\n"
12626 "PREFIX: MorphOS gate prefix\n"
12627 "SUBPREFIX: MorphOS gate sub prefix\n"
12628 "PREMACRO: MorphOS gate file start macro\n"
12629 "Switches:\n"
12630 "AUTOHEADER add the typical automatic generated header\n"
12631 "COMMENT: copy comments found in input file\n"
12632 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12633 "FPUONLY: work only with functions using FPU register arguments\n"
12634 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12635 "NOFPU: disable usage of FPU register arguments\n"
12636 "NOPPC: disable usage of PPC-ABI functions\n"
12637 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12638 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12639 "ONLYCNAMES: do not create C++ or ASM names\n"
12640 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12641 "PPCONLY: only use PPC-ABI functions\n"
12642 "PRIVATE: includes private declared functions\n"
12643 "SECTION: add section statements to asm texts\n"
12644 "SMALLCODE: generate small code link libraries or assembler text\n"
12645 "SMALLDATA: generate small data link libraries or assembler text\n"
12646 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12647 "SORTED: sort generated files by name and not by bias value\n"
12648 "SYSTEMRELEASE: special handling of comments for system includes\n"
12649 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12650 "VOIDBASE: library bases are of type void *\n";
12652 /* print the help text */
12653 static void printhelp(void)
12655 printf("%s\n%s\n\n%s", version+6, PARAM, helptext);
12656 exit(20);
12659 /* initializes the arguments and starts argument parsing */
12660 static void GetArgs(int argc, char **argv)
12662 struct RDArgs *rda;
12663 struct AmiArg amiargs;
12664 int res = 0;
12666 if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
12668 rda->RDA_ExtHelp = helptext;
12669 memset(&amiargs, 0, sizeof(struct AmiArg));
12670 if(ReadArgs(PARAM, (int32 *) &amiargs, rda))
12672 int l;
12673 strptr d, s;
12675 l = strlen(amiargs.TO ? amiargs.TO : "") + 1
12676 + strlen(amiargs.CLIB ? amiargs.CLIB : "") + 1
12677 + strlen(amiargs.HEADER ? amiargs.HEADER : "") + 1
12678 + strlen(amiargs.ABI ? amiargs.ABI : "") + 1
12679 + strlen(amiargs.HUNKNAME ? amiargs.HUNKNAME : "") + 1
12680 + strlen(amiargs.BASENAME ? amiargs.BASENAME : "") + 1
12681 + strlen(amiargs.LIBTYPE ? amiargs.LIBTYPE : "") + 1
12682 + strlen(amiargs.LIBNAME ? amiargs.LIBNAME : "") + 1
12683 + strlen(amiargs.COPYRIGHT ? amiargs.COPYRIGHT : "") + 1
12684 + strlen(amiargs.PREFIX ? amiargs.PREFIX : "") + 1
12685 + strlen(amiargs.SUBPREFIX ? amiargs.SUBPREFIX : "") + 1
12686 + strlen(amiargs.PREMACRO ? amiargs.PREMACRO : "") + 1
12687 + strlen(amiargs.INFILE) + 1;
12688 if((d = AllocListMem(l)))
12690 res = 1;
12692 s = amiargs.INFILE;
12693 args.infile = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12694 if((s = amiargs.TO))
12696 args.to = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12698 if((s = amiargs.HEADER))
12700 args.header = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12702 if((s = amiargs.CLIB))
12704 args.clib = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12706 if((s = amiargs.HUNKNAME))
12708 hunkname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12710 if((s = amiargs.BASENAME))
12712 Flags |= FLAG_BASENAME;
12713 BaseName = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12715 if((s = amiargs.LIBTYPE))
12717 Flags2 |= FLAG2_LIBTYPE;
12718 libtype = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12720 if((s = amiargs.LIBNAME))
12722 Flags2 |= FLAG2_LIBNAME;
12723 libname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12725 if((s = amiargs.PREFIX))
12727 prefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12729 if((s = amiargs.SUBPREFIX))
12731 subprefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12733 if((s = amiargs.PREMACRO))
12735 premacro = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12737 if((s = amiargs.COPYRIGHT))
12739 Copyright = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12741 if((s = amiargs.ABI))
12743 defabi = d; while(*s) *(d++) = *(s++); *d = 0;
12745 if(amiargs.EXTERNC) Flags ^= FLAG_EXTERNC;
12746 if(amiargs.PRIVATE) Flags ^= FLAG_PRIVATE;
12747 if(amiargs.NEWSYNTAX) Flags ^= FLAG_NEWSYNTAX;
12748 if(amiargs.SMALLDATA) Flags ^= FLAG_SMALLDATA;
12749 if(amiargs.SMALLCODE) Flags2 ^= FLAG2_SMALLCODE;
12750 if(amiargs.SMALLTYPES) Flags2 ^= FLAG2_SMALLTYPES;
12751 if(amiargs.USESYSCALL) Flags ^= FLAG_SYSCALL;
12752 if(amiargs.OPT040) Flags ^= FLAG_NOMOVEM;
12753 if(amiargs.NOFPU) Flags ^= FLAG_NOFPU;
12754 if(amiargs.FPUONLY) Flags ^= FLAG_FPUONLY;
12755 if(amiargs.NOPPC) Flags ^= FLAG_NOPPC;
12756 if(amiargs.NOSYMBOL) Flags ^= FLAG_NOSYMBOL;
12757 if(amiargs.PPCONLY) Flags ^= FLAG_PPCONLY;
12758 if(amiargs.SECTION) Flags ^= FLAG_ASMSECTION;
12759 if(amiargs.COMMENT) Flags ^= FLAG_DOCOMMENT;
12760 if(amiargs.SORTED) Flags ^= FLAG_SORTED;
12761 if(amiargs.ONLYCNAMES) Flags ^= FLAG_ONLYCNAMES;
12762 if(amiargs.SYSTEMRELEASE) Flags2 ^= FLAG2_SYSTEMRELEASE;
12763 if(amiargs.VOIDBASE) Flags2 ^= FLAG2_VOIDBASE;
12764 if(amiargs.NOPPCREGNAME) PPCRegPrefix = "";
12765 if(amiargs.AUTOHEADER) Flags2 ^= FLAG2_AUTOHEADER;
12766 if(amiargs.SPECIAL)
12767 args.special = *amiargs.SPECIAL;
12768 if(amiargs.MODE)
12769 args.mode = *amiargs.MODE;
12770 if(amiargs.PRIORITY)
12771 priority = *amiargs.PRIORITY;
12773 FreeArgs(rda);
12775 else
12776 PrintFault(IoErr(), 0);
12777 FreeDosObject(DOS_RDARGS, rda);
12780 if(!res)
12781 /* printhelp(); */
12782 exit(20);
12785 #else
12786 static const strptr helptext =
12787 " -h,--help\n"
12788 " -i,--infile <input filename>\n"
12789 " -s,--special <number>\n"
12790 " -m,--mode <number>\n"
12791 " -t,--to <destination directory>\n"
12792 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12793 " -c,--clib <clib prototypes filename>\n"
12794 " -d,--header <header file or \"\">\n"
12795 " -i,--libname <name of library>\n"
12796 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12797 " -b,--basename <name of library base without '_'>\n"
12798 " -l,--libtype <name of base library type>\n"
12799 " -p,--priority <priority for auto open files>\n"
12800 " -r,--copyright<copyright text>\n"
12801 " --prefix <MorphOS gate prefix>\n"
12802 " --subprefix<MorphOS gate sub prefix>\n"
12803 " --premacro <MorphOS gate file start macro>\n"
12804 "\n"
12805 "Switches:\n"
12806 "--autoheader add the typical automatic generated header\n"
12807 "--comment copy comments found in input file\n"
12808 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12809 "--fpuonly work only with functions using FPU register arguments\n"
12810 "--newsyntax uses new Motorola syntax for asm files\n"
12811 "--nofpu disable usage of FPU register arguments\n"
12812 "--noppc disable usage of PPC-ABI functions\n"
12813 "--noppcregname do not add 'r' to PPC register names\n"
12814 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12815 "--onlycnames do not create C++ or ASM names\n"
12816 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12817 "--ppconly only use PPC-ABI functions\n"
12818 "--private includes private declared functions\n"
12819 "--section add section statements to asm texts\n"
12820 "--smallcode generate small code link libraries or assembler text\n"
12821 "--smalldata generate small data link libraries or assembler text\n"
12822 "--smalltypes allow 8 and 16 bit types in registers\n"
12823 "--sorted sort generated files by name and not by bias value\n"
12824 "--systemrelease special handling of comments for system includes\n"
12825 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12826 "--voidbase library bases are of type void *\n"
12827 "\n"
12828 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12829 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12830 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12831 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12832 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12833 " 6 - pragma for all compilers [default]\n"
12834 " 7 - all compilers with pragma to inline redirect for GCC\n"
12835 " 10 - stub-functions for C - C text\n"
12836 " 11 - stub-functions for C - assembler text\n"
12837 " 12 - stub-functions for C - link library\n"
12838 " 13 - defines and link library for local library base (register call)\n"
12839 " 14 - defines and link library for local library base (stack call)\n"
12840 " 15 - stub-functions for Pascal - assembler text\n"
12841 " 16 - stub-functions for Pascal - link library\n"
12842 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12843 " 18 - module for AmigaE\n"
12844 " 20 - assembler lvo _lvo.i file\n"
12845 " 21 - assembler lvo _lib.i file\n"
12846 " 22 - assembler lvo _lvo.i file no XDEF\n"
12847 " 23 - assembler lvo _lib.i file no XDEF\n"
12848 " 24 - assembler lvo link library\n"
12849 " 30 - proto file with pragma/..._lib.h call\n"
12850 " 31 - proto file with pragma/..._pragmas.h call\n"
12851 " 32 - proto file with pragmas/..._lib.h call\n"
12852 " 33 - proto file with pragmas/..._pragmas.h call\n"
12853 " 34 - proto file with local/..._loc.h call\n"
12854 " 35 - proto file for all compilers (VBCC stubs)\n"
12855 " 36 - proto file for GNU-C compiler only\n"
12856 " 37 - proto file without lib definitions\n"
12857 " 38 - proto file for all compilers (VBCC inline)\n"
12858 " 39 - proto file with special PPC related checks\n"
12859 " 40 - GCC inline file (preprocessor based)\n"
12860 " 41 - GCC inline file (old type - inline based)\n"
12861 " 42 - GCC inline file (library stubs)\n"
12862 " 43 - GCC inline file (new style - macro)\n"
12863 " 44 - GCC inline file (new style - inline)\n"
12864 " 45 - GCC inline file (new style - inline with include lines)\n"
12865 " 46 - GCC inline file (preprocessor based, direct)\n"
12866 " 47 - GCC inline file (new style, direct)\n"
12867 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12868 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12869 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12870 " 52 - GCC inline files for PowerUP (library stubs)\n"
12871 " 53 - SAS-C include file for PowerUP\n"
12872 " 54 - Proto file for PowerUP\n"
12873 " 60 - FPC pascal unit text\n"
12874 " 70 - VBCC inline files\n"
12875 " 71 - VBCC WOS stub-functions - assembler text\n"
12876 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12877 " 73 - VBCC WOS stub-functions - link library\n"
12878 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12879 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12880 " 76 - VBCC PowerUP stub-functions - link library\n"
12881 " 77 - VBCC WOS inline files\n"
12882 " 78 - VBCC MorphOS stub-functions - link library\n"
12883 " 79 - VBCC old inline files\n"
12884 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12885 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12886 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12887 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12888 " 90 - stub-functions for C - assembler text (multiple files)\n"
12889 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12890 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12891 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12892 " 100 - PPC assembler lvo file\n"
12893 " 101 - PPC assembler lvo file no XDEF\n"
12894 " 102 - PPC assembler lvo ELF link library\n"
12895 " 103 - PPC assembler lvo EHF link library\n"
12896 " 104 - PPC V.4-ABI assembler file\n"
12897 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12898 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12899 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12900 " 110 - FD file\n"
12901 " 111 - CLIB file\n"
12902 " 112 - SFD file\n"
12903 " 120 - VBCC auto libopen files (C source)\n"
12904 " 121 - VBCC auto libopen files (m68k link library)\n"
12905 " 122 - VBCC MorphOS inline files\n"
12906 " 123 - VBCC new MorphOS inline files\n"
12907 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12908 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12909 " 132 - GCC inline files for MorphOS (library stubs)\n"
12910 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12911 " 134 - MorphOS gate stubs\n"
12912 " 135 - MorphOS gate stubs (prelib)\n"
12913 " 136 - MorphOS gate stubs (postlib)\n"
12914 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12915 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12916 " 140 - OS4 XML file\n"
12917 " 141 - OS4 PPC->M68K cross-call stubs\n"
12918 " 142 - OS4 M68K->PPC cross-call stubs\n"
12919 " 200 - FD file (source is a pragma file!)\n"
12920 "mode: special 1-7\n"
12921 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12922 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12923 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12924 " 4 - no definition\n"
12925 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12926 " 130-138,141:\n"
12927 " 1 - all functions, normal interface\n"
12928 " 2 - only tag-functions, tagcall interface\n"
12929 " 3 - all functions, normal and tagcall interface [default]\n";
12931 /* print the help text */
12932 static void printhelp(void)
12934 printf("%s\n%s", version+6, helptext);
12935 exit(20);
12938 struct ArgData
12940 strptr ArgName;
12941 uint8 ArgChar;
12942 uint8 ArgNameLen;
12943 uint8 ArgNum;
12946 enum ArgNums {
12947 ARG_HELP, ARG_INFILE, ARG_SPECIAL, ARG_MODE, ARG_TO, ARG_CLIB, ARG_ABI, ARG_COPYRIGHT,
12948 ARG_HEADER, ARG_HUNKNAME, ARG_BASENAME, ARG_LIBTYPE,
12949 ARG_COMMENT, ARG_EXTERNC, ARG_FPUONLY, ARG_NEWSYNTAX, ARG_NOFPU, ARG_NOPPC,
12950 ARG_NOSYMBOL, ARG_ONLYCNAMES, ARG_OPT040, ARG_PPCONLY, ARG_PRIVATE, ARG_SECTION,
12951 ARG_SMALLDATA, ARG_SORTED, ARG_USESYSCALL, ARG_NOPPCREGNAME,
12952 ARG_SYSTEMRELEASE, ARG_PRIORITY, ARG_LIBNAME, ARG_SMALLCODE, ARG_VOIDBASE,
12953 ARG_PREFIX, ARG_SUBPREFIX, ARG_PREMACRO, ARG_SMALLTYPES, ARG_AUTOHEADER
12956 /* argument definition array */
12957 static const struct ArgData argtexts[] = {
12958 {"help", 'h', 4, ARG_HELP},
12959 {"infile", 'i', 6, ARG_INFILE},
12960 {"special", 's', 7, ARG_SPECIAL},
12961 {"mode", 'm', 4, ARG_MODE},
12962 {"to", 't', 2, ARG_TO},
12963 {"clib", 'c', 4, ARG_CLIB},
12964 {"abi", 'a', 3, ARG_ABI},
12965 {"copyright", 'r', 9, ARG_COPYRIGHT},
12966 {"header", 'd', 6, ARG_HEADER},
12967 {"hunkname", 'n', 8, ARG_HUNKNAME},
12968 {"basename", 'b', 8, ARG_BASENAME},
12969 {"libtype", 'l', 7, ARG_LIBTYPE},
12970 {"libname", 'i', 7, ARG_LIBNAME},
12971 {"priority", 'p', 8, ARG_PRIORITY},
12972 {"autoheader", 0, 10, ARG_AUTOHEADER},
12973 {"comment", 0, 7, ARG_COMMENT},
12974 {"externc", 0, 7, ARG_EXTERNC},
12975 {"fpuonly", 0, 7, ARG_FPUONLY},
12976 {"newsyntax", 0, 9, ARG_NEWSYNTAX},
12977 {"nofpu", 0, 5, ARG_NOFPU},
12978 {"noppc", 0, 5, ARG_NOPPC},
12979 {"noppcregname", 0, 12, ARG_NOPPCREGNAME},
12980 {"nosymbol", 0, 8, ARG_NOSYMBOL},
12981 {"onlycnames", 0, 10, ARG_ONLYCNAMES},
12982 {"opt040", 0, 6, ARG_OPT040},
12983 {"ppconly", 0, 7, ARG_PPCONLY},
12984 {"private", 0, 7, ARG_PRIVATE},
12985 {"section", 0, 7, ARG_SECTION},
12986 {"smalldata", 0, 9, ARG_SMALLDATA},
12987 {"smalltypes", 0, 10, ARG_SMALLTYPES},
12988 {"smallcode", 0, 9, ARG_SMALLCODE},
12989 {"sorted", 0, 6, ARG_SORTED},
12990 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE},
12991 {"usesyscall", 0, 10, ARG_USESYSCALL},
12992 {"voidbase", 0, 8, ARG_VOIDBASE},
12993 {"prefix", 0, 6, ARG_PREFIX},
12994 {"subprefix", 0, 9, ARG_SUBPREFIX},
12995 {"premacro", 0, 8, ARG_PREMACRO},
12996 {0,0,0,0}, /* end marker */
12999 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
13000 static uint32 ParseArgEntry(uint32 argc, strptr *argv)
13002 uint32 numentries = 1, l;
13003 strptr a, b;
13004 const struct ArgData *ad;
13006 if((*argv)[0] != '-' || !(*argv)[1])
13007 return 0;
13009 ad = argtexts;
13010 while(ad->ArgName)
13012 if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
13013 break;
13014 ++ad;
13016 if(!ad->ArgName)
13017 return 0;
13018 switch(ad->ArgNum)
13020 case ARG_HELP: printhelp(); break;
13021 case ARG_EXTERNC: Flags ^= FLAG_EXTERNC; break;
13022 case ARG_PRIVATE: Flags ^= FLAG_PRIVATE; break;
13023 case ARG_NEWSYNTAX: Flags ^= FLAG_NEWSYNTAX; break;
13024 case ARG_SMALLDATA: Flags ^= FLAG_SMALLDATA; break;
13025 case ARG_SMALLCODE: Flags2 ^= FLAG2_SMALLCODE; break;
13026 case ARG_SMALLTYPES: Flags2 ^= FLAG2_SMALLTYPES; break;
13027 case ARG_USESYSCALL: Flags ^= FLAG_SYSCALL; break;
13028 case ARG_OPT040: Flags ^= FLAG_NOMOVEM; break;
13029 case ARG_NOFPU: Flags ^= FLAG_NOFPU; break;
13030 case ARG_FPUONLY: Flags ^= FLAG_FPUONLY; break;
13031 case ARG_NOPPC: Flags ^= FLAG_NOPPC; break;
13032 case ARG_NOSYMBOL: Flags ^= FLAG_NOSYMBOL; break;
13033 case ARG_PPCONLY: Flags ^= FLAG_PPCONLY; break;
13034 case ARG_SECTION: Flags ^= FLAG_ASMSECTION; break;
13035 case ARG_COMMENT: Flags ^= FLAG_DOCOMMENT; break;
13036 case ARG_SORTED: Flags ^= FLAG_SORTED; break;
13037 case ARG_ONLYCNAMES: Flags ^= FLAG_ONLYCNAMES; break;
13038 case ARG_SYSTEMRELEASE: Flags2 ^= FLAG2_SYSTEMRELEASE; break;
13039 case ARG_VOIDBASE: Flags2 ^= FLAG2_VOIDBASE; break;
13040 case ARG_AUTOHEADER: Flags2 ^= FLAG2_AUTOHEADER; break;
13041 case ARG_NOPPCREGNAME: PPCRegPrefix = "";
13042 default:
13043 a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
13044 if(!(*a))
13046 if(argc > 1) { a = argv[1]; numentries = 2; }
13047 else { a = 0; numentries = 0;}
13049 else if(*a == '=')
13050 ++a;
13051 if(a)
13053 if(*a == '\"')
13055 l = strlen(++a);
13056 if(a[l-1] == '\"')
13057 a[--l] = 0; /* remove second " */
13059 switch(ad->ArgNum)
13061 case ARG_INFILE: args.infile = a; break;
13062 case ARG_COPYRIGHT: Copyright = a; break;
13063 case ARG_TO: args.to = a; break;
13064 case ARG_ABI: defabi = a; break;
13065 case ARG_CLIB: args.clib = a; break;
13066 case ARG_HEADER: args.header = a; break;
13067 case ARG_HUNKNAME: hunkname = a; break;
13068 case ARG_PREFIX: prefix = a; break;
13069 case ARG_SUBPREFIX: subprefix = a; break;
13070 case ARG_PREMACRO: premacro = a; break;
13071 case ARG_LIBTYPE: libtype = a; Flags2 |= FLAG2_LIBTYPE; break;
13072 case ARG_LIBNAME: libname = a; Flags2 |= FLAG2_LIBNAME; break;
13073 case ARG_BASENAME: BaseName = a; Flags |= FLAG_BASENAME; break;
13074 case ARG_SPECIAL:
13075 args.special = strtoul(a, &b, 10);
13076 if(*b)
13077 numentries = 0;
13078 break;
13079 case ARG_PRIORITY:
13080 priority = strtoul(a, &b, 10);
13081 if(*b)
13082 numentries = 0;
13083 break;
13084 case ARG_MODE:
13085 args.mode = strtoul(a, &b, 10);
13086 if(*b || args.mode < 1 || args.mode > 3)
13087 numentries = 0;
13088 break;
13092 return numentries;
13095 /* initializes the arguments and starts argument parsing */
13096 static void GetArgs(int argc, char **argv)
13098 int res = 1;
13099 int i = 1, j;
13101 while(i < argc && res)
13103 if((j = ParseArgEntry(argc-i, argv+i)) < 1)
13104 res = 0;
13105 else
13106 i += j;
13108 if(!res || !args.infile)
13109 printhelp();
13112 #endif
13114 static strptr mygetfile(strptr name, size_t *len)
13116 strptr ptr = 0;
13117 FILE *infile;
13119 if((infile = fopen(name, "rb")))
13121 if(!fseek(infile, 0, SEEK_END))
13123 *len = ftell(infile);
13124 if(!fseek(infile, 0, SEEK_SET))
13126 if((ptr = AllocListMem(*len+1)))
13128 ptr[*len] = 0;
13129 #ifdef DEBUG_OLD
13130 printf("mygetfile: '%s' size %d\n", name, *len);
13131 #endif
13132 if(fread(ptr, *len, 1, infile) != 1)
13133 ptr = 0;
13137 fclose(infile);
13139 return ptr;
13142 int main(int argc, char **argv)
13144 uint32 mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_BOTH;
13145 strptr amicall = 0, libcall = 0, amitags = 0, libtags = 0;
13146 strptr clibbuf;
13147 size_t clibsize = 0;
13149 GetArgs(argc, argv);
13151 if((tempbuf = (uint8 *) AllocListMem(TEMPSIZE)))
13153 if(!(in.pos = in.buf = mygetfile(args.infile, &in.size)))
13155 if(args.special == 200)
13157 DoError(ERR_OPEN_FILE, 0, args.infile);
13158 exit(20);
13160 else
13162 sprintf((strptr)tempbuf, "%s" SFDFILEEXTENSION, args.infile);
13163 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13165 sprintf((strptr)tempbuf, "%s" FDFILEEXTENSION, args.infile);
13166 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13168 DoError(ERR_OPEN_FILE, 0, args.infile);
13169 exit(20);
13171 else
13172 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13174 else
13175 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13178 printf("SourceFile: %s\n", args.infile);
13180 MakeLines(in.pos, in.size);
13182 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SORTED)) /* is not possible to use both */
13184 DoError(ERR_SORTED_COMMENT, 0);
13185 Flags &= (~FLAG_SORTED);
13188 if(args.special == 200)
13190 CreateFDFile();
13191 exit(0);
13194 if(!GetTypes())
13195 exit(20);
13197 if(!ScanFDFile())
13198 exit(20);
13200 if(args.clib)
13202 if(Flags2 & FLAG2_SFDMODE)
13203 DoError(ERR_SFD_AND_CLIB, 0);
13204 else
13206 sprintf((strptr)tempbuf, "%s_protos.h", args.clib);
13207 if(!(clibbuf = mygetfile(args.clib, &clibsize)) && !(clibbuf = mygetfile((strptr)tempbuf, &clibsize)))
13209 DoError(ERR_OPEN_FILE, 0, args.clib);
13210 exit(20);
13212 ScanClibFile(clibbuf, clibbuf+clibsize);
13216 if(!MakeShortBaseName())
13218 DoError(ERR_MISSING_SHORTBASENAME, 0);
13219 exit(20);
13222 /* WARN when requesting obsolete types! */
13223 switch(args.special)
13225 case 1: case 2: case 3: case 4: case 5: case 7:
13226 printf("You use obsolete data type %ld, better use type 6!\n", args.special);
13227 break;
13228 case 11: case 15: case 71: case 72: case 75:
13229 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13230 "link libraries!\n", args.special);
13231 break;
13232 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13233 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args.special);
13234 break;
13235 case 79:
13236 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13237 break;
13240 if(args.special < 10) /* the pragma area is up to 9 */
13242 mode = MODUS_PRAGMA;
13243 sprintf(filename, "%s_lib.h", ShortBaseName);
13245 switch(args.special)
13247 case 0: break;
13248 case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
13249 case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13250 pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
13251 case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13252 pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
13253 libtags = "def " TEXT_SAS_60; break;
13254 case 4: amicall = ""; break;
13255 case 5: amicall = amitags = ""; break;
13256 case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
13257 case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
13258 TEXT_MAXON ") || defined(" TEXT_STORM ")";
13259 libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
13260 libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
13261 default: mode = MODUS_ERROR; break;
13264 if(args.mode > 0 && args.mode < 5)
13265 pragmode = args.mode;
13267 else if(args.special < 20) /* the misc area is up to 19 */
13269 if(args.mode > 0 && args.mode < 4)
13270 callmode = args.mode - 1;
13271 switch(args.special)
13273 case 10: mode = MODUS_CSTUB;
13274 sprintf(filename, "%s_cstub.h", ShortBaseName); break;
13275 case 11: mode = MODUS_STUBTEXT;
13276 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13277 case 12: mode = MODUS_STUBCODE;
13278 sprintf(filename, "%s.lib", ShortBaseName); break;
13279 case 13: Flags |= FLAG_LOCALREG; /* no break ! */
13280 case 14: mode = MODUS_LOCALDATA;
13281 sprintf(filename, "%s_loc.h", ShortBaseName); break;
13282 case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
13283 Flags ^= FLAG_PASCAL;
13284 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13285 case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
13286 Flags ^= FLAG_PASCAL;
13287 sprintf(filename, "%s.lib", ShortBaseName); break;
13288 case 17: mode = MODUS_BMAP; callmode = TAGMODE_NORMAL;
13289 sprintf(filename, "%s.bmap", ShortBaseName); break;
13290 case 18: mode = MODUS_EMODULE;
13291 sprintf(filename, "%s.m", ShortBaseName); break;
13292 default: mode = MODUS_ERROR; break;
13295 else if(args.special < 30) /* the lvo area is up to 29 */
13297 switch(args.special)
13299 case 20: case 22: mode = MODUS_LVO+args.special-20;
13300 sprintf(filename, "%s_lvo.i", ShortBaseName); break;
13301 case 21: case 23: mode = MODUS_LVO+args.special-20;
13302 sprintf(filename, "%s_lib.i", ShortBaseName); break;
13303 case 24: mode = MODUS_LVOLIB;
13304 sprintf(filename, "%slvo.o", ShortBaseName); break;
13305 default: mode = MODUS_ERROR; break;
13308 else if(args.special < 40) /* the proto area is up to 39 */
13310 if(args.special < 40)
13312 mode = MODUS_PROTO+args.special-30;
13313 sprintf(filename, "%s.h", ShortBaseName);
13315 else
13316 mode = MODUS_ERROR;
13318 else if(args.special < 50) /* the inline area is up to 49 */
13320 if(args.mode > 0 && args.mode < 4)
13321 callmode = args.mode - 1;
13323 switch(args.special)
13325 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13326 case 47:
13327 mode = MODUS_INLINE+args.special-40;
13328 sprintf(filename, "%s.h", ShortBaseName); break;
13329 case 48:
13330 Flags |= FLAG_STORMGCC;
13331 /* the same mode as for 46, but additional flag */
13332 mode = MODUS_INLINE+args.special-40-2;
13333 sprintf(filename, "%s.h", ShortBaseName); break;
13334 default: mode = MODUS_ERROR; break;
13337 else if(args.special < 60) /* the PowerUP area is up to 59 */
13339 if(args.mode > 0 && args.mode < 4)
13340 callmode = args.mode - 1;
13342 switch(args.special)
13344 case 50: case 51: case 52: mode = MODUS_INLINE+args.special-50;
13345 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_POWERUP;
13346 break;
13347 case 53:
13348 sprintf(filename, "%s_pragmas.h", ShortBaseName);
13349 mode = MODUS_SASPOWER; break;
13350 case 54:
13351 sprintf(filename, "%s.h", ShortBaseName);
13352 mode = MODUS_PROTOPOWER; break;
13353 default: mode = MODUS_ERROR; break;
13356 else if(args.special < 70) /* the PASCAL stuff */
13358 if(args.special == 60)
13360 mode = MODUS_PASCAL;
13361 sprintf(filename, "%s.pas", ShortBaseName);
13363 else
13364 mode = MODUS_ERROR;
13366 else if(args.special < 80) /* the VBCC stuff */
13368 if(args.mode > 0 && args.mode < 4)
13369 callmode = args.mode - 1;
13371 switch(args.special)
13373 case 70: mode = MODUS_VBCCINLINE;
13374 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13375 case 71: case 72: case 75:
13376 mode = MODUS_VBCC+args.special-71;
13377 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13378 case 73: case 74:
13379 mode = MODUS_VBCC+args.special-71;
13380 sprintf(filename, "%s.lib", ShortBaseName); break;
13381 case 76:
13382 mode = MODUS_VBCCPUPLIB;
13383 sprintf(filename, "lib%s.a", ShortBaseName); break;
13384 case 77: mode = MODUS_VBCCWOSINLINE;
13385 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13386 case 78: mode = MODUS_VBCCMORPHCODE;
13387 sprintf(filename, "lib%s.a", ShortBaseName); break;
13388 case 79: mode = MODUS_VBCCINLINE;
13389 Flags2 |= FLAG2_OLDVBCC;
13390 callmode = TAGMODE_NORMAL;
13391 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13392 default: mode = MODUS_ERROR; break;
13395 else if(args.special < 90) /* redirect stuff */
13397 mode = MODUS_REDIRECT;
13398 switch(args.special)
13400 case 80: sprintf(filename, "%s_pragmas.h", ShortBaseName); break;
13401 case 81: sprintf(filename, "%s_lib.h", ShortBaseName); break;
13402 case 82: sprintf(filename, "%s.h", ShortBaseName); break;
13403 case 83: sprintf(filename, "%s_protos.h", ShortBaseName); break;
13404 default: mode = MODUS_ERROR; break;
13407 else if(args.special < 100) /* multifile stuff */
13409 Flags |= FLAG_SINGLEFILE;
13410 switch(args.special)
13412 case 90:
13413 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13414 mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
13415 break;
13416 case 91:
13417 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13418 mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
13419 break;
13420 case 92:
13421 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13422 mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
13423 break;
13424 case 93:
13425 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13426 mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
13427 break;
13428 default: mode = MODUS_ERROR; break;
13431 else if(args.special < 110) /* PPC lvo's */
13433 switch(args.special)
13435 case 100: case 101: mode = MODUS_LVOPPC+args.special-100;
13436 sprintf(filename, "%s_lib.i", ShortBaseName);
13437 break;
13438 case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
13439 Flags |= FLAG_ABIV4;
13440 sprintf(filename, "%s_lib.i", ShortBaseName);
13441 break;
13442 case 103: mode = MODUS_LVOLIB;
13443 sprintf(filename, "%slvo.o", ShortBaseName);
13444 break;
13445 case 107: mode = MODUS_LVOLIB;
13446 Flags |= FLAG_ABIV4;
13447 sprintf(filename, "%slvo.o", ShortBaseName);
13448 break;
13449 case 102: mode = MODUS_LVOLIBPPC;
13450 sprintf(filename, "%slvo.o", ShortBaseName); break;
13451 case 106: mode = MODUS_LVOLIBPPC;
13452 Flags |= FLAG_ABIV4;
13453 sprintf(filename, "%slvo.o", ShortBaseName); break;
13454 default: mode = MODUS_ERROR; break;
13457 else if(args.special < 120) /* different files */
13459 if(args.mode > 0 && args.mode < 4)
13460 callmode = args.mode - 1;
13462 switch(args.special)
13464 case 110: mode = MODUS_FD;
13465 sprintf(filename, "%s_lib.fd", ShortBaseName);
13466 if(Flags & FLAG_SORTED) /* is not possible to use here */
13468 DoError(ERR_SORTED_SFD_FD, 0);
13469 Flags &= (~FLAG_SORTED);
13471 break;
13472 case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
13473 sprintf(filename, "%s_protos.h", ShortBaseName);
13474 break;
13475 case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
13476 sprintf(filename, "%s_lib.sfd", ShortBaseName);
13477 if(callmode == 1)
13479 callmode = 2;
13480 DoError(ERR_ONLYTAGMODE_NOTALLOWED, 0);
13483 if(Flags & FLAG_SORTED) /* is not possible to use here */
13485 DoError(ERR_SORTED_SFD_FD, 0);
13486 Flags &= (~FLAG_SORTED);
13488 break;
13489 default: mode = MODUS_ERROR; break;
13492 else if(args.special < 130) /* auto libopen files */
13494 if(args.mode > 0 && args.mode < 4) /* for 122 */
13495 callmode = args.mode - 1;
13497 switch(args.special)
13499 case 120: mode = MODUS_GENAUTO;
13500 sprintf(filename, "%s_autoopenlib.c", ShortBaseName);
13501 break;
13502 case 121: mode = MODUS_GENAUTO+(args.special-120);
13503 sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
13504 break;
13505 case 123: Flags2 |= FLAG2_SHORTPPCVBCCINLINE; /* no break */
13506 case 122: mode = MODUS_VBCCMORPHINLINE;
13507 PPCRegPrefix = ""; /* no "r" allowed */
13508 sprintf(filename, "%s_protos.h", ShortBaseName);
13509 break;
13510 default: mode = MODUS_ERROR; break;
13513 else if(args.special < 140) /* the MorphOS area is up to 139 */
13515 if(args.mode > 0 && args.mode < 4)
13516 callmode = args.mode - 1;
13518 switch(args.special)
13520 case 130: case 131: case 132: mode = MODUS_INLINE+args.special-130;
13521 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13522 break;
13523 case 133: mode = MODUS_INLINE+2;
13524 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13525 Flags2 |= FLAG2_DIRECTVARARGS;
13526 break;
13527 case 134: mode = MODUS_GATESTUBS;
13528 sprintf(filename, "%s_gates.h", ShortBaseName);
13529 break;
13530 case 135: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB;
13531 sprintf(filename, "%s_gates.h", ShortBaseName);
13532 break;
13533 case 136: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB;
13534 sprintf(filename, "%s_gates.h", ShortBaseName);
13535 break;
13536 case 137: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB|FLAG2_REGLIB;
13537 sprintf(filename, "%s_gates.h", ShortBaseName);
13538 break;
13539 case 138: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB|FLAG2_REGLIB;
13540 sprintf(filename, "%s_gates.h", ShortBaseName);
13541 break;
13542 default: mode = MODUS_ERROR; break;
13545 else if(args.special < 150) /* the OS4 area is up to 139 */
13547 if(args.mode > 0 && args.mode < 4)
13548 callmode = args.mode - 1;
13550 switch(args.special)
13552 case 140:
13553 mode = MODUS_XML;
13554 sprintf(filename, "%s.xml", ShortBaseName);
13555 break;
13556 case 141: /* OS4 PPC->M68K cross-call stubs */
13557 mode = MODUS_OS4_PPCSTUBS;
13558 sprintf(filename, "%s.c", ShortBaseName);
13559 break;
13560 case 142: /* OS4 M68K->PPC cross-call stubs */
13561 mode = MODUS_OS4_68KSTUBS;
13562 sprintf(filename, "%s_68k.s", ShortBaseName);
13563 break;
13564 default: mode = MODUS_ERROR; break;
13567 if(Flags & FLAG_SORTED)
13568 SortFDList();
13570 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SINGLEFILE)) /* is not possible to use both */
13572 DoError(ERR_COMMENT_SINGLEFILE, 0);
13573 Flags &= (~FLAG_DOCOMMENT);
13576 if(!mode || mode == MODUS_ERROR)
13577 printhelp();
13579 /* These modes need BaseName always. */
13580 if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
13581 mode == MODUS_STUBCODE || mode == MODUS_EMODULE || (mode >= MODUS_GENAUTO &&
13582 mode <= MODUS_GENAUTO+9)))
13584 DoError(ERR_MISSING_BASENAME, 0);
13585 exit(20);
13588 if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
13590 HEADER = mygetfile(args.header, &headersize);
13591 args.header = 0;
13594 if(!(Flags & FLAG_SINGLEFILE))
13596 if(!OpenDest(filename))
13597 exit(20);
13600 /* from here mode is used as return result */
13601 if(mode >= MODUS_GENAUTO)
13602 mode = CreateGenAuto(filename, mode-MODUS_GENAUTO);
13603 else if(mode >= MODUS_LVOPPC)
13604 mode = CreateLVOFilePPC(mode-MODUS_LVOPPC);
13605 else if(mode >= MODUS_VBCC)
13606 mode = CreateVBCC(mode-MODUS_VBCC, callmode);
13607 else if(mode >= MODUS_INLINE)
13608 mode = CreateInline(mode-MODUS_INLINE, callmode);
13609 else if(mode >= MODUS_PROTO)
13610 mode = CreateProtoFile(mode-MODUS_PROTO+1);
13611 else if(mode >= MODUS_LVO)
13612 mode = CreateLVOFile(mode-MODUS_LVO+1);
13613 else if(mode == MODUS_VBCCMORPHINLINE)
13614 mode = CreateVBCCInline(2, callmode);
13615 else if(mode == MODUS_XML)
13616 mode = CreateXML();
13617 else if(mode == MODUS_OS4_PPCSTUBS)
13618 mode = CreateOS4PPC(callmode);
13619 else if(mode == MODUS_OS4_68KSTUBS)
13620 mode = CreateOS4M68K();
13621 else if(mode == MODUS_GATESTUBS)
13622 mode = CreateGateStubs(callmode);
13623 else if(mode == MODUS_SFD)
13624 mode = CreateSFD(callmode);
13625 else if(mode == MODUS_CLIB)
13626 mode = CreateClib(callmode);
13627 else if(mode == MODUS_FD)
13628 mode = CreateFD();
13629 else if(mode == MODUS_LVOLIBPPC)
13630 mode = CreateLVOLibPPC();
13631 else if(mode == MODUS_VBCCMORPHCODE)
13632 mode = CreateVBCCMorphCode(callmode);
13633 else if(mode == MODUS_VBCCMORPHTEXTSF) /* single files */
13634 mode = CallFunc(callmode, "\n%s", FuncVBCCMorphText);
13635 else if(mode == MODUS_VBCCWOSINLINE)
13636 mode = CreateVBCCInline(1, callmode);
13637 else if(mode == MODUS_VBCCWOSTEXTSF) /* single files */
13638 mode = CallFunc(callmode, "\n%s", FuncVBCCWOSText);
13639 else if(mode == MODUS_VBCCPUPTEXTSF) /* single files */
13640 mode = CallFunc(callmode, "\n%s", FuncVBCCPUPText);
13641 else if(mode == MODUS_ASMTEXTSF) /* single files */
13642 mode = CallFunc(callmode, "\n%s", FuncAsmText);
13643 else if(mode == MODUS_REDIRECT)
13644 mode = CreateProtoRedirect();
13645 else if(mode == MODUS_EMODULE)
13646 mode = CreateEModule(Flags & FLAG_SORTED);
13647 else if(mode == MODUS_LVOLIB)
13648 mode = CreateLVOLib();
13649 else if(mode == MODUS_VBCCPUPLIB)
13650 mode = CreateVBCCPUPLib(callmode);
13651 else if(mode == MODUS_VBCCINLINE)
13652 mode = CreateVBCCInline(0, callmode);
13653 else if(mode == MODUS_PASCAL)
13654 mode = CreateFPCUnit();
13655 else if(mode == MODUS_BMAP)
13656 mode = CreateBMAP();
13657 else if(mode == MODUS_PROTOPOWER)
13658 mode = CreateProtoPowerUP();
13659 else if(mode == MODUS_SASPOWER)
13660 mode = CreateSASPowerUP(callmode);
13661 else if(mode == MODUS_CSTUB)
13662 mode = CreateCSTUBSFile();
13663 else if(mode == MODUS_PRAGMA)
13664 mode = CreatePragmaFile(amicall, libcall, amitags, libtags, pragmode);
13665 else if(mode == MODUS_LOCALDATA)
13666 mode = CreateLocalData(filename, callmode);
13667 else if(mode) /* MODUS_STUBTEXT starts with 1 */
13668 mode = CreateAsmStubs(mode, callmode);
13670 CloseDest(filename);
13672 if(!mode)
13674 DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
13675 exit(20);
13677 free(tempbuf);
13680 return 0;