2 static const char version
[] =
3 "$VER: fd2pragma 2.194 (02.01.2011) by Dirk Stoecker <software@dstoecker.de>";
5 /* There are four defines, which alter the result which is produced after
6 compiling this piece of code. */
8 /* turns on usage of Amiga ReadArgs-system (requires <proto/dos.h> include) */
9 /* #define FD2PRAGMA_READARGS */
11 /* enables Amiga style file name (only relevant for fd2pragma.types file) */
12 /* #define FD2PRAGMA_AMIGA */
14 /* debugging output */
17 /* more debugging output */
18 /* #define DEBUG_OLD */
25 Description: creates pragmas files, lvo files, ...
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:
38 72555 Metzingen (Germany)
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
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
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
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
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),
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
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
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
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
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
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
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
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
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
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
246 2.154 03.10.02 : added VBCC MorphOS inlines (SPECIAL 122). Thanks Frank Wille
248 2.155 04.10.02 : optimized VBCC MorphOS text (SPECIAL 93), fixed VBCC MorphOS
250 2.156 06.10.02 : added warning about obsolete types, fixed VBCC MorphOS Code
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.
294 2.185 08.02.05 : (phx) Special 38 (proto with vbcc inline) always generates
295 an inline-include now, and is no longer restricted to MorphOS & 68k.
296 Special Warp3DPPC support.
297 Marked some powerpc.library functions, which were erroneously
298 detected as tag functions.
299 2.186 17.02.05 : fixed PPC0-mode VBCC WOS stubs
300 2.187 26.03.05 : (phx) "(sysv,r12base)" in MorphOS FD-files is supported.
301 I made it identical to (sysv), which both load the library base
302 to r12 (correct in (sysv,r12base) mode and can't hurt in (sysv) mode).
303 Allow "(void)" instead of "()" as parameter list.
304 Function-pointer types can extend over multiple lines now (does
305 this make sense for other types too?).
306 New SDL-types: FPSmanager, Mix_Chunk, Mix_Music, Mix_MusicType,
307 Mix_EffectFunc_t, Mix_EffectDone_t, Mix_Fading, IPaddress,
308 TCPsocket, UDPpacket, UDPsocket, SDLNet_SocketSet,
309 SDLNet_GenericSocket, TTF_Font.
310 Put some of SDL-gfx functions ("...RGBA()") in the exceptions list.
311 2.188 30.03.05 : (phx) Put NewObject() into the NoInline-list.
312 2.189 21.05.05 : (phx) Always include emul/emulregs.h in vbcc/MOS inlines.
313 2.190 23.08.05 : (phx) Use ".file <name>.o" in assembler sources, HUNK_NAME
314 and ELF ST_FILE symbols. It was "<name>.s" before, which is wrong.
315 2.191 01.11.05 : (phx) Rewrote FuncVBCCWOSInline() based on the MOSInline-
316 function, to be able to handle varargs functions correctly.
317 Also fixed WOS-text and -code generation for PPC0-ABI.
318 2.192 06.01.10 : (phx) Do vbcc MorphOS OS-calls with BCTRL instead of BLRL
319 to avoid messing up the LR-stack of more recent PowerPCs (G4+).
320 2.193 18.09.10 : (phx) GLContext type (tinygl).
321 2.194 03.01.11 : (mazze) Fix for building it on CYGWIN.
322 Added AROS support in the proto file.
325 /* A short note, how fd2pragma works.
326 Working mode for SPECIAL 200 is a bit different!
327 The main function parses arguments. Switches are converted into FLAG_XXX
328 values and stored in global "Flags" or "Flags2" variable. SPECIAL numbers
329 are parsed and are used to call a CreateXXX function, with its interface
330 depending on the need of arguments (Some have 2, some none, ...). Before
331 SPECIAL arguments are parsed, fd2pragma loads (S)FD file and scans it using
332 Scan(S)FDFile(). If SORTED is specified, the list gets sorted nearly directly
333 afterwards. IF CLIB argument is given, the clib file is scanned after FD file
334 and a clib list is created. Now SPECIAL is parsed and mode is set to any of
335 the MODUS_XXX values. Also the destination file name is created if not given.
336 The destination file is opened now.
338 The mode variable is used to determine the correct CreateXXX function,
339 which is called afterwards. This function produces file headers and stuff
340 like that and calls CallFunc to process each FD entry.
342 CallFunc gets 3 arguments. First the workmode (TAG, NORMAL, BOTH).
343 Second the comment method (for C it is "/%s *\x2F\n", for ASM it is "\n%s",
344 no comment is reached with 0 argument). The last is most important. It is the
345 function pointer to a function creating the entries. These functions have
346 always the same interface and are called through CallFunc only! They create
347 an entry for the specified function (e.g. FD entry). Parsing special
348 functions, adding comments, checking for tag-functions, ... is done by
349 CallFunc. It is no problem to call CallFunc multiple with different function
350 pointers (as is done for SPECIAL 6 pragmas).
351 This is also the method if information abount the type or number of functions
352 is needed somewhere in the begin of the output file. A special function to
353 collect this data needs to be started before doing real output. Althought I
354 do not like it much, global variables or flags can be used to store that
357 The functions can use DoOutput to output texts in printf style or
358 DoOutputDirect to output all data in fwrite style. Buffering is done
361 fd2pragma has its own memory managment. All memory must be allocated using
362 AllocListMem and is freed automatically. This is especially useful for
363 DupString function, which is used in FD, SFD and CLIB scanner.
365 Normally this source-file is to big and should be splitted into different
366 files compiled alone and linked together. :-) It takes about 20 minutes to
367 compile it on my Amiga system with optimizations turned on.
369 There are lots of different input and output types and some combinations
370 are really useless or wrong. fd2pragma has the mechanisms to catch these
371 cases properly, but not all cases are really checked, as there are too many
372 of them and each new input type increases the number of combinations.
373 Also not all useful combinations me be handled correctly. If you find a
374 case which really matters please inform me. All the others require the
375 users to use their brains :-)
385 /* These are the only allowed variable types of all related programs! */
387 #include <exec/types.h>
389 typedef signed char int8
; /* signed 8 bit */
390 typedef unsigned char uint8
; /* unsigned 8 bit */
391 typedef signed short int int16
; /* signed 16 bit */
392 typedef unsigned short int uint16
; /* unsigned 16 bit */
393 typedef signed long int int32
; /* signed 32 bit */
394 typedef unsigned long int uint32
; /* unsigned 32 bit */
396 typedef float fl32
; /* 32 bit IEEE float value */
397 typedef double fl64
; /* 64 bit IEEE double value */
398 typedef char string
; /* the string datatype [e.g. one character of string!] */
399 typedef char * strptr
; /* and an string pointer */
401 #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
402 (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
403 #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
404 #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
405 (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
406 #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
408 #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
409 #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
410 #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
411 #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
413 #define TEXT_SAS "__SASC" /* verified */
414 #define TEXT_SAS_60 "__SASC_60" /* verified */
415 #define TEXT_MAXON "__MAXON__" /* verified */
416 #define TEXT_STORM "__STORM__" /* verified */
417 #define TEXT_DICE "_DCC" /* in 2.0 code */
418 #define TEXT_AZTEC "AZTEC_C" /* verified */
419 #define TEXT_GNUC "__GNUC__" /* verified */
420 #define TEXT_VBCC "__VBCC__" /* verified */
422 #define TEMPSIZE 20480
424 #define FLAG_EXTERNC (1<< 0) /* add externc statements */
425 #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
426 #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
427 #define FLAG_PRIVATE (1<< 3) /* also use private functions */
428 #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
429 #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
430 #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
431 #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
432 #define FLAG_DONE (1<< 8) /* destination file is not empty */
433 #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
434 #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
435 #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
436 #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
437 #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
438 #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
439 #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
440 #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
441 #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
442 #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
443 #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
444 #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
445 #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
446 #define FLAG_STORMGCC (1<<22) /* special workaround for StormGCC */
447 #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
448 #define FLAG_MORPHOS (1<<24) /* create MorphOS files */
449 #define FLAG_SORTED (1<<25) /* sort the functions by name */
450 #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
451 #define FLAG_SINGLEFILE (1<<27) /* create single files */
452 #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
453 #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
454 #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
455 #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
457 #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
458 #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
459 #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
460 #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
461 #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
462 #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
463 #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
464 #define FLAG2_VOIDBASE (1<< 7) /* library base should be of type "void *" */
465 #define FLAG2_INLINEMAC (1<< 8) /* use inline macro instead of function */
466 #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
467 #define FLAG2_PRELIB (1<<10) /* MorphOS gate PRELIB flag */
468 #define FLAG2_POSTLIB (1<<11) /* MorphOS gate POSTLIB flag */
469 #define FLAG2_REGLIB (1<<12) /* MorphOS gate REGLIB flag */
470 #define FLAG2_OLDVBCC (1<<13) /* old VBCC style */
471 #define FLAG2_SMALLTYPES (1<<14) /* allow small data types */
472 #define FLAG2_AUTOHEADER (1<<15) /* creates auto generated header */
473 #define FLAG2_LIBNAMECOM (1<<16) /* libname was specified in SFD comment */
474 #define FLAG2_OS4M68KCSTUB (1<<17) /* OS4 M68K stub needs C */
475 #define FLAG2_SHORTPPCVBCCINLINE (1<<18) /* shorter PPC inline using argument */
477 #define FUNCFLAG_NORMAL (1<<0) /* normal function */
478 #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
479 #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
480 #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
482 /* Different modes the main program uses, one for each different file
483 type (except for those done with one function and flag settings). */
484 #define MODUS_STUBTEXT 1
485 #define MODUS_STUBCODE 2
486 #define MODUS_LOCALDATA 3
487 #define MODUS_PRAGMA 4
488 #define MODUS_CSTUB 5
489 #define MODUS_SASPOWER 6
490 #define MODUS_PROTOPOWER 7
492 #define MODUS_PASCAL 9
493 #define MODUS_VBCCINLINE 10
494 #define MODUS_VBCCPUPLIB 11
495 #define MODUS_LVOLIB 12
496 #define MODUS_EMODULE 13
497 #define MODUS_REDIRECT 14
498 #define MODUS_ASMTEXTSF 15
499 #define MODUS_VBCCPUPTEXTSF 16
500 #define MODUS_VBCCWOSTEXTSF 17
501 #define MODUS_VBCCWOSINLINE 18
502 #define MODUS_VBCCMORPHTEXTSF 19
503 #define MODUS_VBCCMORPHCODE 20
504 #define MODUS_LVOLIBPPC 21
506 #define MODUS_CLIB 23
508 #define MODUS_GATESTUBS 25
509 #define MODUS_VBCCMORPHINLINE 26
511 #define MODUS_OS4_PPCSTUBS 28
512 #define MODUS_OS4_68KSTUBS 29
513 #define MODUS_LVO 50 /* and 51 and 52 and 53 */
514 #define MODUS_PROTO 60 /* and 61 to 69 */
515 /* new protos start with 90, but are added to MODUS_PROTO ! */
516 #define MODUS_INLINE 80 /* and 81 to 86 */
517 #define MODUS_VBCC 90 /* and 91 to 94 */
518 #define MODUS_LVOPPC 100 /* and 101 */
519 #define MODUS_GENAUTO 110 /* and 111 to 113 */
520 #define MODUS_ERROR 200
522 enum ABI
{ABI_M68K
, ABI_PPC
, ABI_PPC2
, ABI_PPC0
};
524 /* call types for CallFunc */
525 #define TAGMODE_NORMAL 0 /* produce normal functions only */
526 #define TAGMODE_TAGS 1 /* produce only tag functions */
527 #define TAGMODE_BOTH 2 /* produce both types */
529 /* types specifying name method for pragma creation */
530 #define PRAGMODE_PRAGLIB 1
531 #define PRAGMODE_PRAGSLIB 2
532 #define PRAGMODE_PRAGSPRAGS 3
533 #define PRAGMODE_NONE 4
535 #define BIAS_START 30 /* the library start offset */
536 #define BIAS_OFFSET 6 /* value to switch from one to next function */
538 #ifndef FD2PRAGMA_AMIGA
539 #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
542 #define EXTTYPESFILE "fd2pragma.types"
544 #ifndef EXTTYPESFILE2
545 #ifdef FD2PRAGMA_AMIGA
546 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
548 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
552 #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
554 #define FDFILEEXTENSION "_lib.fd"
555 #define SFDFILEEXTENSION "_lib.sfd"
557 static const strptr RegNames
[] = {
558 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
559 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
560 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
563 static const strptr RegNamesUpper
[] = {
564 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
565 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
566 "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
570 REG_D0
, REG_D1
, REG_D2
, REG_D3
, REG_D4
, REG_D5
, REG_D6
, REG_D7
,
571 REG_A0
, REG_A1
, REG_A2
, REG_A3
, REG_A4
, REG_A5
, REG_A6
, REG_A7
,
572 REG_FP0
, REG_FP1
, REG_FP2
, REG_FP3
, REG_FP4
, REG_FP5
, REG_FP6
, REG_FP7
575 #define MAXREG 24 /* maximum registers of 68K */
576 #define MAXREGNF 16 /* maximum register number without float regs */
577 #define UNDEFREGISTER 255 /* for type scanner */
589 struct ShortList
*Next
;
592 struct ShortListRoot
{
593 struct ShortList
*First
;
594 struct ShortList
*Last
;
598 #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
599 #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
600 #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
601 #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
602 #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
603 #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
604 #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
605 #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
606 #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
607 #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
608 #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
609 #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
610 #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
611 #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
612 #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
613 #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
614 #define AMIPRAGFLAG_MOSSYSV (1<<16) /* MorphOS(sysv) type */
615 #define AMIPRAGFLAG_MOSSYSVR12 (1<<17) /* MorphOS(sysv,r12base) type */
616 #define AMIPRAGFLAG_MOSBASESYSV (1<<18) /* MorphOS(base,sysv) type */
617 #define AMIPRAGFLAG_VARARGS (1<<19) /* last argument is ... */
619 #define AMIPRAGFLAG_MOS_ALL (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12|AMIPRAGFLAG_MOSBASESYSV)
626 #define NUMALIASNAMES 5
629 struct ShortList List
;
634 struct Pragma_AliasName
* AliasName
[NUMALIASNAMES
]; /* alias names */
635 uint16 NumArgs
; /* register numbers */
636 uint16 CallArgs
; /* argument number in fd file */
640 struct AmiArgs Args
[MAXREGPPC
];
644 struct ShortList List
;
649 uint8 Private
; /* is a flag only */
653 struct ShortList List
;
658 struct ShortList List
;
659 struct ShortListRoot Data
; /* contains list of PragData */
664 struct ShortList List
;
665 struct ShortListRoot Name
;
669 uint8 ArgReg
[MAXREG
];
676 uint32 Mode
; /* 0 = Normal, != 0 is TagName */
678 uint8 ArgReg
[MAXREG
];
681 /* NOTE: string creation for CPP-Functions probably does not work at all
682 at the moment, as every compiler uses different systems which seem to
683 change constantly. */
685 /* These CPP types match the strings used for CPP name creation. The
686 defines are used both for name creation and type specification. */
687 #define CPP_TYPE_VOID 'v' /* void, VOID */
688 #define CPP_TYPE_BYTE 'c' /* char, int8 */
689 #define CPP_TYPE_WORD 's' /* short, int16 */
690 #define CPP_TYPE_LONG 'j' /* long, int32 */
691 #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
692 #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
693 #define CPP_TYPE_INT 'i' /* int */
694 #define CPP_TYPE_STRUCTURE 0
695 #define CPP_TYPE_VARARGS 'e'
696 #define CPP_TYPE_LONGLONG 'l' /* long long, int64 */
698 /* These types are for string creation only. */
699 #define CPP_TYPE_ENUM 'E'
700 #define CPP_TYPE_CONST 'C'
701 #define CPP_TYPE_FUNCTION 'F'
702 #define CPP_TYPE_POINTER 'P'
703 #define CPP_TYPE_UNSIGNED 'U'
704 #define CPP_TYPE_FUNCEND 'p'
705 #define CPP_TYPE_REGISTER 'r'
707 /* Some flags to be used in CPP_NameType->Flags. */
708 #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
709 #define CPP_FLAG_CONST (1<<1) /* type is const */
710 #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
711 #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
712 #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
713 #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
714 #define CPP_FLAG_UNION (1<<6) /* it is a union */
715 #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
716 #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
717 #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
718 #define CPP_FLAG_TYPEDEFNAME (1<<10) /* name is created from typedef */
719 #define CPP_FLAG_ARRAY (1<<11) /* this type is an array */
720 #define CPP_FLAG_LONG (1<<12) /* type is long */
721 /* STRPTR is defined different under C and CPP -> I have to create two
722 names, one time unsigned char *, one time signed char *, when somewhere
725 #define COPYCPP_PASSES 4
727 struct CPP_NameType
{ /* structure to describe a argument type */
728 strptr StructureName
; /* if a structure or enum only */
729 strptr FuncArgs
; /* arguments of function - unterminated */
730 strptr TypeStart
; /* start of this type */
731 strptr Replace
; /* replacement of type for SFD files */
732 strptr Unknown
; /* unknown type handled as int */
733 strptr FunctionName
; /* Argument name of function argument */
734 struct ClibData
*FuncPtr
; /* if it is a function pointer */
735 uint16 StructureLength
; /* length of the structure name */
736 uint16 ArgsLength
; /* length of FuncArgs */
737 uint16 TypeLength
; /* length of this type */
738 uint16 FullLength
; /* length of complete type */
739 uint16 PointerDepth
; /* number of * in type */
740 uint16 FuncPointerDepth
; /* number of * in function pointer */
741 uint16 Flags
; /* see above flags */
742 uint8 Type
; /* see above defines */
743 uint8 Register
; /* register number */
746 struct ClibData
{ /* structure to describe data in CLIB file */
747 struct ClibData
* Next
; /* The next entry in this list */
748 strptr FuncName
; /* name of the function */
749 struct CPP_NameType ReturnType
; /* data for return type */
750 struct CPP_NameType Args
[MAXREGPPC
+1]; /* data for argument types */
751 uint16 NumArgs
; /* number of arguments */
754 struct CPP_ExternNames
{ /* structure for EXTTYPESFILE data */
755 struct CPP_ExternNames
* Next
; /* The next entry in this list */
756 strptr Type
; /* The unknown type */
757 struct CPP_NameType NameType
; /* The replacement */
760 struct CPP_TypeField
{ /* structure for internal defined types */
761 strptr Text
; /* name of the type */
762 uint16 Length
; /* length of the name string */
763 uint16 Flags
; /* CPP_FLAG flags */
764 uint8 Type
; /* CPP_TYPE value */
768 struct CPP_Unknown
*Next
;
772 struct Proto_LibType
{ /* structure to define structure type of base vars */
773 strptr BaseName
; /* name of the library base */
774 strptr StructureName
; /* name of the structure to be used (0 for default) */
775 strptr LibraryName
; /* name of the library (maybe 0 for default method) */
776 strptr ShortBaseName
; /* short name of the library base */
779 struct Pragma_ExecpName
{ /* structure to specify special tagnames */
780 strptr FunctionName
; /* function name */
781 strptr TagName
; /* tag name to be used for this function */
782 }; /* TagName 0 is valid as well to disable tagfunctions */
784 struct Pragma_AliasName
{
790 #define NTP_NORMAL 0 /* no tags/args */
791 #define NTP_TAGS 1 /* TagFunction */
792 #define NTP_ARGS 2 /* ArgFunction */
793 #define NTP_UNKNOWN 3 /* CommentFunction */
796 struct ShortList List
;
797 uint32 Type
; /* set by OptimizeFDData */
808 /* EHF definitions! */
809 #define HUNK_PPC_CODE 0x4E9
810 #define HUNK_RELRELOC26 0x4EC
811 #define EXT_RELREF26 229
813 /* ------------------------------------------------------------------ */
814 /* A short set of ELF definitions, see pasm sources in vbcc release for an
815 more complete set of stuff or get elf documentation. These are needed for
816 VBCCPUPCode function. */
818 #define ELFDATA2MSB 2
819 #define EV_CURRENT 1 /* version information */
820 #define ET_REL 1 /* type information */
821 #define EM_POWERPC 20
823 #define SHT_NULL 0 /* inactive */
824 #define SHT_PROGBITS 1 /* program information */
825 #define SHT_SYMTAB 2 /* symbol table */
826 #define SHT_STRTAB 3 /* string table */
827 #define SHT_RELA 4 /* relocation */
829 #define SHF_ALLOC 0x2 /* needs memory when started */
830 #define SHF_EXECINSTR 0x4 /* executable instructions */
832 #define SHN_ABS 0xFFF1
847 #define STT_SECTION 3
849 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
850 #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
852 #define R_PPC_ADDR16_LO 4
853 #define R_PPC_ADDR16_HA 6
854 #define R_PPC_REL24 10
855 #define R_PPC_SDAREL16 32
858 string ar_name
[16]; /* name */
859 string ar_time
[12]; /* modification time */
860 string ar_uid
[6]; /* user id */
861 string ar_gid
[6]; /* group id */
862 string ar_mode
[8]; /* octal file permissions */
863 string ar_size
[10]; /* size in bytes */
864 string ar_fmag
[2]; /* consistency check */
867 /* AmigaOS hunk structure definitions */
869 #include <dos/doshunks.h>
871 #define HUNK_UNIT 999
872 #define HUNK_NAME 1000
873 #define HUNK_CODE 1001
874 #define HUNK_BSS 1003
875 #define HUNK_ABSRELOC32 1004
876 #define HUNK_EXT 1007
877 #define HUNK_SYMBOL 1008
878 #define HUNK_END 1010
879 #define HUNK_DREL16 1016
881 #define EXT_DEF 1 /* normal definition */
882 #define EXT_ABS 2 /* Absolute definition */
883 #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
884 #define EXT_DEXT16 134 /* 16 bit data relative reference */
886 /* ------------------------------------------------------------------ */
888 static struct Args args
= {0,0,0,0,6,0};
889 static struct InFile in
= {0,0,0};
890 static FILE * outfile
;
891 static struct ClibData
* clibdata
= 0;
892 static struct ShortListRoot AmiPragma
= {0,0,sizeof(struct AmiPragma
)},
893 Comment
= {0,0,sizeof(struct Comment
)},
894 Includes
= {0,0,sizeof(struct Include
)};
895 static struct CPP_ExternNames
*extnames
= 0;
896 static struct CPP_Unknown
*unknown
= 0;
897 static strptr BaseName
= 0; /* the correct basename */
898 /* the filename part of basename without Base */
899 static strptr ShortBaseName
= 0;
900 /* like ShortBaseName, but upper case */
901 static strptr ShortBaseNameUpper
= 0;
902 static strptr HEADER
= 0;
903 static strptr Copyright
= 0;
904 static strptr filenamefmt
= 0;
905 static strptr libtype
= 0;
906 static strptr libname
= 0;
907 static strptr defabi
= 0;
908 static strptr hunkname
= ".text";
909 static strptr datahunkname
= "__MERGED";
910 static strptr PPCRegPrefix
= "r";
911 static strptr IDstring
= 0;
912 static strptr prefix
= "";
913 static strptr subprefix
= "";
914 static strptr premacro
= "";
915 static uint8
* tempbuf
= 0;
916 static size_t headersize
= 0;
917 static uint32 Flags
= 0;
918 static uint32 Flags2
= 0;
919 /* Output error occured when 0 */
920 static uint32 Output_Error
= 1;
921 /* are there some tagfuncs in FD */
922 static uint32 tagfuncs
= 0;
923 /* priority for auto libopen */
924 static uint32 priority
= 5;
925 /* needed for filename */
926 static string filename
[255];
928 /* Only for E-Stuff, FD, SFD, XML creation */
929 static int32 LastBias
= 0;
930 /* Only for PPC-LVO Lib's */
931 static uint8
* elfbufpos
= 0;
932 /* Only for PPC-LVO Lib's */
933 static uint32 symoffset
= 0;
934 /* Only for FD, SFD creation */
935 static enum ABI CurrentABI
= ABI_M68K
;
937 /* Prototypes for the functions */
938 static strptr
DupString(strptr
, size_t);
939 static strptr
AllocListMem(size_t);
940 static strptr
SkipBlanks(strptr
);
941 static strptr
SkipBlanksRet(strptr
);
942 static strptr
SkipName(strptr
);
943 static uint32
GetTypes(void);
944 static strptr
GetBaseType(void);
945 static strptr
GetBaseTypeLib(void);
946 static strptr
GetLibraryName(void);
947 static strptr
GetIFXName(void);
948 static int32
MakeShortBaseName(void);
949 static uint32
OpenDest(strptr
);
950 static uint32
CloseDest(strptr
);
951 static uint32
MakeTagFunction(struct AmiPragma
*);
952 static void MakeLines(strptr
, uint32
);
953 static uint32
SpecialFuncs(void);
954 static void SortFDList(void);
955 static void AddAliasName(struct AmiPragma
*, struct Pragma_AliasName
*,
957 static uint32
CheckNames(struct AmiPragma
*);
958 static uint32
ScanSFDFile(enum ABI
);
959 static uint32
ScanFDFile(void);
960 static int32
ScanTypes(strptr
, uint32
);
961 static void FindHeader(void);
962 static uint32
GetRegisterData(struct AmiPragma
*);
963 static uint16
GetFRegisterData(struct AmiPragma
*);
964 static uint32
OutputXDEF(uint32
, strptr
, ...);
965 static uint32
OutputXREF(uint32
, uint32
, strptr
, ...);
966 static uint32
OutputXREF2(uint32
, uint32
, uint32
, strptr
, ...);
967 static uint32
OutputSYMBOL(uint32
, strptr
, ...);
968 static uint8
* AsmStackCopy(uint8
*, struct AmiPragma
*, uint32
, uint32
);
969 /* ------------------------------------------------------------------ */
970 static void DoError(uint32
, uint32
, ...);
971 static uint32
CheckError(struct AmiPragma
*, uint32
);
972 static uint32
DoOutputDirect(void *, size_t);
974 #if defined(__GNUC__)
975 static uint32
DoOutput(strptr
, ...) __attribute__ ((format(printf
, 1, 2)));
977 static uint32
DoOutput(strptr
, ...);
979 /* ------------------------------------------------------------------ */
980 static struct ShortList
*NewItem(struct ShortListRoot
*);
981 static struct ShortList
*RemoveItem(struct ShortListRoot
*, struct ShortList
*);
982 static void AddItem(struct ShortListRoot
*, struct ShortList
*);
983 /* ------------------------------------------------------------------ */
984 typedef uint32 (*FuncType
)(struct AmiPragma
*, uint32
, strptr
);
986 uint32
FuncAMICALL (struct AmiPragma
*, uint32
, strptr
);
987 uint32
FuncLIBCALL (struct AmiPragma
*, uint32
, strptr
);
988 uint32
FuncAsmText (struct AmiPragma
*, uint32
, strptr
);
989 uint32
FuncAsmCode (struct AmiPragma
*, uint32
, strptr
);
990 uint32
FuncCSTUBS (struct AmiPragma
*, uint32
, strptr
);
991 uint32
FuncLVOXDEF (struct AmiPragma
*, uint32
, strptr
);
992 uint32
FuncLVO (struct AmiPragma
*, uint32
, strptr
);
993 uint32
FuncLVOPPCXDEF (struct AmiPragma
*, uint32
, strptr
);
994 uint32
FuncLVOPPC (struct AmiPragma
*, uint32
, strptr
);
995 uint32
FuncLVOPPCBias (struct AmiPragma
*, uint32
, strptr
);
996 uint32
FuncLVOPPCName (struct AmiPragma
*, uint32
, strptr
);
997 uint32
FuncLVOLib (struct AmiPragma
*, uint32
, strptr
);
998 uint32
FuncLocCode (struct AmiPragma
*, uint32
, strptr
);
999 uint32
FuncLocText (struct AmiPragma
*, uint32
, strptr
);
1000 uint32
FuncInline (struct AmiPragma
*, uint32
, strptr
);
1001 uint32
FuncInlineDirect (struct AmiPragma
*, uint32
, strptr
);
1002 uint32
FuncInlineNS (struct AmiPragma
*, uint32
, strptr
);
1003 uint32
FuncPowerUP (struct AmiPragma
*, uint32
, strptr
);
1004 uint32
FuncFPCUnit (struct AmiPragma
*, uint32
, strptr
);
1005 uint32
FuncFPCType (struct AmiPragma
*, uint32
, strptr
);
1006 uint32
FuncFPCTypeTags (struct AmiPragma
*, uint32
, strptr
);
1007 uint32
FuncFPCTypeTagsUnit (struct AmiPragma
*, uint32
, strptr
);
1008 uint32
FuncBMAP (struct AmiPragma
*, uint32
, strptr
);
1009 uint32
FuncVBCCInline (struct AmiPragma
*, uint32
, strptr
);
1010 uint32
FuncVBCCWOSInline (struct AmiPragma
*, uint32
, strptr
);
1011 uint32
FuncVBCCMorphInline (struct AmiPragma
*, uint32
, strptr
);
1012 uint32
FuncVBCCWOSText (struct AmiPragma
*, uint32
, strptr
);
1013 uint32
FuncVBCCWOSCode (struct AmiPragma
*, uint32
, strptr
);
1014 uint32
FuncVBCCPUPText (struct AmiPragma
*, uint32
, strptr
);
1015 uint32
FuncVBCCPUPCode (struct AmiPragma
*, uint32
, strptr
);
1016 uint32
FuncEModule (struct AmiPragma
*, uint32
, strptr
);
1017 uint32
FuncVBCCMorphText (struct AmiPragma
*, uint32
, strptr
);
1018 uint32
FuncVBCCMorphCode (struct AmiPragma
*, uint32
, strptr
);
1019 uint32
FuncFD (struct AmiPragma
*, uint32
, strptr
);
1020 uint32
FuncClib (struct AmiPragma
*, uint32
, strptr
);
1021 uint32
FuncSFD (struct AmiPragma
*, uint32
, strptr
);
1022 uint32
FuncXML (struct AmiPragma
*, uint32
, strptr
);
1023 uint32
FuncOS4PPC (struct AmiPragma
*, uint32
, strptr
);
1024 uint32
FuncOS4M68KCSTUB (struct AmiPragma
*, uint32
, strptr
);
1025 uint32
FuncOS4M68K (struct AmiPragma
*, uint32
, strptr
);
1026 uint32
FuncOS4M68KVect (struct AmiPragma
*, uint32
, strptr
);
1027 uint32
FuncGateStubs (struct AmiPragma
*, uint32
, strptr
);
1028 static uint32
PrintComment (struct Comment
*, strptr
);
1029 static uint32
DoCallFunc (struct AmiPragma
*, uint32
, strptr
, FuncType
);
1030 static uint32
CallFunc (uint32
, strptr
, FuncType
);
1031 static uint32
PrintIncludes(void);
1032 /* ------------------------------------------------------------------ */
1033 static int32
AddClibEntry(strptr
, strptr
, uint32
);
1034 static int32
ScanClibFile(strptr
, strptr
);
1035 static int32
IsCPPType(struct CPP_NameType
*, uint8
);
1036 static uint32
CheckRegisterNum(strptr
, struct CPP_NameType
*);
1037 static uint32
ParseFuncPtrArgs(strptr
, struct CPP_NameType
*);
1038 static int32
GetCPPType(struct CPP_NameType
*, strptr
, uint32
, uint32
);
1039 static struct ClibData
*GetClibFunc(strptr
, struct AmiPragma
*, uint32
);
1040 static int32
CheckKeyword(strptr
, strptr
, int32
);
1041 static uint32
CopyCPPType(strptr
, uint32
, struct ClibData
*, struct AmiArgs
*);
1042 static uint32
OutClibType(struct CPP_NameType
*, strptr
);
1043 static uint32
MakeClibType(strptr
, struct CPP_NameType
*, strptr
);
1044 static uint32
OutPASCALType(struct CPP_NameType
*, strptr
, uint32
);
1045 /* ------------------------------------------------------------------ */
1046 static uint32
CallPrag(uint32
, strptr
, FuncType
);
1047 static uint32
CreatePragmaFile(strptr
, strptr
, strptr
, strptr
, uint32
);
1048 static uint32
CreateCSTUBSFile(void);
1049 static uint32
CreateLVOFile(uint32
);
1050 static uint32
CreateLVOFilePPC(uint32
);
1051 static uint32
CreateAsmStubs(uint32
, uint32
);
1052 static uint32
CreateProtoFile(uint32
);
1053 static uint32
CreateLocalData(strptr
, uint32
);
1054 static uint32
CreateInline(uint32
, uint32
);
1055 static uint32
CreateGateStubs(uint32
);
1056 static uint32
CreateSASPowerUP(uint32
);
1057 static uint32
CreateProtoPowerUP(void);
1058 static uint32
CreateFPCUnit(void);
1059 static uint32
CreateBMAP(void);
1060 static uint32
CreateLVOLib(void);
1061 static uint32
CreateLVOLibPPC(void);
1062 static uint32
CreateVBCCInline(uint32
, uint32
);
1063 static uint32
CreateVBCC(uint32
, uint32
);
1064 static uint32
CreateVBCCPUPLib(uint32
);
1065 static uint32
CreateVBCCMorphCode(uint32
);
1066 static uint32
CreateEModule(uint32
);
1067 static uint32
CreateProtoRedirect(void);
1068 static uint32
CreateFD(void);
1069 static uint32
CreateSFD(uint32
);
1070 static uint32
CreateClib(uint32
);
1071 static uint32
CreateGenAuto(strptr
, uint32
);
1072 static uint32
CreateXML(void);
1073 static uint32
CreateOS4PPC(uint32
);
1074 static uint32
CreateOS4M68K(void);
1075 /* ------------------------------------------------------------------ */
1076 static uint32
GetName(struct NameList
*, struct ShortListRoot
*, uint32
);
1077 static uint32
MakeFD(struct PragList
*);
1078 static void OptimizeFDData(struct PragData
*);
1079 static string
GetHexValue(string
);
1080 static string
GetDoubleHexValue(strptr
);
1081 static uint32
AddFDData(struct ShortListRoot
*, struct FDData
*);
1082 static uint32
GetLibData(struct FDData
*);
1083 static uint32
GetFlibData(struct FDData
*);
1084 static uint32
GetAmiData(struct FDData
*);
1085 static uint32
CreateFDFile(void);
1086 /* ------------------------------------------------------------------ */
1087 static void GetArgs(int argc
, char **argv
);
1088 static strptr
mygetfile(strptr name
, size_t *len
);
1090 #define ERROFFSET_CLIB (1<<31)
1093 ERR_TAGFUNC_NEEDS_ARGUMENT
,
1094 ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
,
1095 ERR_TAG_DEF_WITHOUT_PRAGMA
,
1096 ERR_BASENAME_DECLARED_TWICE
,
1097 ERR_EXPECTED_SLASH_IN_BASENAME
,
1098 ERR_EXPECTED_BASENAME
,
1099 ERR_EXPECTED_BIAS_VALUE
,
1100 ERR_ASSUMING_POSITIVE_BIAS_VALUE
,
1101 ERR_MISSING_FUNCTION_NAME
,
1102 ERR_EXPECTED_OPEN_BRACKET
,
1103 ERR_TO_MUCH_ARGUMENTS
,
1104 ERR_EXPECTED_ARGUMENT_NAME
,
1105 ERR_EXPECTED_CLOSE_BRACKET
,
1106 ERR_EXPECTED_REGISTER_NAME
,
1108 ERR_REGISTER_USED_TWICE
,
1109 ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
,
1110 ERR_ASSUMING_BIAS_OF_30
,
1111 ERR_EXTRA_CHARACTERS
,
1112 ERR_MISSING_BASENAME
,
1115 ERR_DIFFERENT_TO_PREVIOUS
,
1116 ERR_UNKNOWN_VARIABLE_TYPE
,
1119 ERR_PROTOTYPE_MISSING
,
1120 ERR_NOPROTOTYPES_FILE
,
1121 ERR_UNKNOWN_DIRECTIVE
,
1122 ERR_INLINE_A4_AND_A5
,
1123 ERR_INLINE_D7_AND_A45
,
1124 ERR_MISSING_SHORTBASENAME
,
1127 ERR_FLOATARG_NOT_ALLOWED
,
1128 ERR_WRONG_TYPES_LINE
,
1133 ERR_PPC_FUNCTION_NOT_SUPPORTED
,
1136 ERR_ILLEGAL_FUNCTION_POSITION
,
1138 ERR_COMMENT_SINGLEFILE
,
1139 ERR_NOFD2PRAGMATYPES
,
1140 ERR_M68K_FUNCTION_NOT_SUPPORTED
,
1141 ERR_UNKNOWN_RETURNVALUE_TYPE
,
1143 ERR_EXCPECTED_IDSTRING
,
1144 ERR_EXPECTED_ID_ENDSIGN
,
1146 ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
,
1147 ERR_IDSTRING_DECLARED_TWICE
,
1148 ERR_COMMANDLINE_LIBTYPE
,
1149 ERR_COMMANDLINE_BASENAME
,
1150 ERR_LIBTYPE_DECLARED_TWICE
,
1151 ERR_EXPECTED_LIBTYPE
,
1155 ERR_VARARGS_ARGUMENTS_DIFFER
,
1156 ERR_UNEXPECTED_FILEEND
,
1157 ERR_VARARGS_ALIAS_FIRST
,
1159 ERR_EXPECTED_STRUCT
,
1160 ERR_EXPECTED_POINTERSIGN
,
1161 ERR_ARGNAME_KEYWORD_CONFLICT
,
1162 ERR_ARGNAME_ARGNAME_CONFLICT
,
1163 ERR_ONLYTAGMODE_NOTALLOWED
,
1164 ERR_COMMANDLINE_LIBNAME
,
1165 ERR_LIBNAME_DECLARED_TWICE
,
1166 ERR_EXPECTED_LIBNAME
,
1168 ERR_MULTIPLEFUNCTION
,
1169 ERR_INLINE_AX_SWAPREG
,
1171 ERR_ILLEGAL_CHARACTER_DETECTED
,
1172 ERR_UNKNOWN_VARIABLE_TYPE_INT
,
1173 ERR_UNKNOWN_RETURNVALUE_TYPE_INT
,
1174 ERR_ILLEGAL_INTERNAL_VALUE
,
1175 ERR_MOSBASESYSV_NOT_SUPPORTED
,
1176 ERR_ALIASES_NOT_SUPPORTED
,
1177 ERR_FUNCTION_NOT_SUPPORTED
,
1180 static const struct ErrField
{
1181 uint8 Type
; /* 0 = Error, 1 = Warning */
1185 {1, 1, "Tag function must have arguments."},
1186 {1, 1, "Cannot convert pragma name into tag name."},
1187 {1, 1, "Tag definition without preceding Pragma."},
1188 {1, 0, "Basename declared twice."},
1189 {1, 0, "Expected preceding _ in Basename."},
1190 {1, 1, "Expected Basename."},
1191 {1, 0, "Expected Bias value."},
1192 {1, 0, "Assuming positive bias value."},
1193 {1, 1, "Missing function name."},
1194 {1, 1, "Expected '('."},
1195 {1, 1, "Too much arguments."},
1196 {1, 1, "Expected argument name."},
1197 {1, 1, "Expected ')'."},
1198 {1, 1, "Expected register name."},
1199 {1, 1, "A7 not allowed as argument register."},
1200 {1, 1, "Register used twice."},
1201 {1, 0, "Number of arguments != number of registers."},
1202 {1, 0, "Assuming bias of 30."},
1203 {1, 1, "Extra characters."},
1204 {0, 0, "Missing Basename in FD file."},
1205 {0, 0, "Failed to write destination file."},
1206 {1, 1, "Expected ','."},
1207 {0, 1, "Data different to previous given."},
1208 {1, 0, "Unknown type of argument %ld."},
1209 {0, 0, "Unknown problem: program error or corrupt input data."},
1210 {1, 0, "Missing ##end."},
1211 {1, 0, "Prototype for function \"%s\" not found."},
1212 {0, 0, "No prototypes file (CLIB parameter) was specified."},
1213 {1, 1, "Unknown directive '%s' found."},
1214 {1, 0, "Usage of both A4 and A5 is not supported."},
1215 {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
1216 {0, 0, "Missing Basename in FD file and FD filename."},
1217 {1, 0, "A6 not allowed as argument register."},
1218 {1, 0, "Empty or partial file deleted."},
1219 {1, 1, "Floating point arguments not allowed."},
1220 {0, 0, "Wrong definition in external type definition file."},
1221 {1, 0, "Cannot determine if FPU argument is double or single."},
1222 {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
1223 {0, 0, "Could not open file \"%s\"."},
1224 {1, 0, "A5 cannot be used as argument register."},
1225 {1, 0, "Format supports no PPC functions."},
1226 {1, 0, "Unknown ABI '%s' found."},
1227 {0, 0, "SORTED cannot be used with that type."},
1228 {1, 0, "Position of function %s not supported with that type."},
1229 {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
1230 {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
1231 {1, 0, "Missing the types definition file. Using internal defaults."},
1232 {1, 0, "Format supports no M68k functions."},
1233 {1, 0, "Unknown type of return value."},
1234 {1, 0, "With SFD as input CLIB file is ignored."},
1235 {1, 0, "Expected $Id: in ID string."},
1236 {1, 0, "Expected $ at end of ID string."},
1237 {1, 0, "Missing ==end."},
1238 {1, 1, "Expected positive decimal number."},
1239 {1, 0, "ID string declared twice."},
1240 {1, 1, "Library type of commandline overwrites file settings."},
1241 {1, 1, "Basename of commandline overwrites file settings."},
1242 {1, 0, "Library type declared twice."},
1243 {1, 1, "Expected library type definition."},
1244 {1, 1, "SORTED cannot be used with SFD and FD output."},
1245 {1, 0, "Function expected before ##shadow."},
1246 {1, 1, "There is already a varargs function, handling as alias."},
1247 {1, 0, "Varargs function cannot have different arguments."},
1248 {1, 0, "Unexpected end of file."},
1249 {1, 0, "Commands varargs and alias cannot be at file start."},
1250 {1, 0, "Only %d alias names supported."},
1251 {1, 1, "Expected struct keyword in library type."},
1252 {1, 0, "Expected '*' at end of library type definition."},
1253 {1, 1, "Name of argument %d conflicts with keyword '%s'."},
1254 {1, 1, "Name of argument %d conflicts with argument %d."},
1255 {1, 0, "SFD files cannot consist only of varargs functions."},
1256 {1, 1, "Library name of commandline overwrites file settings."},
1257 {1, 0, "Library name declared twice."},
1258 {1, 1, "Expected library name definition."},
1259 {1, 0, "Neither prefix nor subprefix specified."},
1260 {1, 0, "Format supports single function pointer only (void * used)."},
1261 {1, 0, "No swap register left for %s."},
1262 {1, 0, "SFD files should always start with ==id directive."},
1263 {1, 0, "Illegal character detected."},
1264 {1, 0, "Unknown type of argument %ld (%s) handled as int."},
1265 {1, 0, "Unknown type of return value (%s) handled as int."},
1266 {1, 0, "Illegal internal value."},
1267 {1, 0, "Format supports no MorphOS (base,sysv) functions."},
1268 {1, 0, "Format supports no alias names."},
1269 {1, 0, "Format cannot support function %s."},
1275 static uint8 InternalTypes
[] = {
1276 "IX:struct InputXpression\n"
1278 "Class:struct IClass\n"
1279 "BootBlock:struct bootblock\n"
1280 "ValidIDstruct:struct ValidIDstruct\n"
1281 "DisplayInfoHandle:void *\n"
1282 "RESOURCEFILE:void *\n"
1283 "RESOURCEID:unsigned long\n"
1285 "GLbitfield:unsigned long\n"
1286 "GLbyte:signed char\n"
1289 "GLsizei:unsigned long\n"
1290 "GLubyte:unsigned char\n"
1291 "GLushort:unsigned short\n"
1292 "GLuint:unsigned long\n"
1297 "GLboolean:enum ?\n"
1299 "GLlookAt:struct GLlookAt\n"
1300 "GLproject:struct GLproject\n"
1301 "GLunProject:struct GLunProject\n"
1302 "GLfrustum:struct GLfrustum\n"
1303 "GLortho:struct GLortho\n"
1304 "GLbitmap:struct GLbitmap\n"
1305 "GLUquadricObj:struct GLUquadricObj\n"
1306 "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
1307 "GLUnurbsObj:struct GLUnurbsObj\n"
1308 "GLvisual:struct gl_visual\n"
1309 "GLframebuffer:struct gl_frame_buffer\n"
1310 "GLcontext:struct gl_context\n"
1311 "GLContext:struct !\n"
1312 "HGIDA_Stack:unsigned long *\n"
1313 "HGIDA_BoundedStack:unsigned long *\n"
1314 "HGIDA_Queue:unsigned long *\n"
1315 "HGIDA_BoundedQueue:unsigned long *\n"
1316 "HGIDA_List:unsigned long *\n"
1317 "HGIDA_ListItem:unsigned long *\n"
1318 "HGIDA_Error:enum ?\n"
1319 "HGIDA_Direction:enum ?\n"
1322 "mode_t:unsigned short\n"
1323 "pid_t:struct Task *\n"
1324 "fd_set:struct fd_set\n"
1325 "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 "
1326 "unsigned long, register __a1 const unsigned char *, register __a2 struct "
1327 "CSource *, register __a3 struct CSource *)\n"
1328 "pcap_t:struct pcap\n"
1329 "pcap_dumper_t:struct pcap_dumper\n"
1330 "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const "
1331 "unsigned char *)\n"
1332 "u_char:unsigned char\n"
1333 "bpf_u_int32:unsigned long\n"
1336 "MPEGA_STREAM:struct MPEGA_STREAM\n"
1337 "MPEGA_CTRL:struct MPEGA_CTRL\n"
1338 "W3D_Context:struct W3DContext\n"
1339 "W3D_Driver:struct W3DDriver\n"
1340 "W3D_Texture:struct W3DTexture\n"
1341 "W3D_Scissor:struct W3DScissor\n"
1342 "W3D_Line:struct W3D_Line\n"
1343 "W3D_Point:struct W3D_Point\n"
1344 "W3D_Triangle:struct W3D_Triangle\n"
1345 "W3D_Triangles:struct W3D_Triangles\n"
1347 "W3D_Bitmap:struct W3D_Bitmap\n"
1348 "W3D_Fog:struct W3D_Fog\n"
1350 "W3D_Double:double\n"
1351 "W3D_TriangleV:struct W3D_TriangleV\n"
1352 "W3D_TrianglesV:struct W3D_TriangleV\n"
1353 "W3D_ScreenMode:struct W3D_Screenmode\n"
1354 "W3D_Color:struct W3D_Color\n"
1355 "W3D_Lines:struct W3D_Lines\n"
1357 "DITHERINFO:void *\n"
1361 "size_t:unsigned int\n"
1363 "uint8:unsigned char\n"
1364 "uint16:unsigned short\n"
1365 "uint32:unsigned long\n"
1370 "PtrBigNum:struct BigNum *\n"
1371 "BF_KEY:struct bf_key_st\n"
1372 "BF_LONG:unsigned long\n"
1373 "CAST_KEY:struct cast_key_st\n"
1374 "CAST_LONG:unsigned long\n"
1375 "DES_LONG:unsigned long\n"
1376 "des_key_schedule:struct des_ks_struct\n"
1377 "const_des_cblock:unsigned char [8]\n"
1378 "des_cblock:unsigned char [8]\n"
1379 "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
1380 "MD2_CTX:struct MD2state_st\n"
1381 "MD5_CTX:struct MD5state_st\n"
1382 "MDC2_CTX:struct mdc2_ctx_st\n"
1383 "RC2_KEY:struct rc2_key_st\n"
1384 "RC4_KEY:struct rc4_key_st\n"
1385 "RC5_32_KEY:struct rc5_key_st\n"
1386 "RIPEMD160_CTX:struct RIPEMD160state_st\n"
1387 "SHA_CTX:struct SHAstate_st\n"
1388 "ASN1_CTX:struct asn1_ctx_st\n"
1389 "ASN1_OBJECT:struct asn1_object_st\n"
1390 "ASN1_STRING:struct asn1_string_st\n"
1391 "ASN1_TYPE:struct asn1_type_st\n"
1392 "ASN1_METHOD:struct asn1_method_st\n"
1393 "ASN1_HEADER:struct asn1_header_st\n"
1394 "ASN1_INTEGER:struct asn1_string_st\n"
1395 "ASN1_ENUMERATED:struct asn1_string_st\n"
1396 "ASN1_BIT_STRING:struct asn1_string_st\n"
1397 "ASN1_OCTET_STRING:struct asn1_string_st\n"
1398 "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
1399 "ASN1_T61STRING:struct asn1_string_st\n"
1400 "ASN1_IA5STRING:struct asn1_string_st\n"
1401 "ASN1_UTCTIME:struct asn1_string_st\n"
1402 "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
1403 "ASN1_TIME:struct asn1_string_st\n"
1404 "ASN1_GENERALSTRING:struct asn1_string_st\n"
1405 "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
1406 "ASN1_BMPSTRING:struct asn1_string_st\n"
1407 "ASN1_VISIBLESTRING:struct asn1_string_st\n"
1408 "ASN1_UTF8STRING:struct asn1_string_st\n"
1409 "BIO:struct bio_st\n"
1410 "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
1411 "BIO_METHOD:struct bio_method_st\n"
1412 "BIGNUM:struct bignum_st\n"
1413 "BN_CTX:struct bignum_ctx\n"
1414 "BN_ULONG:unsigned long\n"
1415 "BN_MONT_CTX:struct bn_mont_ctx_st\n"
1416 "BN_BLINDING:struct bn_blinding_st\n"
1417 "BN_RECP_CTX:struct bn_recp_ctx_st\n"
1418 "BUF_MEM:struct buf_mem_st\n"
1419 "COMP_METHOD:struct comp_method_st\n"
1420 "COMP_CTX:struct comp_ctx_st\n"
1421 "CONF_VALUE:struct !\n"
1422 "LHASH_NODE:struct lhash_node_st\n"
1423 "LHASH:struct lhash_st\n"
1424 "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
1425 "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
1427 "DSA:struct dsa_st\n"
1428 "DSA_SIG:struct DSA_SIG_st\n"
1429 "ERR_STATE:struct err_state_st\n"
1430 "ERR_STRING_DATA:struct ERR_string_data_st\n"
1431 "EVP_PKEY:struct evp_pkey_st\n"
1432 "EVP_MD:struct env_md_st\n"
1433 "EVP_MD_CTX:struct env_md_ctx_st\n"
1434 "EVP_CIPHER:struct evp_cipher_st\n"
1435 "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
1436 "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
1437 "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
1438 "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char "
1439 "*pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st "
1440 "*cipher, struct env_md_st *md, int en_de)\n"
1441 "HMAC_CTX:struct hmac_ctx_st\n"
1442 "OBJ_NAME:struct obj_name_st\n"
1443 "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
1444 "PEM_USER:struct pem_recip_st\n"
1445 "PEM_CTX:struct pem_ctx_st\n"
1446 "PKCS12_MAC_DATA:struct !\n"
1448 "PKCS12_SAFEBAG:struct !\n"
1449 "PKCS12_BAGS:struct pkcs12_bag_st\n"
1450 "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
1451 "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
1452 "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
1453 "PKCS7_SIGNED:struct pkcs7_signed_st\n"
1454 "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
1455 "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
1456 "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
1457 "PKCS7_DIGEST:struct pkcs7_digest_st\n"
1458 "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
1459 "PKCS7:struct pkcs7_st\n"
1460 "RAND_METHOD:struct rand_meth_st\n"
1461 "RSA:struct rsa_st\n"
1462 "RSA_METHOD:struct rsa_meth_st\n"
1463 "TXT_DB:struct txt_db_st\n"
1464 "X509_OBJECTS:struct X509_objects_st\n"
1465 "X509_ALGOR:struct X509_algor_st\n"
1466 "X509_VAL:struct X509_val_st\n"
1467 "X509_PUBKEY:struct X509_pubkey_st\n"
1468 "X509_SIG:struct X509_sig_st\n"
1469 "X509_NAME_ENTRY:struct X509_name_entry_st\n"
1470 "X509_NAME:struct X509_name_st\n"
1471 "X509_EXTENSION:struct X509_extension_st\n"
1472 "X509_ATTRIBUTE:struct x509_attributes_st\n"
1473 "X509_REQ_INFO:struct X509_req_info_st\n"
1474 "X509_REQ:struct X509_req_st\n"
1475 "X509_CINF:struct x509_cinf_st\n"
1476 "X509:struct x509_st\n"
1477 "X509_REVOKED:struct X509_revoked_st\n"
1478 "X509_CRL_INFO:struct X509_crl_info_st\n"
1479 "X509_CRL:struct X509_crl_st\n"
1480 "X509_PKEY:struct private_key_st\n"
1481 "X509_INFO:struct X509_info_st\n"
1482 "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
1483 "NETSCAPE_SPKI:struct Netscape_spki_st\n"
1484 "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
1485 "CBC_PARAM:struct CBCParameter_st\n"
1486 "PBEPARAM:struct PBEPARAM_st\n"
1487 "PBE2PARAM:struct PBE2PARAM_st\n"
1488 "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
1489 "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
1490 "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
1491 "X509V3_EXT_METHOD:struct v3_ext_method\n"
1492 "X509V3_CTX:struct v3_ext_ctx\n"
1493 "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
1494 "X509_CERT_FILE_CTX:struct x509_file_st\n"
1495 "X509_OBJECT:struct X509_objects_st\n"
1496 "X509_LOOKUP:struct x509_lookup_st\n"
1497 "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
1498 "X509_STORE_CTX:struct x509_store_state_st\n"
1499 "X509_STORE:struct x509_store_st\n"
1500 "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
1501 "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
1502 "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
1503 "GENERAL_NAME:struct GENERAL_NAME_st\n"
1504 "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
1505 "DIST_POINT:struct DIST_POINT_st\n"
1506 "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
1507 "SXNETID:struct SXNET_ID_st\n"
1508 "SXNET:struct SXNET_st\n"
1509 "NOTICEREF:struct NOTICEREF_st\n"
1510 "USERNOTICE:struct USERNOTICE_st\n"
1511 "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
1512 "POLICYINFO:struct POLICYINFO_st\n"
1513 "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
1514 "SSL_CIPHER:struct ssl_cipher_st\n"
1515 "SSL:struct ssl_st\n"
1516 "SSL_CTX:struct ssl_ctx_st\n"
1517 "SSL_METHOD:struct ssl_method_st\n"
1518 "SSL_SESSION:struct ssl_session_st\n"
1519 "SSL_COMP:struct ssl_comp_st\n"
1520 "SSL2_CTX:struct ssl2_ctx_st\n"
1521 "SSL3_RECORD:struct ssl3_record_st\n"
1522 "SSL3_BUFFER:struct ssl3_buffer_st\n"
1523 "SSL3_CTX:struct ssl3_ctx_st\n"
1524 "CERT_PKEY:struct cert_pkey_st\n"
1525 "CERT:struct cert_st\n"
1526 "SESS_CERT:struct sess_cert_st\n"
1527 "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
1528 "SSL3_COMP:struct ssl3_comp_st\n"
1529 "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
1530 "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
1531 "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
1532 "STACK_OF(X509):struct stack_st_X509\n"
1533 "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
1534 "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
1535 "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
1536 "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
1537 "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
1538 "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
1539 "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
1540 "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
1541 "STACK:struct stack_st\n"
1543 "Uint8:unsigned char\n"
1544 "Sint8:signed char\n"
1545 "Uint16:unsigned short\n"
1546 "Sint16:signed short\n"
1547 "Uint32:unsigned long\n"
1548 "Sint32:signed long\n"
1549 "Uint64:unsigned long long\n"
1550 "Sint64:signed long long\n"
1551 "SDL_version:struct !\n"
1552 "SDL_RWops:struct SDL_RWops\n"
1553 "SDL_Rect:struct !\n"
1554 "SDL_Color:struct !\n"
1555 "SDL_Palette:struct !\n"
1556 "SDL_PixelFormat:struct SDL_PixelFormat\n"
1557 "SDL_blit:int (*)(struct SDL_Surface *src,void *srcrect,"
1558 "struct SDL_Surface *dst,void *dstrect)\n"
1559 "SDL_Surface:struct SDL_Surface\n"
1560 "SDL_VideoInfo:struct !\n"
1561 "SDL_Overlay:struct SDL_Overlay\n"
1562 "SDL_GLattr:enum ?\n"
1563 "SDL_GrabMode:enum ?\n"
1564 "SDL_audiostatus:enum ?\n"
1565 "SDL_AudioSpec:struct !\n"
1566 "SDL_AudioCVT:struct SDL_AudioCVT\n"
1568 "SDL_CDtrack:struct !\n"
1569 "SDL_CD:struct SDL_CD\n"
1570 "SDL_Joystick:struct _SDL_Joystick\n"
1573 "SDL_keysym:struct !\n"
1574 "SDL_ActiveEvent:struct !\n"
1575 "SDL_KeyboardEvent:struct !\n"
1576 "SDL_MouseMotionEvent:struct !\n"
1577 "SDL_MouseButtonEvent:struct !\n"
1578 "SDL_JoyAxisEvent:struct !\n"
1579 "SDL_JoyBallEvent:struct !\n"
1580 "SDL_JoyHatEvent:struct !\n"
1581 "SDL_JoyButtonEvent:struct !\n"
1582 "SDL_ResizeEvent:struct !\n"
1583 "SDL_ExposeEvent:struct !\n"
1584 "SDL_QuitEvent:struct !\n"
1585 "SDL_UserEvent:struct !\n"
1586 "SDL_SysWMmsg:struct SDL_SysWMmsg\n"
1587 "SDL_SysWMEvent:struct !\n"
1588 "SDL_Event:union ?\n"
1589 "SDL_eventaction:enum ?\n"
1590 "SDL_EventFilter:void *\n"
1591 "WMcursor:struct WMcursor\n"
1592 "SDL_Cursor:struct !\n"
1593 "SDL_mutex:struct SDL_mutex\n"
1594 "SDL_sem:struct SDL_semaphore\n"
1595 "SDL_cond:struct SDL_cond\n"
1596 "SDL_Thread:struct SDL_Thread\n"
1597 "SDL_TimerCallback:unsigned long (*)(unsigned long)\n"
1598 "SDL_NewTimerCallback:unsigned long (*)(unsigned long,void *)\n"
1599 "SDL_TimerID:struct _SDL_TimerID\n"
1600 "SDL_errorcode:enum ?\n"
1601 "FPSmanager:struct !\n"
1602 "Mix_Chunk:struct !\n"
1603 "Mix_Music:struct !\n"
1604 "Mix_MusicType:enum ?\n"
1605 "Mix_EffectFunc_t:void (*)(int,void *,int,void *)\n"
1606 "Mix_EffectDone_t:void (*)(int,void *)\n"
1607 "Mix_Fading:enum ?\n"
1608 "IPaddress:struct !\n"
1609 "TCPsocket:void *\n"
1610 "UDPpacket:struct !\n"
1611 "UDPsocket:void *\n"
1612 "SDLNet_SocketSet:void *\n"
1613 "SDLNet_GenericSocket:void *\n"
1614 "TTF_Font:struct !\n"
1617 static const struct CPP_TypeField CPP_Field
[] = {
1618 {"int", 3, 0, CPP_TYPE_INT
},
1619 /* long needs special handling due to the fact it is a modifier and a type */
1620 /*{"long", 4, 0, CPP_TYPE_LONG}, */
1621 {"LONG", 4, 0, CPP_TYPE_LONG
},
1622 {"BPTR", 4, 0, CPP_TYPE_LONG
},
1623 {"BSTR", 4, 0, CPP_TYPE_LONG
},
1624 {"CxObj", 5, 0, CPP_TYPE_LONG
},
1625 {"CxMsg", 5, 0, CPP_TYPE_LONG
},
1626 {"ULONG", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1627 {"LONGBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1628 {"CPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1629 {"Tag", 3, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1630 {"Object", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1631 {"short", 5, 0, CPP_TYPE_WORD
},
1632 {"SHORT", 5, 0, CPP_TYPE_WORD
},
1633 {"COUNT", 5, 0, CPP_TYPE_WORD
},
1634 {"WORD", 4, 0, CPP_TYPE_WORD
},
1635 {"USHORT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1636 {"UWORD", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1637 {"UCOUNT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1638 {"WORDBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1639 {"RPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1640 {"BOOL", 4, CPP_FLAG_BOOLEAN
, CPP_TYPE_WORD
},
1641 {"char", 4, 0, CPP_TYPE_BYTE
},
1642 {"BYTE", 4, 0, CPP_TYPE_BYTE
},
1643 {"UBYTE", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1644 {"TEXT", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1645 {"BYTEBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1646 {"float", 5, 0, CPP_TYPE_FLOAT
},
1647 {"FLOAT", 5, 0, CPP_TYPE_FLOAT
},
1648 {"double", 6, 0, CPP_TYPE_DOUBLE
},
1649 {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE
},
1650 {"void", 4, 0, CPP_TYPE_VOID
},
1651 {"VOID", 4, 0, CPP_TYPE_VOID
},
1652 {"APTR", 4, CPP_FLAG_POINTER
, CPP_TYPE_VOID
},
1653 {"STRPTR", 6, CPP_FLAG_POINTER
|CPP_FLAG_STRPTR
, CPP_TYPE_BYTE
},
1654 {"CONST_STRPTR",12,CPP_FLAG_POINTER
|CPP_FLAG_CONST
, CPP_TYPE_BYTE
},
1655 {"ClassID", 7, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1656 {"PLANEPTR", 8, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1660 /* defaults: "Library" shortbname+".library" basename-last 4 chars */
1661 static const struct Proto_LibType Proto_LibTypes
[] = {
1662 {"DOSBase", "DosLibrary", 0, 0},
1663 {"SysBase", "ExecBase", 0, 0},
1664 {"ExpansionBase", "ExpansionBase", 0, 0},
1665 {"GfxBase", "GfxBase", "graphics.library", "graphics"},
1666 {"IntuitionBase", "IntuitionBase", 0, 0},
1667 {"LocaleBase", "LocaleBase", 0, 0},
1668 {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
1669 {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
1670 {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
1671 {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
1672 {"RealTimeBase", "RealTimeBase", 0, 0},
1673 {"RexxSysBase", "RxsLib", 0, 0},
1674 {"UtilityBase", "UtilityBase", 0, 0},
1675 {"WorkbenchBase", 0, "workbench.library", "wb"},
1676 /* resources - The Node entries may be correct, but I don't know it. */
1677 {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
1678 {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
1679 {"CardResource", 0/*"Node"*/, "card.resource", "cardres"},
1680 {"DiskBase", "DiskResource", "disk.resource", 0},
1681 {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
1682 {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
1684 {"ConsoleDevice", 0/*"Device"*/, "console.device", "console"},
1685 {"InputBase", 0/*"Device"*/, "input.device", 0},
1686 {"RamdriveDevice", 0/*"Device"*/, "ramdrive.device", "ramdrive"},
1687 {"TimerBase", 0/*"Device"*/, "timer.device", 0},
1688 /* non default Basenames */
1689 {"DatamasterBase", "DatamasterBase", 0, 0},
1690 {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
1691 {"ReqToolsBase", "ReqToolsBase", 0, 0},
1692 {"UnpackBase", "UnpackLibrary", 0, 0},
1693 {"xfdMasterBase", "xfdMasterBase", 0, 0},
1694 {"xadMasterBase", "xadMasterBase", 0, 0},
1695 /*{"xvsBase", "xvsBase", 0, 0}, now completely private */
1696 {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
1697 {"ArpBase", "ArpBase", 0, 0},
1698 {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
1699 {"PowerPCBase", "PPCBase", 0, 0},
1700 {"MC68060Base", 0, "68060.library", "mc68060"},
1701 {"MC68040Base", 0, "68040.library", "mc68040"},
1702 {"MC680x0Base", 0, "680x0.library", "mc680x0"},
1703 {"P96Base", 0, "Picasso96API.library","Picasso96"},
1704 {"Warp3DPPCBase", 0, "Warp3DPPC.library" ,"Warp3D"},
1705 {"CyberGfxBase", 0, "cybergraphics.library", "cybergraphics"},
1709 /* CachePostDMA, CachePreDMA are done by #?DMA check */
1710 static const struct Pragma_ExecpName Pragma_ExecpNames
[] = {
1711 {"VFWritef", "FWritef"},
1712 {"VFPrintf", "FPrintf"},
1713 {"VPrintf", "Printf"},
1716 {"CloneTagItems", 0},
1718 {"FreeTagItems", 0},
1720 {"PackBoolTags", 0},
1721 {"PackStructureTags", 0},
1722 {"UnpackStructureTags", 0},
1723 {"BGUI_PackStructureTags", 0},
1724 {"BGUI_UnpackStructureTags", 0},
1725 {"Inet_NtoA", 0}, /* socket.library */
1726 {"vsyslog", "syslog"},
1727 {"NewPPCStackSwap", 0},
1728 {"FindTagItemPPC", 0},
1729 {"GetTagDataPPC", 0},
1732 {"SetScheduling", 0},
1733 {"W3D_CreateContext", "W3D_CreateContextTags"},
1734 {"W3D_RequestMode", "W3D_RequestModeTags"},
1735 {"W3D_AllocTexObj", "W3D_AllocTexObjTags"},
1736 {"W3D_BestModeID", "W3D_BestModeIDTags"},
1740 /* This field contains functions, which should not be created as inlines with
1741 some targets. At the moment these are varargs functions, which are used in
1742 the MUI style using complicated defines. Theses functions are disabled in
1743 certain GCC and VBCC environments. */
1744 static const strptr NoCreateInlineFuncs
[] = {
1751 /* For double tagcall names (currently only necessary for dos.library and
1752 datatypes.library). Only one alias supported for a function! */
1753 static const struct Pragma_AliasName Pragma_AliasNames
[] = {
1754 {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL
},
1755 {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL
},
1756 {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL
},
1757 {"SystemTagList", "System", FUNCFLAG_NORMAL
},
1758 {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG
},
1762 /* special names, which get an x before name in BMAP files */
1763 static const strptr BMAPSpecial
[] =
1764 {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
1765 "Translate", "Wait", "Write", 0};
1767 #define FIRST_KNOWN_RELEASE 30
1768 #define LAST_KNOWN_RELEASE 45
1769 static const strptr Release
[] =
1771 "Release 1.0", /* V30 */
1772 "Release 1.1", /* V31 */
1773 "Preliminary Release 1.2", /* V32 */
1774 "Release 1.2", /* V33 */
1775 "Release 1.3", /* V34 */
1776 "Release 1.3 A2024", /* V35 */
1777 "Release 2.0", /* V36 */
1778 "Release 2.04", /* V37 */
1779 "Release 2.1", /* V38 */
1780 "Release 3.0", /* V39 */
1781 "Release 3.1", /* V40 */
1782 "Transitional Release 3.2", /* V41 */
1783 "Transitional Release 3.3", /* V42 */
1784 "Transitional Release 3.4", /* V43 */
1785 "Release 3.5", /* V44 */
1786 "Release 3.9", /* V45 */
1789 /* Keywords, which cannot be argument names. They are used case_insensitive to
1790 be sure they make no conflicts in non-C-languages as well.
1791 Currently these are mostly C keywords.
1793 static const strptr Keywords
[] =
1795 "and", "and_eq", "asm", "auto", "bitand",
1796 "bitor", "break", "case", "catch", "char",
1797 "class", "compl", "const", "continue", "default",
1798 "delete", "do", "double", "else", "enum",
1799 "extern", "false", "float", "for", "friend",
1800 "goto", "if", "inline", "int", "long",
1801 "new", "not", "not_eq", "operator", "or",
1802 "or_eq", "private", "protected", "public", "register",
1803 "return", "short", "signed", "sizeof", "static",
1804 "struct", "switch", "template", "this", "throw",
1805 "true", "try", "typedef", "union", "unsigned",
1806 "virtual", "void", "volatile", "wchar_t", "while",
1807 "xor", "xor_eq", "RastPort", "Tag",
1811 #if !defined __SASC && !defined __AROS__ && !defined _WIN32 && !defined __CYGWIN__
1812 static int stricmp(const char *a
, const char *b
)
1814 while(*a
&& tolower(*a
) == tolower(*b
))
1818 return (tolower(*a
) - tolower(*b
));
1821 static int strnicmp(const char *a
, const char *b
, size_t num
)
1823 while(num
&& *a
&& tolower(*a
) == tolower(*b
))
1827 return num
? (tolower(*a
) - tolower(*b
)) : 0;
1831 static strptr
DupString(strptr Str
, size_t Len
)
1834 if((res
= r
= AllocListMem(Len
+1)))
1836 while(Len
-- && *Str
)
1841 printf("DupString %s.\n", res
);
1846 static strptr
AllocListMem(size_t size
)
1850 printf("AllocListMem Size %d.\n", size
);
1852 if((a
= (strptr
) malloc(size
)))
1857 static strptr
SkipBlanks(strptr OldPtr
)
1859 while(*OldPtr
== ' ' || *OldPtr
== '\t')
1864 static strptr
SkipBlanksRet(strptr OldPtr
)
1866 while(*OldPtr
== ' ' || *OldPtr
== '\t' || *OldPtr
== '\n')
1872 This function is used to skip over variable names.
1874 Inputs: OldPtr - pointer to the beginning of a string.
1876 Result: Pointer to the first character of the string, that is not one
1877 of a-z, A-Z, 0-9 or the underscore.
1880 static strptr
SkipName(strptr OldPtr
)
1882 while(isalnum(*OldPtr
) || *OldPtr
== '_')
1887 static int IsNoCreateInlineFunc(const strptr name
)
1890 for(a
= NoCreateInlineFuncs
; *a
; ++a
)
1892 if(!strcmp(name
, *a
))
1898 static uint32
GetTypes(void)
1904 if(!(ptr
= mygetfile(EXTTYPESFILE
, &len
)))
1906 #ifdef EXTTYPESFILEHIDDEN
1907 if((ptr
= getenv("HOME")))
1909 strptr ptrh
= EXTTYPESFILEHIDDEN
;
1912 ptr
= DupString(ptr
, i
+ sizeof(EXTTYPESFILEHIDDEN
) + 1);
1913 if(i
&& ptr
[i
-1] != '/')
1916 ptr
[i
++] = *(ptrh
++);
1918 ptr
= mygetfile(ptr
, &len
);
1920 if(!ptr
) /* disabled following if ptr != 0 */
1922 if(!(ptr
= mygetfile(EXTTYPESFILE2
, &len
)))
1924 DoError(ERR_NOFD2PRAGMATYPES
, 0);
1925 ptr
= (strptr
) InternalTypes
;
1926 len
= sizeof(InternalTypes
)-1;
1929 if((i
= ScanTypes(ptr
, len
)) > 0)
1931 DoError(ERR_WRONG_TYPES_LINE
, i
);
1937 static strptr
GetBaseType(void)
1939 static strptr basetype
= 0;
1942 if(Flags2
& FLAG2_VOIDBASE
)
1943 basetype
= "void *";
1946 for(i
= 0; !libtype
&& BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1948 if(!(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1950 libtype
= Proto_LibTypes
[i
].StructureName
;
1954 if(libtype
&& (basetype
= malloc(strlen(libtype
) + 9+1)))
1956 sprintf(basetype
, "struct %s *", libtype
);
1959 basetype
= "struct Library *";
1965 static strptr
GetBaseTypeLib(void)
1972 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1974 if(Proto_LibTypes
[i
].StructureName
&&
1975 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1977 return Proto_LibTypes
[i
].StructureName
;
1983 static strptr
GetLibraryName(void)
1990 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1992 if(Proto_LibTypes
[i
].LibraryName
&&
1993 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1995 return (libname
= Proto_LibTypes
[i
].LibraryName
);
1998 if(!(libname
= malloc(strlen(ShortBaseName
)+9)))
2001 /* auto create name */
2002 for(i
= 0; ShortBaseName
[i
]; ++i
)
2003 libname
[i
] = ShortBaseName
[i
];
2004 strcpy(libname
+i
,".library");
2008 static strptr
GetIFXName(void)
2010 static char IFXName
[256];
2011 sprintf(IFXName
, "%c%s", toupper(ShortBaseName
[0]), ShortBaseName
+1);
2015 static int32
MakeShortBaseName(void)
2020 ptr
= p2
= args
.infile
;
2023 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
2028 /* first get name from file */
2030 p2
-= (sizeof(SFDFILEEXTENSION
)-1);
2031 if(p2
> ptr
&& !stricmp(p2
, SFDFILEEXTENSION
))
2032 ShortBaseName
= DupString(ptr
, p2
-ptr
);
2033 p2
+= sizeof(SFDFILEEXTENSION
)-sizeof(FDFILEEXTENSION
);
2034 if(p2
> ptr
&& !stricmp(p2
, FDFILEEXTENSION
))
2035 ShortBaseName
= DupString(ptr
, p2
-ptr
);
2037 /* then try exceptions (overriding filename) */
2040 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
2042 if(Proto_LibTypes
[i
].ShortBaseName
&&
2043 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
2045 if(!(ShortBaseName
= DupString(Proto_LibTypes
[i
].ShortBaseName
,
2046 strlen(Proto_LibTypes
[i
].ShortBaseName
))))
2051 /* and last use default method */
2053 ShortBaseName
= DupString(BaseName
, strlen(BaseName
)-4);
2059 ptr
= ShortBaseName
;
2060 while((*ptr
= tolower(*ptr
))) /* Convert to lowercase */
2063 if((ShortBaseNameUpper
= DupString(ShortBaseName
, strlen(ShortBaseName
))))
2065 ptr
= ShortBaseNameUpper
;
2066 while((*ptr
= toupper(*ptr
))) /* Convert to uppercase */
2075 static uint32
OpenDest(strptr name
)
2077 static uint8 printedname
= 0;
2080 t
= (strptr
) tempbuf
;
2081 if((b
= args
.to
) && *b
)
2085 if(*(t
-1) != ':' && *(t
-1) != '/')
2090 if(!(Flags
& FLAG_SINGLEFILE
))
2091 printf("ResultFile: %s%s\n", tempbuf
, name
);
2092 else if(!printedname
++)
2094 printf("ResultType: %s", tempbuf
); printf(filenamefmt
, "*");
2104 HEADER
= mygetfile((strptr
)tempbuf
, &headersize
);
2108 if((outfile
= fopen((strptr
)tempbuf
, "wb")))
2110 DoError(ERR_OPEN_FILE
, 0, tempbuf
);
2114 static uint32
CloseDest(strptr name
)
2121 if(!(Flags
& FLAG_DONE
) || !Output_Error
)
2124 if(!Output_Error
|| !(Flags
& FLAG_SINGLEFILE
))
2125 DoError(ERR_EMPTY_FILE
, 0);
2127 t
= (strptr
) tempbuf
;
2128 if((b
= args
.to
) && *b
)
2132 if(*(t
-1) != ':' && *(t
-1) != '/')
2139 remove((strptr
)tempbuf
);
2142 Flags
&= ~FLAG_DONE
; /* clear the flag */
2149 static uint32
MakeTagFunction(struct AmiPragma
*ap
)
2151 size_t len
= strlen(ap
->FuncName
);
2155 printf("MakeTagFunction:\n");
2158 if(!ap
->NumArgs
|| ap
->TagName
)
2162 ap
->Flags
|= AMIPRAGFLAG_OWNTAGFUNC
;
2164 while(Pragma_ExecpNames
[i
].FunctionName
&& /* check the exception names */
2165 strcmp(ap
->FuncName
, Pragma_ExecpNames
[i
].FunctionName
))
2168 if(Pragma_ExecpNames
[i
].FunctionName
)
2170 if(!(ap
->TagName
= Pragma_ExecpNames
[i
].TagName
))
2172 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
2176 else if(ap
->FuncName
[len
-1] == 'A')
2178 /* skip names with DMA or MESA at end */
2179 if(!strcmp(ap
->FuncName
+len
-3, "DMA") ||
2180 !strcmp(ap
->FuncName
+len
-4, "MESA") ||
2181 !strcmp(ap
->FuncName
+len
-4, "RGBA") ||
2182 !strcmp(ap
->FuncName
+len
-5, "AMIGA"))
2183 { ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
; --tagfuncs
; return 1;}
2184 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-1)))
2187 else if(!strcmp(ap
->FuncName
+ len
-7, "TagList"))
2189 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-3)))
2191 ap
->TagName
[len
-4] = 's';
2193 else if(!strcmp(ap
->FuncName
+ len
-4, "Args"))
2195 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-4)))
2198 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "tags") ||
2199 !stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "taglist"))
2201 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
2203 memcpy(ap
->TagName
+ len
, "Tags", 5);
2205 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "args"))
2207 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
2209 memcpy(ap
->TagName
+ len
, "Args", 5);
2213 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
2214 --tagfuncs
; /* not a tagfunction, incrementing was false, undo it */
2219 printf("MakeTagFunction: %s / %s (...%s)\n", ap
->TagName
,
2220 ap
->FuncName
, ap
->Args
[ap
->CallArgs
-1].ArgName
);
2226 static void MakeLines(strptr buffer
, uint32 size
)
2230 /* make a real C++ zero string ending line */
2241 /* Do any special functions, which cannot be done with other exception
2242 stuff - currently only dos.library DoPkt function. */
2243 static uint32
SpecialFuncs(void)
2245 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
,
2246 *ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2248 /* first let one more go away, so we can detect if the DoPkt parts are
2249 already inserted in the FD file */
2251 while(ap2
&& (struct AmiPragma
*)(ap2
->List
.Next
) != ap
)
2252 ap2
= (struct AmiPragma
*)(ap2
->List
.Next
);
2254 if(ap2
&& ap2
->Bias
== 0xF0 && ap
->Bias
!= 0xF0 &&
2255 !strcmp("DoPkt", ap2
->FuncName
))
2257 struct AmiPragma
*d
;
2260 RemoveItem(&AmiPragma
, (struct ShortList
*) ap
); /* add in correct order */
2261 for(i
= 0; i
< 5; ++i
)
2263 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
2265 memcpy(d
, ap2
, sizeof(struct AmiPragma
));
2266 d
->FuncName
= DupString(ap2
->FuncName
, 6);
2267 d
->FuncName
[5] = '0'+i
;
2268 d
->NumArgs
= d
->CallArgs
= i
+ 2;
2269 AddItem(&AmiPragma
, (struct ShortList
*) d
);
2271 AddItem(&AmiPragma
, (struct ShortList
*) ap
);
2276 static void SortFDList(void)
2278 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.First
, *ap2
, *ap3
;
2279 AmiPragma
.First
= AmiPragma
.Last
= 0;
2284 ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2286 /* for FD2Inline style we need to use strcmp instead of stricmp here */
2287 while(ap2
&& stricmp(ap2
->FuncName
, ap
->FuncName
) < 0)
2290 ap2
= (struct AmiPragma
*) ap2
->List
.Next
;
2294 ap
= (struct AmiPragma
*) ap
->List
.Next
;
2298 ap2
->List
.Next
= (struct ShortList
*) ap3
->List
.Next
;
2299 ap3
->List
.Next
= (struct ShortList
*) ap2
;
2303 ap2
->List
.Next
= AmiPragma
.First
;
2304 AmiPragma
.First
= (struct ShortList
*) ap2
;
2306 if(ap
&& !ap
->List
.Next
)
2307 AmiPragma
.Last
= (struct ShortList
*) ap2
;
2311 static void AddAliasName(struct AmiPragma
*ap
, struct Pragma_AliasName
*alias
,
2316 if(ap
->NumAlias
> NUMALIASNAMES
)
2317 DoError(ERR_ALIASNAMES
, linenum
, NUMALIASNAMES
);
2320 /* prevent double names */
2321 for(i
= 0; i
< ap
->NumAlias
; ++i
)
2323 if(!strcmp(ap
->AliasName
[i
]->AliasName
, alias
->AliasName
))
2326 ap
->AliasName
[ap
->NumAlias
++] = alias
;
2330 static uint32
CheckNames(struct AmiPragma
*ap
)
2336 printf("CheckNames\n");
2338 for(i
= 0; i
< ap
->CallArgs
; ++i
)
2340 if(!ap
->Args
[i
].ArgName
)
2342 if(!(ap
->Args
[i
].ArgName
= (strptr
)
2343 AllocListMem(4+strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2345 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2349 for(k
= Keywords
; *k
; ++k
)
2351 if(!stricmp(ap
->Args
[i
].ArgName
, *k
))
2353 DoError(ERR_ARGNAME_KEYWORD_CONFLICT
, ap
->Line
, i
, *k
);
2354 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4
2355 +strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2357 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2360 for(j
= 0; j
< i
; ++j
)
2362 if(!stricmp(ap
->Args
[i
].ArgName
, ap
->Args
[j
].ArgName
))
2364 DoError(ERR_ARGNAME_ARGNAME_CONFLICT
, ap
->Line
, i
+1, j
+1);
2365 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4
2366 +strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2368 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2373 /* NOTE: the replaced argument names aren't checked for conflicts */
2374 /* replaced names are of style a0arg */
2378 static uint32
ScanSFDFile(enum ABI abi
)
2384 uint32 functype
= 0;
2386 Flags2
|= FLAG2_SFDMODE
;
2388 if(strncmp("==id", in
.pos
, 4))
2389 DoError(ERR_SFD_START
, 1);
2391 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
2395 if(linenum
< 5 && in
.pos
[1] == ' ' && in
.pos
[2] == '\"')
2399 for(s
= in
.pos
; *s
&& *s
!= '"'; ++s
)
2401 if(*s
) /* library name */
2404 printf("ScanSFDFile: found library name comment\n");
2409 *(s
++) = 0; /* clear the " */
2411 Flags2
|= FLAG2_LIBNAMECOM
;
2422 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2428 d
->Private
= _public
? 0 : 1;
2429 AddItem(&Comment
, (struct ShortList
*) d
);
2436 else if(*in
.pos
== '=' && in
.pos
[1] == '=')
2439 actcom
= 0; /* no Comment */
2441 if(!strnicmp(in
.pos
, "basetype", 8))
2444 printf("ScanSFDFile: found ==basetype\n");
2446 if(!(Flags2
& FLAG2_LIBTYPE
))
2449 DoError(ERR_LIBTYPE_DECLARED_TWICE
, linenum
);
2451 in
.pos
= SkipBlanks(in
.pos
+8);
2452 if(strncmp(in
.pos
, "struct", 6))
2453 DoError(ERR_EXPECTED_STRUCT
, linenum
);
2456 in
.pos
= SkipBlanks(in
.pos
+6);
2458 DoError(ERR_EXPECTED_LIBTYPE
, linenum
);
2462 in
.pos
= SkipName(libtype
);
2463 if(*SkipBlanks(in
.pos
) != '*')
2464 DoError(ERR_EXPECTED_POINTERSIGN
, linenum
);
2471 DoError(ERR_COMMANDLINE_LIBTYPE
, linenum
);
2475 else if(!strnicmp(in
.pos
, "copyright", 9))
2477 Copyright
= SkipBlanks(in
.pos
+9);
2481 else if(!strnicmp(in
.pos
, "libname", 7))
2484 printf("ScanSFDFile: found ==libname\n");
2486 if(!(Flags2
& FLAG2_LIBNAME
))
2488 if(libname
&& !(Flags2
& FLAG2_LIBNAMECOM
))
2489 DoError(ERR_LIBNAME_DECLARED_TWICE
, linenum
);
2491 in
.pos
= SkipBlanks(in
.pos
+7);
2493 DoError(ERR_EXPECTED_LIBNAME
, linenum
);
2495 in
.pos
= SkipName(libname
= in
.pos
);
2498 DoError(ERR_COMMANDLINE_LIBNAME
, linenum
);
2502 else if(!strnicmp(in
.pos
, "base", 4))
2507 printf("ScanSFDFile: found ==base\n");
2509 if(!(Flags
& FLAG_BASENAME
))
2512 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
2514 in
.pos
= SkipBlanks(in
.pos
+4);
2516 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
2520 BaseName
= oldptr
= in
.pos
;
2521 in
.pos
= SkipName(in
.pos
);
2522 if(!(in
.pos
-oldptr
))
2523 DoError(ERR_EXPECTED_BASENAME
, linenum
);
2527 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
2532 else if(!strnicmp(in
.pos
, "bias", 4))
2538 printf("ScanSFDFile: found ==bias\n");
2541 newbias
= strtol(in
.pos
, &ptr
, 10);
2543 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
2544 else if(newbias
< 0)
2546 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
2551 in
.pos
= SkipName(in
.pos
);
2553 else if(!strnicmp(in
.pos
, "end", 3))
2557 else if(!strnicmp(in
.pos
, "public", 6))
2562 else if(!strnicmp(in
.pos
, "private", 7))
2567 else if(!strnicmp(in
.pos
, "abi", 3))
2570 printf("ScanSFDFile: found ==abi\n");
2572 in
.pos
= SkipBlanks(in
.pos
+3);
2573 if(!strnicmp(in
.pos
, "M68k", 4))
2575 abi
= ABI_M68K
; in
.pos
+= 4;
2577 else if(!strnicmp(in
.pos
, "PPC0", 4))
2579 abi
= ABI_PPC0
; in
.pos
+= 4;
2581 else if(!strnicmp(in
.pos
, "PPC2", 4))
2583 abi
= ABI_PPC2
; in
.pos
+= 4;
2585 else if(!strnicmp(in
.pos
, "PPC", 3))
2587 abi
= ABI_PPC
; in
.pos
+= 3;
2590 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
2592 else if(!strnicmp(in
.pos
, "id", 2))
2595 DoError(ERR_IDSTRING_DECLARED_TWICE
, linenum
);
2596 IDstring
= in
.pos
= SkipBlanks(in
.pos
+2);
2597 if(strncmp(in
.pos
, "$Id: ", 5))
2599 DoError(ERR_EXCPECTED_IDSTRING
, linenum
);
2603 if(*(in
.pos
-1) != '$')
2604 DoError(ERR_EXPECTED_ID_ENDSIGN
, linenum
);
2606 else if(!strnicmp(in
.pos
, "include", 7))
2610 if(!(d
= (struct Include
*) NewItem(&Includes
)))
2612 d
->Include
= SkipBlanks(in
.pos
+7);
2613 AddItem(&Includes
, (struct ShortList
*) d
);
2617 else if(!strnicmp(in
.pos
, "varargs", 7))
2620 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2624 bias
-= BIAS_OFFSET
;
2625 functype
|= FUNCFLAG_TAG
;
2629 else if(!strnicmp(in
.pos
, "alias", 5))
2632 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2636 bias
-= BIAS_OFFSET
;
2637 functype
|= FUNCFLAG_ALIAS
;
2641 else if(!strnicmp(in
.pos
, "version", 7))
2643 /* store version entries as comments */
2648 in
.pos
= SkipBlanks(in
.pos
+7);
2649 v
= strtol(in
.pos
, &ptr
, 10);
2651 printf("ScanSFDFile: found ==version %d\n", v
);
2653 if(ptr
== in
.pos
|| v
< 0)
2654 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2657 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2663 d
->Private
= _public
? 0 : 1;
2664 AddItem(&Comment
, (struct ShortList
*) d
);
2665 in
.pos
= SkipName(in
.pos
);
2668 else if(!strnicmp(in
.pos
, "reserve", 7))
2670 /* store reserved entries as comments */
2675 in
.pos
= SkipBlanks(in
.pos
+7);
2676 v
= strtol(in
.pos
, &ptr
, 10);
2678 printf("ScanSFDFile: found ==reserve %d\n", v
);
2682 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
2686 if(ptr
== in
.pos
|| v
< 0)
2687 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2690 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2696 d
->Private
= _public
? 0 : 1;
2697 AddItem(&Comment
, (struct ShortList
*) d
);
2698 in
.pos
= SkipName(in
.pos
);
2699 bias
+= BIAS_OFFSET
*v
;
2703 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
2707 uint32 ft
, startlinenum
;
2708 struct AmiPragma ap
, *ap2
;
2709 struct ClibData d
, *f
;
2715 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
2716 /* join lines, if necessary */
2717 startlinenum
= linenum
;
2719 /* first open bracket */
2720 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
)
2721 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2723 ft
= 0; /* this is needed for function pointer types, which have own
2725 /* first close bracket */
2726 while((*data
!= /*(*/')' || ft
) && data
< in
.buf
+ in
.size
)
2733 else if(*data
== '('/*)*/)
2735 else if(*data
== /*(*/')')
2739 /* second open bracket */
2740 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
)
2741 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2742 /* second close bracket */
2743 while(*data
!= /*(*/')' && data
< in
.buf
+ in
.size
)
2744 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2745 if(data
== in
.buf
+ in
.size
)
2748 DoError(ERR_UNEXPECTED_FILEEND
, linenum
);
2752 ft
= functype
; functype
= 0;
2753 memset(&ap
, 0, sizeof(struct AmiPragma
));
2754 memset(&d
, 0, sizeof(struct ClibData
));
2755 if(!GetCPPType(&d
.ReturnType
, in
.pos
, 1, 1))
2757 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE
, startlinenum
);
2762 else if(d
.ReturnType
.Unknown
)
2763 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, startlinenum
,
2764 d
.ReturnType
.Unknown
);
2766 ap
.FuncName
= d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
2767 +d
.ReturnType
.FullLength
);
2768 in
.pos
= SkipBlanks(SkipName(d
.FuncName
));
2770 if(*in
.pos
!= '('/*)*/)
2772 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2776 *(SkipName(d
.FuncName
)) = 0;
2777 in
.pos
= SkipBlanks(++in
.pos
);
2780 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2782 oldptr
= (strptr
) 1;
2783 if(d
.NumArgs
>= maxreg
)
2785 DoError(ERR_TO_MUCH_ARGUMENTS
, startlinenum
);
2788 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], in
.pos
, 0, 0))
2790 DoError(ERR_UNKNOWN_VARIABLE_TYPE
, startlinenum
, d
.NumArgs
);
2793 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
2794 DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT
, startlinenum
, d
.NumArgs
,
2795 d
.Args
[d
.NumArgs
-1].Unknown
);
2797 oldptr
= in
.pos
= SkipBlanks(d
.Args
[d
.NumArgs
-1].TypeStart
2798 + d
.Args
[d
.NumArgs
-1].FullLength
);
2799 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
2801 if(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
)
2803 oldptr
= d
.Args
[d
.NumArgs
-1].FunctionName
;
2806 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2809 else if(!(oldptr
= DupString(oldptr
, SkipName(oldptr
)-oldptr
)))
2811 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
2815 ap
.Args
[ap
.CallArgs
++].ArgName
= in
.pos
;
2816 in
.pos
= SkipName(in
.pos
);
2818 if(in
.pos
== oldptr
)
2820 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2828 in
.pos
= SkipBlanks(in
.pos
);
2829 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
2831 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2836 in
.pos
= SkipBlanks(++in
.pos
);
2837 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
&&
2838 !(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
))
2839 *(SkipName(oldptr
)) = 0;
2841 printf("Added last argument %d (%s) for %s (%d bytes)\n", d
.NumArgs
,
2842 oldptr
, d
.FuncName
, d
.Args
[d
.NumArgs
-1].FullLength
);
2849 in
.pos
= SkipBlanks(++in
.pos
);
2850 *(SkipName(oldptr
)) = 0;
2852 printf("Added argument %d (%s) for %s (%d bytes)\n", d
.NumArgs
,
2853 oldptr
, d
.FuncName
, d
.Args
[d
.NumArgs
-1].FullLength
);
2857 if(*in
.pos
== /*(*/')')
2859 if(!oldptr
) /* oldptr == 0 means parsing was valid */
2861 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
2864 memcpy(f
, &d
, sizeof(struct ClibData
));
2870 struct ClibData
*e
= clibdata
;
2877 printf("Added prototype for %s (line %ld) with %d args\n", f
->FuncName
,
2878 startlinenum
, f
->NumArgs
);
2880 if(*(in
.pos
= SkipBlanks(in
.pos
)) != '('/*)*/)
2882 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2889 DoError(ERR_ASSUMING_BIAS_OF_30
, startlinenum
);
2895 ap
.Line
= startlinenum
;
2896 bias
+= BIAS_OFFSET
;
2899 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
2903 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2905 if(*in
.pos
!= /*(*/')')
2907 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2912 ap
.NumArgs
= ap
.CallArgs
;
2914 ap
.Flags
|= AMIPRAGFLAG_PPC
;
2916 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
2917 else if(abi
== ABI_PPC2
)
2918 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
2928 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
2930 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
2933 in
.pos
= SkipName(oldptr
);
2934 len
= in
.pos
-oldptr
;
2936 for(i
= 0; i
< MAXREG
; ++i
)
2937 if(!strnicmp(RegNames
[i
], oldptr
, len
))
2942 DoError(ERR_EXPECTED_REGISTER_NAME
, startlinenum
);
2945 else if(i
== REG_A6
)
2946 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
2947 else if(i
== REG_A5
)
2948 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
2949 else if(i
== REG_A4
)
2950 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
2951 else if(i
== REG_D7
)
2952 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
2953 else if(i
== REG_A7
)
2955 DoError(ERR_A7_NOT_ALLOWED
, startlinenum
);
2958 else if(i
>= REG_FP0
)
2959 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
2961 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
2963 for(i
= 0; i
< ap
.NumArgs
; i
++)
2965 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
2967 DoError(ERR_REGISTER_USED_TWICE
, startlinenum
);
2976 in
.pos
= SkipBlanks(in
.pos
);
2977 if(*in
.pos
!= ',' && *in
.pos
!= '-' && *in
.pos
!= '/' &&
2978 *in
.pos
!= /*(*/')')
2980 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2983 } while(*in
.pos
!= /*(*/')');
2985 if(*in
.pos
!= /*(*/')')
2994 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
2995 if(ft
&& !(ft
& FUNCFLAG_TAG
) && ap
.NumArgs
!= ap2
->NumArgs
)
2996 ft
= 0; /* like DoPkt, handle as seperate function */
2997 if(ft
) /* handle alias and varargs */
2999 if(ap2
->TagName
|| (ft
& FUNCFLAG_ALIAS
))
3001 struct Pragma_AliasName
*p
;
3003 if((p
= (struct Pragma_AliasName
*)
3004 AllocListMem(sizeof(struct Pragma_AliasName
))))
3006 p
->FunctionName
= ap2
->TagName
;
3007 p
->AliasName
= ap
.FuncName
;
3008 p
->Type
= (ft
& FUNCFLAG_TAG
) ? FUNCFLAG_TAG
: FUNCFLAG_NORMAL
;
3009 AddAliasName(ap2
, p
, startlinenum
);
3016 ap2
->TagName
= ap
.FuncName
;
3019 if(ap
.CallArgs
!= ap2
->CallArgs
)
3021 if(ap2
->CallArgs
+ 1 == ap
.CallArgs
&& d
.Args
[d
.NumArgs
-1].Type
3022 == CPP_TYPE_VARARGS
)
3029 if(ap
.NumArgs
!= ap2
->NumArgs
)
3031 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
3033 else if(abi
== ABI_M68K
)
3037 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3039 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3041 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
3047 else if(abi
== ABI_M68K
)
3049 if(ap
.CallArgs
!= ap
.NumArgs
)
3050 { /* this is surely no longer necessary, as there wont be any
3051 varargs functions here */
3052 if(ap
.CallArgs
== ap
.NumArgs
+1 && d
.Args
[d
.NumArgs
-1].Type
3053 == CPP_TYPE_VARARGS
)
3056 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3059 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3061 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3062 DoError(ERR_FLOATARG_NOT_ALLOWED
, startlinenum
);
3063 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3064 && !(Flags
& FLAG_PPCONLY
))
3065 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3066 struct AmiPragma
*d
;
3067 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3069 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3072 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3077 if(!(Flags
& FLAG_NOPPC
))
3079 struct AmiPragma
*d
;
3080 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3082 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3085 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3091 in
.pos
= SkipBlanks(in
.pos
);
3093 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3094 ++in
.pos
; /* skip '\0' */
3098 DoError(ERR_MISSING_SFDEND
, 0);
3103 static uint32
ScanFDFile(void)
3110 uint32 shadowmode
= 0;
3111 enum ABI abi
= ABI_M68K
;
3115 if(!stricmp(defabi
, "M68k"))
3117 else if(!stricmp(defabi
, "PPC0"))
3119 else if(!stricmp(defabi
, "PPC2"))
3121 else if(!stricmp(defabi
, "PPC"))
3124 DoError(ERR_UNKNOWN_ABI
, 0, defabi
);
3127 if(in
.size
> 10 && in
.pos
[0] == '=' && in
.pos
[1] == '=')
3128 return ScanSFDFile(abi
);
3131 printf("ScanFDFile:\n");
3134 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
3136 if(*in
.pos
== '*') /* Comment */
3138 strptr oldpos
= in
.pos
;
3140 printf("ScanFDFile: found a comment\n");
3142 in
.pos
= SkipBlanks(in
.pos
+1);
3143 if(!strnicmp(in
.pos
, "notagcall", 9))
3145 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
;
3149 --tagfuncs
; ap
->TagName
= 0;
3150 ap
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3152 in
.pos
= SkipBlanks(in
.pos
+ 9);
3154 else if(!strnicmp(in
.pos
, "tagcall", 7)) /* Tag to create? */
3156 struct AmiPragma
*prevpragma
= (struct AmiPragma
*) AmiPragma
.Last
;
3158 in
.pos
= SkipBlanks(in
.pos
+ 7);
3161 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA
, linenum
);
3166 if(!prevpragma
->NumArgs
)
3168 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT
, linenum
);
3173 /* Get the tag functions name. */
3175 if(!prevpragma
->TagName
&& (_public
|| (Flags
& FLAG_PRIVATE
)))
3180 strptr oldptr
, tptr
= prevpragma
->TagName
;
3182 len
= strlen(prevpragma
->FuncName
)+strlen(in
.pos
)+1;
3183 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
)))
3190 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3191 in
.pos
= SkipName(in
.pos
);
3192 if((len
= in
.pos
-oldptr
))
3194 removeptr
= prevpragma
->TagName
+strlen(prevpragma
->TagName
)-len
;
3195 if(strncmp(removeptr
, oldptr
, len
))
3198 printf("ScanFDFile: *tagcall -: %s, %s, %d\n", removeptr
, oldptr
, len
);
3200 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
, linenum
);
3201 prevpragma
->TagName
= tptr
;
3208 in
.pos
= SkipBlanks(in
.pos
);
3211 in
.pos
= SkipBlanks(in
.pos
+1);
3213 *in
.pos
= toupper(*in
.pos
);
3215 in
.pos
= SkipName((oldptr
= in
.pos
));
3216 len
= in
.pos
-oldptr
;
3219 uint32 a
= strlen(prevpragma
->TagName
);
3220 memcpy(prevpragma
->TagName
+a
, oldptr
, len
);
3221 prevpragma
->TagName
[a
+len
] = '\0';
3224 else if(!prevpragma
->TagName
)
3226 len
= strlen(prevpragma
->FuncName
);
3227 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
+4)))
3229 memcpy(prevpragma
->TagName
+ len
, "Tags", 5);
3239 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
3245 d
->Private
= _public
? 0 : 1;
3246 AddItem(&Comment
, (struct ShortList
*) d
);
3253 else if(*in
.pos
== '#' && in
.pos
[1] == '#')
3256 actcom
= 0; /* no Comment */
3258 if(!strnicmp(in
.pos
, "base", 4))
3263 printf("ScanFDFile: found ##base\n");
3265 if(!(Flags
& FLAG_BASENAME
))
3268 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
3270 in
.pos
= SkipBlanks(in
.pos
+4);
3272 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
3276 BaseName
= oldptr
= in
.pos
;
3277 in
.pos
= SkipName(in
.pos
);
3278 if(!(in
.pos
-oldptr
))
3279 DoError(ERR_EXPECTED_BASENAME
, linenum
);
3283 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
3288 else if(!strnicmp(in
.pos
, "bias", 4))
3294 printf("ScanFDFile: found ##bias\n");
3297 newbias
= strtol(in
.pos
, &ptr
, 10);
3299 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
3300 else if(newbias
< 0)
3302 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
3307 in
.pos
= SkipName(in
.pos
);
3309 else if(!strnicmp(in
.pos
, "end", 3))
3313 else if(!strnicmp(in
.pos
, "shadow", 6)) /* introduced by Storm */
3316 if(bias
== -1 || !AmiPragma
.First
)
3317 DoError(ERR_EARLY_SHADOW
, linenum
);
3320 bias
-= BIAS_OFFSET
;
3324 else if(!strnicmp(in
.pos
, "public", 6))
3329 else if(!strnicmp(in
.pos
, "private", 7))
3334 else if(!strnicmp(in
.pos
, "abi", 3))
3337 printf("ScanFDFile: found ##abi\n");
3339 in
.pos
= SkipBlanks(in
.pos
+3);
3340 if(!strnicmp(in
.pos
, "M68k", 4))
3342 abi
= ABI_M68K
; in
.pos
+= 4;
3344 else if(!strnicmp(in
.pos
, "PPC0", 4))
3346 abi
= ABI_PPC0
; in
.pos
+= 4;
3348 else if(!strnicmp(in
.pos
, "PPC2", 4))
3350 abi
= ABI_PPC2
; in
.pos
+= 4;
3352 else if(!strnicmp(in
.pos
, "PPC", 3))
3354 abi
= ABI_PPC
; in
.pos
+= 3;
3357 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
3360 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
3366 struct AmiPragma ap
, *ap2
;
3369 printf("ScanFDFile: scan Function\n");
3371 memset(&ap
, 0, sizeof(struct AmiPragma
));
3374 oldptr
= in
.pos
= SkipBlanks(in
.pos
);
3375 in
.pos
= SkipName(oldptr
);
3376 if(!(len
= in
.pos
-oldptr
))
3378 DoError(ERR_MISSING_FUNCTION_NAME
, linenum
);
3383 ap
.FuncName
= oldptr
;
3385 in
.pos
= SkipBlanks(in
.pos
);
3386 if(*in
.pos
!= '('/*)*/)
3388 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3393 oldptr
[len
] = '\0'; /* create c string of FunctionName */
3396 printf("ScanFDFile: found function %s\n", ap
.FuncName
);
3399 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
3402 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3404 if(*in
.pos
== '*') /* strange OS3.9 files */
3406 DoError(ERR_ILLEGAL_CHARACTER_DETECTED
, linenum
);
3407 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3410 if(*in
.pos
== /*(*/')' && !ap
.CallArgs
)
3413 if(ap
.CallArgs
>= maxreg
)
3415 DoError(ERR_TO_MUCH_ARGUMENTS
, linenum
); break;
3418 if(!strncmp(in
.pos
, "void", 4))
3420 /* allows "(void)" instead of ()" */
3421 in
.pos
= SkipBlanks(in
.pos
+ 4);
3422 if(*in
.pos
!= /*(*/')')
3423 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3427 if(!strncmp(in
.pos
, "...", 3))
3429 ap
.Flags
= AMIPRAGFLAG_VARARGS
;
3430 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3431 in
.pos
= SkipBlanks(in
.pos
+3);
3432 if(*in
.pos
!= /*(*/')')
3433 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3437 in
.pos
= SkipName(oldptr
);
3440 if(!(len
= in
.pos
-oldptr
))
3442 DoError(ERR_EXPECTED_ARGUMENT_NAME
, linenum
);
3443 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3447 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
3449 in
.pos
= SkipBlanks(in
.pos
);
3451 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3453 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3456 if(*in
.pos
!= /*(*/')') /* create c string ending */
3458 } while(*in
.pos
!= /*(*/')');
3460 if(*in
.pos
!= /*(*/')')
3467 *oldptr
= '\0'; /* create c string ending for last argument */
3471 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
3478 bias
+= BIAS_OFFSET
;
3481 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
3483 in
.pos
= SkipBlanks(in
.pos
+1);
3485 if(*in
.pos
|| ap
.CallArgs
)
3486 /* support for FD's without second empty bracket pair */
3488 if(*in
.pos
!= '('/*)*/)
3490 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3501 oldptr
= in
.pos
= SkipBlanks(in
.pos
+ 1);
3503 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
3506 if(!strncmp(in
.pos
, "base", 4))
3508 in
.pos
= SkipBlanks(in
.pos
+ 4);
3511 in
.pos
= SkipBlanks(in
.pos
+ 1);
3512 if(!strncmp(in
.pos
, "sysv",4))
3514 /* MorphOS V.4 with base in r3: (base,sysv) */
3515 ap
.Flags
|= AMIPRAGFLAG_MOSBASESYSV
;
3516 ap
.NumArgs
= ap
.CallArgs
;
3517 in
.pos
= SkipBlanks(in
.pos
+ 4);
3518 if(*in
.pos
!= /*(*/')')
3519 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3524 else if(!strncmp(in
.pos
, "sysv", 4))
3526 in
.pos
= SkipBlanks(in
.pos
+ 4);
3529 in
.pos
= SkipBlanks(in
.pos
+ 1);
3530 if(!strncmp(in
.pos
, "r12base",7))
3532 /* MorphOS V.4 without passing base: (sysv) */
3533 ap
.Flags
|= AMIPRAGFLAG_MOSSYSVR12
;
3534 ap
.NumArgs
= ap
.CallArgs
;
3535 in
.pos
= SkipBlanks(in
.pos
+ 7);
3536 if(*in
.pos
!= /*(*/')')
3537 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3541 else if (*in
.pos
== /*(*/')')
3543 /* MorphOS V.4 without passing base: (sysv) */
3544 ap
.Flags
|= AMIPRAGFLAG_MOSSYSV
;
3545 ap
.NumArgs
= ap
.CallArgs
;
3550 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3555 in
.pos
= SkipName(oldptr
);
3556 len
= in
.pos
-oldptr
;
3558 for(i
= 0; i
< MAXREG
; ++i
)
3559 if(!strnicmp(RegNames
[i
], oldptr
, len
))
3564 DoError(ERR_EXPECTED_REGISTER_NAME
, linenum
);
3567 else if(i
== REG_A6
)
3568 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
3569 else if(i
== REG_A5
)
3570 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
3571 else if(i
== REG_A4
)
3572 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
3573 else if(i
== REG_D7
)
3574 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
3575 else if(i
== REG_A7
)
3577 DoError(ERR_A7_NOT_ALLOWED
, linenum
);
3580 else if(i
>= REG_FP0
)
3581 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
3583 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
3585 for(i
= 0; i
< ap
.NumArgs
; i
++)
3587 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
3589 DoError(ERR_REGISTER_USED_TWICE
, linenum
);
3598 in
.pos
= SkipBlanks(in
.pos
);
3599 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3601 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3604 } while(*in
.pos
!= /*(*/')');
3606 if(*in
.pos
!= /*(*/')')
3617 while(*in
.pos
&& *in
.pos
!= /*(*/')')
3619 if(*in
.pos
!= /*(*/')')
3621 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3626 ap
.NumArgs
= ap
.CallArgs
;
3628 ap
.Flags
|= AMIPRAGFLAG_PPC
;
3630 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
3631 else if(abi
== ABI_PPC2
)
3632 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
3636 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3638 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
3641 if(ap2
->TagName
&& !(ap2
->Flags
& AMIPRAGFLAG_OWNTAGFUNC
))
3643 struct Pragma_AliasName
*p
;
3644 DoError(ERR_DOUBLE_VARARGS
, linenum
);
3646 if((p
= (struct Pragma_AliasName
*)
3647 AllocListMem(sizeof(struct Pragma_AliasName
))))
3649 p
->FunctionName
= ap2
->TagName
;
3650 p
->AliasName
= ap
.FuncName
;
3651 p
->Type
= FUNCFLAG_TAG
;
3652 AddAliasName(ap2
, p
, linenum
);
3657 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2
->TagName
);
3663 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2
->TagName
);
3665 ap2
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3666 ap2
->TagName
= ap
.FuncName
;
3669 if(ap
.NumArgs
!= ap2
->NumArgs
)
3670 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3671 else if(abi
== ABI_M68K
)
3675 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3677 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3679 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3685 /* handle them as alias instead seperate */
3686 else if(ap2
&& ap2
->Bias
== ap
.Bias
&& ap2
->NumArgs
== ap
.NumArgs
)
3688 struct Pragma_AliasName
*p
;
3690 if((p
= (struct Pragma_AliasName
*)
3691 AllocListMem(sizeof(struct Pragma_AliasName
))))
3693 p
->FunctionName
= ap2
->TagName
;
3694 p
->AliasName
= ap
.FuncName
;
3695 p
->Type
= FUNCFLAG_NORMAL
;
3696 AddAliasName(ap2
, p
, linenum
);
3702 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3704 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3706 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3714 if(ap
.Flags
& AMIPRAGFLAG_VARARGS
)
3716 ap
.TagName
= ap
.FuncName
;
3719 else if((_public
|| (Flags
& FLAG_PRIVATE
)) &&
3720 !MakeTagFunction(&ap
))
3722 else /* check the alias names */
3726 while(Pragma_AliasNames
[i
].FunctionName
)
3728 if(!strcmp(ap
.FuncName
, Pragma_AliasNames
[i
].FunctionName
) ||
3729 (ap
.TagName
&& !strcmp(ap
.TagName
,
3730 Pragma_AliasNames
[i
].FunctionName
)))
3732 AddAliasName(&ap
, (struct Pragma_AliasName
*)
3733 &Pragma_AliasNames
[i
], linenum
);
3741 if(ap
.CallArgs
!= ap
.NumArgs
)
3742 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3744 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3746 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3747 DoError(ERR_FLOATARG_NOT_ALLOWED
, linenum
);
3748 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3749 && !(Flags
& FLAG_PPCONLY
))
3750 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3751 struct AmiPragma
*d
;
3752 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3754 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3757 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3764 if(!(Flags
& FLAG_NOPPC
))
3766 struct AmiPragma
*d
;
3767 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3769 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3772 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3783 in
.pos
= SkipBlanks(in
.pos
);
3785 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3786 ++in
.pos
; /* skip '\0' */
3790 DoError(ERR_MISSING_END
, 0);
3795 static int32
ScanTypes(strptr ptr
, uint32 size
)
3797 struct CPP_ExternNames
*a
= 0, *b
= 0;
3798 strptr endptr
= ptr
+size
;
3801 for(line
= 1; ptr
< endptr
; ++line
)
3803 struct CPP_ExternNames
*n
;
3805 if(*ptr
== '*') /* skip comments */
3807 while(ptr
< endptr
&& *(ptr
++) != '\n')
3810 else if((n
= (struct CPP_ExternNames
*)
3811 AllocListMem(sizeof(struct CPP_ExternNames
))))
3815 n
->Type
= ptr
; /* store start */
3817 while(ptr
< endptr
&& *ptr
!= ':' && *ptr
!= '\n' && *ptr
!= '\t'
3820 wptr
= SkipBlanks(ptr
);
3821 if(*(wptr
++) != ':')
3825 n
->NameType
.StructureName
= n
->Type
;
3826 n
->NameType
.StructureLength
= ptr
-n
->Type
; /* for struct ! types */
3828 if(!GetCPPType(&n
->NameType
, (ptr
= SkipBlanks(wptr
)), 0, 1))
3831 printf("'%20s', slen %2d, typelen %3d, pntd %d, type %c, sn '%.3s'\n",
3832 n
->Type
, n
->NameType
.StructureLength
, n
->NameType
.FullLength
,
3833 n
->NameType
.PointerDepth
, n
->NameType
.Type
? n
->NameType
.Type
: 's',
3834 n
->NameType
.StructureName
? n
->NameType
.StructureName
: "<e>");
3836 ptr
= SkipBlanks(n
->NameType
.TypeStart
+n
->NameType
.FullLength
);
3837 if(*(ptr
++) != '\n')
3840 printf("%.30s\n", ptr
);
3854 extnames
= b
; /* now store the list */
3858 static void FindHeader(void)
3860 strptr str
= HEADER
;
3875 else if(*str
== '/')
3878 else if(*str
== '*' || *str
== ';')
3880 else if(*str
== '{'/*}*/)
3884 else if(*str
== '('/*)*/ && *(++str
) == '*')
3890 while(*str
&& *(str
++) != '\n')
3896 while(*str
&& (*(str
-1) != '*' || *str
!= '/'))
3898 while(*str
&& *(str
++) != '\n')
3903 while(*str
&& *str
!= /*{*/'}')
3905 while(*str
&& *(str
++) != '\n')
3910 while(*str
&& (*(str
-1) != '*' || *str
!= /*(*/')'))
3912 while(*str
&& *(str
++) != '\n')
3917 headersize
= str
-HEADER
;
3920 HEADER
= 0; headersize
= 0;
3924 /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
3925 static uint32
GetRegisterData(struct AmiPragma
*ap
)
3928 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
3929 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
3931 register uint32 i
, data
= 0, reg
;
3933 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3935 if((reg
= ap
->Args
[i
].ArgReg
) <= REG_FP0
)
3937 if(reg
>= 10 || (reg
>= 2 && reg
<= 7)) /* A2-A7 and D2-D7 */
3938 data
|= (1 << (reg
+ 16)) + (1 << (15 - reg
));
3941 if(data
) /* set A6 only when other register used */
3946 static uint16
GetFRegisterData(struct AmiPragma
*ap
)
3949 F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
3950 F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
3952 register uint32 i
, reg
;
3953 register uint16 data
= 0;
3955 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3957 if((reg
= ap
->Args
[i
].ArgReg
) >= REG_FP2
)
3960 data
|= (1 << (reg
+ 8)) + (1 << (7 - reg
));
3966 static uint32
OutputXDEF(uint32 offset
, strptr format
, ...)
3972 va_start(a
, format
);
3973 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3977 EndPutM32(buf
+4+i
, offset
); /* the definition offset */
3979 EndPutM32(buf
, (EXT_DEF
<<24) + (i
>>2));
3981 return DoOutputDirect(buf
, i
+8);
3984 static uint32
OutputXREF(uint32 offset
, uint32 type
, strptr format
, ...)
3990 va_start(a
, format
);
3991 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3995 EndPutM32(buf
+4+i
, 1); /* 1 reference */
3996 EndPutM32(buf
+8+i
, offset
); /* the definition offset */
3998 EndPutM32(buf
, (type
<< 24) + (i
>>2));
4000 return DoOutputDirect(buf
, i
+12);
4003 static uint32
OutputXREF2(uint32 offset1
, uint32 offset2
, uint32 type
,
4010 va_start(a
, format
);
4011 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4015 EndPutM32(buf
+4+i
, 2); /* 2 references */
4016 EndPutM32(buf
+8+i
, offset1
); /* the definition offset */
4017 EndPutM32(buf
+12+i
, offset2
); /* the definition offset */
4019 EndPutM32(buf
, (type
<< 24) + (i
>>2));
4021 return DoOutputDirect(buf
, i
+16);
4024 static uint32
OutputSYMBOL(uint32 offset
, strptr format
, ...)
4030 va_start(a
, format
);
4031 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4035 EndPutM32(buf
+4+i
, offset
);
4037 EndPutM32(buf
, (0 << 24) + (i
>>2));
4039 return DoOutputDirect(buf
, i
+8);
4042 static uint8
*AsmStackCopy(uint8
*data
, struct AmiPragma
*ap
, uint32 flags
,
4045 uint32 i
, j
, k
, l
, tofs
;
4047 if(Flags
& FLAG_PASCAL
)
4053 if(ap
->Args
[k
-1].ArgReg
>= REG_FP0
)
4055 struct ClibData
*cd
;
4057 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
4058 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
4060 if(cd
&& IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_DOUBLE
))
4062 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
4063 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
4068 if(!cd
|| !IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_FLOAT
))
4069 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4070 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
4071 EndPutM16Inc(data
, (ofs
++) << 2);
4074 else if((k
>= 2) && (ap
->Args
[k
-1].ArgReg
< ap
->Args
[k
-2].ArgReg
)
4075 && ap
->Args
[k
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4080 j
= ap
->Args
[--k
].ArgReg
;
4084 } while(k
&& j
< ap
->Args
[k
-1].ArgReg
4085 && ap
->Args
[k
-1].ArgReg
< REG_FP0
);
4086 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4087 EndPutM16Inc(data
, l
);
4088 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
4092 l
= 0x202F; /* MOVE.L offs(A7),xxx */
4094 if((j
= ap
->Args
[--k
].ArgReg
) > 7)
4096 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
4098 /* set destination register and store */
4099 EndPutM16Inc(data
, l
| (j
<< 9));
4100 EndPutM16Inc(data
, (ofs
++) << 2);
4108 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4112 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4114 struct ClibData
*cd
;
4116 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
4117 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
4119 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4121 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
4122 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
4127 if(!cd
|| !IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4128 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4129 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
4130 EndPutM16Inc(data
, (ofs
++) << 2);
4133 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
)
4134 && ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4139 j
= ap
->Args
[i
++].ArgReg
;
4143 } while(i
< k
&& j
< ap
->Args
[i
].ArgReg
4144 && ap
->Args
[i
].ArgReg
< REG_FP0
);
4145 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4146 EndPutM16Inc(data
, l
); /* Store MOVEM.L data */
4147 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
4151 l
= 0x202F; /* MOVE.L offs(A7),xxx */
4153 if((j
= ap
->Args
[i
++].ArgReg
) > 7)
4155 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
4157 /* set destination register and store */
4158 EndPutM16Inc(data
, l
| (j
<< 9));
4159 EndPutM16Inc(data
, (ofs
++) << 2);
4165 if((j
= ap
->Args
[i
].ArgReg
) > 7)
4167 EndPutM16Inc(data
, 0x41EF | ((j
-8) << 9)); /* LEA xxx(A7),Ax */
4168 EndPutM16Inc(data
, ofs
<< 2);
4172 EndPutM16Inc(data
, 0x200F | (j
<< 9)); /* MOVE.L A7,Dx */
4173 EndPutM16Inc(data
, 0x5080 | j
); /* ADDQ.L #8,Dx */
4177 EndPutM16Inc(data
, 0x486F); /* PEA xxx(A7) */
4178 EndPutM16Inc(data
, ofs
<< 2);
4179 EndPutM16Inc(data
, 0x201F | j
<< 9); /* MOVE.L offs(A7),Dx */
4186 /* ------------------------------------------------------------------ */
4188 static void DoError(uint32 errnum
, uint32 line
, ...)
4190 uint32 err
= errnum
& 0xFFFF;
4193 if(Flags
& FLAG_DIDERROR
)
4196 if(!Errors
[err
].Type
)
4197 Flags
|= FLAG_DIDERROR
;
4202 printf("%s %ld in line %ld%s: ",
4203 (Errors
[err
].Type
? "Warning" : "Error"),
4205 errnum
& ERROFFSET_CLIB
? " of clib file" : "");
4209 printf("%s %ld : ", (Errors
[err
].Type
? "Warning" : "Error"), err
);
4211 vprintf(Errors
[err
].Error
, a
);
4213 if(line
&& Errors
[err
].Skip
)
4221 static uint32
CheckError(struct AmiPragma
*ap
, uint32 errflags
)
4223 errflags
&= ap
->Flags
;
4225 if(errflags
& AMIPRAGFLAG_ARGCOUNT
)
4227 if(!(ap
->Flags
& AMIPRAGFLAG_DIDARGWARN
))
4229 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
, ap
->Line
);
4230 ap
->Flags
|= AMIPRAGFLAG_DIDARGWARN
;
4234 else if(errflags
& AMIPRAGFLAG_FLOATARG
)
4236 if(!(ap
->Flags
& AMIPRAGFLAG_DIDFLOATWARN
))
4238 DoError(ERR_FLOATARG_NOT_ALLOWED
, ap
->Line
);
4239 ap
->Flags
|= AMIPRAGFLAG_DIDFLOATWARN
;
4243 else if(errflags
& AMIPRAGFLAG_A6USE
)
4245 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
4248 else if(errflags
& AMIPRAGFLAG_A5USE
)
4250 DoError(ERR_A5_NOT_ALLOWED
, ap
->Line
);
4253 else if(errflags
& AMIPRAGFLAG_PPC
)
4255 if(!(Flags
& FLAG_DIDPPCWARN
))
4257 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4258 Flags
|= FLAG_DIDPPCWARN
;
4262 else if(errflags
& AMIPRAGFLAG_M68K
)
4264 if(!(Flags
& FLAG_DIDM68KWARN
))
4266 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4267 Flags
|= FLAG_DIDM68KWARN
;
4271 else if(errflags
& AMIPRAGFLAG_MOSBASESYSV
)
4273 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED
, ap
->Line
);
4280 static uint32
DoOutput(strptr format
, ...)
4287 va_start(a
, format
);
4288 if(vfprintf(outfile
, format
, a
) < 0)
4292 return Output_Error
;
4295 static uint32
DoOutputDirect(void * data
, size_t size
)
4301 if(fwrite(data
, size
, 1, outfile
) != 1)
4304 return Output_Error
;
4307 /* ------------------------------------------------------------------ */
4309 static struct ShortList
*NewItem(struct ShortListRoot
*list
)
4311 struct ShortList
*item
;
4312 if(!list
|| !list
->Size
)
4314 if(!(item
= (struct ShortList
*) AllocListMem(list
->Size
)))
4319 static struct ShortList
*RemoveItem(struct ShortListRoot
*list
,
4320 struct ShortList
*item
)
4322 struct ShortList
*n
= list
->First
;
4325 list
->First
= item
->Next
;
4328 while(n
&& n
->Next
!= item
)
4332 if(!(n
->Next
= item
->Next
))
4339 static void AddItem(struct ShortListRoot
*list
, struct ShortList
*item
)
4342 list
->First
= list
->Last
= item
;
4345 list
->Last
->Next
= item
;
4350 /* ------------------------------------------------------------------ */
4352 uint32
FuncAMICALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4356 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4359 Flags
|= FLAG_DONE
; /* We did something */
4361 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags
& FUNCFLAG_TAG
?
4362 "tagcall" : "amicall", BaseName
, ap
->Bias
, name
);
4364 for(i
= 0; i
< ap
->NumArgs
; ++i
)
4366 DoOutput("%s",RegNames
[ap
->Args
[i
].ArgReg
]);
4367 if(i
+1 < ap
->NumArgs
)
4371 return DoOutput(/*((*/"))\n");
4374 uint32
FuncLIBCALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4378 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4381 Flags
|= FLAG_DONE
; /* We did something */
4383 if(ap
->Flags
& AMIPRAGFLAG_FLOATARG
)
4385 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName
, name
, ap
->Bias
);
4386 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4387 DoOutput("%02x", ap
->Args
[i
].ArgReg
);
4389 return DoOutput("00%02x\n", ap
->NumArgs
);
4392 if((Flags
& FLAG_SYSCALL
) && !strcmp(BaseName
,"SysBase") &&
4393 (flags
& FUNCFLAG_NORMAL
))
4394 DoOutput("#pragma syscall %-22s %03x ", name
, ap
->Bias
);
4396 DoOutput("#pragma %s %s %-22s %03x ", (flags
& FUNCFLAG_TAG
) ?
4397 "tagcall" : "libcall", BaseName
, name
, ap
->Bias
);
4399 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4400 DoOutput("%x", ap
->Args
[i
].ArgReg
);
4402 return DoOutput("0%x\n", ap
->NumArgs
);
4405 uint32
FuncAsmText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4412 struct ClibData
*cd
;
4414 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4417 Flags
|= FLAG_DONE
; /* We did something */
4419 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
4420 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
4422 if(Flags
& FLAG_SINGLEFILE
)
4424 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
4429 DoOutputDirect(HEADER
, headersize
);
4433 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
4435 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
4436 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
4439 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name
, name
);
4440 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4442 DoOutput("\tXDEF\t%s\n%s:\n",name
, name
);
4446 DoOutput("\tXDEF\t%s_\n%s_:\n",name
, name
);
4447 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4452 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4454 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4455 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name
, txt
, name
, txt
);
4461 if((registers
= GetRegisterData(ap
) >> 16))
4463 if(Flags
& FLAG_NOMOVEM
)
4465 for(i
= 0; i
<= 15; ++i
)
4467 if(registers
& (1 << i
))
4470 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper
[i
]);
4476 uint16 l
= registers
;
4478 DoOutput("\tMOVEM.L\t");
4480 for(i
= 0; i
<= 15; ++i
)
4486 DoOutput("%s",RegNamesUpper
[i
]);
4491 DoOutput(",-(A7)\n");
4496 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset
;
4499 if((fregs
= GetFRegisterData(ap
) >> 8))
4503 DoOutput("\tFMOVEM.X\t");
4505 for(i
= 0; i
<= 7; ++i
)
4511 DoOutput("%s",RegNamesUpper
[REG_FP0
+ i
]);
4516 DoOutput(",-(A7)\n");
4519 if(Flags
& FLAG_SMALLDATA
)
4521 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1
, BaseName
, c2
);
4524 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName
);
4526 if(!(Flags
& FLAG_PASCAL
))
4530 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4534 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4537 struct ClibData
*cd
;
4539 cd
= GetClibFunc(name
, ap
, flags
);
4540 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4541 t
= CPP_TYPE_DOUBLE
;
4542 else if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4546 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4550 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
4551 ? 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4553 if(t
== CPP_TYPE_DOUBLE
)
4557 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
) &&
4558 ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4560 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4561 RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4565 DoOutput("/%s", RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4567 } while((i
< k
) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
].ArgReg
) &&
4568 ap
->Args
[i
].ArgReg
< REG_FP0
);
4573 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4574 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4575 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4582 if(ap
->Args
[i
].ArgReg
> 7)
4583 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1
, offset
<<2, c2
,
4584 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4585 else if(offset
<= 2)
4586 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4587 RegNamesUpper
[ap
->Args
[i
].ArgReg
],offset
<<2,
4588 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4590 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1
,
4591 offset
<<2, c2
,RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4600 if(ap
->Args
[i
-1].ArgReg
>= REG_FP0
)
4603 struct ClibData
*cd
;
4605 cd
= GetClibFunc(name
, ap
, flags
);
4607 if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_DOUBLE
))
4608 t
= CPP_TYPE_DOUBLE
;
4609 else if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_FLOAT
))
4613 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4617 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
?
4618 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4619 if(t
== CPP_TYPE_DOUBLE
)
4623 else if((i
>= 2) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
-2].ArgReg
) &&
4624 ap
->Args
[i
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4626 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4627 RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4631 DoOutput("/%s", RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4633 } while(i
&& (ap
->Args
[i
].ArgReg
< ap
->Args
[i
-1].ArgReg
) &&
4634 ap
->Args
[i
-1].ArgReg
< REG_FP0
);
4640 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4641 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4642 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4647 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1
, ap
->Bias
, c2
);
4651 DoOutput("\tFMOVEM.X\t(A7)+,");
4653 for(i
= 0; i
<= 7; ++i
)
4655 if(fregs
& (1 << i
))
4658 DoOutput("%s",RegNamesUpper
[REG_FP0
+ i
]);
4668 if(Flags
& FLAG_NOMOVEM
)
4670 for(i
= 15; i
>= 0; --i
)
4672 if(registers
& (1 << i
))
4673 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i
>= REG_A0
? "A" : "",
4679 DoOutput("\tMOVEM.L\t(A7)+,");
4681 for(i
= 0; i
<= 15; ++i
)
4683 if(registers
& (1 << i
))
4685 registers
^= 1 << i
;
4686 DoOutput("%s",RegNamesUpper
[i
]);
4695 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4697 return DoOutput("\tRTS\n");
4700 uint32
FuncAsmCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4702 uint32 registers
, offset
= 1, baseref
;
4707 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4710 Flags
|= FLAG_DONE
; /* We did something */
4712 registers
= GetRegisterData(ap
);
4713 fregs
= GetFRegisterData(ap
);
4715 i
= strlen(name
) + 2;
4716 EndPutM32(tempbuf
, HUNK_UNIT
);
4717 EndPutM32(tempbuf
+4, (i
+3)>>2);
4718 DoOutputDirect(tempbuf
, 8);
4719 DoOutput("%s.o", name
);
4720 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4722 i
= strlen(hunkname
);
4723 EndPutM32(tempbuf
, HUNK_NAME
);
4724 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
4725 DoOutputDirect(tempbuf
, 8);
4726 DoOutputDirect(hunkname
, i
);
4727 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4729 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
4733 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
4734 ++offset
; /* one long more on stack */
4738 if(Flags
& FLAG_NOMOVEM
)
4740 for(i
= 0; i
<= 15; ++i
)
4742 if(registers
& (1<< (16+i
)))
4744 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
4752 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
4753 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
4754 for(l
= (uint16
) registers
; l
; l
>>= 1)
4757 ++offset
; /* get offset addition */
4765 EndPutM16Inc(data
, 0xF227); /* FMOVEM.X xxx,-(A7) */
4766 EndPutM16Inc(data
, 0xE000 + ((fregs
>>8)&0xFF));
4767 for(l
= (uint8
) fregs
; l
; l
>>= 1)
4770 offset
+=3; /* get offset addition */
4774 baseref
= (data
-tempbuf
)-8+2; /* one word later (MOVE) - 2 header longs */
4775 if(Flags
& FLAG_SMALLDATA
)
4777 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
4778 EndPutM16Inc(data
, 0); /* place for base reference */
4782 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
4783 EndPutM32Inc(data
, 0); /* place for base reference */
4786 data
= AsmStackCopy(data
, ap
, flags
, offset
);
4788 /* here comes the base reference */
4789 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
4790 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
4794 EndPutM16Inc(data
, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4795 EndPutM16Inc(data
, 0xD000 + (fregs
&0xFF));
4800 if(Flags
& FLAG_NOMOVEM
)
4803 for(i
= 15; i
>= 0; --i
)
4805 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
4806 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
4811 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4812 EndPutM16Inc(data
, (registers
>> 16)); /* store MOVEM.L registers */
4816 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
4817 EndPutM16Inc(data
, 0x4E75); /* RTS */
4819 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
4821 EndPutM32(tempbuf
, HUNK_CODE
);
4822 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
4823 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
4825 EndPutM32(tempbuf
, HUNK_EXT
);
4826 DoOutputDirect(tempbuf
, 4);
4828 OutputXREF(baseref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
),
4830 /* here come the XDEF name references */
4831 OutputXDEF(0, "_%s", name
); /* C name */
4833 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4835 struct ClibData
*cd
;
4836 OutputXDEF(0, "%s", name
); /* ASM name */
4841 OutputXDEF(0, "%s_", name
); /* C++ name no parameters */
4842 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4844 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4846 if(CopyCPPType((strptr
)tempbuf
, i
, cd
, ap
->Args
))
4847 OutputXDEF(0, "%s__%s", name
, tempbuf
);
4853 EndPutM32(tempbuf
, 0);
4854 DoOutputDirect(tempbuf
, 4);
4855 if(!(Flags
& FLAG_NOSYMBOL
))
4857 EndPutM32(tempbuf
, HUNK_SYMBOL
);
4858 DoOutputDirect(tempbuf
, 4);
4859 OutputSYMBOL(0, "_%s", name
); /* C name */
4861 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4863 struct ClibData
*cd
;
4864 OutputSYMBOL(0, "%s", name
); /* ASM name */
4869 OutputSYMBOL(0, "%s_", name
); /* C++ name no parameters */
4870 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4872 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4874 if(CopyCPPType((strptr
) data
, i
, cd
, ap
->Args
))
4875 OutputSYMBOL(0, "%s__%s", name
, (strptr
) data
);
4881 EndPutM32(tempbuf
, 0);
4882 DoOutputDirect(tempbuf
, 4);
4885 EndPutM32(tempbuf
, HUNK_END
);
4886 return DoOutputDirect(tempbuf
, 4);
4889 /* Directly called by FuncInline and FuncInlineDirect also! */
4890 uint32
FuncCSTUBS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4892 struct ClibData
*f
, *t
;
4893 strptr ret
= "return ";
4896 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4899 Flags
|= FLAG_DONE
; /* We did something */
4901 if(!(f
= GetClibFunc(ap
->FuncName
, ap
, 0)))
4903 t
= GetClibFunc(name
, ap
, flags
);
4905 if(flags
& FUNCFLAG_EXTENDMODE
)
4907 sprintf(tempbuf
, "___%s", name
);
4911 if(IsCPPType(&f
->ReturnType
, CPP_TYPE_VOID
))
4914 if(!OutClibType(&f
->ReturnType
, name
) || !DoOutput("("/*)*/))
4916 if(flags
& FUNCFLAG_EXTENDMODE
)
4918 DoOutput("%s %s, ", GetBaseType(), BaseName
);
4921 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4923 if(!OutClibType(&f
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4926 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4928 if(!OutClibType(&t
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4931 else if(ap
->NumArgs
== 1 && !DoOutput("ULONG tag, "))
4934 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret
, ap
->FuncName
))
4936 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4938 if(!DoOutput("%s, ", ap
->Args
[i
].ArgName
))
4941 if(!DoOutput("("/*)*/) || !OutClibType(&f
->Args
[ap
->NumArgs
-1],0))
4944 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4946 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap
->Args
[ap
->NumArgs
-1].ArgName
))
4949 else if(ap
->NumArgs
== 1)
4951 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4954 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4955 ap
->Args
[ap
->NumArgs
-2].ArgName
) || !OutClibType(&f
->Args
[ap
->NumArgs
-2],0)
4956 || !DoOutput(/*(((*/")));\n}\n\n"))
4961 uint32
FuncLVOXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4963 Flags
|= FLAG_DONE
; /* We did something */
4964 return DoOutput("\t\tXDEF\t_LVO%s\n", name
);
4967 uint32
FuncLVO(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4969 Flags
|= FLAG_DONE
; /* We did something */
4970 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name
, ap
->Bias
);
4973 uint32
FuncLVOPPCXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4975 Flags
|= FLAG_DONE
; /* We did something */
4976 return DoOutput("\t.globl\t%sLVO%s\n", Flags
& FLAG_ABIV4
? "" : "_", name
);
4979 uint32
FuncLVOPPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4981 Flags
|= FLAG_DONE
; /* We did something */
4982 return DoOutput(".set\t%sLVO%s,-%d\n", Flags
& FLAG_ABIV4
? "" : "_", name
,
4986 uint32
FuncLVOPPCBias(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4988 Flags
|= FLAG_DONE
; /* We did something */
4990 EndPutM32Inc(elfbufpos
, symoffset
); /* st_name */
4991 symoffset
+= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1) + 1;
4992 EndPutM32Inc(elfbufpos
, -ap
->Bias
); /* st_value */
4993 EndPutM32Inc(elfbufpos
, 0); /* st_size */
4994 *(elfbufpos
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* st_info */
4995 *(elfbufpos
++) = 0; /* st_other */
4996 EndPutM16Inc(elfbufpos
, SHN_ABS
); /* st_shndx */
5001 uint32
FuncLVOPPCName(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5003 Flags
|= FLAG_DONE
; /* We did something */
5004 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5005 return DoOutputDirect("", 1);
5008 uint32
FuncLVOLib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5012 Flags
|= FLAG_DONE
; /* We did something */
5013 j
= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1);
5014 EndPutM32(tempbuf
, (EXT_ABS
<< 24) + ((j
+3)>>2));
5016 DoOutputDirect(tempbuf
, 4);
5017 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5018 DoOutputDirect("\0\0\0", ((j
+3)&(~3))-j
);
5019 EndPutM32(tempbuf
, -ap
->Bias
);
5020 return DoOutputDirect(tempbuf
, 4);
5023 uint32
FuncLocCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5025 strptr str2
= Flags
& FLAG_LOCALREG
? "rE" : "";
5028 struct ClibData
*cd
= 0;
5030 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
5033 Flags
|= FLAG_DONE
; /* We did something */
5035 i
= strlen(name
) + 2;
5036 EndPutM32(tempbuf
, HUNK_UNIT
);
5037 EndPutM32(tempbuf
+4, (i
+3)>>2);
5038 DoOutputDirect(tempbuf
, 8);
5039 DoOutput("%s.o", name
);
5040 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5042 i
= strlen(hunkname
);
5043 EndPutM32(tempbuf
, HUNK_NAME
);
5044 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
5045 DoOutputDirect(tempbuf
, 8);
5046 DoOutputDirect(hunkname
, i
);
5047 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5049 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
5051 if(Flags
& FLAG_LOCALREG
)
5053 if((flags
& FUNCFLAG_TAG
))
5055 i
= ap
->Args
[ap
->NumArgs
-1].ArgReg
;
5056 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE <ea>,-(A7) */
5060 EndPutM16Inc(data
, 0x41EF | ((i
-8) << 9)); /* LEA 8(A7),Ax */
5061 EndPutM16Inc(data
, 8);
5065 EndPutM16Inc(data
, 0x200F | (i
<< 9)); /* MOVE.L A7,Dx */
5066 EndPutM16Inc(data
, 0x5080 | i
); /* ADDQ.L #8,Dx */
5069 EndPutM16Inc(data
, 0x4EAE);
5070 EndPutM16Inc(data
, -ap
->Bias
); /* JSR instruction */
5072 /* MOVE (A7)+,<ea> */
5073 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5074 EndPutM16Inc(data
, 0x4E75); /* RTS */
5078 EndPutM16Inc(data
, 0x4EEE);
5079 EndPutM16Inc(data
, -ap
->Bias
); /* JMP instruction */
5084 uint32 registers
, offset
= 1;
5086 registers
= GetRegisterData(ap
);
5088 if(!registers
) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5090 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
5091 ++offset
; /* one long more on stack */
5095 if(Flags
& FLAG_NOMOVEM
)
5097 for(i
= 0; i
<= 15; ++i
)
5099 if(registers
& (1<< (16+i
)))
5101 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
5108 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
5109 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
5110 for(i
= registers
&0xFFFF; i
; i
>>= 1)
5113 ++offset
; /* get offset addition */
5118 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
)) /* store library base in A6 */
5120 EndPutM16Inc(data
, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5121 EndPutM16Inc(data
, (offset
++) << 2);
5124 data
= AsmStackCopy(data
, ap
, flags
, offset
);
5126 /* here comes the base reference */
5127 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
5128 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
5131 if(Flags
& FLAG_NOMOVEM
)
5133 for(i
= 15; i
>= 0; --i
)
5135 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
5136 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5141 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5142 EndPutM16Inc(data
, registers
>> 16); /* store MOVEM.L registers */
5146 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
5148 EndPutM16Inc(data
, 0x4E75); /* RTS */
5151 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
5153 EndPutM32(tempbuf
, HUNK_CODE
);
5154 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
5155 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
5157 EndPutM32(tempbuf
, HUNK_EXT
);
5158 DoOutputDirect(tempbuf
,4);
5160 /* here come the XDEF name references */
5162 if(!(Flags
& FLAG_ONLYCNAMES
))
5164 OutputXDEF(0, "%s", name
); /* ASM names */
5165 OutputXDEF(0, "LOC_%s", name
);
5168 OutputXDEF(0, "_%s", name
); /* C names */
5169 OutputXDEF(0, "_LOC_%s", name
);
5171 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5175 /* C++ names no parameters */
5176 OutputXDEF(0, "%s__%sP07Library", name
, str2
);
5177 OutputXDEF(0, "LOC_%s__%sP07Library", name
, str2
);
5179 else if((cd
= GetClibFunc(name
, ap
, flags
)))
5183 txt
= (strptr
) tempbuf
;
5185 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5187 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5188 { /* C++ names with parameters */
5189 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5191 OutputXDEF(0, "%s__%sP07Library%s", name
, str2
, txt
);
5192 OutputXDEF(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5196 OutputXDEF(0, "%s__%s", name
, txt
);
5197 OutputXDEF(0, "LOC_%s__%s", name
, txt
);
5204 EndPutM32(tempbuf
, 0);
5205 DoOutputDirect(tempbuf
,4);
5206 if(!(Flags
& FLAG_NOSYMBOL
))
5208 EndPutM32(tempbuf
, HUNK_SYMBOL
);
5209 DoOutputDirect(tempbuf
,4);
5210 if(!(Flags
& FLAG_ONLYCNAMES
))
5212 OutputSYMBOL(0, "%s", name
); /* ASM names */
5213 OutputSYMBOL(0, "LOC_%s", name
);
5216 OutputSYMBOL(0, "_%s", name
); /* C names */
5217 OutputSYMBOL(0, "_LOC_%s", name
);
5219 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5223 /* C++ names no parameters */
5224 OutputSYMBOL(0, "%s__%sP07Library", name
, str2
);
5225 OutputSYMBOL(0, "LOC_%s__%sP07Library", name
, str2
);
5231 txt
= (strptr
) tempbuf
;
5233 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5235 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5236 { /* C++ names with parameters */
5237 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5239 OutputSYMBOL(0, "%s__%sP07Library%s", name
, str2
, txt
);
5240 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5244 OutputSYMBOL(0, "%s__%s", name
, txt
);
5245 OutputSYMBOL(0, "LOC_%s__%s", name
, txt
);
5252 EndPutM32(tempbuf
, 0);
5253 DoOutputDirect(tempbuf
,4);
5255 EndPutM32(tempbuf
, HUNK_END
);
5256 return DoOutputDirect(tempbuf
,4);
5259 uint32
FuncLocText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5261 struct ClibData
*cd
;
5264 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5267 Flags
|= FLAG_DONE
; /* We did something */
5269 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
5272 OutClibType(&cd
->ReturnType
, 0);
5273 DoOutput(" LOC_%s("/*)*/, name
);
5274 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5276 if(Flags
& FLAG_LOCALREG
)
5277 DoOutput("register __a6 ");
5278 DoOutput("%s libbase", GetBaseType());
5285 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
5287 if(((Flags
& FLAG_LOCALREG
&&
5288 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5289 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
5293 if(flags
& FUNCFLAG_NORMAL
)
5295 if(((Flags
& FLAG_LOCALREG
&&
5296 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5297 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) ||
5298 !DoOutput(/*(*/");\n"))
5302 DoOutput("#define %s("/*)*/, name
);
5303 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5304 DoOutput("%c, ", 'a'+(char)i
);
5305 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i
, name
, BaseName
);
5306 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5307 DoOutput("%c, ",'a'+(char)i
);
5308 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i
);
5312 return DoOutput(/*(*/"...);\n");
5315 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5318 return DoOutput(/*(*/");\n");
5322 uint32
FuncInlineDirect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5324 uint32 a4
= 0, a5
= 0;
5326 int32 i
, maxargs
, reg
=0;
5327 struct ClibData
*cd
;
5329 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
|AMIPRAGFLAG_VARARGS
))
5332 Flags
|= FLAG_DONE
; /* We did something */
5334 if(flags
& FUNCFLAG_ALIAS
)
5336 if(flags
& FUNCFLAG_TAG
)
5337 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5340 DoOutput("#define %s("/*)*/, name
);
5341 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5342 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5343 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5344 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5345 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5346 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5349 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5352 if(flags
& FUNCFLAG_TAG
)
5354 /* do not create some strange functions */
5355 if(IsNoCreateInlineFunc(name
))
5356 DoOutput("#if !defined(NO_INLINE_STDARG) "
5357 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5359 DoOutput("#ifndef NO_INLINE_STDARG\n");
5360 DoOutput("static __inline__ ");
5361 FuncCSTUBS(ap
, flags
|FUNCFLAG_EXTENDMODE
, name
);
5363 DoOutput("#define %s("/*)*/, name
);
5364 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5366 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5370 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name
, ShortBaseNameUpper
);
5371 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5372 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5375 DoOutput(/*(*/")\n");
5376 return DoOutput("#endif\n\n");
5379 DoOutput("#define %s("/*)*/, name
);
5382 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5383 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5384 DoOutput("%s", ap
->Args
[i
].ArgName
);
5386 DoOutput(/*(*/") ({ \\\n"/*})*/);
5388 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5390 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5392 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5393 DoOutput(" = (%s); \\\n", ap
->Args
[i
].ArgName
);
5396 if(Flags
& FLAG_INLINENEW
)
5399 DoOutput(" ({ \\\n"/*})*/);
5400 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name
);
5402 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper
);
5405 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
5407 if(i
== ap
->NumArgs
)
5409 DoOutput("(%s);\\\n", ap
->Args
[i
].ArgName
);
5412 DoOutput(" (("/*))*/);
5413 OutClibType(&cd
->ReturnType
, 0);
5414 DoOutput(" (*)("/*)*/);
5417 DoOutput("char * __asm(\"a6\")");
5421 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5423 OutClibType(&cd
->Args
[i
], 0);
5424 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
5425 if(i
< ap
->NumArgs
-1)
5428 DoOutput(/*((*/")) \\\n");
5429 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name
, ap
->Bias
);
5432 DoOutput("_%s__bn", name
);
5436 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5438 if(ap
->Args
[i
].ArgReg
== REG_A6
)
5439 DoOutput("_%s__bn", name
);
5441 DoOutput("_%s_%s", name
, ap
->Args
[i
].ArgName
);
5442 if(i
< ap
->NumArgs
-1)
5445 DoOutput(/*(*/"); \\\n");
5447 DoOutput(/*({*/"});");
5451 /* do A5 first, as it is more important */
5452 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5454 a5
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5455 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5456 a5
|= 1<<ap
->Args
[i
].ArgReg
;
5460 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A5
]);
5465 for(i
= 0; (a5
& 1) && a5
; ++i
)
5467 a5
= i
; /* this is our A5 swap register */
5470 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5472 a4
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5475 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5476 a4
|= 1<<ap
->Args
[i
].ArgReg
;
5480 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A4
]);
5485 for(i
= 0; (a4
& 1) && a4
; ++i
)
5487 a4
= i
; /* this is our A4 swap register */
5490 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5491 noret
= 1; /* this is a void function */
5493 if(ap
->NumArgs
|| !noret
)
5494 DoOutput(" %s{ \\\n", noret
? "" : "(" /*})*/);
5497 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5499 " register int _d1 __asm(\"d1\"); \\\n"
5500 " register int _a0 __asm(\"a0\"); \\\n"
5501 " register int _a1 __asm(\"a1\"); \\\n");
5504 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5505 GetBaseType(), name
, ShortBaseNameUpper
);
5509 sprintf((strptr
)tempbuf
, "__%s__re", name
);
5510 DoOutput(" register ");
5511 OutClibType(&cd
->ReturnType
, (strptr
) tempbuf
);
5512 DoOutput(" __asm(\"d0\"); \\\n");
5514 if((maxargs
= ap
->NumArgs
) >= 9 && (Flags
& FLAG_STORMGCC
))
5516 for(i
= 0; i
< maxargs
; ++i
)
5518 reg
= ap
->Args
[i
].ArgReg
;
5519 if(a5
&& reg
== REG_A5
) reg
= a5
; /* we need to switch */
5520 if(a4
&& reg
== REG_A4
) reg
= a4
; /* we need to switch */
5522 sprintf((strptr
)tempbuf
, "__%s_%s", name
, ap
->Args
[i
].ArgName
);
5523 DoOutput(" register ");
5524 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5525 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames
[reg
],
5526 (strptr
) (tempbuf
+1));
5528 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5530 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name
);
5531 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5533 DoOutput(" ULONG __%s_%s; \\\n", name
, ap
->Args
[i
].ArgName
);
5534 reg
= ap
->Args
[i
].ArgReg
;
5539 else if(reg
== REG_A5
)
5544 /* reg is now either the last register argument or its a4/a5 redirect */
5545 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name
);
5546 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5548 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5549 DoOutput("(ULONG)(%s)%s", (strptr
)tempbuf
, i
== ap
->NumArgs
-1 ?
5552 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5553 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name
, name
,
5554 RegNames
[reg
], name
);
5556 DoOutput(" __asm volatile (\""/*)*/);
5557 if(a5
) DoOutput("exg a5,%s\\n\\t", RegNames
[a5
]);
5558 if(a4
) DoOutput("exg a4,%s\\n\\t", RegNames
[a4
]);
5559 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5561 DoOutput("movem.l ");
5562 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5564 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5565 i
== ap
->NumArgs
-1 ? "" : "/");
5567 DoOutput(",-(a7)\\n\\t");
5568 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5571 DoOutput("move.l (%s),%s\\n\\t", RegNames
[reg
],
5572 RegNames
[ap
->Args
[i
].ArgReg
]);
5574 DoOutput("move.l %ld(%s),%s\\n\\t", (i
-maxargs
)*4, RegNames
[reg
],
5575 RegNames
[ap
->Args
[i
].ArgReg
]);
5578 DoOutput("jsr a6@(-%d:W)", ap
->Bias
);
5579 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5581 DoOutput("\\n\\tmovem.l (a7)+,");
5582 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5584 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5585 i
== ap
->NumArgs
-1 ? "" : "/");
5588 if(a4
) DoOutput("\\n\\texg a4,%s", RegNames
[a4
]);
5589 if(a5
) DoOutput("\\n\\texg a5,%s", RegNames
[a5
]);
5590 DoOutput("\" \\\n");
5593 DoOutput(" : \"=r\" (_d0)");
5595 DoOutput(" : \"=r\"(__%s__re)", name
);
5596 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5598 DoOutput(" \"r\"(__%s__bn)%s", name
, ap
->NumArgs
? "," : "");
5599 for(i
= 0; i
< maxargs
; ++i
)
5601 DoOutput(" \"rf\"(__%s_%s)", name
, ap
->Args
[i
].ArgName
);
5602 if(i
< ap
->NumArgs
-1)
5605 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5606 DoOutput(" \"r\"(__%s__ArgsPtr)", name
);
5607 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5609 if(ap
->NumArgs
|| !noret
)
5610 DoOutput(/*({*/" }%s \\\n", noret
? "" : ");");
5613 return DoOutput(/*({*/"})\n\n");
5616 uint32
FuncInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5618 uint32 noret
= 0, a45
= 0, j
;
5620 struct ClibData
*cd
;
5622 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5625 if(!(Flags
& FLAG_INLINENEW
) && CheckError(ap
, AMIPRAGFLAG_MOSBASESYSV
))
5628 Flags
|= FLAG_DONE
; /* We did something */
5630 if(flags
& FUNCFLAG_ALIAS
)
5632 if(flags
& FUNCFLAG_TAG
)
5633 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5634 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
5636 DoOutput("#define %s("/*)*/, name
);
5637 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5638 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5639 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5640 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5641 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5642 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5645 if(!(cd
= GetClibFunc(ap
->Flags
& AMIPRAGFLAG_VARARGS
?
5646 ap
->TagName
: ap
->FuncName
, ap
, flags
)))
5649 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5650 noret
= 1; /* this is a void function */
5652 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5654 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5658 DoError(ERR_INLINE_A4_AND_A5
, ap
->Line
);
5659 return 1; /* skip this entry */
5663 if(a45
&& (ap
->Flags
& AMIPRAGFLAG_D7USE
))
5665 DoError(ERR_INLINE_D7_AND_A45
, ap
->Line
);
5666 return 1; /* skip this entry */
5669 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
5671 if(Flags
& FLAG_INLINENEW
)
5673 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5674 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "");
5675 if(IsNoCreateInlineFunc(name
))
5677 DoOutput("__inline ");
5678 FuncCSTUBS(ap
, flags
, name
);
5679 /* call CSTUBS, as this equals the method used there */
5683 DoOutput("#define %s("/*)*/, name
);
5684 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5686 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5688 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5690 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5691 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5693 OutClibType(&cd
->Args
[i
], 0);
5694 DoOutput(/*({((*/") _tags);})\n");
5696 return DoOutput("#endif\n\n");
5698 else if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5699 == (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5701 int32 n
, d
, tagl
, local
;
5705 tagl
= 8 + (Flags2
& FLAG2_DIRECTVARARGS
? 0 : 64);
5706 local
= (n
* 4+d
+8+15) & ~15; /* size of the stack frame */
5709 * 0- 3: next frame ptr
5712 * 72-72+n*4+d+8-1: tag list start
5713 * ?-local-1: padding
5716 DoOutput("asm(\"\n"/*)*/
5719 "\t.type\t%s,@function\n"
5721 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5723 "\tstw\t0,%ld(1)\n",
5724 name
, name
, name
, local
, local
+4);
5726 /* If n is odd, one tag is split between regs and stack.
5727 * Copy its ti_Data together with the ti_Tag. */
5729 DoOutput("\tlwz\t0,%ld(1)\n", local
+8); /* read ti_Data */
5731 /* Save the registers */
5732 for(i
= ap
->NumArgs
; i
<= 8; ++i
)
5733 DoOutput("\tstw\t%ld,%ld(1)\n", i
+2, (i
-ap
->NumArgs
) * 4+tagl
);
5736 DoOutput("\tstw\t0,%ld(1)\n", tagl
+n
* 4); /* write ti_Data */
5739 DoOutput("\tli\t0,2\n"
5740 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5742 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5743 tagl
+n
* 4+d
, local
+8+d
, tagl
+n
* 4+d
+4);
5745 if(Flags2
& FLAG2_DIRECTVARARGS
)
5747 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5748 "\tbl\t%s\n", ap
->NumArgs
+2, tagl
, name
);
5755 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
5758 /* Caos.Offset = -fD_GetOffset(obj) */
5759 DoOutput("\tli\t0,%d\n"
5760 "\tstw\t0,8(1)\n", -ap
->Bias
);
5762 /* Save the non-varargs registers in the Caos struct. */
5763 for(i
=0; i
< ap
->NumArgs
-1; ++i
)
5765 DoOutput("\tstw\t%ld,%d(1)\n", i
+3, 8+4+(ap
->Args
[i
].ArgReg
* 4));
5768 DoOutput("\taddi\t0,1,%ld\n"
5770 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5771 "\tlwz\t12,%s@l(3)\n"
5773 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5776 "\tbctrl\n", /* EmulCallOS() */
5777 tagl
, BaseName
, 12+(4 * ap
->Args
[i
].ArgReg
), BaseName
);
5779 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5783 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local
+4, local
, name
, name
);
5787 DoOutput("%s%s__inline ", Flags
& FLAG_INLINESTUB
? "" : "extern ",
5788 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5789 return FuncCSTUBS(ap
, flags
, name
);
5790 /* call CSTUBS, as this equals the method used there */
5794 if(Flags
& FLAG_INLINENEW
) /* new style */
5796 strptr funcpar
= "";
5797 DoOutput("#define %s("/*)*/, name
);
5799 for(i
= 0; i
< cd
->NumArgs
; ++i
)
5801 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5807 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5808 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5809 DoOutput("%s", ap
->Args
[i
].ArgName
);
5811 DoOutput(/*(*/") \\\n\t");
5812 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
5814 DoOutput("((("/*)))*/);
5815 OutClibType(&cd
->ReturnType
, 0);
5816 DoOutput(" (*)("/*)*/);
5817 DoOutput("%s", GetBaseType());
5818 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5821 OutClibType(&cd
->Args
[i
], 0);
5823 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5824 "(%s_BASE_NAME",/*)*/
5825 ShortBaseNameUpper
, ap
->Bias
-2, ShortBaseNameUpper
);
5827 for(i
= 0; i
< ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0); ++i
)
5828 DoOutput(", %s", ap
->Args
[i
].ArgName
);
5829 if(flags
& FUNCFLAG_TAG
)
5830 DoOutput(", __VA_ARGS__");
5831 return DoOutput(/*((*/"))\n\n");
5833 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap
->NumArgs
,
5834 (noret
? "NR" : ""), (a45
? RegNamesUpper
[a45
] : (strptr
) ""),
5835 (BaseName
? "" : "UB"), funcpar
, ap
->Bias
);
5838 OutClibType(&cd
->ReturnType
, 0);
5841 DoOutput("%s, ", name
);
5843 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5845 j
= ap
->Args
[i
].ArgReg
;
5846 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5848 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5852 DoError(ERR_MULTIPLEFUNCTION
, ap
->Line
);
5857 DoOutput("__fpt"); fp
= i
;
5861 OutClibType(&cd
->Args
[i
], 0);
5863 DoOutput(", %s, %s%s", ap
->Args
[i
].ArgName
, RegNames
[j
],
5864 (i
== ap
->NumArgs
-1 && !BaseName
? "" : ", "));
5867 if(BaseName
) /* was "##base" used? */
5868 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper
);
5873 OutClibType(&cd
->Args
[fp
], "__fpt");
5876 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
5877 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5879 return DoOutput(/*(*/")\n\n");
5882 /* old mode or stubs mode */
5884 if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
)) != (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5885 DoOutput("%s%s__inline ", Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
) ?
5886 "" : "extern ", Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5887 OutClibType(&cd
->ReturnType
, 0);
5888 DoOutput("\n%s(%s"/*)*/, name
, (BaseName
?
5889 (ap
->NumArgs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5891 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5893 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5894 if(i
< ap
->NumArgs
-1)
5898 if(Flags
& FLAG_POWERUP
)
5900 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5901 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5902 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5903 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5904 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5905 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5906 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5910 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5912 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5913 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5917 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5920 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper
);
5921 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5922 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5925 DoOutput("\treturn(("/*))*/);
5926 OutClibType(&cd
->ReturnType
, 0);
5927 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5929 return Output_Error
;
5931 else if(Flags
& FLAG_MORPHOS
)
5933 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5937 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5939 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5940 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5944 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5946 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5947 ShortBaseNameUpper
);
5949 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5950 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5953 DoOutput("\treturn(("/*))*/);
5954 OutClibType(&cd
->ReturnType
, 0);
5955 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5957 return Output_Error
;
5960 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName
? " BASE_EXT_DECL\n" : ""));
5964 DoOutput(" register ");
5965 OutClibType(&cd
->ReturnType
, "res");
5966 DoOutput(" __asm(\"d0\");\n");
5970 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5971 GetBaseType(), ShortBaseNameUpper
);
5973 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5975 j
= ap
->Args
[i
].ArgReg
;
5976 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5979 DoOutput(" register ");
5980 OutClibType(&cd
->Args
[i
], RegNames
[j
]);
5981 DoOutput(" __asm(\"%s\") = %s;\n", RegNames
[j
], ap
->Args
[i
].ArgName
);
5986 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
5987 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames
[a45
],
5988 ap
->Bias
, RegNames
[a45
]);
5991 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap
->Bias
);
5993 DoOutput(noret
? " : /* No Output */\n" : " : \"=r\" (res)\n");
5997 DoOutput("\"r\" (a6)%s", (ap
->NumArgs
? ", ": ""));
5999 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6001 j
= ap
->Args
[i
].ArgReg
;
6002 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
6005 DoOutput("\"r\" (%s)%s", RegNames
[j
], (i
< ap
->NumArgs
-1 ? ", " : ""));
6008 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6011 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6013 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6017 /* new style inlines designed by Bernardo Innocenti */
6018 uint32
FuncInlineNS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6021 struct ClibData
*cd
;
6023 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6026 Flags
|= FLAG_DONE
; /* We did something */
6028 if(flags
& FUNCFLAG_ALIAS
)
6030 if(flags
& FUNCFLAG_TAG
)
6031 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6034 DoOutput("#define %s("/*)*/, name
);
6035 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6036 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6037 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6038 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6039 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6040 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6043 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6046 if((flags
& FUNCFLAG_TAG
))
6048 if(!(Flags2
& FLAG2_INLINEMAC
))
6050 DoOutput("static __inline ");
6051 return FuncCSTUBS(ap
, flags
, name
);
6052 /* call CSTUBS, as this equals the method used there */
6056 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6057 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
6058 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6059 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6060 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6062 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6063 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6065 OutClibType(&cd
->Args
[i
], 0);
6066 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6070 if(Flags2
& FLAG2_INLINEMAC
)
6072 DoOutput("#define %s("/*)*/, name
);
6073 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6075 DoOutput("%s", ap
->Args
[i
].ArgName
);
6076 if(i
< ap
->NumArgs
-1)
6079 DoOutput(/*(*/") \\\n\t");
6083 DoOutput("static __inline ");
6084 OutClibType(&cd
->ReturnType
, 0);
6085 DoOutput(" %s("/*)*/, name
);
6086 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6088 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6089 if(i
< ap
->NumArgs
-1)
6092 DoOutput(/*(*/")\n{\n "/*}*/);
6093 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6094 DoOutput("return ");
6096 DoOutput("(("/*))*/);
6097 OutClibType(&cd
->ReturnType
, 0);
6098 DoOutput(" (*)("/*)*/);
6099 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6101 OutClibType(&cd
->Args
[i
], 0);
6102 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
6103 if(i
< ap
->NumArgs
-1)
6110 DoOutput("%s __asm(\"a6\")", GetBaseType());
6112 DoOutput(/*((*/"))");
6113 if(Flags2
& FLAG2_INLINEMAC
)
6116 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6117 ShortBaseNameUpper
, ap
->Bias
);
6120 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
6122 if(i
== ap
->NumArgs
)
6124 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap
->Args
[i
].ArgName
,
6127 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6129 DoOutput("%s", ap
->Args
[i
].ArgName
);
6130 if(i
< ap
->NumArgs
-1)
6137 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
6140 if(Flags2
& FLAG2_INLINEMAC
)
6141 DoOutput(/*(*/")\n");
6143 DoOutput(/*{(*/");\n}\n");
6145 return DoOutput("\n");
6148 uint32
FuncPowerUP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6151 struct ClibData
*cd
;
6153 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6156 Flags
|= FLAG_DONE
; /* We did something */
6158 if(flags
& FUNCFLAG_ALIAS
)
6160 if(flags
& FUNCFLAG_TAG
)
6161 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6164 DoOutput("#define %s("/*)*/, name
);
6165 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6166 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6167 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6168 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6169 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6170 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6173 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6176 if(flags
& FUNCFLAG_TAG
)
6178 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name
);
6179 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6180 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6181 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6183 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6184 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6186 OutClibType(&cd
->Args
[i
], 0);
6187 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6190 DoOutput("#define\t%s("/*)*/, name
);
6195 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6196 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6197 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap
->Args
[i
].ArgName
, name
);
6200 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper
);
6202 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6203 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6204 DoOutput(/*(*/"%s)\n\n", ap
->Args
[i
].ArgName
);
6207 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name
, ShortBaseNameUpper
);
6209 DoOutput(/*(*/")\t_%s()\n\n", name
);
6211 DoOutput("static __inline ");
6212 OutClibType(&cd
->ReturnType
, 0);
6214 DoOutput("\n_%s("/*)*/, name
);
6216 DoOutput("void * %s%s", BaseName
, ap
->NumArgs
? ", " : "");
6218 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6220 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6221 if(i
< ap
->NumArgs
-1)
6225 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6226 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6227 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6228 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6229 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6230 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6231 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6235 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6237 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6238 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
6242 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
6245 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName
);
6246 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6247 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6250 DoOutput("\treturn(("/*))*/);
6251 OutClibType(&cd
->ReturnType
, 0);
6252 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6254 return Output_Error
;
6257 uint32
FuncFPCUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6260 struct ClibData
*cd
;
6262 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6264 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6267 if(!FuncFPCType(ap
, flags
, name
))
6270 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6272 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6273 DoOutput("\tMOVE%s.L\t%s,%s\n", ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "",
6274 ap
->Args
[i
].ArgName
, RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
6277 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName
);
6278 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap
->Bias
);
6280 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6282 if(!cd
->ReturnType
.PointerDepth
&&
6283 cd
->ReturnType
.Flags
== CPP_FLAG_BOOLEAN
)
6284 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6285 " @end:\tMOVE.B\tD0,@RESULT\n");
6287 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6289 return DoOutput(" END;\nEND;\n\n");
6292 uint32
FuncFPCType(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6296 struct ClibData
*cd
;
6298 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6300 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6303 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6305 ret
= 0; DoOutput("PROCEDURE %s", name
);
6308 DoOutput("FUNCTION %s", name
);
6313 for(i
= 0; i
< ap
->NumArgs
;)
6315 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6316 if(++i
!= ap
->NumArgs
)
6323 OutPASCALType(&cd
->ReturnType
, "", 1);
6325 Flags
|= FLAG_DONE
; /* We did something */
6327 return DoOutput(";\n");
6330 uint32
FuncFPCTypeTags(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6334 struct ClibData
*cd
;
6336 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6338 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6341 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6343 ret
= 0; DoOutput("PROCEDURE %s", name
);
6346 DoOutput("FUNCTION %s", name
);
6351 for(i
= 0; i
< ap
->NumArgs
-1;)
6353 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6354 if(++i
!= ap
->NumArgs
)
6357 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6362 OutPASCALType(&cd
->ReturnType
, "", 1);
6364 Flags
|= FLAG_DONE
; /* We did something */
6366 return DoOutput(";\n");
6369 uint32
FuncFPCTypeTagsUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6373 struct ClibData
*cd
;
6375 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6377 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6380 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6382 ret
= 0; DoOutput("PROCEDURE %s", name
);
6385 DoOutput("FUNCTION %s", name
);
6390 for(i
= 0; i
< ap
->NumArgs
-1;)
6392 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6393 if(++i
!= ap
->NumArgs
)
6396 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6401 OutPASCALType(&cd
->ReturnType
, "", 1);
6403 DoOutput(";\nbegin\n");
6406 DoOutput(" %s := %s",name
, ap
->FuncName
);
6407 else DoOutput(" %s", ap
->FuncName
);
6412 for(i
= 0; i
< ap
->NumArgs
-1;)
6414 DoOutput("%s ", ap
->Args
[i
].ArgName
);
6415 if(++i
!= ap
->NumArgs
)
6418 DoOutput("readintags(%s)",ap
->Args
[i
].ArgName
);
6419 DoOutput(/*(*/");");
6424 Flags
|= FLAG_DONE
; /* We did something */
6426 return DoOutput(";\n\n");
6430 uint32
FuncBMAP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6434 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_A5USE
6438 Flags
|= FLAG_DONE
; /* We did something */
6440 for(i
= 0; BMAPSpecial
[i
]; ++i
)
6442 if(!stricmp(name
, BMAPSpecial
[i
]))
6444 DoOutput("x"); break;
6448 DoOutput("%s",name
);
6449 reg
= 0; DoOutputDirect(®
, 1);
6450 reg
= (-ap
->Bias
)>>8; DoOutputDirect(®
, 1);
6451 reg
= -ap
->Bias
; DoOutputDirect(®
, 1);
6452 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6454 reg
= 1+ap
->Args
[i
].ArgReg
; DoOutputDirect(®
, 1);
6457 return DoOutputDirect(®
, 1);
6460 uint32
FuncVBCCInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6462 struct ClibData
*cd
;
6466 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6469 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6472 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
6473 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
6475 Flags
|= FLAG_DONE
; /* We did something */
6477 if(flags
& FUNCFLAG_TAG
)
6479 if(IsNoCreateInlineFunc(name
))
6480 return 1; /* do not create some strange functions */
6481 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6482 "(__STDC_VERSION__ >= 199901L)\n");
6485 if(flags
& FUNCFLAG_ALIAS
)
6487 DoOutput("#define %s("/*)*/, name
);
6488 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6489 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6490 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6491 if(Flags2
& FLAG2_OLDVBCC
)
6493 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6494 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6495 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6500 DoOutput("%s", BaseName
);
6501 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6502 DoOutput(", (%s)", ap
->Args
[i
].ArgName
);
6503 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
?
6508 OutClibType(&cd
->ReturnType
, 0);
6509 DoOutput(" __%s("/*)*/, name
);
6511 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6513 DoOutput("__reg(\"a6\") %s", GetBaseType());
6518 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6519 for(i
= 0; i
< k
; ++i
)
6521 DoOutput("__reg(\"%s\") ", RegNames
[ap
->Args
[i
].ArgReg
]);
6522 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6523 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6525 DoOutput("void * %s", ap
->Args
[i
].ArgName
);
6528 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6529 if(i
< ap
->NumArgs
-1)
6533 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6537 DoOutput("__reg(\"a6\") %s", GetBaseType());
6540 if(flags
& FUNCFLAG_TAG
)
6542 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6544 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6547 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6548 RegNames
[ap
->Args
[k
].ArgReg
]);
6550 if(ap
->Args
[k
].ArgReg
> 7)
6551 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1
, c2
,
6552 RegNames
[ap
->Args
[k
].ArgReg
]);
6554 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6555 RegNames
[ap
->Args
[k
].ArgReg
], RegNames
[ap
->Args
[k
].ArgReg
]);
6557 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6558 "\\tmove%s.l\\t(a7)+,%s\";\n", c1
, ap
->Bias
, c2
,
6559 ap
->Args
[k
].ArgReg
>= REG_A0
? "a" : "", RegNames
[ap
->Args
[k
].ArgReg
]);
6562 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1
, ap
->Bias
, c2
);
6564 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6565 DoOutput("#define %s("/*)*/, name
);
6566 for(i
= 0; i
< k
; ++i
)
6568 DoOutput("%s", ap
->Args
[i
].ArgName
);
6569 if(i
< ap
->NumArgs
-1)
6572 if(flags
& FUNCFLAG_TAG
)
6574 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6575 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6578 DoOutput(/*(*/") __%s("/*)*/, name
);
6579 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6581 DoOutput("%s", BaseName
);
6585 for(i
= 0; i
< k
; ++i
)
6587 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6588 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6590 DoOutput("(void *)");
6592 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6593 if(i
< ap
->NumArgs
-1)
6596 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6600 DoOutput("%s", BaseName
);
6602 if(flags
& FUNCFLAG_TAG
)
6604 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6605 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6606 DoOutput("__VA_ARGS__");
6609 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6612 uint32
FuncVBCCWOSInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6614 struct ClibData
*cd
;
6617 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_M68K
))
6620 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6623 Flags
|= FLAG_DONE
; /* We did something */
6625 if(flags
& FUNCFLAG_TAG
)
6627 if(IsNoCreateInlineFunc(name
))
6628 return 1; /* do not create some strange functions */
6629 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6630 "(__STDC_VERSION__ >= 199901L)\n");
6633 if(flags
& FUNCFLAG_ALIAS
)
6635 DoOutput("#define %s("/*)*/, name
);
6636 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6637 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6638 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6639 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6640 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6641 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6645 OutClibType(&cd
->ReturnType
, 0);
6646 DoOutput(" __%s("/*)*/, name
);
6648 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6650 DoOutput("%s", GetBaseType());
6656 for(i
= 0; i
< k
; ++i
)
6658 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6662 if(flags
& FUNCFLAG_TAG
)
6663 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6665 DoOutput(/*(*/")=\"");
6666 if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6668 DoOutput("\\t.extern\\t_%s\\n", BaseName
);
6669 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6671 /* save tag1 and load taglist-pointer */
6672 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6673 "\\taddi\\t%s%d,%s1,%d\\n",
6674 PPCRegPrefix
, (int)k
+2, 20+(int)k
*4, PPCRegPrefix
, PPCRegPrefix
,
6675 (int)k
+2, PPCRegPrefix
, 20+(int)k
*4);
6677 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6678 "\\tlwz\\t%s0,-%d(%s11)\\n"
6681 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
,
6682 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6684 else if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6686 /* @@@ tagcall handling? */
6687 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6688 "\\t.extern\\t_%s\\n"
6689 "\\tlwz\\t%s2,_%s(%s2)\\n"
6690 "\\tlwz\\t%s0,-%d(%s2)\\n"
6693 "\\tlwz\\t%s2,20(%s1)",
6694 PPCRegPrefix
, PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
,
6695 PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
6696 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6700 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6702 /* save tag1 and load taglist-pointer */
6703 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6704 "\\taddi\\t%s%d,%s1,%d\\n",
6705 PPCRegPrefix
, (int)k
+3, 24+(int)k
*4, PPCRegPrefix
, PPCRegPrefix
,
6706 (int)k
+3, PPCRegPrefix
, 24+(int)k
*4);
6708 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6711 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6715 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6716 DoOutput("#define %s("/*)*/, name
);
6717 for(i
= 0; i
< k
; ++i
)
6719 DoOutput("%s", ap
->Args
[i
].ArgName
);
6720 if(i
< ap
->NumArgs
-1)
6723 if(flags
& FUNCFLAG_TAG
)
6725 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6726 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6729 DoOutput(/*(*/") __%s("/*)*/, name
);
6730 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6732 DoOutput("%s", BaseName
);
6736 for(i
= 0; i
< k
; ++i
)
6738 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6739 if(i
< ap
->NumArgs
-1)
6742 if(flags
& FUNCFLAG_TAG
)
6744 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6745 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6746 DoOutput("__VA_ARGS__");
6749 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6752 uint32
FuncVBCCMorphInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6754 struct ClibData
*cd
;
6757 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6760 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6763 Flags
|= FLAG_DONE
; /* We did something */
6765 if(flags
& FUNCFLAG_TAG
)
6767 if(IsNoCreateInlineFunc(name
))
6768 return 1; /* do not create some strange functions */
6769 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6770 "(__STDC_VERSION__ >= 199901L)\n");
6773 if(flags
& FUNCFLAG_ALIAS
)
6775 DoOutput("#define %s("/*)*/, name
);
6776 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6777 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6778 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6779 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6780 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6781 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6785 OutClibType(&cd
->ReturnType
, 0);
6786 if((flags
& FUNCFLAG_TAG
) && (Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6787 DoOutput(" __linearvarargs");
6789 DoOutput(" __%s("/*)*/, name
);
6791 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6793 DoOutput("%s", GetBaseType());
6798 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6800 if((flags
& FUNCFLAG_TAG
) &&
6801 !(ap
->Flags
& AMIPRAGFLAG_MOS_ALL
))
6803 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6808 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6809 for(i
= 0; i
< k
; ++i
)
6811 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6812 if(i
< ap
->NumArgs
-1)
6816 if(flags
& FUNCFLAG_TAG
)
6818 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6820 if((ap
->Flags
& AMIPRAGFLAG_MOS_ALL
)
6821 && !(ap
->Flags
& AMIPRAGFLAG_VARARGS
))
6823 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6826 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6828 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6836 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
6838 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6839 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6840 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6842 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6843 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6845 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6846 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6848 else if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
6852 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6853 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6854 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6855 PPCRegPrefix
, BaseName
,
6856 PPCRegPrefix
, BaseName
, PPCRegPrefix
,
6857 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6859 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6861 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6862 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6864 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6865 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6869 int ofs
= 4, fix
= 0;
6870 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6871 PPCRegPrefix
, PPCRegPrefix
);
6875 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix
, k
++,
6878 if(Flags2
& FLAG2_SHORTPPCVBCCINLINE
)
6881 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6884 else if(flags
& FUNCFLAG_TAG
)
6886 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6890 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix
);
6891 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6893 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
6896 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix
, k
++);
6898 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6899 PPCRegPrefix
, 8+(k
++-11)*4, PPCRegPrefix
, PPCRegPrefix
);
6903 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6904 PPCRegPrefix
, ofs
, PPCRegPrefix
, (2+k
+fix
-11)*4, PPCRegPrefix
, ofs
);
6906 DoOutput("%d(%s2)\\n\"\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6908 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix
,
6912 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6913 DoOutput("#define %s("/*)*/, name
);
6914 for(i
= 0; i
< k
; ++i
)
6916 DoOutput("%s", ap
->Args
[i
].ArgName
);
6917 if(i
< ap
->NumArgs
-1)
6920 if(flags
& FUNCFLAG_TAG
)
6922 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6923 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6926 DoOutput(/*(*/") __%s("/*)*/, name
);
6927 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6929 DoOutput("%s", BaseName
);
6933 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6935 if(flags
& FUNCFLAG_TAG
&& !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
6937 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6941 for(i
= 0; i
< k
; ++i
)
6943 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6944 if(i
< ap
->NumArgs
-1)
6947 if(flags
& FUNCFLAG_TAG
)
6949 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6950 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6951 DoOutput("__VA_ARGS__");
6954 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6957 uint32
FuncVBCCWOSText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6959 uint32 i
, k
, count
, ofs
;
6960 struct ClibData
*cd
= 0;
6962 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
6965 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
6966 !(cd
= GetClibFunc(name
, ap
, flags
)))
6969 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
6970 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
6971 !(Flags
& FLAG_WOSLIBBASE
)))
6973 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
6979 if(Flags
& FLAG_SINGLEFILE
)
6981 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
6986 DoOutputDirect(HEADER
, headersize
);
6990 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
6991 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
6993 if(Flags
& FLAG_SINGLEFILE
)
6994 DoOutput("\t.file\t\"%s.o\"\n", name
);
6995 DoOutput("\t.align\t3\n");
6996 if(Flags
& FLAG_WOSLIBBASE
) /* PPCBase already in r3, LibBase in r4 */
6998 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
6999 DoOutput("\t.extern _%s\n", BaseName
);
7000 DoOutput("\t.global __%s\n__%s:\n", name
, name
);
7005 DoOutput("\t.extern _%s\n", BaseName
);
7006 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7007 DoOutput("\t.extern _PowerPCBase\n");
7008 DoOutput("\t.global _%s\n_%s:\n", name
, name
);
7011 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7013 DoOutput("\tstw\t%s2,20(%s1)\n"
7015 "\tstw\t%s0,16(%s1)\n"
7016 "\tlwz\t%s2,_%s(%s2)\n"
7017 "\tlwz\t%s0,-%d(%s2)\n"
7020 "\tlwz\t%s0,16(%s1)\n"
7021 "\tlwz\t%s2,20(%s1)\n"
7024 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7025 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2,
7026 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7027 PPCRegPrefix
, PPCRegPrefix
);
7029 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7031 DoOutput("\tmflr\t%s0\n", PPCRegPrefix
);
7032 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7034 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7035 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7036 PPCRegPrefix
, (int)ap
->NumArgs
+2,
7037 20+(int)ap
->NumArgs
*4, PPCRegPrefix
, PPCRegPrefix
,
7038 (int)ap
->NumArgs
+2, PPCRegPrefix
, 20+(int)ap
->NumArgs
*4);
7040 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7041 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7042 "\tlwz\t%s11,_%s(%s2)\n"
7043 "\tlwz\t%s0,-%d(%s11)\n"
7046 "\tlwz\t%s0,40(%s1)\n"
7047 "\taddi\t%s1,%s1,32\n"
7050 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7051 BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
7052 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7055 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7057 count
= ap
->NumArgs
;
7058 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7060 /* init stack frame */
7061 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7062 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7063 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7067 /* extra arguments must be passed on the stack */
7068 k
= 32-(count
-8); /* firstreg */
7070 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7071 PPCRegPrefix
, k
, 56+(count
-8)*4, PPCRegPrefix
, PPCRegPrefix
, k
,
7072 i
+56, PPCRegPrefix
);
7073 if(flags
& FUNCFLAG_TAG
)
7074 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7076 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7078 else if(flags
& FUNCFLAG_TAG
)
7080 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7081 PPCRegPrefix
, i
+20+count
*4);
7085 else /* Args must be shifted! */
7087 /* init stack frame */
7088 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7089 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7090 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7094 /* extra arguments must be passed on the stack */
7097 /* special case: move 8th argument into stack frame */
7098 if(flags
& FUNCFLAG_TAG
)
7099 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7101 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7105 k
= 32-(count
-7); /* firstreg */
7107 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7108 "\tmr\t%s%ld,%s10\n"
7109 "\tlmw\t%s%ld,%ld(%s1)\n",
7110 PPCRegPrefix
, k
, 56+(count
-7)*4, PPCRegPrefix
,
7111 PPCRegPrefix
, k
, PPCRegPrefix
, PPCRegPrefix
, k
+1,
7112 i
+56, PPCRegPrefix
);
7113 if(flags
& FUNCFLAG_TAG
)
7114 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
,
7115 PPCRegPrefix
, i
+20+count
*4);
7116 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7119 else if(flags
& FUNCFLAG_TAG
)
7121 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7122 PPCRegPrefix
, i
+20+count
*4);
7126 /* shift all arguments into their following register */
7127 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7128 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix
, 3+k
, PPCRegPrefix
, 2+k
);
7130 /* load library base and LVO, then call LVO via LR */
7131 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7135 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix
,
7136 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
7138 /* cleanup stack frame and return */
7141 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7142 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, 32-(count
-k
),
7143 56+(count
-k
)*4, PPCRegPrefix
);
7146 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7147 PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7151 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7152 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7154 /* clear PP_Flags, PP_Stack and PP_StackSize */
7155 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7156 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7157 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7159 if(Flags
& FLAG_WOSLIBBASE
)
7160 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7161 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix
, ap
->Bias
, PPCRegPrefix
,
7162 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7164 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix
,
7165 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
);
7167 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7168 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7169 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
,
7170 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7173 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7174 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7175 for(i
= 0; i
< k
; ++i
)
7179 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7180 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7182 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3+ofs
);
7186 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix
, (i
+1+ofs
)*4+196,
7188 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7189 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7190 DoOutput("\tstw\t%s11,", PPCRegPrefix
);
7192 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7194 if(flags
& FUNCFLAG_TAG
)
7196 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7197 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7198 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7199 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix
,
7200 PPCRegPrefix
, 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7201 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7204 if(!(Flags
& FLAG_WOSLIBBASE
))
7205 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
7207 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7208 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7209 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7210 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7211 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7214 if(Flags
& FLAG_WOSLIBBASE
)
7215 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7218 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7222 uint32
FuncVBCCWOSCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7224 uint32 i
, j
, k
, ofs
, count
;
7225 uint8
*data
, *basepos
= 0, *pbasepos
= 0;
7226 struct ClibData
*cd
= 0;
7228 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
7231 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
7232 !(cd
= GetClibFunc(name
, ap
, flags
)))
7235 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
7236 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
7237 !(Flags
& FLAG_WOSLIBBASE
)))
7239 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
7243 Flags
|= FLAG_DONE
; /* We did something */
7245 i
= strlen(name
) + 2;
7246 EndPutM32(tempbuf
, HUNK_UNIT
);
7247 EndPutM32(tempbuf
+4, (i
+3)>>2);
7248 DoOutputDirect(tempbuf
, 8);
7249 DoOutput("%s.o", name
);
7250 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7252 i
= strlen(hunkname
);
7253 EndPutM32(tempbuf
, HUNK_NAME
);
7254 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
7255 DoOutputDirect(tempbuf
, 8);
7256 DoOutputDirect(hunkname
, i
);
7257 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7259 data
= tempbuf
+8; /* we need HUNK_PPC_CODE + size at start */
7261 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7263 EndPutM32Inc(data
, 0x90410014); /* stw r2,20(r1) */
7264 /* mflr r0 = mfspr r0,8 = get link register */
7265 EndPutM32Inc(data
, 0x7C0802A6);
7266 EndPutM32Inc(data
, 0x90010010); /* stw r0,16(r1) */
7268 EndPutM32Inc(data
, 0x80420000); /* lwz r2,BaseName(r2) */
7269 EndPutM32Inc(data
, 0x80030000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r2) */
7270 /* mtlr r0 = mtspr 8,r0 = restore link register */
7271 EndPutM32Inc(data
, 0x7C0803A6);
7272 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7273 EndPutM32Inc(data
, 0x80010010); /* lwz r0,16(r1) */
7274 EndPutM32Inc(data
, 0x80410014); /* lwz r2,20(r1) */
7275 /* mtlr r0 = mtspr 8,r0 = restore link register */
7276 EndPutM32Inc(data
, 0x7C0803A6);
7277 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7279 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7282 /* mflr r0 = mfspr r0,8 = get link register */
7283 EndPutM32Inc(data
, 0x7C0802A6);
7284 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7286 EndPutM32Inc(data
, 0x90010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7287 (uint32
)(20+ap
->NumArgs
*4)); /* stw rN,d(r1) */
7288 EndPutM32Inc(data
, 0x38010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7289 (uint32
)(20+ap
->NumArgs
*4)); /* addi rN,r1,d */
7291 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7292 EndPutM32Inc(data
, 0x9421FFCE); /* stwu r1,-32(r1) */
7293 EndPutM32Inc(data
, 0x81620000); /* lwz r11,BaseName(r2) */
7294 EndPutM32Inc(data
, 0x800C0000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r11) */
7295 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7296 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7297 EndPutM32Inc(data
, 0x80010028); /* lwz r0,40(r1) */
7298 EndPutM32Inc(data
, 0x38210020); /* addi r1,r1,32 */
7299 /* mtlr r0 = mtspr 8,r0 = restore link register */
7300 EndPutM32Inc(data
, 0x7C0803A6);
7301 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7303 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7305 count
= ap
->NumArgs
;
7306 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7308 /* init stack frame */
7309 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7310 /* mflr r0 = mfspr r0,8 = get link register */
7311 EndPutM32Inc(data
, 0x7C0802A6);
7312 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7313 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7317 /* extra arguments must be passed on the stack */
7318 k
= 32-(count
-8); /* firstreg */
7320 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-8)*4));
7321 EndPutM32Inc(data
, 0xB8010000 + (k
<< 21) + (i
+56)); /* lmw rk,Y(r1) */
7322 if(flags
& FUNCFLAG_TAG
)
7323 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4)); /* addi r31,r1,X */
7324 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7326 else if(flags
& FUNCFLAG_TAG
)
7329 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7333 else /* Args must be shifted! */
7335 /* init stack frame */
7336 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7337 /* mflr r0 = mfspr r0,8 = get link register */
7338 EndPutM32Inc(data
, 0x7C0802A6);
7339 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7340 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7344 /* extra arguments must be passed on the stack */
7347 /* special case: move 8th argument into stack frame */
7348 if(flags
& FUNCFLAG_TAG
)
7349 EndPutM32Inc(data
, 0x39410000 + (i
+20+count
*4)); /* addi r10,r1,X */
7350 EndPutM32Inc(data
, 0x91410038); /* stw r10,56(r1) */
7354 k
= 32-(count
-7); /* firstreg */
7357 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-7)*4));
7358 /* mr rk,r10 = or rk,r10,r10 */
7359 EndPutM32Inc(data
, 0x7D405378 + (k
<<16));
7361 EndPutM32Inc(data
, 0xB8010000 + ((k
+1) << 21) + (i
+56));
7362 if(flags
& FUNCFLAG_TAG
)
7365 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4));
7367 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7370 else if(flags
& FUNCFLAG_TAG
)
7373 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7377 /* shift all arguments into their following register */
7378 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7379 EndPutM32Inc(data
, 0x7C000378 + ((3+k
)<<16) + ((2+k
)<<21) + ((2+k
)<<11)); /* mr rX,rY = or rX,rY,rY */
7381 /* load library base and LVO, then call LVO via LR */
7383 EndPutM32Inc(data
, 0x80620000); /* lwz r3,BaseName(r2) */
7386 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7387 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7388 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7391 /* cleanup stack frame and return */
7394 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7395 EndPutM32Inc(data
, 0xB8010000 + ((32-(count
-k
))<<21) + (56+(count
-k
)*4)); /* lmw rX,Y(r1) */
7397 EndPutM32Inc(data
, 0x38210000 + i
); /* addi r1,r1,i */
7398 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) */
7399 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7400 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7404 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7405 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7406 EndPutM32Inc(data
, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7408 EndPutM32Inc(data
, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7409 EndPutM32Inc(data
, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7410 EndPutM32Inc(data
, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7411 EndPutM32Inc(data
, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7413 if(Flags
& FLAG_WOSLIBBASE
)
7415 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7416 EndPutM32Inc(data
, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7417 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7418 EndPutM32Inc(data
, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7422 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7423 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7428 EndPutM32Inc(data
, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7429 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7430 EndPutM32Inc(data
, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7431 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7432 EndPutM32Inc(data
, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7435 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7436 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7437 for(i
= 0; i
< k
; ++i
)
7439 j
= 0x34+4*ap
->Args
[i
].ArgReg
; /* PP_Regs offset */
7442 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7443 EndPutM32Inc(data
, 0x90010020 + ((i
+3+ofs
)<<21)); /* stw rX,0x20(r1) */
7444 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7448 EndPutM32Inc(data
, 0x81610000 + ((i
+1+ofs
)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7449 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7450 EndPutM32Inc(data
, 0x91610020); /* stw r11,0x20(r1) */
7451 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7454 if(flags
& FUNCFLAG_TAG
)
7456 j
= (ap
->NumArgs
+ofs
)*4+0xC4;
7458 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7459 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7460 EndPutM32Inc(data
, 0x39610000 + j
); /* addi r11,r1,j */
7461 EndPutM32Inc(data
, 0x91610000 + (0x34+4*ap
->Args
[i
].ArgReg
)); /* stw r11,X(r1) */
7464 if(!(Flags
& FLAG_WOSLIBBASE
))
7466 pbasepos
= data
; /* store 16BIT reloc offset */
7467 EndPutM32Inc(data
, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7469 EndPutM32Inc(data
, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7470 EndPutM32Inc(data
, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7471 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7472 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7473 EndPutM32Inc(data
, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7474 EndPutM32Inc(data
, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7475 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) = get old link register */
7476 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7477 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump back */
7480 EndPutM32(tempbuf
, HUNK_PPC_CODE
);
7481 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
7482 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
7484 EndPutM32(tempbuf
, HUNK_EXT
);
7485 DoOutputDirect(tempbuf
,4);
7487 /* here come the XDEF name references */
7489 if(Flags
& FLAG_WOSLIBBASE
)
7491 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
7492 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7493 OutputXDEF(0, "__%s", name
);
7498 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7499 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7500 OutputXREF((pbasepos
-tempbuf
-8)+2, EXT_DEXT16
, "_PowerPCBase");
7501 OutputXDEF(0, "_%s", name
);
7503 EndPutM32(tempbuf
, 0);
7504 DoOutputDirect(tempbuf
,4);
7505 if(!(Flags
& FLAG_NOSYMBOL
))
7507 EndPutM32(tempbuf
, HUNK_SYMBOL
);
7508 DoOutputDirect(tempbuf
,4);
7509 if(Flags
& FLAG_WOSLIBBASE
)
7510 OutputSYMBOL(0, "__%s", name
);
7512 OutputSYMBOL(0, "_%s", name
);
7513 EndPutM32(tempbuf
, 0);
7514 DoOutputDirect(tempbuf
,4);
7516 EndPutM32(tempbuf
, HUNK_END
);
7518 return DoOutputDirect(tempbuf
,4);
7521 uint32
FuncVBCCPUPText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7525 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7530 if(Flags
& FLAG_SINGLEFILE
)
7532 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7537 DoOutputDirect(HEADER
, headersize
);
7541 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7542 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7544 if(Flags
& FLAG_SINGLEFILE
)
7545 DoOutput("\t.file\t\"%s.o\"\n", name
);
7547 DoOutput("\t.global %s\n", BaseName
);
7548 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7549 "\t.align\t3\n%s:\n",name
, name
);
7551 if(flags
& FUNCFLAG_TAG
)
7553 /* Hack the stack-frame for varargs.
7554 Build stack-frame, but save LR in our own stack-frame,
7555 because we have to overwrite the lower 8 bytes of the
7557 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7558 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7560 /* Save the caller's saved SP in our own stack-frame. */
7561 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix
,
7562 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7564 /* Store r3-r8 at the top of our stack-frame and r9-r10
7565 at the low 8 bytes of the caller's frame. This way all
7566 arguments will reside in one continuous area. */
7567 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7568 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
, 104+4*(i
-3),
7572 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7573 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7575 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7577 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7580 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
7582 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
7583 100+(i
+1-8)*4, PPCRegPrefix
, PPCRegPrefix
);
7586 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix
,
7587 PPCRegPrefix
, 100+ap
->NumArgs
*4, PPCRegPrefix
);
7588 DoOutput("%d(%s1)\n", 36+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7591 /* Now place the real function call */
7592 /* store offset in Chaos->caos_Un.Offset */
7593 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7594 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix
,
7595 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7596 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7597 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7601 if(Flags
& FLAG_SMALLDATA
)
7602 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix
, BaseName
,
7605 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix
,
7606 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7607 /* store basepointer in A6 */
7608 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7611 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix
, PPCRegPrefix
);
7612 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7613 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7614 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7615 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7616 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7618 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7619 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7621 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name
,
7625 uint32
FuncVBCCPUPCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7627 int32 i
, j
=0, k
, size
;
7628 uint8
*data
, *data2
, *data3
;
7629 struct ArHeader
*arh
;
7633 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7638 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7639 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7640 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7641 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7642 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
7643 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
7644 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
7645 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7646 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7647 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7648 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
7649 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
7650 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
7651 EndPutM32Inc(data
, 0); /* eeh->e_entry */
7652 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
7653 data2
= data
; data
+= 4;
7654 EndPutM32Inc(data
, 0); /* eeh->e_flags */
7655 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
7656 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
7657 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
7658 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
7659 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
7660 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
7663 if(flags
& FUNCFLAG_TAG
)
7665 /* Hack the stack-frame for varargs.
7666 Build stack-frame, but save LR in our own stack-frame,
7667 because we have to overwrite the lower 8 bytes of the
7669 EndPutM32Inc(data
, 0x9421FF80); /* stwu r1,-128(r1) */
7670 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7671 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7673 /* Save the caller's saved SP in our own stack-frame. */
7674 EndPutM32Inc(data
, 0x81610080); /* lwz r11,128(r1) */
7675 EndPutM32Inc(data
, 0x91610060); /* stw r11,96(r1) */
7677 /* Store r3-r8 at the top of our stack-frame and r9-r10
7678 at the low 8 bytes of the caller's frame. This way all
7679 arguments will reside in one continuous area. */
7680 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7681 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (104+4*(i
-3))); /* stw rX,Y(r1) */
7685 EndPutM32Inc(data
, 0x9421FFA0); /* stwu r1,-96(r1) */
7686 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7687 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7690 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7692 j
= 36+4*ap
->Args
[i
].ArgReg
;
7693 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7697 EndPutM32Inc(data
, 0x90010000 + ((i
+3)<<21) + j
); /* stw rX,j(r1) */
7701 EndPutM32Inc(data
, 0x81610000 + (100+(i
+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7702 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7707 EndPutM32Inc(data
, 0x39610000 + (100+ap
->NumArgs
*4)); /* addi r11,r1,X */
7708 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,X(r1) */
7712 /* Now place the real function call */
7713 EndPutM32Inc(data
, 0x39610000 - ap
->Bias
); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7714 EndPutM32Inc(data
, 0x91610008); /* stw r11,8(r1) */
7715 EndPutM32Inc(data
, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7716 EndPutM32Inc(data
, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7717 EndPutM32Inc(data
, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7721 if(Flags
& FLAG_SMALLDATA
)
7723 j
= (data
-data3
)+2; /* store reloc offset */
7724 EndPutM32Inc(data
, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7728 j
= (data
-data3
)+2; /* store reloc offset */
7729 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7730 EndPutM32Inc(data
, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7732 EndPutM32Inc(data
, 0x9161005C); /* stw r11,92(r1) */
7735 EndPutM32Inc(data
, 0x38610008); /* addi r3,r1,8 */
7736 k
= (data
-data3
); /* store reloc offset */
7737 EndPutM32Inc(data
, 0x48000001); /* bl PPCCallOS */
7738 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7740 EndPutM32Inc(data
, 0x81610060); /* lwz r11,96(r1) */
7741 EndPutM32Inc(data
, 0x91610080); /* stw r11,128(r1) */
7742 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7743 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7744 EndPutM32Inc(data
, 0x38210080); /* addi r1,r1,128 */
7748 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7749 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7750 EndPutM32Inc(data
, 0x38210060); /* addi r1,r1,96 */
7753 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
7755 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7756 data
+= 44; /* 1 9 17 27 33 */
7758 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
7761 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
7762 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
7763 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7764 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7765 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
7766 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
7767 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7768 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7769 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
7770 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7773 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
7774 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
7775 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
7776 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
7777 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
7778 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
7779 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
7780 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
7781 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
7782 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
7785 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
7786 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
7787 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
7788 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
7789 data
+= 4; /* esh[2].sh_offset */
7790 data
+= 4; /* esh[2].sh_size */
7791 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7792 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
7793 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
7794 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7796 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
7797 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
7798 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
7799 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
7800 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
7801 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
7802 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
7803 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
7804 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
7805 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
7807 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
7808 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
7809 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
7810 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
7811 data
+= 4; /* esh[4].sh_offset */
7812 data
+= 4; /* esh[4].sh_size */
7813 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
7814 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7815 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
7816 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7818 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
7819 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
7820 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7821 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7822 data
+= 4; /* esh[0].sh_offset */
7823 data
+= 4; /* esh[0].sh_size */
7824 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7825 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7826 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
7827 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7829 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
7830 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 6*16 : 5*16); /* esh[4].sh_size */
7833 data
+= BaseName
? 6*16 : 5*16;
7835 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
7838 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
7839 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
7840 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
7841 *(data2
++) = 0; /* esym[0].st_info */
7842 *(data2
++) = 0; /* esym[0].st_other */
7843 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
7847 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
7848 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
7849 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
7850 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
7851 *(data2
++) = 0; /* esym[1].st_other */
7852 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
7854 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
]) { i
++;} ; /* get next store space */
7855 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
7856 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
7857 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
7858 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
7859 *(data2
++) = 0; /* esym[2].st_other */
7860 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
7862 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
7863 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
7864 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
7865 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
7866 *(data2
++) = 0; /* esym[3].st_other */
7867 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
7869 sprintf((strptr
)data
+i
, "%s", name
); while(data
[i
]) { i
++;} ; /* get next store space */
7870 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
7871 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
7872 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
7873 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
7874 *(data2
++) = 0; /* esym[4].st_other */
7875 EndPutM16Inc(data2
, 0); /* esym[4].st_shndx */
7877 sprintf((strptr
)data
+i
, "PPCCallOS"); while(data
[i
]) { i
++;} ; /* get next store space */
7880 EndPutM32Inc(data2
, i
); /* esym[5].st_name */
7881 EndPutM32Inc(data2
, 0); /* esym[5].st_value */
7882 EndPutM32Inc(data2
, 0); /* esym[5].st_size */
7883 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[5].st_info */
7884 *(data2
++) = 0; /* esym[5].st_other */
7885 EndPutM16
/*Inc*/(data2
, 0); /* esym[5].st_shndx */
7887 sprintf((strptr
)data
+i
, "%s", BaseName
); while(data
[i
]) { i
++;} ; /* get next store space */
7889 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
7890 while(i
&3) /* long aligned */
7894 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
7898 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7899 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_REL24
)); /* erel[0].r_info - entry 4, type 10 */
7900 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7904 if(Flags
& FLAG_SMALLDATA
)
7906 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7907 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_SDAREL16
)); /* erel[1].r_info - entry 5, type 32 */
7908 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7912 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7913 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_HA
)); /* erel[1].r_info - entry 5, type 6 */
7914 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7915 EndPutM32Inc(data
, j
+4); /* erel[2].r_offset */
7916 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_LO
)); /* erel[2].r_info - entry 5, type 4 */
7917 EndPutM32Inc(data
, 0); /* erel[2].r_addend */
7920 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
7922 /* make ar header and store all */
7923 arh
= (struct ArHeader
*) (data
+20);
7924 memset(arh
, ' ', sizeof(struct ArHeader
));
7926 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
7927 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
7928 arh
->ar_mode
[2] = '0';
7929 arh
->ar_mode
[0] = '6';
7930 arh
->ar_fmag
[0] = 96;
7931 arh
->ar_fmag
[1] = '\n';
7933 if((k
= strlen(name
) + 2) >= 16)
7935 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
7940 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
7943 j
= k
+ (data
-tempbuf
);
7944 for(i
= 9; j
; --i
) /* make decimal number */
7946 data
[i
] = (j
%10)+'0';
7949 for(j
= 0; i
< 9; ++j
)
7950 arh
->ar_size
[j
] = data
[++i
];
7952 DoOutputDirect(arh
, sizeof(struct ArHeader
));
7956 DoOutput("%s.o", name
);
7958 *(data
++) = 0x0A; /* alignment byte! */
7961 return DoOutputDirect(tempbuf
, data
-tempbuf
);
7964 uint32
FuncVBCCMorphText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7966 int32 i
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
7968 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7973 if(Flags
& FLAG_SINGLEFILE
)
7975 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7980 DoOutputDirect(HEADER
, headersize
);
7984 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7985 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7987 if(Flags
& FLAG_SINGLEFILE
)
7988 DoOutput("\t.file\t\"%s.o\"\n", name
);
7990 DoOutput("\t.global %s\n", BaseName
);
7991 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name
, name
);
7993 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
7995 if(Flags
& FLAG_SMALLDATA
)
7996 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
7997 PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7999 DoOutput("\tlis\t%s11,%s@ha\n"
8000 "\tlwz\t%s12,%s@l(%s11)\n",
8001 PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
8003 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
8004 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8009 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8011 if(flags
& FUNCFLAG_TAG
)
8015 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8016 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8017 "\tstw\t%s0,4(%s1)\n"
8018 "\tsub\t%s11,%s1,%s12\n"
8019 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8020 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8021 "\tsrwi\t%s12,%s12,2\n"
8022 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8023 "\taddi\t%s12,%s1,4\n"
8024 "\tmr\t%s1,%s11\n" /* new stack frame */
8025 "\taddi\t%s11,%s11,8\n"
8028 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8029 "\tstwu\t%s0,4(%s11)\n"
8030 "\tbdnz\t.copyloop_%s\n"
8031 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8032 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8033 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8034 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8035 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8036 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8037 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8038 PPCRegPrefix
, PPCRegPrefix
, name
,
8039 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8040 name
, PPCRegPrefix
, PPCRegPrefix
);
8042 else if(ap
->NumArgs
>= 8)
8044 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8047 "\tstwu\t%s1,-%ld(%s1)\n"
8048 "\tstw\t%s0,%ld(%s1)\n",
8049 PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
,
8050 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8054 else if(flags
& FUNCFLAG_TAG
)
8056 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8057 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8059 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8060 || ap
->NumArgs
>= 8))
8062 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8064 PPCRegPrefix
, stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
);
8069 /* Hack the stack-frame for varargs.
8070 Build stack-frame, but save LR in our own stack-frame,
8071 because we have to overwrite the lower 8 bytes of the
8073 /* Save the caller's saved SP in our own stack-frame. */
8074 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix
,
8075 stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
);
8077 /* Store r3-r8 at the top of our stack-frame and r9-r10
8078 at the low 8 bytes of the caller's frame. This way all
8079 arguments will reside in one continuous area.
8080 Only copy the really relevant parts. */
8081 for(i
= 10; i
> 10-nrcopyar
; --i
)
8082 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
,
8083 stcksize
+4*(i
-1+nrcopyar
-8),PPCRegPrefix
);
8086 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8088 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8090 for(i
= ap
->NumArgs
-1; i
; --i
)
8094 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, 3+i
, PPCRegPrefix
,
8099 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
8103 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8104 PPCRegPrefix
, stcksize
+((i
-8)+3)*4, PPCRegPrefix
, PPCRegPrefix
,
8105 ((i
-8)+3)*4, PPCRegPrefix
);
8111 /* shift all the arguments one field */
8112 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8114 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, i
, PPCRegPrefix
, i
-1);
8119 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8120 || ap
->NumArgs
>= 8))
8121 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8125 if(Flags
& FLAG_SMALLDATA
)
8126 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix
, basereg
,
8127 BaseName
, PPCRegPrefix
);
8129 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8130 PPCRegPrefix
, basereg
, BaseName
, PPCRegPrefix
, basereg
, BaseName
,
8131 PPCRegPrefix
, basereg
);
8134 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8136 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8137 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8141 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8143 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8146 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
8148 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
8149 stcksize
+(i
+2-8)*4, PPCRegPrefix
, PPCRegPrefix
);
8152 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix
,
8153 PPCRegPrefix
, stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0),
8155 DoOutput("%d(%s2)\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
8158 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8159 PPCRegPrefix
, PPCRegPrefix
);
8161 /* store basepointer in A6 */
8163 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
8165 /* Now place the real function call */
8166 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8167 PPCRegPrefix
, ap
->Bias
);
8169 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix
);
8172 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8174 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8175 PPCRegPrefix
, stcksize
, PPCRegPrefix
, PPCRegPrefix
,
8176 stcksize
+nrcopyar
*4,PPCRegPrefix
);
8179 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8180 || ap
->NumArgs
>= 8))
8182 if(ap
->NumArgs
>= 8)
8185 "\tlwz\t%s0,%ld(%s1)\n"
8186 "\taddi\t%s1,%s1,%ld\n"
8188 PPCRegPrefix
,stcksize
+4,PPCRegPrefix
,PPCRegPrefix
,PPCRegPrefix
,
8189 stcksize
,PPCRegPrefix
);
8194 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8195 "\tlwz\t%s0,4(%s1)\n"
8196 "\tmtlr\t%s0\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8197 PPCRegPrefix
, PPCRegPrefix
);
8202 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8203 "\taddi\t%s1,%s1,%ld\n"
8205 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8206 stcksize
+nrcopyar
*4, PPCRegPrefix
);
8209 DoOutput("\tblr\n");
8212 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8216 uint32
FuncVBCCMorphCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8218 int32 i
, j
, k
=0, size
, nrcopyar
= 0, stcksize
= 16;
8219 int basereg
__attribute__ ((unused
)) = 12;
8220 uint8
*data
, *data2
, *data3
;
8221 struct ArHeader
*arh
;
8225 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
8230 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8231 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8232 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8233 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8234 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
8235 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
8236 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
8237 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8238 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8239 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8240 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
8241 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
8242 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
8243 EndPutM32Inc(data
, 0); /* eeh->e_entry */
8244 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
8245 data2
= data
; data
+= 4;
8246 EndPutM32Inc(data
, 0); /* eeh->e_flags */
8247 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
8248 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
8249 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
8250 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
8251 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
8252 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
8256 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
8258 if(Flags
& FLAG_SMALLDATA
)
8260 k
= (data
-data3
)+2; /* store reloc offset */
8261 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8265 k
= (data
-data3
)+2; /* store reloc offset */
8266 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8267 EndPutM32Inc(data
, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8270 EndPutM32Inc(data
, 0x800c0000 - (ap
->Bias
-2));
8271 EndPutM32Inc(data
, 0x7c0903a6); /* mtctr r0 */
8272 EndPutM32Inc(data
, 0x4e800420); /* bctr */
8277 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8279 if(flags
& FUNCFLAG_TAG
)
8281 /* mflr r0 = mfspr r0,8 = get link register */
8282 EndPutM32Inc(data
, 0x7C0802A6);
8283 /* backchain to next frame: lwz r11,0(r1) */
8284 EndPutM32Inc(data
, 0x81610000);
8285 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8286 EndPutM32Inc(data
, 0x7D815850);
8287 EndPutM32Inc(data
, 0x90010004); /* stw r0,4(r1) */
8288 EndPutM32Inc(data
, 0x7D6C0850); /* sub r11,r1,r12 */
8289 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8290 EndPutM32Inc(data
, 0x396BFFF0);
8291 EndPutM32Inc(data
, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8292 EndPutM32Inc(data
, 0x558CF0BE); /* srwi r12,r12,2 */
8293 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8294 EndPutM32Inc(data
, 0x380CFFFE);
8295 EndPutM32Inc(data
, 0x39810004); /* addi r12,r1,4 */
8296 EndPutM32Inc(data
, 0x7D615B78); /* mr r1,r11 - new stack frame */
8297 EndPutM32Inc(data
, 0x396B0008); /* addi r11,r11,8 */
8298 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8299 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8300 EndPutM32Inc(data
, 0x840C0004);
8301 EndPutM32Inc(data
, 0x940B0004); /* stwu r0,4(r11) */
8302 EndPutM32Inc(data
, 0x4200FFF8); /* bdnz .l */
8303 /* stw r10,8(r1) - last register into stack */
8304 EndPutM32Inc(data
, 0x91410008);
8306 else if(ap
->NumArgs
>= 8)
8308 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8309 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 */
8310 EndPutM32Inc(data
, 0x94220000 - stcksize
); /* stwu r1,-X(r1) */
8311 EndPutM32Inc(data
, 0x90010000 + stcksize
+ 4); /* stw r0,Y(r1) */
8315 else if(flags
& FUNCFLAG_TAG
)
8317 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8318 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8321 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8322 || ap
->NumArgs
>= 8))
8324 EndPutM32Inc(data
, 0x94210000+0x10000-(stcksize
+nrcopyar
*4)); /* stwu r1,-%d(r1) */
8325 /* mflr r0 = mfspr r0,8 = get link register */
8326 EndPutM32Inc(data
, 0x7C0802A6);
8331 /* Hack the stack-frame for varargs.
8332 Build stack-frame, but save LR in our own stack-frame,
8333 because we have to overwrite the lower 8 bytes of the
8335 /* Save the caller's saved SP in our own stack-frame. */
8336 EndPutM32Inc(data
, 0x81610000+stcksize
+nrcopyar
*4); /* lwz r11,%d(r1) */
8337 EndPutM32Inc(data
, 0x91610000+stcksize
); /* stw r11,%d(r1) */
8339 /* Store r3-r8 at the top of our stack-frame and r9-r10
8340 at the low 8 bytes of the caller's frame. This way all
8341 arguments will reside in one continuous area.
8342 Only copy the really relevant parts. */
8343 for(i
= 10; i
> 10-nrcopyar
; --i
)
8344 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (stcksize
+4*(i
-1+nrcopyar
-8))); /* stw rX,Y(r1) */
8347 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8349 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8351 for(i
= ap
->NumArgs
-1; i
; --i
)
8356 EndPutM32Inc(data
, 0x7C000378 + ((3+i
)<<21) + ((3+i
-1)<<16) + ((3+i
-1)<<11));
8361 EndPutM32Inc(data
, 0x91410008);
8366 EndPutM32Inc(data
, 0x81610000 + (stcksize
+((i
-8)+3)*4));
8367 EndPutM32Inc(data
, 0x91620000 + ((i
-8)+3)*4); /* stw r11,j(r1) */
8373 /* shift all the arguments one field */
8374 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8377 EndPutM32Inc(data
, 0x7C000378 + (i
<<21) + ((i
-1)<<16) + ((i
-1)<<11));
8382 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8383 || ap
->NumArgs
>= 8))
8384 EndPutM32Inc(data
, 0x90010000+stcksize
+4); /* stw r0,%d(r1) */
8388 if(Flags
& FLAG_SMALLDATA
)
8390 k
= (data
-data3
)+2; /* store reloc offset */
8391 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8395 k
= (data
-data3
)+2; /* store reloc offset */
8396 EndPutM32Inc(data
, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8397 EndPutM32Inc(data
, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8401 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8404 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2));
8405 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8406 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8410 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8412 j
= 4*ap
->Args
[i
].ArgReg
;
8413 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8417 EndPutM32Inc(data
, 0x90020000 + ((i
+3)<<21) + j
); /* stw rX,j(r2) */
8421 EndPutM32Inc(data
, 0x81610000 + (stcksize
+(i
+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8422 EndPutM32Inc(data
, 0x91620000 + j
); /* stw r11,j(r1) */
8427 EndPutM32Inc(data
, 0x38810000 + (stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0))); /* addi r4,r1,X */
8428 EndPutM32Inc(data
, 0x90820000 + j
); /* stw r4,X(r2) */
8433 EndPutM32Inc(data
, 0x81620064); /* lwz r11,100(r2) */
8436 EndPutM32Inc(data
, 0x91820038); /* stw r12,56(r2) */
8438 /* Now place the real function call */
8439 EndPutM32Inc(data
, 0x38600000 + 0x10000 - ap
->Bias
); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8441 EndPutM32Inc(data
, 0x7D6903A6); /* mtctr r11 */
8442 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8444 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8446 EndPutM32Inc(data
, 0x81610000 + stcksize
); /* lwz r11,X(r1) */
8447 EndPutM32Inc(data
, 0x91610000 + (stcksize
+nrcopyar
*4)); /* stw r11,Y(r1) */
8450 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8451 || ap
->NumArgs
>= 8))
8453 if(ap
->NumArgs
>= 8)
8455 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8456 EndPutM32Inc(data
, 0x38210000 + stcksize
); /* addi r1,r1,Y */
8457 /* mtlr r0 = mtspr 8,r0 = restore link register */
8458 EndPutM32Inc(data
, 0x7C0803A6);
8462 /* restore old stack frame: lwz r1,0(r1) */
8463 EndPutM32Inc(data
, 0x80210000);
8464 EndPutM32Inc(data
, 0x80010004); /* lwz r0,4(r1) */
8465 /* mtlr r0 = mtspr 8,r0 = restore link register */
8466 EndPutM32Inc(data
, 0x7C0803A6);
8471 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8472 EndPutM32Inc(data
, 0x38210000 + (stcksize
+nrcopyar
*4)); /* addi r1,r1,Y */
8473 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8476 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
8479 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8480 data
+= 44; /* 1 9 17 27 33 */
8482 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
8485 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
8486 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
8487 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8488 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8489 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
8490 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
8491 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8492 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8493 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
8494 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8497 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
8498 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
8499 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
8500 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
8501 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
8502 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
8503 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
8504 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
8505 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
8506 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
8509 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
8510 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
8511 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
8512 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
8513 data
+= 4; /* esh[2].sh_offset */
8514 data
+= 4; /* esh[2].sh_size */
8515 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8516 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
8517 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
8518 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8520 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
8521 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
8522 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
8523 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
8524 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
8525 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
8526 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
8527 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
8528 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
8529 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
8531 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
8532 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
8533 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
8534 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
8535 data
+= 4; /* esh[4].sh_offset */
8536 data
+= 4; /* esh[4].sh_size */
8537 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
8538 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8539 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
8540 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8542 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
8543 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
8544 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8545 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8546 data
+= 4; /* esh[0].sh_offset */
8547 data
+= 4; /* esh[0].sh_size */
8548 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8549 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8550 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
8551 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8553 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
8554 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 5*16 : 4*16); /* esh[4].sh_size */
8557 data
+= BaseName
? 5*16 : 4*16;
8559 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
8562 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
8563 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
8564 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
8565 *(data2
++) = 0; /* esym[0].st_info */
8566 *(data2
++) = 0; /* esym[0].st_other */
8567 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
8571 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
8572 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
8573 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
8574 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
8575 *(data2
++) = 0; /* esym[1].st_other */
8576 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
8578 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
]) { i
++;} ; /* get next store space */
8579 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
8580 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
8581 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
8582 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
8583 *(data2
++) = 0; /* esym[2].st_other */
8584 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
8586 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
8587 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
8588 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
8589 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
8590 *(data2
++) = 0; /* esym[3].st_other */
8591 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
8593 sprintf((strptr
)data
+i
, "%s", name
); while(data
[i
]) { i
++;} ; /* get next store space */
8596 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
8597 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
8598 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
8599 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
8600 *(data2
++) = 0; /* esym[4].st_other */
8601 EndPutM16
/*Inc*/(data2
, 0); /* esym[4].st_shndx */
8603 sprintf((strptr
)data
+i
, "%s", BaseName
); while(data
[i
]) { i
++;} ; /* get next store space */
8605 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
8606 while(i
&3) /* long aligned */
8610 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
8616 if(Flags
& FLAG_SMALLDATA
)
8618 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8619 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_SDAREL16
)); /* erel[0].r_info - entry 4, type 32 */
8620 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8624 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8625 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_HA
)); /* erel[0].r_info - entry 4, type 6 */
8626 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8627 EndPutM32Inc(data
, k
+4); /* erel[1].r_offset */
8628 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_LO
)); /* erel[1].r_info - entry 4, type 4 */
8629 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
8632 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
8634 /* make ar header and store all */
8635 arh
= (struct ArHeader
*) (data
+20);
8636 memset(arh
, ' ', sizeof(struct ArHeader
));
8638 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
8639 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
8640 arh
->ar_mode
[2] = '0';
8641 arh
->ar_mode
[0] = '6';
8642 arh
->ar_fmag
[0] = 96;
8643 arh
->ar_fmag
[1] = '\n';
8645 if((k
= strlen(name
) + 2) >= 16)
8647 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
8652 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
8655 j
= k
+ (data
-tempbuf
);
8656 for(i
= 9; j
; --i
) /* make decimal number */
8658 data
[i
] = (j
%10)+'0';
8661 for(j
= 0; i
< 9; ++j
)
8662 arh
->ar_size
[j
] = data
[++i
];
8664 DoOutputDirect(arh
, sizeof(struct ArHeader
));
8668 DoOutput("%s.o", name
);
8670 *(data
++) = 0x0A; /* alignment byte! */
8673 return DoOutputDirect(tempbuf
, data
-tempbuf
);
8676 uint32
FuncEModule(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8680 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_PPC
) ||
8681 (flags
& FUNCFLAG_ALIAS
))
8684 if(LastBias
>= ap
->Bias
)
8685 DoError(ERR_ILLEGAL_FUNCTION_POSITION
, ap
->Line
, name
);
8688 Flags
|= FLAG_DONE
; /* We did something */
8690 for(LastBias
+= BIAS_OFFSET
; LastBias
< ap
->Bias
; LastBias
+= BIAS_OFFSET
)
8691 DoOutputDirect("Dum\x10", 4);
8693 DoOutput("%c", toupper(name
[0]));
8696 DoOutput("%c", tolower(name
[1]));
8698 DoOutput("%s", name
+2);
8701 DoOutputDirect("\x10", 1);
8704 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8706 r
= ap
->Args
[i
].ArgReg
;
8707 DoOutputDirect(&r
, 1);
8714 uint32
FuncFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8718 Flags
|= FLAG_DONE
; /* We did something */
8720 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8722 if(Flags
& FLAG_ISPRIVATE
)
8724 Flags
^= FLAG_ISPRIVATE
;
8725 DoOutput("##public\n");
8730 if(!(Flags
& FLAG_ISPRIVATE
))
8731 DoOutput("##private\n");
8732 Flags
|= FLAG_ISPRIVATE
;
8735 LastBias
+= BIAS_OFFSET
;
8736 if(LastBias
!= ap
->Bias
)
8738 DoOutput("##bias %d\n", ap
->Bias
);
8739 LastBias
= ap
->Bias
;
8742 if(ap
->Abi
!= CurrentABI
)
8746 case ABI_M68K
: DoOutput("##abi M68k\n"); break;
8747 case ABI_PPC0
: DoOutput("##abi PPC0\n"); break;
8748 case ABI_PPC2
: DoOutput("##abi PPC2\n"); break;
8749 case ABI_PPC
: DoOutput("##abi PPC\n"); break;
8751 CurrentABI
= ap
->Abi
;
8754 DoOutput("%s("/*)*/, name
);
8755 for(i
= 0; i
< ap
->CallArgs
; i
++)
8756 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->CallArgs
-1 ? "," : "");
8757 DoOutput(/*(*/")("/*)*/);
8759 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8761 for(i
= 0; i
< ap
->CallArgs
; i
++)
8763 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], i
< ap
->CallArgs
-1 ?
8764 (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
? "/" : ",") : "");
8767 return DoOutput(/*(*/")\n");
8770 /* called from FuncSFD directly */
8771 uint32
FuncClib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8773 struct ClibData
*cd
;
8776 Flags
|= FLAG_DONE
; /* We did something */
8778 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8781 s
= MakeClibType(tempbuf
, &cd
->ReturnType
, 0);
8782 DoOutputDirect(tempbuf
, s
);
8783 DoOutput(" %s("/*)*/, name
);
8787 for(i
= 0; i
< cd
->NumArgs
; i
++)
8789 c
= MakeClibType(tempbuf
, &cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8792 DoOutput(i
? ",\n\t" : "\n\t"); s
= 8;
8796 DoOutput(", "); s
+= 2;
8798 DoOutputDirect(tempbuf
, c
);
8802 else if(Flags2
& FLAG2_CLIBOUT
)
8804 return DoOutput(/*(*/")%s", Flags2
& FLAG2_CLIBOUT
? ";\n" : "");
8807 uint32
FuncSFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8809 struct ClibData
*cd
;
8812 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8815 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8817 if(Flags
& FLAG_ISPRIVATE
)
8819 Flags
^= FLAG_ISPRIVATE
;
8820 DoOutput("==public\n");
8825 if(!(Flags
& FLAG_ISPRIVATE
))
8826 DoOutput("==private\n");
8827 Flags
|= FLAG_ISPRIVATE
;
8830 if(ap
->Abi
!= CurrentABI
)
8834 case ABI_M68K
: DoOutput("==abi M68k\n"); break;
8835 case ABI_PPC0
: DoOutput("==abi PPC0\n"); break;
8836 case ABI_PPC2
: DoOutput("==abi PPC2\n"); break;
8837 case ABI_PPC
: DoOutput("==abi PPC\n"); break;
8839 CurrentABI
= ap
->Abi
;
8842 if(LastBias
+BIAS_OFFSET
< ap
->Bias
)
8844 DoOutput("==reserve %ld\n", ((ap
->Bias
-LastBias
)/BIAS_OFFSET
)-1);
8845 LastBias
= ap
->Bias
;
8847 else if(flags
& FUNCFLAG_TAG
)
8848 DoOutput("==varargs\n");
8849 else if((flags
& FUNCFLAG_ALIAS
) || LastBias
== ap
->Bias
)
8850 DoOutput("==alias\n");
8852 LastBias
+= BIAS_OFFSET
;
8854 if(!FuncClib(ap
, flags
, name
))
8857 DoOutput(" ("/*)*/);
8858 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8862 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8863 in step one, so the "-" can be placed at proper position. */
8864 for(j
= i
= 0; i
< ap
->NumArgs
; i
++)
8866 if(i
== ap
->NumArgs
-1)
8870 else if(IsCPPType(&cd
->Args
[j
>>1], CPP_TYPE_DOUBLE
) && ap
->Args
[i
].ArgReg
< REG_FP0
)
8872 s
= (j
&1) ? "," : "-"; ++j
;
8878 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], s
);
8881 return DoOutput(/*(*/")\n");
8884 uint32
FuncOS4PPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8886 struct ClibData
*cd
;
8887 int32 i
, noret
= 0, registers
;
8889 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
8892 Flags
|= FLAG_DONE
; /* We did something */
8894 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8897 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
8898 noret
= 1; /* this is a void function */
8900 sprintf((strptr
)tempbuf
, "_%s_%s", GetIFXName(), name
);
8901 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
8903 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8904 ap
->NumArgs
? "," : "");
8905 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8908 if(i
== ap
->NumArgs
- 1 && (flags
& FUNCFLAG_TAG
))
8914 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8915 if(i
< ap
->NumArgs
-1)
8919 if(flags
& FUNCFLAG_TAG
)
8921 struct ClibData
*cd2
;
8923 if(!(cd2
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
8926 DoOutput(/*(*/")\n{\n"/*}*/
8928 " va_startlinear(ap, colorMap);\n"
8931 DoOutput("return ");
8932 DoOutput("Self->%s(\n"/*)*/, ap
->FuncName
);
8933 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8935 DoOutput(" %s,\n", ap
->Args
[i
].ArgName
);
8937 DoOutput(" va_getlinearva(ap, "/*)*/);
8938 OutClibType(&cd2
->Args
[i
], 0);
8939 DoOutput(/*((*/"));\n");
8943 DoOutput(/*(*/")\n{\n"/*}*/
8944 " struct Library *LibBase = Self->Data.LibBase;\n"
8945 " struct ExecIFace *IExec = (struct ExecIFace *)"
8946 "Self->Data.IExecPrivate;\n");
8951 OutClibType(&cd
->ReturnType
, "retval");
8956 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8958 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8961 registers
= GetRegisterData(ap
) | 0x40000002; /* set A6 everytime */
8962 for(i
= 0; i
<= 15; ++i
)
8964 if(registers
& (1<< (16+i
)))
8965 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames
[i
], i
);
8971 DoOutput("retval = ("/*)*/);
8972 OutClibType(&cd
->ReturnType
, 0);
8976 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
8977 " ET_Offset, -%d,\n"/*)*/,ap
->Bias
);
8978 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8980 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
],
8981 ap
->Args
[i
].ArgName
);
8983 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
8984 for(i
= 0; i
<= 15; ++i
)
8986 if(registers
& (1<< (16+i
)))
8987 DoOutput(" regs[%ld] = save_%s;\n", i
, RegNames
[i
]);
8991 DoOutput(" return retval;\n");
8993 return DoOutput(/*{*/"}\n\n");
8996 uint32
FuncOS4M68KCSTUB(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8998 struct ClibData
*cd
;
9001 if(ap
->NumArgs
<= 7)
9004 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9007 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9010 Flags
|= FLAG_DONE
; /* We did something */
9012 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9013 noret
= 1; /* this is a void function */
9015 sprintf((strptr
)tempbuf
, "Cstub_%s", name
);
9016 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
9018 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9019 " struct ExecIFace *IExec = (struct ExecIFace *)"
9020 "Interface->Data.IExecPrivate;\n"
9021 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9022 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9025 DoOutput("return ");
9027 DoOutput("Interface->%s(\n"/*)*/,(flags
& FUNCFLAG_TAG
) ? ap
->FuncName
9029 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9031 DoOutput(" ("/*)*/);
9032 OutClibType(&cd
->Args
[i
], 0);
9033 DoOutput(/*(*/") regarray[%d]", ap
->Args
[i
].ArgReg
);
9034 if(i
< ap
->NumArgs
-1)
9037 return DoOutput(/*{(*/");\n}\n\n");
9040 uint32
FuncOS4M68K(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9042 struct ClibData
*cd
;
9045 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9048 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9051 Flags
|= FLAG_DONE
; /* We did something */
9054 "\t.section .data\n"
9055 "\t.globl\tstub_%s\n"
9056 "\t.type\tstub_%s,@function\n"
9059 "\t.short\t0x4ef8\n"
9062 "\t.globl\tstub_%sPPC\n"
9063 "\t.long\tstub_%sPPC\n",name
, name
, name
, name
, name
);
9067 Flags2
|= FLAG2_OS4M68KCSTUB
;
9069 "\t.byte\t2\n" /* Rest of parameters in C */
9070 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9071 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9076 "\t.byte\t%d\n" /* Rest of parameters in C */
9077 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9078 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9080 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9082 DoOutput("\t.byte\t%d,REG68K_%s\n",i
+4,
9083 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9087 "\t.section .text\n"
9091 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9092 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9093 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9094 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9095 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9096 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9097 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9098 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9099 name
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9100 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9101 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9102 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
9106 /* Since this function has 11 arguments, we need a C stub */
9108 "\t.globl\tCstub_%s\n"
9109 "\tlis\t%s4,Cstub_%s@h\n"
9110 "\tori\t%s4,%s4,Cstub_%s@l\n"
9113 name
, PPCRegPrefix
, name
, PPCRegPrefix
, PPCRegPrefix
, name
, PPCRegPrefix
);
9117 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name
);
9120 "\tlwz\t%s11,12(%s1)\n"
9122 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9123 "\tblrl\n" /* Return to emulation */
9125 "\t.globl\tstub_%s68K\n"
9126 "\t.long\tstub_%s68K\n"
9127 "\t.byte\t0\n", /* Flags */
9128 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, name
,
9131 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9134 "\t.byte\t1\n" /* One register (a7 only) */
9135 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9141 "\t.byte\t1,REG68K_A7\n"
9142 "\t.byte\t3,REG68K_D0\n");
9146 "\t.section .data\n"
9150 "\t.short\t0x4e75\n" /* RTS */
9154 uint32
FuncOS4M68KVect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9156 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9159 while(LastBias
+ BIAS_OFFSET
< ap
->Bias
)
9161 DoOutput("\t.long\tstub_Reserved\n");
9162 LastBias
+= BIAS_OFFSET
;
9164 LastBias
= ap
->Bias
;
9166 return DoOutput("\t.long\tstub_%s\n", name
);
9169 uint32
FuncXML(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9171 struct ClibData
*cd
;
9174 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9177 if(flags
& FUNCFLAG_ALIAS
)
9178 DoError(ERR_ALIASES_NOT_SUPPORTED
, ap
->Line
);
9180 Flags
|= FLAG_DONE
; /* We did something */
9182 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
9185 while(LastBias
+BIAS_OFFSET
< ap
->Bias
)
9187 LastBias
+= BIAS_OFFSET
;
9188 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9189 " status=\"unimplemented\"/>\n", LastBias
);
9191 LastBias
= ap
->Bias
;
9193 DoOutput("\t\t<method name=\"%s\" result=\"", name
);
9194 OutClibType(&cd
->ReturnType
, 0);
9196 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9198 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9199 i
== ap
->NumArgs
-1 && (flags
& FUNCFLAG_TAG
) ? "var" : "",
9200 ap
->Args
[i
].ArgName
);
9201 OutClibType(&cd
->Args
[i
], 0);
9204 return DoOutput("\t\t</method>\n");
9207 uint32
FuncGateStubs(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9209 struct ClibData
*cd
;
9210 strptr ret
= "return ";
9213 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
9216 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9219 Flags
|= FLAG_DONE
; /* We did something */
9221 if(flags
& FUNCFLAG_ALIAS
)
9223 if(flags
& FUNCFLAG_TAG
)
9224 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9225 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
9227 DoOutput("#define %s("/*)*/, name
);
9228 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9229 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9230 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
9231 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9232 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9233 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
9236 if((flags
& FUNCFLAG_TAG
))
9238 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9239 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
9240 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9242 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9244 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9246 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9247 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9249 OutClibType(&cd
->Args
[i
], 0);
9250 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9253 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9256 if(!OutClibType(&cd
->ReturnType
, 0))
9259 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix
, name
);
9261 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9264 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
9265 DoOutput(" = ("/*)*/);
9266 OutClibType(&cd
->Args
[i
], 0);
9267 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9268 if((Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
)) && (Flags2
& FLAG2_REGLIB
))
9269 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9271 DoOutput(" %s%s%s("/*)*/, ret
, subprefix
, name
);
9274 if(Flags2
& FLAG2_PRELIB
)
9276 if(Flags2
& FLAG2_REGLIB
)
9277 DoOutput("___RegBase,");
9279 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper
);
9282 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9284 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9286 if(Flags2
& FLAG2_POSTLIB
)
9288 if(Flags2
& FLAG2_REGLIB
)
9289 DoOutput("%s, ___RegBase", ap
->Args
[i
].ArgName
);
9291 DoOutput("%s, %s_BASE_NAME", ap
->Args
[i
].ArgName
, ShortBaseNameUpper
);
9294 DoOutput("%s", ap
->Args
[i
].ArgName
);
9298 if(Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
))
9300 if(Flags2
& FLAG2_REGLIB
)
9301 DoOutput("___RegBase");
9303 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
9306 return DoOutput(/*(({*/"));\n}\n");
9309 static uint32
DoCallFunc(struct AmiPragma
*ap
, uint32 flags
, strptr name
, FuncType Func
)
9313 if(Flags
& FLAG_SINGLEFILE
)
9315 sprintf(filename
, filenamefmt
, name
);
9316 if(!OpenDest(filename
))
9319 res
= Func(ap
, flags
, name
);
9320 if(Flags
& FLAG_SINGLEFILE
)
9322 CloseDest(filename
);
9327 static uint32
PrintComment(struct Comment
*com
, strptr comment
)
9329 if(com
->Private
&& !(Flags
& FLAG_PRIVATE
))
9331 else if((Flags2
& FLAG2_SFDOUT
) && com
->Version
)
9333 return DoOutput("==version %d\n", com
->Version
);
9335 else if((Flags2
& FLAG2_SFDOUT
) && com
->ReservedNum
)
9337 LastBias
+= BIAS_OFFSET
*com
->ReservedNum
;
9338 return DoOutput("==reserve %d\n", com
->ReservedNum
);
9340 else if(!(Flags
& FLAG_DOCOMMENT
) || !comment
)
9345 if(!DoOutput(comment
, com
->Data
))
9348 else if(com
->ReservedNum
)
9351 sprintf(temp
, "* --- (%u function slot%s reserved here) ---", com
->ReservedNum
,
9352 com
->ReservedNum
== 1 ? "" : "s");
9353 if(!DoOutput(comment
, temp
))
9356 else if(com
->Version
)
9359 if(com
->Version
>= FIRST_KNOWN_RELEASE
&& com
->Version
<= LAST_KNOWN_RELEASE
&&
9360 (Flags2
& FLAG2_SYSTEMRELEASE
))
9361 sprintf(temp
, "* --- functions in V%u or higher %s ---", com
->Version
,
9362 Release
[com
->Version
-FIRST_KNOWN_RELEASE
]);
9364 sprintf(temp
, "* --- functions in V%u or higher ---", com
->Version
);
9366 if(!DoOutput(comment
, temp
))
9372 static uint32
CallFunc(uint32 tagmode
, strptr comment
, FuncType Func
)
9374 struct Comment
*com
;
9376 struct AmiPragma
*ap
;
9378 com
= (struct Comment
*) Comment
.First
;
9380 for(ap
= (struct AmiPragma
*) AmiPragma
.First
; ap
;
9381 ap
= (struct AmiPragma
*) ap
->List
.Next
)
9383 if(BaseName
&& (ap
->Flags
& AMIPRAGFLAG_A6USE
))
9385 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
9387 else if((ap
->Flags
& AMIPRAGFLAG_PUBLIC
) || (Flags
& FLAG_PRIVATE
))
9389 while(com
&& com
->Bias
<= ap
->Bias
)
9391 if(!PrintComment(com
, comment
))
9393 com
= (struct Comment
*) com
->List
.Next
;
9394 } /* comment loop */
9397 printf("Processing %s - %s\n", ap
->FuncName
? ap
->FuncName
: "",
9398 ap
->TagName
? ap
->TagName
: "");
9401 if(tagmode
!= TAGMODE_TAGS
)
9403 if(ap
->FuncName
&& !DoCallFunc(ap
, FUNCFLAG_NORMAL
, ap
->FuncName
, Func
))
9406 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9408 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_NORMAL
)
9410 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9418 if(ap
->TagName
&& !DoCallFunc(ap
, FUNCFLAG_TAG
, ap
->TagName
, Func
))
9421 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9423 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_TAG
)
9425 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9434 if(!PrintComment(com
, comment
))
9436 com
= (struct Comment
*) com
->List
.Next
;
9437 } /* comment loop */
9441 static uint32
PrintIncludes(void) /* copies the include lines */
9443 struct Include
*inc
;
9446 inc
= (struct Include
*) Includes
.First
;
9450 s2
= (strptr
) tempbuf
;
9451 for(s
= inc
->Include
; *s
; ++s
)
9455 case '<': *(s2
++) = ' '; break;
9457 case '.': *(s2
++) = '_'; break;
9459 default: *(s2
++) = toupper(*s
);
9463 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf
, inc
->Include
);
9464 inc
= (struct Include
*) inc
->List
.Next
;
9467 DoOutput("#include <exec/types.h>\n");
9468 return DoOutput("\n");
9471 /* ------------------------------------------------------------------ */
9473 static int32
AddClibEntry(strptr buffer
, strptr bufend
, uint32 linenum
)
9475 strptr buf
= buffer
;
9476 struct ClibData d
, *f
;
9478 memset(&d
, 0, sizeof(struct ClibData
));
9479 buf
= SkipBlanksRet(buf
);
9480 if(*buf
== '#') /* preprocessor lines */
9483 printf("Found non-function bracket in preprocessor line %ld\n", linenum
);
9485 while(buf
< bufend
&& *buf
!= '\n')
9489 if(!strnicmp(buf
, "ASM", 3))
9490 buf
= SkipBlanks(buf
+3);
9491 /* else if(!strnicmp(buf, "STACK", 5))
9492 buf = SkipBlanks(buf+5);
9494 else if(!strnicmp(buf
, "REGS", 4))
9495 buf
= SkipBlanks(buf
+4);
9497 if(!strnicmp(buf
, "extern", 6))
9499 buf
= SkipBlanksRet(buf
+6);
9500 if(!strnicmp(buf
, "\"C\"", 3)) /* CPP: extern "C" */
9502 buf
= SkipBlanksRet(buf
+3);
9505 buf
= SkipBlanksRet(buf
+1);
9510 if(!GetCPPType(&d
.ReturnType
, buf
, 1, 1))
9512 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE
, linenum
);
9515 else if(d
.ReturnType
.Unknown
)
9516 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, linenum
,
9517 d
.ReturnType
.Unknown
);
9519 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9521 strptr r
= d
.ReturnType
.TypeStart
;
9522 while(*r
!= '('/*)*/) ++r
;
9523 r
= SkipBlanks(++r
); /* the bracket */
9524 d
.FuncName
= SkipBlanks(++r
); /* the asterisk */
9527 d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
+d
.ReturnType
.FullLength
);
9529 while(*(buf
++) != '('/*)*/)
9531 *(SkipName(d
.FuncName
)) = 0;
9535 printf("Found non-function bracket in line %ld\n", linenum
);
9537 while(buf
< bufend
&& *buf
!= '\n')
9541 buf
= SkipBlanksRet(buf
);
9543 while(*buf
!= /*(*/')' && buf
< bufend
)
9545 if(d
.NumArgs
== MAXREGPPC
+1)
9547 DoError(ERROFFSET_CLIB
| ERR_TO_MUCH_ARGUMENTS
, linenum
);
9550 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 0, 1))
9552 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE
, linenum
, d
.NumArgs
);
9555 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
9556 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE_INT
, linenum
,
9557 d
.NumArgs
, d
.Args
[d
.NumArgs
-1].Unknown
);
9559 buf
= d
.Args
[d
.NumArgs
-1].TypeStart
+ d
.Args
[d
.NumArgs
-1].FullLength
;
9560 while(*buf
!= ',' && *buf
!= /*(*/')' && buf
< bufend
)
9563 printf("Added argument %d for %s (%d bytes)\n", d
.NumArgs
, d
.FuncName
,
9564 d
.Args
[d
.NumArgs
-1].FullLength
);
9567 buf
= SkipBlanksRet(++buf
);
9570 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9571 d
.NumArgs
= 0; /* void arguments are no arguments */
9573 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9576 memcpy(f
, &d
, sizeof(struct ClibData
));
9582 struct ClibData
*e
= clibdata
;
9587 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9589 int numclose
= 2, numopen
= 1;
9590 while(buf
< bufend
&& (numclose
|| numopen
> 0))
9592 if(*buf
== '('/*)*/) { ++numclose
; --numopen
; }
9593 else if(*buf
== /*(*/')') --numclose
;
9599 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9600 f
->FuncName
, linenum
, buf
-buffer
, f
->NumArgs
);
9605 static int32
ScanClibFile(strptr buf
, strptr bufend
)
9607 strptr linestart
= buf
;
9611 /* remove comments and other not so nice characters */
9614 if(*buf
== '\t' || *buf
== '\r' || *buf
== (string
)0xA0)
9616 else if(buf
[0] == '/' && buf
< bufend
-1)
9620 while(buf
< bufend
-1 && (buf
[0] != '*' || buf
[1] != '/'))
9629 else if(buf
[1] == '/')
9631 while(buf
< bufend
&& buf
[0] != '\n')
9638 else if(buf
[0] == '#' && strncmp("#include", buf
, 8))
9640 while(buf
< bufend
&& buf
[0] != '\n')
9649 printf("-----------\n%s-----------\n", linestart
);
9664 else if(!strncmp("#include", buf
, 8))
9668 if(!(d
= (struct Include
*) NewItem(&Includes
)))
9670 d
->Include
= buf
= SkipBlanks(buf
+8);
9671 AddItem(&Includes
, (struct ShortList
*) d
);
9672 while(*buf
&& *buf
!= '>' && *buf
!= '\n')
9680 printf("Added Include line %s\n", d
->Include
);
9684 else if(*buf
== '('/*)*/)
9688 if((i
= AddClibEntry(linestart
, bufend
, linenum
)) == -1) /* no memory */
9692 while(buf
< bufend
&& *buf
!= '\n')
9693 ++buf
; /* skip this line */
9698 while(buf
< bufend
&& i
-- > 0)
9700 if(*(buf
++) == '\n')
9704 } /* skip this function */
9715 static int32
IsCPPType(struct CPP_NameType
*data
, uint8 type
)
9717 if(!data
|| data
->Flags
|| data
->Type
!= type
|| data
->PointerDepth
)
9722 static uint32
CheckRegisterNum(strptr string
, struct CPP_NameType
*data
)
9726 for(i
= 0; i
< MAXREG
; ++i
)
9728 j
= strlen(RegNames
[i
]);
9729 if(!strnicmp(string
, RegNames
[i
], j
))
9732 if(*string
== ' ' || *string
== '\t' || *string
== '\n' || *string
== /*(*/')')
9735 data
->Flags
|= CPP_FLAG_REGISTER
;
9743 static uint32
ParseFuncPtrArgs(strptr buffer
, struct CPP_NameType
*data
)
9745 strptr buf
= buffer
;
9748 memset(&d
, 0, sizeof(struct ClibData
));
9749 while(*buf
!= /*(*/')')
9751 if(d
.NumArgs
== MAXREGPPC
+1)
9753 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 1, 1))
9756 buf
+= d
.Args
[d
.NumArgs
-1].FullLength
;
9757 while(*buf
!= ',' && *buf
!= /*(*/')')
9760 buf
= SkipBlanksRet(++buf
);
9763 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9764 d
.NumArgs
= 0; /* void arguments are no arguments */
9766 if(d
.NumArgs
) /* no need to allocate structure for nothing */
9768 if(!(data
->FuncPtr
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9771 memcpy(data
->FuncPtr
, &d
, sizeof(struct ClibData
));
9773 return (uint32
) (buf
+1-buffer
);
9776 /* rettype turns on usage of "extern" specifier */
9777 static int32
GetCPPType(struct CPP_NameType
*data
, strptr start
, uint32 rettype
, uint32 small
)
9784 data
->TypeStart
= start
= SkipBlanks(start
);
9786 if(!strncmp(start
, "REG", 3) && (start
[3] == ' ' || start
[3] == '\t' || start
[3] == '\n' || start
[3] == '('/*)*/))
9788 u
= SkipBlanksRet(start
+3);
9791 u
= SkipBlanks(u
+1);
9792 if((j
= CheckRegisterNum(u
, data
)))
9794 u
= SkipBlanks(u
+j
);
9796 start
= SkipBlanks(u
+1);
9800 data
->TypeStart
= start
;
9804 start
= SkipBlanks((u
= start
));
9805 if(!strncmp("...",start
,3))
9807 data
->Type
= CPP_TYPE_VARARGS
;
9808 data
->TypeLength
= start
+3 - (data
->TypeStart
);
9809 data
->FullLength
= data
->TypeLength
;
9812 if(CheckKeyword(start
, "const", 5) || CheckKeyword(start
, "CONST", 5))
9814 data
->Flags
|= CPP_FLAG_CONST
; start
+= 5;
9816 else if(rettype
&& CheckKeyword(start
, "extern", 6))
9818 start
+= 6; /* ignore it */
9820 else if(CheckKeyword(start
, "long", 4))
9822 if(data
->Flags
& CPP_FLAG_LONG
)
9823 data
->Type
= CPP_TYPE_LONGLONG
;
9825 data
->Flags
|= CPP_FLAG_LONG
;
9829 else if(CheckKeyword(start
, "signed", 6))
9831 else if(CheckKeyword(start
, "unsigned", 8))
9833 data
->Flags
|= CPP_FLAG_UNSIGNED
; start
+= 8;
9835 else if(CheckKeyword(start
, "register", 8))
9837 data
->Flags
|= CPP_FLAG_REGISTER
; start
+= 8;
9838 data
->Register
= UNDEFREGISTER
;
9840 else if(CheckKeyword(start
, "struct", 6))
9842 start
= SkipBlanks(start
+6);
9843 data
->Flags
|= CPP_FLAG_STRUCT
;
9844 if(*start
== '?') /* ? for external types */
9846 data
->StructureLength
= 0;
9847 data
->StructureName
= "";
9850 else if(*start
== '!') /* ! for typedef types */
9852 data
->Flags
|= CPP_FLAG_TYPEDEFNAME
;
9854 /* structure name and length already set */
9858 start
= SkipName((data
->StructureName
= start
));
9859 data
->StructureLength
= start
-data
->StructureName
;
9862 else if(CheckKeyword(start
, "union", 5))
9864 start
= SkipBlanks(start
+5);
9865 data
->Flags
|= CPP_FLAG_UNION
;
9866 if(*start
!= '?') /* ? for external types */
9868 start
= SkipName((data
->StructureName
= start
));
9869 data
->StructureLength
= start
-data
->StructureName
;
9873 data
->StructureLength
= 0;
9874 data
->StructureName
= "";
9878 else if(CheckKeyword(start
, "enum", 4))
9880 start
= SkipBlanks(start
+4);
9881 data
->Flags
|= CPP_FLAG_ENUM
;
9882 if(*start
!= '?') /* ? for external types */
9884 start
= SkipName((data
->StructureName
= start
));
9885 data
->StructureLength
= start
-data
->StructureName
;
9889 data
->StructureLength
= 0;
9890 data
->StructureName
= "";
9894 else if(*start
== '*')
9896 ++start
; ++data
->PointerDepth
;
9898 else if(*start
== '[')
9900 data
->Flags
|= CPP_FLAG_ARRAY
;
9901 while(*start
&& *start
!= ']')
9906 else if(start
[0] == '_' && start
[1] == '_' && (j
= CheckRegisterNum(start
+2, data
)))
9908 else if(!data
->Type
)
9912 for(i
= 0; CPP_Field
[i
].Text
; ++i
)
9914 if(!strncmp(start
, CPP_Field
[i
].Text
, CPP_Field
[i
].Length
) &&
9915 (start
[CPP_Field
[i
].Length
] == ' ' ||
9916 start
[CPP_Field
[i
].Length
] == '\t' ||
9917 start
[CPP_Field
[i
].Length
] == '\n' ||
9918 start
[CPP_Field
[i
].Length
] == ',' ||
9919 start
[CPP_Field
[i
].Length
] == /*(*/')' ||
9920 start
[CPP_Field
[i
].Length
] == '('/*)*/ ||
9921 start
[CPP_Field
[i
].Length
] == '*'))
9923 start
+= CPP_Field
[i
].Length
;
9924 data
->Type
= CPP_Field
[i
].Type
;
9925 data
->Flags
|= CPP_Field
[i
].Flags
;
9926 if(CPP_Field
[i
].Flags
& CPP_FLAG_POINTER
)
9927 ++data
->PointerDepth
;
9931 if(CPP_Field
[i
].Text
)
9935 struct CPP_ExternNames
*a
= extnames
;
9939 i
= strlen(a
->Type
);
9940 if(!strncmp(a
->Type
, start
, i
) && !isalnum(start
[i
]) &&
9944 data
->StructureName
= a
->NameType
.StructureName
;
9945 data
->FuncPtr
= a
->NameType
.FuncPtr
;
9946 data
->StructureLength
= a
->NameType
.StructureLength
;
9947 data
->PointerDepth
+= a
->NameType
.PointerDepth
;
9948 data
->Type
= a
->NameType
.Type
;
9949 data
->Flags
|= a
->NameType
.Flags
;
9950 data
->FuncArgs
= a
->NameType
.FuncArgs
;
9951 data
->ArgsLength
= a
->NameType
.ArgsLength
;
9955 /* check types here */
9960 else if((!data
->Type
) && (!data
->Flags
))
9963 struct CPP_Unknown
*u
;
9965 data
->Type
= CPP_TYPE_INT
;
9966 size
= SkipName(start
)-start
;
9967 for(u
= unknown
; u
&& strncmp(u
->Unknown
, start
, size
); u
= u
->Next
)
9971 data
->Unknown
= DupString(start
, size
);
9972 if((u
= (struct CPP_Unknown
*) AllocListMem(sizeof(struct CPP_Unknown
))))
9975 u
->Unknown
= data
->Unknown
;
9989 if(start
!= SkipBlanks(u
)) /* we broke the loop after increasing start */
9992 data
->TypeLength
= u
- (data
->TypeStart
);
9993 data
->FullLength
= data
->TypeLength
;
10000 u
= SkipBlanksRet(++u
);
10005 ++data
->FuncPointerDepth
; ++u
;
10007 u
= SkipBlanksRet(u
);
10008 if(CheckKeyword(u
, "const", 5) || CheckKeyword(u
, "CONST", 5))
10010 data
->Flags
|= CPP_FLAG_CONST
; u
+= 6;
10012 u
= SkipBlanksRet(u
);
10014 data
->FunctionName
= u
;
10015 u
= SkipBlanksRet(SkipName(u
));
10020 while(*u
&& numclose
)
10022 if(*u
== '('/*)*/) ++numclose
;
10023 else if(*u
== /*(*/')') --numclose
;
10029 u
= SkipBlanksRet(++u
);
10032 data
->Flags
|= CPP_FLAG_FUNCTION
;
10034 if((j
= ParseFuncPtrArgs(u
+1, data
)))
10036 data
->FuncArgs
= u
;
10037 data
->ArgsLength
= j
+1;
10038 data
->FullLength
= u
+data
->ArgsLength
- (data
->TypeStart
);
10044 if(data
->PointerDepth
)
10045 data
->Flags
|= CPP_FLAG_POINTER
;
10047 if(!(Flags2
& FLAG2_SMALLTYPES
) && !small
)
10049 if(!(data
->Flags
& (CPP_FLAG_STRPTR
|CPP_FLAG_POINTER
|CPP_FLAG_ENUM
10050 |CPP_FLAG_STRUCT
|CPP_FLAG_UNION
|CPP_FLAG_FUNCTION
|CPP_FLAG_REGISTER
)))
10052 if(data
->Type
== CPP_TYPE_BYTE
|| data
->Type
== CPP_TYPE_WORD
|| data
->Type
== CPP_TYPE_INT
)
10054 if(data
->Flags
& CPP_FLAG_UNSIGNED
)
10055 data
->Replace
= "const ULONG";
10057 data
->Replace
= "const LONG";
10058 data
->Type
= CPP_TYPE_LONG
;
10059 if(!(data
->Flags
& CPP_FLAG_CONST
))
10060 data
->Replace
+= 6;
10065 if(!data
->Type
&& (data
->Flags
& CPP_FLAG_LONG
))
10066 data
->Type
= CPP_TYPE_LONG
;
10068 if((!data
->Type
&& !data
->Flags
) || !ok
)
10073 static struct ClibData
*GetClibFunc(strptr name
, struct AmiPragma
*ap
, uint32 flags
)
10075 struct ClibData
*d
= clibdata
;
10079 DoError(ERR_ILLEGAL_INTERNAL_VALUE
, 0);
10083 while(d
&& strcmp(name
, d
->FuncName
))
10088 if(!(ap
->Flags
& AMIPRAGFLAG_NOCLIB
))
10090 DoError(ERR_PROTOTYPE_MISSING
, 0, name
);
10091 ap
->Flags
|= AMIPRAGFLAG_NOCLIB
;
10094 else if(ap
->CallArgs
!= d
->NumArgs
&& (!(flags
& FUNCFLAG_TAG
) ||
10095 ap
->CallArgs
+1 != d
->NumArgs
))
10097 if(!(ap
->Flags
& (AMIPRAGFLAG_CLIBARGCNT
|AMIPRAGFLAG_DIDARGWARN
)))
10099 DoError(ERR_CLIB_ARG_COUNT
, 0, name
, d
->NumArgs
, ap
->NumArgs
);
10100 ap
->Flags
|= AMIPRAGFLAG_CLIBARGCNT
;
10108 static int32
CheckKeyword(strptr string
, strptr keyword
, int32 size
)
10110 if(!strncmp(string
, keyword
, size
))
10113 if(*string
== ' ' || *string
== '\t' || *string
== '\n')
10119 /* return nonzero, when usable, zero, when string already emitted */
10120 static uint32
CopyCPPType(strptr buffer
, uint32 pass
, struct ClibData
*cd
,
10121 struct AmiArgs
*args
)
10123 uint32 ret
= 0, reg
;
10124 uint32 i
, j
, k
= 0;
10126 /* pass 0: signed strptr, MaxonC++ high args */
10127 /* pass 1: unsigned strptr, MaxonC++ high args */
10128 /* pass 2: signed strptr, StormC++ high args */
10129 /* pass 3: unsigned strptr, StormC++ high args */
10131 for(i
= 0; i
< cd
->NumArgs
; ++i
)
10133 struct CPP_NameType
*nt
;
10137 if(args
&& (Flags
& FLAG_LOCALREG
) && (nt
->Type
!= CPP_TYPE_VARARGS
))
10138 reg
= 1 + args
[k
].ArgReg
;
10139 else if((nt
->Flags
& CPP_FLAG_REGISTER
) && nt
->Register
!= UNDEFREGISTER
)
10140 reg
= 1 + nt
->Register
;
10144 if(reg
--) /* subtract the added 1 */
10146 *(buffer
++) = CPP_TYPE_REGISTER
;
10151 *(buffer
++) = reg
/10 + '0';
10152 *(buffer
++) = reg
%10 + '0';
10156 *(buffer
++) = reg
+ (reg
< 10 ? '0' : 'A'-10);
10159 *(buffer
++) = reg
+ '0';
10162 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10164 for(j
= 0; j
< nt
->FuncPointerDepth
; ++j
)
10165 *(buffer
++) = CPP_TYPE_POINTER
;
10166 *(buffer
++) = CPP_TYPE_FUNCTION
;
10168 for(j
= 0; j
< nt
->PointerDepth
; ++j
)
10169 *(buffer
++) = CPP_TYPE_POINTER
;
10170 if(nt
->Flags
& CPP_FLAG_CONST
)
10171 *(buffer
++) = CPP_TYPE_CONST
;
10172 if(nt
->Flags
& CPP_FLAG_UNSIGNED
)
10173 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10174 else if((nt
->Flags
& CPP_FLAG_STRPTR
) && (pass
& 1))
10176 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10177 ret
|= 1; /* we really use this pass */
10179 if(nt
->Flags
& CPP_FLAG_ENUM
)
10180 *(buffer
++) = CPP_TYPE_ENUM
;
10182 *(buffer
++) = cd
->Args
[i
].Type
;
10186 sprintf(buffer
, "%02lu", (uint32
) nt
->StructureLength
); buffer
+= 2;
10187 for(i
= 0; i
< nt
->StructureLength
; ++i
)
10188 *(buffer
++) = nt
->StructureName
[i
];
10190 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10194 ret
|= CopyCPPType(buffer
, pass
, nt
->FuncPtr
, 0);
10196 ++buffer
; /* skip to the new end */
10198 *(buffer
++) = CPP_TYPE_FUNCEND
;
10201 if(IsCPPType(nt
, CPP_TYPE_DOUBLE
)) /* double needs 2 registers */
10212 return ret
; /* return nozero if this pass should be used */
10215 static uint32
OutClibType(struct CPP_NameType
*nt
, strptr txt
)
10218 DoOutput("%s", nt
->Replace
);
10220 DoOutputDirect(nt
->TypeStart
, nt
->TypeLength
);
10221 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10223 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10226 DoOutput(" ("/*)*/);
10227 for(i
= 0; i
< nt
->FuncPointerDepth
; ++i
)
10230 DoOutput("%s)", txt
);
10234 return DoOutputDirect(nt
->FuncArgs
, nt
->ArgsLength
);
10236 return DoOutput("()");
10239 return DoOutput(" %s", txt
);
10245 static uint32
MakeClibType(strptr dest
, struct CPP_NameType
*nt
, strptr txt
)
10253 i
= strlen(nt
->Replace
);
10254 memcpy(a
, nt
->Replace
, i
);
10259 memcpy(a
, nt
->TypeStart
, nt
->TypeLength
);
10260 a
+= nt
->TypeLength
;
10263 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10265 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10268 a
+= sprintf(a
, " (*%s)", txt
);
10270 a
+= sprintf(a
, " (*)");
10273 memcpy(a
, nt
->FuncArgs
, nt
->ArgsLength
);
10274 a
+= nt
->ArgsLength
;
10277 a
+= sprintf(a
, "()");
10280 a
+= sprintf(a
, " %s", txt
);
10282 return (uint32
)(a
-dest
);
10285 static uint32
OutPASCALType(struct CPP_NameType
*t
, strptr txt
, uint32 ret
)
10287 int32 i
= t
->PointerDepth
;
10289 if(t
->Flags
& CPP_FLAG_CONST
)
10290 DoOutput("CONST ");
10291 if(!ret
&& i
== 1 &&
10292 (t
->Type
== CPP_TYPE_LONG
|| t
->Type
== CPP_TYPE_WORD
))
10294 DoOutput("VAR "); --i
;
10297 DoOutput("%s : ", txt
);
10299 if(!i
&& t
->Flags
== CPP_FLAG_BOOLEAN
)
10300 return DoOutput("BOOLEAN");
10301 else if(i
&& t
->Type
== CPP_TYPE_VOID
)
10302 return DoOutput("POINTER");
10303 else if(t
->Flags
& CPP_FLAG_FUNCTION
)
10304 return DoOutput("tPROCEDURE");
10309 if((t
->Flags
& (CPP_FLAG_STRUCT
|CPP_FLAG_UNION
)) && t
->StructureLength
)
10311 if(!t
->PointerDepth
)
10313 return DoOutputDirect(t
->StructureName
, t
->StructureLength
);
10316 if(t
->Flags
& CPP_FLAG_UNSIGNED
)
10318 if(t
->Type
== CPP_TYPE_LONG
)
10319 return DoOutput("CARDINAL");
10320 if(t
->Type
== CPP_TYPE_WORD
)
10321 return DoOutput("int16");
10322 if(t
->Type
== CPP_TYPE_BYTE
)
10323 return DoOutput(t
->PointerDepth
== 1 ? "CHAR" : "int8");
10325 else if(t
->Type
== CPP_TYPE_WORD
)
10326 return DoOutput("INTEGER");
10327 else if(t
->Type
== CPP_TYPE_BYTE
)
10328 return DoOutput("SHORTINT");
10329 return DoOutput("int32INT");
10332 /* ------------------------------------------------------------------ */
10334 static uint32
CallPrag(uint32 tagmode
, strptr type
, FuncType Func
)
10337 if((*type
&& !DoOutput("#if%s\n", type
)) ||
10338 !(CallFunc(tagmode
, tagmode
? 0 : "/%s */\n", Func
)) ||
10339 (*type
&& !DoOutput("#endif\n")))
10344 static uint32
CreatePragmaFile(strptr amicall
, strptr libcall
, strptr amitags
,
10345 strptr libtags
, uint32 mode
)
10347 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10351 case PRAGMODE_PRAGLIB
: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10352 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper
,
10353 ShortBaseNameUpper
); break;
10354 case PRAGMODE_PRAGSLIB
: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10355 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10356 case PRAGMODE_PRAGSPRAGS
: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10357 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10358 case PRAGMODE_NONE
: break;
10365 DoOutputDirect(HEADER
, headersize
);
10368 if(mode
!= PRAGMODE_NONE
&& !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10369 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10372 if((Flags
& FLAG_EXTERNC
) &&
10373 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10376 if(Flags
& FLAG_GNUPRAG
)
10378 DoOutput("#ifdef " TEXT_GNUC
"\n#ifdef NO_OBSOLETE\n"
10379 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10380 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName
);
10381 Flags
|= FLAG_DONE
;
10385 !CallPrag(TAGMODE_NORMAL
, amicall
, FuncAMICALL
) ||
10386 !CallPrag(TAGMODE_NORMAL
, libcall
, FuncLIBCALL
))
10392 !CallPrag(TAGMODE_TAGS
, amitags
, FuncAMICALL
) ||
10393 !CallPrag(TAGMODE_TAGS
, libtags
, FuncLIBCALL
))
10397 if((Flags
& FLAG_EXTERNC
) &&
10398 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10403 case PRAGMODE_PRAGLIB
: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10404 ShortBaseNameUpper
); break;
10405 case PRAGMODE_PRAGSLIB
: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10406 ShortBaseNameUpper
); break;
10407 case PRAGMODE_PRAGSPRAGS
: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10408 ShortBaseNameUpper
); break;
10409 case PRAGMODE_NONE
: break;
10412 return Output_Error
;
10415 static uint32
CreateCSTUBSFile(void)
10417 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10419 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10420 ShortBaseNameUpper
, ShortBaseNameUpper
);
10424 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10430 DoOutputDirect(HEADER
, headersize
);
10433 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10434 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10437 if(!CallFunc(TAGMODE_TAGS
, "/%s */\n", FuncCSTUBS
))
10440 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10441 ShortBaseNameUpper
);
10444 static uint32
CreateLVOFile(uint32 mode
)
10446 strptr data
= "_LVO_I";
10448 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10450 if(mode
== 2 || mode
== 4)
10453 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10454 ShortBaseNameUpper
, data
, ShortBaseNameUpper
, data
) ||
10455 (HEADER
&& (!DoOutput("\n") || !DoOutputDirect(HEADER
, headersize
))) ||
10456 (mode
<= 2 && !CallFunc(TAGMODE_NORMAL
, 0, FuncLVOXDEF
)) ||
10457 !CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVO
) ||
10458 !DoOutput("\n\n\t\tENDC\n"))
10464 static uint32
CreateLVOFilePPC(uint32 mode
)
10466 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10468 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10469 ShortBaseNameUpper
, ShortBaseNameUpper
))
10474 DoOutputDirect(HEADER
, headersize
);
10478 case 0: CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCXDEF
);
10479 case 1: CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVOPPC
);
10481 return DoOutput("\n\t.endif\n");
10484 static uint32
CreateAsmStubs(uint32 mode
, uint32 callmode
)
10486 if(mode
== 1 && (Flags2
& FLAG2_AUTOHEADER
)) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10488 /* 1 = Text, 2 = Code */
10495 DoOutputDirect(HEADER
, headersize
);
10498 if(!(Flags
& FLAG_ASMSECTION
))
10499 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
10500 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
10501 if(!CallFunc(callmode
, "\n%s", FuncAsmText
))
10505 if(!CallFunc(callmode
, 0, FuncAsmCode
))
10513 static uint32
CreateProtoFile(uint32 Type
)
10515 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10517 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper
,
10518 ShortBaseNameUpper
);
10523 DoOutputDirect(HEADER
, headersize
);
10526 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10528 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC
")\n"
10529 "#include <clib/%s_protos.h>\n#endif\n",
10530 ShortBaseNameUpper
, ShortBaseName
);
10534 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10536 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10538 DoOutput("%s;\n#endif\n", BaseName
);
10545 DoOutput("\n#ifdef " TEXT_GNUC
"\n");
10547 DoOutput("#ifndef __cplusplus\n");
10548 DoOutput("#ifdef __AROS__\n");
10549 DoOutput("#include <defines/%s.h>\n", ShortBaseName
);
10550 DoOutput("#else\n");
10551 DoOutput("#include <inline/%s.h>\n", ShortBaseName
);
10552 DoOutput("#endif\n");
10554 DoOutput("#endif\n");
10558 DoOutput("#elif defined(" TEXT_VBCC
")\n"
10559 "#include <inline/%s_protos.h>\n#else", ShortBaseName
);
10561 DoOutput("#elif !defined(" TEXT_VBCC
")");
10565 DoOutput("\n#ifndef __PPC__");
10568 strptr str1
= "pragma", str2
= "lib";
10572 case 4: str1
= "pragmas"; /* no break; */
10573 case 2: str2
= "pragmas"; break;
10574 case 3: str1
= "pragmas"; break;
10575 case 5: str1
= "local"; str2
= "loc"; break;
10577 DoOutput("\n#include <%s/%s_%s.h>\n", str1
, ShortBaseName
, str2
);
10580 DoOutput("#endif\n");
10582 DoOutput("#endif\n");
10585 Flags
|= FLAG_DONE
;
10587 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10590 static uint32
CreateLocalData(strptr to
, uint32 callmode
)
10592 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10594 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10595 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10596 ShortBaseNameUpper
, ShortBaseNameUpper
);
10601 DoOutputDirect(HEADER
, headersize
);
10607 if((Flags
& FLAG_EXTERNC
) &&
10608 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10611 if(!CallFunc(callmode
, "/%s */\n", FuncLocText
))
10614 if((Flags
& FLAG_EXTERNC
) &&
10615 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10618 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper
);
10620 sprintf(filename
, "%s_loc.lib", ShortBaseName
);
10621 if(!CloseDest(to
) || !OpenDest(filename
))
10624 CallFunc(callmode
, 0, FuncLocCode
);
10626 return CloseDest(filename
);
10629 static uint32
CreateInline(uint32 mode
, uint32 callmode
)
10631 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10635 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10638 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10639 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
,
10640 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10645 DoOutputDirect(HEADER
, headersize
);
10650 /* prevent loading of clib-file after inline */
10651 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10652 ShortBaseNameUpper
, ShortBaseNameUpper
);
10656 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10657 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10658 "#include <ppcinline/macros.h>\n#endif\n\n");
10660 DoOutput("#ifndef __INLINE_MACROS_H\n"
10661 "#include <inline/macros.h>\n#endif\n\n");
10662 Flags
|= FLAG_INLINENEW
;
10666 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10667 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10668 "#include <ppcinline/stubs.h>\n#endif\n\n");
10670 DoOutput("#ifndef __INLINE_STUB_H\n"
10671 "#include <inline/stubs.h>\n#endif\n\n");
10673 Flags
|= FLAG_INLINESTUB
;
10676 Flags2
|= FLAG2_INLINEMAC
;
10680 if((Flags
& FLAG_EXTERNC
) &&
10681 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10686 if(mode
&& mode
<= 2)
10688 if(Flags
& FLAG_MORPHOS
)
10689 DoOutput("#include <emul/emulregs.h>\n");
10690 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10691 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10692 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10693 "#define BASE_PAR_DECL0 void\n#endif\n"
10694 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10695 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10698 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10699 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10704 if(!CallFunc(callmode
, "/%s */\n", FuncInline
))
10710 Flags
|= FLAG_INLINENEW
;
10711 if(!CallFunc(callmode
, "/%s */\n", FuncInlineDirect
))
10716 if(!CallFunc(callmode
, "/%s */\n", FuncInlineNS
))
10720 if(mode
&& mode
<= 2 && BaseName
)
10721 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10722 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper
);
10724 if((Flags
& FLAG_EXTERNC
) &&
10725 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10728 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10729 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10732 static uint32
CreateGateStubs(uint32 callmode
)
10734 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10738 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10740 if(!prefix
[0] && !subprefix
[0])
10742 DoError(ERR_PREFIX
, 0); return 1;
10745 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10746 ShortBaseNameUpper
, ShortBaseNameUpper
);
10748 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10749 premacro
, ShortBaseName
);
10754 DoOutputDirect(HEADER
, headersize
);
10759 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10760 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10761 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10762 "#define BASE_PAR_DECL0 void\n#endif\n"
10763 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10764 "BASE_EXT_DECL0\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10769 if(!CallFunc(callmode
, "/%s */\n", FuncGateStubs
))
10772 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper
);
10775 static uint32
CreateSASPowerUP(uint32 callmode
)
10777 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10779 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10780 ShortBaseNameUpper
, ShortBaseNameUpper
);
10785 DoOutputDirect(HEADER
, headersize
);
10788 DoOutput("\n#ifdef __GNUC__\n"
10789 "#ifndef _PPCINLINE__%s_H\n"
10790 "#include <ppcinline/%s.h>\n"
10793 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10794 "#include <ppclib/interface.h>\n"
10796 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10797 "#include <gcclib/powerup_protos.h>\n"
10799 "#ifndef NO_PPCINLINE_STDARG\n"
10800 "#define NO_PPCINLINE_STDARG\n"
10801 "#endif /* SAS-C PPC inlines */\n\n",
10802 ShortBaseNameUpper
, ShortBaseName
);
10806 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10807 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10810 if(!CallFunc(callmode
, "/%s */\n", FuncPowerUP
))
10813 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10814 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper
);
10817 static uint32
CreateProtoPowerUP(void)
10819 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10821 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10822 ShortBaseNameUpper
, ShortBaseNameUpper
);
10827 DoOutputDirect(HEADER
, headersize
);
10830 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName
);
10834 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10835 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10836 "#endif\n%s;\n#endif\n", BaseName
);
10839 DoOutput("\n#ifdef " TEXT_GNUC
"\n"
10840 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10841 "#else\n#include <inline/%s.h>\n#endif\n"
10842 "#else /* SAS-C */\n"
10843 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10844 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10845 ShortBaseName
, ShortBaseName
, ShortBaseName
, ShortBaseName
);
10847 Flags
|= FLAG_DONE
;
10849 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10852 static uint32
CreateFPCUnit(void)
10855 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT
);
10859 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10863 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName
);
10868 DoOutputDirect(HEADER
, headersize
);
10871 DoOutput("**********************************************************************}\n\n");
10872 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10873 DoOutput("{$mode objfpc}\n");
10874 DoOutput("{$I useamigasmartlink.inc}\n");
10875 DoOutput("{$ifdef use_amiga_smartlink}\n");
10876 DoOutput(" {$smartlink on}\n");
10877 DoOutput("{$endif use_amiga_smartlink}\n\n");
10879 DoOutput("UNIT %s;\n", ShortBaseNameUpper
);
10881 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName
, GetBaseTypeLib());
10883 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper
,ShortBaseName
);
10884 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName
);
10885 DoOutput("{$I %s.inc}\n\n",ShortBaseName
);
10887 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncFPCType
))
10890 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10891 if(!CallFunc(TAGMODE_TAGS
, 0, FuncFPCTypeTags
))
10894 DoOutput("\n{Here we read how to compile this unit}\n");
10895 DoOutput("{You can remove this include and use a define instead}\n");
10896 DoOutput("{$I useautoopenlib.inc}\n");
10897 DoOutput("{$ifdef use_init_openlib}\n");
10898 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10899 DoOutput("{$endif use_init_openlib}\n");
10900 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10901 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper
);
10902 DoOutput("\nIMPLEMENTATION\n\n");
10903 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10904 DoOutput("uses \n");
10905 DoOutput("{$ifndef dont_use_openlib}\n");
10906 DoOutput("msgbox, \n");
10907 DoOutput("{$endif dont_use_openlib}\n");
10908 DoOutput("tagsarray;\n\n");
10910 if(!CallFunc(TAGMODE_NORMAL
, "(%s *)\n", FuncFPCUnit
))
10913 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10914 if(!CallFunc(TAGMODE_TAGS
,"(%s *)\n", FuncFPCTypeTagsUnit
))
10917 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10918 DoOutput(" VERSION : string[2] = '0';\n");
10919 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10921 DoOutput("{$ifdef use_init_openlib}\n");
10922 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName
);
10923 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper
);
10925 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10926 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10927 DoOutput("begin\n");
10928 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10929 DoOutput(" if %s <> nil then begin\n",BaseName
);
10930 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10931 DoOutput(" %s := nil;\n",BaseName
);
10932 DoOutput(" end;\n");
10933 DoOutput("end;\n\n");
10934 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10935 DoOutput("begin\n %s := nil;\n",BaseName
);
10936 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10937 DoOutput(" if %s <> nil then begin\n",BaseName
);
10938 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10939 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10940 DoOutput(" end else begin\n");
10941 DoOutput(" MessageBox('FPC Pascal Error',\n");
10942 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10943 DoOutput(" 'Deallocating resources and closing down',\n");
10944 DoOutput(" 'Oops');\n");
10945 DoOutput(" halt(20);\n");
10946 DoOutput(" end;\n");
10947 DoOutput("end;\n\n");
10948 DoOutput("begin\n");
10949 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper
);
10950 DoOutput("{$endif use_init_openlib}\n\n");
10952 DoOutput("{$ifdef use_auto_openlib}\n");
10953 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName
);
10955 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10956 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10957 DoOutput("begin\n");
10958 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10959 DoOutput(" if %s <> nil then begin\n",BaseName
);
10960 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10961 DoOutput(" %s := nil;\n",BaseName
);
10962 DoOutput(" end;\n");
10963 DoOutput("end;\n\n");
10964 DoOutput("begin\n %s := nil;\n",BaseName
);
10965 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10966 DoOutput(" if %s <> nil then begin\n",BaseName
);
10967 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10968 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10969 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper
);
10970 DoOutput(" end else begin\n");
10971 DoOutput(" MessageBox('FPC Pascal Error',\n");
10972 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10973 DoOutput(" 'Deallocating resources and closing down',\n");
10974 DoOutput(" 'Oops');\n");
10975 DoOutput(" halt(20);\n");
10976 DoOutput(" end;\n\n");
10977 DoOutput("{$endif use_auto_openlib}\n\n");
10979 DoOutput("{$ifdef dont_use_openlib}\n");
10980 DoOutput("begin\n");
10981 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper
);
10982 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName
);
10983 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName
);
10984 DoOutput("{$endif dont_use_openlib}\n\n");
10986 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper
);
10989 static uint32
CreateBMAP(void)
10991 return CallFunc(TAGMODE_NORMAL
, 0, FuncBMAP
);
10994 static uint32
CreateLVOLib(void)
10998 i
= strlen(ShortBaseNameUpper
);
10999 EndPutM32(tempbuf
, HUNK_UNIT
);
11000 EndPutM32(tempbuf
+4, (i
+3)>>2);
11001 DoOutputDirect(tempbuf
, 8);
11002 DoOutputDirect(ShortBaseNameUpper
, i
);
11003 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11005 i
= strlen(hunkname
);
11006 EndPutM32(tempbuf
, HUNK_NAME
);
11007 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11008 DoOutputDirect(tempbuf
, 8);
11009 DoOutputDirect(hunkname
, i
);
11010 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11012 EndPutM32(tempbuf
, HUNK_CODE
);
11013 EndPutM32(tempbuf
+4, 0);
11014 EndPutM32(tempbuf
+8, HUNK_EXT
);
11015 DoOutputDirect(tempbuf
, 12);
11017 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOLib
))
11020 EndPutM32(tempbuf
, 0);
11021 EndPutM32(tempbuf
+4, HUNK_END
);
11022 return DoOutputDirect(tempbuf
, 8);
11025 static uint32
CreateLVOLibPPC(void)
11027 uint8
*data
= tempbuf
, *data2
, *data3
;
11029 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11030 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11031 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11032 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11033 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
11034 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
11035 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
11036 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11037 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11038 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11039 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
11040 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
11041 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
11042 EndPutM32Inc(data
, 0); /* eeh->e_entry */
11043 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
11044 data2
= data
; data
+= 4;
11045 EndPutM32Inc(data
, 0); /* eeh->e_flags */
11046 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
11047 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
11048 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
11049 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
11050 EndPutM16Inc(data
, 4); /* eeh->e_shnum */
11051 EndPutM16Inc(data
, 1); /* eeh->e_shstrndx - first table is string table */
11054 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11055 data
+= 28; /* 1 9 17*/
11056 EndPutM32(data2
, data
-tempbuf
); /* store the entry */
11058 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
11059 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
11060 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11061 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11062 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
11063 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
11064 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11065 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11066 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
11067 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11069 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
11070 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
11071 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
11072 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
11073 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[3].sh_offset */
11074 EndPutM32Inc(data
, 27); /* esh[3].sh_size */
11075 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
11076 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
11077 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
11078 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
11080 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
11081 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
11082 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
11083 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
11085 data
+= 4; /* esh[4].sh_offset */
11086 data
+= 4; /* esh[4].sh_size */
11087 EndPutM32Inc(data
, 3); /* esh[4].sh_link - the third entry is our string table */
11088 EndPutM32Inc(data
, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11089 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
11090 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11092 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
11093 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
11094 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11095 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11097 data
+= 4; /* esh[0].sh_offset */
11098 data
+= 4; /* esh[0].sh_size */
11099 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11100 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11101 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
11102 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11104 EndPutM32Inc(data2
, data
-tempbuf
);
11106 EndPutM32Inc(data
,0);
11107 EndPutM32Inc(data
,0); /* first entry is empty */
11108 EndPutM32Inc(data
,0);
11109 EndPutM32Inc(data
,0);
11111 symoffset
= 1; /* initial value */
11114 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCBias
))
11116 EndPutM32(data2
, elfbufpos
-data
+16);
11117 EndPutM32Inc(data3
, elfbufpos
-tempbuf
);
11118 EndPutM32(data3
, symoffset
);
11120 *(elfbufpos
++) = 0; /* first sym entry */
11121 if(!DoOutputDirect(tempbuf
, elfbufpos
-tempbuf
))
11124 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCName
))
11127 while((symoffset
++)&3)
11129 if(!DoOutputDirect("", 1))
11136 static uint32
CreateVBCCInline(uint32 mode
, uint32 callmode
)
11138 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11142 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11145 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11146 ShortBaseNameUpper
, ShortBaseNameUpper
);
11148 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11151 /* always include emul/emulregs.h in MorphOS inlines,
11152 gcc-based sources might depend on it :| */
11153 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11159 DoOutputDirect(HEADER
, headersize
);
11164 if(!CallFunc(callmode
, "/%s */\n", mode
? (mode
== 2 ? FuncVBCCMorphInline
11165 : FuncVBCCWOSInline
) : FuncVBCCInline
))
11168 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper
);
11171 static uint32
CreateVBCC(uint32 mode
, uint32 callmode
)
11175 if(mode
!= 2 && mode
!= 3)
11177 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11182 DoOutputDirect(HEADER
, headersize
);
11188 case 4: res
= CallFunc(callmode
, 0, FuncVBCCPUPText
); break;
11190 case 3: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11191 case 2: res
= CallFunc(callmode
, 0, FuncVBCCWOSCode
); break;
11193 case 1: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11194 case 0: res
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
); break;
11199 static uint32
CreateVBCCPUPLib(uint32 callmode
)
11201 /* output header */
11202 DoOutput("!<arch>\n");
11204 return CallFunc(callmode
, 0, FuncVBCCPUPCode
);
11207 static uint32
CreateVBCCMorphCode(uint32 callmode
)
11209 /* output header */
11210 DoOutput("!<arch>\n");
11212 return CallFunc(callmode
, 0, FuncVBCCMorphCode
);
11215 static uint32
CreateEModule(uint32 sorted
)
11219 DoError(ERR_NO_SORTED
, 0);
11222 DoOutputDirect("EMOD\0\x06", 6);
11223 for(res
= 0; res
< 2; ++res
)
11225 for(i
= 0; BaseName
[i
]; ++i
)
11226 DoOutput("%c", tolower(BaseName
[i
]));
11227 DoOutputDirect("\x00",1);
11229 LastBias
= BIAS_START
-BIAS_OFFSET
;
11230 CallFunc(TAGMODE_NORMAL
, 0, FuncEModule
);
11231 res
= DoOutputDirect("\xFF",1);
11236 static uint32
CreateProtoRedirect(void)
11238 Flags
|= FLAG_DONE
;
11239 return DoOutput("#ifdef NO_OBSOLETE\n"
11240 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11241 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName
);
11244 static uint32
CreateSFD(uint32 callmode
)
11246 struct Include
*inc
;
11247 struct AmiPragma
*ap
;
11250 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11253 if((ap
= (struct AmiPragma
*) AmiPragma
.First
))
11254 LastBias
= ap
->Bias
-BIAS_OFFSET
;
11255 else /* only security, never used normally */
11257 CurrentABI
= ABI_M68K
;
11260 DoOutput("==id %s\n", IDstring
);
11267 tim
= localtime(&t
);
11269 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11270 "noname Exp $\n", '$', filename
, tim
->tm_year
+1900, tim
->tm_mon
+1,
11271 tim
->tm_mday
, tim
->tm_hour
, tim
->tm_min
, tim
->tm_sec
);
11275 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11276 GetLibraryName(), BaseName
, GetBaseType(), GetLibraryName());
11277 DoOutput("==bias %ld\n==public\n", LastBias
+BIAS_OFFSET
);
11279 for(inc
= (struct Include
*) Includes
.First
; inc
; inc
= (struct Include
*) inc
->List
.Next
)
11280 DoOutput("==include %s\n", inc
->Include
);
11281 if(!Includes
.First
)
11282 DoOutput("==include <exec/types.h>\n");
11284 CallFunc(callmode
, "%s\n", FuncSFD
);
11286 return DoOutput("==end\n");
11289 static uint32
CreateClib(uint32 callmode
)
11293 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11296 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11298 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper
,
11299 ShortBaseNameUpper
);
11304 DoOutputDirect(HEADER
, headersize
);
11313 tim
= localtime(&t
);
11317 s
= SkipBlanks(IDstring
+4);
11318 while(*s
&& *s
!= ' ')
11325 if(Flags2
& FLAG2_SYSTEMRELEASE
)
11327 DoOutput("\n/*\n**\t$Id: %s %s\n", filename
, s
);
11334 while(*t
&& *t
!= ' ')
11338 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename
, s
,
11339 tim
->tm_mday
, tim
->tm_mon
+1, tim
->tm_year
+1900);
11341 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11342 if(!Copyright
|| (Copyright
&& strncmp("Copyright ", Copyright
, 10)))
11343 DoOutput("Copyright %c %d ", 0xa9, tim
->tm_year
+1900);
11344 DoOutput("%s\n", Copyright
? Copyright
: Flags2
& FLAG2_SYSTEMRELEASE
?
11345 "Amiga, Inc." : "");
11346 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11351 if((Flags
& FLAG_EXTERNC
) &&
11352 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11355 CallFunc(callmode
, "\n/%s */\n\n", FuncClib
);
11357 if((Flags
& FLAG_EXTERNC
) &&
11358 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11361 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper
);
11364 static uint32
CreateFD(void)
11367 CurrentABI
= ABI_M68K
;
11370 DoOutput("##base _%s\n", BaseName
);
11371 DoOutput("##public\n");
11373 CallFunc(TAGMODE_NORMAL
, "%s\n", FuncFD
);
11375 return DoOutput("##end\n");
11378 static uint32
CreateGenAuto(strptr to
, uint32 type
)
11380 strptr name
, btype
;
11382 uint32 i
, verref
, exitfuncref
, sysref2
, exitref
, rel1
, rel2
, nameref
;
11383 if(!(name
= GetLibraryName()))
11385 btype
= GetBaseType();
11390 Flags
|= FLAG_DONE
;
11391 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11392 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11393 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11394 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11395 btype
, BaseName
, BaseName
,
11396 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", name
, BaseName
,
11397 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", BaseName
)))
11399 sprintf(filename
, "%s_autoopenver.c", ShortBaseName
);
11400 if(!CloseDest(to
) || !OpenDest(filename
))
11402 Flags
|= FLAG_DONE
;
11403 return DoOutput("unsigned long _%sVer = 0;\n", BaseName
);
11406 Flags
|= FLAG_DONE
;
11407 i
= strlen(filename
)-4; /* remove .lib extension */
11408 EndPutM32(tempbuf
, HUNK_UNIT
);
11409 EndPutM32(tempbuf
+4, (i
+3)>>2);
11410 DoOutputDirect(tempbuf
, 8);
11411 DoOutputDirect(filename
, i
);
11412 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11414 i
= strlen(hunkname
);
11415 EndPutM32(tempbuf
, HUNK_NAME
);
11416 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11417 DoOutputDirect(tempbuf
, 8);
11418 DoOutputDirect(hunkname
, i
);
11419 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11421 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
11422 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11424 if(Flags
& FLAG_SMALLDATA
)
11426 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11427 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11431 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11432 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11434 verref
= data
-tempbuf
-8+2;
11435 if(Flags
& FLAG_SMALLDATA
)
11437 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11438 EndPutM16Inc(data
, 0); /* place for basevers reference */
11442 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11443 EndPutM32Inc(data
, 0); /* place for basevers reference */
11445 EndPutM32Inc(data
, 0x43FA0030 + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2) + ((Flags
& FLAG_SMALLDATA
) ? 0 : 6));
11446 EndPutM32Inc(data
, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11448 rel1
= data
-tempbuf
-8+2;
11449 if(Flags
& FLAG_SMALLDATA
)
11451 EndPutM16Inc(data
, 0x2940); /* MOVE.L D0,xxx(A4) */
11452 EndPutM16Inc(data
, 0);
11456 EndPutM16Inc(data
, 0x23C0); /* MOVE.L D0,xxx */
11457 EndPutM32Inc(data
, 0);
11459 EndPutM16Inc(data
, 0x660A + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2)); /* BNE.B .lib */
11460 EndPutM32Inc(data
, 0x48780014); /* PEA 20 */
11462 exitfuncref
= data
-tempbuf
-8+2;
11463 if(Flags2
& FLAG2_SMALLCODE
)
11465 EndPutM16Inc(data
, 0x4EBA); /* JSR _exit(PC) */
11466 EndPutM16Inc(data
, 0); /* place for base reference */
11470 EndPutM16Inc(data
, 0x4EB9); /* JSR _exit */
11471 EndPutM32Inc(data
, 0); /* place for base reference */
11473 EndPutM16Inc(data
, 0x584F); /* ADDQ.W, #4,A7 */
11474 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11475 EndPutM16Inc(data
,0x4E75); /* RTS */
11476 exitref
= data
-tempbuf
-8;
11478 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11479 sysref2
= data
-tempbuf
-8+2;
11481 if(Flags
& FLAG_SMALLDATA
)
11483 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11484 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11488 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11489 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11491 rel2
= data
-tempbuf
-8+2;
11492 if(Flags
& FLAG_SMALLDATA
)
11494 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11495 EndPutM16Inc(data
, 0); /* place for base reference */
11499 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11500 EndPutM32Inc(data
, 0); /* place for base reference */
11502 EndPutM16Inc(data
, 0x6606); /* BNE.B .nolib */
11503 EndPutM16Inc(data
, 0x2240); /* MOVEA.L D0,A1 */
11505 EndPutM32Inc(data
, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11506 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11507 EndPutM16Inc(data
,0x4E75); /* RTS */
11508 nameref
= data
-tempbuf
-8;
11509 memcpy(data
, name
, strlen(name
));
11510 data
+= strlen(name
);
11511 do { *(data
++) = 0; } while((data
-tempbuf
)&3);
11513 EndPutM32(tempbuf
, HUNK_CODE
);
11514 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
11515 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
11517 if(Flags
& FLAG_SMALLDATA
)
11519 EndPutM32(tempbuf
, HUNK_DREL16
);
11523 EndPutM32(tempbuf
, HUNK_ABSRELOC32
);
11525 EndPutM32(tempbuf
+4, 2); /* 2 entries */
11526 EndPutM32(tempbuf
+8, 1); /* to hunk 1 */
11527 EndPutM32(tempbuf
+12, rel1
); /* address 0 */
11528 EndPutM32(tempbuf
+16, rel2
); /* address 0 */
11529 EndPutM32(tempbuf
+20, 0); /* end of reloc hunk */
11530 DoOutputDirect(tempbuf
, 24);
11532 /* extern references */
11533 EndPutM32(tempbuf
, HUNK_EXT
);
11534 DoOutputDirect(tempbuf
, 4);
11536 OutputXREF2(4, sysref2
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "_SysBase");
11537 OutputXREF(verref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "__%sVer", BaseName
);
11538 OutputXREF(exitfuncref
, (Flags2
& FLAG2_SMALLCODE
? EXT_DEXT16
: EXT_REF32
), "_exit");
11539 OutputXDEF(0, "__INIT_%ld_%s", priority
, BaseName
);
11540 OutputXDEF(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11541 OutputXDEF(nameref
, "%sname", ShortBaseName
);
11542 EndPutM32(tempbuf
, 0); /* ext end */
11543 DoOutputDirect(tempbuf
, 4);
11545 if(!(Flags
& FLAG_NOSYMBOL
))
11547 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11548 DoOutputDirect(tempbuf
, 4);
11549 OutputSYMBOL(0, "__INIT_%ld_%s", priority
, BaseName
);
11550 OutputSYMBOL(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11551 OutputSYMBOL(nameref
, "%sname", ShortBaseName
);
11552 EndPutM32(tempbuf
, 0);
11553 DoOutputDirect(tempbuf
, 4);
11556 EndPutM32(tempbuf
, HUNK_END
);
11557 DoOutputDirect(tempbuf
, 4);
11559 i
= strlen(datahunkname
);
11560 EndPutM32(tempbuf
, HUNK_NAME
);
11561 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11562 DoOutputDirect(tempbuf
, 8);
11563 DoOutputDirect(datahunkname
, i
);
11564 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11566 EndPutM32(tempbuf
, HUNK_BSS
);
11567 EndPutM32(tempbuf
+4, 1);
11568 DoOutputDirect(tempbuf
, 8);
11570 EndPutM32(tempbuf
, HUNK_EXT
);
11571 DoOutputDirect(tempbuf
, 4);
11572 OutputXDEF(0, "_%s", BaseName
);
11573 EndPutM32(tempbuf
, 0); /* ext end */
11574 DoOutputDirect(tempbuf
, 4);
11576 if(!(Flags
& FLAG_NOSYMBOL
))
11578 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11579 DoOutputDirect(tempbuf
, 4);
11580 OutputSYMBOL(0, "_%s", BaseName
);
11581 EndPutM32(tempbuf
, 0);
11582 DoOutputDirect(tempbuf
, 4);
11585 EndPutM32(tempbuf
, HUNK_END
);
11586 DoOutputDirect(tempbuf
, 4);
11588 sprintf(filename
, "%s_autoopenver", ShortBaseName
);
11589 i
= strlen(filename
);
11590 EndPutM32(tempbuf
, HUNK_UNIT
);
11591 EndPutM32(tempbuf
+4, (i
+3)>>2);
11592 DoOutputDirect(tempbuf
, 8);
11593 DoOutputDirect(filename
, i
);
11594 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11596 i
= strlen(datahunkname
);
11597 EndPutM32(tempbuf
, HUNK_NAME
);
11598 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11599 DoOutputDirect(tempbuf
, 8);
11600 DoOutputDirect(datahunkname
, i
);
11601 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11603 EndPutM32(tempbuf
, HUNK_BSS
);
11604 EndPutM32(tempbuf
+4, 1);
11605 DoOutputDirect(tempbuf
, 8);
11607 EndPutM32(tempbuf
, HUNK_EXT
);
11608 DoOutputDirect(tempbuf
, 4);
11609 OutputXDEF(0, "_%sVer", BaseName
);
11610 EndPutM32(tempbuf
, 0); /* ext end */
11611 DoOutputDirect(tempbuf
, 4);
11613 if(!(Flags
& FLAG_NOSYMBOL
))
11615 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11616 DoOutputDirect(tempbuf
, 4);
11617 OutputSYMBOL(0, "_%sVer", BaseName
);
11618 EndPutM32(tempbuf
, 0);
11619 DoOutputDirect(tempbuf
, 4);
11622 EndPutM32(tempbuf
, HUNK_END
);
11623 return DoOutputDirect(tempbuf
, 4);
11630 static uint32
CreateXML(void)
11632 struct Include
*inc
;
11637 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11638 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11639 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11640 ShortBaseName
, BaseName
, GetLibraryName());
11641 basetypelib
= GetBaseTypeLib();
11642 if(basetypelib
&& (strcmp(basetypelib
, "Library") != 0))
11643 DoOutput(" basetype=\"%s\"", basetypelib
);
11645 for(inc
= (struct Include
*) Includes
.First
; inc
;
11646 inc
= (struct Include
*) inc
->List
.Next
)
11647 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc
->Include
)-2),
11649 if(!Includes
.First
)
11650 DoOutput("\t<include>exec/types.h</include>\n");
11652 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11653 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11654 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11656 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11657 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11658 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11659 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11660 " status=\"unimplemented\"/>\n");
11662 CallFunc(TAGMODE_BOTH
, 0, FuncXML
);
11664 return DoOutput("\t</interface>\n</library>\n");
11667 static uint32
CreateOS4PPC(uint32 callmode
)
11669 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11674 DoOutputDirect(HEADER
, headersize
);
11680 "#include <stdarg.h>\n"
11681 "#include <exec/types.h>\n"
11682 "#include <exec/interfaces.h>\n"
11683 "#include <exec/emulation.h>\n"
11684 "#include <interfaces/exec.h>\n");
11686 if(!stricmp("exec",ShortBaseName
))
11687 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName
);
11689 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName
);
11691 CallFunc(callmode
, "\n/%s */\n\n", FuncOS4PPC
);
11694 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11695 " return Self->Data.RefCount++;\n}\n\n"
11696 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11697 " return Self->Data.RefCount--;\n}\n\n"
11698 "#define LIBNAME \"%s\"\n"
11699 "#define LIBVERSION 0\n"
11700 "#define IFACENAME \"%s.main\"\n\n",
11701 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11702 GetLibraryName(), GetLibraryName());
11704 /* following text is constant */
11706 "static void InitFunction(APTR dummy, ULONG SegList, "
11707 "struct ExecBase *ExecBase)\n{\n"
11708 " struct Library *LibBase;\n"
11709 " struct ExecIFace *IExec = (struct ExecIFace *)"
11710 "ExecBase->MainInterface;\n"
11711 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11713 " struct Interface *NewInterface;\n"
11714 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11715 " MIT_VectorTable, main_vectors,\n"
11716 " MIT_Version, 1,\n"
11717 " MIT_Name, IFACENAME,\n"
11720 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11721 " IExec->AddInterface(LibBase, NewInterface);\n"
11725 "volatile static struct Resident MyResident =\n{\n"
11726 " RTC_MATCHWORD,\n"
11727 " (struct Resident *)&MyResident,\n"
11728 " (APTR)(&MyResident+1),\n"
11737 "void _start(void)\n"
11738 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11742 static uint32
CreateOS4M68K(void)
11744 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11749 DoOutputDirect(HEADER
, headersize
);
11752 "#include \"exec/interfaces.i\"\n"
11753 "#include \"exec/libraries.i\"\n"
11754 "#include \"exec/emulation.i\"\n"
11755 "#include \"interfaces/%s.i\"\n\n",ShortBaseName
);
11758 "\t.section .data\n"
11759 "\t.globl\tstub_Open\n"
11760 "\t.type\tstub_Open,@function\n"
11763 "\t.short\t0x4ef8\n" /* JMP.w */
11764 "\t.short\t0\n" /* Indicate switch */
11765 "\t.short\t1\n" /* Trap type */
11766 "\t.globl\tstub_OpenPPC\n"
11767 "\t.long\tstub_OpenPPC\n"
11768 "\t.byte\t2\n" /* Register mapping */
11769 "\t.byte\t1,REG68K_A7\n"
11770 "\t.byte\t3,REG68K_A6\n"
11771 "\t.section .text\n"
11775 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11776 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11777 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11778 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11779 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11780 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11781 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11782 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11783 "\tCallLib\tlmi_Open\n"
11784 "\tlwz\t%s11,%s12(%s1)\n"
11786 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11787 "\tblrl\n" /* Return to emulation */
11789 "\t.globl\tstub_Open68K\n"
11790 "\t.long\tstub_Open68K\n"
11791 "\t.byte\t0\n" /* Flags */
11792 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11793 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11794 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11795 "\t.section .data\n"
11799 "\t.short\t0x4e75\n" /* RTS */
11801 "\t.section .data\n"
11802 "\t.globl\tstub_Close\n"
11803 "\t.type\tstub_Close,@function\n"
11806 "\t.short\t0x4ef8\n" /* JMP.w */
11807 "\t.short\t0\n" /* Indicate switch */
11808 "\t.short\t1\n" /* Trap type */
11809 "\t.globl\tstub_ClosePPC\n"
11810 "\t.long\tstub_ClosePPC\n"
11811 "\t.byte\t2\n" /* Register mapping */
11812 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11813 "\t.byte\t3,REG68K_A6\n"
11814 "\t.section .text\n"
11818 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11819 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11820 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11821 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11822 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11823 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11824 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11825 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11826 "\tCallLib\tlmi_Close\n"
11827 "\tlwz\t%s11,12(%s1)\n"
11829 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11830 "\tblrl\n" /* Return to emulation */
11832 "\t.globl\tstub_Close68K\n"
11833 "\t.long\tstub_Close68K\n"
11834 "\t.byte\t0\n" /* Flags */
11835 "\t.byte\t1\n" /* One register (a7 only) */
11836 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11837 "\t.section .data\n"
11841 "\t.short\t0x4e75\n" /* RTS */
11843 "\t.section .data\n"
11844 "\t.globl\tstub_Expunge\n"
11845 "\t.type\tstub_Expunge,@function\n"
11848 "\t.short\t0x7000\n" /* moveq #0, d0 */
11849 "\t.short\t0x4e75\n" /* RTS */
11851 "\t.section .data\n"
11852 "\t.globl\tstub_Reserved\n"
11853 "\t.type\tstub_Reserved,@function\n"
11856 "\t.short\t0x7000\n" /* moveq #0, d0 */
11857 "\t.short\t0x4e75\n\n", /* RTS */
11858 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11859 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11860 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11861 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11862 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11863 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11864 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11865 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11866 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
11868 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68K
);
11870 "\t.globl\tVector68K\n"
11871 "\t.globl\tVecTable68K\n"
11873 "\t.long\tVecTable68K\n"
11875 "\t.long\tstub_Open\n"
11876 "\t.long\tstub_Close\n"
11877 "\t.long\tstub_Expunge\n"
11878 "\t.long\tstub_Reserved\n");
11881 CallFunc(TAGMODE_NORMAL
, 0, FuncOS4M68KVect
);
11882 DoOutput("\t.long\t-1\n");
11884 CloseDest(filename
);
11886 if(Flags2
& FLAG2_OS4M68KCSTUB
)
11888 sprintf(filename
, "%s_68k.c", ShortBaseName
);
11889 if(!OpenDest(filename
))
11891 Flags
&= ~(FLAG_DONE
);
11892 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11897 DoOutputDirect(HEADER
, headersize
);
11901 "#ifdef __USE_INLINE__\n"
11902 "#undef __USE_INLINE__\n"
11904 "#ifndef __NOGLOBALIFACE__\n"
11905 "#define __NOGLOBALIFACE__\n"
11907 "#include <exec/interfaces.h>\n"
11908 "#include <exec/libraries.h>\n"
11909 "#include <exec/emulation.h>\n"
11910 "#include <interfaces/exec.h>\n"
11911 "#include <interfaces/%s.h>\n"
11912 "#include <proto/%s.h>\n\n", ShortBaseName
, ShortBaseName
);
11914 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68KCSTUB
);
11916 return Output_Error
;
11919 /* ------------------------------------------------------------------ */
11921 static uint32
GetName(struct NameList
*t
, struct ShortListRoot
*p
, uint32 args
)
11923 struct NameList
*p2
= (struct NameList
*) p
->First
;
11924 struct AmiPragma ap
;
11925 memset(&ap
, 0, sizeof(struct AmiPragma
));
11926 ap
.FuncName
= t
->NormName
;
11929 ap
.Args
[0].ArgName
= (args
? "args" : "tags");
11930 if(!MakeTagFunction(&ap
))
11936 while(p2
&& (!p2
->PragName
|| strcmp(p2
->PragName
, ap
.TagName
)))
11937 p2
= (struct NameList
*) p2
->List
.Next
;
11942 t
->Type
= (args
? NTP_ARGS
: NTP_TAGS
);
11943 t
->PragName
= ap
.TagName
;
11944 RemoveItem(p
, (struct ShortList
*) p2
);
11947 printf("GetName: name matches - %s _ %s\n", t
->NormName
, t
->PragName
);
11953 static void OptimizeFDData(struct PragData
*pd
)
11956 printf("OptimizeFDData\n");
11961 if(pd
->NumNames
> 1)
11963 struct ShortListRoot n
= {0,0,0}, p
= {0,0,0};
11964 struct NameList
*t
;
11965 while(pd
->Name
.First
) /* sorts in AmiCall and TagCall */
11967 t
= (struct NameList
*) pd
->Name
.First
;
11969 RemoveItem(&pd
->Name
, (struct ShortList
*) t
);
11970 AddItem(t
->PragName
? &p
: &n
, (struct ShortList
*) t
);
11975 t
= (struct NameList
*) n
.First
;
11976 while(p
.First
&& t
)
11978 if(!GetName(t
, &p
, 0))
11984 struct NameList
*t2
= (struct NameList
*) t
->List
.Next
;
11985 RemoveItem(&n
, (struct ShortList
*)t
);
11986 AddItem(&pd
->Name
, (struct ShortList
*) t
);
11990 t
= (struct NameList
*) t
->List
.Next
;
11996 t
= (struct NameList
*) n
.First
;
11997 t
->PragName
= ((struct NameList
*)(p
.First
))->PragName
;
11998 RemoveItem(&n
, (struct ShortList
*) t
);
12000 printf("OptimizeFDData: names together - %s _ %s\n", t
->NormName
, t
->PragName
);
12002 t
->Type
= NTP_UNKNOWN
;
12008 t
= (struct NameList
*) p
.First
;
12009 i
= strlen(t
->PragName
);
12010 t
->NormName
= DupString(t
->PragName
, i
+1);
12011 t
->NormName
[i
++] = 'A';
12012 t
->NormName
[i
] = 0;
12013 t
->Type
= NTP_TAGS
;
12015 printf("OptimizeFDData: NormName created - %s _ %s\n", t
->NormName
, t
->PragName
);
12019 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12020 RemoveItem(&p
, p
.First
);
12024 AddItem(&pd
->Name
, n
.First
); /* add left NormNames */
12026 pd
= (struct PragData
*) pd
->List
.Next
;
12030 static uint32
MakeFD(struct PragList
*pl
)
12032 struct PragData
*pd
= (struct PragData
*) pl
->Data
.First
;
12036 printf("MakeFD\n");
12040 OptimizeFDData(pd
);
12042 printf("MakeFD: after Optimizing\n");
12044 DoOutput("##base _%s\n##bias %ld\n##public\n", pl
->Basename
, bias
);
12046 while(pd
&& Output_Error
)
12048 struct NameList
*n
= (struct NameList
*) pd
->Name
.First
;
12050 if(bias
!= pd
->Bias
)
12051 DoOutput("##bias %ld\n", (bias
= pd
->Bias
));
12055 strptr lastpar
= "last";
12058 if(n
->Type
== NTP_TAGS
)
12060 else if(n
->Type
== NTP_ARGS
)
12063 DoOutput("%s("/*)*/,n
->NormName
);
12065 DoOutput(/*(*/")()\n");
12068 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12069 DoOutput("par%ld,",i
+1);
12070 DoOutput(/*(*/"%s)("/*)*/, lastpar
);
12071 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12072 DoOutput("%s,", RegNames
[pd
->ArgReg
[i
]]);
12073 DoOutput(/*(*/"%s)\n", RegNames
[pd
->ArgReg
[i
]]);
12075 if(n
->Type
== NTP_UNKNOWN
)
12078 for(i
= 0; n
->NormName
[i
] == n
->PragName
[i
]; ++i
)
12080 DoOutput("*tagcall");
12082 DoOutput("-%s", n
->NormName
+i
);
12084 DoOutput("+%s", n
->PragName
+i
);
12089 if((n
= (struct NameList
*) n
->List
.Next
))
12090 DoOutput("##bias %ld\n", pd
->Bias
);
12091 Flags
|= FLAG_DONE
;
12094 pd
= (struct PragData
*)pd
->List
.Next
; bias
+= BIAS_OFFSET
;
12097 DoOutput("##end\n");
12099 return Output_Error
;
12102 static uint32
AddFDData(struct ShortListRoot
*pls
, struct FDData
*fd
)
12104 struct NameList
*t
;
12105 struct PragList
*pl
= (struct PragList
*) pls
->First
;
12106 struct PragData
*pd
;
12108 while(pl
&& strcmp(pl
->Basename
, fd
->Basename
))
12109 pl
= (struct PragList
*) pl
->List
.Next
;
12114 printf("AddFDData: New PragList - %s\n", fd
->Basename
);
12116 if(!(pl
= (struct PragList
*) NewItem(pls
)))
12118 pl
->Basename
= fd
->Basename
;
12119 pl
->Data
.Size
= sizeof(struct PragData
);
12120 AddItem(pls
, (struct ShortList
*) pl
);
12123 if((pd
= (struct PragData
*) pl
->Data
.First
))
12125 while(pd
->List
.Next
&& ((struct PragData
*) pd
->List
.Next
)->Bias
12127 pd
= (struct PragData
*) pd
->List
.Next
;
12130 if(!pd
|| pd
->Bias
!= fd
->Bias
)
12132 struct PragData
*pd2
;
12134 printf("AddFDData: New PragData - %ld, %ld\n", fd
->Bias
, fd
->NumArgs
);
12136 if(!(pd2
= (struct PragData
*) NewItem(&pl
->Data
)))
12138 pd2
->Bias
= fd
->Bias
;
12139 memcpy(pd2
->ArgReg
, fd
->ArgReg
, MAXREG
);
12140 pd2
->NumArgs
= fd
->NumArgs
;
12141 pd2
->Name
.Size
= sizeof(struct NameList
);
12143 AddItem(&pl
->Data
, (struct ShortList
*) pd2
);
12144 else if(pd
->Bias
> fd
->Bias
) /* Insert at start */
12146 pd2
->List
.Next
= pl
->Data
.First
;
12147 pl
->Data
.First
= (struct ShortList
*) pd2
;
12149 else /* Insert the entry */
12151 pd2
->List
.Next
= pd
->List
.Next
;
12152 pd
->List
.Next
= (struct ShortList
*) pd2
;
12158 uint32 i
= fd
->NumArgs
;
12159 if(fd
->NumArgs
!= pd
->NumArgs
)
12162 printf("ArgNum %ld != %ld\n", fd
->NumArgs
, pd
->NumArgs
);
12164 return ERR_DIFFERENT_TO_PREVIOUS
;
12169 if(fd
->ArgReg
[i
] != pd
->ArgReg
[i
])
12172 printf("ArgReg %x != %x\n", fd
->ArgReg
[i
], pd
->ArgReg
[i
]);
12174 return ERR_DIFFERENT_TO_PREVIOUS
;
12179 t
= (struct NameList
*) pd
->Name
.First
; /* skips same names */
12180 while(t
&& (!(fd
->Mode
? t
->PragName
: t
->NormName
) ||
12181 strcmp(fd
->Name
, fd
->Mode
? t
->PragName
: t
->NormName
)))
12182 t
= (struct NameList
*) t
->List
.Next
;
12187 if(!(t
= (struct NameList
*) NewItem(&pd
->Name
)))
12190 t
->PragName
= fd
->Name
;
12192 t
->NormName
= fd
->Name
;
12193 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12196 printf("AddFDData: New NameList - %s\n", fd
->Name
);
12201 static string
GetHexValue(string data
)
12204 return (string
) (data
- 'a' + 10);
12205 else if(data
>= 'A')
12206 return (string
) (data
- 'A' + 10);
12208 return (string
) (data
- '0');
12211 static string
GetDoubleHexValue(strptr data
)
12213 return (string
)((GetHexValue(*data
)<<4)+GetHexValue(data
[1]));
12216 static uint32
GetLibData(struct FDData
*fd
)
12219 fd
->Name
= SkipBlanks(in
.pos
);
12220 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12221 in
.pos
= SkipBlanks(in
.pos
);
12222 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12223 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
)));
12224 if((fd
->NumArgs
= GetHexValue(*(--in
.pos
))) > MAXREGNF
- 2)
12225 return ERR_TO_MUCH_ARGUMENTS
;
12226 --in
.pos
; /* skips return register */
12227 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12229 if((fd
->ArgReg
[i
] = GetHexValue(*(--in
.pos
))) > REG_A5
)
12230 return ERR_EXPECTED_REGISTER_NAME
;
12235 static uint32
GetFlibData(struct FDData
*fd
)
12238 fd
->Name
= SkipBlanks(in
.pos
);
12239 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12240 in
.pos
= SkipBlanks(in
.pos
);
12241 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12242 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
))) - 2;
12243 if((fd
->NumArgs
= GetDoubleHexValue(in
.pos
)) > MAXREG
-2)
12244 return ERR_TO_MUCH_ARGUMENTS
;
12245 in
.pos
-= 2; /* skips return register */
12246 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12249 if((fd
->ArgReg
[i
] = GetDoubleHexValue(in
.pos
)) >= MAXREG
)
12250 return ERR_EXPECTED_REGISTER_NAME
;
12251 else if(fd
->ArgReg
[i
] >= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12252 return ERR_FLOATARG_NOT_ALLOWED
;
12257 static uint32
GetAmiData(struct FDData
*fd
)
12260 in
.pos
= SkipBlanks(in
.pos
);
12261 if(*in
.pos
!= '('/*)*/)
12262 return ERR_EXPECTED_OPEN_BRACKET
;
12263 fd
->Basename
= ++in
.pos
;
12264 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12266 return ERR_EXPECTED_COMMA
;
12268 in
.pos
= SkipBlanks(++in
.pos
);
12269 if(!strncmp(in
.pos
, "0x", 2))
12270 fd
->Bias
= strtoul(in
.pos
+2, 0, 16);
12272 fd
->Bias
= strtoul(in
.pos
, 0, 10);
12274 in
.pos
= SkipBlanks(SkipName(in
.pos
));
12276 return ERR_EXPECTED_COMMA
;
12277 fd
->Name
= in
.pos
= SkipBlanks(++in
.pos
);
12278 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12279 if(*in
.pos
!= '('/*)*/)
12280 return ERR_EXPECTED_OPEN_BRACKET
;
12282 in
.pos
= SkipBlanks(++in
.pos
);
12283 if(*in
.pos
== /*(*/')')
12286 while(*in
.pos
!= /*(*/')')
12289 in
.pos
= SkipBlanks(in
.pos
+1);
12291 for(i
= 0; i
< REG_FP0
; i
++)
12292 if(!strnicmp(RegNames
[i
], in
.pos
, 2))
12296 for(; i
< MAXREG
; i
++)
12297 if(!strnicmp(RegNames
[i
], in
.pos
, 3))
12302 return ERR_EXPECTED_REGISTER_NAME
;
12303 else if(i
>= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12304 return ERR_FLOATARG_NOT_ALLOWED
;
12306 fd
->ArgReg
[fd
->NumArgs
] = i
; ++fd
->NumArgs
;
12308 if(fd
->NumArgs
> MAXREG
-2)
12309 return ERR_TO_MUCH_ARGUMENTS
;
12311 in
.pos
= SkipBlanks(in
.pos
+(i
>= REG_FP0
? 3 : 2));
12313 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
12314 return ERR_EXPECTED_CLOSE_BRACKET
;
12316 in
.pos
= SkipBlanks(in
.pos
+1);
12317 if(*in
.pos
!= /*(*/')')
12318 return ERR_EXPECTED_CLOSE_BRACKET
;
12322 static uint32
CreateFDFile(void)
12324 struct ShortListRoot pl
= {0, 0, sizeof(struct PragList
)};
12325 uint32 linenum
, err
= 0, skip
;
12328 ptr
= p2
= args
.infile
;
12331 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
12335 for(p2
= ptr
; *p2
&& *p2
!= '_' && *p2
!= '.'; ++p2
)
12339 ShortBaseName
= ptr
;
12343 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
12345 in
.pos
= SkipBlanks(in
.pos
);
12346 if(!strncmp("#pragma", in
.pos
, 7))
12351 memset(&fd
, 0, sizeof(struct FDData
));
12353 in
.pos
= SkipBlanks(in
.pos
+7);
12354 if(!strncmp("tagcall", in
.pos
, 7))
12357 in
.pos
= SkipBlanks(in
.pos
+7);
12358 if(*in
.pos
== '(' /*)*/) /* Storm method */
12359 err
= GetAmiData(&fd
);
12360 else /* SAS method */
12362 fd
.Basename
= in
.pos
;
12363 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12364 err
= GetLibData(&fd
);
12367 else if(!strncmp("amicall", in
.pos
, 7)) /* Storm method */
12370 err
= GetAmiData(&fd
);
12372 else if(!strncmp("libcall", in
.pos
, 7)) /* SAS method */
12374 fd
.Basename
= SkipBlanks(in
.pos
+7);
12375 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12376 err
= GetLibData(&fd
);
12378 else if(!strncmp("flibcall", in
.pos
, 8)) /* SAS method */
12380 fd
.Basename
= SkipBlanks(in
.pos
+8);
12381 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12382 err
= GetFlibData(&fd
);
12384 else if(!strncmp("syscall", in
.pos
, 7)) /* SAS method */
12386 fd
.Basename
= "SysBase";
12387 err
= GetLibData(&fd
);
12393 DoError(err
, linenum
);
12396 else if((err
= AddFDData(&pl
, &fd
)))
12399 DoError(err
, linenum
);
12403 while(*(in
.pos
++)) /* jumps to first char of next line */
12409 struct PragList
*p
= (struct PragList
*) pl
.First
;
12417 text
= ShortBaseName
; i
= strlen(text
);
12421 text
= p
->Basename
; i
= strlen(text
)-4;
12424 to
= DupString(text
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12425 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12440 i
= strlen(p
->Basename
) - 4;
12441 to
= DupString(p
->Basename
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12442 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12449 p
= (struct PragList
*) p
->List
.Next
;
12457 #ifdef FD2PRAGMA_READARGS
12458 #include <proto/dos.h>
12460 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12461 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12462 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12463 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12464 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12466 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12467 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12468 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12469 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12497 uint32 NOPPCREGNAME
;
12508 uint32 SYSTEMRELEASE
;
12513 static const strptr helptext
=
12514 "INFILE: the input file which should be used\n"
12515 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12516 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12517 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12518 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12519 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12520 "\t 6 - pragma for all compilers [default]\n"
12521 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12522 "\t10 - stub-functions for C - C text\n"
12523 "\t11 - stub-functions for C - assembler text\n"
12524 "\t12 - stub-functions for C - link library\n"
12525 "\t13 - defines and link library for local library base (register call)\n"
12526 "\t14 - defines and link library for local library base (stack call)\n"
12527 "\t15 - stub-functions for Pascal - assembler text\n"
12528 "\t16 - stub-functions for Pascal - link library\n"
12529 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12530 "\t18 - module for AmigaE\n"
12531 "\t20 - assembler lvo _lvo.i file\n"
12532 "\t21 - assembler lvo _lib.i file\n"
12533 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12534 "\t23 - assembler lvo _lib.i file no XDEF\n"
12535 "\t24 - assembler lvo link library\n"
12536 "\t30 - proto file with pragma/..._lib.h call\n"
12537 "\t31 - proto file with pragma/..._pragmas.h call\n"
12538 "\t32 - proto file with pragmas/..._lib.h call\n"
12539 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12540 "\t34 - proto file with local/..._loc.h call\n"
12541 "\t35 - proto file for all compilers (VBCC stubs)\n"
12542 "\t36 - proto file for GNU-C compiler only\n"
12543 "\t37 - proto file without lib definitions\n"
12544 "\t38 - proto file for all compilers (VBCC inline)\n"
12545 "\t39 - proto file with special PPC related checks\n"
12546 "\t40 - GCC inline file (preprocessor based)\n"
12547 "\t41 - GCC inline file (old type - inline based)\n"
12548 "\t42 - GCC inline file (library stubs)\n"
12549 "\t43 - GCC inline file (new style - macro)\n"
12550 "\t44 - GCC inline file (new style - inline)\n"
12551 "\t45 - GCC inline file (new style - inline with include lines)\n"
12552 "\t46 - GCC inline file (preprocessor based, direct)\n"
12553 "\t47 - GCC inline file (new style, direct)\n"
12554 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12555 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12556 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12557 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12558 "\t53 - SAS-C include file for PowerUP\n"
12559 "\t54 - Proto file for PowerUP\n"
12560 "\t60 - FPC pascal unit text\n"
12561 "\t70 - VBCC inline files\n"
12562 "\t71 - VBCC WOS stub-functions - assembler text\n"
12563 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12564 "\t73 - VBCC WOS stub-functions - link library\n"
12565 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12566 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12567 "\t76 - VBCC PowerUP stub-functions - link library\n"
12568 "\t77 - VBCC WOS inline files\n"
12569 "\t78 - VBCC MorphOS stub-functions - link library\n"
12570 "\t79 - VBCC old inline files\n"
12571 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12572 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12573 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12574 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12575 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12576 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12577 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12578 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12579 " 100 - PPC assembler lvo file\n"
12580 " 101 - PPC assembler lvo file no XDEF\n"
12581 " 102 - PPC assembler lvo ELF link library\n"
12582 " 103 - PPC assembler lvo EHF link library\n"
12583 " 104 - PPC V.4-ABI assembler file\n"
12584 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12585 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12586 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12588 " 111 - CLIB file\n"
12589 " 112 - SFD file\n"
12590 " 120 - VBCC auto libopen files (C source)\n"
12591 " 121 - VBCC auto libopen files (m68k link library)\n"
12592 " 122 - VBCC MorphOS inline files\n"
12593 " 123 - VBCC new MorphOS inline files\n"
12594 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12595 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12596 " 132 - GCC inline files for MorphOS (library stubs)\n"
12597 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12598 " 134 - MorphOS gate stubs\n"
12599 " 135 - MorphOS gate stubs (prelib)\n"
12600 " 136 - MorphOS gate stubs (postlib)\n"
12601 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12602 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12603 " 140 - OS4 XML file\n"
12604 " 141 - OS4 PPC->M68K cross-call stubs\n"
12605 " 142 - OS4 M68K->PPC cross-call stubs\n"
12606 " 200 - FD file (source is a pragma file!)\n"
12607 "MODE: SPECIAL 1-7:\n"
12608 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12609 " 2: _PRAGMAS_..._LIB_H definition method\n"
12610 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12611 " 4: no definition\n"
12612 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12614 " 1: all functions, normal interface\n"
12615 " 2: only tag-functions, tagcall interface\n"
12616 " 3: all functions, normal and tagcall interface [default]\n"
12617 "TO: the destination directory (self creation of filename)\n"
12618 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12619 "CLIB: name of the prototypes file in clib directory\n"
12620 "COPYRIGHT: the copyright text for CLIB files\n"
12621 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12622 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12623 "BASENAME: name of library base without '_'\n"
12624 "LIBNAME: name of the library (.e.g. dos.library)\n"
12625 "LIBTYPE: type of base library structure\n"
12626 "PRIORITY: priority for auto open files\n"
12627 "PREFIX: MorphOS gate prefix\n"
12628 "SUBPREFIX: MorphOS gate sub prefix\n"
12629 "PREMACRO: MorphOS gate file start macro\n"
12631 "AUTOHEADER add the typical automatic generated header\n"
12632 "COMMENT: copy comments found in input file\n"
12633 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12634 "FPUONLY: work only with functions using FPU register arguments\n"
12635 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12636 "NOFPU: disable usage of FPU register arguments\n"
12637 "NOPPC: disable usage of PPC-ABI functions\n"
12638 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12639 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12640 "ONLYCNAMES: do not create C++ or ASM names\n"
12641 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12642 "PPCONLY: only use PPC-ABI functions\n"
12643 "PRIVATE: includes private declared functions\n"
12644 "SECTION: add section statements to asm texts\n"
12645 "SMALLCODE: generate small code link libraries or assembler text\n"
12646 "SMALLDATA: generate small data link libraries or assembler text\n"
12647 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12648 "SORTED: sort generated files by name and not by bias value\n"
12649 "SYSTEMRELEASE: special handling of comments for system includes\n"
12650 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12651 "VOIDBASE: library bases are of type void *\n";
12653 /* print the help text */
12654 static void printhelp(void)
12656 printf("%s\n%s\n\n%s", version
+6, PARAM
, helptext
);
12660 /* initializes the arguments and starts argument parsing */
12661 static void GetArgs(int argc
, char **argv
)
12663 struct RDArgs
*rda
;
12664 struct AmiArg amiargs
;
12667 if((rda
= (struct RDArgs
*) AllocDosObject(DOS_RDARGS
, 0)))
12669 rda
->RDA_ExtHelp
= helptext
;
12670 memset(&amiargs
, 0, sizeof(struct AmiArg
));
12671 if(ReadArgs(PARAM
, (int32
*) &amiargs
, rda
))
12676 l
= strlen(amiargs
.TO
? amiargs
.TO
: "") + 1
12677 + strlen(amiargs
.CLIB
? amiargs
.CLIB
: "") + 1
12678 + strlen(amiargs
.HEADER
? amiargs
.HEADER
: "") + 1
12679 + strlen(amiargs
.ABI
? amiargs
.ABI
: "") + 1
12680 + strlen(amiargs
.HUNKNAME
? amiargs
.HUNKNAME
: "") + 1
12681 + strlen(amiargs
.BASENAME
? amiargs
.BASENAME
: "") + 1
12682 + strlen(amiargs
.LIBTYPE
? amiargs
.LIBTYPE
: "") + 1
12683 + strlen(amiargs
.LIBNAME
? amiargs
.LIBNAME
: "") + 1
12684 + strlen(amiargs
.COPYRIGHT
? amiargs
.COPYRIGHT
: "") + 1
12685 + strlen(amiargs
.PREFIX
? amiargs
.PREFIX
: "") + 1
12686 + strlen(amiargs
.SUBPREFIX
? amiargs
.SUBPREFIX
: "") + 1
12687 + strlen(amiargs
.PREMACRO
? amiargs
.PREMACRO
: "") + 1
12688 + strlen(amiargs
.INFILE
) + 1;
12689 if((d
= AllocListMem(l
)))
12693 s
= amiargs
.INFILE
;
12694 args
.infile
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12695 if((s
= amiargs
.TO
))
12697 args
.to
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12699 if((s
= amiargs
.HEADER
))
12701 args
.header
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12703 if((s
= amiargs
.CLIB
))
12705 args
.clib
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12707 if((s
= amiargs
.HUNKNAME
))
12709 hunkname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12711 if((s
= amiargs
.BASENAME
))
12713 Flags
|= FLAG_BASENAME
;
12714 BaseName
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12716 if((s
= amiargs
.LIBTYPE
))
12718 Flags2
|= FLAG2_LIBTYPE
;
12719 libtype
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12721 if((s
= amiargs
.LIBNAME
))
12723 Flags2
|= FLAG2_LIBNAME
;
12724 libname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12726 if((s
= amiargs
.PREFIX
))
12728 prefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12730 if((s
= amiargs
.SUBPREFIX
))
12732 subprefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12734 if((s
= amiargs
.PREMACRO
))
12736 premacro
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12738 if((s
= amiargs
.COPYRIGHT
))
12740 Copyright
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12742 if((s
= amiargs
.ABI
))
12744 defabi
= d
; while(*s
) *(d
++) = *(s
++); *d
= 0;
12746 if(amiargs
.EXTERNC
) Flags
^= FLAG_EXTERNC
;
12747 if(amiargs
.PRIVATE
) Flags
^= FLAG_PRIVATE
;
12748 if(amiargs
.NEWSYNTAX
) Flags
^= FLAG_NEWSYNTAX
;
12749 if(amiargs
.SMALLDATA
) Flags
^= FLAG_SMALLDATA
;
12750 if(amiargs
.SMALLCODE
) Flags2
^= FLAG2_SMALLCODE
;
12751 if(amiargs
.SMALLTYPES
) Flags2
^= FLAG2_SMALLTYPES
;
12752 if(amiargs
.USESYSCALL
) Flags
^= FLAG_SYSCALL
;
12753 if(amiargs
.OPT040
) Flags
^= FLAG_NOMOVEM
;
12754 if(amiargs
.NOFPU
) Flags
^= FLAG_NOFPU
;
12755 if(amiargs
.FPUONLY
) Flags
^= FLAG_FPUONLY
;
12756 if(amiargs
.NOPPC
) Flags
^= FLAG_NOPPC
;
12757 if(amiargs
.NOSYMBOL
) Flags
^= FLAG_NOSYMBOL
;
12758 if(amiargs
.PPCONLY
) Flags
^= FLAG_PPCONLY
;
12759 if(amiargs
.SECTION
) Flags
^= FLAG_ASMSECTION
;
12760 if(amiargs
.COMMENT
) Flags
^= FLAG_DOCOMMENT
;
12761 if(amiargs
.SORTED
) Flags
^= FLAG_SORTED
;
12762 if(amiargs
.ONLYCNAMES
) Flags
^= FLAG_ONLYCNAMES
;
12763 if(amiargs
.SYSTEMRELEASE
) Flags2
^= FLAG2_SYSTEMRELEASE
;
12764 if(amiargs
.VOIDBASE
) Flags2
^= FLAG2_VOIDBASE
;
12765 if(amiargs
.NOPPCREGNAME
) PPCRegPrefix
= "";
12766 if(amiargs
.AUTOHEADER
) Flags2
^= FLAG2_AUTOHEADER
;
12767 if(amiargs
.SPECIAL
)
12768 args
.special
= *amiargs
.SPECIAL
;
12770 args
.mode
= *amiargs
.MODE
;
12771 if(amiargs
.PRIORITY
)
12772 priority
= *amiargs
.PRIORITY
;
12777 PrintFault(IoErr(), 0);
12778 FreeDosObject(DOS_RDARGS
, rda
);
12787 static const strptr helptext
=
12789 " -i,--infile <input filename>\n"
12790 " -s,--special <number>\n"
12791 " -m,--mode <number>\n"
12792 " -t,--to <destination directory>\n"
12793 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12794 " -c,--clib <clib prototypes filename>\n"
12795 " -d,--header <header file or \"\">\n"
12796 " -i,--libname <name of library>\n"
12797 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12798 " -b,--basename <name of library base without '_'>\n"
12799 " -l,--libtype <name of base library type>\n"
12800 " -p,--priority <priority for auto open files>\n"
12801 " -r,--copyright<copyright text>\n"
12802 " --prefix <MorphOS gate prefix>\n"
12803 " --subprefix<MorphOS gate sub prefix>\n"
12804 " --premacro <MorphOS gate file start macro>\n"
12807 "--autoheader add the typical automatic generated header\n"
12808 "--comment copy comments found in input file\n"
12809 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12810 "--fpuonly work only with functions using FPU register arguments\n"
12811 "--newsyntax uses new Motorola syntax for asm files\n"
12812 "--nofpu disable usage of FPU register arguments\n"
12813 "--noppc disable usage of PPC-ABI functions\n"
12814 "--noppcregname do not add 'r' to PPC register names\n"
12815 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12816 "--onlycnames do not create C++ or ASM names\n"
12817 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12818 "--ppconly only use PPC-ABI functions\n"
12819 "--private includes private declared functions\n"
12820 "--section add section statements to asm texts\n"
12821 "--smallcode generate small code link libraries or assembler text\n"
12822 "--smalldata generate small data link libraries or assembler text\n"
12823 "--smalltypes allow 8 and 16 bit types in registers\n"
12824 "--sorted sort generated files by name and not by bias value\n"
12825 "--systemrelease special handling of comments for system includes\n"
12826 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12827 "--voidbase library bases are of type void *\n"
12829 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12830 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12831 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12832 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12833 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12834 " 6 - pragma for all compilers [default]\n"
12835 " 7 - all compilers with pragma to inline redirect for GCC\n"
12836 " 10 - stub-functions for C - C text\n"
12837 " 11 - stub-functions for C - assembler text\n"
12838 " 12 - stub-functions for C - link library\n"
12839 " 13 - defines and link library for local library base (register call)\n"
12840 " 14 - defines and link library for local library base (stack call)\n"
12841 " 15 - stub-functions for Pascal - assembler text\n"
12842 " 16 - stub-functions for Pascal - link library\n"
12843 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12844 " 18 - module for AmigaE\n"
12845 " 20 - assembler lvo _lvo.i file\n"
12846 " 21 - assembler lvo _lib.i file\n"
12847 " 22 - assembler lvo _lvo.i file no XDEF\n"
12848 " 23 - assembler lvo _lib.i file no XDEF\n"
12849 " 24 - assembler lvo link library\n"
12850 " 30 - proto file with pragma/..._lib.h call\n"
12851 " 31 - proto file with pragma/..._pragmas.h call\n"
12852 " 32 - proto file with pragmas/..._lib.h call\n"
12853 " 33 - proto file with pragmas/..._pragmas.h call\n"
12854 " 34 - proto file with local/..._loc.h call\n"
12855 " 35 - proto file for all compilers (VBCC stubs)\n"
12856 " 36 - proto file for GNU-C compiler only\n"
12857 " 37 - proto file without lib definitions\n"
12858 " 38 - proto file for all compilers (VBCC inline)\n"
12859 " 39 - proto file with special PPC related checks\n"
12860 " 40 - GCC inline file (preprocessor based)\n"
12861 " 41 - GCC inline file (old type - inline based)\n"
12862 " 42 - GCC inline file (library stubs)\n"
12863 " 43 - GCC inline file (new style - macro)\n"
12864 " 44 - GCC inline file (new style - inline)\n"
12865 " 45 - GCC inline file (new style - inline with include lines)\n"
12866 " 46 - GCC inline file (preprocessor based, direct)\n"
12867 " 47 - GCC inline file (new style, direct)\n"
12868 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12869 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12870 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12871 " 52 - GCC inline files for PowerUP (library stubs)\n"
12872 " 53 - SAS-C include file for PowerUP\n"
12873 " 54 - Proto file for PowerUP\n"
12874 " 60 - FPC pascal unit text\n"
12875 " 70 - VBCC inline files\n"
12876 " 71 - VBCC WOS stub-functions - assembler text\n"
12877 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12878 " 73 - VBCC WOS stub-functions - link library\n"
12879 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12880 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12881 " 76 - VBCC PowerUP stub-functions - link library\n"
12882 " 77 - VBCC WOS inline files\n"
12883 " 78 - VBCC MorphOS stub-functions - link library\n"
12884 " 79 - VBCC old inline files\n"
12885 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12886 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12887 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12888 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12889 " 90 - stub-functions for C - assembler text (multiple files)\n"
12890 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12891 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12892 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12893 " 100 - PPC assembler lvo file\n"
12894 " 101 - PPC assembler lvo file no XDEF\n"
12895 " 102 - PPC assembler lvo ELF link library\n"
12896 " 103 - PPC assembler lvo EHF link library\n"
12897 " 104 - PPC V.4-ABI assembler file\n"
12898 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12899 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12900 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12902 " 111 - CLIB file\n"
12903 " 112 - SFD file\n"
12904 " 120 - VBCC auto libopen files (C source)\n"
12905 " 121 - VBCC auto libopen files (m68k link library)\n"
12906 " 122 - VBCC MorphOS inline files\n"
12907 " 123 - VBCC new MorphOS inline files\n"
12908 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12909 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12910 " 132 - GCC inline files for MorphOS (library stubs)\n"
12911 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12912 " 134 - MorphOS gate stubs\n"
12913 " 135 - MorphOS gate stubs (prelib)\n"
12914 " 136 - MorphOS gate stubs (postlib)\n"
12915 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12916 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12917 " 140 - OS4 XML file\n"
12918 " 141 - OS4 PPC->M68K cross-call stubs\n"
12919 " 142 - OS4 M68K->PPC cross-call stubs\n"
12920 " 200 - FD file (source is a pragma file!)\n"
12921 "mode: special 1-7\n"
12922 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12923 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12924 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12925 " 4 - no definition\n"
12926 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12928 " 1 - all functions, normal interface\n"
12929 " 2 - only tag-functions, tagcall interface\n"
12930 " 3 - all functions, normal and tagcall interface [default]\n";
12932 /* print the help text */
12933 static void printhelp(void)
12935 printf("%s\n%s", version
+6, helptext
);
12948 ARG_HELP
, ARG_INFILE
, ARG_SPECIAL
, ARG_MODE
, ARG_TO
, ARG_CLIB
, ARG_ABI
, ARG_COPYRIGHT
,
12949 ARG_HEADER
, ARG_HUNKNAME
, ARG_BASENAME
, ARG_LIBTYPE
,
12950 ARG_COMMENT
, ARG_EXTERNC
, ARG_FPUONLY
, ARG_NEWSYNTAX
, ARG_NOFPU
, ARG_NOPPC
,
12951 ARG_NOSYMBOL
, ARG_ONLYCNAMES
, ARG_OPT040
, ARG_PPCONLY
, ARG_PRIVATE
, ARG_SECTION
,
12952 ARG_SMALLDATA
, ARG_SORTED
, ARG_USESYSCALL
, ARG_NOPPCREGNAME
,
12953 ARG_SYSTEMRELEASE
, ARG_PRIORITY
, ARG_LIBNAME
, ARG_SMALLCODE
, ARG_VOIDBASE
,
12954 ARG_PREFIX
, ARG_SUBPREFIX
, ARG_PREMACRO
, ARG_SMALLTYPES
, ARG_AUTOHEADER
12957 /* argument definition array */
12958 static const struct ArgData argtexts
[] = {
12959 {"help", 'h', 4, ARG_HELP
},
12960 {"infile", 'i', 6, ARG_INFILE
},
12961 {"special", 's', 7, ARG_SPECIAL
},
12962 {"mode", 'm', 4, ARG_MODE
},
12963 {"to", 't', 2, ARG_TO
},
12964 {"clib", 'c', 4, ARG_CLIB
},
12965 {"abi", 'a', 3, ARG_ABI
},
12966 {"copyright", 'r', 9, ARG_COPYRIGHT
},
12967 {"header", 'd', 6, ARG_HEADER
},
12968 {"hunkname", 'n', 8, ARG_HUNKNAME
},
12969 {"basename", 'b', 8, ARG_BASENAME
},
12970 {"libtype", 'l', 7, ARG_LIBTYPE
},
12971 {"libname", 'i', 7, ARG_LIBNAME
},
12972 {"priority", 'p', 8, ARG_PRIORITY
},
12973 {"autoheader", 0, 10, ARG_AUTOHEADER
},
12974 {"comment", 0, 7, ARG_COMMENT
},
12975 {"externc", 0, 7, ARG_EXTERNC
},
12976 {"fpuonly", 0, 7, ARG_FPUONLY
},
12977 {"newsyntax", 0, 9, ARG_NEWSYNTAX
},
12978 {"nofpu", 0, 5, ARG_NOFPU
},
12979 {"noppc", 0, 5, ARG_NOPPC
},
12980 {"noppcregname", 0, 12, ARG_NOPPCREGNAME
},
12981 {"nosymbol", 0, 8, ARG_NOSYMBOL
},
12982 {"onlycnames", 0, 10, ARG_ONLYCNAMES
},
12983 {"opt040", 0, 6, ARG_OPT040
},
12984 {"ppconly", 0, 7, ARG_PPCONLY
},
12985 {"private", 0, 7, ARG_PRIVATE
},
12986 {"section", 0, 7, ARG_SECTION
},
12987 {"smalldata", 0, 9, ARG_SMALLDATA
},
12988 {"smalltypes", 0, 10, ARG_SMALLTYPES
},
12989 {"smallcode", 0, 9, ARG_SMALLCODE
},
12990 {"sorted", 0, 6, ARG_SORTED
},
12991 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE
},
12992 {"usesyscall", 0, 10, ARG_USESYSCALL
},
12993 {"voidbase", 0, 8, ARG_VOIDBASE
},
12994 {"prefix", 0, 6, ARG_PREFIX
},
12995 {"subprefix", 0, 9, ARG_SUBPREFIX
},
12996 {"premacro", 0, 8, ARG_PREMACRO
},
12997 {0,0,0,0}, /* end marker */
13000 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
13001 static uint32
ParseArgEntry(uint32 argc
, strptr
*argv
)
13003 uint32 numentries
= 1, l
;
13005 const struct ArgData
*ad
;
13007 if((*argv
)[0] != '-' || !(*argv
)[1])
13013 if((*argv
)[1] == ad
->ArgChar
|| ((*argv
)[1] == '-' && !strncmp(ad
->ArgName
, (*argv
)+2, ad
->ArgNameLen
)))
13021 case ARG_HELP
: printhelp(); break;
13022 case ARG_EXTERNC
: Flags
^= FLAG_EXTERNC
; break;
13023 case ARG_PRIVATE
: Flags
^= FLAG_PRIVATE
; break;
13024 case ARG_NEWSYNTAX
: Flags
^= FLAG_NEWSYNTAX
; break;
13025 case ARG_SMALLDATA
: Flags
^= FLAG_SMALLDATA
; break;
13026 case ARG_SMALLCODE
: Flags2
^= FLAG2_SMALLCODE
; break;
13027 case ARG_SMALLTYPES
: Flags2
^= FLAG2_SMALLTYPES
; break;
13028 case ARG_USESYSCALL
: Flags
^= FLAG_SYSCALL
; break;
13029 case ARG_OPT040
: Flags
^= FLAG_NOMOVEM
; break;
13030 case ARG_NOFPU
: Flags
^= FLAG_NOFPU
; break;
13031 case ARG_FPUONLY
: Flags
^= FLAG_FPUONLY
; break;
13032 case ARG_NOPPC
: Flags
^= FLAG_NOPPC
; break;
13033 case ARG_NOSYMBOL
: Flags
^= FLAG_NOSYMBOL
; break;
13034 case ARG_PPCONLY
: Flags
^= FLAG_PPCONLY
; break;
13035 case ARG_SECTION
: Flags
^= FLAG_ASMSECTION
; break;
13036 case ARG_COMMENT
: Flags
^= FLAG_DOCOMMENT
; break;
13037 case ARG_SORTED
: Flags
^= FLAG_SORTED
; break;
13038 case ARG_ONLYCNAMES
: Flags
^= FLAG_ONLYCNAMES
; break;
13039 case ARG_SYSTEMRELEASE
: Flags2
^= FLAG2_SYSTEMRELEASE
; break;
13040 case ARG_VOIDBASE
: Flags2
^= FLAG2_VOIDBASE
; break;
13041 case ARG_AUTOHEADER
: Flags2
^= FLAG2_AUTOHEADER
; break;
13042 case ARG_NOPPCREGNAME
: PPCRegPrefix
= "";
13044 a
= *argv
+((*argv
)[1] == '-' ? ad
->ArgNameLen
+2 : 2);
13047 if(argc
> 1) { a
= argv
[1]; numentries
= 2; }
13048 else { a
= 0; numentries
= 0;}
13058 a
[--l
] = 0; /* remove second " */
13062 case ARG_INFILE
: args
.infile
= a
; break;
13063 case ARG_COPYRIGHT
: Copyright
= a
; break;
13064 case ARG_TO
: args
.to
= a
; break;
13065 case ARG_ABI
: defabi
= a
; break;
13066 case ARG_CLIB
: args
.clib
= a
; break;
13067 case ARG_HEADER
: args
.header
= a
; break;
13068 case ARG_HUNKNAME
: hunkname
= a
; break;
13069 case ARG_PREFIX
: prefix
= a
; break;
13070 case ARG_SUBPREFIX
: subprefix
= a
; break;
13071 case ARG_PREMACRO
: premacro
= a
; break;
13072 case ARG_LIBTYPE
: libtype
= a
; Flags2
|= FLAG2_LIBTYPE
; break;
13073 case ARG_LIBNAME
: libname
= a
; Flags2
|= FLAG2_LIBNAME
; break;
13074 case ARG_BASENAME
: BaseName
= a
; Flags
|= FLAG_BASENAME
; break;
13076 args
.special
= strtoul(a
, &b
, 10);
13081 priority
= strtoul(a
, &b
, 10);
13086 args
.mode
= strtoul(a
, &b
, 10);
13087 if(*b
|| args
.mode
< 1 || args
.mode
> 3)
13096 /* initializes the arguments and starts argument parsing */
13097 static void GetArgs(int argc
, char **argv
)
13102 while(i
< argc
&& res
)
13104 if((j
= ParseArgEntry(argc
-i
, argv
+i
)) < 1)
13109 if(!res
|| !args
.infile
)
13115 static strptr
mygetfile(strptr name
, size_t *len
)
13120 if((infile
= fopen(name
, "rb")))
13122 if(!fseek(infile
, 0, SEEK_END
))
13124 *len
= ftell(infile
);
13125 if(!fseek(infile
, 0, SEEK_SET
))
13127 if((ptr
= AllocListMem(*len
+1)))
13131 printf("mygetfile: '%s' size %d\n", name
, *len
);
13133 if(fread(ptr
, *len
, 1, infile
) != 1)
13143 int main(int argc
, char **argv
)
13145 uint32 mode
= 0, pragmode
= PRAGMODE_PRAGLIB
, callmode
= TAGMODE_BOTH
;
13146 strptr amicall
= 0, libcall
= 0, amitags
= 0, libtags
= 0;
13148 size_t clibsize
= 0;
13150 GetArgs(argc
, argv
);
13152 if((tempbuf
= (uint8
*) AllocListMem(TEMPSIZE
)))
13154 if(!(in
.pos
= in
.buf
= mygetfile(args
.infile
, &in
.size
)))
13156 if(args
.special
== 200)
13158 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13163 sprintf((strptr
)tempbuf
, "%s" SFDFILEEXTENSION
, args
.infile
);
13164 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13166 sprintf((strptr
)tempbuf
, "%s" FDFILEEXTENSION
, args
.infile
);
13167 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13169 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13173 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13176 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13179 printf("SourceFile: %s\n", args
.infile
);
13181 MakeLines(in
.pos
, in
.size
);
13183 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SORTED
)) /* is not possible to use both */
13185 DoError(ERR_SORTED_COMMENT
, 0);
13186 Flags
&= (~FLAG_SORTED
);
13189 if(args
.special
== 200)
13203 if(Flags2
& FLAG2_SFDMODE
)
13204 DoError(ERR_SFD_AND_CLIB
, 0);
13207 sprintf((strptr
)tempbuf
, "%s_protos.h", args
.clib
);
13208 if(!(clibbuf
= mygetfile(args
.clib
, &clibsize
)) && !(clibbuf
= mygetfile((strptr
)tempbuf
, &clibsize
)))
13210 DoError(ERR_OPEN_FILE
, 0, args
.clib
);
13213 ScanClibFile(clibbuf
, clibbuf
+clibsize
);
13217 if(!MakeShortBaseName())
13219 DoError(ERR_MISSING_SHORTBASENAME
, 0);
13223 /* WARN when requesting obsolete types! */
13224 switch(args
.special
)
13226 case 1: case 2: case 3: case 4: case 5: case 7:
13227 printf("You use obsolete data type %ld, better use type 6!\n", args
.special
);
13229 case 11: case 15: case 71: case 72: case 75:
13230 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13231 "link libraries!\n", args
.special
);
13233 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13234 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args
.special
);
13237 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13241 if(args
.special
< 10) /* the pragma area is up to 9 */
13243 mode
= MODUS_PRAGMA
;
13244 sprintf(filename
, "%s_lib.h", ShortBaseName
);
13246 switch(args
.special
)
13249 case 1: pragmode
= PRAGMODE_PRAGSLIB
; amicall
= ""; break;
13250 case 2: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13251 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= ""; break;
13252 case 3: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13253 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= "";
13254 libtags
= "def " TEXT_SAS_60
; break;
13255 case 4: amicall
= ""; break;
13256 case 5: amicall
= amitags
= ""; break;
13257 case 7: Flags
|= FLAG_GNUPRAG
; /* no break ! */
13258 case 6: amicall
= " defined(" TEXT_AZTEC
") || defined("
13259 TEXT_MAXON
") || defined(" TEXT_STORM
")";
13260 libcall
= " defined(" TEXT_DICE
") || defined(" TEXT_SAS
")";
13261 libtags
= "def " TEXT_SAS_60
; amitags
="def " TEXT_STORM
; break;
13262 default: mode
= MODUS_ERROR
; break;
13265 if(args
.mode
> 0 && args
.mode
< 5)
13266 pragmode
= args
.mode
;
13268 else if(args
.special
< 20) /* the misc area is up to 19 */
13270 if(args
.mode
> 0 && args
.mode
< 4)
13271 callmode
= args
.mode
- 1;
13272 switch(args
.special
)
13274 case 10: mode
= MODUS_CSTUB
;
13275 sprintf(filename
, "%s_cstub.h", ShortBaseName
); break;
13276 case 11: mode
= MODUS_STUBTEXT
;
13277 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13278 case 12: mode
= MODUS_STUBCODE
;
13279 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13280 case 13: Flags
|= FLAG_LOCALREG
; /* no break ! */
13281 case 14: mode
= MODUS_LOCALDATA
;
13282 sprintf(filename
, "%s_loc.h", ShortBaseName
); break;
13283 case 15: mode
= MODUS_STUBTEXT
; callmode
= TAGMODE_NORMAL
;
13284 Flags
^= FLAG_PASCAL
;
13285 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13286 case 16: mode
= MODUS_STUBCODE
; callmode
= TAGMODE_NORMAL
;
13287 Flags
^= FLAG_PASCAL
;
13288 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13289 case 17: mode
= MODUS_BMAP
; callmode
= TAGMODE_NORMAL
;
13290 sprintf(filename
, "%s.bmap", ShortBaseName
); break;
13291 case 18: mode
= MODUS_EMODULE
;
13292 sprintf(filename
, "%s.m", ShortBaseName
); break;
13293 default: mode
= MODUS_ERROR
; break;
13296 else if(args
.special
< 30) /* the lvo area is up to 29 */
13298 switch(args
.special
)
13300 case 20: case 22: mode
= MODUS_LVO
+args
.special
-20;
13301 sprintf(filename
, "%s_lvo.i", ShortBaseName
); break;
13302 case 21: case 23: mode
= MODUS_LVO
+args
.special
-20;
13303 sprintf(filename
, "%s_lib.i", ShortBaseName
); break;
13304 case 24: mode
= MODUS_LVOLIB
;
13305 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13306 default: mode
= MODUS_ERROR
; break;
13309 else if(args
.special
< 40) /* the proto area is up to 39 */
13311 if(args
.special
< 40)
13313 mode
= MODUS_PROTO
+args
.special
-30;
13314 sprintf(filename
, "%s.h", ShortBaseName
);
13317 mode
= MODUS_ERROR
;
13319 else if(args
.special
< 50) /* the inline area is up to 49 */
13321 if(args
.mode
> 0 && args
.mode
< 4)
13322 callmode
= args
.mode
- 1;
13324 switch(args
.special
)
13326 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13328 mode
= MODUS_INLINE
+args
.special
-40;
13329 sprintf(filename
, "%s.h", ShortBaseName
); break;
13331 Flags
|= FLAG_STORMGCC
;
13332 /* the same mode as for 46, but additional flag */
13333 mode
= MODUS_INLINE
+args
.special
-40-2;
13334 sprintf(filename
, "%s.h", ShortBaseName
); break;
13335 default: mode
= MODUS_ERROR
; break;
13338 else if(args
.special
< 60) /* the PowerUP area is up to 59 */
13340 if(args
.mode
> 0 && args
.mode
< 4)
13341 callmode
= args
.mode
- 1;
13343 switch(args
.special
)
13345 case 50: case 51: case 52: mode
= MODUS_INLINE
+args
.special
-50;
13346 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_POWERUP
;
13349 sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13350 mode
= MODUS_SASPOWER
; break;
13352 sprintf(filename
, "%s.h", ShortBaseName
);
13353 mode
= MODUS_PROTOPOWER
; break;
13354 default: mode
= MODUS_ERROR
; break;
13357 else if(args
.special
< 70) /* the PASCAL stuff */
13359 if(args
.special
== 60)
13361 mode
= MODUS_PASCAL
;
13362 sprintf(filename
, "%s.pas", ShortBaseName
);
13365 mode
= MODUS_ERROR
;
13367 else if(args
.special
< 80) /* the VBCC stuff */
13369 if(args
.mode
> 0 && args
.mode
< 4)
13370 callmode
= args
.mode
- 1;
13372 switch(args
.special
)
13374 case 70: mode
= MODUS_VBCCINLINE
;
13375 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13376 case 71: case 72: case 75:
13377 mode
= MODUS_VBCC
+args
.special
-71;
13378 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13380 mode
= MODUS_VBCC
+args
.special
-71;
13381 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13383 mode
= MODUS_VBCCPUPLIB
;
13384 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13385 case 77: mode
= MODUS_VBCCWOSINLINE
;
13386 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13387 case 78: mode
= MODUS_VBCCMORPHCODE
;
13388 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13389 case 79: mode
= MODUS_VBCCINLINE
;
13390 Flags2
|= FLAG2_OLDVBCC
;
13391 callmode
= TAGMODE_NORMAL
;
13392 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13393 default: mode
= MODUS_ERROR
; break;
13396 else if(args
.special
< 90) /* redirect stuff */
13398 mode
= MODUS_REDIRECT
;
13399 switch(args
.special
)
13401 case 80: sprintf(filename
, "%s_pragmas.h", ShortBaseName
); break;
13402 case 81: sprintf(filename
, "%s_lib.h", ShortBaseName
); break;
13403 case 82: sprintf(filename
, "%s.h", ShortBaseName
); break;
13404 case 83: sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13405 default: mode
= MODUS_ERROR
; break;
13408 else if(args
.special
< 100) /* multifile stuff */
13410 Flags
|= FLAG_SINGLEFILE
;
13411 switch(args
.special
)
13414 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13415 mode
= MODUS_ASMTEXTSF
; filenamefmt
= "%s.s";
13418 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13419 mode
= MODUS_VBCCPUPTEXTSF
; filenamefmt
= "%s.s";
13422 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13423 mode
= MODUS_VBCCWOSTEXTSF
; filenamefmt
= "%s.s";
13426 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13427 mode
= MODUS_VBCCMORPHTEXTSF
; filenamefmt
= "%s.s";
13429 default: mode
= MODUS_ERROR
; break;
13432 else if(args
.special
< 110) /* PPC lvo's */
13434 switch(args
.special
)
13436 case 100: case 101: mode
= MODUS_LVOPPC
+args
.special
-100;
13437 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13439 case 104: case 105: mode
= MODUS_LVOPPC
+args
.special
-104;
13440 Flags
|= FLAG_ABIV4
;
13441 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13443 case 103: mode
= MODUS_LVOLIB
;
13444 sprintf(filename
, "%slvo.o", ShortBaseName
);
13446 case 107: mode
= MODUS_LVOLIB
;
13447 Flags
|= FLAG_ABIV4
;
13448 sprintf(filename
, "%slvo.o", ShortBaseName
);
13450 case 102: mode
= MODUS_LVOLIBPPC
;
13451 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13452 case 106: mode
= MODUS_LVOLIBPPC
;
13453 Flags
|= FLAG_ABIV4
;
13454 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13455 default: mode
= MODUS_ERROR
; break;
13458 else if(args
.special
< 120) /* different files */
13460 if(args
.mode
> 0 && args
.mode
< 4)
13461 callmode
= args
.mode
- 1;
13463 switch(args
.special
)
13465 case 110: mode
= MODUS_FD
;
13466 sprintf(filename
, "%s_lib.fd", ShortBaseName
);
13467 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13469 DoError(ERR_SORTED_SFD_FD
, 0);
13470 Flags
&= (~FLAG_SORTED
);
13473 case 111: mode
= MODUS_CLIB
; Flags2
|= FLAG2_CLIBOUT
;
13474 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13476 case 112: mode
= MODUS_SFD
; Flags2
|= FLAG2_SFDOUT
;
13477 sprintf(filename
, "%s_lib.sfd", ShortBaseName
);
13481 DoError(ERR_ONLYTAGMODE_NOTALLOWED
, 0);
13484 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13486 DoError(ERR_SORTED_SFD_FD
, 0);
13487 Flags
&= (~FLAG_SORTED
);
13490 default: mode
= MODUS_ERROR
; break;
13493 else if(args
.special
< 130) /* auto libopen files */
13495 if(args
.mode
> 0 && args
.mode
< 4) /* for 122 */
13496 callmode
= args
.mode
- 1;
13498 switch(args
.special
)
13500 case 120: mode
= MODUS_GENAUTO
;
13501 sprintf(filename
, "%s_autoopenlib.c", ShortBaseName
);
13503 case 121: mode
= MODUS_GENAUTO
+(args
.special
-120);
13504 sprintf(filename
, "%s_autoopenlib.lib", ShortBaseName
);
13506 case 123: Flags2
|= FLAG2_SHORTPPCVBCCINLINE
; /* no break */
13507 case 122: mode
= MODUS_VBCCMORPHINLINE
;
13508 PPCRegPrefix
= ""; /* no "r" allowed */
13509 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13511 default: mode
= MODUS_ERROR
; break;
13514 else if(args
.special
< 140) /* the MorphOS area is up to 139 */
13516 if(args
.mode
> 0 && args
.mode
< 4)
13517 callmode
= args
.mode
- 1;
13519 switch(args
.special
)
13521 case 130: case 131: case 132: mode
= MODUS_INLINE
+args
.special
-130;
13522 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13524 case 133: mode
= MODUS_INLINE
+2;
13525 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13526 Flags2
|= FLAG2_DIRECTVARARGS
;
13528 case 134: mode
= MODUS_GATESTUBS
;
13529 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13531 case 135: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
;
13532 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13534 case 136: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
;
13535 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13537 case 137: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
|FLAG2_REGLIB
;
13538 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13540 case 138: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
|FLAG2_REGLIB
;
13541 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13543 default: mode
= MODUS_ERROR
; break;
13546 else if(args
.special
< 150) /* the OS4 area is up to 139 */
13548 if(args
.mode
> 0 && args
.mode
< 4)
13549 callmode
= args
.mode
- 1;
13551 switch(args
.special
)
13555 sprintf(filename
, "%s.xml", ShortBaseName
);
13557 case 141: /* OS4 PPC->M68K cross-call stubs */
13558 mode
= MODUS_OS4_PPCSTUBS
;
13559 sprintf(filename
, "%s.c", ShortBaseName
);
13561 case 142: /* OS4 M68K->PPC cross-call stubs */
13562 mode
= MODUS_OS4_68KSTUBS
;
13563 sprintf(filename
, "%s_68k.s", ShortBaseName
);
13565 default: mode
= MODUS_ERROR
; break;
13568 if(Flags
& FLAG_SORTED
)
13571 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SINGLEFILE
)) /* is not possible to use both */
13573 DoError(ERR_COMMENT_SINGLEFILE
, 0);
13574 Flags
&= (~FLAG_DOCOMMENT
);
13577 if(!mode
|| mode
== MODUS_ERROR
)
13580 /* These modes need BaseName always. */
13581 if(!BaseName
&& (mode
== MODUS_PRAGMA
|| mode
== MODUS_STUBTEXT
||
13582 mode
== MODUS_STUBCODE
|| mode
== MODUS_EMODULE
|| (mode
>= MODUS_GENAUTO
&&
13583 mode
<= MODUS_GENAUTO
+9)))
13585 DoError(ERR_MISSING_BASENAME
, 0);
13589 if(args
.header
&& args
.header
[0] && (args
.header
[0] != '@' || args
.header
[1]))
13591 HEADER
= mygetfile(args
.header
, &headersize
);
13595 if(!(Flags
& FLAG_SINGLEFILE
))
13597 if(!OpenDest(filename
))
13601 /* from here mode is used as return result */
13602 if(mode
>= MODUS_GENAUTO
)
13603 mode
= CreateGenAuto(filename
, mode
-MODUS_GENAUTO
);
13604 else if(mode
>= MODUS_LVOPPC
)
13605 mode
= CreateLVOFilePPC(mode
-MODUS_LVOPPC
);
13606 else if(mode
>= MODUS_VBCC
)
13607 mode
= CreateVBCC(mode
-MODUS_VBCC
, callmode
);
13608 else if(mode
>= MODUS_INLINE
)
13609 mode
= CreateInline(mode
-MODUS_INLINE
, callmode
);
13610 else if(mode
>= MODUS_PROTO
)
13611 mode
= CreateProtoFile(mode
-MODUS_PROTO
+1);
13612 else if(mode
>= MODUS_LVO
)
13613 mode
= CreateLVOFile(mode
-MODUS_LVO
+1);
13614 else if(mode
== MODUS_VBCCMORPHINLINE
)
13615 mode
= CreateVBCCInline(2, callmode
);
13616 else if(mode
== MODUS_XML
)
13617 mode
= CreateXML();
13618 else if(mode
== MODUS_OS4_PPCSTUBS
)
13619 mode
= CreateOS4PPC(callmode
);
13620 else if(mode
== MODUS_OS4_68KSTUBS
)
13621 mode
= CreateOS4M68K();
13622 else if(mode
== MODUS_GATESTUBS
)
13623 mode
= CreateGateStubs(callmode
);
13624 else if(mode
== MODUS_SFD
)
13625 mode
= CreateSFD(callmode
);
13626 else if(mode
== MODUS_CLIB
)
13627 mode
= CreateClib(callmode
);
13628 else if(mode
== MODUS_FD
)
13630 else if(mode
== MODUS_LVOLIBPPC
)
13631 mode
= CreateLVOLibPPC();
13632 else if(mode
== MODUS_VBCCMORPHCODE
)
13633 mode
= CreateVBCCMorphCode(callmode
);
13634 else if(mode
== MODUS_VBCCMORPHTEXTSF
) /* single files */
13635 mode
= CallFunc(callmode
, "\n%s", FuncVBCCMorphText
);
13636 else if(mode
== MODUS_VBCCWOSINLINE
)
13637 mode
= CreateVBCCInline(1, callmode
);
13638 else if(mode
== MODUS_VBCCWOSTEXTSF
) /* single files */
13639 mode
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
);
13640 else if(mode
== MODUS_VBCCPUPTEXTSF
) /* single files */
13641 mode
= CallFunc(callmode
, "\n%s", FuncVBCCPUPText
);
13642 else if(mode
== MODUS_ASMTEXTSF
) /* single files */
13643 mode
= CallFunc(callmode
, "\n%s", FuncAsmText
);
13644 else if(mode
== MODUS_REDIRECT
)
13645 mode
= CreateProtoRedirect();
13646 else if(mode
== MODUS_EMODULE
)
13647 mode
= CreateEModule(Flags
& FLAG_SORTED
);
13648 else if(mode
== MODUS_LVOLIB
)
13649 mode
= CreateLVOLib();
13650 else if(mode
== MODUS_VBCCPUPLIB
)
13651 mode
= CreateVBCCPUPLib(callmode
);
13652 else if(mode
== MODUS_VBCCINLINE
)
13653 mode
= CreateVBCCInline(0, callmode
);
13654 else if(mode
== MODUS_PASCAL
)
13655 mode
= CreateFPCUnit();
13656 else if(mode
== MODUS_BMAP
)
13657 mode
= CreateBMAP();
13658 else if(mode
== MODUS_PROTOPOWER
)
13659 mode
= CreateProtoPowerUP();
13660 else if(mode
== MODUS_SASPOWER
)
13661 mode
= CreateSASPowerUP(callmode
);
13662 else if(mode
== MODUS_CSTUB
)
13663 mode
= CreateCSTUBSFile();
13664 else if(mode
== MODUS_PRAGMA
)
13665 mode
= CreatePragmaFile(amicall
, libcall
, amitags
, libtags
, pragmode
);
13666 else if(mode
== MODUS_LOCALDATA
)
13667 mode
= CreateLocalData(filename
, callmode
);
13668 else if(mode
) /* MODUS_STUBTEXT starts with 1 */
13669 mode
= CreateAsmStubs(mode
, callmode
);
13671 CloseDest(filename
);
13675 DoError(Output_Error
? ERR_UNKNOWN_ERROR
: ERR_WRITING_FILE
, 0);