Indentation fix, cleanup.
[AROS.git] / tools / fd2pragma / fd2pragma.c
blob09c98266cf9404fff0e854b1ac7059142438b5be
1 /* $Id$ */
2 static const char version[] =
3 "$VER: fd2pragma 2.195 (24.05.2015) 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.
323 2.195 24.05.15 : (phx) Merge data-register pairs from the FD file for
324 64-bit data types when generating vbcc 68k assembler inlines.
327 /* A short note, how fd2pragma works.
328 Working mode for SPECIAL 200 is a bit different!
329 The main function parses arguments. Switches are converted into FLAG_XXX
330 values and stored in global "Flags" or "Flags2" variable. SPECIAL numbers
331 are parsed and are used to call a CreateXXX function, with its interface
332 depending on the need of arguments (Some have 2, some none, ...). Before
333 SPECIAL arguments are parsed, fd2pragma loads (S)FD file and scans it using
334 Scan(S)FDFile(). If SORTED is specified, the list gets sorted nearly directly
335 afterwards. IF CLIB argument is given, the clib file is scanned after FD file
336 and a clib list is created. Now SPECIAL is parsed and mode is set to any of
337 the MODUS_XXX values. Also the destination file name is created if not given.
338 The destination file is opened now.
340 The mode variable is used to determine the correct CreateXXX function,
341 which is called afterwards. This function produces file headers and stuff
342 like that and calls CallFunc to process each FD entry.
344 CallFunc gets 3 arguments. First the workmode (TAG, NORMAL, BOTH).
345 Second the comment method (for C it is "/%s *\x2F\n", for ASM it is "\n%s",
346 no comment is reached with 0 argument). The last is most important. It is the
347 function pointer to a function creating the entries. These functions have
348 always the same interface and are called through CallFunc only! They create
349 an entry for the specified function (e.g. FD entry). Parsing special
350 functions, adding comments, checking for tag-functions, ... is done by
351 CallFunc. It is no problem to call CallFunc multiple with different function
352 pointers (as is done for SPECIAL 6 pragmas).
353 This is also the method if information abount the type or number of functions
354 is needed somewhere in the begin of the output file. A special function to
355 collect this data needs to be started before doing real output. Althought I
356 do not like it much, global variables or flags can be used to store that
357 information.
359 The functions can use DoOutput to output texts in printf style or
360 DoOutputDirect to output all data in fwrite style. Buffering is done
361 automatically.
363 fd2pragma has its own memory managment. All memory must be allocated using
364 AllocListMem and is freed automatically. This is especially useful for
365 DupString function, which is used in FD, SFD and CLIB scanner.
367 Normally this source-file is to big and should be splitted into different
368 files compiled alone and linked together. :-) It takes about 20 minutes to
369 compile it on my Amiga system with optimizations turned on.
371 There are lots of different input and output types and some combinations
372 are really useless or wrong. fd2pragma has the mechanisms to catch these
373 cases properly, but not all cases are really checked, as there are too many
374 of them and each new input type increases the number of combinations.
375 Also not all useful combinations me be handled correctly. If you find a
376 case which really matters please inform me. All the others require the
377 users to use their brains :-)
380 #include <ctype.h>
381 #include <stdio.h>
382 #include <stdlib.h>
383 #include <string.h>
384 #include <stdarg.h>
385 #include <time.h>
387 /* These are the only allowed variable types of all related programs! */
388 #ifdef __amigaos4__
389 #include <exec/types.h>
390 #else
391 typedef signed char int8; /* signed 8 bit */
392 typedef unsigned char uint8; /* unsigned 8 bit */
393 typedef signed short int int16; /* signed 16 bit */
394 typedef unsigned short int uint16; /* unsigned 16 bit */
395 typedef signed long int int32; /* signed 32 bit */
396 typedef unsigned long int uint32; /* unsigned 32 bit */
397 #endif
398 typedef float fl32; /* 32 bit IEEE float value */
399 typedef double fl64; /* 64 bit IEEE double value */
400 typedef char string; /* the string datatype [e.g. one character of string!] */
401 typedef char * strptr; /* and an string pointer */
403 #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
404 (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
405 #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
406 #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
407 (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
408 #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
410 #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
411 #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
412 #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
413 #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
415 #define TEXT_SAS "__SASC" /* verified */
416 #define TEXT_SAS_60 "__SASC_60" /* verified */
417 #define TEXT_MAXON "__MAXON__" /* verified */
418 #define TEXT_STORM "__STORM__" /* verified */
419 #define TEXT_DICE "_DCC" /* in 2.0 code */
420 #define TEXT_AZTEC "AZTEC_C" /* verified */
421 #define TEXT_GNUC "__GNUC__" /* verified */
422 #define TEXT_VBCC "__VBCC__" /* verified */
424 #define TEMPSIZE 20480
426 #define FLAG_EXTERNC (1<< 0) /* add externc statements */
427 #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
428 #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
429 #define FLAG_PRIVATE (1<< 3) /* also use private functions */
430 #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
431 #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
432 #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
433 #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
434 #define FLAG_DONE (1<< 8) /* destination file is not empty */
435 #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
436 #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
437 #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
438 #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
439 #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
440 #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
441 #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
442 #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
443 #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
444 #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
445 #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
446 #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
447 #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
448 #define FLAG_STORMGCC (1<<22) /* special workaround for StormGCC */
449 #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
450 #define FLAG_MORPHOS (1<<24) /* create MorphOS files */
451 #define FLAG_SORTED (1<<25) /* sort the functions by name */
452 #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
453 #define FLAG_SINGLEFILE (1<<27) /* create single files */
454 #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
455 #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
456 #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
457 #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
459 #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
460 #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
461 #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
462 #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
463 #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
464 #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
465 #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
466 #define FLAG2_VOIDBASE (1<< 7) /* library base should be of type "void *" */
467 #define FLAG2_INLINEMAC (1<< 8) /* use inline macro instead of function */
468 #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
469 #define FLAG2_PRELIB (1<<10) /* MorphOS gate PRELIB flag */
470 #define FLAG2_POSTLIB (1<<11) /* MorphOS gate POSTLIB flag */
471 #define FLAG2_REGLIB (1<<12) /* MorphOS gate REGLIB flag */
472 #define FLAG2_OLDVBCC (1<<13) /* old VBCC style */
473 #define FLAG2_SMALLTYPES (1<<14) /* allow small data types */
474 #define FLAG2_AUTOHEADER (1<<15) /* creates auto generated header */
475 #define FLAG2_LIBNAMECOM (1<<16) /* libname was specified in SFD comment */
476 #define FLAG2_OS4M68KCSTUB (1<<17) /* OS4 M68K stub needs C */
477 #define FLAG2_SHORTPPCVBCCINLINE (1<<18) /* shorter PPC inline using argument */
479 #define FUNCFLAG_NORMAL (1<<0) /* normal function */
480 #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
481 #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
482 #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
484 /* Different modes the main program uses, one for each different file
485 type (except for those done with one function and flag settings). */
486 #define MODUS_STUBTEXT 1
487 #define MODUS_STUBCODE 2
488 #define MODUS_LOCALDATA 3
489 #define MODUS_PRAGMA 4
490 #define MODUS_CSTUB 5
491 #define MODUS_SASPOWER 6
492 #define MODUS_PROTOPOWER 7
493 #define MODUS_BMAP 8
494 #define MODUS_PASCAL 9
495 #define MODUS_VBCCINLINE 10
496 #define MODUS_VBCCPUPLIB 11
497 #define MODUS_LVOLIB 12
498 #define MODUS_EMODULE 13
499 #define MODUS_REDIRECT 14
500 #define MODUS_ASMTEXTSF 15
501 #define MODUS_VBCCPUPTEXTSF 16
502 #define MODUS_VBCCWOSTEXTSF 17
503 #define MODUS_VBCCWOSINLINE 18
504 #define MODUS_VBCCMORPHTEXTSF 19
505 #define MODUS_VBCCMORPHCODE 20
506 #define MODUS_LVOLIBPPC 21
507 #define MODUS_FD 22
508 #define MODUS_CLIB 23
509 #define MODUS_SFD 24
510 #define MODUS_GATESTUBS 25
511 #define MODUS_VBCCMORPHINLINE 26
512 #define MODUS_XML 27
513 #define MODUS_OS4_PPCSTUBS 28
514 #define MODUS_OS4_68KSTUBS 29
515 #define MODUS_LVO 50 /* and 51 and 52 and 53 */
516 #define MODUS_PROTO 60 /* and 61 to 69 */
517 /* new protos start with 90, but are added to MODUS_PROTO ! */
518 #define MODUS_INLINE 80 /* and 81 to 86 */
519 #define MODUS_VBCC 90 /* and 91 to 94 */
520 #define MODUS_LVOPPC 100 /* and 101 */
521 #define MODUS_GENAUTO 110 /* and 111 to 113 */
522 #define MODUS_ERROR 200
524 enum ABI {ABI_M68K, ABI_PPC, ABI_PPC2, ABI_PPC0};
526 /* call types for CallFunc */
527 #define TAGMODE_NORMAL 0 /* produce normal functions only */
528 #define TAGMODE_TAGS 1 /* produce only tag functions */
529 #define TAGMODE_BOTH 2 /* produce both types */
531 /* types specifying name method for pragma creation */
532 #define PRAGMODE_PRAGLIB 1
533 #define PRAGMODE_PRAGSLIB 2
534 #define PRAGMODE_PRAGSPRAGS 3
535 #define PRAGMODE_NONE 4
537 #define BIAS_START 30 /* the library start offset */
538 #define BIAS_OFFSET 6 /* value to switch from one to next function */
540 #ifndef FD2PRAGMA_AMIGA
541 #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
542 #endif
543 #ifndef EXTTYPESFILE
544 #define EXTTYPESFILE "fd2pragma.types"
545 #endif
546 #ifndef EXTTYPESFILE2
547 #ifdef FD2PRAGMA_AMIGA
548 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
549 #else
550 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
551 #endif
552 #endif
554 #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
556 #define FDFILEEXTENSION "_lib.fd"
557 #define SFDFILEEXTENSION "_lib.sfd"
559 static const strptr libstring = "Library";
561 static const strptr RegNames[] = {
562 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
563 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
564 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
565 "d0/d1", "d2/d3", "d4/d5", "d6/d7",
568 static const strptr RegNamesUpper[] = {
569 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
570 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
571 "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
572 "D0/D1", "D2/D3", "D4/D5", "D6/D7",
575 enum Register_ID {
576 REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
577 REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7,
578 REG_FP0, REG_FP1, REG_FP2, REG_FP3, REG_FP4, REG_FP5, REG_FP6, REG_FP7,
579 REG_D0D1, REG_D2D3, REG_D4D5, REG_D6D7
581 #define MAXREGPPC 26
582 #define MAXREG 24 /* maximum registers of 68K */
583 #define MAXREGNF 16 /* maximum register number without float regs */
584 #define UNDEFREGISTER 255 /* for type scanner */
586 struct Args {
587 strptr infile;
588 strptr to;
589 strptr clib;
590 strptr header;
591 int32 special;
592 int32 mode;
595 struct ShortList {
596 struct ShortList *Next;
599 struct ShortListRoot {
600 struct ShortList *First;
601 struct ShortList *Last;
602 size_t Size;
605 #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
606 #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
607 #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
608 #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
609 #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
610 #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
611 #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
612 #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
613 #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
614 #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
615 #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
616 #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
617 #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
618 #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
619 #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
620 #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
621 #define AMIPRAGFLAG_MOSSYSV (1<<16) /* MorphOS(sysv) type */
622 #define AMIPRAGFLAG_MOSSYSVR12 (1<<17) /* MorphOS(sysv,r12base) type */
623 #define AMIPRAGFLAG_MOSBASESYSV (1<<18) /* MorphOS(base,sysv) type */
624 #define AMIPRAGFLAG_VARARGS (1<<19) /* last argument is ... */
626 #define AMIPRAGFLAG_MOS_ALL (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12|AMIPRAGFLAG_MOSBASESYSV)
628 struct AmiArgs {
629 strptr ArgName;
630 uint16 ArgReg;
633 #define NUMALIASNAMES 5
635 struct AmiPragma {
636 struct ShortList List;
637 uint32 Line;
638 uint32 Flags;
639 strptr FuncName;
640 strptr TagName;
641 struct Pragma_AliasName * AliasName[NUMALIASNAMES]; /* alias names */
642 uint16 NumArgs; /* register numbers */
643 uint16 CallArgs; /* argument number in fd file */
644 int16 Bias;
645 int8 NumAlias;
646 enum ABI Abi;
647 struct AmiArgs Args[MAXREGPPC];
650 struct Comment {
651 struct ShortList List;
652 strptr Data;
653 int16 Bias;
654 uint16 ReservedNum;
655 uint16 Version;
656 uint8 Private; /* is a flag only */
659 struct Include {
660 struct ShortList List;
661 strptr Include;
664 struct PragList {
665 struct ShortList List;
666 struct ShortListRoot Data; /* contains list of PragData */
667 strptr Basename;
670 struct PragData {
671 struct ShortList List;
672 struct ShortListRoot Name;
673 uint32 NumNames;
674 uint32 Bias;
675 uint32 NumArgs;
676 uint8 ArgReg[MAXREG];
679 struct FDData {
680 strptr Name;
681 strptr Basename;
682 uint32 Bias;
683 uint32 Mode; /* 0 = Normal, != 0 is TagName */
684 uint32 NumArgs;
685 uint8 ArgReg[MAXREG];
688 /* NOTE: string creation for CPP-Functions probably does not work at all
689 at the moment, as every compiler uses different systems which seem to
690 change constantly. */
692 /* These CPP types match the strings used for CPP name creation. The
693 defines are used both for name creation and type specification. */
694 #define CPP_TYPE_VOID 'v' /* void, VOID */
695 #define CPP_TYPE_BYTE 'c' /* char, int8 */
696 #define CPP_TYPE_WORD 's' /* short, int16 */
697 #define CPP_TYPE_LONG 'j' /* long, int32 */
698 #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
699 #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
700 #define CPP_TYPE_INT 'i' /* int */
701 #define CPP_TYPE_STRUCTURE 0
702 #define CPP_TYPE_VARARGS 'e'
703 #define CPP_TYPE_LONGLONG 'l' /* long long, int64 */
705 /* These types are for string creation only. */
706 #define CPP_TYPE_ENUM 'E'
707 #define CPP_TYPE_CONST 'C'
708 #define CPP_TYPE_FUNCTION 'F'
709 #define CPP_TYPE_POINTER 'P'
710 #define CPP_TYPE_UNSIGNED 'U'
711 #define CPP_TYPE_FUNCEND 'p'
712 #define CPP_TYPE_REGISTER 'r'
714 /* Some flags to be used in CPP_NameType->Flags. */
715 #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
716 #define CPP_FLAG_CONST (1<<1) /* type is const */
717 #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
718 #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
719 #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
720 #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
721 #define CPP_FLAG_UNION (1<<6) /* it is a union */
722 #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
723 #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
724 #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
725 #define CPP_FLAG_TYPEDEFNAME (1<<10) /* name is created from typedef */
726 #define CPP_FLAG_ARRAY (1<<11) /* this type is an array */
727 #define CPP_FLAG_LONG (1<<12) /* type is long */
728 /* STRPTR is defined different under C and CPP -> I have to create two
729 names, one time unsigned char *, one time signed char *, when somewhere
730 a STRPTR occurs */
732 #define COPYCPP_PASSES 4
734 struct CPP_NameType { /* structure to describe a argument type */
735 strptr StructureName; /* if a structure or enum only */
736 strptr FuncArgs; /* arguments of function - unterminated */
737 strptr TypeStart; /* start of this type */
738 strptr Replace; /* replacement of type for SFD files */
739 strptr Unknown; /* unknown type handled as int */
740 strptr FunctionName; /* Argument name of function argument */
741 struct ClibData *FuncPtr; /* if it is a function pointer */
742 uint16 StructureLength; /* length of the structure name */
743 uint16 ArgsLength; /* length of FuncArgs */
744 uint16 TypeLength; /* length of this type */
745 uint16 FullLength; /* length of complete type */
746 uint16 PointerDepth; /* number of * in type */
747 uint16 FuncPointerDepth; /* number of * in function pointer */
748 uint16 Flags; /* see above flags */
749 uint8 Type; /* see above defines */
750 uint8 Register; /* register number */
753 struct ClibData { /* structure to describe data in CLIB file */
754 struct ClibData * Next; /* The next entry in this list */
755 strptr FuncName; /* name of the function */
756 struct CPP_NameType ReturnType; /* data for return type */
757 struct CPP_NameType Args[MAXREGPPC+1]; /* data for argument types */
758 uint16 NumArgs; /* number of arguments */
761 struct CPP_ExternNames { /* structure for EXTTYPESFILE data */
762 struct CPP_ExternNames * Next; /* The next entry in this list */
763 strptr Type; /* The unknown type */
764 struct CPP_NameType NameType; /* The replacement */
767 struct CPP_TypeField { /* structure for internal defined types */
768 strptr Text; /* name of the type */
769 uint16 Length; /* length of the name string */
770 uint16 Flags; /* CPP_FLAG flags */
771 uint8 Type; /* CPP_TYPE value */
774 struct CPP_Unknown {
775 struct CPP_Unknown *Next;
776 strptr Unknown;
779 struct Proto_LibType { /* structure to define structure type of base vars */
780 strptr BaseName; /* name of the library base */
781 strptr StructureName; /* name of the structure to be used (0 for default) */
782 strptr LibraryName; /* name of the library (maybe 0 for default method) */
783 strptr ShortBaseName; /* short name of the library base */
786 struct Pragma_ExecpName { /* structure to specify special tagnames */
787 strptr FunctionName; /* function name */
788 strptr TagName; /* tag name to be used for this function */
789 }; /* TagName 0 is valid as well to disable tagfunctions */
791 struct Pragma_AliasName {
792 strptr FunctionName;
793 strptr AliasName;
794 uint32 Type;
797 #define NTP_NORMAL 0 /* no tags/args */
798 #define NTP_TAGS 1 /* TagFunction */
799 #define NTP_ARGS 2 /* ArgFunction */
800 #define NTP_UNKNOWN 3 /* CommentFunction */
802 struct NameList {
803 struct ShortList List;
804 uint32 Type; /* set by OptimizeFDData */
805 strptr NormName;
806 strptr PragName;
809 struct InFile {
810 strptr pos;
811 strptr buf;
812 size_t size;
815 /* EHF definitions! */
816 #define HUNK_PPC_CODE 0x4E9
817 #define HUNK_RELRELOC26 0x4EC
818 #define EXT_RELREF26 229
820 /* ------------------------------------------------------------------ */
821 /* A short set of ELF definitions, see pasm sources in vbcc release for an
822 more complete set of stuff or get elf documentation. These are needed for
823 VBCCPUPCode function. */
824 #define ELFCLASS32 1
825 #define ELFDATA2MSB 2
826 #define EV_CURRENT 1 /* version information */
827 #define ET_REL 1 /* type information */
828 #define EM_POWERPC 20
830 #define SHT_NULL 0 /* inactive */
831 #define SHT_PROGBITS 1 /* program information */
832 #define SHT_SYMTAB 2 /* symbol table */
833 #define SHT_STRTAB 3 /* string table */
834 #define SHT_RELA 4 /* relocation */
836 #define SHF_ALLOC 0x2 /* needs memory when started */
837 #define SHF_EXECINSTR 0x4 /* executable instructions */
839 #define SHN_ABS 0xFFF1
841 #define EI_NIDENT 16
842 #define EI_MAG0 0
843 #define EI_MAG1 1
844 #define EI_MAG2 2
845 #define EI_MAG3 3
846 #define EI_CLASS 4
847 #define EI_DATA 5
848 #define EI_VERSION 6
850 #define STB_LOCAL 0
851 #define STB_GLOBAL 1
852 #define STT_FUNC 2
853 #define STT_NOTYPE 0
854 #define STT_SECTION 3
855 #define STT_FILE 4
856 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
857 #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
859 #define R_PPC_ADDR16_LO 4
860 #define R_PPC_ADDR16_HA 6
861 #define R_PPC_REL24 10
862 #define R_PPC_SDAREL16 32
864 struct ArHeader {
865 string ar_name[16]; /* name */
866 string ar_time[12]; /* modification time */
867 string ar_uid[6]; /* user id */
868 string ar_gid[6]; /* group id */
869 string ar_mode[8]; /* octal file permissions */
870 string ar_size[10]; /* size in bytes */
871 string ar_fmag[2]; /* consistency check */
874 /* AmigaOS hunk structure definitions */
875 #ifdef __amigaos4__
876 #include <dos/doshunks.h>
877 #else
878 #define HUNK_UNIT 999
879 #define HUNK_NAME 1000
880 #define HUNK_CODE 1001
881 #define HUNK_BSS 1003
882 #define HUNK_ABSRELOC32 1004
883 #define HUNK_EXT 1007
884 #define HUNK_SYMBOL 1008
885 #define HUNK_END 1010
886 #define HUNK_DREL16 1016
888 #define EXT_DEF 1 /* normal definition */
889 #define EXT_ABS 2 /* Absolute definition */
890 #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
891 #define EXT_DEXT16 134 /* 16 bit data relative reference */
892 #endif
893 /* ------------------------------------------------------------------ */
895 static struct Args args = {0,0,0,0,6,0};
896 static struct InFile in = {0,0,0};
897 static FILE * outfile;
898 static struct ClibData * clibdata = 0;
899 static struct ShortListRoot AmiPragma = {0,0,sizeof(struct AmiPragma)},
900 Comment = {0,0,sizeof(struct Comment)},
901 Includes = {0,0,sizeof(struct Include)};
902 static struct CPP_ExternNames *extnames = 0;
903 static struct CPP_Unknown *unknown = 0;
904 static strptr BaseName = 0; /* the correct basename */
905 /* the filename part of basename without Base */
906 static strptr ShortBaseName = 0;
907 /* like ShortBaseName, but upper case */
908 static strptr ShortBaseNameUpper = 0;
909 static strptr HEADER = 0;
910 static strptr Copyright = 0;
911 static strptr filenamefmt = 0;
912 static strptr libtype = 0;
913 static strptr libname = 0;
914 static strptr defabi = 0;
915 static strptr hunkname = ".text";
916 static strptr datahunkname = "__MERGED";
917 static strptr PPCRegPrefix = "r";
918 static strptr IDstring = 0;
919 static strptr prefix = "";
920 static strptr subprefix = "";
921 static strptr premacro = "";
922 static uint8 * tempbuf = 0;
923 static size_t headersize = 0;
924 static uint32 Flags = 0;
925 static uint32 Flags2 = 0;
926 /* Output error occured when 0 */
927 static uint32 Output_Error = 1;
928 /* are there some tagfuncs in FD */
929 static uint32 tagfuncs = 0;
930 /* priority for auto libopen */
931 static uint32 priority = 5;
932 /* needed for filename */
933 static string filename[255];
935 /* Only for E-Stuff, FD, SFD, XML creation */
936 static int32 LastBias = 0;
937 /* Only for PPC-LVO Lib's */
938 static uint8 * elfbufpos = 0;
939 /* Only for PPC-LVO Lib's */
940 static uint32 symoffset = 0;
941 /* Only for FD, SFD creation */
942 static enum ABI CurrentABI = ABI_M68K;
944 /* Prototypes for the functions */
945 static strptr DupString(strptr, size_t);
946 static strptr AllocListMem(size_t);
947 static strptr SkipBlanks(strptr);
948 static strptr SkipBlanksRet(strptr);
949 static strptr SkipName(strptr);
950 static uint32 GetTypes(void);
951 static strptr GetBaseType(void);
952 static strptr GetBaseTypeLib(void);
953 static strptr GetLibraryName(void);
954 static strptr GetIFXName(void);
955 static int32 MakeShortBaseName(void);
956 static uint32 OpenDest(strptr);
957 static uint32 CloseDest(strptr);
958 static uint32 MakeTagFunction(struct AmiPragma *);
959 static void MakeLines(strptr, uint32);
960 static uint32 SpecialFuncs(void);
961 static void SortFDList(void);
962 static void AddAliasName(struct AmiPragma *, struct Pragma_AliasName *,
963 uint32);
964 static uint32 CheckNames(struct AmiPragma *);
965 static uint32 ScanSFDFile(enum ABI);
966 static uint32 ScanFDFile(void);
967 static int32 ScanTypes(strptr, uint32);
968 static void FindHeader(void);
969 static uint32 GetRegisterData(struct AmiPragma *);
970 static uint16 GetFRegisterData(struct AmiPragma *);
971 static uint32 OutputXDEF(uint32, strptr, ...);
972 static uint32 OutputXREF(uint32, uint32, strptr, ...);
973 static uint32 OutputXREF2(uint32, uint32, uint32, strptr, ...);
974 static uint32 OutputSYMBOL(uint32, strptr, ...);
975 static uint8 * AsmStackCopy(uint8 *, struct AmiPragma *, uint32, uint32);
976 /* ------------------------------------------------------------------ */
977 static void DoError(uint32, uint32, ...);
978 static uint32 CheckError(struct AmiPragma *, uint32);
979 static uint32 DoOutputDirect(void *, size_t);
981 #if defined(__GNUC__)
982 static uint32 DoOutput(strptr, ...) __attribute__ ((format(printf, 1, 2)));
983 #else
984 static uint32 DoOutput(strptr, ...);
985 #endif
986 /* ------------------------------------------------------------------ */
987 static struct ShortList *NewItem(struct ShortListRoot *);
988 static struct ShortList *RemoveItem(struct ShortListRoot *, struct ShortList *);
989 static void AddItem(struct ShortListRoot *, struct ShortList *);
990 /* ------------------------------------------------------------------ */
991 typedef uint32 (*FuncType)(struct AmiPragma *, uint32, strptr);
993 uint32 FuncAMICALL (struct AmiPragma *, uint32, strptr);
994 uint32 FuncLIBCALL (struct AmiPragma *, uint32, strptr);
995 uint32 FuncAsmText (struct AmiPragma *, uint32, strptr);
996 uint32 FuncAsmCode (struct AmiPragma *, uint32, strptr);
997 uint32 FuncCSTUBS (struct AmiPragma *, uint32, strptr);
998 uint32 FuncLVOXDEF (struct AmiPragma *, uint32, strptr);
999 uint32 FuncLVO (struct AmiPragma *, uint32, strptr);
1000 uint32 FuncLVOPPCXDEF (struct AmiPragma *, uint32, strptr);
1001 uint32 FuncLVOPPC (struct AmiPragma *, uint32, strptr);
1002 uint32 FuncLVOPPCBias (struct AmiPragma *, uint32, strptr);
1003 uint32 FuncLVOPPCName (struct AmiPragma *, uint32, strptr);
1004 uint32 FuncLVOLib (struct AmiPragma *, uint32, strptr);
1005 uint32 FuncLocCode (struct AmiPragma *, uint32, strptr);
1006 uint32 FuncLocText (struct AmiPragma *, uint32, strptr);
1007 uint32 FuncInline (struct AmiPragma *, uint32, strptr);
1008 uint32 FuncInlineDirect (struct AmiPragma *, uint32, strptr);
1009 uint32 FuncInlineNS (struct AmiPragma *, uint32, strptr);
1010 uint32 FuncPowerUP (struct AmiPragma *, uint32, strptr);
1011 uint32 FuncFPCUnit (struct AmiPragma *, uint32, strptr);
1012 uint32 FuncFPCType (struct AmiPragma *, uint32, strptr);
1013 uint32 FuncFPCTypeTags (struct AmiPragma *, uint32, strptr);
1014 uint32 FuncFPCTypeTagsUnit (struct AmiPragma *, uint32, strptr);
1015 uint32 FuncBMAP (struct AmiPragma *, uint32, strptr);
1016 uint32 FuncVBCCInline (struct AmiPragma *, uint32, strptr);
1017 uint32 FuncVBCCWOSInline (struct AmiPragma *, uint32, strptr);
1018 uint32 FuncVBCCMorphInline (struct AmiPragma *, uint32, strptr);
1019 uint32 FuncVBCCWOSText (struct AmiPragma *, uint32, strptr);
1020 uint32 FuncVBCCWOSCode (struct AmiPragma *, uint32, strptr);
1021 uint32 FuncVBCCPUPText (struct AmiPragma *, uint32, strptr);
1022 uint32 FuncVBCCPUPCode (struct AmiPragma *, uint32, strptr);
1023 uint32 FuncEModule (struct AmiPragma *, uint32, strptr);
1024 uint32 FuncVBCCMorphText (struct AmiPragma *, uint32, strptr);
1025 uint32 FuncVBCCMorphCode (struct AmiPragma *, uint32, strptr);
1026 uint32 FuncFD (struct AmiPragma *, uint32, strptr);
1027 uint32 FuncClib (struct AmiPragma *, uint32, strptr);
1028 uint32 FuncSFD (struct AmiPragma *, uint32, strptr);
1029 uint32 FuncXML (struct AmiPragma *, uint32, strptr);
1030 uint32 FuncOS4PPC (struct AmiPragma *, uint32, strptr);
1031 uint32 FuncOS4M68KCSTUB (struct AmiPragma *, uint32, strptr);
1032 uint32 FuncOS4M68K (struct AmiPragma *, uint32, strptr);
1033 uint32 FuncOS4M68KVect (struct AmiPragma *, uint32, strptr);
1034 uint32 FuncGateStubs (struct AmiPragma *, uint32, strptr);
1035 static uint32 PrintComment (struct Comment *, strptr);
1036 static uint32 DoCallFunc (struct AmiPragma *, uint32, strptr, FuncType);
1037 static uint32 CallFunc (uint32, strptr, FuncType);
1038 static uint32 PrintIncludes(void);
1039 /* ------------------------------------------------------------------ */
1040 static int32 AddClibEntry(strptr, strptr, uint32);
1041 static int32 ScanClibFile(strptr, strptr);
1042 static int32 IsCPPType(struct CPP_NameType *, uint8);
1043 static uint32 CheckRegisterNum(strptr, struct CPP_NameType *);
1044 static uint32 ParseFuncPtrArgs(strptr, struct CPP_NameType *);
1045 static int32 GetCPPType(struct CPP_NameType *, strptr, uint32, uint32);
1046 static struct ClibData *GetClibFunc(strptr, struct AmiPragma *, uint32);
1047 static int32 CheckKeyword(strptr, strptr, int32);
1048 static uint32 CopyCPPType(strptr, uint32, struct ClibData *, struct AmiArgs *);
1049 static uint32 OutClibType(struct CPP_NameType *, strptr);
1050 static uint32 MakeClibType(strptr, struct CPP_NameType *, strptr);
1051 static uint32 OutPASCALType(struct CPP_NameType *, strptr, uint32);
1052 /* ------------------------------------------------------------------ */
1053 static uint32 CallPrag(uint32, strptr, FuncType);
1054 static uint32 CreatePragmaFile(strptr, strptr, strptr, strptr, uint32);
1055 static uint32 CreateCSTUBSFile(void);
1056 static uint32 CreateLVOFile(uint32);
1057 static uint32 CreateLVOFilePPC(uint32);
1058 static uint32 CreateAsmStubs(uint32, uint32);
1059 static uint32 CreateProtoFile(uint32);
1060 static uint32 CreateLocalData(strptr, uint32);
1061 static uint32 CreateInline(uint32, uint32);
1062 static uint32 CreateGateStubs(uint32);
1063 static uint32 CreateSASPowerUP(uint32);
1064 static uint32 CreateProtoPowerUP(void);
1065 static uint32 CreateFPCUnit(void);
1066 static uint32 CreateBMAP(void);
1067 static uint32 CreateLVOLib(void);
1068 static uint32 CreateLVOLibPPC(void);
1069 static uint32 CreateVBCCInline(uint32, uint32);
1070 static uint32 CreateVBCC(uint32, uint32);
1071 static uint32 CreateVBCCPUPLib(uint32);
1072 static uint32 CreateVBCCMorphCode(uint32);
1073 static uint32 CreateEModule(uint32);
1074 static uint32 CreateProtoRedirect(void);
1075 static uint32 CreateFD(void);
1076 static uint32 CreateSFD(uint32);
1077 static uint32 CreateClib(uint32);
1078 static uint32 CreateGenAuto(strptr, uint32);
1079 static uint32 CreateXML(void);
1080 static uint32 CreateOS4PPC(uint32);
1081 static uint32 CreateOS4M68K(void);
1082 /* ------------------------------------------------------------------ */
1083 static uint32 GetName(struct NameList *, struct ShortListRoot *, uint32);
1084 static uint32 MakeFD(struct PragList *);
1085 static void OptimizeFDData(struct PragData *);
1086 static string GetHexValue(string);
1087 static string GetDoubleHexValue(strptr);
1088 static uint32 AddFDData(struct ShortListRoot *, struct FDData *);
1089 static uint32 GetLibData(struct FDData *);
1090 static uint32 GetFlibData(struct FDData *);
1091 static uint32 GetAmiData(struct FDData *);
1092 static uint32 CreateFDFile(void);
1093 /* ------------------------------------------------------------------ */
1094 static void GetArgs(int argc, char **argv);
1095 static strptr mygetfile(strptr name, size_t *len);
1097 #define ERROFFSET_CLIB (1<<31)
1099 enum {
1100 ERR_TAGFUNC_NEEDS_ARGUMENT,
1101 ERR_CANNOT_CONVERT_PRAGMA_TAGCALL,
1102 ERR_TAG_DEF_WITHOUT_PRAGMA,
1103 ERR_BASENAME_DECLARED_TWICE,
1104 ERR_EXPECTED_SLASH_IN_BASENAME,
1105 ERR_EXPECTED_BASENAME,
1106 ERR_EXPECTED_BIAS_VALUE,
1107 ERR_ASSUMING_POSITIVE_BIAS_VALUE,
1108 ERR_MISSING_FUNCTION_NAME,
1109 ERR_EXPECTED_OPEN_BRACKET,
1110 ERR_TO_MUCH_ARGUMENTS,
1111 ERR_EXPECTED_ARGUMENT_NAME,
1112 ERR_EXPECTED_CLOSE_BRACKET,
1113 ERR_EXPECTED_REGISTER_NAME,
1114 ERR_A7_NOT_ALLOWED,
1115 ERR_REGISTER_USED_TWICE,
1116 ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER,
1117 ERR_ASSUMING_BIAS_OF_30,
1118 ERR_EXTRA_CHARACTERS,
1119 ERR_MISSING_BASENAME,
1120 ERR_WRITING_FILE,
1121 ERR_EXPECTED_COMMA,
1122 ERR_DIFFERENT_TO_PREVIOUS,
1123 ERR_UNKNOWN_VARIABLE_TYPE,
1124 ERR_UNKNOWN_ERROR,
1125 ERR_MISSING_END,
1126 ERR_PROTOTYPE_MISSING,
1127 ERR_NOPROTOTYPES_FILE,
1128 ERR_UNKNOWN_DIRECTIVE,
1129 ERR_INLINE_A4_AND_A5,
1130 ERR_INLINE_D7_AND_A45,
1131 ERR_MISSING_SHORTBASENAME,
1132 ERR_A6_NOT_ALLOWED,
1133 ERR_EMPTY_FILE,
1134 ERR_FLOATARG_NOT_ALLOWED,
1135 ERR_WRONG_TYPES_LINE,
1136 ERR_LONG_DOUBLE,
1137 ERR_CLIB_ARG_COUNT,
1138 ERR_OPEN_FILE,
1139 ERR_A5_NOT_ALLOWED,
1140 ERR_PPC_FUNCTION_NOT_SUPPORTED,
1141 ERR_UNKNOWN_ABI,
1142 ERR_NO_SORTED,
1143 ERR_ILLEGAL_FUNCTION_POSITION,
1144 ERR_SORTED_COMMENT,
1145 ERR_COMMENT_SINGLEFILE,
1146 ERR_NOFD2PRAGMATYPES,
1147 ERR_M68K_FUNCTION_NOT_SUPPORTED,
1148 ERR_UNKNOWN_RETURNVALUE_TYPE,
1149 ERR_SFD_AND_CLIB,
1150 ERR_EXCPECTED_IDSTRING,
1151 ERR_EXPECTED_ID_ENDSIGN,
1152 ERR_MISSING_SFDEND,
1153 ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER,
1154 ERR_IDSTRING_DECLARED_TWICE,
1155 ERR_COMMANDLINE_LIBTYPE,
1156 ERR_COMMANDLINE_BASENAME,
1157 ERR_LIBTYPE_DECLARED_TWICE,
1158 ERR_EXPECTED_LIBTYPE,
1159 ERR_SORTED_SFD_FD,
1160 ERR_EARLY_SHADOW,
1161 ERR_DOUBLE_VARARGS,
1162 ERR_VARARGS_ARGUMENTS_DIFFER,
1163 ERR_UNEXPECTED_FILEEND,
1164 ERR_VARARGS_ALIAS_FIRST,
1165 ERR_ALIASNAMES,
1166 ERR_EXPECTED_STRUCT,
1167 ERR_EXPECTED_POINTERSIGN,
1168 ERR_ARGNAME_KEYWORD_CONFLICT,
1169 ERR_ARGNAME_ARGNAME_CONFLICT,
1170 ERR_ONLYTAGMODE_NOTALLOWED,
1171 ERR_COMMANDLINE_LIBNAME,
1172 ERR_LIBNAME_DECLARED_TWICE,
1173 ERR_EXPECTED_LIBNAME,
1174 ERR_PREFIX,
1175 ERR_MULTIPLEFUNCTION,
1176 ERR_INLINE_AX_SWAPREG,
1177 ERR_SFD_START,
1178 ERR_ILLEGAL_CHARACTER_DETECTED,
1179 ERR_UNKNOWN_VARIABLE_TYPE_INT,
1180 ERR_UNKNOWN_RETURNVALUE_TYPE_INT,
1181 ERR_ILLEGAL_INTERNAL_VALUE,
1182 ERR_MOSBASESYSV_NOT_SUPPORTED,
1183 ERR_ALIASES_NOT_SUPPORTED,
1184 ERR_FUNCTION_NOT_SUPPORTED,
1187 static const struct ErrField {
1188 uint8 Type; /* 0 = Error, 1 = Warning */
1189 uint8 Skip;
1190 strptr Error;
1191 } Errors[] = {
1192 {1, 1, "Tag function must have arguments."},
1193 {1, 1, "Cannot convert pragma name into tag name."},
1194 {1, 1, "Tag definition without preceding Pragma."},
1195 {1, 0, "Basename declared twice."},
1196 {1, 0, "Expected preceding _ in Basename."},
1197 {1, 1, "Expected Basename."},
1198 {1, 0, "Expected Bias value."},
1199 {1, 0, "Assuming positive bias value."},
1200 {1, 1, "Missing function name."},
1201 {1, 1, "Expected '('."},
1202 {1, 1, "Too much arguments."},
1203 {1, 1, "Expected argument name."},
1204 {1, 1, "Expected ')'."},
1205 {1, 1, "Expected register name."},
1206 {1, 1, "A7 not allowed as argument register."},
1207 {1, 1, "Register used twice."},
1208 {1, 0, "Number of arguments != number of registers."},
1209 {1, 0, "Assuming bias of 30."},
1210 {1, 1, "Extra characters."},
1211 {0, 0, "Missing Basename in FD file."},
1212 {0, 0, "Failed to write destination file."},
1213 {1, 1, "Expected ','."},
1214 {0, 1, "Data different to previous given."},
1215 {1, 0, "Unknown type of argument %ld."},
1216 {0, 0, "Unknown problem: program error or corrupt input data."},
1217 {1, 0, "Missing ##end."},
1218 {1, 0, "Prototype for function \"%s\" not found."},
1219 {0, 0, "No prototypes file (CLIB parameter) was specified."},
1220 {1, 1, "Unknown directive '%s' found."},
1221 {1, 0, "Usage of both A4 and A5 is not supported."},
1222 {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
1223 {0, 0, "Missing Basename in FD file and FD filename."},
1224 {1, 0, "A6 not allowed as argument register."},
1225 {1, 0, "Empty or partial file deleted."},
1226 {1, 1, "Floating point arguments not allowed."},
1227 {0, 0, "Wrong definition in external type definition file."},
1228 {1, 0, "Cannot determine if FPU argument is double or single."},
1229 {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
1230 {0, 0, "Could not open file \"%s\"."},
1231 {1, 0, "A5 cannot be used as argument register."},
1232 {1, 0, "Format supports no PPC functions."},
1233 {1, 0, "Unknown ABI '%s' found."},
1234 {0, 0, "SORTED cannot be used with that type."},
1235 {1, 0, "Position of function %s not supported with that type."},
1236 {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
1237 {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
1238 {1, 0, "Missing the types definition file. Using internal defaults."},
1239 {1, 0, "Format supports no M68k functions."},
1240 {1, 0, "Unknown type of return value."},
1241 {1, 0, "With SFD as input CLIB file is ignored."},
1242 {1, 0, "Expected $Id: in ID string."},
1243 {1, 0, "Expected $ at end of ID string."},
1244 {1, 0, "Missing ==end."},
1245 {1, 1, "Expected positive decimal number."},
1246 {1, 0, "ID string declared twice."},
1247 {1, 1, "Library type of commandline overwrites file settings."},
1248 {1, 1, "Basename of commandline overwrites file settings."},
1249 {1, 0, "Library type declared twice."},
1250 {1, 1, "Expected library type definition."},
1251 {1, 1, "SORTED cannot be used with SFD and FD output."},
1252 {1, 0, "Function expected before ##shadow."},
1253 {1, 1, "There is already a varargs function, handling as alias."},
1254 {1, 0, "Varargs function cannot have different arguments."},
1255 {1, 0, "Unexpected end of file."},
1256 {1, 0, "Commands varargs and alias cannot be at file start."},
1257 {1, 0, "Only %d alias names supported."},
1258 {1, 1, "Expected struct keyword in library type."},
1259 {1, 0, "Expected '*' at end of library type definition."},
1260 {1, 1, "Name of argument %d conflicts with keyword '%s'."},
1261 {1, 1, "Name of argument %d conflicts with argument %d."},
1262 {1, 0, "SFD files cannot consist only of varargs functions."},
1263 {1, 1, "Library name of commandline overwrites file settings."},
1264 {1, 0, "Library name declared twice."},
1265 {1, 1, "Expected library name definition."},
1266 {1, 0, "Neither prefix nor subprefix specified."},
1267 {1, 0, "Format supports single function pointer only (void * used)."},
1268 {1, 0, "No swap register left for %s."},
1269 {1, 0, "SFD files should always start with ==id directive."},
1270 {1, 0, "Illegal character detected."},
1271 {1, 0, "Unknown type of argument %ld (%s) handled as int."},
1272 {1, 0, "Unknown type of return value (%s) handled as int."},
1273 {1, 0, "Illegal internal value."},
1274 {1, 0, "Format supports no MorphOS (base,sysv) functions."},
1275 {1, 0, "Format supports no alias names."},
1276 {1, 0, "Format cannot support function %s."},
1279 #ifdef __SASC
1280 __far
1281 #endif
1282 static uint8 InternalTypes[] = {
1283 "IX:struct InputXpression\n"
1284 "Msg:struct ? *\n"
1285 "Class:struct IClass\n"
1286 "BootBlock:struct bootblock\n"
1287 "ValidIDstruct:struct ValidIDstruct\n"
1288 "DisplayInfoHandle:void *\n"
1289 "RESOURCEFILE:void *\n"
1290 "RESOURCEID:unsigned long\n"
1291 "GLvoid:void\n"
1292 "GLbitfield:unsigned long\n"
1293 "GLbyte:signed char\n"
1294 "GLshort:short\n"
1295 "GLint:long\n"
1296 "GLsizei:unsigned long\n"
1297 "GLubyte:unsigned char\n"
1298 "GLushort:unsigned short\n"
1299 "GLuint:unsigned long\n"
1300 "GLfloat:float\n"
1301 "GLclampf:float\n"
1302 "GLdouble:double\n"
1303 "GLclampd:double\n"
1304 "GLboolean:enum ?\n"
1305 "GLenum:enum ?\n"
1306 "GLlookAt:struct GLlookAt\n"
1307 "GLproject:struct GLproject\n"
1308 "GLunProject:struct GLunProject\n"
1309 "GLfrustum:struct GLfrustum\n"
1310 "GLortho:struct GLortho\n"
1311 "GLbitmap:struct GLbitmap\n"
1312 "GLUquadricObj:struct GLUquadricObj\n"
1313 "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
1314 "GLUnurbsObj:struct GLUnurbsObj\n"
1315 "GLvisual:struct gl_visual\n"
1316 "GLframebuffer:struct gl_frame_buffer\n"
1317 "GLcontext:struct gl_context\n"
1318 "GLContext:struct !\n"
1319 "HGIDA_Stack:unsigned long *\n"
1320 "HGIDA_BoundedStack:unsigned long *\n"
1321 "HGIDA_Queue:unsigned long *\n"
1322 "HGIDA_BoundedQueue:unsigned long *\n"
1323 "HGIDA_List:unsigned long *\n"
1324 "HGIDA_ListItem:unsigned long *\n"
1325 "HGIDA_Error:enum ?\n"
1326 "HGIDA_Direction:enum ?\n"
1327 "uid_t:long\n"
1328 "gid_t:long\n"
1329 "mode_t:unsigned short\n"
1330 "pid_t:struct Task *\n"
1331 "fd_set:struct fd_set\n"
1332 "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 "
1333 "unsigned long, register __a1 const unsigned char *, register __a2 struct "
1334 "CSource *, register __a3 struct CSource *)\n"
1335 "pcap_t:struct pcap\n"
1336 "pcap_dumper_t:struct pcap_dumper\n"
1337 "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const "
1338 "unsigned char *)\n"
1339 "u_char:unsigned char\n"
1340 "bpf_u_int32:unsigned long\n"
1341 "Fixed:long\n"
1342 "sposition:long\n"
1343 "MPEGA_STREAM:struct MPEGA_STREAM\n"
1344 "MPEGA_CTRL:struct MPEGA_CTRL\n"
1345 "W3D_Context:struct W3DContext\n"
1346 "W3D_Driver:struct W3DDriver\n"
1347 "W3D_Texture:struct W3DTexture\n"
1348 "W3D_Scissor:struct W3DScissor\n"
1349 "W3D_Line:struct W3D_Line\n"
1350 "W3D_Point:struct W3D_Point\n"
1351 "W3D_Triangle:struct W3D_Triangle\n"
1352 "W3D_Triangles:struct W3D_Triangles\n"
1353 "W3D_Float:float\n"
1354 "W3D_Bitmap:struct W3D_Bitmap\n"
1355 "W3D_Fog:struct W3D_Fog\n"
1356 "W3D_Bool:short\n"
1357 "W3D_Double:double\n"
1358 "W3D_TriangleV:struct W3D_TriangleV\n"
1359 "W3D_TrianglesV:struct W3D_TriangleV\n"
1360 "W3D_ScreenMode:struct W3D_Screenmode\n"
1361 "W3D_Color:struct W3D_Color\n"
1362 "W3D_Lines:struct W3D_Lines\n"
1363 "RGBFTYPE:enum ?\n"
1364 "DITHERINFO:void *\n"
1365 "SLayer:void *\n"
1366 "va_list:char *\n"
1367 "time_t:long\n"
1368 "size_t:unsigned int\n"
1369 "FILE:struct ? *\n"
1370 "uint8:unsigned char\n"
1371 "uint16:unsigned short\n"
1372 "uint32:unsigned long\n"
1373 "int8:char\n"
1374 "int16:short\n"
1375 "int32:long\n"
1376 "AVLKey:void *\n"
1377 "PtrBigNum:struct BigNum *\n"
1378 "BF_KEY:struct bf_key_st\n"
1379 "BF_LONG:unsigned long\n"
1380 "CAST_KEY:struct cast_key_st\n"
1381 "CAST_LONG:unsigned long\n"
1382 "DES_LONG:unsigned long\n"
1383 "des_key_schedule:struct des_ks_struct\n"
1384 "const_des_cblock:unsigned char [8]\n"
1385 "des_cblock:unsigned char [8]\n"
1386 "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
1387 "MD2_CTX:struct MD2state_st\n"
1388 "MD5_CTX:struct MD5state_st\n"
1389 "MDC2_CTX:struct mdc2_ctx_st\n"
1390 "RC2_KEY:struct rc2_key_st\n"
1391 "RC4_KEY:struct rc4_key_st\n"
1392 "RC5_32_KEY:struct rc5_key_st\n"
1393 "RIPEMD160_CTX:struct RIPEMD160state_st\n"
1394 "SHA_CTX:struct SHAstate_st\n"
1395 "ASN1_CTX:struct asn1_ctx_st\n"
1396 "ASN1_OBJECT:struct asn1_object_st\n"
1397 "ASN1_STRING:struct asn1_string_st\n"
1398 "ASN1_TYPE:struct asn1_type_st\n"
1399 "ASN1_METHOD:struct asn1_method_st\n"
1400 "ASN1_HEADER:struct asn1_header_st\n"
1401 "ASN1_INTEGER:struct asn1_string_st\n"
1402 "ASN1_ENUMERATED:struct asn1_string_st\n"
1403 "ASN1_BIT_STRING:struct asn1_string_st\n"
1404 "ASN1_OCTET_STRING:struct asn1_string_st\n"
1405 "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
1406 "ASN1_T61STRING:struct asn1_string_st\n"
1407 "ASN1_IA5STRING:struct asn1_string_st\n"
1408 "ASN1_UTCTIME:struct asn1_string_st\n"
1409 "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
1410 "ASN1_TIME:struct asn1_string_st\n"
1411 "ASN1_GENERALSTRING:struct asn1_string_st\n"
1412 "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
1413 "ASN1_BMPSTRING:struct asn1_string_st\n"
1414 "ASN1_VISIBLESTRING:struct asn1_string_st\n"
1415 "ASN1_UTF8STRING:struct asn1_string_st\n"
1416 "BIO:struct bio_st\n"
1417 "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
1418 "BIO_METHOD:struct bio_method_st\n"
1419 "BIGNUM:struct bignum_st\n"
1420 "BN_CTX:struct bignum_ctx\n"
1421 "BN_ULONG:unsigned long\n"
1422 "BN_MONT_CTX:struct bn_mont_ctx_st\n"
1423 "BN_BLINDING:struct bn_blinding_st\n"
1424 "BN_RECP_CTX:struct bn_recp_ctx_st\n"
1425 "BUF_MEM:struct buf_mem_st\n"
1426 "COMP_METHOD:struct comp_method_st\n"
1427 "COMP_CTX:struct comp_ctx_st\n"
1428 "CONF_VALUE:struct !\n"
1429 "LHASH_NODE:struct lhash_node_st\n"
1430 "LHASH:struct lhash_st\n"
1431 "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
1432 "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
1433 "DH:struct dh_st\n"
1434 "DSA:struct dsa_st\n"
1435 "DSA_SIG:struct DSA_SIG_st\n"
1436 "ERR_STATE:struct err_state_st\n"
1437 "ERR_STRING_DATA:struct ERR_string_data_st\n"
1438 "EVP_PKEY:struct evp_pkey_st\n"
1439 "EVP_MD:struct env_md_st\n"
1440 "EVP_MD_CTX:struct env_md_ctx_st\n"
1441 "EVP_CIPHER:struct evp_cipher_st\n"
1442 "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
1443 "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
1444 "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
1445 "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char "
1446 "*pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st "
1447 "*cipher, struct env_md_st *md, int en_de)\n"
1448 "HMAC_CTX:struct hmac_ctx_st\n"
1449 "OBJ_NAME:struct obj_name_st\n"
1450 "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
1451 "PEM_USER:struct pem_recip_st\n"
1452 "PEM_CTX:struct pem_ctx_st\n"
1453 "PKCS12_MAC_DATA:struct !\n"
1454 "PKCS12:struct !\n"
1455 "PKCS12_SAFEBAG:struct !\n"
1456 "PKCS12_BAGS:struct pkcs12_bag_st\n"
1457 "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
1458 "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
1459 "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
1460 "PKCS7_SIGNED:struct pkcs7_signed_st\n"
1461 "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
1462 "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
1463 "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
1464 "PKCS7_DIGEST:struct pkcs7_digest_st\n"
1465 "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
1466 "PKCS7:struct pkcs7_st\n"
1467 "RAND_METHOD:struct rand_meth_st\n"
1468 "RSA:struct rsa_st\n"
1469 "RSA_METHOD:struct rsa_meth_st\n"
1470 "TXT_DB:struct txt_db_st\n"
1471 "X509_OBJECTS:struct X509_objects_st\n"
1472 "X509_ALGOR:struct X509_algor_st\n"
1473 "X509_VAL:struct X509_val_st\n"
1474 "X509_PUBKEY:struct X509_pubkey_st\n"
1475 "X509_SIG:struct X509_sig_st\n"
1476 "X509_NAME_ENTRY:struct X509_name_entry_st\n"
1477 "X509_NAME:struct X509_name_st\n"
1478 "X509_EXTENSION:struct X509_extension_st\n"
1479 "X509_ATTRIBUTE:struct x509_attributes_st\n"
1480 "X509_REQ_INFO:struct X509_req_info_st\n"
1481 "X509_REQ:struct X509_req_st\n"
1482 "X509_CINF:struct x509_cinf_st\n"
1483 "X509:struct x509_st\n"
1484 "X509_REVOKED:struct X509_revoked_st\n"
1485 "X509_CRL_INFO:struct X509_crl_info_st\n"
1486 "X509_CRL:struct X509_crl_st\n"
1487 "X509_PKEY:struct private_key_st\n"
1488 "X509_INFO:struct X509_info_st\n"
1489 "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
1490 "NETSCAPE_SPKI:struct Netscape_spki_st\n"
1491 "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
1492 "CBC_PARAM:struct CBCParameter_st\n"
1493 "PBEPARAM:struct PBEPARAM_st\n"
1494 "PBE2PARAM:struct PBE2PARAM_st\n"
1495 "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
1496 "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
1497 "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
1498 "X509V3_EXT_METHOD:struct v3_ext_method\n"
1499 "X509V3_CTX:struct v3_ext_ctx\n"
1500 "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
1501 "X509_CERT_FILE_CTX:struct x509_file_st\n"
1502 "X509_OBJECT:struct X509_objects_st\n"
1503 "X509_LOOKUP:struct x509_lookup_st\n"
1504 "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
1505 "X509_STORE_CTX:struct x509_store_state_st\n"
1506 "X509_STORE:struct x509_store_st\n"
1507 "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
1508 "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
1509 "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
1510 "GENERAL_NAME:struct GENERAL_NAME_st\n"
1511 "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
1512 "DIST_POINT:struct DIST_POINT_st\n"
1513 "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
1514 "SXNETID:struct SXNET_ID_st\n"
1515 "SXNET:struct SXNET_st\n"
1516 "NOTICEREF:struct NOTICEREF_st\n"
1517 "USERNOTICE:struct USERNOTICE_st\n"
1518 "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
1519 "POLICYINFO:struct POLICYINFO_st\n"
1520 "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
1521 "SSL_CIPHER:struct ssl_cipher_st\n"
1522 "SSL:struct ssl_st\n"
1523 "SSL_CTX:struct ssl_ctx_st\n"
1524 "SSL_METHOD:struct ssl_method_st\n"
1525 "SSL_SESSION:struct ssl_session_st\n"
1526 "SSL_COMP:struct ssl_comp_st\n"
1527 "SSL2_CTX:struct ssl2_ctx_st\n"
1528 "SSL3_RECORD:struct ssl3_record_st\n"
1529 "SSL3_BUFFER:struct ssl3_buffer_st\n"
1530 "SSL3_CTX:struct ssl3_ctx_st\n"
1531 "CERT_PKEY:struct cert_pkey_st\n"
1532 "CERT:struct cert_st\n"
1533 "SESS_CERT:struct sess_cert_st\n"
1534 "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
1535 "SSL3_COMP:struct ssl3_comp_st\n"
1536 "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
1537 "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
1538 "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
1539 "STACK_OF(X509):struct stack_st_X509\n"
1540 "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
1541 "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
1542 "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
1543 "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
1544 "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
1545 "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
1546 "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
1547 "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
1548 "STACK:struct stack_st\n"
1549 "SDL_bool:enum ?\n"
1550 "Uint8:unsigned char\n"
1551 "Sint8:signed char\n"
1552 "Uint16:unsigned short\n"
1553 "Sint16:signed short\n"
1554 "Uint32:unsigned long\n"
1555 "Sint32:signed long\n"
1556 "Uint64:unsigned long long\n"
1557 "Sint64:signed long long\n"
1558 "SDL_version:struct !\n"
1559 "SDL_RWops:struct SDL_RWops\n"
1560 "SDL_Rect:struct !\n"
1561 "SDL_Color:struct !\n"
1562 "SDL_Palette:struct !\n"
1563 "SDL_PixelFormat:struct SDL_PixelFormat\n"
1564 "SDL_blit:int (*)(struct SDL_Surface *src,void *srcrect,"
1565 "struct SDL_Surface *dst,void *dstrect)\n"
1566 "SDL_Surface:struct SDL_Surface\n"
1567 "SDL_VideoInfo:struct !\n"
1568 "SDL_Overlay:struct SDL_Overlay\n"
1569 "SDL_GLattr:enum ?\n"
1570 "SDL_GrabMode:enum ?\n"
1571 "SDL_audiostatus:enum ?\n"
1572 "SDL_AudioSpec:struct !\n"
1573 "SDL_AudioCVT:struct SDL_AudioCVT\n"
1574 "CDstatus:enum ?\n"
1575 "SDL_CDtrack:struct !\n"
1576 "SDL_CD:struct SDL_CD\n"
1577 "SDL_Joystick:struct _SDL_Joystick\n"
1578 "SDLKey:enum ?\n"
1579 "SDLMod:enum ?\n"
1580 "SDL_keysym:struct !\n"
1581 "SDL_ActiveEvent:struct !\n"
1582 "SDL_KeyboardEvent:struct !\n"
1583 "SDL_MouseMotionEvent:struct !\n"
1584 "SDL_MouseButtonEvent:struct !\n"
1585 "SDL_JoyAxisEvent:struct !\n"
1586 "SDL_JoyBallEvent:struct !\n"
1587 "SDL_JoyHatEvent:struct !\n"
1588 "SDL_JoyButtonEvent:struct !\n"
1589 "SDL_ResizeEvent:struct !\n"
1590 "SDL_ExposeEvent:struct !\n"
1591 "SDL_QuitEvent:struct !\n"
1592 "SDL_UserEvent:struct !\n"
1593 "SDL_SysWMmsg:struct SDL_SysWMmsg\n"
1594 "SDL_SysWMEvent:struct !\n"
1595 "SDL_Event:union ?\n"
1596 "SDL_eventaction:enum ?\n"
1597 "SDL_EventFilter:void *\n"
1598 "WMcursor:struct WMcursor\n"
1599 "SDL_Cursor:struct !\n"
1600 "SDL_mutex:struct SDL_mutex\n"
1601 "SDL_sem:struct SDL_semaphore\n"
1602 "SDL_cond:struct SDL_cond\n"
1603 "SDL_Thread:struct SDL_Thread\n"
1604 "SDL_TimerCallback:unsigned long (*)(unsigned long)\n"
1605 "SDL_NewTimerCallback:unsigned long (*)(unsigned long,void *)\n"
1606 "SDL_TimerID:struct _SDL_TimerID\n"
1607 "SDL_errorcode:enum ?\n"
1608 "FPSmanager:struct !\n"
1609 "Mix_Chunk:struct !\n"
1610 "Mix_Music:struct !\n"
1611 "Mix_MusicType:enum ?\n"
1612 "Mix_EffectFunc_t:void (*)(int,void *,int,void *)\n"
1613 "Mix_EffectDone_t:void (*)(int,void *)\n"
1614 "Mix_Fading:enum ?\n"
1615 "IPaddress:struct !\n"
1616 "TCPsocket:void *\n"
1617 "UDPpacket:struct !\n"
1618 "UDPsocket:void *\n"
1619 "SDLNet_SocketSet:void *\n"
1620 "SDLNet_GenericSocket:void *\n"
1621 "TTF_Font:struct !\n"
1624 static const struct CPP_TypeField CPP_Field[] = {
1625 {"int", 3, 0, CPP_TYPE_INT},
1626 /* long needs special handling due to the fact it is a modifier and a type */
1627 /*{"long", 4, 0, CPP_TYPE_LONG}, */
1628 {"LONG", 4, 0, CPP_TYPE_LONG},
1629 {"BPTR", 4, 0, CPP_TYPE_LONG},
1630 {"BSTR", 4, 0, CPP_TYPE_LONG},
1631 {"CxObj", 5, 0, CPP_TYPE_LONG},
1632 {"CxMsg", 5, 0, CPP_TYPE_LONG},
1633 {"ULONG", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1634 {"LONGBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1635 {"CPTR", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1636 {"Tag", 3, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1637 {"Object", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_LONG},
1638 {"short", 5, 0, CPP_TYPE_WORD},
1639 {"SHORT", 5, 0, CPP_TYPE_WORD},
1640 {"COUNT", 5, 0, CPP_TYPE_WORD},
1641 {"WORD", 4, 0, CPP_TYPE_WORD},
1642 {"USHORT", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1643 {"UWORD", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1644 {"UCOUNT", 6, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1645 {"WORDBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1646 {"RPTR", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_WORD},
1647 {"BOOL", 4, CPP_FLAG_BOOLEAN, CPP_TYPE_WORD},
1648 {"char", 4, 0, CPP_TYPE_BYTE},
1649 {"BYTE", 4, 0, CPP_TYPE_BYTE},
1650 {"UBYTE", 5, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1651 {"TEXT", 4, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1652 {"BYTEBITS", 8, CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1653 {"float", 5, 0, CPP_TYPE_FLOAT},
1654 {"FLOAT", 5, 0, CPP_TYPE_FLOAT},
1655 {"double", 6, 0, CPP_TYPE_DOUBLE},
1656 {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE},
1657 {"void", 4, 0, CPP_TYPE_VOID},
1658 {"VOID", 4, 0, CPP_TYPE_VOID},
1659 {"APTR", 4, CPP_FLAG_POINTER, CPP_TYPE_VOID},
1660 {"STRPTR", 6, CPP_FLAG_POINTER|CPP_FLAG_STRPTR, CPP_TYPE_BYTE},
1661 {"CONST_STRPTR",12,CPP_FLAG_POINTER|CPP_FLAG_CONST, CPP_TYPE_BYTE},
1662 {"ClassID", 7, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1663 {"PLANEPTR", 8, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED, CPP_TYPE_BYTE},
1664 {0,0,0,0},
1667 /* defaults: "Library" shortbname+".library" basename-last 4 chars */
1668 static const struct Proto_LibType Proto_LibTypes[] = {
1669 {"DOSBase", "DosLibrary", 0, 0},
1670 {"SysBase", "ExecBase", 0, 0},
1671 {"ExpansionBase", "ExpansionBase", 0, 0},
1672 {"GfxBase", "GfxBase", "graphics.library", "graphics"},
1673 {"IntuitionBase", "IntuitionBase", 0, 0},
1674 {"LocaleBase", "LocaleBase", 0, 0},
1675 {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
1676 {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
1677 {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
1678 {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
1679 {"RealTimeBase", "RealTimeBase", 0, 0},
1680 {"RexxSysBase", "RxsLib", 0, 0},
1681 {"UtilityBase", "UtilityBase", 0, 0},
1682 {"WorkbenchBase", 0, "workbench.library", "wb"},
1683 /* resources - The Node entries may be correct, but I don't know it. */
1684 {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
1685 {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
1686 {"CardResource", 0/*"Node"*/, "card.resource", "cardres"},
1687 {"DiskBase", "DiskResource", "disk.resource", 0},
1688 {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
1689 {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
1690 /* devices */
1691 {"ConsoleDevice", 0/*"Device"*/, "console.device", "console"},
1692 {"InputBase", 0/*"Device"*/, "input.device", 0},
1693 {"RamdriveDevice", 0/*"Device"*/, "ramdrive.device", "ramdrive"},
1694 {"TimerBase", 0/*"Device"*/, "timer.device", 0},
1695 /* non default Basenames */
1696 {"DatamasterBase", "DatamasterBase", 0, 0},
1697 {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
1698 {"ReqToolsBase", "ReqToolsBase", 0, 0},
1699 {"UnpackBase", "UnpackLibrary", 0, 0},
1700 {"xfdMasterBase", "xfdMasterBase", 0, 0},
1701 {"xadMasterBase", "xadMasterBase", 0, 0},
1702 /*{"xvsBase", "xvsBase", 0, 0}, now completely private */
1703 {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
1704 {"ArpBase", "ArpBase", 0, 0},
1705 {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
1706 {"PowerPCBase", "PPCBase", 0, 0},
1707 {"MC68060Base", 0, "68060.library", "mc68060"},
1708 {"MC68040Base", 0, "68040.library", "mc68040"},
1709 {"MC680x0Base", 0, "680x0.library", "mc680x0"},
1710 {"P96Base", 0, "Picasso96API.library","Picasso96"},
1711 {"Warp3DPPCBase", 0, "Warp3DPPC.library" ,"Warp3D"},
1712 {"CyberGfxBase", 0, "cybergraphics.library", "cybergraphics"},
1713 {0, 0, 0, 0},
1716 /* CachePostDMA, CachePreDMA are done by #?DMA check */
1717 static const struct Pragma_ExecpName Pragma_ExecpNames[] = {
1718 {"VFWritef", "FWritef"},
1719 {"VFPrintf", "FPrintf"},
1720 {"VPrintf", "Printf"},
1721 {"ReadArgs", 0},
1722 {"FreeArgs", 0},
1723 {"CloneTagItems", 0},
1724 {"FindTagItem", 0},
1725 {"FreeTagItems", 0},
1726 {"GetTagData", 0},
1727 {"PackBoolTags", 0},
1728 {"PackStructureTags", 0},
1729 {"UnpackStructureTags", 0},
1730 {"BGUI_PackStructureTags", 0},
1731 {"BGUI_UnpackStructureTags", 0},
1732 {"Inet_NtoA", 0}, /* socket.library */
1733 {"vsyslog", "syslog"},
1734 {"NewPPCStackSwap", 0},
1735 {"FindTagItemPPC", 0},
1736 {"GetTagDataPPC", 0},
1737 {"GetInfo", 0},
1738 {"GetHALInfo", 0},
1739 {"SetScheduling", 0},
1740 {"W3D_CreateContext", "W3D_CreateContextTags"},
1741 {"W3D_RequestMode", "W3D_RequestModeTags"},
1742 {"W3D_AllocTexObj", "W3D_AllocTexObjTags"},
1743 {"W3D_BestModeID", "W3D_BestModeIDTags"},
1744 {0,0},
1747 /* This field contains functions, which should not be created as inlines with
1748 some targets. At the moment these are varargs functions, which are used in
1749 the MUI style using complicated defines. Theses functions are disabled in
1750 certain GCC and VBCC environments. */
1751 static const strptr NoCreateInlineFuncs[] = {
1752 "NewObject",
1753 "MUI_NewObject",
1754 "PM_MakeItem",
1758 /* For double tagcall names (currently only necessary for dos.library and
1759 datatypes.library). Only one alias supported for a function! */
1760 static const struct Pragma_AliasName Pragma_AliasNames[] = {
1761 {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL},
1762 {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL},
1763 {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL},
1764 {"SystemTagList", "System", FUNCFLAG_NORMAL},
1765 {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG},
1766 {0,0,0},
1769 /* special names, which get an x before name in BMAP files */
1770 static const strptr BMAPSpecial[] =
1771 {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
1772 "Translate", "Wait", "Write", 0};
1774 #define FIRST_KNOWN_RELEASE 30
1775 #define LAST_KNOWN_RELEASE 45
1776 static const strptr Release[] =
1778 "Release 1.0", /* V30 */
1779 "Release 1.1", /* V31 */
1780 "Preliminary Release 1.2", /* V32 */
1781 "Release 1.2", /* V33 */
1782 "Release 1.3", /* V34 */
1783 "Release 1.3 A2024", /* V35 */
1784 "Release 2.0", /* V36 */
1785 "Release 2.04", /* V37 */
1786 "Release 2.1", /* V38 */
1787 "Release 3.0", /* V39 */
1788 "Release 3.1", /* V40 */
1789 "Transitional Release 3.2", /* V41 */
1790 "Transitional Release 3.3", /* V42 */
1791 "Transitional Release 3.4", /* V43 */
1792 "Release 3.5", /* V44 */
1793 "Release 3.9", /* V45 */
1796 /* Keywords, which cannot be argument names. They are used case_insensitive to
1797 be sure they make no conflicts in non-C-languages as well.
1798 Currently these are mostly C keywords.
1800 static const strptr Keywords[] =
1802 "and", "and_eq", "asm", "auto", "bitand",
1803 "bitor", "break", "case", "catch", "char",
1804 "class", "compl", "const", "continue", "default",
1805 "delete", "do", "double", "else", "enum",
1806 "extern", "false", "float", "for", "friend",
1807 "goto", "if", "inline", "int", "long",
1808 "new", "not", "not_eq", "operator", "or",
1809 "or_eq", "private", "protected", "public", "register",
1810 "return", "short", "signed", "sizeof", "static",
1811 "struct", "switch", "template", "this", "throw",
1812 "true", "try", "typedef", "union", "unsigned",
1813 "virtual", "void", "volatile", "wchar_t", "while",
1814 "xor", "xor_eq", "RastPort", "Tag",
1818 #if !defined __SASC && !defined __AROS__ && !defined _WIN32 && !defined __CYGWIN__
1819 static int stricmp(const char *a, const char *b)
1821 while(*a && tolower(*a) == tolower(*b))
1823 ++a; ++b;
1825 return (tolower(*a) - tolower(*b));
1828 static int strnicmp(const char *a, const char *b, size_t num)
1830 while(num && *a && tolower(*a) == tolower(*b))
1832 ++a; ++b; --num;
1834 return num ? (tolower(*a) - tolower(*b)) : 0;
1836 #endif
1838 static strptr DupString(strptr Str, size_t Len)
1840 strptr res, r;
1841 if((res = r = AllocListMem(Len+1)))
1843 while(Len-- && *Str)
1844 *(r++) = *(Str++);
1845 *r = '\0';
1847 #ifdef DEBUG_OLD
1848 printf("DupString %s.\n", res);
1849 #endif
1850 return res;
1853 static strptr AllocListMem(size_t size)
1855 strptr a;
1856 #ifdef DEBUG_OLD
1857 printf("AllocListMem Size %d.\n", size);
1858 #endif
1859 if((a = (strptr) malloc(size)))
1860 memset(a, 0, size);
1861 return a;
1864 static strptr SkipBlanks(strptr OldPtr)
1866 while(*OldPtr == ' ' || *OldPtr == '\t')
1867 ++OldPtr;
1868 return OldPtr;
1871 static strptr SkipBlanksRet(strptr OldPtr)
1873 while(*OldPtr == ' ' || *OldPtr == '\t' || *OldPtr == '\n')
1874 ++OldPtr;
1875 return OldPtr;
1879 This function is used to skip over variable names.
1881 Inputs: OldPtr - pointer to the beginning of a string.
1883 Result: Pointer to the first character of the string, that is not one
1884 of a-z, A-Z, 0-9 or the underscore.
1887 static strptr SkipName(strptr OldPtr)
1889 while(isalnum(*OldPtr) || *OldPtr == '_')
1890 ++OldPtr;
1891 return OldPtr;
1894 static int IsNoCreateInlineFunc(const strptr name)
1896 const strptr *a;
1897 for(a = NoCreateInlineFuncs; *a; ++a)
1899 if(!strcmp(name, *a))
1900 return 1;
1902 return 0;
1905 static uint32 GetTypes(void)
1907 strptr ptr;
1908 size_t len;
1909 uint32 i;
1911 if(!(ptr = mygetfile(EXTTYPESFILE, &len)))
1913 #ifdef EXTTYPESFILEHIDDEN
1914 if((ptr = getenv("HOME")))
1916 strptr ptrh = EXTTYPESFILEHIDDEN;
1918 i = strlen(ptr);
1919 ptr = DupString(ptr, i + sizeof(EXTTYPESFILEHIDDEN) + 1);
1920 if(i && ptr[i-1] != '/')
1921 ptr[i++] = '/';
1922 while(*ptrh)
1923 ptr[i++] = *(ptrh++);
1924 ptr[i] = 0;
1925 ptr = mygetfile(ptr, &len);
1927 if(!ptr) /* disabled following if ptr != 0 */
1928 #endif
1929 if(!(ptr = mygetfile(EXTTYPESFILE2, &len)))
1931 DoError(ERR_NOFD2PRAGMATYPES, 0);
1932 ptr = (strptr) InternalTypes;
1933 len = sizeof(InternalTypes)-1;
1936 if((i = ScanTypes(ptr, len)) > 0)
1938 DoError(ERR_WRONG_TYPES_LINE, i);
1939 return 0;
1941 return 1;
1944 static strptr GetBaseType(void)
1946 static strptr basetype = 0;
1947 uint32 i;
1949 if(Flags2 & FLAG2_VOIDBASE)
1950 basetype = "void *";
1951 else if(!basetype)
1953 for(i = 0; !libtype && BaseName && Proto_LibTypes[i].BaseName; ++i)
1955 if(!(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
1957 libtype = Proto_LibTypes[i].StructureName;
1958 break;
1961 if(libtype && (basetype = malloc(strlen(libtype) + 9+1)))
1963 sprintf(basetype, "struct %s *", libtype);
1965 if(!libtype)
1966 basetype = "struct Library *";
1969 return basetype;
1972 static strptr GetBaseTypeLib(void)
1974 uint32 i;
1976 if(libtype)
1977 return libtype;
1979 for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
1981 if(Proto_LibTypes[i].StructureName &&
1982 !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
1984 return Proto_LibTypes[i].StructureName;
1987 return libstring;
1990 static strptr GetLibraryName(void)
1992 uint32 i;
1994 if(libname)
1995 return libname;
1997 for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
1999 if(Proto_LibTypes[i].LibraryName &&
2000 !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
2002 return (libname = Proto_LibTypes[i].LibraryName);
2005 if(!(libname = malloc(strlen(ShortBaseName)+9)))
2006 return 0;
2008 /* auto create name */
2009 for(i = 0; ShortBaseName[i]; ++i)
2010 libname[i] = ShortBaseName[i];
2011 strcpy(libname+i,".library");
2012 return libname;
2015 static strptr GetIFXName(void)
2017 static char IFXName[256];
2018 sprintf(IFXName, "%c%s", toupper(ShortBaseName[0]), ShortBaseName+1);
2019 return IFXName;
2022 static int32 MakeShortBaseName(void)
2024 strptr ptr, p2;
2025 uint32 i;
2027 ptr = p2 = args.infile;
2028 while(*p2)
2030 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
2031 ptr = p2+1;
2032 ++p2;
2035 /* first get name from file */
2037 p2 -= (sizeof(SFDFILEEXTENSION)-1);
2038 if(p2 > ptr && !stricmp(p2, SFDFILEEXTENSION))
2039 ShortBaseName = DupString(ptr, p2-ptr);
2040 p2 += sizeof(SFDFILEEXTENSION)-sizeof(FDFILEEXTENSION);
2041 if(p2 > ptr && !stricmp(p2, FDFILEEXTENSION))
2042 ShortBaseName = DupString(ptr, p2-ptr);
2044 /* then try exceptions (overriding filename) */
2045 if(BaseName)
2047 for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
2049 if(Proto_LibTypes[i].ShortBaseName &&
2050 !(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
2052 if(!(ShortBaseName = DupString(Proto_LibTypes[i].ShortBaseName,
2053 strlen(Proto_LibTypes[i].ShortBaseName))))
2054 return 0;
2055 break;
2058 /* and last use default method */
2059 if(!ShortBaseName)
2060 ShortBaseName = DupString(BaseName, strlen(BaseName)-4);
2063 if(!ShortBaseName)
2064 return 0;
2066 ptr = ShortBaseName;
2067 while((*ptr = tolower(*ptr))) /* Convert to lowercase */
2068 ptr++;
2070 if((ShortBaseNameUpper = DupString(ShortBaseName, strlen(ShortBaseName))))
2072 ptr = ShortBaseNameUpper;
2073 while((*ptr = toupper(*ptr))) /* Convert to uppercase */
2074 ptr++;
2076 else
2077 return 0;
2079 return 1;
2082 static uint32 OpenDest(strptr name)
2084 static uint8 printedname = 0;
2085 strptr b, t;
2087 t = (strptr) tempbuf;
2088 if((b = args.to) && *b)
2090 while(*b)
2091 *(t++) = *(b++);
2092 if(*(t-1) != ':' && *(t-1) != '/')
2093 *(t++) = '/';
2095 *t = 0;
2097 if(!(Flags & FLAG_SINGLEFILE))
2098 printf("ResultFile: %s%s\n", tempbuf, name);
2099 else if(!printedname++)
2101 printf("ResultType: %s", tempbuf); printf(filenamefmt, "*");
2102 printf("\n");
2105 while(*name)
2106 *(t++) = *(name++);
2107 *t = 0;
2109 if(args.header)
2111 HEADER = mygetfile((strptr)tempbuf, &headersize);
2112 FindHeader();
2115 if((outfile = fopen((strptr)tempbuf, "wb")))
2116 return 1;
2117 DoError(ERR_OPEN_FILE, 0, tempbuf);
2118 return 0;
2121 static uint32 CloseDest(strptr name)
2123 if(outfile)
2125 fclose(outfile);
2126 outfile = 0;
2128 if(!(Flags & FLAG_DONE) || !Output_Error)
2130 strptr b, t;
2131 if(!Output_Error || !(Flags & FLAG_SINGLEFILE))
2132 DoError(ERR_EMPTY_FILE, 0);
2134 t = (strptr) tempbuf;
2135 if((b = args.to) && *b)
2137 while(*b)
2138 *(t++) = *(b++);
2139 if(*(t-1) != ':' && *(t-1) != '/')
2140 *(t++) = '/';
2142 while(*name)
2143 *(t++) = *(name++);
2144 *t = 0;
2146 remove((strptr)tempbuf);
2147 return 0;
2149 Flags &= ~FLAG_DONE; /* clear the flag */
2151 else
2152 return 0;
2153 return 1;
2156 static uint32 MakeTagFunction(struct AmiPragma *ap)
2158 size_t len = strlen(ap->FuncName);
2159 long i=0;
2161 #ifdef DEBUG_OLD
2162 printf("MakeTagFunction:\n");
2163 #endif
2165 if(!ap->NumArgs || ap->TagName)
2166 return 1;
2168 ++tagfuncs;
2169 ap->Flags |= AMIPRAGFLAG_OWNTAGFUNC;
2171 while(Pragma_ExecpNames[i].FunctionName && /* check the exception names */
2172 strcmp(ap->FuncName, Pragma_ExecpNames[i].FunctionName))
2173 ++i;
2175 if(Pragma_ExecpNames[i].FunctionName)
2177 if(!(ap->TagName = Pragma_ExecpNames[i].TagName))
2179 ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
2180 --tagfuncs;
2183 else if(ap->FuncName[len-1] == 'A')
2185 /* skip names with DMA or MESA at end */
2186 if(!strcmp(ap->FuncName+len-3, "DMA") ||
2187 !strcmp(ap->FuncName+len-4, "MESA") ||
2188 !strcmp(ap->FuncName+len-4, "RGBA") ||
2189 !strcmp(ap->FuncName+len-5, "AMIGA"))
2190 { ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC; --tagfuncs; return 1;}
2191 if(!(ap->TagName = DupString(ap->FuncName, len-1)))
2192 return 0;
2194 else if(!strcmp(ap->FuncName + len-7, "TagList"))
2196 if(!(ap->TagName = DupString(ap->FuncName, len-3)))
2197 return 0;
2198 ap->TagName[len-4] = 's';
2200 else if(!strcmp(ap->FuncName + len-4, "Args"))
2202 if(!(ap->TagName = DupString(ap->FuncName, len-4)))
2203 return 0;
2205 else if(!stricmp(ap->Args[ap->CallArgs-1].ArgName, "tags") ||
2206 !stricmp(ap->Args[ap->CallArgs-1].ArgName, "taglist"))
2208 if(!(ap->TagName = DupString(ap->FuncName, len+4)))
2209 return 0;
2210 memcpy(ap->TagName + len, "Tags", 5);
2212 else if(!stricmp(ap->Args[ap->CallArgs-1].ArgName, "args"))
2214 if(!(ap->TagName = DupString(ap->FuncName, len+4)))
2215 return 0;
2216 memcpy(ap->TagName + len, "Args", 5);
2218 else
2220 ap->Flags ^= AMIPRAGFLAG_OWNTAGFUNC;
2221 --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
2224 #ifdef DEBUG
2225 if(ap->TagName)
2226 printf("MakeTagFunction: %s / %s (...%s)\n", ap->TagName,
2227 ap->FuncName, ap->Args[ap->CallArgs-1].ArgName);
2228 #endif
2230 return 1;
2233 static void MakeLines(strptr buffer, uint32 size)
2235 if(size && buffer)
2237 /* make a real C++ zero string ending line */
2238 while(size--)
2240 if(*buffer == '\n')
2241 *buffer = '\0';
2242 ++buffer;
2244 *buffer = '\0';
2248 /* Do any special functions, which cannot be done with other exception
2249 stuff - currently only dos.library DoPkt function. */
2250 static uint32 SpecialFuncs(void)
2252 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last,
2253 *ap2 = (struct AmiPragma *) AmiPragma.First;
2255 /* first let one more go away, so we can detect if the DoPkt parts are
2256 already inserted in the FD file */
2258 while(ap2 && (struct AmiPragma *)(ap2->List.Next) != ap)
2259 ap2 = (struct AmiPragma *)(ap2->List.Next);
2261 if(ap2 && ap2->Bias == 0xF0 && ap->Bias != 0xF0 &&
2262 !strcmp("DoPkt", ap2->FuncName))
2264 struct AmiPragma *d;
2265 uint32 i;
2267 RemoveItem(&AmiPragma, (struct ShortList *) ap); /* add in correct order */
2268 for(i = 0; i < 5; ++i)
2270 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
2271 return 0;
2272 memcpy(d, ap2, sizeof(struct AmiPragma));
2273 d->FuncName = DupString(ap2->FuncName, 6);
2274 d->FuncName[5] = '0'+i;
2275 d->NumArgs = d->CallArgs = i + 2;
2276 AddItem(&AmiPragma, (struct ShortList *) d);
2278 AddItem(&AmiPragma, (struct ShortList *) ap);
2280 return 1;
2283 static void SortFDList(void)
2285 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.First, *ap2, *ap3;
2286 AmiPragma.First = AmiPragma.Last = 0;
2288 while(ap)
2290 ap3 = 0;
2291 ap2 = (struct AmiPragma *) AmiPragma.First;
2293 /* for FD2Inline style we need to use strcmp instead of stricmp here */
2294 while(ap2 && stricmp(ap2->FuncName, ap->FuncName) < 0)
2296 ap3 = ap2;
2297 ap2 = (struct AmiPragma *) ap2->List.Next;
2300 ap2 = ap;
2301 ap = (struct AmiPragma *) ap->List.Next;
2303 if(ap3)
2305 ap2->List.Next = (struct ShortList *) ap3->List.Next;
2306 ap3->List.Next = (struct ShortList *) ap2;
2308 else
2310 ap2->List.Next = AmiPragma.First;
2311 AmiPragma.First = (struct ShortList *) ap2;
2313 if(ap && !ap->List.Next)
2314 AmiPragma.Last = (struct ShortList *) ap2;
2318 static void AddAliasName(struct AmiPragma *ap, struct Pragma_AliasName *alias,
2319 uint32 linenum)
2321 int8 i;
2323 if(ap->NumAlias > NUMALIASNAMES)
2324 DoError(ERR_ALIASNAMES, linenum, NUMALIASNAMES);
2325 else
2327 /* prevent double names */
2328 for(i = 0; i < ap->NumAlias; ++i)
2330 if(!strcmp(ap->AliasName[i]->AliasName, alias->AliasName))
2331 return;
2333 ap->AliasName[ap->NumAlias++] = alias;
2337 static uint32 CheckNames(struct AmiPragma *ap)
2339 uint32 i, j;
2340 const strptr *k;
2342 #ifdef DEBUG_OLD
2343 printf("CheckNames\n");
2344 #endif
2345 for(i = 0; i < ap->CallArgs; ++i)
2347 if(!ap->Args[i].ArgName)
2349 if(!(ap->Args[i].ArgName = (strptr)
2350 AllocListMem(4+strlen(RegNames[ap->Args[i].ArgReg]))))
2351 return 0;
2352 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2354 else
2356 for(k = Keywords; *k; ++k)
2358 if(!stricmp(ap->Args[i].ArgName, *k))
2360 DoError(ERR_ARGNAME_KEYWORD_CONFLICT, ap->Line, i, *k);
2361 if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4
2362 +strlen(RegNames[ap->Args[i].ArgReg]))))
2363 return 0;
2364 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2367 for(j = 0; j < i; ++j)
2369 if(!stricmp(ap->Args[i].ArgName, ap->Args[j].ArgName))
2371 DoError(ERR_ARGNAME_ARGNAME_CONFLICT, ap->Line, i+1, j+1);
2372 if(!(ap->Args[i].ArgName = (strptr) AllocListMem(4
2373 +strlen(RegNames[ap->Args[i].ArgReg]))))
2374 return 0;
2375 sprintf(ap->Args[i].ArgName, "%sarg", RegNames[ap->Args[i].ArgReg]);
2380 /* NOTE: the replaced argument names aren't checked for conflicts */
2381 /* replaced names are of style a0arg */
2382 return 1;
2385 static uint32 ScanSFDFile(enum ABI abi)
2387 uint32 _public = 1;
2388 int32 bias = -1;
2389 uint32 linenum;
2390 uint32 actcom = 0;
2391 uint32 functype = 0;
2393 Flags2 |= FLAG2_SFDMODE;
2395 if(strncmp("==id", in.pos, 4))
2396 DoError(ERR_SFD_START, 1);
2398 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
2400 if(*in.pos == '*')
2402 if(linenum < 5 && in.pos[1] == ' ' && in.pos[2] == '\"')
2404 strptr s;
2405 in.pos += 3;
2406 for(s = in.pos; *s && *s != '"'; ++s)
2408 if(*s) /* library name */
2410 #ifdef DEBUG_OLD
2411 printf("ScanSFDFile: found library name comment\n");
2412 #endif
2413 if(!libname)
2415 libname = in.pos;
2416 *(s++) = 0; /* clear the " */
2417 in.pos = s;
2418 Flags2 |= FLAG2_LIBNAMECOM;
2422 else
2424 if(actcom)
2425 *(in.pos-1) = '\n';
2426 else
2428 struct Comment *d;
2429 if(!(d = (struct Comment *) NewItem(&Comment)))
2430 return 0;
2431 d->Bias = bias;
2432 d->Data = in.pos;
2433 d->ReservedNum = 0;
2434 d->Version = 0;
2435 d->Private = _public ? 0 : 1;
2436 AddItem(&Comment, (struct ShortList *) d);
2437 actcom = 1;
2440 while(*in.pos)
2441 ++in.pos;
2443 else if(*in.pos == '=' && in.pos[1] == '=')
2445 in.pos += 2;
2446 actcom = 0; /* no Comment */
2448 if(!strnicmp(in.pos, "basetype", 8))
2450 #ifdef DEBUG_OLD
2451 printf("ScanSFDFile: found ==basetype\n");
2452 #endif
2453 if(!(Flags2 & FLAG2_LIBTYPE))
2455 if(libtype)
2456 DoError(ERR_LIBTYPE_DECLARED_TWICE, linenum);
2458 in.pos = SkipBlanks(in.pos+8);
2459 if(strncmp(in.pos, "struct", 6))
2460 DoError(ERR_EXPECTED_STRUCT, linenum);
2461 else
2463 in.pos = SkipBlanks(in.pos+6);
2464 if(!*in.pos)
2465 DoError(ERR_EXPECTED_LIBTYPE, linenum);
2466 else
2468 libtype = in.pos;
2469 in.pos = SkipName(libtype);
2470 if(*SkipBlanks(in.pos) != '*')
2471 DoError(ERR_EXPECTED_POINTERSIGN, linenum);
2472 if(*in.pos)
2473 *(in.pos++) = 0;
2477 else
2478 DoError(ERR_COMMANDLINE_LIBTYPE, linenum);
2479 while(*in.pos)
2480 ++in.pos;
2482 else if(!strnicmp(in.pos, "copyright", 9))
2484 Copyright = SkipBlanks(in.pos+9);
2485 while(*in.pos)
2486 ++in.pos;
2488 else if(!strnicmp(in.pos, "libname", 7))
2490 #ifdef DEBUG_OLD
2491 printf("ScanSFDFile: found ==libname\n");
2492 #endif
2493 if(!(Flags2 & FLAG2_LIBNAME))
2495 if(libname && !(Flags2 & FLAG2_LIBNAMECOM))
2496 DoError(ERR_LIBNAME_DECLARED_TWICE, linenum);
2498 in.pos = SkipBlanks(in.pos+7);
2499 if(!*in.pos)
2500 DoError(ERR_EXPECTED_LIBNAME, linenum);
2501 else
2502 in.pos = SkipName(libname = in.pos);
2504 else
2505 DoError(ERR_COMMANDLINE_LIBNAME, linenum);
2506 while(*in.pos)
2507 ++in.pos;
2509 else if(!strnicmp(in.pos, "base", 4))
2511 strptr oldptr;
2513 #ifdef DEBUG_OLD
2514 printf("ScanSFDFile: found ==base\n");
2515 #endif
2516 if(!(Flags & FLAG_BASENAME))
2518 if(BaseName)
2519 DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
2521 in.pos = SkipBlanks(in.pos+4);
2522 if(*in.pos != '_')
2523 DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
2524 else
2525 ++in.pos;
2527 BaseName = oldptr = in.pos;
2528 in.pos = SkipName(in.pos);
2529 if(!(in.pos-oldptr))
2530 DoError(ERR_EXPECTED_BASENAME, linenum);
2532 else
2534 DoError(ERR_COMMANDLINE_BASENAME, linenum);
2535 while(*in.pos)
2536 ++in.pos;
2539 else if(!strnicmp(in.pos, "bias", 4))
2541 strptr ptr;
2542 int32 newbias;
2544 #ifdef DEBUG_OLD
2545 printf("ScanSFDFile: found ==bias\n");
2546 #endif
2547 in.pos += 5;
2548 newbias = strtol(in.pos, &ptr, 10);
2549 if(ptr == in.pos)
2550 DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
2551 else if(newbias < 0)
2553 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
2554 bias = -newbias;
2556 else
2557 bias = newbias;
2558 in.pos = SkipName(in.pos);
2560 else if(!strnicmp(in.pos, "end", 3))
2562 bias = 0; break;
2564 else if(!strnicmp(in.pos, "public", 6))
2566 in.pos += 6;
2567 _public = 1;
2569 else if(!strnicmp(in.pos, "private", 7))
2571 in.pos += 7;
2572 _public = 0;
2574 else if(!strnicmp(in.pos, "abi", 3))
2576 #ifdef DEBUG_OLD
2577 printf("ScanSFDFile: found ==abi\n");
2578 #endif
2579 in.pos = SkipBlanks(in.pos+3);
2580 if(!strnicmp(in.pos, "M68k", 4))
2582 abi = ABI_M68K; in.pos += 4;
2584 else if(!strnicmp(in.pos, "PPC0", 4))
2586 abi = ABI_PPC0; in.pos += 4;
2588 else if(!strnicmp(in.pos, "PPC2", 4))
2590 abi = ABI_PPC2; in.pos += 4;
2592 else if(!strnicmp(in.pos, "PPC", 3))
2594 abi = ABI_PPC; in.pos += 3;
2596 else
2597 DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
2599 else if(!strnicmp(in.pos, "id", 2))
2601 if(IDstring)
2602 DoError(ERR_IDSTRING_DECLARED_TWICE, linenum);
2603 IDstring = in.pos = SkipBlanks(in.pos+2);
2604 if(strncmp(in.pos, "$Id: ", 5))
2606 DoError(ERR_EXCPECTED_IDSTRING, linenum);
2608 while(*in.pos)
2609 ++in.pos;
2610 if(*(in.pos-1) != '$')
2611 DoError(ERR_EXPECTED_ID_ENDSIGN, linenum);
2613 else if(!strnicmp(in.pos, "include", 7))
2615 struct Include *d;
2617 if(!(d = (struct Include *) NewItem(&Includes)))
2618 return 0;
2619 d->Include = SkipBlanks(in.pos+7);
2620 AddItem(&Includes, (struct ShortList *) d);
2621 while(*in.pos)
2622 ++in.pos;
2624 else if(!strnicmp(in.pos, "varargs", 7))
2626 if(bias == -1)
2627 DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
2628 else
2630 if(!functype)
2631 bias -= BIAS_OFFSET;
2632 functype |= FUNCFLAG_TAG;
2634 in.pos += 7;
2636 else if(!strnicmp(in.pos, "alias", 5))
2638 if(bias == -1)
2639 DoError(ERR_VARARGS_ALIAS_FIRST, linenum);
2640 else
2642 if(!functype)
2643 bias -= BIAS_OFFSET;
2644 functype |= FUNCFLAG_ALIAS;
2646 in.pos += 5;
2648 else if(!strnicmp(in.pos, "version", 7))
2650 /* store version entries as comments */
2651 struct Comment *d;
2652 strptr ptr;
2653 int16 v;
2655 in.pos = SkipBlanks(in.pos+7);
2656 v = strtol(in.pos, &ptr, 10);
2657 #ifdef DEBUG_OLD
2658 printf("ScanSFDFile: found ==version %d\n", v);
2659 #endif
2660 if(ptr == in.pos || v < 0)
2661 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
2662 else
2664 if(!(d = (struct Comment *) NewItem(&Comment)))
2665 return 0;
2666 d->Bias = bias;
2667 d->Data = 0;
2668 d->ReservedNum = 0;
2669 d->Version = v;
2670 d->Private = _public ? 0 : 1;
2671 AddItem(&Comment, (struct ShortList *) d);
2672 in.pos = SkipName(in.pos);
2675 else if(!strnicmp(in.pos, "reserve", 7))
2677 /* store reserved entries as comments */
2678 struct Comment *d;
2679 strptr ptr;
2680 int16 v;
2682 in.pos = SkipBlanks(in.pos+7);
2683 v = strtol(in.pos, &ptr, 10);
2684 #ifdef DEBUG_OLD
2685 printf("ScanSFDFile: found ==reserve %d\n", v);
2686 #endif
2687 if(bias == -1)
2689 DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
2690 bias = BIAS_START;
2693 if(ptr == in.pos || v < 0)
2694 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER, linenum);
2695 else
2697 if(!(d = (struct Comment *) NewItem(&Comment)))
2698 return 0;
2699 d->Bias = bias;
2700 d->Data = 0;
2701 d->ReservedNum = v;
2702 d->Version = 0;
2703 d->Private = _public ? 0 : 1;
2704 AddItem(&Comment, (struct ShortList *) d);
2705 in.pos = SkipName(in.pos);
2706 bias += BIAS_OFFSET*v;
2709 else
2710 DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
2712 else /* function */
2714 uint32 ft, startlinenum;
2715 struct AmiPragma ap, *ap2;
2716 struct ClibData d, *f;
2717 strptr oldptr;
2718 uint32 maxreg;
2719 strptr data;
2721 actcom = 0;
2722 maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
2723 /* join lines, if necessary */
2724 startlinenum = linenum;
2725 data = in.pos;
2726 /* first open bracket */
2727 while(*data != '('/*)*/ && data < in.buf + in.size)
2728 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2729 ++data;
2730 ft = 0; /* this is needed for function pointer types, which have own
2731 brackets */
2732 /* first close bracket */
2733 while((*data != /*(*/')' || ft) && data < in.buf + in.size)
2735 if(!*data)
2737 *data = ' ';
2738 ++linenum;
2740 else if(*data == '('/*)*/)
2741 ++ft;
2742 else if(*data == /*(*/')')
2743 --ft;
2744 ++data;
2746 /* second open bracket */
2747 while(*data != '('/*)*/ && data < in.buf + in.size)
2748 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2749 /* second close bracket */
2750 while(*data != /*(*/')' && data < in.buf + in.size)
2751 { if(!*data) {*data = ' '; ++linenum; } ++data; }
2752 if(data == in.buf + in.size)
2754 in.pos = data;
2755 DoError(ERR_UNEXPECTED_FILEEND, linenum);
2756 continue;
2759 ft = functype; functype = 0;
2760 memset(&ap, 0, sizeof(struct AmiPragma));
2761 memset(&d, 0, sizeof(struct ClibData));
2762 if(!GetCPPType(&d.ReturnType, in.pos, 1, 1))
2764 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE, startlinenum);
2765 while(*(in.pos++))
2767 continue;
2769 else if(d.ReturnType.Unknown)
2770 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT, startlinenum,
2771 d.ReturnType.Unknown);
2773 ap.FuncName = d.FuncName = SkipBlanks(d.ReturnType.TypeStart
2774 +d.ReturnType.FullLength);
2775 in.pos = SkipBlanks(SkipName(d.FuncName));
2777 if(*in.pos != '('/*)*/)
2779 DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
2780 ++in.pos;
2781 continue;
2783 *(SkipName(d.FuncName)) = 0;
2784 in.pos = SkipBlanks(++in.pos);
2786 oldptr = 0;
2787 while(*in.pos && *in.pos != /*(*/')')
2789 oldptr = (strptr) 1;
2790 if(d.NumArgs >= maxreg)
2792 DoError(ERR_TO_MUCH_ARGUMENTS, startlinenum);
2793 return 0;
2795 else if(!GetCPPType(&d.Args[d.NumArgs++], in.pos, 0, 0))
2797 DoError(ERR_UNKNOWN_VARIABLE_TYPE, startlinenum, d.NumArgs);
2798 break;
2800 else if(d.Args[d.NumArgs-1].Unknown)
2801 DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT, startlinenum, d.NumArgs,
2802 d.Args[d.NumArgs-1].Unknown);
2804 oldptr = in.pos = SkipBlanks(d.Args[d.NumArgs-1].TypeStart
2805 + d.Args[d.NumArgs-1].FullLength);
2806 if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS)
2808 if(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION)
2810 oldptr = d.Args[d.NumArgs-1].FunctionName;
2811 if(!oldptr)
2813 DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
2814 break;
2816 else if(!(oldptr = DupString(oldptr, SkipName(oldptr)-oldptr)))
2817 return 0;
2818 ap.Args[ap.CallArgs++].ArgName = oldptr;
2820 else
2822 ap.Args[ap.CallArgs++].ArgName = in.pos;
2823 in.pos = SkipName(in.pos);
2825 if(in.pos == oldptr)
2827 DoError(ERR_EXPECTED_ARGUMENT_NAME, startlinenum);
2828 break;
2832 else
2833 ++ap.CallArgs;
2835 in.pos = SkipBlanks(in.pos);
2836 if(*in.pos != ',' && *in.pos != /*(*/')')
2838 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2839 break;
2841 if(*in.pos == ')')
2843 in.pos = SkipBlanks(++in.pos);
2844 if(d.Args[d.NumArgs-1].Type != CPP_TYPE_VARARGS &&
2845 !(d.Args[d.NumArgs-1].Flags & CPP_FLAG_FUNCTION))
2846 *(SkipName(oldptr)) = 0;
2847 #ifdef DEBUG_OLD
2848 printf("Added last argument %d (%s) for %s (%d bytes)\n", d.NumArgs,
2849 oldptr, d.FuncName, d.Args[d.NumArgs-1].FullLength);
2850 #endif
2851 oldptr = 0;
2852 break;
2854 else
2856 in.pos = SkipBlanks(++in.pos);
2857 *(SkipName(oldptr)) = 0;
2858 #ifdef DEBUG_OLD
2859 printf("Added argument %d (%s) for %s (%d bytes)\n", d.NumArgs,
2860 oldptr, d.FuncName, d.Args[d.NumArgs-1].FullLength);
2861 #endif
2864 if(*in.pos == /*(*/')')
2865 ++in.pos;
2866 if(!oldptr) /* oldptr == 0 means parsing was valid */
2868 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
2869 return -1;
2871 memcpy(f, &d, sizeof(struct ClibData));
2873 if(!clibdata)
2874 clibdata = f;
2875 else
2877 struct ClibData *e = clibdata;
2878 while(e->Next)
2879 e = e->Next;
2880 e->Next = f;
2883 #ifdef DEBUG_OLD
2884 printf("Added prototype for %s (line %ld) with %d args\n", f->FuncName,
2885 startlinenum, f->NumArgs);
2886 #endif
2887 if(*(in.pos = SkipBlanks(in.pos)) != '('/*)*/)
2889 DoError(ERR_EXPECTED_OPEN_BRACKET, startlinenum);
2890 ++in.pos;
2891 continue;
2894 if(bias == -1)
2896 DoError(ERR_ASSUMING_BIAS_OF_30, startlinenum);
2897 bias = BIAS_START;
2900 ap.Bias = bias;
2901 ap.Abi = abi;
2902 ap.Line = startlinenum;
2903 bias += BIAS_OFFSET;
2905 if(_public)
2906 ap.Flags |= AMIPRAGFLAG_PUBLIC;
2908 if(abi != ABI_M68K)
2910 while(*in.pos && *in.pos != /*(*/')')
2911 ++in.pos;
2912 if(*in.pos != /*(*/')')
2914 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2915 ++in.pos;
2916 continue;
2918 ++in.pos;
2919 ap.NumArgs = ap.CallArgs;
2921 ap.Flags |= AMIPRAGFLAG_PPC;
2922 if(abi == ABI_PPC0)
2923 ap.Flags |= AMIPRAGFLAG_PPC0;
2924 else if(abi == ABI_PPC2)
2925 ap.Flags |= AMIPRAGFLAG_PPC2;
2927 else
2929 uint32 len;
2933 uint32 i;
2935 oldptr = in.pos = SkipBlanks(in.pos+1);
2937 if(*in.pos == /*(*/')' && !ap.NumArgs)
2938 break;
2940 in.pos = SkipName(oldptr);
2941 len = in.pos-oldptr;
2943 for(i = 0; i < MAXREG; ++i)
2944 if(!strnicmp(RegNames[i], oldptr, len))
2945 break;
2947 if(i == MAXREG)
2949 DoError(ERR_EXPECTED_REGISTER_NAME, startlinenum);
2950 break;
2952 else if(i == REG_A6)
2953 ap.Flags |= AMIPRAGFLAG_A6USE;
2954 else if(i == REG_A5)
2955 ap.Flags |= AMIPRAGFLAG_A5USE;
2956 else if(i == REG_A4)
2957 ap.Flags |= AMIPRAGFLAG_A4USE;
2958 else if(i == REG_D7)
2959 ap.Flags |= AMIPRAGFLAG_D7USE;
2960 else if(i == REG_A7)
2962 DoError(ERR_A7_NOT_ALLOWED, startlinenum);
2963 break;
2965 else if(i >= REG_FP0)
2966 ap.Flags |= AMIPRAGFLAG_FLOATARG;
2968 ap.Args[ap.NumArgs].ArgReg = i;
2970 for(i = 0; i < ap.NumArgs; i++)
2972 if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
2974 DoError(ERR_REGISTER_USED_TWICE, startlinenum);
2975 break;
2978 if(i < ap.NumArgs)
2979 break;
2981 ++ap.NumArgs;
2983 in.pos = SkipBlanks(in.pos);
2984 if(*in.pos != ',' && *in.pos != '-' && *in.pos != '/' &&
2985 *in.pos != /*(*/')')
2987 DoError(ERR_EXPECTED_CLOSE_BRACKET, startlinenum);
2988 break;
2990 } while(*in.pos != /*(*/')');
2992 if(*in.pos != /*(*/')')
2994 while(*(in.pos++))
2995 ++in.pos;
2996 continue;
2998 else
2999 ++in.pos;
3001 ap2 = (struct AmiPragma *)(AmiPragma.Last);
3002 if(ft && !(ft & FUNCFLAG_TAG) && ap.NumArgs != ap2->NumArgs)
3003 ft = 0; /* like DoPkt, handle as seperate function */
3004 if(ft) /* handle alias and varargs */
3006 if(ap2->TagName || (ft & FUNCFLAG_ALIAS))
3008 struct Pragma_AliasName *p;
3010 if((p = (struct Pragma_AliasName *)
3011 AllocListMem(sizeof(struct Pragma_AliasName))))
3013 p->FunctionName = ap2->TagName;
3014 p->AliasName = ap.FuncName;
3015 p->Type = (ft & FUNCFLAG_TAG) ? FUNCFLAG_TAG : FUNCFLAG_NORMAL;
3016 AddAliasName(ap2, p, startlinenum);
3018 else
3019 return 0;
3021 else
3023 ap2->TagName = ap.FuncName;
3024 ++tagfuncs;
3026 if(ap.CallArgs != ap2->CallArgs)
3028 if(ap2->CallArgs + 1 == ap.CallArgs && d.Args[d.NumArgs-1].Type
3029 == CPP_TYPE_VARARGS)
3031 --ap.CallArgs;
3032 if(abi != ABI_M68K)
3033 --ap.NumArgs;
3036 if(ap.NumArgs != ap2->NumArgs)
3038 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
3040 else if(abi == ABI_M68K)
3042 uint32 i;
3044 for(i = 0; i < ap2->NumArgs; ++i)
3046 if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
3048 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, startlinenum);
3049 break;
3054 else if(abi == ABI_M68K)
3056 if(ap.CallArgs != ap.NumArgs)
3057 { /* this is surely no longer necessary, as there wont be any
3058 varargs functions here */
3059 if(ap.CallArgs == ap.NumArgs+1 && d.Args[d.NumArgs-1].Type
3060 == CPP_TYPE_VARARGS)
3061 --ap.CallArgs;
3062 else
3063 ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
3066 ap.Flags |= AMIPRAGFLAG_M68K;
3068 if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
3069 DoError(ERR_FLOATARG_NOT_ALLOWED, startlinenum);
3070 else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
3071 && !(Flags & FLAG_PPCONLY))
3072 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3073 struct AmiPragma *d;
3074 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3075 return 0;
3076 memcpy(d, &ap, sizeof(struct AmiPragma));
3077 if(!CheckNames(d))
3078 return 0;
3079 AddItem(&AmiPragma, (struct ShortList *) d);
3082 else
3084 if(!(Flags & FLAG_NOPPC))
3086 struct AmiPragma *d;
3087 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3088 return 0;
3089 memcpy(d, &ap, sizeof(struct AmiPragma));
3090 if(!CheckNames(d))
3091 return 0;
3092 AddItem(&AmiPragma, (struct ShortList *) d);
3098 in.pos = SkipBlanks(in.pos);
3099 if(*in.pos)
3100 DoError(ERR_EXTRA_CHARACTERS, linenum);
3101 ++in.pos; /* skip '\0' */
3104 if(bias)
3105 DoError(ERR_MISSING_SFDEND, 0);
3107 return 1;
3110 static uint32 ScanFDFile(void)
3112 uint32 _public = 1;
3113 int32 bias = -1;
3114 uint32 linenum;
3115 size_t len;
3116 uint32 actcom = 0;
3117 uint32 shadowmode = 0;
3118 enum ABI abi = ABI_M68K;
3120 if(defabi)
3122 if(!stricmp(defabi, "M68k"))
3123 abi = ABI_M68K;
3124 else if(!stricmp(defabi, "PPC0"))
3125 abi = ABI_PPC0;
3126 else if(!stricmp(defabi, "PPC2"))
3127 abi = ABI_PPC2;
3128 else if(!stricmp(defabi, "PPC"))
3129 abi = ABI_PPC;
3130 else
3131 DoError(ERR_UNKNOWN_ABI, 0, defabi);
3134 if(in.size > 10 && in.pos[0] == '=' && in.pos[1] == '=')
3135 return ScanSFDFile(abi);
3137 #ifdef DEBUG_OLD
3138 printf("ScanFDFile:\n");
3139 #endif
3141 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
3143 if(*in.pos == '*') /* Comment */
3145 strptr oldpos = in.pos;
3146 #ifdef DEBUG_OLD
3147 printf("ScanFDFile: found a comment\n");
3148 #endif
3149 in.pos = SkipBlanks(in.pos+1);
3150 if(!strnicmp(in.pos, "notagcall", 9))
3152 struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last;
3154 if(ap->TagName)
3156 --tagfuncs; ap->TagName = 0;
3157 ap->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
3159 in.pos = SkipBlanks(in.pos + 9);
3161 else if(!strnicmp(in.pos, "tagcall", 7)) /* Tag to create? */
3163 struct AmiPragma *prevpragma = (struct AmiPragma *) AmiPragma.Last;
3165 in.pos = SkipBlanks(in.pos + 7);
3166 if(!prevpragma)
3168 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
3169 ++in.pos;
3170 continue;
3173 if(!prevpragma->NumArgs)
3175 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
3176 ++in.pos;
3177 continue;
3180 /* Get the tag functions name. */
3182 if(!prevpragma->TagName && (_public || (Flags & FLAG_PRIVATE)))
3183 ++tagfuncs;
3185 if(*in.pos)
3187 strptr oldptr, tptr = prevpragma->TagName;
3189 len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
3190 if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len)))
3191 return 0;
3193 if(*in.pos == '-')
3195 strptr removeptr;
3197 oldptr = in.pos = SkipBlanks(in.pos+1);
3198 in.pos = SkipName(in.pos);
3199 if((len = in.pos-oldptr))
3201 removeptr = prevpragma->TagName+strlen(prevpragma->TagName)-len;
3202 if(strncmp(removeptr, oldptr, len))
3204 #ifdef DEBUG_OLD
3205 printf("ScanFDFile: *tagcall -: %s, %s, %d\n", removeptr, oldptr, len);
3206 #endif
3207 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
3208 prevpragma->TagName = tptr;
3209 ++in.pos;
3210 continue;
3213 *removeptr = '\0';
3215 in.pos = SkipBlanks(in.pos);
3217 if(*in.pos == '+')
3218 in.pos = SkipBlanks(in.pos+1);
3219 else
3220 *in.pos = toupper(*in.pos);
3222 in.pos = SkipName((oldptr = in.pos));
3223 len = in.pos-oldptr;
3224 if(len)
3226 uint32 a = strlen(prevpragma->TagName);
3227 memcpy(prevpragma->TagName+a, oldptr, len);
3228 prevpragma->TagName[a+len] = '\0';
3231 else if(!prevpragma->TagName)
3233 len = strlen(prevpragma->FuncName);
3234 if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len+4)))
3235 return 0;
3236 memcpy(prevpragma->TagName + len, "Tags", 5);
3239 else
3241 if(actcom)
3242 *(oldpos-1) = '\n';
3243 else
3245 struct Comment *d;
3246 if(!(d = (struct Comment *) NewItem(&Comment)))
3247 return 0;
3248 d->Bias = bias;
3249 d->Data = oldpos;
3250 d->ReservedNum = 0;
3251 d->Version = 0;
3252 d->Private = _public ? 0 : 1;
3253 AddItem(&Comment, (struct ShortList *) d);
3254 actcom = 1;
3256 while(*in.pos)
3257 ++in.pos;
3260 else if(*in.pos == '#' && in.pos[1] == '#')
3262 in.pos += 2;
3263 actcom = 0; /* no Comment */
3265 if(!strnicmp(in.pos, "base", 4))
3267 strptr oldptr;
3269 #ifdef DEBUG_OLD
3270 printf("ScanFDFile: found ##base\n");
3271 #endif
3272 if(!(Flags & FLAG_BASENAME))
3274 if(BaseName)
3275 DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
3277 in.pos = SkipBlanks(in.pos+4);
3278 if(*in.pos != '_')
3279 DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
3280 else
3281 ++in.pos;
3283 BaseName = oldptr = in.pos;
3284 in.pos = SkipName(in.pos);
3285 if(!(in.pos-oldptr))
3286 DoError(ERR_EXPECTED_BASENAME, linenum);
3288 else
3290 DoError(ERR_COMMANDLINE_BASENAME, linenum);
3291 while(*in.pos)
3292 ++in.pos;
3295 else if(!strnicmp(in.pos, "bias", 4))
3297 strptr ptr;
3298 int32 newbias;
3300 #ifdef DEBUG_OLD
3301 printf("ScanFDFile: found ##bias\n");
3302 #endif
3303 in.pos += 5;
3304 newbias = strtol(in.pos, &ptr, 10);
3305 if(ptr == in.pos)
3306 DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
3307 else if(newbias < 0)
3309 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
3310 bias = -newbias;
3312 else
3313 bias = newbias;
3314 in.pos = SkipName(in.pos);
3316 else if(!strnicmp(in.pos, "end", 3))
3318 bias = 0; break;
3320 else if(!strnicmp(in.pos, "shadow", 6)) /* introduced by Storm */
3322 in.pos += 6;
3323 if(bias == -1 || !AmiPragma.First)
3324 DoError(ERR_EARLY_SHADOW, linenum);
3325 else
3327 bias -= BIAS_OFFSET;
3328 shadowmode = 1;
3331 else if(!strnicmp(in.pos, "public", 6))
3333 in.pos += 6;
3334 _public = 1;
3336 else if(!strnicmp(in.pos, "private", 7))
3338 in.pos += 7;
3339 _public = 0;
3341 else if(!strnicmp(in.pos, "abi", 3))
3343 #ifdef DEBUG_OLD
3344 printf("ScanFDFile: found ##abi\n");
3345 #endif
3346 in.pos = SkipBlanks(in.pos+3);
3347 if(!strnicmp(in.pos, "M68k", 4))
3349 abi = ABI_M68K; in.pos += 4;
3351 else if(!strnicmp(in.pos, "PPC0", 4))
3353 abi = ABI_PPC0; in.pos += 4;
3355 else if(!strnicmp(in.pos, "PPC2", 4))
3357 abi = ABI_PPC2; in.pos += 4;
3359 else if(!strnicmp(in.pos, "PPC", 3))
3361 abi = ABI_PPC; in.pos += 3;
3363 else
3364 DoError(ERR_UNKNOWN_ABI, linenum, in.pos);
3366 else
3367 DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos-2);
3369 else
3371 strptr oldptr;
3372 uint32 maxreg;
3373 struct AmiPragma ap, *ap2;
3375 #ifdef DEBUG_OLD
3376 printf("ScanFDFile: scan Function\n");
3377 #endif
3378 memset(&ap, 0, sizeof(struct AmiPragma));
3379 actcom = 0;
3381 oldptr = in.pos = SkipBlanks(in.pos);
3382 in.pos = SkipName(oldptr);
3383 if(!(len = in.pos-oldptr))
3385 DoError(ERR_MISSING_FUNCTION_NAME, linenum);
3386 ++in.pos;
3387 continue;
3390 ap.FuncName = oldptr;
3392 in.pos = SkipBlanks(in.pos);
3393 if(*in.pos != '('/*)*/)
3395 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3396 ++in.pos;
3397 continue;
3400 oldptr[len] = '\0'; /* create c string of FunctionName */
3402 #ifdef DEBUG_OLD
3403 printf("ScanFDFile: found function %s\n", ap.FuncName);
3404 #endif
3406 maxreg = ((abi == ABI_M68K) ? MAXREG-2 : MAXREGPPC);
3409 oldptr = in.pos = SkipBlanks(in.pos+1);
3411 if(*in.pos == '*') /* strange OS3.9 files */
3413 DoError(ERR_ILLEGAL_CHARACTER_DETECTED, linenum);
3414 oldptr = in.pos = SkipBlanks(in.pos+1);
3417 if(*in.pos == /*(*/')' && !ap.CallArgs)
3418 break;
3420 if(ap.CallArgs >= maxreg)
3422 DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
3425 if(!strncmp(in.pos, "void", 4))
3427 /* allows "(void)" instead of ()" */
3428 in.pos = SkipBlanks(in.pos + 4);
3429 if(*in.pos != /*(*/')')
3430 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3431 break;
3434 if(!strncmp(in.pos, "...", 3))
3436 ap.Flags = AMIPRAGFLAG_VARARGS;
3437 ap.Args[ap.CallArgs++].ArgName = 0;
3438 in.pos = SkipBlanks(in.pos+3);
3439 if(*in.pos != /*(*/')')
3440 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3441 break;
3444 in.pos = SkipName(oldptr);
3445 if(*in.pos == '*')
3446 ++in.pos;
3447 if(!(len = in.pos-oldptr))
3449 DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
3450 ap.Args[ap.CallArgs++].ArgName = 0;
3452 else
3454 ap.Args[ap.CallArgs++].ArgName = oldptr;
3455 oldptr = in.pos;
3456 in.pos = SkipBlanks(in.pos);
3458 if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
3460 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3461 break;
3463 if(*in.pos != /*(*/')') /* create c string ending */
3464 *oldptr = '\0';
3465 } while(*in.pos != /*(*/')');
3467 if(*in.pos != /*(*/')')
3469 while(*(in.pos++))
3470 ++in.pos;
3471 continue;
3473 else
3474 *oldptr = '\0'; /* create c string ending for last argument */
3476 if(bias == -1)
3478 DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
3479 bias = BIAS_START;
3482 ap.Bias = bias;
3483 ap.Abi = abi;
3484 ap.Line = linenum;
3485 bias += BIAS_OFFSET;
3487 if(_public)
3488 ap.Flags |= AMIPRAGFLAG_PUBLIC;
3490 in.pos = SkipBlanks(in.pos+1);
3492 if(*in.pos || ap.CallArgs)
3493 /* support for FD's without second empty bracket pair */
3495 if(*in.pos != '('/*)*/)
3497 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3498 ++in.pos;
3499 continue;
3502 if(abi == ABI_M68K)
3506 uint32 i;
3508 oldptr = in.pos = SkipBlanks(in.pos + 1);
3510 if(*in.pos == /*(*/')' && !ap.NumArgs)
3511 break;
3513 if(!strncmp(in.pos, "base", 4))
3515 in.pos = SkipBlanks(in.pos + 4);
3516 if(*in.pos == ',')
3518 in.pos = SkipBlanks(in.pos + 1);
3519 if(!strncmp(in.pos, "sysv",4))
3521 /* MorphOS V.4 with base in r3: (base,sysv) */
3522 ap.Flags |= AMIPRAGFLAG_MOSBASESYSV;
3523 ap.NumArgs = ap.CallArgs;
3524 in.pos = SkipBlanks(in.pos + 4);
3525 if(*in.pos != /*(*/')')
3526 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3527 break;
3531 else if(!strncmp(in.pos, "sysv", 4))
3533 in.pos = SkipBlanks(in.pos + 4);
3534 if(*in.pos == ',')
3536 in.pos = SkipBlanks(in.pos + 1);
3537 if(!strncmp(in.pos, "r12base",7))
3539 /* MorphOS V.4 without passing base: (sysv) */
3540 ap.Flags |= AMIPRAGFLAG_MOSSYSVR12;
3541 ap.NumArgs = ap.CallArgs;
3542 in.pos = SkipBlanks(in.pos + 7);
3543 if(*in.pos != /*(*/')')
3544 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3545 break;
3548 else if (*in.pos == /*(*/')')
3550 /* MorphOS V.4 without passing base: (sysv) */
3551 ap.Flags |= AMIPRAGFLAG_MOSSYSV;
3552 ap.NumArgs = ap.CallArgs;
3553 break;
3555 else
3557 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3558 break;
3562 in.pos = SkipName(oldptr);
3563 len = in.pos-oldptr;
3565 for(i = 0; i < MAXREG; ++i)
3566 if(!strnicmp(RegNames[i], oldptr, len))
3567 break;
3569 if(i == MAXREG)
3571 DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
3572 break;
3574 else if(i == REG_A6)
3575 ap.Flags |= AMIPRAGFLAG_A6USE;
3576 else if(i == REG_A5)
3577 ap.Flags |= AMIPRAGFLAG_A5USE;
3578 else if(i == REG_A4)
3579 ap.Flags |= AMIPRAGFLAG_A4USE;
3580 else if(i == REG_D7)
3581 ap.Flags |= AMIPRAGFLAG_D7USE;
3582 else if(i == REG_A7)
3584 DoError(ERR_A7_NOT_ALLOWED, linenum);
3585 break;
3587 else if(i >= REG_FP0)
3588 ap.Flags |= AMIPRAGFLAG_FLOATARG;
3590 ap.Args[ap.NumArgs].ArgReg = i;
3592 for(i = 0; i < ap.NumArgs; i++)
3594 if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
3596 DoError(ERR_REGISTER_USED_TWICE, linenum);
3597 break;
3600 if(i < ap.NumArgs)
3601 break;
3603 ++ap.NumArgs;
3605 in.pos = SkipBlanks(in.pos);
3606 if(*in.pos != ',' && *in.pos != '/' && *in.pos != /*(*/')')
3608 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3609 break;
3611 } while(*in.pos != /*(*/')');
3613 if(*in.pos != /*(*/')')
3615 while(*(in.pos++))
3616 ++in.pos;
3617 continue;
3619 else
3620 ++in.pos;
3622 else
3624 while(*in.pos && *in.pos != /*(*/')')
3625 ++in.pos;
3626 if(*in.pos != /*(*/')')
3628 DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
3629 ++in.pos;
3630 continue;
3632 ++in.pos;
3633 ap.NumArgs = ap.CallArgs;
3635 ap.Flags |= AMIPRAGFLAG_PPC;
3636 if(abi == ABI_PPC0)
3637 ap.Flags |= AMIPRAGFLAG_PPC0;
3638 else if(abi == ABI_PPC2)
3639 ap.Flags |= AMIPRAGFLAG_PPC2;
3642 else
3643 DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
3645 ap2 = (struct AmiPragma *)(AmiPragma.Last);
3646 if(shadowmode)
3648 if(ap2->TagName && !(ap2->Flags & AMIPRAGFLAG_OWNTAGFUNC))
3650 struct Pragma_AliasName *p;
3651 DoError(ERR_DOUBLE_VARARGS, linenum);
3653 if((p = (struct Pragma_AliasName *)
3654 AllocListMem(sizeof(struct Pragma_AliasName))))
3656 p->FunctionName = ap2->TagName;
3657 p->AliasName = ap.FuncName;
3658 p->Type = FUNCFLAG_TAG;
3659 AddAliasName(ap2, p, linenum);
3661 else
3662 return 0;
3663 #ifdef DEBUG_OLD
3664 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2->TagName);
3665 #endif
3667 else
3669 #ifdef DEBUG_OLD
3670 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2->TagName);
3671 #endif
3672 ap2->Flags &= ~(AMIPRAGFLAG_OWNTAGFUNC);
3673 ap2->TagName = ap.FuncName;
3674 ++tagfuncs;
3676 if(ap.NumArgs != ap2->NumArgs)
3677 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3678 else if(abi == ABI_M68K)
3680 uint32 i;
3682 for(i = 0; i < ap2->NumArgs; ++i)
3684 if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
3686 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3687 break;
3692 /* handle them as alias instead seperate */
3693 else if(ap2 && ap2->Bias == ap.Bias && ap2->NumArgs == ap.NumArgs)
3695 struct Pragma_AliasName *p;
3697 if((p = (struct Pragma_AliasName *)
3698 AllocListMem(sizeof(struct Pragma_AliasName))))
3700 p->FunctionName = ap2->TagName;
3701 p->AliasName = ap.FuncName;
3702 p->Type = FUNCFLAG_NORMAL;
3703 AddAliasName(ap2, p, linenum);
3705 if(abi == ABI_M68K)
3707 uint32 i;
3709 for(i = 0; i < ap2->NumArgs; ++i)
3711 if(ap2->Args[i].ArgReg != ap.Args[i].ArgReg)
3713 DoError(ERR_VARARGS_ARGUMENTS_DIFFER, linenum);
3714 break;
3719 else
3721 if(ap.Flags & AMIPRAGFLAG_VARARGS)
3723 ap.TagName = ap.FuncName;
3724 ap.FuncName = 0;
3726 else if((_public || (Flags & FLAG_PRIVATE)) &&
3727 !MakeTagFunction(&ap))
3728 return 0;
3729 else /* check the alias names */
3731 uint32 i = 0;
3733 while(Pragma_AliasNames[i].FunctionName)
3735 if(!strcmp(ap.FuncName, Pragma_AliasNames[i].FunctionName) ||
3736 (ap.TagName && !strcmp(ap.TagName,
3737 Pragma_AliasNames[i].FunctionName)))
3739 AddAliasName(&ap, (struct Pragma_AliasName *)
3740 &Pragma_AliasNames[i], linenum);
3742 ++i;
3746 if(abi == ABI_M68K)
3748 if(ap.CallArgs != ap.NumArgs)
3749 ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
3751 ap.Flags |= AMIPRAGFLAG_M68K;
3753 if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
3754 DoError(ERR_FLOATARG_NOT_ALLOWED, linenum);
3755 else if(((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
3756 && !(Flags & FLAG_PPCONLY))
3757 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3758 struct AmiPragma *d;
3759 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3760 return 0;
3761 memcpy(d, &ap, sizeof(struct AmiPragma));
3762 if(!CheckNames(d))
3763 return 0;
3764 AddItem(&AmiPragma, (struct ShortList *) d);
3765 if(!SpecialFuncs())
3766 return 0;
3769 else
3771 if(!(Flags & FLAG_NOPPC))
3773 struct AmiPragma *d;
3774 if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
3775 return 0;
3776 memcpy(d, &ap, sizeof(struct AmiPragma));
3777 if(!CheckNames(d))
3778 return 0;
3779 AddItem(&AmiPragma, (struct ShortList *) d);
3781 if(!SpecialFuncs())
3782 return 0;
3787 shadowmode = 0;
3790 in.pos = SkipBlanks(in.pos);
3791 if(*in.pos)
3792 DoError(ERR_EXTRA_CHARACTERS, linenum);
3793 ++in.pos; /* skip '\0' */
3796 if(bias)
3797 DoError(ERR_MISSING_END, 0);
3799 return 1;
3802 static int32 ScanTypes(strptr ptr, uint32 size)
3804 struct CPP_ExternNames *a = 0, *b = 0;
3805 strptr endptr = ptr+size;
3806 int32 line;
3808 for(line = 1; ptr < endptr; ++line)
3810 struct CPP_ExternNames *n;
3812 if(*ptr == '*') /* skip comments */
3814 while(ptr < endptr && *(ptr++) != '\n')
3817 else if((n = (struct CPP_ExternNames *)
3818 AllocListMem(sizeof(struct CPP_ExternNames))))
3820 strptr wptr;
3822 n->Type = ptr; /* store start */
3824 while(ptr < endptr && *ptr != ':' && *ptr != '\n' && *ptr != '\t'
3825 && *ptr != ' ')
3826 ++ptr;
3827 wptr = SkipBlanks(ptr);
3828 if(*(wptr++) != ':')
3829 return line;
3830 *ptr = 0;
3832 n->NameType.StructureName = n->Type;
3833 n->NameType.StructureLength = ptr-n->Type; /* for struct ! types */
3835 if(!GetCPPType(&n->NameType, (ptr = SkipBlanks(wptr)), 0, 1))
3836 return line;
3837 #ifdef DEBUG_OLD
3838 printf("'%20s', slen %2d, typelen %3d, pntd %d, type %c, sn '%.3s'\n",
3839 n->Type, n->NameType.StructureLength, n->NameType.FullLength,
3840 n->NameType.PointerDepth, n->NameType.Type ? n->NameType.Type : 's',
3841 n->NameType.StructureName ? n->NameType.StructureName : "<e>");
3842 #endif
3843 ptr = SkipBlanks(n->NameType.TypeStart+n->NameType.FullLength);
3844 if(*(ptr++) != '\n')
3846 #ifdef DEBUG_OLD
3847 printf("%.30s\n", ptr);
3848 #endif
3849 return line;
3852 if(!a)
3853 b = n;
3854 else
3855 a->Next = n;
3856 a = n;
3858 else
3859 return -1;
3861 extnames = b; /* now store the list */
3862 return 0;
3865 static void FindHeader(void)
3867 strptr str = HEADER;
3868 uint32 mode = 0;
3872 if(!mode)
3873 HEADER = str;
3875 if(*str == '/')
3877 ++str;
3878 if(*str == '*')
3880 mode = 2; break;
3882 else if(*str == '/')
3883 mode = 1;
3885 else if(*str == '*' || *str == ';')
3886 mode = 1;
3887 else if(*str == '{'/*}*/)
3889 mode = 3; break;
3891 else if(*str == '('/*)*/ && *(++str) == '*')
3893 mode = 4; break;
3895 else if(mode)
3896 break;
3897 while(*str && *(str++) != '\n')
3899 } while(*str);
3901 if(mode == 2)
3903 while(*str && (*(str-1) != '*' || *str != '/'))
3904 ++str;
3905 while(*str && *(str++) != '\n')
3908 else if(mode == 3)
3910 while(*str && *str != /*{*/'}')
3911 ++str;
3912 while(*str && *(str++) != '\n')
3915 else if(mode == 4)
3917 while(*str && (*(str-1) != '*' || *str != /*(*/')'))
3918 ++str;
3919 while(*str && *(str++) != '\n')
3923 if(mode)
3924 headersize = str-HEADER;
3925 else
3927 HEADER = 0; headersize = 0;
3931 /* merge data register pairs for 64-bit argument types */
3932 static void FindRegPairs(struct AmiPragma *ap, struct ClibData *cd)
3934 int i, j, k;
3936 for(i = 0, j = 0, k = 0; i < ap->CallArgs || j < ap->NumArgs; ++i, ++j)
3938 if(i < ap->CallArgs && (cd->Args[i].Type == CPP_TYPE_DOUBLE ||
3939 cd->Args[i].Type == CPP_TYPE_LONGLONG)
3940 && j < ap->NumArgs-1 && ap->Args[j].ArgReg < REG_D7
3941 && (ap->Args[j].ArgReg & 1) == 0
3942 && ap->Args[j].ArgReg + 1 == ap->Args[j+1].ArgReg)
3944 ap->Args[k++].ArgReg = REG_D0D1 + (ap->Args[j].ArgReg - REG_D0) / 2;
3945 ++j; /* skip next ArgReg */
3947 else if(j < ap->NumArgs)
3948 ap->Args[k++].ArgReg = ap->Args[j].ArgReg;
3951 ap->NumArgs = k;
3952 if (ap->NumArgs != ap->CallArgs)
3953 ap->Flags |= AMIPRAGFLAG_ARGCOUNT;
3954 else
3955 ap->Flags &= ~AMIPRAGFLAG_ARGCOUNT;
3958 /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
3959 static uint32 GetRegisterData(struct AmiPragma *ap)
3961 /* usage of result:
3962 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
3963 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
3965 register uint32 i, data = 0, reg;
3967 for(i = 0; i < ap->NumArgs; ++i)
3969 if((reg = ap->Args[i].ArgReg) <= REG_FP0)
3971 if(reg >= 10 || (reg >= 2 && reg <= 7)) /* A2-A7 and D2-D7 */
3972 data |= (1 << (reg + 16)) + (1 << (15 - reg));
3975 if(data) /* set A6 only when other register used */
3976 data |= 0x40000002;
3977 return data;
3980 static uint16 GetFRegisterData(struct AmiPragma *ap)
3982 /* usage of result:
3983 F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
3984 F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
3986 register uint32 i, reg;
3987 register uint16 data = 0;
3989 for(i = 0; i < ap->NumArgs; ++i)
3991 if((reg = ap->Args[i].ArgReg) >= REG_FP2)
3993 reg -= REG_FP0;
3994 data |= (1 << (reg + 8)) + (1 << (7 - reg));
3997 return data;
4000 static uint32 OutputXDEF(uint32 offset, strptr format, ...)
4002 uint8 buf[150];
4003 va_list a;
4004 size_t i;
4006 va_start(a, format);
4007 i = vsprintf((strptr)(buf+4), format, a);
4008 va_end(a);
4009 while(i&3)
4010 buf[4+i++] = 0;
4011 EndPutM32(buf+4+i, offset); /* the definition offset */
4013 EndPutM32(buf, (EXT_DEF<<24) + (i>>2));
4015 return DoOutputDirect(buf, i+8);
4018 static uint32 OutputXREF(uint32 offset, uint32 type, strptr format, ...)
4020 uint8 buf[150];
4021 va_list a;
4022 size_t i;
4024 va_start(a, format);
4025 i = vsprintf((strptr)(buf+4), format, a);
4026 va_end(a);
4027 while(i&3)
4028 buf[4+i++] = 0;
4029 EndPutM32(buf+4+i, 1); /* 1 reference */
4030 EndPutM32(buf+8+i, offset); /* the definition offset */
4032 EndPutM32(buf, (type << 24) + (i>>2));
4034 return DoOutputDirect(buf, i+12);
4037 static uint32 OutputXREF2(uint32 offset1, uint32 offset2, uint32 type,
4038 strptr format, ...)
4040 uint8 buf[150];
4041 va_list a;
4042 size_t i;
4044 va_start(a, format);
4045 i = vsprintf((strptr)(buf+4), format, a);
4046 va_end(a);
4047 while(i&3)
4048 buf[4+i++] = 0;
4049 EndPutM32(buf+4+i, 2); /* 2 references */
4050 EndPutM32(buf+8+i, offset1); /* the definition offset */
4051 EndPutM32(buf+12+i, offset2); /* the definition offset */
4053 EndPutM32(buf, (type << 24) + (i>>2));
4055 return DoOutputDirect(buf, i+16);
4058 static uint32 OutputSYMBOL(uint32 offset, strptr format, ...)
4060 va_list a;
4061 uint8 buf[150];
4062 size_t i;
4064 va_start(a, format);
4065 i = vsprintf((strptr)(buf+4), format, a);
4066 va_end(a);
4067 while(i&3)
4068 buf[4+i++] = 0;
4069 EndPutM32(buf+4+i, offset);
4071 EndPutM32(buf, (0 << 24) + (i>>2));
4073 return DoOutputDirect(buf, i+8);
4076 static uint8 *AsmStackCopy(uint8 *data, struct AmiPragma *ap, uint32 flags,
4077 uint32 ofs)
4079 uint32 i, j, k, l, tofs;
4081 if(Flags & FLAG_PASCAL)
4083 k = ap->NumArgs;
4085 while(k)
4087 if(ap->Args[k-1].ArgReg >= REG_FP0)
4089 struct ClibData *cd;
4091 cd = GetClibFunc(ap->FuncName, ap, flags);
4092 EndPutM16Inc(data, 0xF22F); /* FMOVE.? offs(A7),FPx */
4094 if(cd && IsCPPType(&cd->Args[k-1], CPP_TYPE_DOUBLE))
4096 EndPutM16Inc(data, 0x5400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
4097 EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
4098 ofs += 2;
4100 else
4102 if(!cd || !IsCPPType(&cd->Args[k-1], CPP_TYPE_FLOAT))
4103 DoError(ERR_LONG_DOUBLE, ap->Line);
4104 EndPutM16Inc(data, 0x4400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7));
4105 EndPutM16Inc(data, (ofs++) << 2);
4108 else if((k >= 2) && (ap->Args[k-1].ArgReg < ap->Args[k-2].ArgReg)
4109 && ap->Args[k-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4111 l = 0; tofs = ofs;
4114 j = ap->Args[--k].ArgReg;
4116 ++ofs;
4117 l |= 1 << j;
4118 } while(k && j < ap->Args[k-1].ArgReg
4119 && ap->Args[k-1].ArgReg < REG_FP0);
4120 EndPutM16Inc(data, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4121 EndPutM16Inc(data, l);
4122 EndPutM16Inc(data, tofs << 2); /* store start offset */
4124 else
4126 l = 0x202F; /* MOVE.L offs(A7),xxx */
4128 if((j = ap->Args[--k].ArgReg) > 7)
4130 l |= (1<<6); j -= 8; /* set MOVEA bit */
4132 /* set destination register and store */
4133 EndPutM16Inc(data, l | (j << 9));
4134 EndPutM16Inc(data, (ofs++) << 2);
4138 else
4140 i = 0;
4142 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
4144 while(i < k)
4146 if(ap->Args[i].ArgReg >= REG_FP0)
4148 struct ClibData *cd;
4150 cd = GetClibFunc(ap->FuncName, ap, flags);
4151 EndPutM16Inc(data, 0xF22F); /* FMOVE.? offs(A7),FPx */
4153 if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
4155 EndPutM16Inc(data, 0x5400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
4156 EndPutM16Inc(data, ofs<<2); /* one double needs two longs */
4157 ofs += 2;
4159 else
4161 if(!cd || !IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
4162 DoError(ERR_LONG_DOUBLE, ap->Line);
4163 EndPutM16Inc(data, 0x4400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7));
4164 EndPutM16Inc(data, (ofs++) << 2);
4167 else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg)
4168 && ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4170 l = 0; tofs = ofs;
4173 j = ap->Args[i++].ArgReg;
4175 ++ofs;
4176 l |= 1 << j;
4177 } while(i < k && j < ap->Args[i].ArgReg
4178 && ap->Args[i].ArgReg < REG_FP0);
4179 EndPutM16Inc(data, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4180 EndPutM16Inc(data, l); /* Store MOVEM.L data */
4181 EndPutM16Inc(data, tofs << 2); /* store start offset */
4183 else
4185 l = 0x202F; /* MOVE.L offs(A7),xxx */
4187 if((j = ap->Args[i++].ArgReg) > 7)
4189 l |= (1<<6); j -= 8; /* set MOVEA bit */
4191 /* set destination register and store */
4192 EndPutM16Inc(data, l | (j << 9));
4193 EndPutM16Inc(data, (ofs++) << 2);
4197 if(i < ap->NumArgs)
4199 if((j = ap->Args[i].ArgReg) > 7)
4201 EndPutM16Inc(data, 0x41EF | ((j-8) << 9)); /* LEA xxx(A7),Ax */
4202 EndPutM16Inc(data, ofs << 2);
4204 else if(ofs == 2)
4206 EndPutM16Inc(data, 0x200F | (j << 9)); /* MOVE.L A7,Dx */
4207 EndPutM16Inc(data, 0x5080 | j); /* ADDQ.L #8,Dx */
4209 else
4211 EndPutM16Inc(data, 0x486F); /* PEA xxx(A7) */
4212 EndPutM16Inc(data, ofs << 2);
4213 EndPutM16Inc(data, 0x201F | j << 9); /* MOVE.L offs(A7),Dx */
4218 return data;
4220 /* ------------------------------------------------------------------ */
4222 static void DoError(uint32 errnum, uint32 line, ...)
4224 uint32 err = errnum & 0xFFFF;
4225 va_list a;
4227 if(Flags & FLAG_DIDERROR)
4228 return;
4230 if(!Errors[err].Type)
4231 Flags |= FLAG_DIDERROR;
4233 va_start(a, line);
4234 printf((line ? "%s %ld in line %ld%s: " : "%s %ld : "),
4235 (Errors[err].Type ? "Warning" : "Error"), err, line,
4236 errnum & ERROFFSET_CLIB ? " of clib file" : "");
4237 vprintf(Errors[err].Error, a);
4238 printf("\n");
4239 if(line && Errors[err].Skip)
4241 while(*in.pos)
4242 ++in.pos;
4244 va_end(a);
4247 static uint32 CheckError(struct AmiPragma *ap, uint32 errflags)
4249 errflags &= ap->Flags;
4251 if(errflags & AMIPRAGFLAG_ARGCOUNT)
4253 if(!(ap->Flags & AMIPRAGFLAG_DIDARGWARN))
4255 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
4256 ap->Flags |= AMIPRAGFLAG_DIDARGWARN;
4258 return 1;
4260 else if(errflags & AMIPRAGFLAG_FLOATARG)
4262 if(!(ap->Flags & AMIPRAGFLAG_DIDFLOATWARN))
4264 DoError(ERR_FLOATARG_NOT_ALLOWED, ap->Line);
4265 ap->Flags |= AMIPRAGFLAG_DIDFLOATWARN;
4267 return 1;
4269 else if(errflags & AMIPRAGFLAG_A6USE)
4271 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
4272 return 1;
4274 else if(errflags & AMIPRAGFLAG_A5USE)
4276 DoError(ERR_A5_NOT_ALLOWED, ap->Line);
4277 return 1;
4279 else if(errflags & AMIPRAGFLAG_PPC)
4281 if(!(Flags & FLAG_DIDPPCWARN))
4283 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
4284 Flags |= FLAG_DIDPPCWARN;
4286 return 1;
4288 else if(errflags & AMIPRAGFLAG_M68K)
4290 if(!(Flags & FLAG_DIDM68KWARN))
4292 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED, 0/*ap->Line*/);
4293 Flags |= FLAG_DIDM68KWARN;
4295 return 1;
4297 else if(errflags & AMIPRAGFLAG_MOSBASESYSV)
4299 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED, ap->Line);
4300 return 1;
4303 return 0;
4306 static uint32 DoOutput(strptr format, ...)
4308 va_list a;
4310 if(!Output_Error)
4311 return 0;
4313 va_start(a, format);
4314 if(vfprintf(outfile, format, a) < 0)
4315 Output_Error = 1;
4316 va_end(a);
4318 return Output_Error;
4321 static uint32 DoOutputDirect(void * data, size_t size)
4323 if(!Output_Error)
4324 return 0;
4325 if(size)
4327 if(fwrite(data, size, 1, outfile) != 1)
4328 Output_Error = 0;
4330 return Output_Error;
4333 /* ------------------------------------------------------------------ */
4335 static struct ShortList *NewItem(struct ShortListRoot *list)
4337 struct ShortList *item;
4338 if(!list || !list->Size)
4339 return 0;
4340 if(!(item = (struct ShortList *) AllocListMem(list->Size)))
4341 return 0;
4342 return item;
4345 static struct ShortList *RemoveItem(struct ShortListRoot *list,
4346 struct ShortList *item)
4348 struct ShortList *n = list->First;
4350 if(n == item)
4351 list->First = item->Next;
4352 else
4354 while(n && n->Next != item)
4355 n = n->Next;
4356 if(!n)
4357 return 0;
4358 if(!(n->Next = item->Next))
4359 list->Last = n;
4361 item->Next = 0;
4362 return item;
4365 static void AddItem(struct ShortListRoot *list, struct ShortList *item)
4367 if(!list->First)
4368 list->First = list->Last = item;
4369 else
4371 list->Last->Next = item;
4372 list->Last = item;
4376 /* ------------------------------------------------------------------ */
4378 uint32 FuncAMICALL(struct AmiPragma *ap, uint32 flags, strptr name)
4380 uint32 i;
4382 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4383 return 1;
4385 Flags |= FLAG_DONE; /* We did something */
4387 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags & FUNCFLAG_TAG ?
4388 "tagcall" : "amicall", BaseName, ap->Bias, name);
4390 for(i = 0; i < ap->NumArgs; ++i)
4392 DoOutput(RegNames[ap->Args[i].ArgReg]);
4393 if(i+1 < ap->NumArgs)
4394 DoOutput(",");
4397 return DoOutput(/*((*/"))\n");
4400 uint32 FuncLIBCALL(struct AmiPragma *ap, uint32 flags, strptr name)
4402 int32 i;
4404 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4405 return 1;
4407 Flags |= FLAG_DONE; /* We did something */
4409 if(ap->Flags & AMIPRAGFLAG_FLOATARG)
4411 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName, name, ap->Bias);
4412 for(i = ap->NumArgs-1; i >= 0; --i)
4413 DoOutput("%02x", ap->Args[i].ArgReg);
4415 return DoOutput("00%02x\n", ap->NumArgs);
4418 if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase") &&
4419 (flags & FUNCFLAG_NORMAL))
4420 DoOutput("#pragma syscall %-22s %03x ", name, ap->Bias);
4421 else
4422 DoOutput("#pragma %s %s %-22s %03x ", (flags & FUNCFLAG_TAG) ?
4423 "tagcall" : "libcall", BaseName, name, ap->Bias);
4425 for(i = ap->NumArgs-1; i >= 0; --i)
4426 DoOutput("%x", ap->Args[i].ArgReg);
4428 return DoOutput("0%x\n", ap->NumArgs);
4431 uint32 FuncAsmText(struct AmiPragma *ap, uint32 flags, strptr name)
4433 int32 i;
4434 uint32 registers;
4435 uint16 fregs;
4436 uint32 offset = 1;
4437 strptr c1, c2;
4438 struct ClibData *cd;
4440 if(CheckError(ap, AMIPRAGFLAG_PPC))
4441 return 1;
4443 Flags |= FLAG_DONE; /* We did something */
4445 c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
4446 c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
4448 if(Flags & FLAG_SINGLEFILE)
4450 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
4452 if(HEADER)
4454 DoOutput("\n");
4455 DoOutputDirect(HEADER, headersize);
4459 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
4461 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
4462 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
4465 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name, name);
4466 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4468 DoOutput("\tXDEF\t%s\n%s:\n",name, name);
4469 if(clibdata)
4471 if(!ap->NumArgs)
4472 DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
4473 else if((cd = GetClibFunc(name, ap, flags)))
4475 string txt[300];
4476 uint32 i;
4478 for(i = 0; i < COPYCPP_PASSES; ++i)
4480 if(CopyCPPType(txt, i, cd, ap->Args))
4481 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name, txt, name, txt);
4487 if((registers = GetRegisterData(ap) >> 16))
4489 if(Flags & FLAG_NOMOVEM)
4491 for(i = 0; i <= 15; ++i)
4493 if(registers & (1 << i))
4495 ++offset;
4496 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper[i]);
4500 else
4502 uint16 l = registers;
4504 DoOutput("\tMOVEM.L\t");
4506 for(i = 0; i <= 15; ++i)
4508 if(l & (1 << i))
4510 ++offset;
4511 l ^= 1 << i;
4512 DoOutput(RegNamesUpper[i]);
4513 if(l)
4514 DoOutput("/");
4517 DoOutput(",-(A7)\n");
4520 else
4522 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
4525 if((fregs = GetFRegisterData(ap) >> 8))
4527 uint8 l = fregs;
4529 DoOutput("\tFMOVEM.X\t");
4531 for(i = 0; i <= 7; ++i)
4533 if(l & (1 << i))
4535 offset += 3;
4536 l ^= 1 << i;
4537 DoOutput(RegNamesUpper[REG_FP0 + i]);
4538 if(l)
4539 DoOutput("/");
4542 DoOutput(",-(A7)\n");
4545 if(Flags & FLAG_SMALLDATA)
4547 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1, BaseName, c2);
4549 else
4550 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName);
4552 if(!(Flags & FLAG_PASCAL))
4554 int32 k;
4556 k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
4558 for(i = 0; i < k;)
4560 if(ap->Args[i].ArgReg >= REG_FP0)
4562 uint32 t;
4563 struct ClibData *cd;
4565 cd = GetClibFunc(name, ap, flags);
4566 if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
4567 t = CPP_TYPE_DOUBLE;
4568 else if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
4569 t = CPP_TYPE_FLOAT;
4570 else
4572 DoError(ERR_LONG_DOUBLE, ap->Line);
4573 t = CPP_TYPE_FLOAT;
4576 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE
4577 ? 'D' : 'S', c1, offset<<2, c2, RegNamesUpper[ap->Args[i++].ArgReg]);
4579 if(t == CPP_TYPE_DOUBLE)
4580 ++offset;
4581 ++offset;
4583 else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg) &&
4584 ap->Args[i+1].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4586 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
4587 RegNamesUpper[ap->Args[i++].ArgReg]);
4591 DoOutput("/%s", RegNamesUpper[ap->Args[i++].ArgReg]);
4592 ++offset;
4593 } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg) &&
4594 ap->Args[i].ArgReg < REG_FP0);
4595 DoOutput("\n");
4597 else
4599 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4600 ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
4601 RegNamesUpper[ap->Args[i].ArgReg]);
4602 ++i;
4606 if(i < ap->NumArgs)
4608 if(ap->Args[i].ArgReg > 7)
4609 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1, offset<<2, c2,
4610 RegNamesUpper[ap->Args[i].ArgReg]);
4611 else if(offset <= 2)
4612 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4613 RegNamesUpper[ap->Args[i].ArgReg],offset<<2,
4614 RegNamesUpper[ap->Args[i].ArgReg]);
4615 else
4616 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1,
4617 offset<<2, c2,RegNamesUpper[ap->Args[i].ArgReg]);
4620 else
4622 i = ap->NumArgs;
4624 while(i)
4626 if(ap->Args[i-1].ArgReg >= REG_FP0)
4628 uint32 t;
4629 struct ClibData *cd;
4631 cd = GetClibFunc(name, ap, flags);
4633 if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_DOUBLE))
4634 t = CPP_TYPE_DOUBLE;
4635 else if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_FLOAT))
4636 t = CPP_TYPE_FLOAT;
4637 else
4639 DoError(ERR_LONG_DOUBLE, ap->Line);
4640 t = CPP_TYPE_FLOAT;
4643 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t == CPP_TYPE_DOUBLE ?
4644 'D' : 'S', c1, offset<<2, c2, RegNamesUpper[ap->Args[--i].ArgReg]);
4645 if(t == CPP_TYPE_DOUBLE)
4646 ++offset;
4647 ++offset;
4649 else if((i >= 2) && (ap->Args[i-1].ArgReg < ap->Args[i-2].ArgReg) &&
4650 ap->Args[i-2].ArgReg < REG_FP0 && !(Flags & FLAG_NOMOVEM))
4652 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1, (offset++)<<2, c2,
4653 RegNamesUpper[ap->Args[--i].ArgReg]);
4657 DoOutput("/%s", RegNamesUpper[ap->Args[--i].ArgReg]);
4658 ++offset;
4659 } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg) &&
4660 ap->Args[i-1].ArgReg < REG_FP0);
4661 DoOutput("\n");
4663 else
4665 --i;
4666 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4667 ap->Args[i].ArgReg >= REG_A0 ? "A" : "", c1, (offset++)<<2, c2,
4668 RegNamesUpper[ap->Args[i].ArgReg]);
4673 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1, ap->Bias, c2);
4675 if(fregs)
4677 DoOutput("\tFMOVEM.X\t(A7)+,");
4679 for(i = 0; i <= 7; ++i)
4681 if(fregs & (1 << i))
4683 fregs ^= 1 << i;
4684 DoOutput(RegNamesUpper[REG_FP0 + i]);
4685 if(fregs)
4686 DoOutput("/");
4689 DoOutput("\n");
4692 if(registers)
4694 if(Flags & FLAG_NOMOVEM)
4696 for(i = 15; i >= 0; --i)
4698 if(registers & (1 << i))
4699 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i >= REG_A0 ? "A" : "",
4700 RegNamesUpper[i]);
4703 else
4705 DoOutput("\tMOVEM.L\t(A7)+,");
4707 for(i = 0; i <= 15; ++i)
4709 if(registers & (1 << i))
4711 registers ^= 1 << i;
4712 DoOutput(RegNamesUpper[i]);
4713 if(registers)
4714 DoOutput("/");
4717 DoOutput("\n");
4720 else
4721 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4723 return DoOutput("\tRTS\n");
4726 uint32 FuncAsmCode(struct AmiPragma *ap, uint32 flags, strptr name)
4728 uint32 registers, offset = 1, baseref;
4729 size_t i;
4730 uint8 *data;
4731 uint16 fregs;
4733 if(CheckError(ap, AMIPRAGFLAG_PPC))
4734 return 1;
4736 Flags |= FLAG_DONE; /* We did something */
4738 registers = GetRegisterData(ap);
4739 fregs = GetFRegisterData(ap);
4741 i = strlen(name) + 2;
4742 EndPutM32(tempbuf, HUNK_UNIT);
4743 EndPutM32(tempbuf+4, (i+3)>>2);
4744 DoOutputDirect(tempbuf, 8);
4745 DoOutput("%s.o", name);
4746 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
4748 i = strlen(hunkname);
4749 EndPutM32(tempbuf, HUNK_NAME);
4750 EndPutM32(tempbuf+4, (i + 3)>>2);
4751 DoOutputDirect(tempbuf, 8);
4752 DoOutputDirect(hunkname, i);
4753 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
4755 data = tempbuf+8; /* we need HUNK_CODE + size at start */
4757 if(!registers)
4759 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
4760 ++offset; /* one long more on stack */
4762 else
4764 if(Flags & FLAG_NOMOVEM)
4766 for(i = 0; i <= 15; ++i)
4768 if(registers & (1<< (16+i)))
4770 EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
4771 ++offset;
4775 else
4777 uint32 l;
4778 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
4779 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
4780 for(l = (uint16) registers; l; l >>= 1)
4782 if(l & 1)
4783 ++offset; /* get offset addition */
4788 if(fregs)
4790 uint32 l;
4791 EndPutM16Inc(data, 0xF227); /* FMOVEM.X xxx,-(A7) */
4792 EndPutM16Inc(data, 0xE000 + ((fregs>>8)&0xFF));
4793 for(l = (uint8) fregs; l; l >>= 1)
4795 if(l & 1)
4796 offset+=3; /* get offset addition */
4800 baseref = (data-tempbuf)-8+2; /* one word later (MOVE) - 2 header longs */
4801 if(Flags & FLAG_SMALLDATA)
4803 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
4804 EndPutM16Inc(data, 0); /* place for base reference */
4806 else
4808 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
4809 EndPutM32Inc(data, 0); /* place for base reference */
4812 data = AsmStackCopy(data, ap, flags, offset);
4814 /* here comes the base reference */
4815 EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
4816 EndPutM16Inc(data, -ap->Bias); /* JSR offset */
4818 if(fregs)
4820 EndPutM16Inc(data, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4821 EndPutM16Inc(data, 0xD000 + (fregs&0xFF));
4824 if(registers)
4826 if(Flags & FLAG_NOMOVEM)
4828 int32 i;
4829 for(i = 15; i >= 0; --i)
4831 if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
4832 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
4835 else
4837 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4838 EndPutM16Inc(data, (registers >> 16)); /* store MOVEM.L registers */
4841 else
4842 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
4843 EndPutM16Inc(data, 0x4E75); /* RTS */
4845 EndPutM16Inc(data, 0); /* get longword assignment if not yet */
4847 EndPutM32(tempbuf, HUNK_CODE);
4848 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
4849 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
4851 EndPutM32(tempbuf, HUNK_EXT);
4852 DoOutputDirect(tempbuf, 4);
4854 OutputXREF(baseref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32),
4855 "_%s", BaseName);
4856 /* here come the XDEF name references */
4857 OutputXDEF(0, "_%s", name); /* C name */
4859 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4861 struct ClibData *cd;
4862 OutputXDEF(0, "%s", name); /* ASM name */
4864 if(clibdata)
4866 if(!ap->NumArgs)
4867 OutputXDEF(0, "%s_", name); /* C++ name no parameters */
4868 else if((cd = GetClibFunc(name, ap, flags)))
4870 for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
4872 if(CopyCPPType((strptr)tempbuf, i, cd, ap->Args))
4873 OutputXDEF(0, "%s__%s", name, tempbuf);
4879 EndPutM32(tempbuf, 0);
4880 DoOutputDirect(tempbuf, 4);
4881 if(!(Flags & FLAG_NOSYMBOL))
4883 EndPutM32(tempbuf, HUNK_SYMBOL);
4884 DoOutputDirect(tempbuf, 4);
4885 OutputSYMBOL(0, "_%s", name); /* C name */
4887 if(!(Flags & (FLAG_PASCAL|FLAG_ONLYCNAMES)))
4889 struct ClibData *cd;
4890 OutputSYMBOL(0, "%s", name); /* ASM name */
4892 if(clibdata)
4894 if(!ap->NumArgs)
4895 OutputSYMBOL(0, "%s_", name); /* C++ name no parameters */
4896 else if((cd = GetClibFunc(name, ap, flags)))
4898 for(i = 0; i < COPYCPP_PASSES; ++i) /* C++ name with parameters */
4900 if(CopyCPPType((strptr) data, i, cd, ap->Args))
4901 OutputSYMBOL(0, "%s__%s", name, (strptr) data);
4907 EndPutM32(tempbuf, 0);
4908 DoOutputDirect(tempbuf, 4);
4911 EndPutM32(tempbuf, HUNK_END);
4912 return DoOutputDirect(tempbuf, 4);
4915 /* Directly called by FuncInline and FuncInlineDirect also! */
4916 uint32 FuncCSTUBS(struct AmiPragma *ap, uint32 flags, strptr name)
4918 struct ClibData *f, *t;
4919 strptr ret = "return ";
4920 int32 i;
4922 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
4923 return 1;
4925 Flags |= FLAG_DONE; /* We did something */
4927 if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
4928 return 1;
4929 t = GetClibFunc(name, ap, flags);
4931 if(flags & FUNCFLAG_EXTENDMODE)
4933 sprintf(tempbuf, "___%s", name);
4934 name = tempbuf;
4937 if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
4938 ret = "";
4940 if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
4941 return 0;
4942 if(flags & FUNCFLAG_EXTENDMODE)
4944 DoOutput("%s %s, ", GetBaseType(), BaseName);
4947 for(i = 0; i < ap->NumArgs-1; i++)
4949 if(!OutClibType(&f->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4950 return 0;
4952 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4954 if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
4955 return 0;
4957 else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
4958 return 0;
4960 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret, ap->FuncName))
4961 return 0;
4962 for(i = 0; i < ap->NumArgs-1; i++)
4964 if(!DoOutput("%s, ", ap->Args[i].ArgName))
4965 return 0;
4967 if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
4968 return 0;
4970 if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
4972 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
4973 return 0;
4975 else if(ap->NumArgs == 1)
4977 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4978 return 0;
4980 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4981 ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(&f->Args[ap->NumArgs-2],0)
4982 || !DoOutput(/*(((*/")));\n}\n\n"))
4983 return 0;
4984 return 1;
4987 uint32 FuncLVOXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
4989 Flags |= FLAG_DONE; /* We did something */
4990 return DoOutput("\t\tXDEF\t_LVO%s\n", name);
4993 uint32 FuncLVO(struct AmiPragma *ap, uint32 flags, strptr name)
4995 Flags |= FLAG_DONE; /* We did something */
4996 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name, ap->Bias);
4999 uint32 FuncLVOPPCXDEF(struct AmiPragma *ap, uint32 flags, strptr name)
5001 Flags |= FLAG_DONE; /* We did something */
5002 return DoOutput("\t.globl\t%sLVO%s\n", Flags & FLAG_ABIV4 ? "" : "_", name);
5005 uint32 FuncLVOPPC(struct AmiPragma *ap, uint32 flags, strptr name)
5007 Flags |= FLAG_DONE; /* We did something */
5008 return DoOutput(".set\t%sLVO%s,-%d\n", Flags & FLAG_ABIV4 ? "" : "_", name,
5009 ap->Bias);
5012 uint32 FuncLVOPPCBias(struct AmiPragma *ap, uint32 flags, strptr name)
5014 Flags |= FLAG_DONE; /* We did something */
5016 EndPutM32Inc(elfbufpos, symoffset); /* st_name */
5017 symoffset += strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1) + 1;
5018 EndPutM32Inc(elfbufpos, -ap->Bias); /* st_value */
5019 EndPutM32Inc(elfbufpos, 0); /* st_size */
5020 *(elfbufpos++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* st_info */
5021 *(elfbufpos++) = 0; /* st_other */
5022 EndPutM16Inc(elfbufpos, SHN_ABS); /* st_shndx */
5024 return 1;
5027 uint32 FuncLVOPPCName(struct AmiPragma *ap, uint32 flags, strptr name)
5029 Flags |= FLAG_DONE; /* We did something */
5030 DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
5031 return DoOutputDirect("", 1);
5034 uint32 FuncLVOLib(struct AmiPragma *ap, uint32 flags, strptr name)
5036 uint32 j;
5038 Flags |= FLAG_DONE; /* We did something */
5039 j = strlen(name) + 3 + (Flags & FLAG_ABIV4 ? 0 : 1);
5040 EndPutM32(tempbuf, (EXT_ABS << 24) + ((j+3)>>2));
5042 DoOutputDirect(tempbuf, 4);
5043 DoOutput("%sLVO%s", Flags & FLAG_ABIV4 ? "" : "_", name);
5044 DoOutputDirect("\0\0\0", ((j+3)&(~3))-j);
5045 EndPutM32(tempbuf, -ap->Bias);
5046 return DoOutputDirect(tempbuf, 4);
5049 uint32 FuncLocCode(struct AmiPragma *ap, uint32 flags, strptr name)
5051 strptr str2 = Flags & FLAG_LOCALREG ? "rE" : "";
5052 uint8 *data;
5053 int32 i;
5054 struct ClibData *cd = 0;
5056 if(CheckError(ap, AMIPRAGFLAG_PPC))
5057 return 1;
5059 Flags |= FLAG_DONE; /* We did something */
5061 i = strlen(name) + 2;
5062 EndPutM32(tempbuf, HUNK_UNIT);
5063 EndPutM32(tempbuf+4, (i+3)>>2);
5064 DoOutputDirect(tempbuf, 8);
5065 DoOutput("%s.o", name);
5066 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
5068 i = strlen(hunkname);
5069 EndPutM32(tempbuf, HUNK_NAME);
5070 EndPutM32(tempbuf+4, (i + 3)>>2);
5071 DoOutputDirect(tempbuf, 8);
5072 DoOutputDirect(hunkname, i);
5073 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
5075 data = tempbuf+8; /* we need HUNK_CODE + size at start */
5077 if(Flags & FLAG_LOCALREG)
5079 if((flags & FUNCFLAG_TAG))
5081 i = ap->Args[ap->NumArgs-1].ArgReg;
5082 EndPutM16Inc(data, 0x2F00 + i); /* MOVE <ea>,-(A7) */
5084 if(i > 7)
5086 EndPutM16Inc(data, 0x41EF | ((i-8) << 9)); /* LEA 8(A7),Ax */
5087 EndPutM16Inc(data, 8);
5089 else
5091 EndPutM16Inc(data, 0x200F | (i << 9)); /* MOVE.L A7,Dx */
5092 EndPutM16Inc(data, 0x5080 | i); /* ADDQ.L #8,Dx */
5095 EndPutM16Inc(data, 0x4EAE);
5096 EndPutM16Inc(data, -ap->Bias); /* JSR instruction */
5098 /* MOVE (A7)+,<ea> */
5099 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
5100 EndPutM16Inc(data, 0x4E75); /* RTS */
5102 else
5104 EndPutM16Inc(data, 0x4EEE);
5105 EndPutM16Inc(data, -ap->Bias); /* JMP instruction */
5108 else
5110 uint32 registers, offset = 1;
5112 registers = GetRegisterData(ap);
5114 if(!registers) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5116 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
5117 ++offset; /* one long more on stack */
5119 else
5121 if(Flags & FLAG_NOMOVEM)
5123 for(i = 0; i <= 15; ++i)
5125 if(registers & (1<< (16+i)))
5127 EndPutM16Inc(data, 0x2F00 + i); /* MOVE.L xxx,-(A7) */
5128 ++offset;
5132 else
5134 EndPutM16Inc(data, 0x48E7); /* MOVEM.L xxx,-(A7) */
5135 EndPutM16Inc(data, registers); /* store MOVEM.L registers */
5136 for(i = registers&0xFFFF; i; i >>= 1)
5138 if(i & 1)
5139 ++offset; /* get offset addition */
5144 if(!(ap->Flags & AMIPRAGFLAG_A6USE)) /* store library base in A6 */
5146 EndPutM16Inc(data, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5147 EndPutM16Inc(data, (offset++) << 2);
5150 data = AsmStackCopy(data, ap, flags, offset);
5152 /* here comes the base reference */
5153 EndPutM16Inc(data, 0x4EAE); /* JSR xxx(A6) */
5154 EndPutM16Inc(data, -ap->Bias); /* JSR offset */
5155 if(registers)
5157 if(Flags & FLAG_NOMOVEM)
5159 for(i = 15; i >= 0; --i)
5161 if(registers & (1<<(16+i))) /* MOVE.L (A7)+,xxx */
5162 EndPutM16Inc(data, 0x201F + ((i&7)<<9) + ((i>>3)<<6));
5165 else
5167 EndPutM16Inc(data, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5168 EndPutM16Inc(data, registers >> 16); /* store MOVEM.L registers */
5171 else
5172 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
5174 EndPutM16Inc(data, 0x4E75); /* RTS */
5177 EndPutM16Inc(data, 0); /* get longword assignment if not yet */
5179 EndPutM32(tempbuf, HUNK_CODE);
5180 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
5181 DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
5183 EndPutM32(tempbuf, HUNK_EXT);
5184 DoOutputDirect(tempbuf,4);
5186 /* here come the XDEF name references */
5188 if(!(Flags & FLAG_ONLYCNAMES))
5190 OutputXDEF(0, "%s", name); /* ASM names */
5191 OutputXDEF(0, "LOC_%s", name);
5194 OutputXDEF(0, "_%s", name); /* C names */
5195 OutputXDEF(0, "_LOC_%s", name);
5197 if(clibdata && !(Flags & FLAG_ONLYCNAMES))
5199 if(!ap->NumArgs)
5201 /* C++ names no parameters */
5202 OutputXDEF(0, "%s__%sP07Library", name, str2);
5203 OutputXDEF(0, "LOC_%s__%sP07Library", name, str2);
5205 else if((cd = GetClibFunc(name, ap, flags)))
5207 strptr txt;
5209 txt = (strptr) tempbuf;
5211 for(i = 0; i < COPYCPP_PASSES; ++i)
5213 if(CopyCPPType(txt, i, cd, ap->Args))
5214 { /* C++ names with parameters */
5215 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5217 OutputXDEF(0, "%s__%sP07Library%s", name, str2, txt);
5218 OutputXDEF(0, "LOC_%s__%sP07Library%s", name, str2, txt);
5220 else
5222 OutputXDEF(0, "%s__%s", name, txt);
5223 OutputXDEF(0, "LOC_%s__%s", name, txt);
5230 EndPutM32(tempbuf, 0);
5231 DoOutputDirect(tempbuf,4);
5232 if(!(Flags & FLAG_NOSYMBOL))
5234 EndPutM32(tempbuf, HUNK_SYMBOL);
5235 DoOutputDirect(tempbuf,4);
5236 if(!(Flags & FLAG_ONLYCNAMES))
5238 OutputSYMBOL(0, "%s", name); /* ASM names */
5239 OutputSYMBOL(0, "LOC_%s", name);
5242 OutputSYMBOL(0, "_%s", name); /* C names */
5243 OutputSYMBOL(0, "_LOC_%s", name);
5245 if(clibdata && !(Flags & FLAG_ONLYCNAMES))
5247 if(!ap->NumArgs)
5249 /* C++ names no parameters */
5250 OutputSYMBOL(0, "%s__%sP07Library", name, str2);
5251 OutputSYMBOL(0, "LOC_%s__%sP07Library", name, str2);
5253 else if(cd)
5255 strptr txt;
5257 txt = (strptr) tempbuf;
5259 for(i = 0; i < COPYCPP_PASSES; ++i)
5261 if(CopyCPPType(txt, i, cd, ap->Args))
5262 { /* C++ names with parameters */
5263 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5265 OutputSYMBOL(0, "%s__%sP07Library%s", name, str2, txt);
5266 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name, str2, txt);
5268 else
5270 OutputSYMBOL(0, "%s__%s", name, txt);
5271 OutputSYMBOL(0, "LOC_%s__%s", name, txt);
5278 EndPutM32(tempbuf, 0);
5279 DoOutputDirect(tempbuf,4);
5281 EndPutM32(tempbuf, HUNK_END);
5282 return DoOutputDirect(tempbuf,4);
5285 uint32 FuncLocText(struct AmiPragma *ap, uint32 flags, strptr name)
5287 struct ClibData *cd;
5288 int32 i;
5290 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5291 return 1;
5293 Flags |= FLAG_DONE; /* We did something */
5295 if(!(cd = GetClibFunc(name, ap, flags)))
5296 return 1;
5298 OutClibType(&cd->ReturnType, 0);
5299 DoOutput(" LOC_%s("/*)*/, name);
5300 if(!(ap->Flags & AMIPRAGFLAG_A6USE))
5302 if(Flags & FLAG_LOCALREG)
5303 DoOutput("register __a6 ");
5304 DoOutput("%s libbase", GetBaseType());
5305 if(ap->NumArgs)
5306 DoOutput(", ");
5309 if(ap->NumArgs)
5311 for(i = 0; i < ap->NumArgs-1; i++)
5313 if(((Flags & FLAG_LOCALREG &&
5314 !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
5315 !OutClibType(&cd->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
5316 return 0;
5319 if(flags & FUNCFLAG_NORMAL)
5321 if(((Flags & FLAG_LOCALREG &&
5322 !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
5323 !OutClibType(&cd->Args[i], ap->Args[i].ArgName) ||
5324 !DoOutput(/*(*/");\n"))
5325 return 0;
5326 if(BaseName)
5328 DoOutput("#define %s("/*)*/, name);
5329 for(i = 0; i < ap->NumArgs-1; ++i)
5330 DoOutput("%c, ", 'a'+(char)i);
5331 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i, name, BaseName);
5332 for(i = 0; i < ap->NumArgs-1; ++i)
5333 DoOutput("%c, ",'a'+(char)i);
5334 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i);
5337 else
5338 return DoOutput(/*(*/"...);\n");
5340 else if(BaseName)
5341 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5342 name, name);
5343 else
5344 return DoOutput(/*(*/");\n");
5345 return 1;
5348 uint32 FuncInlineDirect(struct AmiPragma *ap, uint32 flags, strptr name)
5350 uint32 a4 = 0, a5 = 0;
5351 int32 noret = 0;
5352 int32 i, maxargs, reg=0;
5353 struct ClibData *cd;
5355 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC|AMIPRAGFLAG_VARARGS))
5356 return 1;
5358 Flags |= FLAG_DONE; /* We did something */
5360 if(flags & FUNCFLAG_ALIAS)
5362 if(flags & FUNCFLAG_TAG)
5363 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5364 name, ap->TagName);
5366 DoOutput("#define %s("/*)*/, name);
5367 for(i = 0; i < ap->NumArgs-1; ++i)
5368 DoOutput("%s, ", ap->Args[i].ArgName);
5369 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
5370 for(i = 0; i < ap->NumArgs-1; ++i)
5371 DoOutput("(%s), ", ap->Args[i].ArgName);
5372 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
5375 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
5376 return 1;
5378 if(flags & FUNCFLAG_TAG)
5380 /* do not create some strange functions */
5381 if(IsNoCreateInlineFunc(name))
5382 DoOutput("#if !defined(NO_INLINE_STDARG) "
5383 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5384 else
5385 DoOutput("#ifndef NO_INLINE_STDARG\n");
5386 DoOutput("static __inline__ ");
5387 FuncCSTUBS(ap, flags|FUNCFLAG_EXTENDMODE, name);
5389 DoOutput("#define %s("/*)*/, name);
5390 for(i = 0; i < ap->NumArgs-1; ++i)
5392 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->NumArgs-2 ? ", " : "");
5394 if(ap->NumArgs < 2)
5395 DoOutput("tags");
5396 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name, ShortBaseNameUpper);
5397 for(i = 0; i < ap->NumArgs-1; ++i)
5398 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->NumArgs-2 ? ", " : "");
5399 if(ap->NumArgs < 2)
5400 DoOutput("tags");
5401 DoOutput(/*(*/")\n");
5402 return DoOutput("#endif\n\n");
5405 DoOutput("#define %s("/*)*/, name);
5406 if(ap->NumArgs)
5408 for(i = 0; i < ap->NumArgs-1; ++i)
5409 DoOutput("%s, ", ap->Args[i].ArgName);
5410 DoOutput("%s", ap->Args[i].ArgName);
5412 DoOutput(/*(*/") ({ \\\n"/*})*/);
5414 for(i = 0; i < ap->NumArgs; ++i)
5416 sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
5417 DoOutput(" ");
5418 OutClibType(&cd->Args[i], (strptr) tempbuf);
5419 DoOutput(" = (%s); \\\n", ap->Args[i].ArgName);
5422 if(Flags & FLAG_INLINENEW)
5424 if(ap->NumArgs)
5425 DoOutput(" ({ \\\n"/*})*/);
5426 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name);
5427 if(BaseName)
5428 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper);
5429 else
5431 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
5433 if(i == ap->NumArgs)
5434 return 1;
5435 DoOutput("(%s);\\\n", ap->Args[i].ArgName);
5438 DoOutput(" (("/*))*/);
5439 OutClibType(&cd->ReturnType, 0);
5440 DoOutput(" (*)("/*)*/);
5441 if(BaseName)
5443 DoOutput("char * __asm(\"a6\")");
5444 if(ap->NumArgs)
5445 DoOutput(", ");
5447 for(i = 0; i < ap->NumArgs; ++i)
5449 OutClibType(&cd->Args[i], 0);
5450 DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
5451 if(i < ap->NumArgs-1)
5452 DoOutput(", ");
5454 DoOutput(/*((*/")) \\\n");
5455 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name, ap->Bias);
5456 if(BaseName)
5458 DoOutput("_%s__bn", name);
5459 if(ap->NumArgs)
5460 DoOutput(", ");
5462 for(i = 0; i < ap->NumArgs; ++i)
5464 if(ap->Args[i].ArgReg == REG_A6)
5465 DoOutput("_%s__bn", name);
5466 else
5467 DoOutput("_%s_%s", name, ap->Args[i].ArgName);
5468 if(i < ap->NumArgs-1)
5469 DoOutput(", ");
5471 DoOutput(/*(*/"); \\\n");
5472 if(ap->NumArgs)
5473 DoOutput(/*({*/"});");
5475 else
5477 /* do A5 first, as it is more important */
5478 if(ap->Flags & AMIPRAGFLAG_A5USE)
5480 a5 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5481 for(i = 0; i < ap->NumArgs; ++i)
5482 a5 |= 1<<ap->Args[i].ArgReg;
5483 a5 &= 0xFFF;
5484 if(a5 == 0xFFF)
5486 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A5]);
5487 a5 = 0;
5489 else
5491 for(i = 0; (a5 & 1) && a5; ++i)
5492 a5 >>= 1;
5493 a5 = i; /* this is our A5 swap register */
5496 if(ap->Flags & AMIPRAGFLAG_A4USE)
5498 a4 = 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5499 if(a5)
5500 a4 |= (1<<a5);
5501 for(i = 0; i < ap->NumArgs; ++i)
5502 a4 |= 1<<ap->Args[i].ArgReg;
5503 a4 &= 0xFFF;
5504 if(a4 == 0xFFF)
5506 DoError(ERR_INLINE_AX_SWAPREG, ap->Line, RegNamesUpper[REG_A4]);
5507 a4 = 0;
5509 else
5511 for(i = 0; (a4 & 1) && a4; ++i)
5512 a4 >>= 1;
5513 a4 = i; /* this is our A4 swap register */
5516 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5517 noret = 1; /* this is a void function */
5519 if(ap->NumArgs || !noret)
5520 DoOutput(" %s{ \\\n", noret ? "" : "(" /*})*/);
5522 if(noret)
5523 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5524 DoOutput(
5525 " register int _d1 __asm(\"d1\"); \\\n"
5526 " register int _a0 __asm(\"a0\"); \\\n"
5527 " register int _a1 __asm(\"a1\"); \\\n");
5529 if(BaseName)
5530 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5531 GetBaseType(), name, ShortBaseNameUpper);
5533 if(!noret)
5535 sprintf((strptr)tempbuf, "__%s__re", name);
5536 DoOutput(" register ");
5537 OutClibType(&cd->ReturnType, (strptr) tempbuf);
5538 DoOutput(" __asm(\"d0\"); \\\n");
5540 if((maxargs = ap->NumArgs) >= 9 && (Flags & FLAG_STORMGCC))
5541 maxargs = 7;
5542 for(i = 0; i < maxargs; ++i)
5544 reg = ap->Args[i].ArgReg;
5545 if(a5 && reg == REG_A5) reg = a5; /* we need to switch */
5546 if(a4 && reg == REG_A4) reg = a4; /* we need to switch */
5548 sprintf((strptr)tempbuf, "__%s_%s", name, ap->Args[i].ArgName);
5549 DoOutput(" register ");
5550 OutClibType(&cd->Args[i], (strptr) tempbuf);
5551 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames[reg],
5552 (strptr) (tempbuf+1));
5554 if(i != ap->NumArgs) /* StormGCC mode */
5556 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name);
5557 for(i = maxargs; i < ap->NumArgs; ++i)
5559 DoOutput(" ULONG __%s_%s; \\\n", name, ap->Args[i].ArgName);
5560 reg = ap->Args[i].ArgReg;
5561 if(reg == REG_A4)
5563 reg = a4; a4 = 0;
5565 else if(reg == REG_A5)
5567 reg = a5; a5 = 0;
5570 /* reg is now either the last register argument or its a4/a5 redirect */
5571 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name);
5572 for(i = maxargs; i < ap->NumArgs; ++i)
5574 sprintf((strptr)tempbuf, "_%s_%s", name, ap->Args[i].ArgName);
5575 DoOutput("(ULONG)(%s)%s", (strptr)tempbuf, i == ap->NumArgs-1 ?
5576 "" : ", ");
5578 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5579 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name, name,
5580 RegNames[reg], name);
5582 DoOutput(" __asm volatile (\""/*)*/);
5583 if(a5) DoOutput("exg a5,%s\\n\\t", RegNames[a5]);
5584 if(a4) DoOutput("exg a4,%s\\n\\t", RegNames[a4]);
5585 if(maxargs != ap->NumArgs) /* StormGCC mode */
5587 DoOutput("movem.l ");
5588 for(i = maxargs; i < ap->NumArgs; ++i)
5590 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg],
5591 i == ap->NumArgs-1 ? "" : "/");
5593 DoOutput(",-(a7)\\n\\t");
5594 for(i = maxargs; i < ap->NumArgs; ++i)
5596 if(i == maxargs)
5597 DoOutput("move.l (%s),%s\\n\\t", RegNames[reg],
5598 RegNames[ap->Args[i].ArgReg]);
5599 else
5600 DoOutput("move.l %ld(%s),%s\\n\\t", (i-maxargs)*4, RegNames[reg],
5601 RegNames[ap->Args[i].ArgReg]);
5604 DoOutput("jsr a6@(-%d:W)", ap->Bias);
5605 if(maxargs != ap->NumArgs) /* StormGCC mode */
5607 DoOutput("\\n\\tmovem.l (a7)+,");
5608 for(i = maxargs; i < ap->NumArgs; ++i)
5610 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg],
5611 i == ap->NumArgs-1 ? "" : "/");
5614 if(a4) DoOutput("\\n\\texg a4,%s", RegNames[a4]);
5615 if(a5) DoOutput("\\n\\texg a5,%s", RegNames[a5]);
5616 DoOutput("\" \\\n");
5618 if(noret)
5619 DoOutput(" : \"=r\" (_d0)");
5620 else
5621 DoOutput(" : \"=r\"(__%s__re)", name);
5622 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5623 if(BaseName)
5624 DoOutput(" \"r\"(__%s__bn)%s", name, ap->NumArgs ? "," : "");
5625 for(i = 0; i < maxargs; ++i)
5627 DoOutput(" \"rf\"(__%s_%s)", name, ap->Args[i].ArgName);
5628 if(i < ap->NumArgs-1)
5629 DoOutput(",");
5631 if(i != ap->NumArgs) /* StormGCC mode */
5632 DoOutput(" \"r\"(__%s__ArgsPtr)", name);
5633 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5635 if(ap->NumArgs || !noret)
5636 DoOutput(/*({*/" }%s \\\n", noret ? "" : ");");
5639 return DoOutput(/*({*/"})\n\n");
5642 uint32 FuncInline(struct AmiPragma *ap, uint32 flags, strptr name)
5644 uint32 noret = 0, a45 = 0, j;
5645 int32 fp = -1, i;
5646 struct ClibData *cd;
5648 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
5649 return 1;
5651 if(!(Flags & FLAG_INLINENEW) && CheckError(ap, AMIPRAGFLAG_MOSBASESYSV))
5652 return 1;
5654 Flags |= FLAG_DONE; /* We did something */
5656 if(flags & FUNCFLAG_ALIAS)
5658 if(flags & FUNCFLAG_TAG)
5659 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5660 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
5662 DoOutput("#define %s("/*)*/, name);
5663 for(i = 0; i < ap->NumArgs-1; ++i)
5664 DoOutput("%s, ", ap->Args[i].ArgName);
5665 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
5666 for(i = 0; i < ap->NumArgs-1; ++i)
5667 DoOutput("(%s), ", ap->Args[i].ArgName);
5668 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
5671 if(!(cd = GetClibFunc(ap->Flags & AMIPRAGFLAG_VARARGS ?
5672 ap->TagName : ap->FuncName, ap, flags)))
5673 return 1;
5675 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5676 noret = 1; /* this is a void function */
5678 if(ap->Flags & AMIPRAGFLAG_A5USE)
5679 a45 = REG_A5;
5680 if(ap->Flags & AMIPRAGFLAG_A4USE)
5682 if(a45)
5684 DoError(ERR_INLINE_A4_AND_A5, ap->Line);
5685 return 1; /* skip this entry */
5687 a45 = REG_A4;
5689 if(a45 && (ap->Flags & AMIPRAGFLAG_D7USE))
5691 DoError(ERR_INLINE_D7_AND_A45, ap->Line);
5692 return 1; /* skip this entry */
5695 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_MOSBASESYSV))
5697 if(Flags & FLAG_INLINENEW)
5699 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5700 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "");
5701 if(IsNoCreateInlineFunc(name))
5703 DoOutput("__inline ");
5704 FuncCSTUBS(ap, flags, name);
5705 /* call CSTUBS, as this equals the method used there */
5707 else
5709 DoOutput("#define %s("/*)*/, name);
5710 for(i = 0; i < ap->NumArgs-1; ++i)
5712 DoOutput("%s, ", ap->Args[i].ArgName);
5714 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5715 ap->FuncName);
5716 for(i = 0; i < ap->NumArgs-1; ++i)
5717 DoOutput("(%s), ", ap->Args[i].ArgName);
5718 DoOutput("("/*)*/);
5719 OutClibType(&cd->Args[i], 0);
5720 DoOutput(/*({((*/") _tags);})\n");
5722 return DoOutput("#endif\n\n");
5724 else if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS))
5725 == (FLAG_INLINESTUB|FLAG_MORPHOS))
5727 int32 n, d, tagl, local;
5729 n = 9-ap->NumArgs;
5730 d = n & 1 ? 4 : 0;
5731 tagl = 8 + (Flags2 & FLAG2_DIRECTVARARGS ? 0 : 64);
5732 local = (n * 4+d+8+15) & ~15; /* size of the stack frame */
5734 /* Stack frame:
5735 * 0- 3: next frame ptr
5736 * 4- 7: save lr
5737 * 8-71: struct Caos
5738 * 72-72+n*4+d+8-1: tag list start
5739 * ?-local-1: padding
5742 DoOutput("asm(\"\n"/*)*/
5743 "\t.align\t2\n"
5744 "\t.globl\t%s\n"
5745 "\t.type\t%s,@function\n"
5746 "%s:\n"
5747 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5748 "\tmflr\t0\n"
5749 "\tstw\t0,%ld(1)\n",
5750 name, name, name, local, local+4);
5752 /* If n is odd, one tag is split between regs and stack.
5753 * Copy its ti_Data together with the ti_Tag. */
5754 if(d)
5755 DoOutput("\tlwz\t0,%ld(1)\n", local+8); /* read ti_Data */
5757 /* Save the registers */
5758 for(i = ap->NumArgs; i <= 8; ++i)
5759 DoOutput("\tstw\t%ld,%ld(1)\n", i+2, (i-ap->NumArgs) * 4+tagl);
5761 if(d)
5762 DoOutput("\tstw\t0,%ld(1)\n", tagl+n * 4); /* write ti_Data */
5764 /* Add TAG_MORE */
5765 DoOutput("\tli\t0,2\n"
5766 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5767 "\taddi\t0,1,%ld\n"
5768 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5769 tagl+n * 4+d, local+8+d, tagl+n * 4+d+4);
5771 if(Flags2 & FLAG2_DIRECTVARARGS)
5773 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5774 "\tbl\t%s\n", ap->NumArgs+2, tagl, name);
5776 else
5779 if(!BaseName)
5781 DoError(ERR_MISSING_BASENAME, ap->Line);
5782 return 1;
5784 /* Caos.Offset = -fD_GetOffset(obj) */
5785 DoOutput("\tli\t0,%d\n"
5786 "\tstw\t0,8(1)\n", -ap->Bias);
5788 /* Save the non-varargs registers in the Caos struct. */
5789 for(i=0; i < ap->NumArgs-1; ++i)
5791 DoOutput("\tstw\t%ld,%d(1)\n", i+3, 8+4+(ap->Args[i].ArgReg * 4));
5794 DoOutput("\taddi\t0,1,%ld\n"
5795 "\tlis\t3,%s@ha\n"
5796 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5797 "\tlwz\t12,%s@l(3)\n"
5798 "\tlwz\t11,88(2)\n"
5799 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5800 "\tmtctr\t11\n"
5801 "\taddi\t3,1,8\n"
5802 "\tbctrl\n", /* EmulCallOS() */
5803 tagl, BaseName, 12+(4 * ap->Args[i].ArgReg), BaseName);
5805 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5806 "\tmtlr\t0\n"
5807 "\taddi\t1,1,%ld\n"
5808 "\tblr\n"
5809 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local+4, local, name, name);
5811 else
5813 DoOutput("%s%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ",
5814 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
5815 return FuncCSTUBS(ap, flags, name);
5816 /* call CSTUBS, as this equals the method used there */
5820 if(Flags & FLAG_INLINENEW) /* new style */
5822 strptr funcpar = "";
5823 DoOutput("#define %s("/*)*/, name);
5825 for(i = 0; i < cd->NumArgs; ++i)
5827 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5828 funcpar = "FP";
5831 if(ap->NumArgs)
5833 for(i = 0; i < ap->NumArgs-1; ++i)
5834 DoOutput("%s, ", ap->Args[i].ArgName);
5835 DoOutput("%s", ap->Args[i].ArgName);
5837 DoOutput(/*(*/") \\\n\t");
5838 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
5840 DoOutput("((("/*)))*/);
5841 OutClibType(&cd->ReturnType, 0);
5842 DoOutput(" (*)("/*)*/);
5843 DoOutput("%s", GetBaseType());
5844 for(i = 0; i < ap->NumArgs; ++i)
5846 DoOutput(", ");
5847 OutClibType(&cd->Args[i], 0);
5849 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5850 "(%s_BASE_NAME",/*)*/
5851 ShortBaseNameUpper, ap->Bias-2, ShortBaseNameUpper);
5853 for(i = 0; i < ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0); ++i)
5854 DoOutput(", %s", ap->Args[i].ArgName);
5855 if(flags & FUNCFLAG_TAG)
5856 DoOutput(", __VA_ARGS__");
5857 return DoOutput(/*((*/"))\n\n");
5859 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap->NumArgs,
5860 (noret ? "NR" : ""), (a45 ? RegNamesUpper[a45] : (strptr) ""),
5861 (BaseName ? "" : "UB"), funcpar, ap->Bias);
5862 if(!noret)
5864 OutClibType(&cd->ReturnType, 0);
5865 DoOutput(", ");
5867 DoOutput("%s, ", name);
5869 for(i = 0; i < ap->NumArgs; ++i)
5871 j = ap->Args[i].ArgReg;
5872 if(a45 && (j == REG_A4 || j == REG_A5))
5873 j = REG_D7;
5874 if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
5876 if(fp != -1)
5878 DoError(ERR_MULTIPLEFUNCTION, ap->Line);
5879 DoOutput("void *");
5881 else
5883 DoOutput("__fpt"); fp = i;
5886 else
5887 OutClibType(&cd->Args[i], 0);
5889 DoOutput(", %s, %s%s", ap->Args[i].ArgName, RegNames[j],
5890 (i == ap->NumArgs-1 && !BaseName ? "" : ", "));
5893 if(BaseName) /* was "##base" used? */
5894 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper);
5896 if(fp >= 0)
5898 DoOutput(", ");
5899 OutClibType(&cd->Args[fp], "__fpt");
5902 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
5903 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5905 return DoOutput(/*(*/")\n\n");
5908 /* old mode or stubs mode */
5910 if((Flags & (FLAG_INLINESTUB|FLAG_MORPHOS)) != (FLAG_INLINESTUB|FLAG_MORPHOS))
5911 DoOutput("%s%s__inline ", Flags & (FLAG_INLINESTUB|FLAG_MORPHOS) ?
5912 "" : "extern ", Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "static " : "");
5913 OutClibType(&cd->ReturnType, 0);
5914 DoOutput("\n%s(%s"/*)*/, name, (BaseName ?
5915 (ap->NumArgs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5917 for(i = 0; i < ap->NumArgs; ++i)
5919 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
5920 if(i < ap->NumArgs-1)
5921 DoOutput(", ");
5924 if(Flags & FLAG_POWERUP)
5926 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5927 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5928 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5929 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5930 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5931 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5932 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5934 if(ap->NumArgs)
5936 for(i = 0; i < ap->NumArgs; ++i)
5938 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5939 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
5943 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
5945 if(BaseName)
5946 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper);
5947 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5948 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5949 else
5951 DoOutput("\treturn(("/*))*/);
5952 OutClibType(&cd->ReturnType, 0);
5953 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5955 return Output_Error;
5957 else if(Flags & FLAG_MORPHOS)
5959 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5961 if(ap->NumArgs)
5963 for(i = 0; i < ap->NumArgs; ++i)
5965 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5966 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
5970 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
5971 if(BaseName)
5972 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5973 ShortBaseNameUpper);
5975 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
5976 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5977 else
5979 DoOutput("\treturn(("/*))*/);
5980 OutClibType(&cd->ReturnType, 0);
5981 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5983 return Output_Error;
5986 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName ? " BASE_EXT_DECL\n" : ""));
5988 if(!noret)
5990 DoOutput(" register ");
5991 OutClibType(&cd->ReturnType, "res");
5992 DoOutput(" __asm(\"d0\");\n");
5995 if(BaseName)
5996 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5997 GetBaseType(), ShortBaseNameUpper);
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(" register ");
6006 OutClibType(&cd->Args[i], RegNames[j]);
6007 DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
6010 if(a45)
6012 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
6013 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames[a45],
6014 ap->Bias, RegNames[a45]);
6016 else
6017 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap->Bias);
6019 DoOutput(noret ? " : /* No Output */\n" : " : \"=r\" (res)\n");
6021 DoOutput(" : ");
6022 if(BaseName)
6023 DoOutput("\"r\" (a6)%s", (ap->NumArgs ? ", ": ""));
6025 for(i = 0; i < ap->NumArgs; ++i)
6027 j = ap->Args[i].ArgReg;
6028 if(a45 && (j == REG_A4 || j == REG_A5))
6029 j = REG_D7;
6031 DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
6034 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6036 if(noret)
6037 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6038 else
6039 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6043 /* new style inlines designed by Bernardo Innocenti */
6044 uint32 FuncInlineNS(struct AmiPragma *ap, uint32 flags, strptr name)
6046 int32 i;
6047 struct ClibData *cd;
6049 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6050 return 1;
6052 Flags |= FLAG_DONE; /* We did something */
6054 if(flags & FUNCFLAG_ALIAS)
6056 if(flags & FUNCFLAG_TAG)
6057 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6058 name, ap->TagName);
6060 DoOutput("#define %s("/*)*/, name);
6061 for(i = 0; i < ap->NumArgs-1; ++i)
6062 DoOutput("%s, ", ap->Args[i].ArgName);
6063 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6064 for(i = 0; i < ap->NumArgs-1; ++i)
6065 DoOutput("(%s), ", ap->Args[i].ArgName);
6066 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
6069 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6070 return 1;
6072 if((flags & FUNCFLAG_TAG))
6074 if(!(Flags2 & FLAG2_INLINEMAC))
6076 DoOutput("static __inline ");
6077 return FuncCSTUBS(ap, flags, name);
6078 /* call CSTUBS, as this equals the method used there */
6080 else
6082 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6083 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
6084 for(i = 0; i < ap->NumArgs-1; ++i)
6085 DoOutput("%s, ", ap->Args[i].ArgName);
6086 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6087 ap->FuncName);
6088 for(i = 0; i < ap->NumArgs-1; ++i)
6089 DoOutput("(%s), ", ap->Args[i].ArgName);
6090 DoOutput("("/*)*/);
6091 OutClibType(&cd->Args[i], 0);
6092 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6096 if(Flags2 & FLAG2_INLINEMAC)
6098 DoOutput("#define %s("/*)*/, name);
6099 for(i = 0; i < ap->NumArgs; ++i)
6101 DoOutput("%s", ap->Args[i].ArgName);
6102 if(i < ap->NumArgs-1)
6103 DoOutput(", ");
6105 DoOutput(/*(*/") \\\n\t");
6107 else
6109 DoOutput("static __inline ");
6110 OutClibType(&cd->ReturnType, 0);
6111 DoOutput(" %s("/*)*/, name);
6112 for(i = 0; i < ap->NumArgs; ++i)
6114 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6115 if(i < ap->NumArgs-1)
6116 DoOutput(", ");
6118 DoOutput(/*(*/")\n{\n "/*}*/);
6119 if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6120 DoOutput("return ");
6122 DoOutput("(("/*))*/);
6123 OutClibType(&cd->ReturnType, 0);
6124 DoOutput(" (*)("/*)*/);
6125 for(i = 0; i < ap->NumArgs; ++i)
6127 OutClibType(&cd->Args[i], 0);
6128 DoOutput(" __asm(\"%s\")", RegNames[ap->Args[i].ArgReg]);
6129 if(i < ap->NumArgs-1)
6130 DoOutput(", ");
6132 if(BaseName)
6134 if(ap->NumArgs)
6135 DoOutput(", ");
6136 DoOutput("%s __asm(\"a6\")", GetBaseType());
6138 DoOutput(/*((*/"))");
6139 if(Flags2 & FLAG2_INLINEMAC)
6140 DoOutput(" \\");
6141 if(BaseName)
6142 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6143 ShortBaseNameUpper, ap->Bias);
6144 else
6146 for(i = 0; i < ap->NumArgs && ap->Args[i].ArgReg != REG_A6; ++i)
6148 if(i == ap->NumArgs)
6149 return 1;
6150 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap->Args[i].ArgName,
6151 ap->Bias);
6153 for(i = 0; i < ap->NumArgs; ++i)
6155 DoOutput("%s", ap->Args[i].ArgName);
6156 if(i < ap->NumArgs-1)
6157 DoOutput(", ");
6159 if(BaseName)
6161 if(ap->NumArgs)
6162 DoOutput(", ");
6163 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
6166 if(Flags2 & FLAG2_INLINEMAC)
6167 DoOutput(/*(*/")\n");
6168 else
6169 DoOutput(/*{(*/");\n}\n");
6171 return DoOutput("\n");
6174 uint32 FuncPowerUP(struct AmiPragma *ap, uint32 flags, strptr name)
6176 int32 i;
6177 struct ClibData *cd;
6179 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6180 return 1;
6182 Flags |= FLAG_DONE; /* We did something */
6184 if(flags & FUNCFLAG_ALIAS)
6186 if(flags & FUNCFLAG_TAG)
6187 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6188 name, ap->TagName);
6190 DoOutput("#define %s("/*)*/, name);
6191 for(i = 0; i < ap->NumArgs-1; ++i)
6192 DoOutput("%s, ", ap->Args[i].ArgName);
6193 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6194 for(i = 0; i < ap->NumArgs-1; ++i)
6195 DoOutput("(%s), ", ap->Args[i].ArgName);
6196 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
6199 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6200 return 1;
6202 if(flags & FUNCFLAG_TAG)
6204 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name);
6205 for(i = 0; i < ap->NumArgs-1; ++i)
6206 DoOutput("%s, ", ap->Args[i].ArgName);
6207 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6208 ap->FuncName);
6209 for(i = 0; i < ap->NumArgs-1; ++i)
6210 DoOutput("(%s), ", ap->Args[i].ArgName);
6211 DoOutput("("/*)*/);
6212 OutClibType(&cd->Args[i], 0);
6213 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6216 DoOutput("#define\t%s("/*)*/, name);
6218 if(ap->NumArgs)
6221 for(i = 0; i < ap->NumArgs-1; ++i)
6222 DoOutput("%s, ", ap->Args[i].ArgName);
6223 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap->Args[i].ArgName, name);
6225 if(BaseName)
6226 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper);
6228 for(i = 0; i < ap->NumArgs-1; ++i)
6229 DoOutput("%s, ", ap->Args[i].ArgName);
6230 DoOutput(/*(*/"%s)\n\n", ap->Args[i].ArgName);
6232 else if(BaseName)
6233 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name, ShortBaseNameUpper);
6234 else
6235 DoOutput(/*(*/")\t_%s()\n\n", name);
6237 DoOutput("static __inline ");
6238 OutClibType(&cd->ReturnType, 0);
6240 DoOutput("\n_%s("/*)*/, name);
6241 if(BaseName)
6242 DoOutput("void * %s%s", BaseName, ap->NumArgs ? ", " : "");
6244 for(i = 0; i < ap->NumArgs; ++i)
6246 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6247 if(i < ap->NumArgs-1)
6248 DoOutput(", ");
6251 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6252 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6253 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6254 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6255 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6256 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6257 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6259 if(ap->NumArgs)
6261 for(i = 0; i < ap->NumArgs; ++i)
6263 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6264 RegNames[ap->Args[i].ArgReg], ap->Args[i].ArgName);
6268 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap->Bias);
6270 if(BaseName)
6271 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName);
6272 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6273 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6274 else
6276 DoOutput("\treturn(("/*))*/);
6277 OutClibType(&cd->ReturnType, 0);
6278 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6280 return Output_Error;
6283 uint32 FuncFPCUnit(struct AmiPragma *ap, uint32 flags, strptr name)
6285 int32 i;
6286 struct ClibData *cd;
6288 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6289 return 1;
6290 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6291 return 1;
6293 if(!FuncFPCType(ap, flags, name))
6294 return 0;
6296 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6298 for(i = 0; i < ap->NumArgs; ++i)
6299 DoOutput("\tMOVE%s.L\t%s,%s\n", ap->Args[i].ArgReg >= REG_A0 ? "A" : "",
6300 ap->Args[i].ArgName, RegNamesUpper[ap->Args[i].ArgReg]);
6302 if(BaseName)
6303 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName);
6304 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap->Bias);
6306 if(!IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6308 if(!cd->ReturnType.PointerDepth &&
6309 cd->ReturnType.Flags == CPP_FLAG_BOOLEAN)
6310 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6311 " @end:\tMOVE.B\tD0,@RESULT\n");
6312 else
6313 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6315 return DoOutput(" END;\nEND;\n\n");
6318 uint32 FuncFPCType(struct AmiPragma *ap, uint32 flags, strptr name)
6320 uint32 ret = 1;
6321 int32 i;
6322 struct ClibData *cd;
6324 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6325 return 1;
6326 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6327 return 1;
6329 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6331 ret = 0; DoOutput("PROCEDURE %s", name);
6333 else
6334 DoOutput("FUNCTION %s", name);
6336 if(ap->NumArgs)
6338 DoOutput("("/*)*/);
6339 for(i = 0; i < ap->NumArgs;)
6341 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6342 if(++i != ap->NumArgs)
6343 DoOutput("; ");
6345 DoOutput(/*(*/")");
6348 if(ret)
6349 OutPASCALType(&cd->ReturnType, "", 1);
6351 Flags |= FLAG_DONE; /* We did something */
6353 return DoOutput(";\n");
6356 uint32 FuncFPCTypeTags(struct AmiPragma *ap, uint32 flags, strptr name)
6358 uint32 ret = 1;
6359 int32 i;
6360 struct ClibData *cd;
6362 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6363 return 1;
6364 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6365 return 1;
6367 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6369 ret = 0; DoOutput("PROCEDURE %s", name);
6371 else
6372 DoOutput("FUNCTION %s", name);
6374 if(ap->NumArgs)
6376 DoOutput("("/*)*/);
6377 for(i = 0; i < ap->NumArgs-1;)
6379 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6380 if(++i != ap->NumArgs)
6381 DoOutput("; ");
6383 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
6384 DoOutput(/*(*/")");
6387 if(ret)
6388 OutPASCALType(&cd->ReturnType, "", 1);
6390 Flags |= FLAG_DONE; /* We did something */
6392 return DoOutput(";\n");
6395 uint32 FuncFPCTypeTagsUnit(struct AmiPragma *ap, uint32 flags, strptr name)
6397 uint32 ret = 1;
6398 int32 i;
6399 struct ClibData *cd;
6401 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
6402 return 1;
6403 else if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
6404 return 1;
6406 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
6408 ret = 0; DoOutput("PROCEDURE %s", name);
6410 else
6411 DoOutput("FUNCTION %s", name);
6413 if(ap->NumArgs)
6415 DoOutput("("/*)*/);
6416 for(i = 0; i < ap->NumArgs-1;)
6418 OutPASCALType(&cd->Args[i], ap->Args[i].ArgName, 0);
6419 if(++i != ap->NumArgs)
6420 DoOutput("; ");
6422 DoOutput("const %s : Array Of Const",ap->Args[i].ArgName);
6423 DoOutput(/*(*/")");
6426 if(ret)
6427 OutPASCALType(&cd->ReturnType, "", 1);
6429 DoOutput(";\nbegin\n");
6431 if(ret)
6432 DoOutput(" %s := %s",name, ap->FuncName);
6433 else DoOutput(" %s", ap->FuncName);
6435 if(ap->NumArgs)
6437 DoOutput("("/*)*/);
6438 for(i = 0; i < ap->NumArgs-1;)
6440 DoOutput("%s ", ap->Args[i].ArgName);
6441 if(++i != ap->NumArgs)
6442 DoOutput(", ");
6444 DoOutput("readintags(%s)",ap->Args[i].ArgName);
6445 DoOutput(/*(*/");");
6448 DoOutput("\nend");
6450 Flags |= FLAG_DONE; /* We did something */
6452 return DoOutput(";\n\n");
6456 uint32 FuncBMAP(struct AmiPragma *ap, uint32 flags, strptr name)
6458 uint8 reg, i;
6460 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_A5USE
6461 |AMIPRAGFLAG_PPC))
6462 return 1;
6464 Flags |= FLAG_DONE; /* We did something */
6466 for(i = 0; BMAPSpecial[i]; ++i)
6468 if(!stricmp(name, BMAPSpecial[i]))
6470 DoOutput("x"); break;
6474 DoOutput(name);
6475 reg = 0; DoOutputDirect(&reg, 1);
6476 reg = (-ap->Bias)>>8; DoOutputDirect(&reg, 1);
6477 reg = -ap->Bias; DoOutputDirect(&reg, 1);
6478 for(i = 0; i < ap->NumArgs; ++i)
6480 reg = 1+ap->Args[i].ArgReg; DoOutputDirect(&reg, 1);
6482 reg = 0;
6483 return DoOutputDirect(&reg, 1);
6486 uint32 FuncVBCCInline(struct AmiPragma *ap, uint32 flags, strptr name)
6488 struct ClibData *cd;
6489 strptr c1, c2;
6490 int32 i, k;
6492 if(!(cd = GetClibFunc(name, ap, flags)))
6493 return 1;
6495 /* find register pairs for 64-bit types (long long, double) */
6496 FindRegPairs(ap, cd);
6498 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6499 return 1;
6501 c1 = Flags & FLAG_NEWSYNTAX ? "(" : ""; /*)*/
6502 c2 = Flags & FLAG_NEWSYNTAX ? "," : "("; /*)*/
6504 Flags |= FLAG_DONE; /* We did something */
6506 if(flags & FUNCFLAG_TAG)
6508 if(IsNoCreateInlineFunc(name))
6509 return 1; /* do not create some strange functions */
6510 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6511 "(__STDC_VERSION__ >= 199901L)\n");
6514 if(flags & FUNCFLAG_ALIAS)
6516 DoOutput("#define %s("/*)*/, name);
6517 for(i = 0; i < ap->NumArgs-1; ++i)
6518 DoOutput("%s, ", ap->Args[i].ArgName);
6519 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6520 if(Flags2 & FLAG2_OLDVBCC)
6522 for(i = 0; i < ap->NumArgs; ++i)
6523 DoOutput("(%s), ", ap->Args[i].ArgName);
6524 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6525 "#endif\n" : "");
6527 else
6529 DoOutput("%s", BaseName);
6530 for(i = 0; i < ap->NumArgs; ++i)
6531 DoOutput(", (%s)", ap->Args[i].ArgName);
6532 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ?
6533 "#endif\n" : "");
6537 OutClibType(&cd->ReturnType, 0);
6538 DoOutput(" __%s("/*)*/, name);
6540 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6542 DoOutput("__reg(\"a6\") %s", GetBaseType());
6543 if(ap->NumArgs)
6544 DoOutput(", ");
6547 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
6548 for(i = 0; i < k; ++i)
6550 DoOutput("__reg(\"%s\") ", RegNames[ap->Args[i].ArgReg]);
6551 if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
6552 && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
6554 DoOutput("void * %s", ap->Args[i].ArgName);
6556 else
6557 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6558 if(i < ap->NumArgs-1)
6559 DoOutput(", ");
6562 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6564 if(ap->NumArgs)
6565 DoOutput(", ");
6566 DoOutput("__reg(\"a6\") %s", GetBaseType());
6569 if(flags & FUNCFLAG_TAG)
6571 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6573 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6574 DoOutput(", ");
6576 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6577 RegNames[ap->Args[k].ArgReg]);
6579 if(ap->Args[k].ArgReg > 7)
6580 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1, c2,
6581 RegNames[ap->Args[k].ArgReg]);
6582 else
6583 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6584 RegNames[ap->Args[k].ArgReg], RegNames[ap->Args[k].ArgReg]);
6586 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6587 "\\tmove%s.l\\t(a7)+,%s\";\n", c1, ap->Bias, c2,
6588 ap->Args[k].ArgReg >= REG_A0 ? "a" : "", RegNames[ap->Args[k].ArgReg]);
6590 else
6591 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1, ap->Bias, c2);
6593 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6594 DoOutput("#define %s("/*)*/, name);
6595 for(i = 0; i < k; ++i)
6597 DoOutput("%s", ap->Args[i].ArgName);
6598 if(i < ap->NumArgs-1)
6599 DoOutput(", ");
6601 if(flags & FUNCFLAG_TAG)
6603 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6604 DoOutput("%s, ", ap->Args[k].ArgName);
6605 DoOutput("...");
6607 DoOutput(/*(*/") __%s("/*)*/, name);
6608 if(!(Flags2 & FLAG2_OLDVBCC) && BaseName)
6610 DoOutput("%s", BaseName);
6611 if(ap->NumArgs)
6612 DoOutput(", ");
6614 for(i = 0; i < k; ++i)
6616 if(ap->Args[i].ArgReg >= REG_A0 && ap->Args[i].ArgReg <= REG_A7
6617 && !(cd->Args[i].Flags & (CPP_FLAG_POINTER|CPP_FLAG_FUNCTION)))
6619 DoOutput("(void *)");
6621 DoOutput("(%s)", ap->Args[i].ArgName);
6622 if(i < ap->NumArgs-1)
6623 DoOutput(", ");
6625 if((Flags2 & FLAG2_OLDVBCC) && BaseName)
6627 if(ap->NumArgs)
6628 DoOutput(", ");
6629 DoOutput("%s", BaseName);
6631 if(flags & FUNCFLAG_TAG)
6633 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6634 DoOutput("(%s), ", ap->Args[k].ArgName);
6635 DoOutput("__VA_ARGS__");
6638 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6641 uint32 FuncVBCCWOSInline(struct AmiPragma *ap, uint32 flags, strptr name)
6643 struct ClibData *cd;
6644 int32 i, k;
6646 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_M68K))
6647 return 1;
6649 if(!(cd = GetClibFunc(name, ap, flags)))
6650 return 1;
6652 Flags |= FLAG_DONE; /* We did something */
6654 if(flags & FUNCFLAG_TAG)
6656 if(IsNoCreateInlineFunc(name))
6657 return 1; /* do not create some strange functions */
6658 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6659 "(__STDC_VERSION__ >= 199901L)\n");
6662 if(flags & FUNCFLAG_ALIAS)
6664 DoOutput("#define %s("/*)*/, name);
6665 for(i = 0; i < ap->NumArgs-1; ++i)
6666 DoOutput("%s, ", ap->Args[i].ArgName);
6667 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6668 for(i = 0; i < ap->NumArgs; ++i)
6669 DoOutput("(%s), ", ap->Args[i].ArgName);
6670 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6671 "#endif\n" : "");
6674 OutClibType(&cd->ReturnType, 0);
6675 DoOutput(" __%s("/*)*/, name);
6677 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6679 DoOutput("%s", GetBaseType());
6680 if(ap->NumArgs)
6681 DoOutput(", ");
6684 k = ap->NumArgs;
6685 for(i = 0; i < k; ++i)
6687 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6688 if(i < k-1)
6689 DoOutput(", ");
6691 if(flags & FUNCFLAG_TAG)
6692 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6694 DoOutput(/*(*/")=\"");
6695 if(ap->Flags & AMIPRAGFLAG_PPC0)
6697 DoOutput("\\t.extern\\t_%s\\n", BaseName);
6698 if ((flags & FUNCFLAG_TAG) && k>0)
6700 /* save tag1 and load taglist-pointer */
6701 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6702 "\\taddi\\t%s%d,%s1,%d\\n",
6703 PPCRegPrefix, k+2, 20+k*4, PPCRegPrefix, PPCRegPrefix,
6704 k+2, PPCRegPrefix, 20+k*4);
6706 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6707 "\\tlwz\\t%s0,-%d(%s11)\\n"
6708 "\\tmtlr\\t%s0\\n"
6709 "\\tblrl",
6710 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix,
6711 ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6713 else if(ap->Flags & AMIPRAGFLAG_PPC2)
6715 /* @@@ tagcall handling? */
6716 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6717 "\\t.extern\\t_%s\\n"
6718 "\\tlwz\\t%s2,_%s(%s2)\\n"
6719 "\\tlwz\\t%s0,-%d(%s2)\\n"
6720 "\\tmtlr\\t%s0\\n"
6721 "\\tblrl\\n"
6722 "\\tlwz\\t%s2,20(%s1)",
6723 PPCRegPrefix, PPCRegPrefix, BaseName, PPCRegPrefix, BaseName,
6724 PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
6725 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
6727 else
6729 if ((flags & FUNCFLAG_TAG) && k>0)
6731 /* save tag1 and load taglist-pointer */
6732 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6733 "\\taddi\\t%s%d,%s1,%d\\n",
6734 PPCRegPrefix, k+3, 24+k*4, PPCRegPrefix, PPCRegPrefix,
6735 k+3, PPCRegPrefix, 24+k*4);
6737 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6738 "\\tmtlr\\t%s0\\n"
6739 "\\tblrl",
6740 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
6742 DoOutput("\";\n");
6744 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6745 DoOutput("#define %s("/*)*/, name);
6746 for(i = 0; i < k; ++i)
6748 DoOutput("%s", ap->Args[i].ArgName);
6749 if(i < ap->NumArgs-1)
6750 DoOutput(", ");
6752 if(flags & FUNCFLAG_TAG)
6754 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6755 DoOutput("%s, ", ap->Args[k].ArgName);
6756 DoOutput("...");
6758 DoOutput(/*(*/") __%s("/*)*/, name);
6759 if(!(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)))
6761 DoOutput("%s", BaseName);
6762 if(ap->NumArgs)
6763 DoOutput(", ");
6765 for(i = 0; i < k; ++i)
6767 DoOutput("(%s)", ap->Args[i].ArgName);
6768 if(i < ap->NumArgs-1)
6769 DoOutput(", ");
6771 if(flags & FUNCFLAG_TAG)
6773 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6774 DoOutput("(%s), ", ap->Args[k].ArgName);
6775 DoOutput("__VA_ARGS__");
6778 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6781 uint32 FuncVBCCMorphInline(struct AmiPragma *ap, uint32 flags, strptr name)
6783 struct ClibData *cd;
6784 int32 i, k;
6786 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
6787 return 1;
6789 if(!(cd = GetClibFunc(name, ap, flags)))
6790 return 1;
6792 Flags |= FLAG_DONE; /* We did something */
6794 if(flags & FUNCFLAG_TAG)
6796 if(IsNoCreateInlineFunc(name))
6797 return 1; /* do not create some strange functions */
6798 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6799 "(__STDC_VERSION__ >= 199901L)\n");
6802 if(flags & FUNCFLAG_ALIAS)
6804 DoOutput("#define %s("/*)*/, name);
6805 for(i = 0; i < ap->NumArgs-1; ++i)
6806 DoOutput("%s, ", ap->Args[i].ArgName);
6807 DoOutput(/*(*/"%s) __%s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
6808 for(i = 0; i < ap->NumArgs; ++i)
6809 DoOutput("(%s), ", ap->Args[i].ArgName);
6810 return DoOutput(/*(*/"%s)\n%s\n", BaseName, flags & FUNCFLAG_TAG ?
6811 "#endif\n" : "");
6814 OutClibType(&cd->ReturnType, 0);
6815 if((flags & FUNCFLAG_TAG) && (Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6816 DoOutput(" __linearvarargs");
6818 DoOutput(" __%s("/*)*/, name);
6820 if(BaseName && !(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12)))
6822 DoOutput("%s", GetBaseType());
6823 if(ap->NumArgs)
6824 DoOutput(", ");
6827 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6829 if((flags & FUNCFLAG_TAG) &&
6830 !(ap->Flags & AMIPRAGFLAG_MOS_ALL))
6832 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6833 DoOutput("long, ");
6837 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-1 : ap->NumArgs;
6838 for(i = 0; i < k; ++i)
6840 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
6841 if(i < ap->NumArgs-1)
6842 DoOutput(", ");
6845 if(flags & FUNCFLAG_TAG)
6847 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6849 if((ap->Flags & AMIPRAGFLAG_MOS_ALL)
6850 && !(ap->Flags & AMIPRAGFLAG_VARARGS))
6852 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6853 DoOutput("long, ");
6855 if(cd->Args[k].Type != CPP_TYPE_VARARGS)
6857 OutClibType(&cd->Args[k], ap->Args[k].ArgName);
6858 DoOutput(", ");
6862 DoOutput("...");
6865 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
6867 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6868 PPCRegPrefix, ap->Bias-2, PPCRegPrefix);
6869 if((ap->Flags != AMIPRAGFLAG_VARARGS) && (flags & FUNCFLAG_TAG))
6871 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6872 PPCRegPrefix,3+k+1,PPCRegPrefix);
6874 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6875 "\t\"\\tbctrl\";\n", PPCRegPrefix);
6877 else if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
6879 if (BaseName)
6881 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6882 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6883 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6884 PPCRegPrefix, BaseName,
6885 PPCRegPrefix, BaseName, PPCRegPrefix,
6886 PPCRegPrefix, ap->Bias-2, PPCRegPrefix);
6888 if((ap->Flags != AMIPRAGFLAG_VARARGS) && (flags & FUNCFLAG_TAG))
6890 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6891 PPCRegPrefix,3+k+1,PPCRegPrefix);
6893 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6894 "\t\"\\tbctrl\";\n", PPCRegPrefix);
6896 else
6898 int ofs = 4, fix = 0;
6899 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6900 PPCRegPrefix, PPCRegPrefix);
6901 k = 3;
6902 if(BaseName)
6904 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix, k++,
6905 PPCRegPrefix);
6907 if(Flags2 & FLAG2_SHORTPPCVBCCINLINE)
6909 ofs = 12;
6910 if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
6911 fix = 8+1-i;
6913 else if(flags & FUNCFLAG_TAG)
6915 if((i = ap->NumArgs+(BaseName?1:0)) <= 8)
6916 k += 8+1-i;
6919 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix);
6920 for(i = 0; i < ap->NumArgs; ++i)
6922 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
6924 if(k <= 7+3)
6925 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix, k++);
6926 else
6927 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6928 PPCRegPrefix, 8+(k++-11)*4, PPCRegPrefix, PPCRegPrefix);
6930 else
6932 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6933 PPCRegPrefix, ofs, PPCRegPrefix, (2+k+fix-11)*4, PPCRegPrefix, ofs);
6935 DoOutput("%d(%s2)\\n\"\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
6937 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix,
6938 ap->Bias);
6941 k = (flags & FUNCFLAG_TAG) ? ap->NumArgs-2 : ap->NumArgs;
6942 DoOutput("#define %s("/*)*/, name);
6943 for(i = 0; i < k; ++i)
6945 DoOutput("%s", ap->Args[i].ArgName);
6946 if(i < ap->NumArgs-1)
6947 DoOutput(", ");
6949 if(flags & FUNCFLAG_TAG)
6951 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6952 DoOutput("%s, ", ap->Args[k].ArgName);
6953 DoOutput("...");
6955 DoOutput(/*(*/") __%s("/*)*/, name);
6956 if(BaseName && !(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12)))
6958 DoOutput("%s", BaseName);
6959 if(ap->NumArgs)
6960 DoOutput(", ");
6962 if(!(Flags2 & FLAG2_SHORTPPCVBCCINLINE))
6964 if(flags & FUNCFLAG_TAG && !(ap->Flags & AMIPRAGFLAG_MOSBASESYSV))
6966 for(i = ap->NumArgs+(BaseName?1:0); i <= 8; ++i)
6967 DoOutput("0, ");
6970 for(i = 0; i < k; ++i)
6972 DoOutput("(%s)", ap->Args[i].ArgName);
6973 if(i < ap->NumArgs-1)
6974 DoOutput(", ");
6976 if(flags & FUNCFLAG_TAG)
6978 if(ap->NumArgs > 1 && cd->Args[ap->NumArgs-1].Type != CPP_TYPE_VARARGS)
6979 DoOutput("(%s), ", ap->Args[k].ArgName);
6980 DoOutput("__VA_ARGS__");
6983 return DoOutput(/*(*/")\n%s\n", flags & FUNCFLAG_TAG ? "#endif\n" : "");
6986 uint32 FuncVBCCWOSText(struct AmiPragma *ap, uint32 flags, strptr name)
6988 uint32 i, k, count, ofs;
6989 struct ClibData *cd = 0;
6991 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
6992 return 1;
6994 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&
6995 !(cd = GetClibFunc(name, ap, flags)))
6996 return 1;
6998 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
6999 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) ||
7000 !(Flags & FLAG_WOSLIBBASE)))
7002 DoError(ERR_MISSING_BASENAME, ap->Line);
7003 return 1;
7006 Flags |= FLAG_DONE;
7008 if(Flags & FLAG_SINGLEFILE)
7010 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7012 if(HEADER)
7014 DoOutput("\n");
7015 DoOutputDirect(HEADER, headersize);
7019 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
7020 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
7022 if(Flags & FLAG_SINGLEFILE)
7023 DoOutput("\t.file\t\"%s.o\"\n", name);
7024 DoOutput("\t.align\t3\n");
7025 if(Flags & FLAG_WOSLIBBASE) /* PPCBase already in r3, LibBase in r4 */
7027 if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
7028 DoOutput("\t.extern _%s\n", BaseName);
7029 DoOutput("\t.global __%s\n__%s:\n", name, name);
7031 else
7033 if(BaseName)
7034 DoOutput("\t.extern _%s\n", BaseName);
7035 if(!(ap->Flags & AMIPRAGFLAG_PPC))
7036 DoOutput("\t.extern _PowerPCBase\n");
7037 DoOutput("\t.global _%s\n_%s:\n", name, name);
7040 if(ap->Flags & AMIPRAGFLAG_PPC2)
7042 DoOutput("\tstw\t%s2,20(%s1)\n"
7043 "\tmflr\t%s0\n"
7044 "\tstw\t%s0,16(%s1)\n"
7045 "\tlwz\t%s2,_%s(%s2)\n"
7046 "\tlwz\t%s0,-%d(%s2)\n"
7047 "\tmtlr\t%s0\n"
7048 "\tblrl\n"
7049 "\tlwz\t%s0,16(%s1)\n"
7050 "\tlwz\t%s2,20(%s1)\n"
7051 "\tmtlr\t%s0\n"
7052 "\tblr\n",
7053 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7054 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2,
7055 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7056 PPCRegPrefix, PPCRegPrefix);
7058 else if(ap->Flags & AMIPRAGFLAG_PPC0)
7060 DoOutput("\tmflr\t%s0\n", PPCRegPrefix);
7061 if((flags & FUNCFLAG_TAG) && ap->NumArgs>0)
7063 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7064 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7065 PPCRegPrefix, (int)ap->NumArgs+2,
7066 20+(int)ap->NumArgs*4, PPCRegPrefix, PPCRegPrefix,
7067 (int)ap->NumArgs+2, PPCRegPrefix, 20+(int)ap->NumArgs*4);
7069 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7070 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7071 "\tlwz\t%s11,_%s(%s2)\n"
7072 "\tlwz\t%s0,-%d(%s11)\n"
7073 "\tmtlr\t%s0\n"
7074 "\tblrl\n"
7075 "\tlwz\t%s0,40(%s1)\n"
7076 "\taddi\t%s1,%s1,32\n"
7077 "\tmtlr\t%s0\n"
7078 "\tblr\n",
7079 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7080 BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias-2, PPCRegPrefix,
7081 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7082 PPCRegPrefix);
7084 else if(ap->Flags & AMIPRAGFLAG_PPC)
7086 count = ap->NumArgs;
7087 if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
7089 /* init stack frame */
7090 i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
7091 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7092 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
7094 if(count > 8)
7096 /* extra arguments must be passed on the stack */
7097 k = 32-(count-8); /* firstreg */
7099 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7100 PPCRegPrefix, k, 56+(count-8)*4, PPCRegPrefix, PPCRegPrefix, k,
7101 i+56, PPCRegPrefix);
7102 if(flags & FUNCFLAG_TAG)
7103 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
7104 i+20+count*4);
7105 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
7107 else if(flags & FUNCFLAG_TAG)
7109 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
7110 PPCRegPrefix, i+20+count*4);
7111 --count;
7114 else /* Args must be shifted! */
7116 /* init stack frame */
7117 i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
7118 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7119 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix);
7121 if(count > 7)
7123 /* extra arguments must be passed on the stack */
7124 if(count == 8)
7126 /* special case: move 8th argument into stack frame */
7127 if(flags & FUNCFLAG_TAG)
7128 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix, PPCRegPrefix,
7129 i+20+count*4);
7130 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7132 else
7134 k = 32-(count-7); /* firstreg */
7136 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7137 "\tmr\t%s%ld,%s10\n"
7138 "\tlmw\t%s%ld,%ld(%s1)\n",
7139 PPCRegPrefix, k, 56+(count-7)*4, PPCRegPrefix,
7140 PPCRegPrefix, k, PPCRegPrefix, PPCRegPrefix, k+1,
7141 i+56, PPCRegPrefix);
7142 if(flags & FUNCFLAG_TAG)
7143 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix,
7144 PPCRegPrefix, i+20+count*4);
7145 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix, k, PPCRegPrefix);
7148 else if(flags & FUNCFLAG_TAG)
7150 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix, count+3,
7151 PPCRegPrefix, i+20+count*4);
7152 --count;
7155 /* shift all arguments into their following register */
7156 for(k=(count<8)?count:7; k > 0; --k)
7157 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix, 3+k, PPCRegPrefix, 2+k);
7159 /* load library base and LVO, then call LVO via LR */
7160 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix, BaseName, PPCRegPrefix);
7163 /* call LVO */
7164 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix,
7165 ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
7167 /* cleanup stack frame and return */
7168 if(count > 8)
7170 k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
7171 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, 32-(count-k),
7172 56+(count-k)*4, PPCRegPrefix);
7175 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7176 PPCRegPrefix, PPCRegPrefix, i, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7178 else
7180 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7181 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7183 /* clear PP_Flags, PP_Stack and PP_StackSize */
7184 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7185 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7186 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7188 if(Flags & FLAG_WOSLIBBASE)
7189 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7190 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix, ap->Bias, PPCRegPrefix,
7191 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7192 else if(!BaseName)
7193 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix,
7194 ap->Bias, PPCRegPrefix, PPCRegPrefix);
7195 else
7196 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7197 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7198 PPCRegPrefix, BaseName, PPCRegPrefix, PPCRegPrefix, ap->Bias,
7199 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7200 PPCRegPrefix);
7202 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
7203 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
7204 for(i = 0; i < k; ++i)
7206 if(i + ofs <= 7)
7208 if(ap->Args[i].ArgReg == REG_A6)
7209 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix, i+3+ofs,
7210 PPCRegPrefix);
7211 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3+ofs);
7213 else
7215 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix, (i+1+ofs)*4+196,
7216 PPCRegPrefix);
7217 if(ap->Args[i].ArgReg == REG_A6)
7218 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7219 DoOutput("\tstw\t%s11,", PPCRegPrefix);
7221 DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
7223 if(flags & FUNCFLAG_TAG)
7225 if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
7226 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i+3+ofs,
7227 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
7228 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix,
7229 PPCRegPrefix, 0xC4+(ap->NumArgs+ofs)*4, PPCRegPrefix);
7230 DoOutput("%d(%s1)\n", 0x34+4*ap->Args[i].ArgReg, PPCRegPrefix);
7233 if(!(Flags & FLAG_WOSLIBBASE))
7234 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix, PPCRegPrefix);
7236 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7237 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7238 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7239 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7240 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7243 if(Flags & FLAG_WOSLIBBASE)
7244 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7245 name, name, name);
7246 else
7247 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7248 name, name, name);
7251 uint32 FuncVBCCWOSCode(struct AmiPragma *ap, uint32 flags, strptr name)
7253 uint32 i, j, k, ofs, count;
7254 uint8 *data, *basepos = 0, *pbasepos = 0;
7255 struct ClibData *cd = 0;
7257 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG))
7258 return 1;
7260 if((flags & FUNCFLAG_TAG) && !(ap->Flags & AMIPRAGFLAG_PPC) &&
7261 !(cd = GetClibFunc(name, ap, flags)))
7262 return 1;
7264 if((ap->Flags & AMIPRAGFLAG_PPC) && !BaseName &&
7265 ((ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2)) ||
7266 !(Flags & FLAG_WOSLIBBASE)))
7268 DoError(ERR_MISSING_BASENAME, ap->Line);
7269 return 1;
7272 Flags |= FLAG_DONE; /* We did something */
7274 i = strlen(name) + 2;
7275 EndPutM32(tempbuf, HUNK_UNIT);
7276 EndPutM32(tempbuf+4, (i+3)>>2);
7277 DoOutputDirect(tempbuf, 8);
7278 DoOutput("%s.o", name);
7279 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
7281 i = strlen(hunkname);
7282 EndPutM32(tempbuf, HUNK_NAME);
7283 EndPutM32(tempbuf+4, (i + 3)>>2);
7284 DoOutputDirect(tempbuf, 8);
7285 DoOutputDirect(hunkname, i);
7286 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
7288 data = tempbuf+8; /* we need HUNK_PPC_CODE + size at start */
7290 if(ap->Flags & AMIPRAGFLAG_PPC2)
7292 EndPutM32Inc(data, 0x90410014); /* stw r2,20(r1) */
7293 /* mflr r0 = mfspr r0,8 = get link register */
7294 EndPutM32Inc(data, 0x7C0802A6);
7295 EndPutM32Inc(data, 0x90010010); /* stw r0,16(r1) */
7296 basepos = data;
7297 EndPutM32Inc(data, 0x80420000); /* lwz r2,BaseName(r2) */
7298 EndPutM32Inc(data, 0x80030000-(ap->Bias-2));/* lwz r0,-ap->Bias-2(r2) */
7299 /* mtlr r0 = mtspr 8,r0 = restore link register */
7300 EndPutM32Inc(data, 0x7C0803A6);
7301 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7302 EndPutM32Inc(data, 0x80010010); /* lwz r0,16(r1) */
7303 EndPutM32Inc(data, 0x80410014); /* lwz r2,20(r1) */
7304 /* mtlr r0 = mtspr 8,r0 = restore link register */
7305 EndPutM32Inc(data, 0x7C0803A6);
7306 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7308 else if(ap->Flags & AMIPRAGFLAG_PPC0)
7310 basepos = data;
7311 /* mflr r0 = mfspr r0,8 = get link register */
7312 EndPutM32Inc(data, 0x7C0802A6);
7313 if((flags & FUNCFLAG_TAG) && ap->NumArgs>0)
7315 EndPutM32Inc(data, 0x90010000 + (((uint32)ap->NumArgs+2) << 21) +
7316 (uint32)(20+ap->NumArgs*4)); /* stw rN,d(r1) */
7317 EndPutM32Inc(data, 0x38010000 + (((uint32)ap->NumArgs+2) << 21) +
7318 (uint32)(20+ap->NumArgs*4)); /* addi rN,r1,d */
7320 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7321 EndPutM32Inc(data, 0x9421FFCE); /* stwu r1,-32(r1) */
7322 EndPutM32Inc(data, 0x81620000); /* lwz r11,BaseName(r2) */
7323 EndPutM32Inc(data, 0x800C0000-(ap->Bias-2));/* lwz r0,-ap->Bias-2(r11) */
7324 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7325 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7326 EndPutM32Inc(data, 0x80010028); /* lwz r0,40(r1) */
7327 EndPutM32Inc(data, 0x38210020); /* addi r1,r1,32 */
7328 /* mtlr r0 = mtspr 8,r0 = restore link register */
7329 EndPutM32Inc(data, 0x7C0803A6);
7330 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7332 else if(ap->Flags & AMIPRAGFLAG_PPC)
7334 count = ap->NumArgs;
7335 if(Flags & FLAG_WOSLIBBASE) /* LibBase already in r3 */
7337 /* init stack frame */
7338 i = (count <= 8) ? 32 : ((56+(count-8)*8+15)&~15); /* stksize */
7339 /* mflr r0 = mfspr r0,8 = get link register */
7340 EndPutM32Inc(data, 0x7C0802A6);
7341 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7342 EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
7344 if(count > 8)
7346 /* extra arguments must be passed on the stack */
7347 k = 32-(count-8); /* firstreg */
7348 /* stmw rk,X(r1) */
7349 EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-8)*4));
7350 EndPutM32Inc(data, 0xB8010000 + (k << 21) + (i+56)); /* lmw rk,Y(r1) */
7351 if(flags & FUNCFLAG_TAG)
7352 EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4)); /* addi r31,r1,X */
7353 EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
7355 else if(flags & FUNCFLAG_TAG)
7357 /* addi rX,r1,Y */
7358 EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4));
7359 --count;
7362 else /* Args must be shifted! */
7364 /* init stack frame */
7365 i = (count < 8) ? 32 : ((56+(count-7)*8+15)&~15); /* stksize */
7366 /* mflr r0 = mfspr r0,8 = get link register */
7367 EndPutM32Inc(data, 0x7C0802A6);
7368 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) */
7369 EndPutM32Inc(data, 0x94220000 - i); /* stwu r1,-i(r1) */
7371 if(count > 7)
7373 /* extra arguments must be passed on the stack */
7374 if(count == 8)
7376 /* special case: move 8th argument into stack frame */
7377 if(flags & FUNCFLAG_TAG)
7378 EndPutM32Inc(data, 0x39410000 + (i+20+count*4)); /* addi r10,r1,X */
7379 EndPutM32Inc(data, 0x91410038); /* stw r10,56(r1) */
7381 else
7383 k = 32-(count-7); /* firstreg */
7385 /* stmw rk,X(r1) */
7386 EndPutM32Inc(data, 0xBC010000 + (k << 21) + (56+(count-7)*4));
7387 /* mr rk,r10 = or rk,r10,r10 */
7388 EndPutM32Inc(data, 0x7D405378 + (k<<16));
7389 /* lmw rk,Y(r1) */
7390 EndPutM32Inc(data, 0xB8010000 + ((k+1) << 21) + (i+56));
7391 if(flags & FUNCFLAG_TAG)
7393 /* addi r31,r1,X */
7394 EndPutM32Inc(data, 0x3BE10000 + (i+20+count*4));
7396 EndPutM32Inc(data, 0xBC010038 + (k << 21)); /* stmw rk,56(r1) */
7399 else if(flags & FUNCFLAG_TAG)
7401 /* addi rX,r1,Y */
7402 EndPutM32Inc(data, 0x38010000 + ((count+3)<<21) + (i+20+count*4));
7403 --count;
7406 /* shift all arguments into their following register */
7407 for(k=(count<8)?count:7; k > 0; --k)
7408 EndPutM32Inc(data, 0x7C000378 + ((3+k)<<16) + ((2+k)<<21) + ((2+k)<<11)); /* mr rX,rY = or rX,rY,rY */
7410 /* load library base and LVO, then call LVO via LR */
7411 basepos = data;
7412 EndPutM32Inc(data, 0x80620000); /* lwz r3,BaseName(r2) */
7414 /* call LVO */
7415 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7416 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7417 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7420 /* cleanup stack frame and return */
7421 if(count > 8)
7423 k = Flags & FLAG_WOSLIBBASE ? 8 : 7; /* restore saved regs */
7424 EndPutM32Inc(data, 0xB8010000 + ((32-(count-k))<<21) + (56+(count-k)*4)); /* lmw rX,Y(r1) */
7426 EndPutM32Inc(data, 0x38210000 + i); /* addi r1,r1,i */
7427 EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) */
7428 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7429 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump */
7431 else
7433 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7434 EndPutM32Inc(data, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7435 EndPutM32Inc(data, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7437 EndPutM32Inc(data, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7438 EndPutM32Inc(data, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7439 EndPutM32Inc(data, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7440 EndPutM32Inc(data, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7442 if(Flags & FLAG_WOSLIBBASE)
7444 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7445 EndPutM32Inc(data, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7446 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7447 EndPutM32Inc(data, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7449 else if(!BaseName)
7451 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7452 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7454 else
7456 basepos = data;
7457 EndPutM32Inc(data, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7458 EndPutM32Inc(data, 0x39610000 -ap->Bias); /* li r11,ap->Bias */
7459 EndPutM32Inc(data, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7460 EndPutM32Inc(data, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7461 EndPutM32Inc(data, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7464 ofs = Flags & FLAG_WOSLIBBASE ? 2 : 0;
7465 k = ap->NumArgs - (flags & FUNCFLAG_TAG ? 1 : 0);
7466 for(i = 0; i < k; ++i)
7468 j = 0x34+4*ap->Args[i].ArgReg; /* PP_Regs offset */
7469 if(i + ofs <= 7)
7471 if(ap->Args[i].ArgReg == REG_A6)
7472 EndPutM32Inc(data, 0x90010020 + ((i+3+ofs)<<21)); /* stw rX,0x20(r1) */
7473 EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
7475 else
7477 EndPutM32Inc(data, 0x81610000 + ((i+1+ofs)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7478 if(ap->Args[i].ArgReg == REG_A6)
7479 EndPutM32Inc(data, 0x91610020); /* stw r11,0x20(r1) */
7480 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
7483 if(flags & FUNCFLAG_TAG)
7485 j = (ap->NumArgs+ofs)*4+0xC4;
7487 if((i+ofs) <= 7 && cd->Args[i].Type != CPP_TYPE_VARARGS)
7488 EndPutM32Inc(data, 0x90010000 + ((i+3+ofs)<<21) + j); /* stw rX,j(r1) */
7489 EndPutM32Inc(data, 0x39610000 + j); /* addi r11,r1,j */
7490 EndPutM32Inc(data, 0x91610000 + (0x34+4*ap->Args[i].ArgReg)); /* stw r11,X(r1) */
7493 if(!(Flags & FLAG_WOSLIBBASE))
7495 pbasepos = data; /* store 16BIT reloc offset */
7496 EndPutM32Inc(data, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7498 EndPutM32Inc(data, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7499 EndPutM32Inc(data, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7500 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7501 EndPutM32Inc(data, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7502 EndPutM32Inc(data, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7503 EndPutM32Inc(data, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7504 EndPutM32Inc(data, 0x80010008); /* lwz r0,8(r1) = get old link register */
7505 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7506 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 = jump back */
7509 EndPutM32(tempbuf, HUNK_PPC_CODE);
7510 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
7511 DoOutputDirect(tempbuf, (data-tempbuf)&(~3));
7513 EndPutM32(tempbuf, HUNK_EXT);
7514 DoOutputDirect(tempbuf,4);
7516 /* here come the XDEF name references */
7518 if(Flags & FLAG_WOSLIBBASE)
7520 if(ap->Flags & (AMIPRAGFLAG_PPC0|AMIPRAGFLAG_PPC2))
7521 OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
7522 OutputXDEF(0, "__%s", name);
7524 else
7526 if(BaseName)
7527 OutputXREF((basepos-tempbuf-8)+2, EXT_DEXT16, "_%s", BaseName);
7528 if(!(ap->Flags & AMIPRAGFLAG_PPC))
7529 OutputXREF((pbasepos-tempbuf-8)+2, EXT_DEXT16, "_PowerPCBase");
7530 OutputXDEF(0, "_%s", name);
7532 EndPutM32(tempbuf, 0);
7533 DoOutputDirect(tempbuf,4);
7534 if(!(Flags & FLAG_NOSYMBOL))
7536 EndPutM32(tempbuf, HUNK_SYMBOL);
7537 DoOutputDirect(tempbuf,4);
7538 if(Flags & FLAG_WOSLIBBASE)
7539 OutputSYMBOL(0, "__%s", name);
7540 else
7541 OutputSYMBOL(0, "_%s", name);
7542 EndPutM32(tempbuf, 0);
7543 DoOutputDirect(tempbuf,4);
7545 EndPutM32(tempbuf, HUNK_END);
7547 return DoOutputDirect(tempbuf,4);
7550 uint32 FuncVBCCPUPText(struct AmiPragma *ap, uint32 flags, strptr name)
7552 int32 i;
7554 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7555 return 1;
7557 Flags |= FLAG_DONE;
7559 if(Flags & FLAG_SINGLEFILE)
7561 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
7563 if(HEADER)
7565 DoOutput("\n");
7566 DoOutputDirect(HEADER, headersize);
7570 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
7571 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
7573 if(Flags & FLAG_SINGLEFILE)
7574 DoOutput("\t.file\t\"%s.o\"\n", name);
7575 if(BaseName)
7576 DoOutput("\t.global %s\n", BaseName);
7577 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7578 "\t.align\t3\n%s:\n",name, name);
7580 if(flags & FUNCFLAG_TAG)
7582 /* Hack the stack-frame for varargs.
7583 Build stack-frame, but save LR in our own stack-frame,
7584 because we have to overwrite the lower 8 bytes of the
7585 caller's frame. */
7586 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7587 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7589 /* Save the caller's saved SP in our own stack-frame. */
7590 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix,
7591 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7593 /* Store r3-r8 at the top of our stack-frame and r9-r10
7594 at the low 8 bytes of the caller's frame. This way all
7595 arguments will reside in one continuous area. */
7596 for(i=3+ap->NumArgs-1; i <= 10; ++i)
7597 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i, 104+4*(i-3),
7598 PPCRegPrefix);
7600 else
7601 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7602 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7604 for(i = 0; i < ap->NumArgs; ++i)
7606 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
7608 if(i <= 7)
7609 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
7610 else
7611 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
7612 100+(i+1-8)*4, PPCRegPrefix, PPCRegPrefix);
7614 else
7615 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix,
7616 PPCRegPrefix, 100+ap->NumArgs*4, PPCRegPrefix);
7617 DoOutput("%d(%s1)\n", 36+4*ap->Args[i].ArgReg, PPCRegPrefix);
7620 /* Now place the real function call */
7621 /* store offset in Chaos->caos_Un.Offset */
7622 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7623 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix,
7624 ap->Bias, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7625 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7626 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7628 if(BaseName)
7630 if(Flags & FLAG_SMALLDATA)
7631 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix, BaseName,
7632 PPCRegPrefix);
7633 else
7634 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix,
7635 BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
7636 /* store basepointer in A6 */
7637 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix, PPCRegPrefix);
7640 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix, PPCRegPrefix);
7641 if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
7642 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7643 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7644 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
7645 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7646 else
7647 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7648 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
7650 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name,
7651 name, name);
7654 uint32 FuncVBCCPUPCode(struct AmiPragma *ap, uint32 flags, strptr name)
7656 int32 i, j=0, k, size;
7657 uint8 *data, *data2, *data3;
7658 struct ArHeader *arh;
7660 data = tempbuf;
7662 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7663 return 1;
7665 Flags |= FLAG_DONE;
7667 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7668 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7669 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7670 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7671 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
7672 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
7673 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
7674 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7675 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7676 *(data++) = 0; *(data++) = 0; *(data++) = 0;
7677 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
7678 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
7679 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
7680 EndPutM32Inc(data, 0); /* eeh->e_entry */
7681 EndPutM32Inc(data, 0); /* eeh->e_phoff */
7682 data2 = data; data += 4;
7683 EndPutM32Inc(data, 0); /* eeh->e_flags */
7684 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
7685 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
7686 EndPutM16Inc(data, 0); /* eeh->e_phnum */
7687 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
7688 EndPutM16Inc(data, 6); /* eeh->e_shnum */
7689 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
7691 data3 = data;
7692 if(flags & FUNCFLAG_TAG)
7694 /* Hack the stack-frame for varargs.
7695 Build stack-frame, but save LR in our own stack-frame,
7696 because we have to overwrite the lower 8 bytes of the
7697 caller's frame. */
7698 EndPutM32Inc(data, 0x9421FF80); /* stwu r1,-128(r1) */
7699 EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7700 EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
7702 /* Save the caller's saved SP in our own stack-frame. */
7703 EndPutM32Inc(data, 0x81610080); /* lwz r11,128(r1) */
7704 EndPutM32Inc(data, 0x91610060); /* stw r11,96(r1) */
7706 /* Store r3-r8 at the top of our stack-frame and r9-r10
7707 at the low 8 bytes of the caller's frame. This way all
7708 arguments will reside in one continuous area. */
7709 for(i=3+ap->NumArgs-1; i <= 10; ++i)
7710 EndPutM32Inc(data, 0x90010000 + (i<<21) + (104+4*(i-3))); /* stw rX,Y(r1) */
7712 else
7714 EndPutM32Inc(data, 0x9421FFA0); /* stwu r1,-96(r1) */
7715 EndPutM32Inc(data, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7716 EndPutM32Inc(data, 0x91610064); /* stw r11,100(r1) */
7719 for(i = 0; i < ap->NumArgs; ++i)
7721 j = 36+4*ap->Args[i].ArgReg;
7722 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
7724 if(i <= 7)
7726 EndPutM32Inc(data, 0x90010000 + ((i+3)<<21) + j); /* stw rX,j(r1) */
7728 else
7730 EndPutM32Inc(data, 0x81610000 + (100+(i+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7731 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,j(r1) */
7734 else
7736 EndPutM32Inc(data, 0x39610000 + (100+ap->NumArgs*4)); /* addi r11,r1,X */
7737 EndPutM32Inc(data, 0x91610000 + j); /* stw r11,X(r1) */
7741 /* Now place the real function call */
7742 EndPutM32Inc(data, 0x39610000 - ap->Bias); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7743 EndPutM32Inc(data, 0x91610008); /* stw r11,8(r1) */
7744 EndPutM32Inc(data, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7745 EndPutM32Inc(data, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7746 EndPutM32Inc(data, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7748 if(BaseName)
7750 if(Flags & FLAG_SMALLDATA)
7752 j = (data-data3)+2; /* store reloc offset */
7753 EndPutM32Inc(data, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7755 else
7757 j = (data-data3)+2; /* store reloc offset */
7758 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7759 EndPutM32Inc(data, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7761 EndPutM32Inc(data, 0x9161005C); /* stw r11,92(r1) */
7764 EndPutM32Inc(data, 0x38610008); /* addi r3,r1,8 */
7765 k = (data-data3); /* store reloc offset */
7766 EndPutM32Inc(data, 0x48000001); /* bl PPCCallOS */
7767 if(flags & FUNCFLAG_TAG) /* Varargs. Rebuild the caller's stack-frame. */
7769 EndPutM32Inc(data, 0x81610060); /* lwz r11,96(r1) */
7770 EndPutM32Inc(data, 0x91610080); /* stw r11,128(r1) */
7771 EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
7772 EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7773 EndPutM32Inc(data, 0x38210080); /* addi r1,r1,128 */
7775 else
7777 EndPutM32Inc(data, 0x81610064); /* lwz r11,100(r1) */
7778 EndPutM32Inc(data, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7779 EndPutM32Inc(data, 0x38210060); /* addi r1,r1,96 */
7782 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
7784 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7785 data += 44; /* 1 9 17 27 33 */
7787 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
7788 data2 = data-44;
7790 EndPutM32Inc(data, 0); /* esh[0].sh_name */
7791 EndPutM32Inc(data, 0); /* esh[0].sh_type */
7792 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
7793 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
7794 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
7795 EndPutM32Inc(data, 0); /* esh[0].sh_size */
7796 EndPutM32Inc(data, 0); /* esh[0].sh_link */
7797 EndPutM32Inc(data, 0); /* esh[0].sh_info */
7798 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
7799 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
7801 size = data2-data3;
7802 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
7803 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
7804 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
7805 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
7806 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
7807 EndPutM32Inc(data, size); /* esh[1].sh_size */
7808 EndPutM32Inc(data, 0); /* esh[1].sh_link */
7809 EndPutM32Inc(data, 0); /* esh[1].sh_info */
7810 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
7811 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
7813 data3 = data;
7814 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
7815 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
7816 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
7817 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
7818 data += 4; /* esh[2].sh_offset */
7819 data += 4; /* esh[2].sh_size */
7820 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7821 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
7822 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
7823 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7825 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
7826 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
7827 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
7828 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
7829 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
7830 EndPutM32Inc(data, 44); /* esh[3].sh_size */
7831 EndPutM32Inc(data, 0); /* esh[3].sh_link */
7832 EndPutM32Inc(data, 0); /* esh[3].sh_info */
7833 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
7834 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
7836 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
7837 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
7838 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
7839 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
7840 data += 4; /* esh[4].sh_offset */
7841 data += 4; /* esh[4].sh_size */
7842 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
7843 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7844 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
7845 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7847 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
7848 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
7849 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
7850 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
7851 data += 4; /* esh[0].sh_offset */
7852 data += 4; /* esh[0].sh_size */
7853 EndPutM32Inc(data, 0); /* esh[0].sh_link */
7854 EndPutM32Inc(data, 0); /* esh[0].sh_info */
7855 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
7856 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
7858 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
7859 EndPutM32(data3+(2*40)+(5*4), BaseName ? 6*16 : 5*16); /* esh[4].sh_size */
7861 data2 = data;
7862 data += BaseName ? 6*16 : 5*16;
7864 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
7866 i = 0;
7867 EndPutM32Inc(data2, i); /* esym[0].st_name */
7868 EndPutM32Inc(data2, 0); /* esym[0].st_value */
7869 EndPutM32Inc(data2, 0); /* esym[0].st_size */
7870 *(data2++) = 0; /* esym[0].st_info */
7871 *(data2++) = 0; /* esym[0].st_other */
7872 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
7873 data[0] = 0;
7875 i += 1;
7876 EndPutM32Inc(data2, i); /* esym[1].st_name */
7877 EndPutM32Inc(data2, 0); /* esym[1].st_value */
7878 EndPutM32Inc(data2, 0); /* esym[1].st_size */
7879 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
7880 *(data2++) = 0; /* esym[1].st_other */
7881 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
7883 sprintf((strptr)data+i, "%s.o", name); while(data[i++]) ; /* get next store space */
7884 EndPutM32Inc(data2, 0); /* esym[2].st_name */
7885 EndPutM32Inc(data2, 0); /* esym[2].st_value */
7886 EndPutM32Inc(data2, 0); /* esym[2].st_size */
7887 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
7888 *(data2++) = 0; /* esym[2].st_other */
7889 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
7891 EndPutM32Inc(data2, i); /* esym[3].st_name */
7892 EndPutM32Inc(data2, 0); /* esym[3].st_value */
7893 EndPutM32Inc(data2, size); /* esym[3].st_size */
7894 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
7895 *(data2++) = 0; /* esym[3].st_other */
7896 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
7898 sprintf((strptr)data+i, name); while(data[i++]) ; /* get next store space */
7899 EndPutM32Inc(data2, i); /* esym[4].st_name */
7900 EndPutM32Inc(data2, 0); /* esym[4].st_value */
7901 EndPutM32Inc(data2, 0); /* esym[4].st_size */
7902 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
7903 *(data2++) = 0; /* esym[4].st_other */
7904 EndPutM16Inc(data2, 0); /* esym[4].st_shndx */
7906 sprintf((strptr)data+i, "PPCCallOS"); while(data[i++]) ; /* get next store space */
7907 if(BaseName)
7909 EndPutM32Inc(data2, i); /* esym[5].st_name */
7910 EndPutM32Inc(data2, 0); /* esym[5].st_value */
7911 EndPutM32Inc(data2, 0); /* esym[5].st_size */
7912 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[5].st_info */
7913 *(data2++) = 0; /* esym[5].st_other */
7914 EndPutM16/*Inc*/(data2, 0); /* esym[5].st_shndx */
7916 sprintf((strptr)data+i, BaseName); while(data[i++]) ; /* get next store space */
7918 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
7919 while(i&3) /* long aligned */
7920 data[i++] = 0;
7921 data += i;
7923 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
7925 data2 = data;
7927 EndPutM32Inc(data, k); /* erel[0].r_offset */
7928 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_REL24)); /* erel[0].r_info - entry 4, type 10 */
7929 EndPutM32Inc(data, 0); /* erel[0].r_addend */
7931 if(BaseName)
7933 if(Flags & FLAG_SMALLDATA)
7935 EndPutM32Inc(data, j); /* erel[1].r_offset */
7936 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_SDAREL16)); /* erel[1].r_info - entry 5, type 32 */
7937 EndPutM32Inc(data, 0); /* erel[1].r_addend */
7939 else
7941 EndPutM32Inc(data, j); /* erel[1].r_offset */
7942 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_HA)); /* erel[1].r_info - entry 5, type 6 */
7943 EndPutM32Inc(data, 0); /* erel[1].r_addend */
7944 EndPutM32Inc(data, j+4); /* erel[2].r_offset */
7945 EndPutM32Inc(data, ELF32_R_INFO(5,R_PPC_ADDR16_LO)); /* erel[2].r_info - entry 5, type 4 */
7946 EndPutM32Inc(data, 0); /* erel[2].r_addend */
7949 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
7951 /* make ar header and store all */
7952 arh = (struct ArHeader *) (data+20);
7953 memset(arh, ' ', sizeof(struct ArHeader));
7955 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
7956 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
7957 arh->ar_mode[2] = '0';
7958 arh->ar_mode[0] = '6';
7959 arh->ar_fmag[0] = 96;
7960 arh->ar_fmag[1] = '\n';
7962 if((k = strlen(name) + 2) >= 16)
7964 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
7966 else
7968 k = 0;
7969 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
7972 j = k + (data-tempbuf);
7973 for(i = 9; j; --i) /* make decimal number */
7975 data[i] = (j%10)+'0';
7976 j /= 10;
7978 for(j = 0; i < 9; ++j)
7979 arh->ar_size[j] = data[++i];
7981 DoOutputDirect(arh, sizeof(struct ArHeader));
7983 if(k)
7985 DoOutput("%s.o", name);
7986 if(k & 1)
7987 *(data++) = 0x0A; /* alignment byte! */
7990 return DoOutputDirect(tempbuf, data-tempbuf);
7993 uint32 FuncVBCCMorphText(struct AmiPragma *ap, uint32 flags, strptr name)
7995 int32 i, nrcopyar = 0, stcksize = 16, basereg = 12;
7997 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
7998 return 1;
8000 Flags |= FLAG_DONE;
8002 if(Flags & FLAG_SINGLEFILE)
8004 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
8006 if(HEADER)
8008 DoOutput("\n");
8009 DoOutputDirect(HEADER, headersize);
8013 if(Flags & (FLAG_ASMSECTION|FLAG_SINGLEFILE))
8014 DoOutput("\t.section %s,\"acrx4\"\n", hunkname);
8016 if(Flags & FLAG_SINGLEFILE)
8017 DoOutput("\t.file\t\"%s.o\"\n", name);
8018 if(BaseName)
8019 DoOutput("\t.global %s\n", BaseName);
8020 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name, name);
8022 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
8024 if(Flags & FLAG_SMALLDATA)
8025 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
8026 PPCRegPrefix, BaseName, PPCRegPrefix);
8027 else
8028 DoOutput("\tlis\t%s11,%s@ha\n"
8029 "\tlwz\t%s12,%s@l(%s11)\n",
8030 PPCRegPrefix, BaseName, PPCRegPrefix, BaseName, PPCRegPrefix);
8032 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
8033 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
8036 else
8038 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8040 if(flags & FUNCFLAG_TAG)
8042 DoOutput(
8043 "\tmflr\t%s0\n"
8044 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8045 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8046 "\tstw\t%s0,4(%s1)\n"
8047 "\tsub\t%s11,%s1,%s12\n"
8048 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8049 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8050 "\tsrwi\t%s12,%s12,2\n"
8051 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8052 "\taddi\t%s12,%s1,4\n"
8053 "\tmr\t%s1,%s11\n" /* new stack frame */
8054 "\taddi\t%s11,%s11,8\n"
8055 "\tmtctr\t%s0\n"
8056 ".copyloop_%s:\n"
8057 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8058 "\tstwu\t%s0,4(%s11)\n"
8059 "\tbdnz\t.copyloop_%s\n"
8060 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8061 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8062 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8063 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8064 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8065 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8066 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8067 PPCRegPrefix, PPCRegPrefix, name,
8068 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8069 name, PPCRegPrefix, PPCRegPrefix);
8071 else if(ap->NumArgs >= 8)
8073 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8074 DoOutput(
8075 "\tmflr\t%s0\n"
8076 "\tstwu\t%s1,-%ld(%s1)\n"
8077 "\tstw\t%s0,%ld(%s1)\n",
8078 PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix,
8079 PPCRegPrefix, stcksize+4, PPCRegPrefix);
8081 basereg = 3;
8083 else if(flags & FUNCFLAG_TAG)
8085 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8086 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8088 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8089 || ap->NumArgs >= 8))
8091 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8092 "\tmflr\t%s0\n",
8093 PPCRegPrefix, stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix);
8096 if(nrcopyar)
8098 /* Hack the stack-frame for varargs.
8099 Build stack-frame, but save LR in our own stack-frame,
8100 because we have to overwrite the lower 8 bytes of the
8101 caller's frame. */
8102 /* Save the caller's saved SP in our own stack-frame. */
8103 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix,
8104 stcksize+nrcopyar*4, PPCRegPrefix, PPCRegPrefix, stcksize, PPCRegPrefix);
8106 /* Store r3-r8 at the top of our stack-frame and r9-r10
8107 at the low 8 bytes of the caller's frame. This way all
8108 arguments will reside in one continuous area.
8109 Only copy the really relevant parts. */
8110 for(i = 10; i > 10-nrcopyar; --i)
8111 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix, i,
8112 stcksize+4*(i-1+nrcopyar-8),PPCRegPrefix);
8115 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8117 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8119 for(i = ap->NumArgs-1; i; --i)
8121 if(i < 7)
8123 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix, 3+i, PPCRegPrefix,
8124 3+i-1);
8126 else if(i == 7)
8128 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix, PPCRegPrefix);
8130 else
8132 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8133 PPCRegPrefix, stcksize+((i-8)+3)*4, PPCRegPrefix, PPCRegPrefix,
8134 ((i-8)+3)*4, PPCRegPrefix);
8138 else
8140 /* shift all the arguments one field */
8141 for(i = ap->NumArgs+3; i > 3; --i)
8143 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix, i, PPCRegPrefix, i-1);
8148 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8149 || ap->NumArgs >= 8))
8150 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix, stcksize+4, PPCRegPrefix);
8152 if(BaseName)
8154 if(Flags & FLAG_SMALLDATA)
8155 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix, basereg,
8156 BaseName, PPCRegPrefix);
8157 else
8158 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8159 PPCRegPrefix, basereg, BaseName, PPCRegPrefix, basereg, BaseName,
8160 PPCRegPrefix, basereg);
8163 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8165 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8166 PPCRegPrefix, ap->Bias-2, PPCRegPrefix, PPCRegPrefix);
8168 else
8170 for(i = 0; i < ap->NumArgs; ++i)
8172 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8174 if(i <= 7)
8175 DoOutput("\tstw\t%s%ld,", PPCRegPrefix, i+3);
8176 else
8177 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix,
8178 stcksize+(i+2-8)*4, PPCRegPrefix, PPCRegPrefix);
8180 else
8181 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix,
8182 PPCRegPrefix, stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0),
8183 PPCRegPrefix);
8184 DoOutput("%d(%s2)\n", 4*ap->Args[i].ArgReg, PPCRegPrefix);
8187 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8188 PPCRegPrefix, PPCRegPrefix);
8190 /* store basepointer in A6 */
8191 if(BaseName)
8192 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix, PPCRegPrefix);
8194 /* Now place the real function call */
8195 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8196 PPCRegPrefix, ap->Bias);
8198 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix);
8201 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8203 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8204 PPCRegPrefix, stcksize, PPCRegPrefix, PPCRegPrefix,
8205 stcksize+nrcopyar*4,PPCRegPrefix);
8208 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8209 || ap->NumArgs >= 8))
8211 if(ap->NumArgs >= 8)
8213 DoOutput(
8214 "\tlwz\t%s0,%ld(%s1)\n"
8215 "\taddi\t%s1,%s1,%ld\n"
8216 "\tmtlr\t%s0\n",
8217 PPCRegPrefix,stcksize+4,PPCRegPrefix,PPCRegPrefix,PPCRegPrefix,
8218 stcksize,PPCRegPrefix);
8220 else
8222 DoOutput(
8223 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8224 "\tlwz\t%s0,4(%s1)\n"
8225 "\tmtlr\t%s0\n", PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8226 PPCRegPrefix, PPCRegPrefix);
8229 else
8231 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8232 "\taddi\t%s1,%s1,%ld\n"
8233 "\tmtlr\t%s0\n",
8234 PPCRegPrefix, stcksize+4, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
8235 stcksize+nrcopyar*4, PPCRegPrefix);
8238 DoOutput("\tblr\n");
8241 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8242 name, name, name);
8245 uint32 FuncVBCCMorphCode(struct AmiPragma *ap, uint32 flags, strptr name)
8247 int32 i, j, k=0, size, nrcopyar = 0, stcksize = 16, basereg = 12;
8248 uint8 *data, *data2, *data3;
8249 struct ArHeader *arh;
8251 data = tempbuf;
8253 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_PPC))
8254 return 1;
8256 Flags |= FLAG_DONE;
8258 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8259 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8260 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8261 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8262 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
8263 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
8264 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
8265 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8266 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8267 *(data++) = 0; *(data++) = 0; *(data++) = 0;
8268 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
8269 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
8270 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
8271 EndPutM32Inc(data, 0); /* eeh->e_entry */
8272 EndPutM32Inc(data, 0); /* eeh->e_phoff */
8273 data2 = data; data += 4;
8274 EndPutM32Inc(data, 0); /* eeh->e_flags */
8275 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
8276 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
8277 EndPutM16Inc(data, 0); /* eeh->e_phnum */
8278 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
8279 EndPutM16Inc(data, 6); /* eeh->e_shnum */
8280 EndPutM16Inc(data, 3); /* eeh->e_shstrndx - fourth table is string table */
8282 data3 = data;
8284 if(ap->Flags & (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12))
8286 if(Flags & FLAG_SMALLDATA)
8288 k = (data-data3)+2; /* store reloc offset */
8289 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8291 else
8293 k = (data-data3)+2; /* store reloc offset */
8294 EndPutM32Inc(data, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8295 EndPutM32Inc(data, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8298 EndPutM32Inc(data, 0x800c0000 - (ap->Bias-2));
8299 EndPutM32Inc(data, 0x7c0903a6); /* mtctr r0 */
8300 EndPutM32Inc(data, 0x4e800420); /* bctr */
8303 else
8305 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8307 if(flags & FUNCFLAG_TAG)
8309 /* mflr r0 = mfspr r0,8 = get link register */
8310 EndPutM32Inc(data, 0x7C0802A6);
8311 /* backchain to next frame: lwz r11,0(r1) */
8312 EndPutM32Inc(data, 0x81610000);
8313 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8314 EndPutM32Inc(data, 0x7D815850);
8315 EndPutM32Inc(data, 0x90010004); /* stw r0,4(r1) */
8316 EndPutM32Inc(data, 0x7D6C0850); /* sub r11,r1,r12 */
8317 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8318 EndPutM32Inc(data, 0x396BFFF0);
8319 EndPutM32Inc(data, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8320 EndPutM32Inc(data, 0x558CF0BE); /* srwi r12,r12,2 */
8321 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8322 EndPutM32Inc(data, 0x380CFFFE);
8323 EndPutM32Inc(data, 0x39810004); /* addi r12,r1,4 */
8324 EndPutM32Inc(data, 0x7D615B78); /* mr r1,r11 - new stack frame */
8325 EndPutM32Inc(data, 0x396B0008); /* addi r11,r11,8 */
8326 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8327 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8328 EndPutM32Inc(data, 0x840C0004);
8329 EndPutM32Inc(data, 0x940B0004); /* stwu r0,4(r11) */
8330 EndPutM32Inc(data, 0x4200FFF8); /* bdnz .l */
8331 /* stw r10,8(r1) - last register into stack */
8332 EndPutM32Inc(data, 0x91410008);
8334 else if(ap->NumArgs >= 8)
8336 stcksize = ((8 + (ap->NumArgs-7)*4 + 15) & (~15));
8337 EndPutM32Inc(data, 0x7C0802A6); /* mflr r0 */
8338 EndPutM32Inc(data, 0x94220000 - stcksize); /* stwu r1,-X(r1) */
8339 EndPutM32Inc(data, 0x90010000 + stcksize + 4); /* stw r0,Y(r1) */
8341 basereg = 3;
8343 else if(flags & FUNCFLAG_TAG)
8345 nrcopyar = ap->NumArgs > 8 ? 0 : 8 + 1 - ap->NumArgs;
8346 stcksize = (((nrcopyar + 2 + 3)&(~3))-nrcopyar)*4;
8349 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8350 || ap->NumArgs >= 8))
8352 EndPutM32Inc(data, 0x94210000+0x10000-(stcksize+nrcopyar*4)); /* stwu r1,-%d(r1) */
8353 /* mflr r0 = mfspr r0,8 = get link register */
8354 EndPutM32Inc(data, 0x7C0802A6);
8357 if(nrcopyar)
8359 /* Hack the stack-frame for varargs.
8360 Build stack-frame, but save LR in our own stack-frame,
8361 because we have to overwrite the lower 8 bytes of the
8362 caller's frame. */
8363 /* Save the caller's saved SP in our own stack-frame. */
8364 EndPutM32Inc(data, 0x81610000+stcksize+nrcopyar*4); /* lwz r11,%d(r1) */
8365 EndPutM32Inc(data, 0x91610000+stcksize); /* stw r11,%d(r1) */
8367 /* Store r3-r8 at the top of our stack-frame and r9-r10
8368 at the low 8 bytes of the caller's frame. This way all
8369 arguments will reside in one continuous area.
8370 Only copy the really relevant parts. */
8371 for(i = 10; i > 10-nrcopyar; --i)
8372 EndPutM32Inc(data, 0x90010000 + (i<<21) + (stcksize+4*(i-1+nrcopyar-8))); /* stw rX,Y(r1) */
8375 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8377 if(flags & FUNCFLAG_TAG || ap->NumArgs >= 8)
8379 for(i = ap->NumArgs-1; i; --i)
8381 if(i < 7)
8383 /* mr rX,rY */
8384 EndPutM32Inc(data, 0x7C000378 + ((3+i)<<21) + ((3+i-1)<<16) + ((3+i-1)<<11));
8386 else if(i == 7)
8388 /* stw r10,8(r1) */
8389 EndPutM32Inc(data, 0x91410008);
8391 else
8393 /* lwz r11,X(r1) */
8394 EndPutM32Inc(data, 0x81610000 + (stcksize+((i-8)+3)*4));
8395 EndPutM32Inc(data, 0x91620000 + ((i-8)+3)*4); /* stw r11,j(r1) */
8399 else
8401 /* shift all the arguments one field */
8402 for(i = ap->NumArgs+3; i > 3; --i)
8404 /* mr rX,rY */
8405 EndPutM32Inc(data, 0x7C000378 + (i<<21) + ((i-1)<<16) + ((i-1)<<11));
8410 if(!(ap->Flags & AMIPRAGFLAG_MOSBASESYSV) || !((flags & FUNCFLAG_TAG)
8411 || ap->NumArgs >= 8))
8412 EndPutM32Inc(data, 0x90010000+stcksize+4); /* stw r0,%d(r1) */
8414 if(BaseName)
8416 if(Flags & FLAG_SMALLDATA)
8418 k = (data-data3)+2; /* store reloc offset */
8419 EndPutM32Inc(data, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8421 else
8423 k = (data-data3)+2; /* store reloc offset */
8424 EndPutM32Inc(data, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8425 EndPutM32Inc(data, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8429 if(ap->Flags & AMIPRAGFLAG_MOSBASESYSV)
8431 /* lwz r0,X(r3) */
8432 EndPutM32Inc(data, 0x80040000 - (ap->Bias-2));
8433 EndPutM32Inc(data, 0x7C0903A6); /* mtctr r0 */
8434 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8436 else
8438 for(i = 0; i < ap->NumArgs; ++i)
8440 j = 4*ap->Args[i].ArgReg;
8441 if(!(flags & FUNCFLAG_TAG) || i < ap->NumArgs-1)
8443 if(i <= 7)
8445 EndPutM32Inc(data, 0x90020000 + ((i+3)<<21) + j); /* stw rX,j(r2) */
8447 else
8449 EndPutM32Inc(data, 0x81610000 + (stcksize+(i+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8450 EndPutM32Inc(data, 0x91620000 + j); /* stw r11,j(r1) */
8453 else
8455 EndPutM32Inc(data, 0x38810000 + (stcksize+8+(ap->NumArgs > 8 ? (ap->NumArgs-8)*4 : 0))); /* addi r4,r1,X */
8456 EndPutM32Inc(data, 0x90820000 + j); /* stw r4,X(r2) */
8461 EndPutM32Inc(data, 0x81620064); /* lwz r11,100(r2) */
8463 if(BaseName)
8464 EndPutM32Inc(data, 0x91820038); /* stw r12,56(r2) */
8466 /* Now place the real function call */
8467 EndPutM32Inc(data, 0x38600000 + 0x10000 - ap->Bias); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8469 EndPutM32Inc(data, 0x7D6903A6); /* mtctr r11 */
8470 EndPutM32Inc(data, 0x4E800421); /* bctrl */
8472 if(nrcopyar) /* Varargs. Rebuild the caller's stack-frame. */
8474 EndPutM32Inc(data, 0x81610000 + stcksize); /* lwz r11,X(r1) */
8475 EndPutM32Inc(data, 0x91610000 + (stcksize+nrcopyar*4)); /* stw r11,Y(r1) */
8478 if((ap->Flags & AMIPRAGFLAG_MOSBASESYSV) && ((flags & FUNCFLAG_TAG)
8479 || ap->NumArgs >= 8))
8481 if(ap->NumArgs >= 8)
8483 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8484 EndPutM32Inc(data, 0x38210000 + stcksize); /* addi r1,r1,Y */
8485 /* mtlr r0 = mtspr 8,r0 = restore link register */
8486 EndPutM32Inc(data, 0x7C0803A6);
8488 else
8490 /* restore old stack frame: lwz r1,0(r1) */
8491 EndPutM32Inc(data, 0x80210000);
8492 EndPutM32Inc(data, 0x80010004); /* lwz r0,4(r1) */
8493 /* mtlr r0 = mtspr 8,r0 = restore link register */
8494 EndPutM32Inc(data, 0x7C0803A6);
8497 else
8499 EndPutM32Inc(data, 0x80010000 + stcksize+4); /* lwz r0,X(r1) */
8500 EndPutM32Inc(data, 0x38210000 + (stcksize+nrcopyar*4)); /* addi r1,r1,Y */
8501 EndPutM32Inc(data, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8504 EndPutM32Inc(data, 0x4E800020); /* blr = bclr 20,0 */
8507 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8508 data += 44; /* 1 9 17 27 33 */
8510 EndPutM32(data2, data-tempbuf); /* eeh->e_shoff */
8511 data2 = data-44;
8513 EndPutM32Inc(data, 0); /* esh[0].sh_name */
8514 EndPutM32Inc(data, 0); /* esh[0].sh_type */
8515 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8516 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8517 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
8518 EndPutM32Inc(data, 0); /* esh[0].sh_size */
8519 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8520 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8521 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
8522 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8524 size = data2-data3;
8525 EndPutM32Inc(data, 27); /* esh[1].sh_name = .text */
8526 EndPutM32Inc(data, SHT_PROGBITS); /* esh[1].sh_type */
8527 EndPutM32Inc(data, SHF_ALLOC|SHF_EXECINSTR); /* esh[1].sh_flags */
8528 EndPutM32Inc(data, 0); /* esh[1].sh_addr */
8529 EndPutM32Inc(data, data3-tempbuf); /* esh[1].sh_offset */
8530 EndPutM32Inc(data, size); /* esh[1].sh_size */
8531 EndPutM32Inc(data, 0); /* esh[1].sh_link */
8532 EndPutM32Inc(data, 0); /* esh[1].sh_info */
8533 EndPutM32Inc(data, 16); /* esh[1].sh_addralign */
8534 EndPutM32Inc(data, 0); /* esh[1].sh_entsize */
8536 data3 = data;
8537 EndPutM32Inc(data, 33); /* esh[2].sh_name = .rela.text */
8538 EndPutM32Inc(data, SHT_RELA); /* esh[2].sh_type */
8539 EndPutM32Inc(data, 0); /* esh[2].sh_flags */
8540 EndPutM32Inc(data, 0); /* esh[2].sh_addr */
8541 data += 4; /* esh[2].sh_offset */
8542 data += 4; /* esh[2].sh_size */
8543 EndPutM32Inc(data, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8544 EndPutM32Inc(data, 1); /* esh[2].sh_info - the second entry is programm data */
8545 EndPutM32Inc(data, 4); /* esh[2].sh_addralign */
8546 EndPutM32Inc(data, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8548 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
8549 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
8550 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
8551 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
8552 EndPutM32Inc(data, data2-tempbuf); /* esh[3].sh_offset */
8553 EndPutM32Inc(data, 44); /* esh[3].sh_size */
8554 EndPutM32Inc(data, 0); /* esh[3].sh_link */
8555 EndPutM32Inc(data, 0); /* esh[3].sh_info */
8556 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
8557 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
8559 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
8560 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
8561 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
8562 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
8563 data += 4; /* esh[4].sh_offset */
8564 data += 4; /* esh[4].sh_size */
8565 EndPutM32Inc(data, 5); /* esh[4].sh_link - the sixth entry is our string table */
8566 EndPutM32Inc(data, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8567 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
8568 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8570 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
8571 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
8572 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
8573 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
8574 data += 4; /* esh[0].sh_offset */
8575 data += 4; /* esh[0].sh_size */
8576 EndPutM32Inc(data, 0); /* esh[0].sh_link */
8577 EndPutM32Inc(data, 0); /* esh[0].sh_info */
8578 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
8579 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
8581 EndPutM32(data3+(2*40)+(4*4), data-tempbuf); /* esh[4].sh_offset */
8582 EndPutM32(data3+(2*40)+(5*4), BaseName ? 5*16 : 4*16); /* esh[4].sh_size */
8584 data2 = data;
8585 data += BaseName ? 5*16 : 4*16;
8587 EndPutM32(data3+(3*40)+(4*4), data-tempbuf); /* esh[5].sh_offset */
8589 i = 0;
8590 EndPutM32Inc(data2, i); /* esym[0].st_name */
8591 EndPutM32Inc(data2, 0); /* esym[0].st_value */
8592 EndPutM32Inc(data2, 0); /* esym[0].st_size */
8593 *(data2++) = 0; /* esym[0].st_info */
8594 *(data2++) = 0; /* esym[0].st_other */
8595 EndPutM16Inc(data2, 0); /* esym[0].st_shndx */
8596 data[0] = 0;
8598 i += 1;
8599 EndPutM32Inc(data2, i); /* esym[1].st_name */
8600 EndPutM32Inc(data2, 0); /* esym[1].st_value */
8601 EndPutM32Inc(data2, 0); /* esym[1].st_size */
8602 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_FILE); /* esym[1].st_info */
8603 *(data2++) = 0; /* esym[1].st_other */
8604 EndPutM16Inc(data2, SHN_ABS); /* esym[1].st_shndx */
8606 sprintf((strptr)data+i, "%s.o", name); while(data[i++]) ; /* get next store space */
8607 EndPutM32Inc(data2, 0); /* esym[2].st_name */
8608 EndPutM32Inc(data2, 0); /* esym[2].st_value */
8609 EndPutM32Inc(data2, 0); /* esym[2].st_size */
8610 *(data2++) = ELF32_ST_INFO(STB_LOCAL,STT_SECTION); /* esym[2].st_info */
8611 *(data2++) = 0; /* esym[2].st_other */
8612 EndPutM16Inc(data2, 1); /* esym[2].st_shndx - the second entry is program section! */
8614 EndPutM32Inc(data2, i); /* esym[3].st_name */
8615 EndPutM32Inc(data2, 0); /* esym[3].st_value */
8616 EndPutM32Inc(data2, size); /* esym[3].st_size */
8617 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_FUNC); /* esym[3].st_info */
8618 *(data2++) = 0; /* esym[3].st_other */
8619 EndPutM16Inc(data2, 1); /* esym[3].st_shndx - the second entry is program section! */
8621 sprintf((strptr)data+i, name); while(data[i++]) ; /* get next store space */
8622 if(BaseName)
8624 EndPutM32Inc(data2, i); /* esym[4].st_name */
8625 EndPutM32Inc(data2, 0); /* esym[4].st_value */
8626 EndPutM32Inc(data2, 0); /* esym[4].st_size */
8627 *(data2++) = ELF32_ST_INFO(STB_GLOBAL,STT_NOTYPE); /* esym[4].st_info */
8628 *(data2++) = 0; /* esym[4].st_other */
8629 EndPutM16/*Inc*/(data2, 0); /* esym[4].st_shndx */
8631 sprintf((strptr)data+i, BaseName); while(data[i++]) ; /* get next store space */
8633 EndPutM32(data3+(3*40)+(5*4), i); /* esh[5].sh_size */
8634 while(i&3) /* long aligned */
8635 data[i++] = 0;
8636 data += i;
8638 EndPutM32(data3+(4*4), data-tempbuf); /* esh[2].sh_offset */
8640 data2 = data;
8642 if(BaseName)
8644 if(Flags & FLAG_SMALLDATA)
8646 EndPutM32Inc(data, k); /* erel[0].r_offset */
8647 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_SDAREL16)); /* erel[0].r_info - entry 4, type 32 */
8648 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8650 else
8652 EndPutM32Inc(data, k); /* erel[0].r_offset */
8653 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_HA)); /* erel[0].r_info - entry 4, type 6 */
8654 EndPutM32Inc(data, 0); /* erel[0].r_addend */
8655 EndPutM32Inc(data, k+4); /* erel[1].r_offset */
8656 EndPutM32Inc(data, ELF32_R_INFO(4,R_PPC_ADDR16_LO)); /* erel[1].r_info - entry 4, type 4 */
8657 EndPutM32Inc(data, 0); /* erel[1].r_addend */
8660 EndPutM32(data3+(5*4), data-data2); /* esh[2].sh_size */
8662 /* make ar header and store all */
8663 arh = (struct ArHeader *) (data+20);
8664 memset(arh, ' ', sizeof(struct ArHeader));
8666 arh->ar_time[sprintf(arh->ar_time, "%lu", (uint32) time(0))] = ' ';
8667 arh->ar_uid[0] = arh->ar_gid[0] = arh->ar_mode[1] =
8668 arh->ar_mode[2] = '0';
8669 arh->ar_mode[0] = '6';
8670 arh->ar_fmag[0] = 96;
8671 arh->ar_fmag[1] = '\n';
8673 if((k = strlen(name) + 2) >= 16)
8675 arh->ar_name[sprintf(arh->ar_name, "#1/%ld", k)] = ' ';
8677 else
8679 k = 0;
8680 arh->ar_name[sprintf(arh->ar_name, "%s.o", name)] = ' ';
8683 j = k + (data-tempbuf);
8684 for(i = 9; j; --i) /* make decimal number */
8686 data[i] = (j%10)+'0';
8687 j /= 10;
8689 for(j = 0; i < 9; ++j)
8690 arh->ar_size[j] = data[++i];
8692 DoOutputDirect(arh, sizeof(struct ArHeader));
8694 if(k)
8696 DoOutput("%s.o", name);
8697 if(k & 1)
8698 *(data++) = 0x0A; /* alignment byte! */
8701 return DoOutputDirect(tempbuf, data-tempbuf);
8704 uint32 FuncEModule(struct AmiPragma *ap, uint32 flags, strptr name)
8706 uint8 i, r;
8708 if(CheckError(ap, AMIPRAGFLAG_FLOATARG|AMIPRAGFLAG_A6USE|AMIPRAGFLAG_PPC) ||
8709 (flags & FUNCFLAG_ALIAS))
8710 return 1;
8712 if(LastBias >= ap->Bias)
8713 DoError(ERR_ILLEGAL_FUNCTION_POSITION, ap->Line, name);
8714 else
8716 Flags |= FLAG_DONE; /* We did something */
8718 for(LastBias += BIAS_OFFSET; LastBias < ap->Bias; LastBias += BIAS_OFFSET)
8719 DoOutputDirect("Dum\x10", 4);
8721 DoOutput("%c", toupper(name[0]));
8722 if(name[1])
8724 DoOutput("%c", tolower(name[1]));
8725 if(name[2])
8726 DoOutput("%s", name+2);
8728 if(!ap->NumArgs)
8729 DoOutputDirect("\x10", 1);
8730 else
8732 for(i = 0; i < ap->NumArgs; ++i)
8734 r = ap->Args[i].ArgReg;
8735 DoOutputDirect(&r, 1);
8739 return 1;
8742 uint32 FuncFD(struct AmiPragma *ap, uint32 flags, strptr name)
8744 int32 i;
8746 Flags |= FLAG_DONE; /* We did something */
8748 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8750 if(Flags & FLAG_ISPRIVATE)
8752 Flags ^= FLAG_ISPRIVATE;
8753 DoOutput("##public\n");
8756 else
8758 if(!(Flags & FLAG_ISPRIVATE))
8759 DoOutput("##private\n");
8760 Flags |= FLAG_ISPRIVATE;
8763 LastBias += BIAS_OFFSET;
8764 if(LastBias != ap->Bias)
8766 DoOutput("##bias %d\n", ap->Bias);
8767 LastBias = ap->Bias;
8770 if(ap->Abi != CurrentABI)
8772 switch(ap->Abi)
8774 case ABI_M68K: DoOutput("##abi M68k\n"); break;
8775 case ABI_PPC0: DoOutput("##abi PPC0\n"); break;
8776 case ABI_PPC2: DoOutput("##abi PPC2\n"); break;
8777 case ABI_PPC: DoOutput("##abi PPC\n"); break;
8779 CurrentABI = ap->Abi;
8782 DoOutput("%s("/*)*/, name);
8783 for(i = 0; i < ap->CallArgs; i++)
8784 DoOutput("%s%s", ap->Args[i].ArgName, i < ap->CallArgs-1 ? "," : "");
8785 DoOutput(/*(*/")("/*)*/);
8787 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8789 for(i = 0; i < ap->CallArgs; i++)
8791 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], i < ap->CallArgs-1 ?
8792 (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg ? "/" : ",") : "");
8795 return DoOutput(/*(*/")\n");
8798 /* called from FuncSFD directly */
8799 uint32 FuncClib(struct AmiPragma *ap, uint32 flags, strptr name)
8801 struct ClibData *cd;
8802 int32 i, s, c;
8804 Flags |= FLAG_DONE; /* We did something */
8806 if(!(cd = GetClibFunc(name, ap, flags)))
8807 return 1;
8809 s = MakeClibType(tempbuf, &cd->ReturnType, 0);
8810 DoOutputDirect(tempbuf, s);
8811 DoOutput(" %s("/*)*/, name);
8813 if(ap->NumArgs)
8815 for(i = 0; i < cd->NumArgs; i++)
8817 c = MakeClibType(tempbuf, &cd->Args[i], ap->Args[i].ArgName);
8818 if(s+c+2 > 75 && s)
8820 DoOutput(i ? ",\n\t" : "\n\t"); s = 8;
8822 else if(i)
8824 DoOutput(", "); s += 2;
8826 DoOutputDirect(tempbuf, c);
8827 s += c;
8830 else if(Flags2 & FLAG2_CLIBOUT)
8831 DoOutput("void");
8832 return DoOutput(/*(*/")%s", Flags2 & FLAG2_CLIBOUT ? ";\n" : "");
8835 uint32 FuncSFD(struct AmiPragma *ap, uint32 flags, strptr name)
8837 struct ClibData *cd;
8838 int32 i, j;
8840 if(!(cd = GetClibFunc(name, ap, flags)))
8841 return 1;
8843 if(ap->Flags & AMIPRAGFLAG_PUBLIC)
8845 if(Flags & FLAG_ISPRIVATE)
8847 Flags ^= FLAG_ISPRIVATE;
8848 DoOutput("==public\n");
8851 else
8853 if(!(Flags & FLAG_ISPRIVATE))
8854 DoOutput("==private\n");
8855 Flags |= FLAG_ISPRIVATE;
8858 if(ap->Abi != CurrentABI)
8860 switch(ap->Abi)
8862 case ABI_M68K: DoOutput("==abi M68k\n"); break;
8863 case ABI_PPC0: DoOutput("==abi PPC0\n"); break;
8864 case ABI_PPC2: DoOutput("==abi PPC2\n"); break;
8865 case ABI_PPC: DoOutput("==abi PPC\n"); break;
8867 CurrentABI = ap->Abi;
8870 if(LastBias+BIAS_OFFSET < ap->Bias)
8872 DoOutput("==reserve %ld\n", ((ap->Bias-LastBias)/BIAS_OFFSET)-1);
8873 LastBias = ap->Bias;
8875 else if(flags & FUNCFLAG_TAG)
8876 DoOutput("==varargs\n");
8877 else if((flags & FUNCFLAG_ALIAS) || LastBias == ap->Bias)
8878 DoOutput("==alias\n");
8879 else
8880 LastBias += BIAS_OFFSET;
8882 if(!FuncClib(ap, flags, name))
8883 return 0;
8885 DoOutput(" ("/*)*/);
8886 if(!(ap->Flags & AMIPRAGFLAG_PPC))
8888 strptr s;
8890 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8891 in step one, so the "-" can be placed at proper position. */
8892 for(j = i = 0; i < ap->NumArgs; i++)
8894 if(i == ap->NumArgs-1)
8896 s = ""; j += 2;
8898 else if(IsCPPType(&cd->Args[j>>1], CPP_TYPE_DOUBLE) && ap->Args[i].ArgReg < REG_FP0)
8900 s = (j&1) ? "," : "-"; ++j;
8902 else
8904 s = ","; j += 2;
8906 DoOutput("%s%s", RegNames[ap->Args[i].ArgReg], s);
8909 return DoOutput(/*(*/")\n");
8912 uint32 FuncOS4PPC(struct AmiPragma *ap, uint32 flags, strptr name)
8914 struct ClibData *cd;
8915 int32 i, noret = 0, registers;
8917 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
8918 return 1;
8920 Flags |= FLAG_DONE; /* We did something */
8922 if(!(cd = GetClibFunc(name, ap, flags)))
8923 return 1;
8925 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
8926 noret = 1; /* this is a void function */
8928 sprintf((strptr)tempbuf, "_%s_%s", GetIFXName(), name);
8929 OutClibType(&cd->ReturnType, (strptr)tempbuf);
8931 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8932 ap->NumArgs ? "," : "");
8933 for(i = 0; i < ap->NumArgs; ++i)
8935 DoOutput(" ");
8936 if(i == ap->NumArgs - 1 && (flags & FUNCFLAG_TAG))
8938 DoOutput("...\n");
8940 else
8942 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
8943 if(i < ap->NumArgs-1)
8944 DoOutput(",\n");
8947 if(flags & FUNCFLAG_TAG)
8949 struct ClibData *cd2;
8951 if(!(cd2 = GetClibFunc(ap->FuncName, ap, flags)))
8952 return 1;
8954 DoOutput(/*(*/")\n{\n"/*}*/
8955 " va_list ap;\n"
8956 " va_startlinear(ap, colorMap);\n"
8957 " ");
8958 if(!noret)
8959 DoOutput("return ");
8960 DoOutput("Self->%s(\n"/*)*/, ap->FuncName);
8961 for(i = 0; i < ap->NumArgs-1; ++i)
8963 DoOutput(" %s,\n", ap->Args[i].ArgName);
8965 DoOutput(" va_getlinearva(ap, "/*)*/);
8966 OutClibType(&cd2->Args[i], 0);
8967 DoOutput(/*((*/"));\n");
8969 else
8971 DoOutput(/*(*/")\n{\n"/*}*/
8972 " struct Library *LibBase = Self->Data.LibBase;\n"
8973 " struct ExecIFace *IExec = (struct ExecIFace *)"
8974 "Self->Data.IExecPrivate;\n");
8976 if(!noret)
8978 DoOutput(" ");
8979 OutClibType(&cd->ReturnType, "retval");
8980 DoOutput(";\n");
8983 DoOutput(
8984 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8985 "->EmuWS);\n");
8986 for(i = 0; i < ap->NumArgs; ++i)
8989 registers = GetRegisterData(ap) | 0x40000002; /* set A6 everytime */
8990 for(i = 0; i <= 15; ++i)
8992 if(registers & (1<< (16+i)))
8993 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames[i], i);
8995 DoOutput("\n ");
8997 if(!noret)
8999 DoOutput("retval = ("/*)*/);
9000 OutClibType(&cd->ReturnType, 0);
9001 DoOutput(/*(*/")");
9004 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
9005 " ET_Offset, -%d,\n"/*)*/,ap->Bias);
9006 for(i = 0; i < ap->NumArgs; ++i)
9008 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper[ap->Args[i].ArgReg],
9009 ap->Args[i].ArgName);
9011 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
9012 for(i = 0; i <= 15; ++i)
9014 if(registers & (1<< (16+i)))
9015 DoOutput(" regs[%ld] = save_%s;\n", i, RegNames[i]);
9018 if(!noret)
9019 DoOutput(" return retval;\n");
9021 return DoOutput(/*{*/"}\n\n");
9024 uint32 FuncOS4M68KCSTUB(struct AmiPragma *ap, uint32 flags, strptr name)
9026 struct ClibData *cd;
9027 int32 i, noret = 0;
9029 if(ap->NumArgs <= 7)
9030 return 1;
9032 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9033 return 1;
9035 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9036 return 1;
9038 Flags |= FLAG_DONE; /* We did something */
9040 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9041 noret = 1; /* this is a void function */
9043 sprintf((strptr)tempbuf, "Cstub_%s", name);
9044 OutClibType(&cd->ReturnType, (strptr)tempbuf);
9046 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9047 " struct ExecIFace *IExec = (struct ExecIFace *)"
9048 "Interface->Data.IExecPrivate;\n"
9049 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9050 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9052 if(!noret)
9053 DoOutput("return ");
9055 DoOutput("Interface->%s(\n"/*)*/,(flags & FUNCFLAG_TAG) ? ap->FuncName
9056 : name);
9057 for(i = 0; i < ap->NumArgs; ++i)
9059 DoOutput(" ("/*)*/);
9060 OutClibType(&cd->Args[i], 0);
9061 DoOutput(/*(*/") regarray[%d]", ap->Args[i].ArgReg);
9062 if(i < ap->NumArgs-1)
9063 DoOutput(",\n");
9065 return DoOutput(/*{(*/");\n}\n\n");
9068 uint32 FuncOS4M68K(struct AmiPragma *ap, uint32 flags, strptr name)
9070 struct ClibData *cd;
9071 int i;
9073 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9074 return 1;
9076 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9077 return 1;
9079 Flags |= FLAG_DONE; /* We did something */
9081 DoOutput(
9082 "\t.section .data\n"
9083 "\t.globl\tstub_%s\n"
9084 "\t.type\tstub_%s,@function\n"
9085 "\n"
9086 "stub_%s:\n"
9087 "\t.short\t0x4ef8\n"
9088 "\t.short 0\n"
9089 "\t.short 1\n"
9090 "\t.globl\tstub_%sPPC\n"
9091 "\t.long\tstub_%sPPC\n",name, name, name, name, name);
9093 if(ap->NumArgs > 7)
9095 Flags2 |= FLAG2_OS4M68KCSTUB;
9096 DoOutput(
9097 "\t.byte\t2\n" /* Rest of parameters in C */
9098 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9099 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9101 else
9103 DoOutput(
9104 "\t.byte\t%d\n" /* Rest of parameters in C */
9105 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9106 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9107 ap->NumArgs+2);
9108 for(i = 0; i < ap->NumArgs; ++i)
9110 DoOutput("\t.byte\t%d,REG68K_%s\n",i+4,
9111 RegNamesUpper[ap->Args[i].ArgReg]);
9114 DoOutput(
9115 "\t.section .text\n"
9116 "\t.align\t2\n"
9117 "\n"
9118 "stub_%sPPC:\n"
9119 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9120 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9121 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9122 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9123 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9124 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9125 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9126 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9127 name, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9128 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9129 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
9130 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
9132 if(ap->NumArgs > 7)
9134 /* Since this function has 11 arguments, we need a C stub */
9135 DoOutput(
9136 "\t.globl\tCstub_%s\n"
9137 "\tlis\t%s4,Cstub_%s@h\n"
9138 "\tori\t%s4,%s4,Cstub_%s@l\n"
9139 "\tmtlr\t%s4\n"
9140 "\tblrl\n",
9141 name, PPCRegPrefix, name, PPCRegPrefix, PPCRegPrefix, name, PPCRegPrefix);
9143 else
9145 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name);
9147 DoOutput(
9148 "\tlwz\t%s11,12(%s1)\n"
9149 "\tmtlr\t%s11\n"
9150 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9151 "\tblrl\n" /* Return to emulation */
9152 "\n"
9153 "\t.globl\tstub_%s68K\n"
9154 "\t.long\tstub_%s68K\n"
9155 "\t.byte\t0\n", /* Flags */
9156 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, name,
9157 name);
9159 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9161 DoOutput(
9162 "\t.byte\t1\n" /* One register (a7 only) */
9163 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9165 else
9167 DoOutput(
9168 "\t.byte\t2\n"
9169 "\t.byte\t1,REG68K_A7\n"
9170 "\t.byte\t3,REG68K_D0\n");
9173 return DoOutput(
9174 "\t.section .data\n"
9175 "\t.align\t4\n"
9176 "\n"
9177 "stub_%s68K:\n"
9178 "\t.short\t0x4e75\n" /* RTS */
9179 "\n", name);
9182 uint32 FuncOS4M68KVect(struct AmiPragma *ap, uint32 flags, strptr name)
9184 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9185 return 1;
9187 while(LastBias + BIAS_OFFSET < ap->Bias)
9189 DoOutput("\t.long\tstub_Reserved\n");
9190 LastBias += BIAS_OFFSET;
9192 LastBias = ap->Bias;
9194 return DoOutput("\t.long\tstub_%s\n", name);
9197 uint32 FuncXML(struct AmiPragma *ap, uint32 flags, strptr name)
9199 struct ClibData *cd;
9200 int32 i;
9202 if(CheckError(ap, AMIPRAGFLAG_PPC|AMIPRAGFLAG_MOS_ALL))
9203 return 1;
9205 if(flags & FUNCFLAG_ALIAS)
9206 DoError(ERR_ALIASES_NOT_SUPPORTED, ap->Line);
9208 Flags |= FLAG_DONE; /* We did something */
9210 if(!(cd = GetClibFunc(name, ap, flags)))
9211 return 1;
9213 while(LastBias+BIAS_OFFSET < ap->Bias)
9215 LastBias += BIAS_OFFSET;
9216 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9217 " status=\"unimplemented\"/>\n", LastBias);
9219 LastBias = ap->Bias;
9221 DoOutput("\t\t<method name=\"%s\" result=\"", name);
9222 OutClibType(&cd->ReturnType, 0);
9223 DoOutput("\">\n");
9224 for(i = 0; i < ap->NumArgs; ++i)
9226 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9227 i == ap->NumArgs-1 && (flags & FUNCFLAG_TAG) ? "var" : "",
9228 ap->Args[i].ArgName);
9229 OutClibType(&cd->Args[i], 0);
9230 DoOutput("\"/>\n");
9232 return DoOutput("\t\t</method>\n");
9235 uint32 FuncGateStubs(struct AmiPragma *ap, uint32 flags, strptr name)
9237 struct ClibData *cd;
9238 strptr ret = "return ";
9239 int32 i;
9241 if(CheckError(ap, AMIPRAGFLAG_ARGCOUNT|AMIPRAGFLAG_PPC))
9242 return 1;
9244 if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
9245 return 1;
9247 Flags |= FLAG_DONE; /* We did something */
9249 if(flags & FUNCFLAG_ALIAS)
9251 if(flags & FUNCFLAG_TAG)
9252 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9253 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name, ap->TagName);
9255 DoOutput("#define %s("/*)*/, name);
9256 for(i = 0; i < ap->NumArgs-1; ++i)
9257 DoOutput("%s, ", ap->Args[i].ArgName);
9258 DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
9259 for(i = 0; i < ap->NumArgs-1; ++i)
9260 DoOutput("(%s), ", ap->Args[i].ArgName);
9261 return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
9264 if((flags & FUNCFLAG_TAG))
9266 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9267 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", name);
9268 for(i = 0; i < ap->NumArgs-1; ++i)
9270 DoOutput("%s, ", ap->Args[i].ArgName);
9272 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9273 ap->FuncName);
9274 for(i = 0; i < ap->NumArgs-1; ++i)
9275 DoOutput("(%s), ", ap->Args[i].ArgName);
9276 DoOutput("("/*)*/);
9277 OutClibType(&cd->Args[i], 0);
9278 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9281 if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
9282 ret = "";
9284 if(!OutClibType(&cd->ReturnType, 0))
9285 return 0;
9287 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix, name);
9289 for(i = 0; i < ap->NumArgs; ++i)
9291 DoOutput(" ");
9292 OutClibType(&cd->Args[i], ap->Args[i].ArgName);
9293 DoOutput(" = ("/*)*/);
9294 OutClibType(&cd->Args[i], 0);
9295 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper[ap->Args[i].ArgReg]);
9296 if((Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB)) && (Flags2 & FLAG2_REGLIB))
9297 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9299 DoOutput(" %s%s%s("/*)*/, ret, subprefix, name);
9300 if(ap->NumArgs)
9302 if(Flags2 & FLAG2_PRELIB)
9304 if(Flags2 & FLAG2_REGLIB)
9305 DoOutput("___RegBase,");
9306 else
9307 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper);
9310 for(i = 0; i < ap->NumArgs-1; ++i)
9312 DoOutput("%s, ", ap->Args[i].ArgName);
9314 if(Flags2 & FLAG2_POSTLIB)
9316 if(Flags2 & FLAG2_REGLIB)
9317 DoOutput("%s, ___RegBase", ap->Args[i].ArgName);
9318 else
9319 DoOutput("%s, %s_BASE_NAME", ap->Args[i].ArgName, ShortBaseNameUpper);
9321 else
9322 DoOutput("%s", ap->Args[i].ArgName);
9324 else
9326 if(Flags2 & (FLAG2_PRELIB|FLAG2_POSTLIB))
9328 if(Flags2 & FLAG2_REGLIB)
9329 DoOutput("___RegBase");
9330 else
9331 DoOutput("%s_BASE_NAME", ShortBaseNameUpper);
9334 return DoOutput(/*(({*/"));\n}\n");
9337 static uint32 DoCallFunc(struct AmiPragma *ap, uint32 flags, strptr name, FuncType Func)
9339 uint32 res;
9341 if(Flags & FLAG_SINGLEFILE)
9343 sprintf(filename, filenamefmt, name);
9344 if(!OpenDest(filename))
9345 return 0;
9347 res = Func(ap, flags, name);
9348 if(Flags & FLAG_SINGLEFILE)
9350 CloseDest(filename);
9352 return res;
9355 static uint32 PrintComment(struct Comment *com, strptr comment)
9357 if(com->Private && !(Flags & FLAG_PRIVATE))
9358 return 1;
9359 else if((Flags2 & FLAG2_SFDOUT) && com->Version)
9361 return DoOutput("==version %d\n", com->Version);
9363 else if((Flags2 & FLAG2_SFDOUT) && com->ReservedNum)
9365 LastBias += BIAS_OFFSET*com->ReservedNum;
9366 return DoOutput("==reserve %d\n", com->ReservedNum);
9368 else if(!(Flags & FLAG_DOCOMMENT) || !comment)
9369 return 1;
9371 if(com->Data)
9373 if(!DoOutput(comment, com->Data))
9374 return 0;
9376 else if(com->ReservedNum)
9378 string temp[256];
9379 sprintf(temp, "* --- (%u function slot%s reserved here) ---", com->ReservedNum,
9380 com->ReservedNum == 1 ? "" : "s");
9381 if(!DoOutput(comment, temp))
9382 return 0;
9384 else if(com->Version)
9386 string temp[256];
9387 if(com->Version >= FIRST_KNOWN_RELEASE && com->Version <= LAST_KNOWN_RELEASE &&
9388 (Flags2 & FLAG2_SYSTEMRELEASE))
9389 sprintf(temp, "* --- functions in V%u or higher %s ---", com->Version,
9390 Release[com->Version-FIRST_KNOWN_RELEASE]);
9391 else
9392 sprintf(temp, "* --- functions in V%u or higher ---", com->Version);
9394 if(!DoOutput(comment, temp))
9395 return 0;
9397 return 1;
9400 static uint32 CallFunc(uint32 tagmode, strptr comment, FuncType Func)
9402 struct Comment *com;
9403 int32 i;
9404 struct AmiPragma *ap;
9406 com = (struct Comment *) Comment.First;
9408 for(ap = (struct AmiPragma *) AmiPragma.First; ap;
9409 ap = (struct AmiPragma *) ap->List.Next)
9411 if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
9413 DoError(ERR_A6_NOT_ALLOWED, ap->Line);
9415 else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
9417 while(com && com->Bias <= ap->Bias)
9419 if(!PrintComment(com, comment))
9420 return 0;
9421 com = (struct Comment *) com->List.Next;
9422 } /* comment loop */
9424 #ifdef DEBUG_OLD
9425 printf("Processing %s - %s\n", ap->FuncName ? ap->FuncName : "",
9426 ap->TagName ? ap->TagName : "");
9427 #endif
9429 if(tagmode != TAGMODE_TAGS)
9431 if(ap->FuncName && !DoCallFunc(ap, FUNCFLAG_NORMAL, ap->FuncName, Func))
9432 return 0;
9434 for(i = 0; i < ap->NumAlias; ++i)
9436 if(ap->AliasName[i]->Type & FUNCFLAG_NORMAL)
9438 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9439 return 0;
9444 if(tagmode)
9446 if(ap->TagName && !DoCallFunc(ap, FUNCFLAG_TAG, ap->TagName, Func))
9447 return 0;
9449 for(i = 0; i < ap->NumAlias; ++i)
9451 if(ap->AliasName[i]->Type & FUNCFLAG_TAG)
9453 if(!DoCallFunc(ap, FUNCFLAG_ALIAS|ap->AliasName[i]->Type, ap->AliasName[i]->AliasName, Func))
9454 return 0;
9460 while(com)
9462 if(!PrintComment(com, comment))
9463 return 0;
9464 com = (struct Comment *) com->List.Next;
9465 } /* comment loop */
9466 return 1;
9469 static uint32 PrintIncludes(void) /* copies the include lines */
9471 struct Include *inc;
9472 strptr s, s2;
9474 inc = (struct Include *) Includes.First;
9476 while(inc)
9478 s2 = (strptr) tempbuf;
9479 for(s = inc->Include; *s; ++s)
9481 switch(*s)
9483 case '<': *(s2++) = ' '; break;
9484 case '/':
9485 case '.': *(s2++) = '_'; break;
9486 case '>': break;
9487 default: *(s2++) = toupper(*s);
9489 *s2 = 0;
9491 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf, inc->Include);
9492 inc = (struct Include *) inc->List.Next;
9494 if(!Includes.First)
9495 DoOutput("#include <exec/types.h>\n");
9496 return DoOutput("\n");
9499 /* ------------------------------------------------------------------ */
9501 static int32 AddClibEntry(strptr buffer, strptr bufend, uint32 linenum)
9503 strptr buf = buffer;
9504 struct ClibData d, *f;
9506 memset(&d, 0, sizeof(struct ClibData));
9507 buf = SkipBlanksRet(buf);
9508 if(*buf == '#') /* preprocessor lines */
9510 #ifdef DEBUG_OLD
9511 printf("Found non-function bracket in preprocessor line %ld\n", linenum);
9512 #endif
9513 while(buf < bufend && *buf != '\n')
9514 ++buf;
9515 return buf-buffer;
9517 if(!strnicmp(buf, "ASM", 3))
9518 buf = SkipBlanks(buf+3);
9519 /* else if(!strnicmp(buf, "STACK", 5))
9520 buf = SkipBlanks(buf+5);
9522 else if(!strnicmp(buf, "REGS", 4))
9523 buf = SkipBlanks(buf+4);
9525 if(!strnicmp(buf, "extern", 6))
9527 buf = SkipBlanksRet(buf+6);
9528 if(!strnicmp(buf, "\"C\"", 3)) /* CPP: extern "C" */
9530 buf = SkipBlanksRet(buf+3);
9531 if (*buf == '{')
9533 buf = SkipBlanksRet(buf+1);
9538 if(!GetCPPType(&d.ReturnType, buf, 1, 1))
9540 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE, linenum);
9541 return 0;
9543 else if(d.ReturnType.Unknown)
9544 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_RETURNVALUE_TYPE_INT, linenum,
9545 d.ReturnType.Unknown);
9547 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9549 strptr r = d.ReturnType.TypeStart;
9550 while(*r != '('/*)*/) ++r;
9551 r = SkipBlanks(++r); /* the bracket */
9552 d.FuncName = SkipBlanks(++r); /* the asterisk */
9554 else
9555 d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
9556 buf = d.FuncName;
9557 while(*(buf++) != '('/*)*/)
9559 *(SkipName(d.FuncName)) = 0;
9560 if(!(*d.FuncName))
9562 #ifdef DEBUG_OLD
9563 printf("Found non-function bracket in line %ld\n", linenum);
9564 #endif
9565 while(buf < bufend && *buf != '\n')
9566 ++buf;
9567 return buf-buffer;
9569 buf = SkipBlanksRet(buf);
9571 while(*buf != /*(*/')' && buf < bufend)
9573 if(d.NumArgs == MAXREGPPC+1)
9575 DoError(ERROFFSET_CLIB | ERR_TO_MUCH_ARGUMENTS, linenum);
9576 return 0;
9578 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 0, 1))
9580 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
9581 return 0;
9583 else if(d.Args[d.NumArgs-1].Unknown)
9584 DoError(ERROFFSET_CLIB | ERR_UNKNOWN_VARIABLE_TYPE_INT, linenum,
9585 d.NumArgs, d.Args[d.NumArgs-1].Unknown);
9587 buf = d.Args[d.NumArgs-1].TypeStart + d.Args[d.NumArgs-1].FullLength;
9588 while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
9589 ++buf;
9590 #ifdef DEBUG
9591 printf("Added argument %d for %s (%d bytes)\n", d.NumArgs, d.FuncName,
9592 d.Args[d.NumArgs-1].FullLength);
9593 #endif
9594 if(*buf == ',')
9595 buf = SkipBlanksRet(++buf);
9598 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9599 d.NumArgs = 0; /* void arguments are no arguments */
9601 if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9602 return -1;
9604 memcpy(f, &d, sizeof(struct ClibData));
9606 if(!clibdata)
9607 clibdata = f;
9608 else
9610 struct ClibData *e = clibdata;
9611 while(e->Next)
9612 e = e->Next;
9613 e->Next = f;
9615 if(d.ReturnType.Flags & CPP_FLAG_FUNCTION)
9617 int numclose = 2, numopen = 1;
9618 while(buf < bufend && (numclose || numopen > 0))
9620 if(*buf == '('/*)*/) { ++numclose; --numopen; }
9621 else if(*buf == /*(*/')') --numclose;
9622 ++buf;
9626 #ifdef DEBUG
9627 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9628 f->FuncName, linenum, buf-buffer, f->NumArgs);
9629 #endif
9630 return buf-buffer;
9633 static int32 ScanClibFile(strptr buf, strptr bufend)
9635 strptr linestart = buf;
9636 uint32 linenum = 1;
9637 int added = 0;
9639 /* remove comments and other not so nice characters */
9640 while(buf < bufend)
9642 if(*buf == '\t' || *buf == '\r' || *buf == (string)0xA0)
9643 *(buf++) = ' ';
9644 else if(buf[0] == '/' && buf < bufend-1)
9646 if(buf[1] == '*')
9648 while(buf < bufend-1 && (buf[0] != '*' || buf[1] != '/'))
9650 if(*buf != '\n')
9651 *buf = ' ';
9652 ++buf;
9654 *(buf++) = ' ';
9655 *(buf++) = ' ';
9657 else if(buf[1] == '/')
9659 while(buf < bufend && buf[0] != '\n')
9660 *(buf++) = ' ';
9661 ++buf;
9663 else
9664 ++buf;
9666 else if(buf[0] == '#' && strncmp("#include", buf, 8))
9668 while(buf < bufend && buf[0] != '\n')
9669 *(buf++) = ' ';
9670 ++buf;
9672 else
9673 ++buf;
9676 #ifdef DEBUG_OLD
9677 printf("-----------\n%s-----------\n", linestart);
9678 #endif
9680 buf = linestart;
9681 while(buf < bufend)
9683 if(*buf == '\n')
9685 ++buf; ++linenum;
9686 if(added)
9688 linestart = buf;
9689 added = 0;
9692 else if(!strncmp("#include", buf, 8))
9694 struct Include *d;
9696 if(!(d = (struct Include *) NewItem(&Includes)))
9697 return 0;
9698 d->Include = buf = SkipBlanks(buf+8);
9699 AddItem(&Includes, (struct ShortList *) d);
9700 while(*buf && *buf != '>' && *buf != '\n')
9701 ++buf;
9702 if(*buf == '>')
9703 ++buf;
9704 if(*buf == '\n')
9705 ++linenum;
9706 *(buf++) = 0;
9707 #ifdef DEBUG_OLD
9708 printf("Added Include line %s\n", d->Include);
9709 #endif
9710 added = 1;
9712 else if(*buf == '('/*)*/)
9714 int32 i;
9716 if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
9717 return 0;
9718 else if(!i)
9720 while(buf < bufend && *buf != '\n')
9721 ++buf; /* skip this line */
9723 else
9725 i -= buf-linestart;
9726 while(buf < bufend && i-- > 0)
9728 if(*(buf++) == '\n')
9730 linestart = buf;
9731 ++linenum;
9732 } /* skip this function */
9735 added = 1;
9737 else
9738 ++buf;
9739 } /* while */
9740 return 1;
9743 static int32 IsCPPType(struct CPP_NameType *data, uint8 type)
9745 if(!data || data->Flags || data->Type != type || data->PointerDepth)
9746 return 0;
9747 return type;
9750 static uint32 CheckRegisterNum(strptr string, struct CPP_NameType *data)
9752 uint32 i, j;
9754 for(i = 0; i < MAXREG; ++i)
9756 j = strlen(RegNames[i]);
9757 if(!strnicmp(string, RegNames[i], j))
9759 string += j;
9760 if(*string == ' ' || *string == '\t' || *string == '\n' || *string == /*(*/')')
9762 data->Register = i;
9763 data->Flags |= CPP_FLAG_REGISTER;
9764 return j;
9768 return 0;
9771 static uint32 ParseFuncPtrArgs(strptr buffer, struct CPP_NameType *data)
9773 strptr buf = buffer;
9774 struct ClibData d;
9776 memset(&d, 0, sizeof(struct ClibData));
9777 while(*buf != /*(*/')')
9779 if(d.NumArgs == MAXREGPPC+1)
9780 return 0;
9781 else if(!GetCPPType(&d.Args[d.NumArgs++], buf, 1, 1))
9782 return 0;
9784 buf += d.Args[d.NumArgs-1].FullLength;
9785 while(*buf != ',' && *buf != /*(*/')')
9786 ++buf;
9787 if(*buf == ',')
9788 buf = SkipBlanksRet(++buf);
9791 if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
9792 d.NumArgs = 0; /* void arguments are no arguments */
9794 if(d.NumArgs) /* no need to allocate structure for nothing */
9796 if(!(data->FuncPtr = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
9797 return 0;
9799 memcpy(data->FuncPtr, &d, sizeof(struct ClibData));
9801 return (uint32) (buf+1-buffer);
9804 /* rettype turns on usage of "extern" specifier */
9805 static int32 GetCPPType(struct CPP_NameType *data, strptr start, uint32 rettype, uint32 small)
9807 uint32 ok = 1, j;
9808 strptr u;
9810 data->Unknown = 0;
9811 data->Replace = 0;
9812 data->TypeStart = start = SkipBlanks(start);
9814 if(!strncmp(start, "REG", 3) && (start[3] == ' ' || start[3] == '\t' || start[3] == '\n' || start[3] == '('/*)*/))
9816 u = SkipBlanksRet(start+3);
9817 if(*u == '('/*)*/)
9819 u = SkipBlanks(u+1);
9820 if((j = CheckRegisterNum(u, data)))
9822 u = SkipBlanks(u+j);
9823 if(*u == ')')
9824 start = SkipBlanks(u+1);
9828 data->TypeStart = start;
9832 start = SkipBlanks((u = start));
9833 if(!strncmp("...",start,3))
9835 data->Type = CPP_TYPE_VARARGS;
9836 data->TypeLength = start+3 - (data->TypeStart);
9837 data->FullLength = data->TypeLength;
9838 return 1;
9840 if(CheckKeyword(start, "const", 5) || CheckKeyword(start, "CONST", 5))
9842 data->Flags |= CPP_FLAG_CONST; start += 5;
9844 else if(rettype && CheckKeyword(start, "extern", 6))
9846 start += 6; /* ignore it */
9848 else if(CheckKeyword(start, "long", 4))
9850 if(data->Flags & CPP_FLAG_LONG)
9851 data->Type = CPP_TYPE_LONGLONG;
9852 else
9853 data->Flags |= CPP_FLAG_LONG;
9855 start += 4;
9857 else if(CheckKeyword(start, "signed", 6))
9858 start += 6;
9859 else if(CheckKeyword(start, "unsigned", 8))
9861 data->Flags |= CPP_FLAG_UNSIGNED; start += 8;
9863 else if(CheckKeyword(start, "register", 8))
9865 data->Flags |= CPP_FLAG_REGISTER; start += 8;
9866 data->Register = UNDEFREGISTER;
9868 else if(CheckKeyword(start, "struct", 6))
9870 start = SkipBlanks(start+6);
9871 data->Flags |= CPP_FLAG_STRUCT;
9872 if(*start == '?') /* ? for external types */
9874 data->StructureLength = 0;
9875 data->StructureName = "";
9876 ++start;
9878 else if(*start == '!') /* ! for typedef types */
9880 data->Flags |= CPP_FLAG_TYPEDEFNAME;
9881 ++start;
9882 /* structure name and length already set */
9884 else
9886 start = SkipName((data->StructureName = start));
9887 data->StructureLength = start-data->StructureName;
9890 else if(CheckKeyword(start, "union", 5))
9892 start = SkipBlanks(start+5);
9893 data->Flags |= CPP_FLAG_UNION;
9894 if(*start != '?') /* ? for external types */
9896 start = SkipName((data->StructureName = start));
9897 data->StructureLength = start-data->StructureName;
9899 else
9901 data->StructureLength = 0;
9902 data->StructureName = "";
9903 ++start;
9906 else if(CheckKeyword(start, "enum", 4))
9908 start = SkipBlanks(start+4);
9909 data->Flags |= CPP_FLAG_ENUM;
9910 if(*start != '?') /* ? for external types */
9912 start = SkipName((data->StructureName = start));
9913 data->StructureLength = start-data->StructureName;
9915 else
9917 data->StructureLength = 0;
9918 data->StructureName = "";
9919 ++start;
9922 else if(*start == '*')
9924 ++start; ++data->PointerDepth;
9926 else if(*start == '[')
9928 data->Flags |= CPP_FLAG_ARRAY;
9929 while(*start && *start != ']')
9930 ++start;
9931 if(*start)
9932 ++start;
9934 else if(start[0] == '_' && start[1] == '_' && (j = CheckRegisterNum(start+2, data)))
9935 start += 2 + j;
9936 else if(!data->Type)
9938 uint32 i;
9940 for(i = 0; CPP_Field[i].Text; ++i)
9942 if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length) &&
9943 (start[CPP_Field[i].Length] == ' ' ||
9944 start[CPP_Field[i].Length] == '\t' ||
9945 start[CPP_Field[i].Length] == '\n' ||
9946 start[CPP_Field[i].Length] == ',' ||
9947 start[CPP_Field[i].Length] == /*(*/')' ||
9948 start[CPP_Field[i].Length] == '('/*)*/ ||
9949 start[CPP_Field[i].Length] == '*'))
9951 start += CPP_Field[i].Length;
9952 data->Type = CPP_Field[i].Type;
9953 data->Flags |= CPP_Field[i].Flags;
9954 if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
9955 ++data->PointerDepth;
9956 break;
9959 if(CPP_Field[i].Text)
9960 continue;
9961 else if(extnames)
9963 struct CPP_ExternNames *a = extnames;
9965 while(a)
9967 i = strlen(a->Type);
9968 if(!strncmp(a->Type, start, i) && !isalnum(start[i]) &&
9969 start[i] != '_')
9971 start += i;
9972 data->StructureName = a->NameType.StructureName;
9973 data->FuncPtr = a->NameType.FuncPtr;
9974 data->StructureLength = a->NameType.StructureLength;
9975 data->PointerDepth += a->NameType.PointerDepth;
9976 data->Type = a->NameType.Type;
9977 data->Flags |= a->NameType.Flags;
9978 data->FuncArgs = a->NameType.FuncArgs;
9979 data->ArgsLength = a->NameType.ArgsLength;
9980 break;
9983 /* check types here */
9984 a = a->Next;
9986 if(a)
9987 continue;
9988 else if((!data->Type) && (!data->Flags))
9990 long size;
9991 struct CPP_Unknown *u;
9993 data->Type = CPP_TYPE_INT;
9994 size = SkipName(start)-start;
9995 for(u = unknown; u && strncmp(u->Unknown, start, size); u = u->Next)
9997 if(!u)
9999 data->Unknown = DupString(start, size);
10000 if((u = (struct CPP_Unknown *) AllocListMem(sizeof(struct CPP_Unknown))))
10002 u->Next = unknown;
10003 u->Unknown = data->Unknown;
10004 unknown = u;
10007 start += size;
10008 continue;
10011 break;
10013 else
10014 break;
10015 }while(1);
10017 if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
10018 u = start;
10020 data->TypeLength = u - (data->TypeStart);
10021 data->FullLength = data->TypeLength;
10023 u = SkipBlanks(u);
10025 if(*u == '('/*)*/)
10027 ok = 0;
10028 u = SkipBlanksRet(++u);
10029 if(*u == '*')
10031 while(*u == '*')
10033 ++data->FuncPointerDepth; ++u;
10035 u = SkipBlanksRet(u);
10036 if(CheckKeyword(u, "const", 5) || CheckKeyword(u, "CONST", 5))
10038 data->Flags |= CPP_FLAG_CONST; u += 6;
10040 u = SkipBlanksRet(u);
10041 if(*u != /*(*/')')
10042 data->FunctionName = u;
10043 u = SkipBlanksRet(SkipName(u));
10044 if(*u == '('/*)*/)
10046 int numclose = 1;
10047 ++u;
10048 while(*u && numclose)
10050 if(*u == '('/*)*/) ++numclose;
10051 else if(*u == /*(*/')') --numclose;
10052 ++u;
10055 if(*u == /*(*/')')
10057 u = SkipBlanksRet(++u);
10058 if(*u == '('/*)*/)
10060 data->Flags |= CPP_FLAG_FUNCTION;
10062 if((j = ParseFuncPtrArgs(u+1, data)))
10063 ok = 1;
10064 data->FuncArgs = u;
10065 data->ArgsLength = j+1;
10066 data->FullLength = u+data->ArgsLength - (data->TypeStart);
10072 if(data->PointerDepth)
10073 data->Flags |= CPP_FLAG_POINTER;
10075 if(!(Flags2 & FLAG2_SMALLTYPES) && !small)
10077 if(!(data->Flags & (CPP_FLAG_STRPTR|CPP_FLAG_POINTER|CPP_FLAG_ENUM
10078 |CPP_FLAG_STRUCT|CPP_FLAG_UNION|CPP_FLAG_FUNCTION|CPP_FLAG_REGISTER)))
10080 if(data->Type == CPP_TYPE_BYTE || data->Type == CPP_TYPE_WORD || data->Type == CPP_TYPE_INT)
10082 if(data->Flags & CPP_FLAG_UNSIGNED)
10083 data->Replace = "const ULONG";
10084 else
10085 data->Replace = "const LONG";
10086 data->Type = CPP_TYPE_LONG;
10087 if(!(data->Flags & CPP_FLAG_CONST))
10088 data->Replace += 6;
10093 if(!data->Type && (data->Flags & CPP_FLAG_LONG))
10094 data->Type = CPP_TYPE_LONG;
10096 if((!data->Type && !data->Flags) || !ok)
10097 return 0;
10098 return 1;
10101 static struct ClibData *GetClibFunc(strptr name, struct AmiPragma *ap, uint32 flags)
10103 struct ClibData *d = clibdata;
10105 if(!name)
10107 DoError(ERR_ILLEGAL_INTERNAL_VALUE, 0);
10108 return 0;
10111 while(d && strcmp(name, d->FuncName))
10112 d = d->Next;
10114 if(!d)
10116 if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
10118 DoError(ERR_PROTOTYPE_MISSING, 0, name);
10119 ap->Flags |= AMIPRAGFLAG_NOCLIB;
10122 else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
10123 ap->CallArgs+1 != d->NumArgs))
10125 if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDARGWARN)))
10127 DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
10128 ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
10130 return 0;
10133 return d;
10136 static int32 CheckKeyword(strptr string, strptr keyword, int32 size)
10138 if(!strncmp(string, keyword, size))
10140 string += size;
10141 if(*string == ' ' || *string == '\t' || *string == '\n')
10142 return size;
10144 return 0;
10147 /* return nonzero, when usable, zero, when string already emitted */
10148 static uint32 CopyCPPType(strptr buffer, uint32 pass, struct ClibData *cd,
10149 struct AmiArgs *args)
10151 uint32 ret = 0, reg;
10152 uint32 i, j, k = 0;
10154 /* pass 0: signed strptr, MaxonC++ high args */
10155 /* pass 1: unsigned strptr, MaxonC++ high args */
10156 /* pass 2: signed strptr, StormC++ high args */
10157 /* pass 3: unsigned strptr, StormC++ high args */
10159 for(i = 0; i < cd->NumArgs; ++i)
10161 struct CPP_NameType *nt;
10163 nt = &cd->Args[i];
10165 if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
10166 reg = 1 + args[k].ArgReg;
10167 else if((nt->Flags & CPP_FLAG_REGISTER) && nt->Register != UNDEFREGISTER)
10168 reg = 1 + nt->Register;
10169 else
10170 reg = 0;
10172 if(reg--) /* subtract the added 1 */
10174 *(buffer++) = CPP_TYPE_REGISTER;
10175 if(reg >= 10)
10177 if(pass & 2)
10179 *(buffer++) = reg/10 + '0';
10180 *(buffer++) = reg%10 + '0';
10181 ret |= 2;
10183 else
10184 *(buffer++) = reg + (reg < 10 ? '0' : 'A'-10);
10186 else
10187 *(buffer++) = reg + '0';
10190 if(nt->Flags & CPP_FLAG_FUNCTION)
10192 for(j = 0; j < nt->FuncPointerDepth; ++j)
10193 *(buffer++) = CPP_TYPE_POINTER;
10194 *(buffer++) = CPP_TYPE_FUNCTION;
10196 for(j = 0; j < nt->PointerDepth; ++j)
10197 *(buffer++) = CPP_TYPE_POINTER;
10198 if(nt->Flags & CPP_FLAG_CONST)
10199 *(buffer++) = CPP_TYPE_CONST;
10200 if(nt->Flags & CPP_FLAG_UNSIGNED)
10201 *(buffer++) = CPP_TYPE_UNSIGNED;
10202 else if((nt->Flags & CPP_FLAG_STRPTR) && (pass & 1))
10204 *(buffer++) = CPP_TYPE_UNSIGNED;
10205 ret |= 1; /* we really use this pass */
10207 if(nt->Flags & CPP_FLAG_ENUM)
10208 *(buffer++) = CPP_TYPE_ENUM;
10209 if(nt->Type)
10210 *(buffer++) = cd->Args[i].Type;
10211 else
10213 uint32 i;
10214 sprintf(buffer, "%02lu", (uint32) nt->StructureLength); buffer += 2;
10215 for(i = 0; i < nt->StructureLength; ++i)
10216 *(buffer++) = nt->StructureName[i];
10218 if(nt->Flags & CPP_FLAG_FUNCTION)
10220 if(nt->FuncPtr)
10222 ret |= CopyCPPType(buffer, pass, nt->FuncPtr, 0);
10223 while(*buffer)
10224 ++buffer; /* skip to the new end */
10226 *(buffer++) = CPP_TYPE_FUNCEND;
10228 ++k;
10229 if(IsCPPType(nt, CPP_TYPE_DOUBLE)) /* double needs 2 registers */
10230 ++k;
10233 *(buffer) = 0;
10235 if(ret != pass)
10236 ret = 0;
10237 if(!pass)
10238 ret = 0x80;
10240 return ret; /* return nozero if this pass should be used */
10243 static uint32 OutClibType(struct CPP_NameType *nt, strptr txt)
10245 if(nt->Replace)
10246 DoOutput("%s", nt->Replace);
10247 else
10248 DoOutputDirect(nt->TypeStart, nt->TypeLength);
10249 if(nt->Type != CPP_TYPE_VARARGS)
10251 if(nt->Flags & CPP_FLAG_FUNCTION)
10253 uint32 i;
10254 DoOutput(" ("/*)*/);
10255 for(i = 0; i < nt->FuncPointerDepth; ++i)
10256 DoOutput("*");
10257 DoOutput(/*((*/txt ? "%s)" : ")", txt);
10258 if(nt->FuncArgs)
10259 return DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
10260 else
10261 return DoOutput("()");
10263 else if(txt)
10264 return DoOutput(" %s", txt);
10267 return 1;
10270 static uint32 MakeClibType(strptr dest, struct CPP_NameType *nt, strptr txt)
10272 strptr a;
10274 a = dest;
10275 if(nt->Replace)
10277 uint32 i;
10278 i = strlen(nt->Replace);
10279 memcpy(a, nt->Replace, i);
10280 a += i;
10282 else
10284 memcpy(a, nt->TypeStart, nt->TypeLength);
10285 a += nt->TypeLength;
10288 if(nt->Type != CPP_TYPE_VARARGS)
10290 if(nt->Flags & CPP_FLAG_FUNCTION)
10292 a += sprintf(a, (txt ? " (*%s)" : " (*)"), txt);
10293 if(nt->FuncArgs)
10295 memcpy(a, nt->FuncArgs, nt->ArgsLength);
10296 a += nt->ArgsLength;
10298 else
10299 a += sprintf(a, "()");
10301 else if(txt)
10302 a += sprintf(a, " %s", txt);
10304 return (uint32)(a-dest);
10307 static uint32 OutPASCALType(struct CPP_NameType *t, strptr txt, uint32 ret)
10309 int32 i = t->PointerDepth;
10311 if(t->Flags & CPP_FLAG_CONST)
10312 DoOutput("CONST ");
10313 if(!ret && i == 1 &&
10314 (t->Type == CPP_TYPE_LONG || t->Type == CPP_TYPE_WORD))
10316 DoOutput("VAR "); --i;
10319 DoOutput("%s : ", txt);
10321 if(!i && t->Flags == CPP_FLAG_BOOLEAN)
10322 return DoOutput("BOOLEAN");
10323 else if(i && t->Type == CPP_TYPE_VOID)
10324 return DoOutput("POINTER");
10325 else if(t->Flags & CPP_FLAG_FUNCTION)
10326 return DoOutput("tPROCEDURE");
10328 while(i--)
10329 DoOutput("p");
10331 if((t->Flags & (CPP_FLAG_STRUCT|CPP_FLAG_UNION)) && t->StructureLength)
10333 if(!t->PointerDepth)
10334 DoOutput("t");
10335 return DoOutputDirect(t->StructureName, t->StructureLength);
10338 if(t->Flags & CPP_FLAG_UNSIGNED)
10340 if(t->Type == CPP_TYPE_LONG)
10341 return DoOutput("CARDINAL");
10342 if(t->Type == CPP_TYPE_WORD)
10343 return DoOutput("int16");
10344 if(t->Type == CPP_TYPE_BYTE)
10345 return DoOutput(t->PointerDepth == 1 ? "CHAR" : "int8");
10347 else if(t->Type == CPP_TYPE_WORD)
10348 return DoOutput("INTEGER");
10349 else if(t->Type == CPP_TYPE_BYTE)
10350 return DoOutput("SHORTINT");
10351 return DoOutput("int32INT");
10354 /* ------------------------------------------------------------------ */
10356 static uint32 CallPrag(uint32 tagmode, strptr type, FuncType Func)
10358 if(type)
10359 if((*type && !DoOutput("#if%s\n", type)) ||
10360 !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
10361 (*type && !DoOutput("#endif\n")))
10362 return 0;
10363 return 1;
10366 static uint32 CreatePragmaFile(strptr amicall, strptr libcall, strptr amitags,
10367 strptr libtags, uint32 mode)
10369 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10371 switch(mode)
10373 case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10374 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper,
10375 ShortBaseNameUpper); break;
10376 case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10377 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10378 case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10379 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper, ShortBaseNameUpper); break;
10380 case PRAGMODE_NONE: break;
10381 default: return 0;
10384 if(HEADER)
10386 DoOutput("\n");
10387 DoOutputDirect(HEADER, headersize);
10390 if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10391 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10392 return 0;
10394 if((Flags & FLAG_EXTERNC) &&
10395 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10396 return 0;
10398 if(Flags & FLAG_GNUPRAG)
10400 DoOutput("#ifdef " TEXT_GNUC "\n#ifdef NO_OBSOLETE\n"
10401 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10402 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName);
10403 Flags |= FLAG_DONE;
10407 !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
10408 !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
10409 return 0;
10411 if(tagfuncs)
10414 !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
10415 !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
10416 return 0;
10419 if((Flags & FLAG_EXTERNC) &&
10420 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10421 return 0;
10423 switch(mode)
10425 case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10426 ShortBaseNameUpper); break;
10427 case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10428 ShortBaseNameUpper); break;
10429 case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10430 ShortBaseNameUpper); break;
10431 case PRAGMODE_NONE: break;
10432 default: return 0;
10434 return Output_Error;
10437 static uint32 CreateCSTUBSFile(void)
10439 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10441 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10442 ShortBaseNameUpper, ShortBaseNameUpper);
10444 if(!clibdata)
10446 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10449 if(HEADER)
10451 DoOutput("\n");
10452 DoOutputDirect(HEADER, headersize);
10455 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10456 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
10457 return 0;
10459 if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
10460 return 0;
10462 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10463 ShortBaseNameUpper);
10466 static uint32 CreateLVOFile(uint32 mode)
10468 strptr data = "_LVO_I";
10470 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10472 if(mode == 2 || mode == 4)
10473 data = "_LIB_I";
10475 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10476 ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
10477 (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
10478 (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
10479 !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
10480 !DoOutput("\n\n\t\tENDC\n"))
10481 return 0;
10483 return 1;
10486 static uint32 CreateLVOFilePPC(uint32 mode)
10488 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10490 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10491 ShortBaseNameUpper, ShortBaseNameUpper))
10492 return 0;
10493 if(HEADER)
10495 DoOutput("\n");
10496 DoOutputDirect(HEADER, headersize);
10498 switch(mode)
10500 case 0: CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCXDEF);
10501 case 1: CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVOPPC);
10503 return DoOutput("\n\t.endif\n");
10506 static uint32 CreateAsmStubs(uint32 mode, uint32 callmode)
10508 if(mode == 1 && (Flags2 & FLAG2_AUTOHEADER)) DoOutput("* %s\n\n", AUTOHEADERTEXT);
10510 /* 1 = Text, 2 = Code */
10511 switch(mode)
10513 case 1:
10514 if(HEADER)
10516 DoOutput("\n");
10517 DoOutputDirect(HEADER, headersize);
10520 if(!(Flags & FLAG_ASMSECTION))
10521 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname,
10522 Flags & FLAG_SMALLDATA ? "N" : "X", BaseName);
10523 if(!CallFunc(callmode, "\n%s", FuncAsmText))
10524 return 0;
10525 break;
10526 case 2:
10527 if(!CallFunc(callmode, 0, FuncAsmCode))
10528 return 0;
10529 break;
10532 return 1;
10535 static uint32 CreateProtoFile(uint32 Type)
10537 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10539 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
10540 ShortBaseNameUpper);
10542 if(HEADER)
10544 DoOutput("\n");
10545 DoOutputDirect(HEADER, headersize);
10548 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10549 if(Type != 5)
10550 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC ")\n"
10551 "#include <clib/%s_protos.h>\n#endif\n",
10552 ShortBaseNameUpper, ShortBaseName);
10554 if(BaseName)
10556 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10557 if(Type == 7)
10558 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10559 "#endif\n");
10560 DoOutput("%s;\n#endif\n", BaseName);
10563 if(Type != 8)
10565 if(Type >= 6)
10567 DoOutput("\n#ifdef " TEXT_GNUC "\n");
10568 if(Type == 10)
10569 DoOutput("#ifndef __cplusplus\n");
10570 DoOutput("#ifdef __AROS__\n");
10571 DoOutput("#include <defines/%s.h>\n", ShortBaseName);
10572 DoOutput("#else\n");
10573 DoOutput("#include <inline/%s.h>\n", ShortBaseName);
10574 DoOutput("#endif\n");
10575 if(Type == 10)
10576 DoOutput("#endif\n");
10577 if(Type != 7)
10579 if(Type == 9)
10580 DoOutput("#elif defined(" TEXT_VBCC ")\n"
10581 "#include <inline/%s_protos.h>\n#else", ShortBaseName);
10582 else
10583 DoOutput("#elif !defined(" TEXT_VBCC ")");
10586 if(Type == 10)
10587 DoOutput("\n#ifndef __PPC__");
10588 if(Type != 7)
10590 strptr str1 = "pragma", str2 = "lib";
10592 switch(Type)
10594 case 4: str1 = "pragmas"; /* no break; */
10595 case 2: str2 = "pragmas"; break;
10596 case 3: str1 = "pragmas"; break;
10597 case 5: str1 = "local"; str2 = "loc"; break;
10599 DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
10601 if(Type == 10)
10602 DoOutput("#endif\n");
10603 if(Type >= 6)
10604 DoOutput("#endif\n");
10607 Flags |= FLAG_DONE;
10609 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10612 static uint32 CreateLocalData(strptr to, uint32 callmode)
10614 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10616 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10617 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10618 ShortBaseNameUpper, ShortBaseNameUpper);
10620 if(HEADER)
10622 DoOutput("\n");
10623 DoOutputDirect(HEADER, headersize);
10626 DoOutput("\n");
10627 PrintIncludes();
10629 if((Flags & FLAG_EXTERNC) &&
10630 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10631 return 0;
10633 if(!CallFunc(callmode, "/%s */\n", FuncLocText))
10634 return 0;
10636 if((Flags & FLAG_EXTERNC) &&
10637 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10638 return 0;
10640 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper);
10642 sprintf(filename, "%s_loc.lib", ShortBaseName);
10643 if(!CloseDest(to) || !OpenDest(filename))
10644 return 0;
10646 CallFunc(callmode, 0, FuncLocCode);
10648 return CloseDest(filename);
10651 static uint32 CreateInline(uint32 mode, uint32 callmode)
10653 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10655 if(!clibdata)
10657 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10660 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10661 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper,
10662 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10664 if(HEADER)
10666 DoOutput("\n");
10667 DoOutputDirect(HEADER, headersize);
10670 DoOutput("\n");
10672 /* prevent loading of clib-file after inline */
10673 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10674 ShortBaseNameUpper, ShortBaseNameUpper);
10676 if(!mode)
10678 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10679 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10680 "#include <ppcinline/macros.h>\n#endif\n\n");
10681 else
10682 DoOutput("#ifndef __INLINE_MACROS_H\n"
10683 "#include <inline/macros.h>\n#endif\n\n");
10684 Flags |= FLAG_INLINENEW;
10686 else if(mode <= 2)
10688 if(Flags & (FLAG_POWERUP|FLAG_MORPHOS))
10689 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10690 "#include <ppcinline/stubs.h>\n#endif\n\n");
10691 else
10692 DoOutput("#ifndef __INLINE_STUB_H\n"
10693 "#include <inline/stubs.h>\n#endif\n\n");
10694 if(mode == 2)
10695 Flags |= FLAG_INLINESTUB;
10697 else if(mode == 3)
10698 Flags2 |= FLAG2_INLINEMAC;
10700 PrintIncludes();
10702 if((Flags & FLAG_EXTERNC) &&
10703 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10704 return 0;
10706 if(BaseName)
10708 if(mode && mode <= 2)
10710 if(Flags & FLAG_MORPHOS)
10711 DoOutput("#include <emul/emulregs.h>\n");
10712 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10713 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10714 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10715 "#define BASE_PAR_DECL0 void\n#endif\n"
10716 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10717 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10719 else
10720 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10721 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10724 if(mode <= 2)
10726 if(!CallFunc(callmode, "/%s */\n", FuncInline))
10727 return 0;
10729 else if(mode >= 6)
10731 if(mode == 7)
10732 Flags |= FLAG_INLINENEW;
10733 if(!CallFunc(callmode, "/%s */\n", FuncInlineDirect))
10734 return 0;
10736 else
10738 if(!CallFunc(callmode, "/%s */\n", FuncInlineNS))
10739 return 0;
10742 if(mode && mode <= 2 && BaseName)
10743 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10744 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper);
10746 if((Flags & FLAG_EXTERNC) &&
10747 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10748 return 0;
10750 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10751 Flags & (FLAG_POWERUP|FLAG_MORPHOS) ? "PPC" : "", ShortBaseNameUpper);
10754 static uint32 CreateGateStubs(uint32 callmode)
10756 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10758 if(!clibdata)
10760 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10762 if(!prefix[0] && !subprefix[0])
10764 DoError(ERR_PREFIX, 0); return 1;
10767 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10768 ShortBaseNameUpper, ShortBaseNameUpper);
10770 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10771 premacro, ShortBaseName);
10773 if(HEADER)
10775 DoOutput("\n");
10776 DoOutputDirect(HEADER, headersize);
10779 if(BaseName)
10781 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10782 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10783 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10784 "#define BASE_PAR_DECL0 void\n#endif\n"
10785 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10786 "BASE_EXT_DECL0\n", GetBaseType(), BaseName, ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10789 DoOutput("\n");
10791 if(!CallFunc(callmode, "/%s */\n", FuncGateStubs))
10792 return 0;
10794 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper);
10797 static uint32 CreateSASPowerUP(uint32 callmode)
10799 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10801 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10802 ShortBaseNameUpper, ShortBaseNameUpper);
10804 if(HEADER)
10806 DoOutput("\n");
10807 DoOutputDirect(HEADER, headersize);
10810 DoOutput("\n#ifdef __GNUC__\n"
10811 "#ifndef _PPCINLINE__%s_H\n"
10812 "#include <ppcinline/%s.h>\n"
10813 "#endif\n"
10814 "#else\n\n"
10815 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10816 "#include <ppclib/interface.h>\n"
10817 "#endif\n\n"
10818 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10819 "#include <gcclib/powerup_protos.h>\n"
10820 "#endif\n\n"
10821 "#ifndef NO_PPCINLINE_STDARG\n"
10822 "#define NO_PPCINLINE_STDARG\n"
10823 "#endif /* SAS-C PPC inlines */\n\n",
10824 ShortBaseNameUpper, ShortBaseName);
10826 if(BaseName)
10828 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10829 ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
10832 if(!CallFunc(callmode, "/%s */\n", FuncPowerUP))
10833 return 0;
10835 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10836 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper);
10839 static uint32 CreateProtoPowerUP(void)
10841 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
10843 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10844 ShortBaseNameUpper, ShortBaseNameUpper);
10846 if(HEADER)
10848 DoOutput("\n");
10849 DoOutputDirect(HEADER, headersize);
10852 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName);
10854 if(BaseName)
10856 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10857 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10858 "#endif\n%s;\n#endif\n", BaseName);
10861 DoOutput("\n#ifdef " TEXT_GNUC "\n"
10862 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10863 "#else\n#include <inline/%s.h>\n#endif\n"
10864 "#else /* SAS-C */\n"
10865 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10866 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10867 ShortBaseName, ShortBaseName, ShortBaseName, ShortBaseName);
10869 Flags |= FLAG_DONE;
10871 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper);
10874 static uint32 CreateFPCUnit(void)
10877 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT);
10879 if(!clibdata)
10881 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
10884 DoOutput("{\n");
10885 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName);
10887 if(HEADER)
10889 DoOutput("\n");
10890 DoOutputDirect(HEADER, headersize);
10893 DoOutput("**********************************************************************}\n\n");
10894 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10895 DoOutput("{$mode objfpc}\n");
10896 DoOutput("{$I useamigasmartlink.inc}\n");
10897 DoOutput("{$ifdef use_amiga_smartlink}\n");
10898 DoOutput(" {$smartlink on}\n");
10899 DoOutput("{$endif use_amiga_smartlink}\n\n");
10901 DoOutput("UNIT %s;\n", ShortBaseNameUpper);
10903 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName, GetBaseTypeLib());
10905 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper,ShortBaseName);
10906 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName);
10907 DoOutput("{$I %s.inc}\n\n",ShortBaseName);
10909 if(!CallFunc(TAGMODE_NORMAL, 0, FuncFPCType))
10910 return 0;
10912 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10913 if(!CallFunc(TAGMODE_TAGS, 0, FuncFPCTypeTags))
10914 return 0;
10916 DoOutput("\n{Here we read how to compile this unit}\n");
10917 DoOutput("{You can remove this include and use a define instead}\n");
10918 DoOutput("{$I useautoopenlib.inc}\n");
10919 DoOutput("{$ifdef use_init_openlib}\n");
10920 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10921 DoOutput("{$endif use_init_openlib}\n");
10922 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10923 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper);
10924 DoOutput("\nIMPLEMENTATION\n\n");
10925 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10926 DoOutput("uses \n");
10927 DoOutput("{$ifndef dont_use_openlib}\n");
10928 DoOutput("msgbox, \n");
10929 DoOutput("{$endif dont_use_openlib}\n");
10930 DoOutput("tagsarray;\n\n");
10932 if(!CallFunc(TAGMODE_NORMAL, "(%s *)\n", FuncFPCUnit))
10933 return 0;
10935 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10936 if(!CallFunc(TAGMODE_TAGS,"(%s *)\n", FuncFPCTypeTagsUnit))
10937 return 0;
10939 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10940 DoOutput(" VERSION : string[2] = '0';\n");
10941 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10943 DoOutput("{$ifdef use_init_openlib}\n");
10944 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName);
10945 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper);
10947 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10948 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10949 DoOutput("begin\n");
10950 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10951 DoOutput(" if %s <> nil then begin\n",BaseName);
10952 DoOutput(" CloseLibrary(%s);\n",BaseName);
10953 DoOutput(" %s := nil;\n",BaseName);
10954 DoOutput(" end;\n");
10955 DoOutput("end;\n\n");
10956 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper);
10957 DoOutput("begin\n %s := nil;\n",BaseName);
10958 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10959 DoOutput(" if %s <> nil then begin\n",BaseName);
10960 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10961 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10962 DoOutput(" end else begin\n");
10963 DoOutput(" MessageBox('FPC Pascal Error',\n");
10964 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10965 DoOutput(" 'Deallocating resources and closing down',\n");
10966 DoOutput(" 'Oops');\n");
10967 DoOutput(" halt(20);\n");
10968 DoOutput(" end;\n");
10969 DoOutput("end;\n\n");
10970 DoOutput("begin\n");
10971 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper);
10972 DoOutput("{$endif use_init_openlib}\n\n");
10974 DoOutput("{$ifdef use_auto_openlib}\n");
10975 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName);
10977 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName);
10978 DoOutput("procedure Close%sLibrary;\n",ShortBaseName);
10979 DoOutput("begin\n");
10980 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName);
10981 DoOutput(" if %s <> nil then begin\n",BaseName);
10982 DoOutput(" CloseLibrary(%s);\n",BaseName);
10983 DoOutput(" %s := nil;\n",BaseName);
10984 DoOutput(" end;\n");
10985 DoOutput("end;\n\n");
10986 DoOutput("begin\n %s := nil;\n",BaseName);
10987 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName, ShortBaseNameUpper);
10988 DoOutput(" if %s <> nil then begin\n",BaseName);
10989 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName);
10990 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName);
10991 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper);
10992 DoOutput(" end else begin\n");
10993 DoOutput(" MessageBox('FPC Pascal Error',\n");
10994 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName);
10995 DoOutput(" 'Deallocating resources and closing down',\n");
10996 DoOutput(" 'Oops');\n");
10997 DoOutput(" halt(20);\n");
10998 DoOutput(" end;\n\n");
10999 DoOutput("{$endif use_auto_openlib}\n\n");
11001 DoOutput("{$ifdef dont_use_openlib}\n");
11002 DoOutput("begin\n");
11003 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper);
11004 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName);
11005 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName);
11006 DoOutput("{$endif dont_use_openlib}\n\n");
11008 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper);
11011 static uint32 CreateBMAP(void)
11013 return CallFunc(TAGMODE_NORMAL, 0, FuncBMAP);
11016 static uint32 CreateLVOLib(void)
11018 uint32 i;
11020 i = strlen(ShortBaseNameUpper);
11021 EndPutM32(tempbuf, HUNK_UNIT);
11022 EndPutM32(tempbuf+4, (i+3)>>2);
11023 DoOutputDirect(tempbuf, 8);
11024 DoOutputDirect(ShortBaseNameUpper, i);
11025 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11027 i = strlen(hunkname);
11028 EndPutM32(tempbuf, HUNK_NAME);
11029 EndPutM32(tempbuf+4, (i + 3)>>2);
11030 DoOutputDirect(tempbuf, 8);
11031 DoOutputDirect(hunkname, i);
11032 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11034 EndPutM32(tempbuf, HUNK_CODE);
11035 EndPutM32(tempbuf+4, 0);
11036 EndPutM32(tempbuf+8, HUNK_EXT);
11037 DoOutputDirect(tempbuf, 12);
11039 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOLib))
11040 return 0;
11042 EndPutM32(tempbuf, 0);
11043 EndPutM32(tempbuf+4, HUNK_END);
11044 return DoOutputDirect(tempbuf, 8);
11047 static uint32 CreateLVOLibPPC(void)
11049 uint8 *data = tempbuf, *data2, *data3;
11051 *(data++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11052 *(data++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11053 *(data++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11054 *(data++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11055 *(data++) = ELFCLASS32; /* eeh->e_ident[EI_CLASS] */
11056 *(data++) = ELFDATA2MSB; /* eeh->e_ident[EI_DATA] */
11057 *(data++) = EV_CURRENT; /* eeh->e_ident[EI_VERSION] */
11058 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11059 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11060 *(data++) = 0; *(data++) = 0; *(data++) = 0;
11061 EndPutM16Inc(data, ET_REL); /* eeh->e_type */
11062 EndPutM16Inc(data, EM_POWERPC); /* eeh->e_machine */
11063 EndPutM32Inc(data, EV_CURRENT); /* eeh->e_version */
11064 EndPutM32Inc(data, 0); /* eeh->e_entry */
11065 EndPutM32Inc(data, 0); /* eeh->e_phoff */
11066 data2 = data; data += 4;
11067 EndPutM32Inc(data, 0); /* eeh->e_flags */
11068 EndPutM16Inc(data, 52); /* eeh->e_ehsize */
11069 EndPutM16Inc(data, 0); /* eeh->e_phentsize */
11070 EndPutM16Inc(data, 0); /* eeh->e_phnum */
11071 EndPutM16Inc(data, 40); /* eeh->e_shentsize */
11072 EndPutM16Inc(data, 4); /* eeh->e_shnum */
11073 EndPutM16Inc(data, 1); /* eeh->e_shstrndx - first table is string table */
11075 data3 = data;
11076 memcpy(data, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11077 data += 28; /* 1 9 17*/
11078 EndPutM32(data2, data-tempbuf); /* store the entry */
11080 EndPutM32Inc(data, 0); /* esh[0].sh_name */
11081 EndPutM32Inc(data, 0); /* esh[0].sh_type */
11082 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11083 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11084 EndPutM32Inc(data, 0); /* esh[0].sh_offset */
11085 EndPutM32Inc(data, 0); /* esh[0].sh_size */
11086 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11087 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11088 EndPutM32Inc(data, 0); /* esh[0].sh_addralign */
11089 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11091 EndPutM32Inc(data, 17); /* esh[3].sh_name = .shstrtab */
11092 EndPutM32Inc(data, SHT_STRTAB); /* esh[3].sh_type */
11093 EndPutM32Inc(data, 0); /* esh[3].sh_flags */
11094 EndPutM32Inc(data, 0); /* esh[3].sh_addr */
11095 EndPutM32Inc(data, data3-tempbuf); /* esh[3].sh_offset */
11096 EndPutM32Inc(data, 27); /* esh[3].sh_size */
11097 EndPutM32Inc(data, 0); /* esh[3].sh_link */
11098 EndPutM32Inc(data, 0); /* esh[3].sh_info */
11099 EndPutM32Inc(data, 1); /* esh[3].sh_addralign */
11100 EndPutM32Inc(data, 0); /* esh[3].sh_entsize */
11102 EndPutM32Inc(data, 1); /* esh[4].sh_name = .symtab */
11103 EndPutM32Inc(data, SHT_SYMTAB); /* esh[4].sh_type */
11104 EndPutM32Inc(data, 0); /* esh[4].sh_flags */
11105 EndPutM32Inc(data, 0); /* esh[4].sh_addr */
11106 data2 = data;
11107 data += 4; /* esh[4].sh_offset */
11108 data += 4; /* esh[4].sh_size */
11109 EndPutM32Inc(data, 3); /* esh[4].sh_link - the third entry is our string table */
11110 EndPutM32Inc(data, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11111 EndPutM32Inc(data, 4); /* esh[4].sh_addralign */
11112 EndPutM32Inc(data, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11114 EndPutM32Inc(data, 9); /* esh[0].sh_name = .strtab */
11115 EndPutM32Inc(data, SHT_STRTAB); /* esh[0].sh_type */
11116 EndPutM32Inc(data, 0); /* esh[0].sh_flags */
11117 EndPutM32Inc(data, 0); /* esh[0].sh_addr */
11118 data3 = data;
11119 data += 4; /* esh[0].sh_offset */
11120 data += 4; /* esh[0].sh_size */
11121 EndPutM32Inc(data, 0); /* esh[0].sh_link */
11122 EndPutM32Inc(data, 0); /* esh[0].sh_info */
11123 EndPutM32Inc(data, 1); /* esh[0].sh_addralign */
11124 EndPutM32Inc(data, 0); /* esh[0].sh_entsize */
11126 EndPutM32Inc(data2, data-tempbuf);
11128 EndPutM32Inc(data,0);
11129 EndPutM32Inc(data,0); /* first entry is empty */
11130 EndPutM32Inc(data,0);
11131 EndPutM32Inc(data,0);
11133 symoffset = 1; /* initial value */
11134 elfbufpos = data;
11136 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCBias))
11137 return 0;
11138 EndPutM32(data2, elfbufpos-data+16);
11139 EndPutM32Inc(data3, elfbufpos-tempbuf);
11140 EndPutM32(data3, symoffset);
11142 *(elfbufpos++) = 0; /* first sym entry */
11143 if(!DoOutputDirect(tempbuf, elfbufpos-tempbuf))
11144 return 0;
11146 if(!CallFunc(TAGMODE_NORMAL, 0, FuncLVOPPCName))
11147 return 0;
11149 while((symoffset++)&3)
11151 if(!DoOutputDirect("", 1))
11152 return 0;
11155 return 1;
11158 static uint32 CreateVBCCInline(uint32 mode, uint32 callmode)
11160 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11162 if(!clibdata)
11164 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11167 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11168 ShortBaseNameUpper, ShortBaseNameUpper);
11170 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11171 if (mode == 2)
11173 /* always include emul/emulregs.h in MorphOS inlines,
11174 gcc-based sources might depend on it :| */
11175 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11178 if(HEADER)
11180 DoOutput("\n");
11181 DoOutputDirect(HEADER, headersize);
11184 DoOutput("\n");
11186 if(!CallFunc(callmode, "/%s */\n", mode ? (mode == 2 ? FuncVBCCMorphInline
11187 : FuncVBCCWOSInline) : FuncVBCCInline))
11188 return 0;
11190 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper);
11193 static uint32 CreateVBCC(uint32 mode, uint32 callmode)
11195 uint32 res = 0;
11197 if(mode != 2 && mode != 3)
11199 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11201 if(HEADER)
11203 DoOutput("\n");
11204 DoOutputDirect(HEADER, headersize);
11208 switch(mode)
11210 case 4: res = CallFunc(callmode, 0, FuncVBCCPUPText); break;
11212 case 3: Flags |= FLAG_WOSLIBBASE; /* no break! */
11213 case 2: res = CallFunc(callmode, 0, FuncVBCCWOSCode); break;
11215 case 1: Flags |= FLAG_WOSLIBBASE; /* no break! */
11216 case 0: res = CallFunc(callmode, "\n%s", FuncVBCCWOSText); break;
11218 return res;
11221 static uint32 CreateVBCCPUPLib(uint32 callmode)
11223 /* output header */
11224 DoOutput("!<arch>\n");
11226 return CallFunc(callmode, 0, FuncVBCCPUPCode);
11229 static uint32 CreateVBCCMorphCode(uint32 callmode)
11231 /* output header */
11232 DoOutput("!<arch>\n");
11234 return CallFunc(callmode, 0, FuncVBCCMorphCode);
11237 static uint32 CreateEModule(uint32 sorted)
11239 uint32 res = 0, i;
11240 if(sorted)
11241 DoError(ERR_NO_SORTED, 0);
11242 else
11244 DoOutputDirect("EMOD\0\x06", 6);
11245 for(res = 0; res < 2; ++res)
11247 for(i = 0; BaseName[i]; ++i)
11248 DoOutput("%c", tolower(BaseName[i]));
11249 DoOutputDirect("\x00",1);
11251 LastBias = BIAS_START-BIAS_OFFSET;
11252 CallFunc(TAGMODE_NORMAL, 0, FuncEModule);
11253 res = DoOutputDirect("\xFF",1);
11255 return res;
11258 static uint32 CreateProtoRedirect(void)
11260 Flags |= FLAG_DONE;
11261 return DoOutput("#ifdef NO_OBSOLETE\n"
11262 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11263 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName);
11266 static uint32 CreateSFD(uint32 callmode)
11268 struct Include *inc;
11269 struct AmiPragma *ap;
11270 if(!clibdata)
11272 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11275 if((ap = (struct AmiPragma *) AmiPragma.First))
11276 LastBias = ap->Bias-BIAS_OFFSET;
11277 else /* only security, never used normally */
11278 LastBias = 0;
11279 CurrentABI = ABI_M68K;
11281 if(IDstring)
11282 DoOutput("==id %s\n", IDstring);
11283 else
11285 time_t t;
11286 struct tm * tim;
11288 t = time(&t);
11289 tim = localtime(&t);
11291 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11292 "noname Exp $\n", '$', filename, tim->tm_year+1900, tim->tm_mon+1,
11293 tim->tm_mday, tim->tm_hour, tim->tm_min, tim->tm_sec);
11296 if(BaseName)
11297 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11298 GetLibraryName(), BaseName, GetBaseType(), GetLibraryName());
11299 DoOutput("==bias %ld\n==public\n", LastBias+BIAS_OFFSET);
11301 for(inc = (struct Include *) Includes.First; inc; inc = (struct Include *) inc->List.Next)
11302 DoOutput("==include %s\n", inc->Include);
11303 if(!Includes.First)
11304 DoOutput("==include <exec/types.h>\n");
11306 CallFunc(callmode, "%s\n", FuncSFD);
11308 return DoOutput("==end\n");
11311 static uint32 CreateClib(uint32 callmode)
11313 if(!clibdata)
11315 DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
11318 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11320 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper,
11321 ShortBaseNameUpper);
11323 if(HEADER)
11325 DoOutput("\n");
11326 DoOutputDirect(HEADER, headersize);
11328 else
11330 strptr s = 0;
11331 time_t t;
11332 struct tm * tim;
11334 t = time(&t);
11335 tim = localtime(&t);
11337 if(IDstring)
11339 s = SkipBlanks(IDstring+4);
11340 while(*s && *s != ' ')
11341 ++s;
11342 s=SkipBlanks(s);
11344 if(!s || !*s)
11345 s = "1.0";
11347 if(Flags2 & FLAG2_SYSTEMRELEASE)
11349 DoOutput("\n/*\n**\t$Id: %s %s\n", filename, s);
11351 else
11353 strptr t;
11355 t = s;
11356 while(*t && *t != ' ')
11357 ++t;
11358 *t = 0;
11360 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename, s,
11361 tim->tm_mday, tim->tm_mon+1, tim->tm_year+1900);
11363 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11364 if(!Copyright || (Copyright && strncmp("Copyright ", Copyright, 10)))
11365 DoOutput("Copyright © %d ", tim->tm_year+1900);
11366 DoOutput("%s\n", Copyright ? Copyright : Flags2 & FLAG2_SYSTEMRELEASE ?
11367 "Amiga, Inc." : "");
11368 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11371 PrintIncludes();
11373 if((Flags & FLAG_EXTERNC) &&
11374 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11375 return 0;
11377 CallFunc(callmode, "\n/%s */\n\n", FuncClib);
11379 if((Flags & FLAG_EXTERNC) &&
11380 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11381 return 0;
11383 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper);
11386 static uint32 CreateFD(void)
11388 LastBias = 0;
11389 CurrentABI = ABI_M68K;
11391 if(BaseName)
11392 DoOutput("##base _%s\n", BaseName);
11393 DoOutput("##public\n");
11395 CallFunc(TAGMODE_NORMAL, "%s\n", FuncFD);
11397 return DoOutput("##end\n");
11400 static uint32 CreateGenAuto(strptr to, uint32 type)
11402 strptr name, btype;
11403 uint8 *data;
11404 uint32 i, verref, exitfuncref, sysref2, exitref, rel1, rel2, nameref;
11405 if(!(name = GetLibraryName()))
11406 return 0;
11407 btype = GetBaseType();
11409 switch(type)
11411 case 0:
11412 Flags |= FLAG_DONE;
11413 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11414 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11415 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11416 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11417 btype, BaseName, BaseName,
11418 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", name, BaseName,
11419 priority, BaseName, BaseName, !strcmp("struct Library *", btype) ? "" : "(struct Library *) ", BaseName)))
11420 return 0;
11421 sprintf(filename, "%s_autoopenver.c", ShortBaseName);
11422 if(!CloseDest(to) || !OpenDest(filename))
11423 return 0;
11424 Flags |= FLAG_DONE;
11425 return DoOutput("unsigned long _%sVer = 0;\n", BaseName);
11426 break;
11427 case 1: /* m68k */
11428 Flags |= FLAG_DONE;
11429 i = strlen(filename)-4; /* remove .lib extension */
11430 EndPutM32(tempbuf, HUNK_UNIT);
11431 EndPutM32(tempbuf+4, (i+3)>>2);
11432 DoOutputDirect(tempbuf, 8);
11433 DoOutputDirect(filename, i);
11434 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11436 i = strlen(hunkname);
11437 EndPutM32(tempbuf, HUNK_NAME);
11438 EndPutM32(tempbuf+4, (i + 3)>>2);
11439 DoOutputDirect(tempbuf, 8);
11440 DoOutputDirect(hunkname, i);
11441 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11443 data = tempbuf+8; /* we need HUNK_CODE + size at start */
11444 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11445 /* SysBase */
11446 if(Flags & FLAG_SMALLDATA)
11448 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11449 EndPutM16Inc(data, 0); /* place for sysbase reference */
11451 else
11453 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11454 EndPutM32Inc(data, 0); /* place for sysbase reference */
11456 verref = data-tempbuf-8+2;
11457 if(Flags & FLAG_SMALLDATA)
11459 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11460 EndPutM16Inc(data, 0); /* place for basevers reference */
11462 else
11464 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11465 EndPutM32Inc(data, 0); /* place for basevers reference */
11467 EndPutM32Inc(data, 0x43FA0030 + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2) + ((Flags & FLAG_SMALLDATA) ? 0 : 6));
11468 EndPutM32Inc(data, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11470 rel1 = data-tempbuf-8+2;
11471 if(Flags & FLAG_SMALLDATA)
11473 EndPutM16Inc(data, 0x2940); /* MOVE.L D0,xxx(A4) */
11474 EndPutM16Inc(data, 0);
11476 else
11478 EndPutM16Inc(data, 0x23C0); /* MOVE.L D0,xxx */
11479 EndPutM32Inc(data, 0);
11481 EndPutM16Inc(data, 0x660A + ((Flags2 & FLAG2_SMALLCODE) ? 0 : 2)); /* BNE.B .lib */
11482 EndPutM32Inc(data, 0x48780014); /* PEA 20 */
11484 exitfuncref = data-tempbuf-8+2;
11485 if(Flags2 & FLAG2_SMALLCODE)
11487 EndPutM16Inc(data, 0x4EBA); /* JSR _exit(PC) */
11488 EndPutM16Inc(data, 0); /* place for base reference */
11490 else
11492 EndPutM16Inc(data, 0x4EB9); /* JSR _exit */
11493 EndPutM32Inc(data, 0); /* place for base reference */
11495 EndPutM16Inc(data, 0x584F); /* ADDQ.W, #4,A7 */
11496 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11497 EndPutM16Inc(data,0x4E75); /* RTS */
11498 exitref = data-tempbuf-8;
11500 EndPutM16Inc(data, 0x2F0E); /* MOVE.L A6,-(A7) */
11501 sysref2 = data-tempbuf-8+2;
11502 /* SysBase */
11503 if(Flags & FLAG_SMALLDATA)
11505 EndPutM16Inc(data, 0x2C6C); /* MOVEA.L base(A4),A6 */
11506 EndPutM16Inc(data, 0); /* place for sysbase reference */
11508 else
11510 EndPutM16Inc(data, 0x2C79); /* MOVEA.L base,A6 */
11511 EndPutM32Inc(data, 0); /* place for sysbase reference */
11513 rel2 = data-tempbuf-8+2;
11514 if(Flags & FLAG_SMALLDATA)
11516 EndPutM16Inc(data, 0x202C); /* MOVE.L xxx(A4),D0 */
11517 EndPutM16Inc(data, 0); /* place for base reference */
11519 else
11521 EndPutM16Inc(data, 0x2039); /* MOVE.L xxx,D0 */
11522 EndPutM32Inc(data, 0); /* place for base reference */
11524 EndPutM16Inc(data, 0x6606); /* BNE.B .nolib */
11525 EndPutM16Inc(data, 0x2240); /* MOVEA.L D0,A1 */
11527 EndPutM32Inc(data, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11528 EndPutM16Inc(data, 0x2C5F); /* MOVE.L (A7)+,A6 */
11529 EndPutM16Inc(data,0x4E75); /* RTS */
11530 nameref = data-tempbuf-8;
11531 memcpy(data, name, strlen(name));
11532 data += strlen(name);
11533 do { *(data++) = 0; } while((data-tempbuf)&3);
11535 EndPutM32(tempbuf, HUNK_CODE);
11536 EndPutM32(tempbuf+4, (data-tempbuf-8)>>2)
11537 DoOutputDirect(tempbuf, (size_t)(data-tempbuf)&(~3));
11539 if(Flags & FLAG_SMALLDATA)
11541 EndPutM32(tempbuf, HUNK_DREL16);
11543 else
11545 EndPutM32(tempbuf, HUNK_ABSRELOC32);
11547 EndPutM32(tempbuf+4, 2); /* 2 entries */
11548 EndPutM32(tempbuf+8, 1); /* to hunk 1 */
11549 EndPutM32(tempbuf+12, rel1); /* address 0 */
11550 EndPutM32(tempbuf+16, rel2); /* address 0 */
11551 EndPutM32(tempbuf+20, 0); /* end of reloc hunk */
11552 DoOutputDirect(tempbuf, 24);
11554 /* extern references */
11555 EndPutM32(tempbuf, HUNK_EXT);
11556 DoOutputDirect(tempbuf, 4);
11558 OutputXREF2(4, sysref2, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "_SysBase");
11559 OutputXREF(verref, (Flags & FLAG_SMALLDATA ? EXT_DEXT16 : EXT_REF32), "__%sVer", BaseName);
11560 OutputXREF(exitfuncref, (Flags2 & FLAG2_SMALLCODE ? EXT_DEXT16 : EXT_REF32), "_exit");
11561 OutputXDEF(0, "__INIT_%ld_%s", priority, BaseName);
11562 OutputXDEF(exitref, "__EXIT_%ld_%s", priority, BaseName);
11563 OutputXDEF(nameref, "%sname", ShortBaseName);
11564 EndPutM32(tempbuf, 0); /* ext end */
11565 DoOutputDirect(tempbuf, 4);
11567 if(!(Flags & FLAG_NOSYMBOL))
11569 EndPutM32(tempbuf, HUNK_SYMBOL);
11570 DoOutputDirect(tempbuf, 4);
11571 OutputSYMBOL(0, "__INIT_%ld_%s", priority, BaseName);
11572 OutputSYMBOL(exitref, "__EXIT_%ld_%s", priority, BaseName);
11573 OutputSYMBOL(nameref, "%sname", ShortBaseName);
11574 EndPutM32(tempbuf, 0);
11575 DoOutputDirect(tempbuf, 4);
11578 EndPutM32(tempbuf, HUNK_END);
11579 DoOutputDirect(tempbuf, 4);
11581 i = strlen(datahunkname);
11582 EndPutM32(tempbuf, HUNK_NAME);
11583 EndPutM32(tempbuf+4, (i + 3)>>2);
11584 DoOutputDirect(tempbuf, 8);
11585 DoOutputDirect(datahunkname, i);
11586 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11588 EndPutM32(tempbuf, HUNK_BSS);
11589 EndPutM32(tempbuf+4, 1);
11590 DoOutputDirect(tempbuf, 8);
11592 EndPutM32(tempbuf, HUNK_EXT);
11593 DoOutputDirect(tempbuf, 4);
11594 OutputXDEF(0, "_%s", BaseName);
11595 EndPutM32(tempbuf, 0); /* ext end */
11596 DoOutputDirect(tempbuf, 4);
11598 if(!(Flags & FLAG_NOSYMBOL))
11600 EndPutM32(tempbuf, HUNK_SYMBOL);
11601 DoOutputDirect(tempbuf, 4);
11602 OutputSYMBOL(0, "_%s", BaseName);
11603 EndPutM32(tempbuf, 0);
11604 DoOutputDirect(tempbuf, 4);
11607 EndPutM32(tempbuf, HUNK_END);
11608 DoOutputDirect(tempbuf, 4);
11610 sprintf(filename, "%s_autoopenver", ShortBaseName);
11611 i = strlen(filename);
11612 EndPutM32(tempbuf, HUNK_UNIT);
11613 EndPutM32(tempbuf+4, (i+3)>>2);
11614 DoOutputDirect(tempbuf, 8);
11615 DoOutputDirect(filename, i);
11616 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11618 i = strlen(datahunkname);
11619 EndPutM32(tempbuf, HUNK_NAME);
11620 EndPutM32(tempbuf+4, (i + 3)>>2);
11621 DoOutputDirect(tempbuf, 8);
11622 DoOutputDirect(datahunkname, i);
11623 DoOutputDirect("\0\0\0", ((i+3)&(~3))-i);
11625 EndPutM32(tempbuf, HUNK_BSS);
11626 EndPutM32(tempbuf+4, 1);
11627 DoOutputDirect(tempbuf, 8);
11629 EndPutM32(tempbuf, HUNK_EXT);
11630 DoOutputDirect(tempbuf, 4);
11631 OutputXDEF(0, "_%sVer", BaseName);
11632 EndPutM32(tempbuf, 0); /* ext end */
11633 DoOutputDirect(tempbuf, 4);
11635 if(!(Flags & FLAG_NOSYMBOL))
11637 EndPutM32(tempbuf, HUNK_SYMBOL);
11638 DoOutputDirect(tempbuf, 4);
11639 OutputSYMBOL(0, "_%sVer", BaseName);
11640 EndPutM32(tempbuf, 0);
11641 DoOutputDirect(tempbuf, 4);
11644 EndPutM32(tempbuf, HUNK_END);
11645 return DoOutputDirect(tempbuf, 4);
11647 break;
11649 return 0;
11652 static uint32 CreateXML(void)
11654 struct Include *inc;
11656 LastBias = 30;
11657 DoOutput(
11658 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11659 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11660 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11661 ShortBaseName, BaseName, GetLibraryName());
11662 if(GetBaseTypeLib() != libstring)
11663 DoOutput(" basetype=\"%s\"", GetBaseTypeLib());
11664 DoOutput(">\n");
11665 for(inc = (struct Include *) Includes.First; inc;
11666 inc = (struct Include *) inc->List.Next)
11667 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc->Include)-2),
11668 inc->Include+1);
11669 if(!Includes.First)
11670 DoOutput("\t<include>exec/types.h</include>\n");
11672 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11673 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11674 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11675 DoOutput(
11676 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11677 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11678 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11679 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11680 " status=\"unimplemented\"/>\n");
11682 CallFunc(TAGMODE_BOTH, 0, FuncXML);
11684 return DoOutput("\t</interface>\n</library>\n");
11687 static uint32 CreateOS4PPC(uint32 callmode)
11689 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11691 if(HEADER)
11693 DoOutput("\n");
11694 DoOutputDirect(HEADER, headersize);
11697 PrintIncludes();
11699 DoOutput(
11700 "#include <stdarg.h>\n"
11701 "#include <exec/types.h>\n"
11702 "#include <exec/interfaces.h>\n"
11703 "#include <exec/emulation.h>\n"
11704 "#include <interfaces/exec.h>\n");
11706 if(!stricmp("exec",ShortBaseName))
11707 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName);
11709 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName);
11711 CallFunc(callmode, "\n/%s */\n\n", FuncOS4PPC);
11713 DoOutput(
11714 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11715 " return Self->Data.RefCount++;\n}\n\n"
11716 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11717 " return Self->Data.RefCount--;\n}\n\n"
11718 "#define LIBNAME \"%s\"\n"
11719 "#define LIBVERSION 0\n"
11720 "#define IFACENAME \"%s.main\"\n\n",
11721 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11722 GetLibraryName(), GetLibraryName());
11724 /* following text is constant */
11725 return DoOutput(
11726 "static void InitFunction(APTR dummy, ULONG SegList, "
11727 "struct ExecBase *ExecBase)\n{\n"
11728 " struct Library *LibBase;\n"
11729 " struct ExecIFace *IExec = (struct ExecIFace *)"
11730 "ExecBase->MainInterface;\n"
11731 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11732 " {\n"
11733 " struct Interface *NewInterface;\n"
11734 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11735 " MIT_VectorTable, main_vectors,\n"
11736 " MIT_Version, 1,\n"
11737 " MIT_Name, IFACENAME,\n"
11738 " TAG_DONE)))\n"
11739 " {\n"
11740 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11741 " IExec->AddInterface(LibBase, NewInterface);\n"
11742 " }\n"
11743 " }\n"
11744 "}\n\n"
11745 "volatile static struct Resident MyResident =\n{\n"
11746 " RTC_MATCHWORD,\n"
11747 " (struct Resident *)&MyResident,\n"
11748 " (APTR)(&MyResident+1),\n"
11749 " RTF_NATIVE,\n"
11750 " LIBVERSION,\n"
11751 " NT_UNKNOWN,\n"
11752 " -120,\n"
11753 " IFACENAME,\n"
11754 " IFACENAME,\n"
11755 " InitFunction\n"
11756 "};\n\n"
11757 "void _start(void)\n"
11758 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11759 "\n}\n");
11762 static uint32 CreateOS4M68K(void)
11764 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11766 if(HEADER)
11768 DoOutput("\n");
11769 DoOutputDirect(HEADER, headersize);
11771 DoOutput(
11772 "#include \"exec/interfaces.i\"\n"
11773 "#include \"exec/libraries.i\"\n"
11774 "#include \"exec/emulation.i\"\n"
11775 "#include \"interfaces/%s.i\"\n\n",ShortBaseName);
11777 DoOutput(
11778 "\t.section .data\n"
11779 "\t.globl\tstub_Open\n"
11780 "\t.type\tstub_Open,@function\n"
11781 "\n"
11782 "stub_Open:\n"
11783 "\t.short\t0x4ef8\n" /* JMP.w */
11784 "\t.short\t0\n" /* Indicate switch */
11785 "\t.short\t1\n" /* Trap type */
11786 "\t.globl\tstub_OpenPPC\n"
11787 "\t.long\tstub_OpenPPC\n"
11788 "\t.byte\t2\n" /* Register mapping */
11789 "\t.byte\t1,REG68K_A7\n"
11790 "\t.byte\t3,REG68K_A6\n"
11791 "\t.section .text\n"
11792 "\t.align\t4\n"
11793 "\n"
11794 "stub_OpenPPC:\n"
11795 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11796 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11797 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11798 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11799 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11800 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11801 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11802 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11803 "\tCallLib\tlmi_Open\n"
11804 "\tlwz\t%s11,%s12(%s1)\n"
11805 "\tmtlr\t%s11\n"
11806 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11807 "\tblrl\n" /* Return to emulation */
11808 "\n"
11809 "\t.globl\tstub_Open68K\n"
11810 "\t.long\tstub_Open68K\n"
11811 "\t.byte\t0\n" /* Flags */
11812 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11813 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11814 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11815 "\t.section .data\n"
11816 "\t.align\t4\n"
11817 "\n"
11818 "stub_Open68K:\n"
11819 "\t.short\t0x4e75\n" /* RTS */
11820 "\n"
11821 "\t.section .data\n"
11822 "\t.globl\tstub_Close\n"
11823 "\t.type\tstub_Close,@function\n"
11824 "\n"
11825 "stub_Close:\n"
11826 "\t.short\t0x4ef8\n" /* JMP.w */
11827 "\t.short\t0\n" /* Indicate switch */
11828 "\t.short\t1\n" /* Trap type */
11829 "\t.globl\tstub_ClosePPC\n"
11830 "\t.long\tstub_ClosePPC\n"
11831 "\t.byte\t2\n" /* Register mapping */
11832 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11833 "\t.byte\t3,REG68K_A6\n"
11834 "\t.section .text\n"
11835 "\t.align\t4\n"
11836 "\n"
11837 "stub_ClosePPC:\n"
11838 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11839 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11840 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11841 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11842 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11843 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11844 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11845 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11846 "\tCallLib\tlmi_Close\n"
11847 "\tlwz\t%s11,12(%s1)\n"
11848 "\tmtlr\t%s11\n"
11849 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11850 "\tblrl\n" /* Return to emulation */
11851 "\n"
11852 "\t.globl\tstub_Close68K\n"
11853 "\t.long\tstub_Close68K\n"
11854 "\t.byte\t0\n" /* Flags */
11855 "\t.byte\t1\n" /* One register (a7 only) */
11856 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11857 "\t.section .data\n"
11858 "\t.align\t4\n"
11859 "\n"
11860 "stub_Close68K:\n"
11861 "\t.short\t0x4e75\n" /* RTS */
11862 "\n"
11863 "\t.section .data\n"
11864 "\t.globl\tstub_Expunge\n"
11865 "\t.type\tstub_Expunge,@function\n"
11866 "\n"
11867 "stub_Expunge:\n"
11868 "\t.short\t0x7000\n" /* moveq #0, d0 */
11869 "\t.short\t0x4e75\n" /* RTS */
11870 "\n"
11871 "\t.section .data\n"
11872 "\t.globl\tstub_Reserved\n"
11873 "\t.type\tstub_Reserved,@function\n"
11874 "\n"
11875 "stub_Reserved:\n"
11876 "\t.short\t0x7000\n" /* moveq #0, d0 */
11877 "\t.short\t0x4e75\n\n", /* RTS */
11878 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11879 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11880 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11881 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11882 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11883 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11884 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11885 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix,
11886 PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix, PPCRegPrefix);
11888 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68K);
11889 DoOutput("\n"
11890 "\t.globl\tVector68K\n"
11891 "\t.globl\tVecTable68K\n"
11892 "Vector68K:\n"
11893 "\t.long\tVecTable68K\n"
11894 "VecTable68K:\n"
11895 "\t.long\tstub_Open\n"
11896 "\t.long\tstub_Close\n"
11897 "\t.long\tstub_Expunge\n"
11898 "\t.long\tstub_Reserved\n");
11900 LastBias = 30;
11901 CallFunc(TAGMODE_NORMAL, 0, FuncOS4M68KVect);
11902 DoOutput("\t.long\t-1\n");
11904 CloseDest(filename);
11906 if(Flags2 & FLAG2_OS4M68KCSTUB)
11908 sprintf(filename, "%s_68k.c", ShortBaseName);
11909 if(!OpenDest(filename))
11910 exit(20);
11911 Flags &= ~(FLAG_DONE);
11912 if(Flags2 & FLAG2_AUTOHEADER) DoOutput("/* %s */\n\n", AUTOHEADERTEXT);
11914 if(HEADER)
11916 DoOutput("\n");
11917 DoOutputDirect(HEADER, headersize);
11920 DoOutput(
11921 "#ifdef __USE_INLINE__\n"
11922 "#undef __USE_INLINE__\n"
11923 "#endif\n"
11924 "#ifndef __NOGLOBALIFACE__\n"
11925 "#define __NOGLOBALIFACE__\n"
11926 "#endif\n\n"
11927 "#include <exec/interfaces.h>\n"
11928 "#include <exec/libraries.h>\n"
11929 "#include <exec/emulation.h>\n"
11930 "#include <interfaces/exec.h>\n"
11931 "#include <interfaces/%s.h>\n"
11932 "#include <proto/%s.h>\n\n", ShortBaseName, ShortBaseName);
11934 CallFunc(TAGMODE_NORMAL, "\n/%s */\n\n", FuncOS4M68KCSTUB);
11936 return Output_Error;
11939 /* ------------------------------------------------------------------ */
11941 static uint32 GetName(struct NameList *t, struct ShortListRoot *p, uint32 args)
11943 struct NameList *p2 = (struct NameList *) p->First;
11944 struct AmiPragma ap;
11945 memset(&ap, 0, sizeof(struct AmiPragma));
11946 ap.FuncName = t->NormName;
11947 ap.NumArgs = 1;
11948 ap.CallArgs = 1;
11949 ap.Args[0].ArgName = (args ? "args" : "tags");
11950 if(!MakeTagFunction(&ap))
11951 return 0;
11953 if(!ap.TagName)
11954 return 0;
11956 while(p2 && (!p2->PragName || strcmp(p2->PragName, ap.TagName)))
11957 p2 = (struct NameList *) p2->List.Next;
11959 if(!p2)
11960 return 0;
11962 t->Type = (args ? NTP_ARGS : NTP_TAGS);
11963 t->PragName = ap.TagName;
11964 RemoveItem(p, (struct ShortList *) p2);
11966 #ifdef DEBUG_OLD
11967 printf("GetName: name matches - %s _ %s\n", t->NormName, t->PragName);
11968 #endif
11970 return 1;
11973 static void OptimizeFDData(struct PragData *pd)
11975 #ifdef DEBUG_OLD
11976 printf("OptimizeFDData\n");
11977 #endif
11979 while(pd)
11981 if(pd->NumNames > 1)
11983 struct ShortListRoot n = {0,0,0}, p = {0,0,0};
11984 struct NameList *t;
11985 while(pd->Name.First) /* sorts in AmiCall and TagCall */
11987 t = (struct NameList *) pd->Name.First;
11989 RemoveItem(&pd->Name, (struct ShortList *) t);
11990 AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
11993 if(p.First)
11995 t = (struct NameList *) n.First;
11996 while(p.First && t)
11998 if(!GetName(t, &p, 0))
12000 GetName(t, &p, 1);
12002 if(t->PragName)
12004 struct NameList *t2 = (struct NameList *) t->List.Next;
12005 RemoveItem(&n, (struct ShortList *)t);
12006 AddItem(&pd->Name, (struct ShortList *) t);
12007 t = t2;
12009 else
12010 t = (struct NameList *) t->List.Next;
12012 while(p.First)
12014 if(n.First)
12016 t = (struct NameList *) n.First;
12017 t->PragName = ((struct NameList *)(p.First))->PragName;
12018 RemoveItem(&n, (struct ShortList *) t);
12019 #ifdef DEBUG_OLD
12020 printf("OptimizeFDData: names together - %s _ %s\n", t->NormName, t->PragName);
12021 #endif
12022 t->Type = NTP_UNKNOWN;
12024 else
12026 uint32 i;
12028 t = (struct NameList *) p.First;
12029 i = strlen(t->PragName);
12030 t->NormName = DupString(t->PragName, i+1);
12031 t->NormName[i++] = 'A';
12032 t->NormName[i] = 0;
12033 t->Type = NTP_TAGS;
12034 #ifdef DEBUG_OLD
12035 printf("OptimizeFDData: NormName created - %s _ %s\n", t->NormName, t->PragName);
12036 #endif
12039 AddItem(&pd->Name, (struct ShortList *) t);
12040 RemoveItem(&p, p.First);
12044 AddItem(&pd->Name, n.First); /* add left NormNames */
12046 pd = (struct PragData *) pd->List.Next;
12050 static uint32 MakeFD(struct PragList *pl)
12052 struct PragData *pd = (struct PragData *) pl->Data.First;
12053 uint32 bias;
12055 #ifdef DEBUG_OLD
12056 printf("MakeFD\n");
12057 #endif
12058 bias = pd->Bias;
12060 OptimizeFDData(pd);
12061 #ifdef DEBUG_OLD
12062 printf("MakeFD: after Optimizing\n");
12063 #endif
12064 DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
12066 while(pd && Output_Error)
12068 struct NameList *n = (struct NameList *) pd->Name.First;
12070 if(bias != pd->Bias)
12071 DoOutput("##bias %ld\n", (bias = pd->Bias));
12073 while(n)
12075 strptr lastpar = "last";
12076 uint32 i;
12078 if(n->Type == NTP_TAGS)
12079 lastpar = "tags";
12080 else if(n->Type == NTP_ARGS)
12081 lastpar = "args";
12083 DoOutput("%s("/*)*/,n->NormName);
12084 if(!pd->NumArgs)
12085 DoOutput(/*(*/")()\n");
12086 else
12088 for(i = 0; i < pd->NumArgs-1; ++i)
12089 DoOutput("par%ld,",i+1);
12090 DoOutput(/*(*/"%s)("/*)*/, lastpar);
12091 for(i = 0; i < pd->NumArgs-1; ++i)
12092 DoOutput("%s,", RegNames[pd->ArgReg[i]]);
12093 DoOutput(/*(*/"%s)\n", RegNames[pd->ArgReg[i]]);
12095 if(n->Type == NTP_UNKNOWN)
12097 uint32 i;
12098 for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
12100 DoOutput("*tagcall");
12101 if(n->NormName[i])
12102 DoOutput("-%s", n->NormName+i);
12103 if(n->PragName[i])
12104 DoOutput("+%s", n->PragName+i);
12106 DoOutput("\n");
12109 if((n = (struct NameList *) n->List.Next))
12110 DoOutput("##bias %ld\n", pd->Bias);
12111 Flags |= FLAG_DONE;
12114 pd = (struct PragData *)pd->List.Next; bias += BIAS_OFFSET;
12117 DoOutput("##end\n");
12119 return Output_Error;
12122 static uint32 AddFDData(struct ShortListRoot *pls, struct FDData *fd)
12124 struct NameList *t;
12125 struct PragList *pl = (struct PragList *) pls->First;
12126 struct PragData *pd;
12128 while(pl && strcmp(pl->Basename, fd->Basename))
12129 pl = (struct PragList *) pl->List.Next;
12131 if(!pl)
12133 #ifdef DEBUG_OLD
12134 printf("AddFDData: New PragList - %s\n", fd->Basename);
12135 #endif
12136 if(!(pl = (struct PragList *) NewItem(pls)))
12137 return 100;
12138 pl->Basename = fd->Basename;
12139 pl->Data.Size = sizeof(struct PragData);
12140 AddItem(pls, (struct ShortList *) pl);
12143 if((pd = (struct PragData *) pl->Data.First))
12145 while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
12146 <= fd->Bias)
12147 pd = (struct PragData *) pd->List.Next;
12150 if(!pd || pd->Bias != fd->Bias)
12152 struct PragData *pd2;
12153 #ifdef DEBUG_OLD
12154 printf("AddFDData: New PragData - %ld, %ld\n", fd->Bias, fd->NumArgs);
12155 #endif
12156 if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
12157 return 100;
12158 pd2->Bias = fd->Bias;
12159 memcpy(pd2->ArgReg, fd->ArgReg, MAXREG);
12160 pd2->NumArgs = fd->NumArgs;
12161 pd2->Name.Size = sizeof(struct NameList);
12162 if(!pd)
12163 AddItem(&pl->Data, (struct ShortList *) pd2);
12164 else if(pd->Bias > fd->Bias) /* Insert at start */
12166 pd2->List.Next = pl->Data.First;
12167 pl->Data.First = (struct ShortList *) pd2;
12169 else /* Insert the entry */
12171 pd2->List.Next = pd->List.Next;
12172 pd->List.Next = (struct ShortList *) pd2;
12174 pd = pd2;
12176 else
12178 uint32 i = fd->NumArgs;
12179 if(fd->NumArgs != pd->NumArgs)
12181 #ifdef DEBUG_OLD
12182 printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
12183 #endif
12184 return ERR_DIFFERENT_TO_PREVIOUS;
12187 while(i--)
12189 if(fd->ArgReg[i] != pd->ArgReg[i])
12191 #ifdef DEBUG_OLD
12192 printf("ArgReg %x != %x\n", fd->ArgReg[i], pd->ArgReg[i]);
12193 #endif
12194 return ERR_DIFFERENT_TO_PREVIOUS;
12199 t = (struct NameList *) pd->Name.First; /* skips same names */
12200 while(t && (!(fd->Mode ? t->PragName : t->NormName) ||
12201 strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName)))
12202 t = (struct NameList *) t->List.Next;
12204 if(t)
12205 return 0;
12207 if(!(t = (struct NameList *) NewItem(&pd->Name)))
12208 return 100;
12209 if(fd->Mode)
12210 t->PragName = fd->Name;
12211 else
12212 t->NormName = fd->Name;
12213 AddItem(&pd->Name, (struct ShortList *) t);
12214 ++(pd->NumNames);
12215 #ifdef DEBUG_OLD
12216 printf("AddFDData: New NameList - %s\n", fd->Name);
12217 #endif
12218 return 0;
12221 static string GetHexValue(string data)
12223 if(data >= 'a')
12224 return (string) (data - 'a' + 10);
12225 else if(data >= 'A')
12226 return (string) (data - 'A' + 10);
12227 else
12228 return (string) (data - '0');
12231 static string GetDoubleHexValue(strptr data)
12233 return (string)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
12236 static uint32 GetLibData(struct FDData *fd)
12238 uint32 i;
12239 fd->Name = SkipBlanks(in.pos);
12240 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12241 in.pos = SkipBlanks(in.pos);
12242 fd->Bias = strtoul(in.pos, 0, 16);
12243 in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
12244 if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
12245 return ERR_TO_MUCH_ARGUMENTS;
12246 --in.pos; /* skips return register */
12247 for(i = 0; i < fd->NumArgs; ++i)
12249 if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
12250 return ERR_EXPECTED_REGISTER_NAME;
12252 return 0;
12255 static uint32 GetFlibData(struct FDData *fd)
12257 uint32 i;
12258 fd->Name = SkipBlanks(in.pos);
12259 in.pos = SkipName(fd->Name); *(in.pos++) = 0;
12260 in.pos = SkipBlanks(in.pos);
12261 fd->Bias = strtoul(in.pos, 0, 16);
12262 in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
12263 if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
12264 return ERR_TO_MUCH_ARGUMENTS;
12265 in.pos -= 2; /* skips return register */
12266 for(i = 0; i < fd->NumArgs; ++i)
12268 in.pos -= 2;
12269 if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
12270 return ERR_EXPECTED_REGISTER_NAME;
12271 else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
12272 return ERR_FLOATARG_NOT_ALLOWED;
12274 return 0;
12277 static uint32 GetAmiData(struct FDData *fd)
12279 strptr endptr;
12280 in.pos = SkipBlanks(in.pos);
12281 if(*in.pos != '('/*)*/)
12282 return ERR_EXPECTED_OPEN_BRACKET;
12283 fd->Basename = ++in.pos;
12284 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12285 if(*in.pos != ',')
12286 return ERR_EXPECTED_COMMA;
12287 *endptr = 0;
12288 in.pos = SkipBlanks(++in.pos);
12289 if(!strncmp(in.pos, "0x", 2))
12290 fd->Bias = strtoul(in.pos+2, 0, 16);
12291 else
12292 fd->Bias = strtoul(in.pos, 0, 10);
12294 in.pos = SkipBlanks(SkipName(in.pos));
12295 if(*in.pos != ',')
12296 return ERR_EXPECTED_COMMA;
12297 fd->Name = in.pos = SkipBlanks(++in.pos);
12298 in.pos = SkipBlanks(endptr = SkipName(in.pos));
12299 if(*in.pos != '('/*)*/)
12300 return ERR_EXPECTED_OPEN_BRACKET;
12301 *endptr = 0;
12302 in.pos = SkipBlanks(++in.pos);
12303 if(*in.pos == /*(*/')')
12304 return 0;
12305 --in.pos;
12306 while(*in.pos != /*(*/')')
12308 uint32 i;
12309 in.pos = SkipBlanks(in.pos+1);
12311 for(i = 0; i < REG_FP0; i++)
12312 if(!strnicmp(RegNames[i], in.pos, 2))
12313 break;
12314 if(i == REG_FP0)
12316 for(; i < MAXREG; i++)
12317 if(!strnicmp(RegNames[i], in.pos, 3))
12318 break;
12321 if(i == MAXREG)
12322 return ERR_EXPECTED_REGISTER_NAME;
12323 else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
12324 return ERR_FLOATARG_NOT_ALLOWED;
12326 fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
12328 if(fd->NumArgs > MAXREG-2)
12329 return ERR_TO_MUCH_ARGUMENTS;
12331 in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
12333 if(*in.pos != ',' && *in.pos != /*(*/')')
12334 return ERR_EXPECTED_CLOSE_BRACKET;
12336 in.pos = SkipBlanks(in.pos+1);
12337 if(*in.pos != /*(*/')')
12338 return ERR_EXPECTED_CLOSE_BRACKET;
12339 return 0;
12342 static uint32 CreateFDFile(void)
12344 struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
12345 uint32 linenum, err = 0, skip;
12346 strptr ptr, p2;
12348 ptr = p2 = args.infile;
12349 while(*p2)
12351 if(*p2 == '/' || *p2 == ':' || *p2 == '\\')
12352 ptr = p2+1;
12353 ++p2;
12355 for(p2 = ptr; *p2 && *p2 != '_' && *p2 != '.'; ++p2)
12357 if(p2 != ptr)
12359 ShortBaseName = ptr;
12360 *p2 = '\0';
12363 for(linenum = 1; in.pos < in.buf + in.size; ++linenum)
12365 in.pos = SkipBlanks(in.pos);
12366 if(!strncmp("#pragma", in.pos, 7))
12368 struct FDData fd;
12370 skip = 0;
12371 memset(&fd, 0, sizeof(struct FDData));
12373 in.pos = SkipBlanks(in.pos+7);
12374 if(!strncmp("tagcall", in.pos, 7))
12376 fd.Mode = 1;
12377 in.pos = SkipBlanks(in.pos+7);
12378 if(*in.pos == '(' /*)*/) /* Storm method */
12379 err = GetAmiData(&fd);
12380 else /* SAS method */
12382 fd.Basename = in.pos;
12383 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12384 err = GetLibData(&fd);
12387 else if(!strncmp("amicall", in.pos, 7)) /* Storm method */
12389 in.pos += 7;
12390 err = GetAmiData(&fd);
12392 else if(!strncmp("libcall", in.pos, 7)) /* SAS method */
12394 fd.Basename = SkipBlanks(in.pos+7);
12395 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12396 err = GetLibData(&fd);
12398 else if(!strncmp("flibcall", in.pos, 8)) /* SAS method */
12400 fd.Basename = SkipBlanks(in.pos+8);
12401 in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
12402 err = GetFlibData(&fd);
12404 else if(!strncmp("syscall", in.pos, 7)) /* SAS method */
12406 fd.Basename = "SysBase";
12407 err = GetLibData(&fd);
12409 else
12410 skip = 1;
12412 if(err)
12413 DoError(err, linenum);
12414 else if(skip)
12416 else if((err = AddFDData(&pl, &fd)))
12418 if(err != 100)
12419 DoError(err, linenum);
12420 return 0;
12423 while(*(in.pos++)) /* jumps to first char of next line */
12427 if(pl.First)
12429 struct PragList *p = (struct PragList *) pl.First;
12430 if(!p->List.Next)
12432 strptr text, to;
12433 uint32 i;
12435 if(ShortBaseName)
12437 text = ShortBaseName; i = strlen(text);
12439 else
12441 text = p->Basename; i = strlen(text)-4;
12444 to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
12445 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12446 if(!OpenDest(to))
12447 return 0;
12449 err = MakeFD(p);
12450 CloseDest(to);
12451 if(!err)
12452 return 0;
12454 else
12456 while(p)
12458 strptr to;
12459 uint32 i;
12460 i = strlen(p->Basename) - 4;
12461 to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
12462 memcpy(to+i, FDFILEEXTENSION, sizeof(FDFILEEXTENSION));
12463 if(!OpenDest(to))
12464 return 0;
12465 i = MakeFD(p);
12466 CloseDest(to);
12467 if(!i)
12468 return 0;
12469 p = (struct PragList *) p->List.Next;
12474 return 1;
12477 #ifdef FD2PRAGMA_READARGS
12478 #include <proto/dos.h>
12480 /* undefine OS4 HUNKNAME macro */
12481 #ifdef HUNKNAME
12482 #undef HUNKNAME
12483 #endif
12485 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12486 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12487 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12488 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12489 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12490 "NEWSYNTAX/S," \
12491 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12492 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12493 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12494 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12495 "VOIDBASE/S"
12497 struct AmiArg
12499 strptr INFILE;
12500 uint32* SPECIAL;
12501 uint32* MODE;
12502 strptr TO;
12503 strptr ABI;
12504 strptr CLIB;
12505 strptr COPYRIGHT;
12506 strptr HEADER;
12507 strptr HUNKNAME;
12508 strptr BASENAME;
12509 strptr LIBTYPE;
12510 strptr LIBNAME;
12511 uint32* PRIORITY;
12512 strptr PREFIX;
12513 strptr SUBPREFIX;
12514 strptr PREMACRO;
12515 uint32 AUTOHEADER;
12516 uint32 COMMENT;
12517 uint32 EXTERNC;
12518 uint32 FPUONLY;
12519 uint32 NEWSYNTAX;
12520 uint32 NOFPU;
12521 uint32 NOPPC;
12522 uint32 NOPPCREGNAME;
12523 uint32 NOSYMBOL;
12524 uint32 ONLYCNAMES;
12525 uint32 OPT040;
12526 uint32 PPCONLY;
12527 uint32 PRIVATE;
12528 uint32 SECTION;
12529 uint32 SMALLCODE;
12530 uint32 SMALLDATA;
12531 uint32 SMALLTYPES;
12532 uint32 SORTED;
12533 uint32 SYSTEMRELEASE;
12534 uint32 USESYSCALL;
12535 uint32 VOIDBASE;
12538 static const strptr helptext =
12539 "INFILE: the input file which should be used\n"
12540 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12541 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12542 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12543 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12544 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12545 "\t 6 - pragma for all compilers [default]\n"
12546 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12547 "\t10 - stub-functions for C - C text\n"
12548 "\t11 - stub-functions for C - assembler text\n"
12549 "\t12 - stub-functions for C - link library\n"
12550 "\t13 - defines and link library for local library base (register call)\n"
12551 "\t14 - defines and link library for local library base (stack call)\n"
12552 "\t15 - stub-functions for Pascal - assembler text\n"
12553 "\t16 - stub-functions for Pascal - link library\n"
12554 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12555 "\t18 - module for AmigaE\n"
12556 "\t20 - assembler lvo _lvo.i file\n"
12557 "\t21 - assembler lvo _lib.i file\n"
12558 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12559 "\t23 - assembler lvo _lib.i file no XDEF\n"
12560 "\t24 - assembler lvo link library\n"
12561 "\t30 - proto file with pragma/..._lib.h call\n"
12562 "\t31 - proto file with pragma/..._pragmas.h call\n"
12563 "\t32 - proto file with pragmas/..._lib.h call\n"
12564 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12565 "\t34 - proto file with local/..._loc.h call\n"
12566 "\t35 - proto file for all compilers (VBCC stubs)\n"
12567 "\t36 - proto file for GNU-C compiler only\n"
12568 "\t37 - proto file without lib definitions\n"
12569 "\t38 - proto file for all compilers (VBCC inline)\n"
12570 "\t39 - proto file with special PPC related checks\n"
12571 "\t40 - GCC inline file (preprocessor based)\n"
12572 "\t41 - GCC inline file (old type - inline based)\n"
12573 "\t42 - GCC inline file (library stubs)\n"
12574 "\t43 - GCC inline file (new style - macro)\n"
12575 "\t44 - GCC inline file (new style - inline)\n"
12576 "\t45 - GCC inline file (new style - inline with include lines)\n"
12577 "\t46 - GCC inline file (preprocessor based, direct)\n"
12578 "\t47 - GCC inline file (new style, direct)\n"
12579 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12580 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12581 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12582 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12583 "\t53 - SAS-C include file for PowerUP\n"
12584 "\t54 - Proto file for PowerUP\n"
12585 "\t60 - FPC pascal unit text\n"
12586 "\t70 - VBCC inline files\n"
12587 "\t71 - VBCC WOS stub-functions - assembler text\n"
12588 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12589 "\t73 - VBCC WOS stub-functions - link library\n"
12590 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12591 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12592 "\t76 - VBCC PowerUP stub-functions - link library\n"
12593 "\t77 - VBCC WOS inline files\n"
12594 "\t78 - VBCC MorphOS stub-functions - link library\n"
12595 "\t79 - VBCC old inline files\n"
12596 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12597 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12598 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12599 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12600 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12601 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12602 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12603 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12604 " 100 - PPC assembler lvo file\n"
12605 " 101 - PPC assembler lvo file no XDEF\n"
12606 " 102 - PPC assembler lvo ELF link library\n"
12607 " 103 - PPC assembler lvo EHF link library\n"
12608 " 104 - PPC V.4-ABI assembler file\n"
12609 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12610 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12611 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12612 " 110 - FD file\n"
12613 " 111 - CLIB file\n"
12614 " 112 - SFD file\n"
12615 " 120 - VBCC auto libopen files (C source)\n"
12616 " 121 - VBCC auto libopen files (m68k link library)\n"
12617 " 122 - VBCC MorphOS inline files\n"
12618 " 123 - VBCC new MorphOS inline files\n"
12619 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12620 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12621 " 132 - GCC inline files for MorphOS (library stubs)\n"
12622 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12623 " 134 - MorphOS gate stubs\n"
12624 " 135 - MorphOS gate stubs (prelib)\n"
12625 " 136 - MorphOS gate stubs (postlib)\n"
12626 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12627 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12628 " 140 - OS4 XML file\n"
12629 " 141 - OS4 PPC->M68K cross-call stubs\n"
12630 " 142 - OS4 M68K->PPC cross-call stubs\n"
12631 " 200 - FD file (source is a pragma file!)\n"
12632 "MODE: SPECIAL 1-7:\n"
12633 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12634 " 2: _PRAGMAS_..._LIB_H definition method\n"
12635 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12636 " 4: no definition\n"
12637 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12638 " 130-138,141:\n"
12639 " 1: all functions, normal interface\n"
12640 " 2: only tag-functions, tagcall interface\n"
12641 " 3: all functions, normal and tagcall interface [default]\n"
12642 "TO: the destination directory (self creation of filename)\n"
12643 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12644 "CLIB: name of the prototypes file in clib directory\n"
12645 "COPYRIGHT: the copyright text for CLIB files\n"
12646 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12647 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12648 "BASENAME: name of library base without '_'\n"
12649 "LIBNAME: name of the library (.e.g. dos.library)\n"
12650 "LIBTYPE: type of base library structure\n"
12651 "PRIORITY: priority for auto open files\n"
12652 "PREFIX: MorphOS gate prefix\n"
12653 "SUBPREFIX: MorphOS gate sub prefix\n"
12654 "PREMACRO: MorphOS gate file start macro\n"
12655 "Switches:\n"
12656 "AUTOHEADER add the typical automatic generated header\n"
12657 "COMMENT: copy comments found in input file\n"
12658 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12659 "FPUONLY: work only with functions using FPU register arguments\n"
12660 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12661 "NOFPU: disable usage of FPU register arguments\n"
12662 "NOPPC: disable usage of PPC-ABI functions\n"
12663 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12664 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12665 "ONLYCNAMES: do not create C++ or ASM names\n"
12666 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12667 "PPCONLY: only use PPC-ABI functions\n"
12668 "PRIVATE: includes private declared functions\n"
12669 "SECTION: add section statements to asm texts\n"
12670 "SMALLCODE: generate small code link libraries or assembler text\n"
12671 "SMALLDATA: generate small data link libraries or assembler text\n"
12672 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12673 "SORTED: sort generated files by name and not by bias value\n"
12674 "SYSTEMRELEASE: special handling of comments for system includes\n"
12675 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12676 "VOIDBASE: library bases are of type void *\n";
12678 /* print the help text */
12679 static void printhelp(void)
12681 printf("%s\n%s\n\n%s", version+6, PARAM, helptext);
12682 exit(20);
12685 /* initializes the arguments and starts argument parsing */
12686 static void GetArgs(int argc, char **argv)
12688 struct RDArgs *rda;
12689 struct AmiArg amiargs;
12690 int res = 0;
12692 if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
12694 rda->RDA_ExtHelp = helptext;
12695 memset(&amiargs, 0, sizeof(struct AmiArg));
12696 if(ReadArgs(PARAM, (int32 *) &amiargs, rda))
12698 int l;
12699 strptr d, s;
12701 l = strlen(amiargs.TO ? amiargs.TO : "") + 1
12702 + strlen(amiargs.CLIB ? amiargs.CLIB : "") + 1
12703 + strlen(amiargs.HEADER ? amiargs.HEADER : "") + 1
12704 + strlen(amiargs.ABI ? amiargs.ABI : "") + 1
12705 + strlen(amiargs.HUNKNAME ? amiargs.HUNKNAME : "") + 1
12706 + strlen(amiargs.BASENAME ? amiargs.BASENAME : "") + 1
12707 + strlen(amiargs.LIBTYPE ? amiargs.LIBTYPE : "") + 1
12708 + strlen(amiargs.LIBNAME ? amiargs.LIBNAME : "") + 1
12709 + strlen(amiargs.COPYRIGHT ? amiargs.COPYRIGHT : "") + 1
12710 + strlen(amiargs.PREFIX ? amiargs.PREFIX : "") + 1
12711 + strlen(amiargs.SUBPREFIX ? amiargs.SUBPREFIX : "") + 1
12712 + strlen(amiargs.PREMACRO ? amiargs.PREMACRO : "") + 1
12713 + strlen(amiargs.INFILE) + 1;
12714 if((d = AllocListMem(l)))
12716 res = 1;
12718 s = amiargs.INFILE;
12719 args.infile = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12720 if((s = amiargs.TO))
12722 args.to = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12724 if((s = amiargs.HEADER))
12726 args.header = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12728 if((s = amiargs.CLIB))
12730 args.clib = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12732 if((s = amiargs.HUNKNAME))
12734 hunkname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12736 if((s = amiargs.BASENAME))
12738 Flags |= FLAG_BASENAME;
12739 BaseName = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12741 if((s = amiargs.LIBTYPE))
12743 Flags2 |= FLAG2_LIBTYPE;
12744 libtype = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12746 if((s = amiargs.LIBNAME))
12748 Flags2 |= FLAG2_LIBNAME;
12749 libname = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12751 if((s = amiargs.PREFIX))
12753 prefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12755 if((s = amiargs.SUBPREFIX))
12757 subprefix = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12759 if((s = amiargs.PREMACRO))
12761 premacro = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12763 if((s = amiargs.COPYRIGHT))
12765 Copyright = d; while(*s) *(d++) = *(s++); *(d++) = 0;
12767 if((s = amiargs.ABI))
12769 defabi = d; while(*s) *(d++) = *(s++); *d = 0;
12771 if(amiargs.EXTERNC) Flags ^= FLAG_EXTERNC;
12772 if(amiargs.PRIVATE) Flags ^= FLAG_PRIVATE;
12773 if(amiargs.NEWSYNTAX) Flags ^= FLAG_NEWSYNTAX;
12774 if(amiargs.SMALLDATA) Flags ^= FLAG_SMALLDATA;
12775 if(amiargs.SMALLCODE) Flags2 ^= FLAG2_SMALLCODE;
12776 if(amiargs.SMALLTYPES) Flags2 ^= FLAG2_SMALLTYPES;
12777 if(amiargs.USESYSCALL) Flags ^= FLAG_SYSCALL;
12778 if(amiargs.OPT040) Flags ^= FLAG_NOMOVEM;
12779 if(amiargs.NOFPU) Flags ^= FLAG_NOFPU;
12780 if(amiargs.FPUONLY) Flags ^= FLAG_FPUONLY;
12781 if(amiargs.NOPPC) Flags ^= FLAG_NOPPC;
12782 if(amiargs.NOSYMBOL) Flags ^= FLAG_NOSYMBOL;
12783 if(amiargs.PPCONLY) Flags ^= FLAG_PPCONLY;
12784 if(amiargs.SECTION) Flags ^= FLAG_ASMSECTION;
12785 if(amiargs.COMMENT) Flags ^= FLAG_DOCOMMENT;
12786 if(amiargs.SORTED) Flags ^= FLAG_SORTED;
12787 if(amiargs.ONLYCNAMES) Flags ^= FLAG_ONLYCNAMES;
12788 if(amiargs.SYSTEMRELEASE) Flags2 ^= FLAG2_SYSTEMRELEASE;
12789 if(amiargs.VOIDBASE) Flags2 ^= FLAG2_VOIDBASE;
12790 if(amiargs.NOPPCREGNAME) PPCRegPrefix = "";
12791 if(amiargs.AUTOHEADER) Flags2 ^= FLAG2_AUTOHEADER;
12792 if(amiargs.SPECIAL)
12793 args.special = *amiargs.SPECIAL;
12794 if(amiargs.MODE)
12795 args.mode = *amiargs.MODE;
12796 if(amiargs.PRIORITY)
12797 priority = *amiargs.PRIORITY;
12799 FreeArgs(rda);
12801 else
12802 PrintFault(IoErr(), 0);
12803 FreeDosObject(DOS_RDARGS, rda);
12806 if(!res)
12807 /* printhelp(); */
12808 exit(20);
12811 #else
12812 static const strptr helptext =
12813 " -h,--help\n"
12814 " -i,--infile <input filename>\n"
12815 " -s,--special <number>\n"
12816 " -m,--mode <number>\n"
12817 " -t,--to <destination directory>\n"
12818 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12819 " -c,--clib <clib prototypes filename>\n"
12820 " -d,--header <header file or \"\">\n"
12821 " -i,--libname <name of library>\n"
12822 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12823 " -b,--basename <name of library base without '_'>\n"
12824 " -l,--libtype <name of base library type>\n"
12825 " -p,--priority <priority for auto open files>\n"
12826 " -r,--copyright<copyright text>\n"
12827 " --prefix <MorphOS gate prefix>\n"
12828 " --subprefix<MorphOS gate sub prefix>\n"
12829 " --premacro <MorphOS gate file start macro>\n"
12830 "\n"
12831 "Switches:\n"
12832 "--autoheader add the typical automatic generated header\n"
12833 "--comment copy comments found in input file\n"
12834 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12835 "--fpuonly work only with functions using FPU register arguments\n"
12836 "--newsyntax uses new Motorola syntax for asm files\n"
12837 "--nofpu disable usage of FPU register arguments\n"
12838 "--noppc disable usage of PPC-ABI functions\n"
12839 "--noppcregname do not add 'r' to PPC register names\n"
12840 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12841 "--onlycnames do not create C++ or ASM names\n"
12842 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12843 "--ppconly only use PPC-ABI functions\n"
12844 "--private includes private declared functions\n"
12845 "--section add section statements to asm texts\n"
12846 "--smallcode generate small code link libraries or assembler text\n"
12847 "--smalldata generate small data link libraries or assembler text\n"
12848 "--smalltypes allow 8 and 16 bit types in registers\n"
12849 "--sorted sort generated files by name and not by bias value\n"
12850 "--systemrelease special handling of comments for system includes\n"
12851 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12852 "--voidbase library bases are of type void *\n"
12853 "\n"
12854 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12855 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12856 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12857 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12858 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12859 " 6 - pragma for all compilers [default]\n"
12860 " 7 - all compilers with pragma to inline redirect for GCC\n"
12861 " 10 - stub-functions for C - C text\n"
12862 " 11 - stub-functions for C - assembler text\n"
12863 " 12 - stub-functions for C - link library\n"
12864 " 13 - defines and link library for local library base (register call)\n"
12865 " 14 - defines and link library for local library base (stack call)\n"
12866 " 15 - stub-functions for Pascal - assembler text\n"
12867 " 16 - stub-functions for Pascal - link library\n"
12868 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12869 " 18 - module for AmigaE\n"
12870 " 20 - assembler lvo _lvo.i file\n"
12871 " 21 - assembler lvo _lib.i file\n"
12872 " 22 - assembler lvo _lvo.i file no XDEF\n"
12873 " 23 - assembler lvo _lib.i file no XDEF\n"
12874 " 24 - assembler lvo link library\n"
12875 " 30 - proto file with pragma/..._lib.h call\n"
12876 " 31 - proto file with pragma/..._pragmas.h call\n"
12877 " 32 - proto file with pragmas/..._lib.h call\n"
12878 " 33 - proto file with pragmas/..._pragmas.h call\n"
12879 " 34 - proto file with local/..._loc.h call\n"
12880 " 35 - proto file for all compilers (VBCC stubs)\n"
12881 " 36 - proto file for GNU-C compiler only\n"
12882 " 37 - proto file without lib definitions\n"
12883 " 38 - proto file for all compilers (VBCC inline)\n"
12884 " 39 - proto file with special PPC related checks\n"
12885 " 40 - GCC inline file (preprocessor based)\n"
12886 " 41 - GCC inline file (old type - inline based)\n"
12887 " 42 - GCC inline file (library stubs)\n"
12888 " 43 - GCC inline file (new style - macro)\n"
12889 " 44 - GCC inline file (new style - inline)\n"
12890 " 45 - GCC inline file (new style - inline with include lines)\n"
12891 " 46 - GCC inline file (preprocessor based, direct)\n"
12892 " 47 - GCC inline file (new style, direct)\n"
12893 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12894 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12895 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12896 " 52 - GCC inline files for PowerUP (library stubs)\n"
12897 " 53 - SAS-C include file for PowerUP\n"
12898 " 54 - Proto file for PowerUP\n"
12899 " 60 - FPC pascal unit text\n"
12900 " 70 - VBCC inline files\n"
12901 " 71 - VBCC WOS stub-functions - assembler text\n"
12902 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12903 " 73 - VBCC WOS stub-functions - link library\n"
12904 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12905 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12906 " 76 - VBCC PowerUP stub-functions - link library\n"
12907 " 77 - VBCC WOS inline files\n"
12908 " 78 - VBCC MorphOS stub-functions - link library\n"
12909 " 79 - VBCC old inline files\n"
12910 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12911 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12912 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12913 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12914 " 90 - stub-functions for C - assembler text (multiple files)\n"
12915 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12916 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12917 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12918 " 100 - PPC assembler lvo file\n"
12919 " 101 - PPC assembler lvo file no XDEF\n"
12920 " 102 - PPC assembler lvo ELF link library\n"
12921 " 103 - PPC assembler lvo EHF link library\n"
12922 " 104 - PPC V.4-ABI assembler file\n"
12923 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12924 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12925 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12926 " 110 - FD file\n"
12927 " 111 - CLIB file\n"
12928 " 112 - SFD file\n"
12929 " 120 - VBCC auto libopen files (C source)\n"
12930 " 121 - VBCC auto libopen files (m68k link library)\n"
12931 " 122 - VBCC MorphOS inline files\n"
12932 " 123 - VBCC new MorphOS inline files\n"
12933 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12934 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12935 " 132 - GCC inline files for MorphOS (library stubs)\n"
12936 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12937 " 134 - MorphOS gate stubs\n"
12938 " 135 - MorphOS gate stubs (prelib)\n"
12939 " 136 - MorphOS gate stubs (postlib)\n"
12940 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12941 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12942 " 140 - OS4 XML file\n"
12943 " 141 - OS4 PPC->M68K cross-call stubs\n"
12944 " 142 - OS4 M68K->PPC cross-call stubs\n"
12945 " 200 - FD file (source is a pragma file!)\n"
12946 "mode: special 1-7\n"
12947 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12948 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12949 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12950 " 4 - no definition\n"
12951 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12952 " 130-138,141:\n"
12953 " 1 - all functions, normal interface\n"
12954 " 2 - only tag-functions, tagcall interface\n"
12955 " 3 - all functions, normal and tagcall interface [default]\n";
12957 /* print the help text */
12958 static void printhelp(void)
12960 printf("%s\n%s", version+6, helptext);
12961 exit(20);
12964 struct ArgData
12966 strptr ArgName;
12967 uint8 ArgChar;
12968 uint8 ArgNameLen;
12969 uint8 ArgNum;
12972 enum ArgNums {
12973 ARG_HELP, ARG_INFILE, ARG_SPECIAL, ARG_MODE, ARG_TO, ARG_CLIB, ARG_ABI, ARG_COPYRIGHT,
12974 ARG_HEADER, ARG_HUNKNAME, ARG_BASENAME, ARG_LIBTYPE,
12975 ARG_COMMENT, ARG_EXTERNC, ARG_FPUONLY, ARG_NEWSYNTAX, ARG_NOFPU, ARG_NOPPC,
12976 ARG_NOSYMBOL, ARG_ONLYCNAMES, ARG_OPT040, ARG_PPCONLY, ARG_PRIVATE, ARG_SECTION,
12977 ARG_SMALLDATA, ARG_SORTED, ARG_USESYSCALL, ARG_NOPPCREGNAME,
12978 ARG_SYSTEMRELEASE, ARG_PRIORITY, ARG_LIBNAME, ARG_SMALLCODE, ARG_VOIDBASE,
12979 ARG_PREFIX, ARG_SUBPREFIX, ARG_PREMACRO, ARG_SMALLTYPES, ARG_AUTOHEADER
12982 /* argument definition array */
12983 static const struct ArgData argtexts[] = {
12984 {"help", 'h', 4, ARG_HELP},
12985 {"infile", 'i', 6, ARG_INFILE},
12986 {"special", 's', 7, ARG_SPECIAL},
12987 {"mode", 'm', 4, ARG_MODE},
12988 {"to", 't', 2, ARG_TO},
12989 {"clib", 'c', 4, ARG_CLIB},
12990 {"abi", 'a', 3, ARG_ABI},
12991 {"copyright", 'r', 9, ARG_COPYRIGHT},
12992 {"header", 'd', 6, ARG_HEADER},
12993 {"hunkname", 'n', 8, ARG_HUNKNAME},
12994 {"basename", 'b', 8, ARG_BASENAME},
12995 {"libtype", 'l', 7, ARG_LIBTYPE},
12996 {"libname", 'i', 7, ARG_LIBNAME},
12997 {"priority", 'p', 8, ARG_PRIORITY},
12998 {"autoheader", 0, 10, ARG_AUTOHEADER},
12999 {"comment", 0, 7, ARG_COMMENT},
13000 {"externc", 0, 7, ARG_EXTERNC},
13001 {"fpuonly", 0, 7, ARG_FPUONLY},
13002 {"newsyntax", 0, 9, ARG_NEWSYNTAX},
13003 {"nofpu", 0, 5, ARG_NOFPU},
13004 {"noppc", 0, 5, ARG_NOPPC},
13005 {"noppcregname", 0, 12, ARG_NOPPCREGNAME},
13006 {"nosymbol", 0, 8, ARG_NOSYMBOL},
13007 {"onlycnames", 0, 10, ARG_ONLYCNAMES},
13008 {"opt040", 0, 6, ARG_OPT040},
13009 {"ppconly", 0, 7, ARG_PPCONLY},
13010 {"private", 0, 7, ARG_PRIVATE},
13011 {"section", 0, 7, ARG_SECTION},
13012 {"smalldata", 0, 9, ARG_SMALLDATA},
13013 {"smalltypes", 0, 10, ARG_SMALLTYPES},
13014 {"smallcode", 0, 9, ARG_SMALLCODE},
13015 {"sorted", 0, 6, ARG_SORTED},
13016 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE},
13017 {"usesyscall", 0, 10, ARG_USESYSCALL},
13018 {"voidbase", 0, 8, ARG_VOIDBASE},
13019 {"prefix", 0, 6, ARG_PREFIX},
13020 {"subprefix", 0, 9, ARG_SUBPREFIX},
13021 {"premacro", 0, 8, ARG_PREMACRO},
13022 {0,0,0,0}, /* end marker */
13025 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
13026 static uint32 ParseArgEntry(uint32 argc, strptr *argv)
13028 uint32 numentries = 1, l;
13029 strptr a, b;
13030 const struct ArgData *ad;
13032 if((*argv)[0] != '-' || !(*argv)[1])
13033 return 0;
13035 ad = argtexts;
13036 while(ad->ArgName)
13038 if((*argv)[1] == ad->ArgChar || ((*argv)[1] == '-' && !strncmp(ad->ArgName, (*argv)+2, ad->ArgNameLen)))
13039 break;
13040 ++ad;
13042 if(!ad->ArgName)
13043 return 0;
13044 switch(ad->ArgNum)
13046 case ARG_HELP: printhelp(); break;
13047 case ARG_EXTERNC: Flags ^= FLAG_EXTERNC; break;
13048 case ARG_PRIVATE: Flags ^= FLAG_PRIVATE; break;
13049 case ARG_NEWSYNTAX: Flags ^= FLAG_NEWSYNTAX; break;
13050 case ARG_SMALLDATA: Flags ^= FLAG_SMALLDATA; break;
13051 case ARG_SMALLCODE: Flags2 ^= FLAG2_SMALLCODE; break;
13052 case ARG_SMALLTYPES: Flags2 ^= FLAG2_SMALLTYPES; break;
13053 case ARG_USESYSCALL: Flags ^= FLAG_SYSCALL; break;
13054 case ARG_OPT040: Flags ^= FLAG_NOMOVEM; break;
13055 case ARG_NOFPU: Flags ^= FLAG_NOFPU; break;
13056 case ARG_FPUONLY: Flags ^= FLAG_FPUONLY; break;
13057 case ARG_NOPPC: Flags ^= FLAG_NOPPC; break;
13058 case ARG_NOSYMBOL: Flags ^= FLAG_NOSYMBOL; break;
13059 case ARG_PPCONLY: Flags ^= FLAG_PPCONLY; break;
13060 case ARG_SECTION: Flags ^= FLAG_ASMSECTION; break;
13061 case ARG_COMMENT: Flags ^= FLAG_DOCOMMENT; break;
13062 case ARG_SORTED: Flags ^= FLAG_SORTED; break;
13063 case ARG_ONLYCNAMES: Flags ^= FLAG_ONLYCNAMES; break;
13064 case ARG_SYSTEMRELEASE: Flags2 ^= FLAG2_SYSTEMRELEASE; break;
13065 case ARG_VOIDBASE: Flags2 ^= FLAG2_VOIDBASE; break;
13066 case ARG_AUTOHEADER: Flags2 ^= FLAG2_AUTOHEADER; break;
13067 case ARG_NOPPCREGNAME: PPCRegPrefix = "";
13068 default:
13069 a = *argv+((*argv)[1] == '-' ? ad->ArgNameLen+2 : 2);
13070 if(!(*a))
13072 if(argc > 1) { a = argv[1]; numentries = 2; }
13073 else { a = 0; numentries = 0;}
13075 else if(*a == '=')
13076 ++a;
13077 if(a)
13079 if(*a == '\"')
13081 l = strlen(++a);
13082 if(a[l-1] == '\"')
13083 a[--l] = 0; /* remove second " */
13085 switch(ad->ArgNum)
13087 case ARG_INFILE: args.infile = a; break;
13088 case ARG_COPYRIGHT: Copyright = a; break;
13089 case ARG_TO: args.to = a; break;
13090 case ARG_ABI: defabi = a; break;
13091 case ARG_CLIB: args.clib = a; break;
13092 case ARG_HEADER: args.header = a; break;
13093 case ARG_HUNKNAME: hunkname = a; break;
13094 case ARG_PREFIX: prefix = a; break;
13095 case ARG_SUBPREFIX: subprefix = a; break;
13096 case ARG_PREMACRO: premacro = a; break;
13097 case ARG_LIBTYPE: libtype = a; Flags2 |= FLAG2_LIBTYPE; break;
13098 case ARG_LIBNAME: libname = a; Flags2 |= FLAG2_LIBNAME; break;
13099 case ARG_BASENAME: BaseName = a; Flags |= FLAG_BASENAME; break;
13100 case ARG_SPECIAL:
13101 args.special = strtoul(a, &b, 10);
13102 if(*b)
13103 numentries = 0;
13104 break;
13105 case ARG_PRIORITY:
13106 priority = strtoul(a, &b, 10);
13107 if(*b)
13108 numentries = 0;
13109 break;
13110 case ARG_MODE:
13111 args.mode = strtoul(a, &b, 10);
13112 if(*b || args.mode < 1 || args.mode > 3)
13113 numentries = 0;
13114 break;
13118 return numentries;
13121 /* initializes the arguments and starts argument parsing */
13122 static void GetArgs(int argc, char **argv)
13124 int res = 1;
13125 int i = 1, j;
13127 while(i < argc && res)
13129 if((j = ParseArgEntry(argc-i, argv+i)) < 1)
13130 res = 0;
13131 else
13132 i += j;
13134 if(!res || !args.infile)
13135 printhelp();
13138 #endif
13140 static strptr mygetfile(strptr name, size_t *len)
13142 strptr ptr = 0;
13143 FILE *infile;
13145 if((infile = fopen(name, "rb")))
13147 if(!fseek(infile, 0, SEEK_END))
13149 *len = ftell(infile);
13150 if(!fseek(infile, 0, SEEK_SET))
13152 if((ptr = AllocListMem(*len+1)))
13154 ptr[*len] = 0;
13155 #ifdef DEBUG_OLD
13156 printf("mygetfile: '%s' size %d\n", name, *len);
13157 #endif
13158 if(fread(ptr, *len, 1, infile) != 1)
13159 ptr = 0;
13163 fclose(infile);
13165 return ptr;
13168 int main(int argc, char **argv)
13170 uint32 mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_BOTH;
13171 strptr amicall = 0, libcall = 0, amitags = 0, libtags = 0;
13172 strptr clibbuf;
13173 size_t clibsize = 0;
13175 GetArgs(argc, argv);
13177 if((tempbuf = (uint8 *) AllocListMem(TEMPSIZE)))
13179 if(!(in.pos = in.buf = mygetfile(args.infile, &in.size)))
13181 if(args.special == 200)
13183 DoError(ERR_OPEN_FILE, 0, args.infile);
13184 exit(20);
13186 else
13188 sprintf((strptr)tempbuf, "%s" SFDFILEEXTENSION, args.infile);
13189 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13191 sprintf((strptr)tempbuf, "%s" FDFILEEXTENSION, args.infile);
13192 if(!(in.pos = in.buf = mygetfile((strptr)tempbuf, &in.size)))
13194 DoError(ERR_OPEN_FILE, 0, args.infile);
13195 exit(20);
13197 else
13198 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13200 else
13201 args.infile = DupString((strptr) tempbuf, strlen((strptr) tempbuf));
13204 printf("SourceFile: %s\n", args.infile);
13206 MakeLines(in.pos, in.size);
13208 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SORTED)) /* is not possible to use both */
13210 DoError(ERR_SORTED_COMMENT, 0);
13211 Flags &= (~FLAG_SORTED);
13214 if(args.special == 200)
13216 CreateFDFile();
13217 exit(0);
13220 if(!GetTypes())
13221 exit(20);
13223 if(!ScanFDFile())
13224 exit(20);
13226 if(args.clib)
13228 if(Flags2 & FLAG2_SFDMODE)
13229 DoError(ERR_SFD_AND_CLIB, 0);
13230 else
13232 sprintf((strptr)tempbuf, "%s_protos.h", args.clib);
13233 if(!(clibbuf = mygetfile(args.clib, &clibsize)) && !(clibbuf = mygetfile((strptr)tempbuf, &clibsize)))
13235 DoError(ERR_OPEN_FILE, 0, args.clib);
13236 exit(20);
13238 ScanClibFile(clibbuf, clibbuf+clibsize);
13242 if(!MakeShortBaseName())
13244 DoError(ERR_MISSING_SHORTBASENAME, 0);
13245 exit(20);
13248 /* WARN when requesting obsolete types! */
13249 switch(args.special)
13251 case 1: case 2: case 3: case 4: case 5: case 7:
13252 printf("You use obsolete data type %ld, better use type 6!\n", args.special);
13253 break;
13254 case 11: case 15: case 71: case 72: case 75:
13255 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13256 "link libraries!\n", args.special);
13257 break;
13258 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13259 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args.special);
13260 break;
13261 case 79:
13262 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13263 break;
13266 if(args.special < 10) /* the pragma area is up to 9 */
13268 mode = MODUS_PRAGMA;
13269 sprintf(filename, "%s_lib.h", ShortBaseName);
13271 switch(args.special)
13273 case 0: break;
13274 case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
13275 case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13276 pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
13277 case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
13278 pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
13279 libtags = "def " TEXT_SAS_60; break;
13280 case 4: amicall = ""; break;
13281 case 5: amicall = amitags = ""; break;
13282 case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
13283 case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
13284 TEXT_MAXON ") || defined(" TEXT_STORM ")";
13285 libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
13286 libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
13287 default: mode = MODUS_ERROR; break;
13290 if(args.mode > 0 && args.mode < 5)
13291 pragmode = args.mode;
13293 else if(args.special < 20) /* the misc area is up to 19 */
13295 if(args.mode > 0 && args.mode < 4)
13296 callmode = args.mode - 1;
13297 switch(args.special)
13299 case 10: mode = MODUS_CSTUB;
13300 sprintf(filename, "%s_cstub.h", ShortBaseName); break;
13301 case 11: mode = MODUS_STUBTEXT;
13302 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13303 case 12: mode = MODUS_STUBCODE;
13304 sprintf(filename, "%s.lib", ShortBaseName); break;
13305 case 13: Flags |= FLAG_LOCALREG; /* no break ! */
13306 case 14: mode = MODUS_LOCALDATA;
13307 sprintf(filename, "%s_loc.h", ShortBaseName); break;
13308 case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
13309 Flags ^= FLAG_PASCAL;
13310 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13311 case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
13312 Flags ^= FLAG_PASCAL;
13313 sprintf(filename, "%s.lib", ShortBaseName); break;
13314 case 17: mode = MODUS_BMAP; callmode = TAGMODE_NORMAL;
13315 sprintf(filename, "%s.bmap", ShortBaseName); break;
13316 case 18: mode = MODUS_EMODULE;
13317 sprintf(filename, "%s.m", ShortBaseName); break;
13318 default: mode = MODUS_ERROR; break;
13321 else if(args.special < 30) /* the lvo area is up to 29 */
13323 switch(args.special)
13325 case 20: case 22: mode = MODUS_LVO+args.special-20;
13326 sprintf(filename, "%s_lvo.i", ShortBaseName); break;
13327 case 21: case 23: mode = MODUS_LVO+args.special-20;
13328 sprintf(filename, "%s_lib.i", ShortBaseName); break;
13329 case 24: mode = MODUS_LVOLIB;
13330 sprintf(filename, "%slvo.o", ShortBaseName); break;
13331 default: mode = MODUS_ERROR; break;
13334 else if(args.special < 40) /* the proto area is up to 39 */
13336 if(args.special < 40)
13338 mode = MODUS_PROTO+args.special-30;
13339 sprintf(filename, "%s.h", ShortBaseName);
13341 else
13342 mode = MODUS_ERROR;
13344 else if(args.special < 50) /* the inline area is up to 49 */
13346 if(args.mode > 0 && args.mode < 4)
13347 callmode = args.mode - 1;
13349 switch(args.special)
13351 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13352 case 47:
13353 mode = MODUS_INLINE+args.special-40;
13354 sprintf(filename, "%s.h", ShortBaseName); break;
13355 case 48:
13356 Flags |= FLAG_STORMGCC;
13357 /* the same mode as for 46, but additional flag */
13358 mode = MODUS_INLINE+args.special-40-2;
13359 sprintf(filename, "%s.h", ShortBaseName); break;
13360 default: mode = MODUS_ERROR; break;
13363 else if(args.special < 60) /* the PowerUP area is up to 59 */
13365 if(args.mode > 0 && args.mode < 4)
13366 callmode = args.mode - 1;
13368 switch(args.special)
13370 case 50: case 51: case 52: mode = MODUS_INLINE+args.special-50;
13371 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_POWERUP;
13372 break;
13373 case 53:
13374 sprintf(filename, "%s_pragmas.h", ShortBaseName);
13375 mode = MODUS_SASPOWER; break;
13376 case 54:
13377 sprintf(filename, "%s.h", ShortBaseName);
13378 mode = MODUS_PROTOPOWER; break;
13379 default: mode = MODUS_ERROR; break;
13382 else if(args.special < 70) /* the PASCAL stuff */
13384 if(args.special == 60)
13386 mode = MODUS_PASCAL;
13387 sprintf(filename, "%s.pas", ShortBaseName);
13389 else
13390 mode = MODUS_ERROR;
13392 else if(args.special < 80) /* the VBCC stuff */
13394 if(args.mode > 0 && args.mode < 4)
13395 callmode = args.mode - 1;
13397 switch(args.special)
13399 case 70: mode = MODUS_VBCCINLINE;
13400 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13401 case 71: case 72: case 75:
13402 mode = MODUS_VBCC+args.special-71;
13403 sprintf(filename, "%s_stub.s", ShortBaseName); break;
13404 case 73: case 74:
13405 mode = MODUS_VBCC+args.special-71;
13406 sprintf(filename, "%s.lib", ShortBaseName); break;
13407 case 76:
13408 mode = MODUS_VBCCPUPLIB;
13409 sprintf(filename, "lib%s.a", ShortBaseName); break;
13410 case 77: mode = MODUS_VBCCWOSINLINE;
13411 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13412 case 78: mode = MODUS_VBCCMORPHCODE;
13413 sprintf(filename, "lib%s.a", ShortBaseName); break;
13414 case 79: mode = MODUS_VBCCINLINE;
13415 Flags2 |= FLAG2_OLDVBCC;
13416 callmode = TAGMODE_NORMAL;
13417 sprintf(filename, "%s_protos.h", ShortBaseName); break;
13418 default: mode = MODUS_ERROR; break;
13421 else if(args.special < 90) /* redirect stuff */
13423 mode = MODUS_REDIRECT;
13424 switch(args.special)
13426 case 80: sprintf(filename, "%s_pragmas.h", ShortBaseName); break;
13427 case 81: sprintf(filename, "%s_lib.h", ShortBaseName); break;
13428 case 82: sprintf(filename, "%s.h", ShortBaseName); break;
13429 case 83: sprintf(filename, "%s_protos.h", ShortBaseName); break;
13430 default: mode = MODUS_ERROR; break;
13433 else if(args.special < 100) /* multifile stuff */
13435 Flags |= FLAG_SINGLEFILE;
13436 switch(args.special)
13438 case 90:
13439 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13440 mode = MODUS_ASMTEXTSF; filenamefmt = "%s.s";
13441 break;
13442 case 91:
13443 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13444 mode = MODUS_VBCCPUPTEXTSF; filenamefmt = "%s.s";
13445 break;
13446 case 92:
13447 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13448 mode = MODUS_VBCCWOSTEXTSF; filenamefmt = "%s.s";
13449 break;
13450 case 93:
13451 if(args.mode > 0 && args.mode < 4) callmode = args.mode - 1;
13452 mode = MODUS_VBCCMORPHTEXTSF; filenamefmt = "%s.s";
13453 break;
13454 default: mode = MODUS_ERROR; break;
13457 else if(args.special < 110) /* PPC lvo's */
13459 switch(args.special)
13461 case 100: case 101: mode = MODUS_LVOPPC+args.special-100;
13462 sprintf(filename, "%s_lib.i", ShortBaseName);
13463 break;
13464 case 104: case 105: mode = MODUS_LVOPPC+args.special-104;
13465 Flags |= FLAG_ABIV4;
13466 sprintf(filename, "%s_lib.i", ShortBaseName);
13467 break;
13468 case 103: mode = MODUS_LVOLIB;
13469 sprintf(filename, "%slvo.o", ShortBaseName);
13470 break;
13471 case 107: mode = MODUS_LVOLIB;
13472 Flags |= FLAG_ABIV4;
13473 sprintf(filename, "%slvo.o", ShortBaseName);
13474 break;
13475 case 102: mode = MODUS_LVOLIBPPC;
13476 sprintf(filename, "%slvo.o", ShortBaseName); break;
13477 case 106: mode = MODUS_LVOLIBPPC;
13478 Flags |= FLAG_ABIV4;
13479 sprintf(filename, "%slvo.o", ShortBaseName); break;
13480 default: mode = MODUS_ERROR; break;
13483 else if(args.special < 120) /* different files */
13485 if(args.mode > 0 && args.mode < 4)
13486 callmode = args.mode - 1;
13488 switch(args.special)
13490 case 110: mode = MODUS_FD;
13491 sprintf(filename, "%s_lib.fd", ShortBaseName);
13492 if(Flags & FLAG_SORTED) /* is not possible to use here */
13494 DoError(ERR_SORTED_SFD_FD, 0);
13495 Flags &= (~FLAG_SORTED);
13497 break;
13498 case 111: mode = MODUS_CLIB; Flags2 |= FLAG2_CLIBOUT;
13499 sprintf(filename, "%s_protos.h", ShortBaseName);
13500 break;
13501 case 112: mode = MODUS_SFD; Flags2 |= FLAG2_SFDOUT;
13502 sprintf(filename, "%s_lib.sfd", ShortBaseName);
13503 if(callmode == 1)
13505 callmode = 2;
13506 DoError(ERR_ONLYTAGMODE_NOTALLOWED, 0);
13509 if(Flags & FLAG_SORTED) /* is not possible to use here */
13511 DoError(ERR_SORTED_SFD_FD, 0);
13512 Flags &= (~FLAG_SORTED);
13514 break;
13515 default: mode = MODUS_ERROR; break;
13518 else if(args.special < 130) /* auto libopen files */
13520 if(args.mode > 0 && args.mode < 4) /* for 122 */
13521 callmode = args.mode - 1;
13523 switch(args.special)
13525 case 120: mode = MODUS_GENAUTO;
13526 sprintf(filename, "%s_autoopenlib.c", ShortBaseName);
13527 break;
13528 case 121: mode = MODUS_GENAUTO+(args.special-120);
13529 sprintf(filename, "%s_autoopenlib.lib", ShortBaseName);
13530 break;
13531 case 123: Flags2 |= FLAG2_SHORTPPCVBCCINLINE; /* no break */
13532 case 122: mode = MODUS_VBCCMORPHINLINE;
13533 PPCRegPrefix = ""; /* no "r" allowed */
13534 sprintf(filename, "%s_protos.h", ShortBaseName);
13535 break;
13536 default: mode = MODUS_ERROR; break;
13539 else if(args.special < 140) /* the MorphOS area is up to 139 */
13541 if(args.mode > 0 && args.mode < 4)
13542 callmode = args.mode - 1;
13544 switch(args.special)
13546 case 130: case 131: case 132: mode = MODUS_INLINE+args.special-130;
13547 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13548 break;
13549 case 133: mode = MODUS_INLINE+2;
13550 sprintf(filename, "%s.h", ShortBaseName); Flags |= FLAG_MORPHOS;
13551 Flags2 |= FLAG2_DIRECTVARARGS;
13552 break;
13553 case 134: mode = MODUS_GATESTUBS;
13554 sprintf(filename, "%s_gates.h", ShortBaseName);
13555 break;
13556 case 135: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB;
13557 sprintf(filename, "%s_gates.h", ShortBaseName);
13558 break;
13559 case 136: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB;
13560 sprintf(filename, "%s_gates.h", ShortBaseName);
13561 break;
13562 case 137: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_PRELIB|FLAG2_REGLIB;
13563 sprintf(filename, "%s_gates.h", ShortBaseName);
13564 break;
13565 case 138: mode = MODUS_GATESTUBS; Flags2 |= FLAG2_POSTLIB|FLAG2_REGLIB;
13566 sprintf(filename, "%s_gates.h", ShortBaseName);
13567 break;
13568 default: mode = MODUS_ERROR; break;
13571 else if(args.special < 150) /* the OS4 area is up to 139 */
13573 if(args.mode > 0 && args.mode < 4)
13574 callmode = args.mode - 1;
13576 switch(args.special)
13578 case 140:
13579 mode = MODUS_XML;
13580 sprintf(filename, "%s.xml", ShortBaseName);
13581 break;
13582 case 141: /* OS4 PPC->M68K cross-call stubs */
13583 mode = MODUS_OS4_PPCSTUBS;
13584 sprintf(filename, "%s.c", ShortBaseName);
13585 break;
13586 case 142: /* OS4 M68K->PPC cross-call stubs */
13587 mode = MODUS_OS4_68KSTUBS;
13588 sprintf(filename, "%s_68k.s", ShortBaseName);
13589 break;
13590 default: mode = MODUS_ERROR; break;
13593 if(Flags & FLAG_SORTED)
13594 SortFDList();
13596 if((Flags & FLAG_DOCOMMENT) && (Flags & FLAG_SINGLEFILE)) /* is not possible to use both */
13598 DoError(ERR_COMMENT_SINGLEFILE, 0);
13599 Flags &= (~FLAG_DOCOMMENT);
13602 if(!mode || mode == MODUS_ERROR)
13603 printhelp();
13605 /* These modes need BaseName always. */
13606 if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
13607 mode == MODUS_STUBCODE || mode == MODUS_EMODULE || (mode >= MODUS_GENAUTO &&
13608 mode <= MODUS_GENAUTO+9)))
13610 DoError(ERR_MISSING_BASENAME, 0);
13611 exit(20);
13614 if(args.header && args.header[0] && (args.header[0] != '@' || args.header[1]))
13616 HEADER = mygetfile(args.header, &headersize);
13617 args.header = 0;
13620 if(!(Flags & FLAG_SINGLEFILE))
13622 if(!OpenDest(filename))
13623 exit(20);
13626 /* from here mode is used as return result */
13627 if(mode >= MODUS_GENAUTO)
13628 mode = CreateGenAuto(filename, mode-MODUS_GENAUTO);
13629 else if(mode >= MODUS_LVOPPC)
13630 mode = CreateLVOFilePPC(mode-MODUS_LVOPPC);
13631 else if(mode >= MODUS_VBCC)
13632 mode = CreateVBCC(mode-MODUS_VBCC, callmode);
13633 else if(mode >= MODUS_INLINE)
13634 mode = CreateInline(mode-MODUS_INLINE, callmode);
13635 else if(mode >= MODUS_PROTO)
13636 mode = CreateProtoFile(mode-MODUS_PROTO+1);
13637 else if(mode >= MODUS_LVO)
13638 mode = CreateLVOFile(mode-MODUS_LVO+1);
13639 else if(mode == MODUS_VBCCMORPHINLINE)
13640 mode = CreateVBCCInline(2, callmode);
13641 else if(mode == MODUS_XML)
13642 mode = CreateXML();
13643 else if(mode == MODUS_OS4_PPCSTUBS)
13644 mode = CreateOS4PPC(callmode);
13645 else if(mode == MODUS_OS4_68KSTUBS)
13646 mode = CreateOS4M68K();
13647 else if(mode == MODUS_GATESTUBS)
13648 mode = CreateGateStubs(callmode);
13649 else if(mode == MODUS_SFD)
13650 mode = CreateSFD(callmode);
13651 else if(mode == MODUS_CLIB)
13652 mode = CreateClib(callmode);
13653 else if(mode == MODUS_FD)
13654 mode = CreateFD();
13655 else if(mode == MODUS_LVOLIBPPC)
13656 mode = CreateLVOLibPPC();
13657 else if(mode == MODUS_VBCCMORPHCODE)
13658 mode = CreateVBCCMorphCode(callmode);
13659 else if(mode == MODUS_VBCCMORPHTEXTSF) /* single files */
13660 mode = CallFunc(callmode, "\n%s", FuncVBCCMorphText);
13661 else if(mode == MODUS_VBCCWOSINLINE)
13662 mode = CreateVBCCInline(1, callmode);
13663 else if(mode == MODUS_VBCCWOSTEXTSF) /* single files */
13664 mode = CallFunc(callmode, "\n%s", FuncVBCCWOSText);
13665 else if(mode == MODUS_VBCCPUPTEXTSF) /* single files */
13666 mode = CallFunc(callmode, "\n%s", FuncVBCCPUPText);
13667 else if(mode == MODUS_ASMTEXTSF) /* single files */
13668 mode = CallFunc(callmode, "\n%s", FuncAsmText);
13669 else if(mode == MODUS_REDIRECT)
13670 mode = CreateProtoRedirect();
13671 else if(mode == MODUS_EMODULE)
13672 mode = CreateEModule(Flags & FLAG_SORTED);
13673 else if(mode == MODUS_LVOLIB)
13674 mode = CreateLVOLib();
13675 else if(mode == MODUS_VBCCPUPLIB)
13676 mode = CreateVBCCPUPLib(callmode);
13677 else if(mode == MODUS_VBCCINLINE)
13678 mode = CreateVBCCInline(0, callmode);
13679 else if(mode == MODUS_PASCAL)
13680 mode = CreateFPCUnit();
13681 else if(mode == MODUS_BMAP)
13682 mode = CreateBMAP();
13683 else if(mode == MODUS_PROTOPOWER)
13684 mode = CreateProtoPowerUP();
13685 else if(mode == MODUS_SASPOWER)
13686 mode = CreateSASPowerUP(callmode);
13687 else if(mode == MODUS_CSTUB)
13688 mode = CreateCSTUBSFile();
13689 else if(mode == MODUS_PRAGMA)
13690 mode = CreatePragmaFile(amicall, libcall, amitags, libtags, pragmode);
13691 else if(mode == MODUS_LOCALDATA)
13692 mode = CreateLocalData(filename, callmode);
13693 else if(mode) /* MODUS_STUBTEXT starts with 1 */
13694 mode = CreateAsmStubs(mode, callmode);
13696 CloseDest(filename);
13698 if(!mode)
13700 DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
13701 exit(20);
13703 free(tempbuf);
13706 return 0;