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
;
4200 printf((line
? "%s %ld in line %ld%s: " : "%s %ld : "),
4201 (Errors
[err
].Type
? "Warning" : "Error"), err
, line
,
4202 errnum
& ERROFFSET_CLIB
? " of clib file" : "");
4203 vprintf(Errors
[err
].Error
, a
);
4205 if(line
&& Errors
[err
].Skip
)
4213 static uint32
CheckError(struct AmiPragma
*ap
, uint32 errflags
)
4215 errflags
&= ap
->Flags
;
4217 if(errflags
& AMIPRAGFLAG_ARGCOUNT
)
4219 if(!(ap
->Flags
& AMIPRAGFLAG_DIDARGWARN
))
4221 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
, ap
->Line
);
4222 ap
->Flags
|= AMIPRAGFLAG_DIDARGWARN
;
4226 else if(errflags
& AMIPRAGFLAG_FLOATARG
)
4228 if(!(ap
->Flags
& AMIPRAGFLAG_DIDFLOATWARN
))
4230 DoError(ERR_FLOATARG_NOT_ALLOWED
, ap
->Line
);
4231 ap
->Flags
|= AMIPRAGFLAG_DIDFLOATWARN
;
4235 else if(errflags
& AMIPRAGFLAG_A6USE
)
4237 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
4240 else if(errflags
& AMIPRAGFLAG_A5USE
)
4242 DoError(ERR_A5_NOT_ALLOWED
, ap
->Line
);
4245 else if(errflags
& AMIPRAGFLAG_PPC
)
4247 if(!(Flags
& FLAG_DIDPPCWARN
))
4249 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4250 Flags
|= FLAG_DIDPPCWARN
;
4254 else if(errflags
& AMIPRAGFLAG_M68K
)
4256 if(!(Flags
& FLAG_DIDM68KWARN
))
4258 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4259 Flags
|= FLAG_DIDM68KWARN
;
4263 else if(errflags
& AMIPRAGFLAG_MOSBASESYSV
)
4265 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED
, ap
->Line
);
4272 static uint32
DoOutput(strptr format
, ...)
4279 va_start(a
, format
);
4280 if(vfprintf(outfile
, format
, a
) < 0)
4284 return Output_Error
;
4287 static uint32
DoOutputDirect(void * data
, size_t size
)
4293 if(fwrite(data
, size
, 1, outfile
) != 1)
4296 return Output_Error
;
4299 /* ------------------------------------------------------------------ */
4301 static struct ShortList
*NewItem(struct ShortListRoot
*list
)
4303 struct ShortList
*item
;
4304 if(!list
|| !list
->Size
)
4306 if(!(item
= (struct ShortList
*) AllocListMem(list
->Size
)))
4311 static struct ShortList
*RemoveItem(struct ShortListRoot
*list
,
4312 struct ShortList
*item
)
4314 struct ShortList
*n
= list
->First
;
4317 list
->First
= item
->Next
;
4320 while(n
&& n
->Next
!= item
)
4324 if(!(n
->Next
= item
->Next
))
4331 static void AddItem(struct ShortListRoot
*list
, struct ShortList
*item
)
4334 list
->First
= list
->Last
= item
;
4337 list
->Last
->Next
= item
;
4342 /* ------------------------------------------------------------------ */
4344 uint32
FuncAMICALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4348 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4351 Flags
|= FLAG_DONE
; /* We did something */
4353 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags
& FUNCFLAG_TAG
?
4354 "tagcall" : "amicall", BaseName
, ap
->Bias
, name
);
4356 for(i
= 0; i
< ap
->NumArgs
; ++i
)
4358 DoOutput("%s",RegNames
[ap
->Args
[i
].ArgReg
]);
4359 if(i
+1 < ap
->NumArgs
)
4363 return DoOutput(/*((*/"))\n");
4366 uint32
FuncLIBCALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4370 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4373 Flags
|= FLAG_DONE
; /* We did something */
4375 if(ap
->Flags
& AMIPRAGFLAG_FLOATARG
)
4377 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName
, name
, ap
->Bias
);
4378 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4379 DoOutput("%02x", ap
->Args
[i
].ArgReg
);
4381 return DoOutput("00%02x\n", ap
->NumArgs
);
4384 if((Flags
& FLAG_SYSCALL
) && !strcmp(BaseName
,"SysBase") &&
4385 (flags
& FUNCFLAG_NORMAL
))
4386 DoOutput("#pragma syscall %-22s %03x ", name
, ap
->Bias
);
4388 DoOutput("#pragma %s %s %-22s %03x ", (flags
& FUNCFLAG_TAG
) ?
4389 "tagcall" : "libcall", BaseName
, name
, ap
->Bias
);
4391 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4392 DoOutput("%x", ap
->Args
[i
].ArgReg
);
4394 return DoOutput("0%x\n", ap
->NumArgs
);
4397 uint32
FuncAsmText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4404 struct ClibData
*cd
;
4406 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4409 Flags
|= FLAG_DONE
; /* We did something */
4411 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
4412 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
4414 if(Flags
& FLAG_SINGLEFILE
)
4416 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
4421 DoOutputDirect(HEADER
, headersize
);
4425 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
4427 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
4428 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
4431 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name
, name
);
4432 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4434 DoOutput("\tXDEF\t%s\n%s:\n",name
, name
);
4438 DoOutput("\tXDEF\t%s_\n%s_:\n",name
, name
);
4439 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4444 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4446 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4447 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name
, txt
, name
, txt
);
4453 if((registers
= GetRegisterData(ap
) >> 16))
4455 if(Flags
& FLAG_NOMOVEM
)
4457 for(i
= 0; i
<= 15; ++i
)
4459 if(registers
& (1 << i
))
4462 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper
[i
]);
4468 uint16 l
= registers
;
4470 DoOutput("\tMOVEM.L\t");
4472 for(i
= 0; i
<= 15; ++i
)
4478 DoOutput("%s",RegNamesUpper
[i
]);
4483 DoOutput(",-(A7)\n");
4488 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset
;
4491 if((fregs
= GetFRegisterData(ap
) >> 8))
4495 DoOutput("\tFMOVEM.X\t");
4497 for(i
= 0; i
<= 7; ++i
)
4503 DoOutput("%s",RegNamesUpper
[REG_FP0
+ i
]);
4508 DoOutput(",-(A7)\n");
4511 if(Flags
& FLAG_SMALLDATA
)
4513 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1
, BaseName
, c2
);
4516 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName
);
4518 if(!(Flags
& FLAG_PASCAL
))
4522 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4526 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4529 struct ClibData
*cd
;
4531 cd
= GetClibFunc(name
, ap
, flags
);
4532 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4533 t
= CPP_TYPE_DOUBLE
;
4534 else if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4538 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4542 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
4543 ? 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4545 if(t
== CPP_TYPE_DOUBLE
)
4549 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
) &&
4550 ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4552 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4553 RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4557 DoOutput("/%s", RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4559 } while((i
< k
) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
].ArgReg
) &&
4560 ap
->Args
[i
].ArgReg
< REG_FP0
);
4565 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4566 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4567 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4574 if(ap
->Args
[i
].ArgReg
> 7)
4575 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1
, offset
<<2, c2
,
4576 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4577 else if(offset
<= 2)
4578 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4579 RegNamesUpper
[ap
->Args
[i
].ArgReg
],offset
<<2,
4580 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4582 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1
,
4583 offset
<<2, c2
,RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4592 if(ap
->Args
[i
-1].ArgReg
>= REG_FP0
)
4595 struct ClibData
*cd
;
4597 cd
= GetClibFunc(name
, ap
, flags
);
4599 if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_DOUBLE
))
4600 t
= CPP_TYPE_DOUBLE
;
4601 else if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_FLOAT
))
4605 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4609 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
?
4610 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4611 if(t
== CPP_TYPE_DOUBLE
)
4615 else if((i
>= 2) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
-2].ArgReg
) &&
4616 ap
->Args
[i
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4618 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4619 RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4623 DoOutput("/%s", RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4625 } while(i
&& (ap
->Args
[i
].ArgReg
< ap
->Args
[i
-1].ArgReg
) &&
4626 ap
->Args
[i
-1].ArgReg
< REG_FP0
);
4632 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4633 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4634 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4639 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1
, ap
->Bias
, c2
);
4643 DoOutput("\tFMOVEM.X\t(A7)+,");
4645 for(i
= 0; i
<= 7; ++i
)
4647 if(fregs
& (1 << i
))
4650 DoOutput("%s",RegNamesUpper
[REG_FP0
+ i
]);
4660 if(Flags
& FLAG_NOMOVEM
)
4662 for(i
= 15; i
>= 0; --i
)
4664 if(registers
& (1 << i
))
4665 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i
>= REG_A0
? "A" : "",
4671 DoOutput("\tMOVEM.L\t(A7)+,");
4673 for(i
= 0; i
<= 15; ++i
)
4675 if(registers
& (1 << i
))
4677 registers
^= 1 << i
;
4678 DoOutput("%s",RegNamesUpper
[i
]);
4687 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4689 return DoOutput("\tRTS\n");
4692 uint32
FuncAsmCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4694 uint32 registers
, offset
= 1, baseref
;
4699 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4702 Flags
|= FLAG_DONE
; /* We did something */
4704 registers
= GetRegisterData(ap
);
4705 fregs
= GetFRegisterData(ap
);
4707 i
= strlen(name
) + 2;
4708 EndPutM32(tempbuf
, HUNK_UNIT
);
4709 EndPutM32(tempbuf
+4, (i
+3)>>2);
4710 DoOutputDirect(tempbuf
, 8);
4711 DoOutput("%s.o", name
);
4712 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4714 i
= strlen(hunkname
);
4715 EndPutM32(tempbuf
, HUNK_NAME
);
4716 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
4717 DoOutputDirect(tempbuf
, 8);
4718 DoOutputDirect(hunkname
, i
);
4719 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4721 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
4725 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
4726 ++offset
; /* one long more on stack */
4730 if(Flags
& FLAG_NOMOVEM
)
4732 for(i
= 0; i
<= 15; ++i
)
4734 if(registers
& (1<< (16+i
)))
4736 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
4744 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
4745 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
4746 for(l
= (uint16
) registers
; l
; l
>>= 1)
4749 ++offset
; /* get offset addition */
4757 EndPutM16Inc(data
, 0xF227); /* FMOVEM.X xxx,-(A7) */
4758 EndPutM16Inc(data
, 0xE000 + ((fregs
>>8)&0xFF));
4759 for(l
= (uint8
) fregs
; l
; l
>>= 1)
4762 offset
+=3; /* get offset addition */
4766 baseref
= (data
-tempbuf
)-8+2; /* one word later (MOVE) - 2 header longs */
4767 if(Flags
& FLAG_SMALLDATA
)
4769 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
4770 EndPutM16Inc(data
, 0); /* place for base reference */
4774 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
4775 EndPutM32Inc(data
, 0); /* place for base reference */
4778 data
= AsmStackCopy(data
, ap
, flags
, offset
);
4780 /* here comes the base reference */
4781 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
4782 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
4786 EndPutM16Inc(data
, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4787 EndPutM16Inc(data
, 0xD000 + (fregs
&0xFF));
4792 if(Flags
& FLAG_NOMOVEM
)
4795 for(i
= 15; i
>= 0; --i
)
4797 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
4798 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
4803 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4804 EndPutM16Inc(data
, (registers
>> 16)); /* store MOVEM.L registers */
4808 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
4809 EndPutM16Inc(data
, 0x4E75); /* RTS */
4811 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
4813 EndPutM32(tempbuf
, HUNK_CODE
);
4814 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
4815 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
4817 EndPutM32(tempbuf
, HUNK_EXT
);
4818 DoOutputDirect(tempbuf
, 4);
4820 OutputXREF(baseref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
),
4822 /* here come the XDEF name references */
4823 OutputXDEF(0, "_%s", name
); /* C name */
4825 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4827 struct ClibData
*cd
;
4828 OutputXDEF(0, "%s", name
); /* ASM name */
4833 OutputXDEF(0, "%s_", name
); /* C++ name no parameters */
4834 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4836 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4838 if(CopyCPPType((strptr
)tempbuf
, i
, cd
, ap
->Args
))
4839 OutputXDEF(0, "%s__%s", name
, tempbuf
);
4845 EndPutM32(tempbuf
, 0);
4846 DoOutputDirect(tempbuf
, 4);
4847 if(!(Flags
& FLAG_NOSYMBOL
))
4849 EndPutM32(tempbuf
, HUNK_SYMBOL
);
4850 DoOutputDirect(tempbuf
, 4);
4851 OutputSYMBOL(0, "_%s", name
); /* C name */
4853 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4855 struct ClibData
*cd
;
4856 OutputSYMBOL(0, "%s", name
); /* ASM name */
4861 OutputSYMBOL(0, "%s_", name
); /* C++ name no parameters */
4862 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4864 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4866 if(CopyCPPType((strptr
) data
, i
, cd
, ap
->Args
))
4867 OutputSYMBOL(0, "%s__%s", name
, (strptr
) data
);
4873 EndPutM32(tempbuf
, 0);
4874 DoOutputDirect(tempbuf
, 4);
4877 EndPutM32(tempbuf
, HUNK_END
);
4878 return DoOutputDirect(tempbuf
, 4);
4881 /* Directly called by FuncInline and FuncInlineDirect also! */
4882 uint32
FuncCSTUBS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4884 struct ClibData
*f
, *t
;
4885 strptr ret
= "return ";
4888 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4891 Flags
|= FLAG_DONE
; /* We did something */
4893 if(!(f
= GetClibFunc(ap
->FuncName
, ap
, 0)))
4895 t
= GetClibFunc(name
, ap
, flags
);
4897 if(flags
& FUNCFLAG_EXTENDMODE
)
4899 sprintf(tempbuf
, "___%s", name
);
4903 if(IsCPPType(&f
->ReturnType
, CPP_TYPE_VOID
))
4906 if(!OutClibType(&f
->ReturnType
, name
) || !DoOutput("("/*)*/))
4908 if(flags
& FUNCFLAG_EXTENDMODE
)
4910 DoOutput("%s %s, ", GetBaseType(), BaseName
);
4913 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4915 if(!OutClibType(&f
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4918 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4920 if(!OutClibType(&t
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4923 else if(ap
->NumArgs
== 1 && !DoOutput("ULONG tag, "))
4926 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret
, ap
->FuncName
))
4928 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4930 if(!DoOutput("%s, ", ap
->Args
[i
].ArgName
))
4933 if(!DoOutput("("/*)*/) || !OutClibType(&f
->Args
[ap
->NumArgs
-1],0))
4936 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4938 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap
->Args
[ap
->NumArgs
-1].ArgName
))
4941 else if(ap
->NumArgs
== 1)
4943 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4946 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4947 ap
->Args
[ap
->NumArgs
-2].ArgName
) || !OutClibType(&f
->Args
[ap
->NumArgs
-2],0)
4948 || !DoOutput(/*(((*/")));\n}\n\n"))
4953 uint32
FuncLVOXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4955 Flags
|= FLAG_DONE
; /* We did something */
4956 return DoOutput("\t\tXDEF\t_LVO%s\n", name
);
4959 uint32
FuncLVO(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4961 Flags
|= FLAG_DONE
; /* We did something */
4962 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name
, ap
->Bias
);
4965 uint32
FuncLVOPPCXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4967 Flags
|= FLAG_DONE
; /* We did something */
4968 return DoOutput("\t.globl\t%sLVO%s\n", Flags
& FLAG_ABIV4
? "" : "_", name
);
4971 uint32
FuncLVOPPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4973 Flags
|= FLAG_DONE
; /* We did something */
4974 return DoOutput(".set\t%sLVO%s,-%d\n", Flags
& FLAG_ABIV4
? "" : "_", name
,
4978 uint32
FuncLVOPPCBias(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4980 Flags
|= FLAG_DONE
; /* We did something */
4982 EndPutM32Inc(elfbufpos
, symoffset
); /* st_name */
4983 symoffset
+= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1) + 1;
4984 EndPutM32Inc(elfbufpos
, -ap
->Bias
); /* st_value */
4985 EndPutM32Inc(elfbufpos
, 0); /* st_size */
4986 *(elfbufpos
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* st_info */
4987 *(elfbufpos
++) = 0; /* st_other */
4988 EndPutM16Inc(elfbufpos
, SHN_ABS
); /* st_shndx */
4993 uint32
FuncLVOPPCName(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4995 Flags
|= FLAG_DONE
; /* We did something */
4996 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
4997 return DoOutputDirect("", 1);
5000 uint32
FuncLVOLib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5004 Flags
|= FLAG_DONE
; /* We did something */
5005 j
= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1);
5006 EndPutM32(tempbuf
, (EXT_ABS
<< 24) + ((j
+3)>>2));
5008 DoOutputDirect(tempbuf
, 4);
5009 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5010 DoOutputDirect("\0\0\0", ((j
+3)&(~3))-j
);
5011 EndPutM32(tempbuf
, -ap
->Bias
);
5012 return DoOutputDirect(tempbuf
, 4);
5015 uint32
FuncLocCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5017 strptr str2
= Flags
& FLAG_LOCALREG
? "rE" : "";
5020 struct ClibData
*cd
= 0;
5022 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
5025 Flags
|= FLAG_DONE
; /* We did something */
5027 i
= strlen(name
) + 2;
5028 EndPutM32(tempbuf
, HUNK_UNIT
);
5029 EndPutM32(tempbuf
+4, (i
+3)>>2);
5030 DoOutputDirect(tempbuf
, 8);
5031 DoOutput("%s.o", name
);
5032 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5034 i
= strlen(hunkname
);
5035 EndPutM32(tempbuf
, HUNK_NAME
);
5036 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
5037 DoOutputDirect(tempbuf
, 8);
5038 DoOutputDirect(hunkname
, i
);
5039 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5041 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
5043 if(Flags
& FLAG_LOCALREG
)
5045 if((flags
& FUNCFLAG_TAG
))
5047 i
= ap
->Args
[ap
->NumArgs
-1].ArgReg
;
5048 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE <ea>,-(A7) */
5052 EndPutM16Inc(data
, 0x41EF | ((i
-8) << 9)); /* LEA 8(A7),Ax */
5053 EndPutM16Inc(data
, 8);
5057 EndPutM16Inc(data
, 0x200F | (i
<< 9)); /* MOVE.L A7,Dx */
5058 EndPutM16Inc(data
, 0x5080 | i
); /* ADDQ.L #8,Dx */
5061 EndPutM16Inc(data
, 0x4EAE);
5062 EndPutM16Inc(data
, -ap
->Bias
); /* JSR instruction */
5064 /* MOVE (A7)+,<ea> */
5065 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5066 EndPutM16Inc(data
, 0x4E75); /* RTS */
5070 EndPutM16Inc(data
, 0x4EEE);
5071 EndPutM16Inc(data
, -ap
->Bias
); /* JMP instruction */
5076 uint32 registers
, offset
= 1;
5078 registers
= GetRegisterData(ap
);
5080 if(!registers
) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5082 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
5083 ++offset
; /* one long more on stack */
5087 if(Flags
& FLAG_NOMOVEM
)
5089 for(i
= 0; i
<= 15; ++i
)
5091 if(registers
& (1<< (16+i
)))
5093 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
5100 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
5101 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
5102 for(i
= registers
&0xFFFF; i
; i
>>= 1)
5105 ++offset
; /* get offset addition */
5110 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
)) /* store library base in A6 */
5112 EndPutM16Inc(data
, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5113 EndPutM16Inc(data
, (offset
++) << 2);
5116 data
= AsmStackCopy(data
, ap
, flags
, offset
);
5118 /* here comes the base reference */
5119 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
5120 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
5123 if(Flags
& FLAG_NOMOVEM
)
5125 for(i
= 15; i
>= 0; --i
)
5127 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
5128 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5133 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5134 EndPutM16Inc(data
, registers
>> 16); /* store MOVEM.L registers */
5138 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
5140 EndPutM16Inc(data
, 0x4E75); /* RTS */
5143 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
5145 EndPutM32(tempbuf
, HUNK_CODE
);
5146 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
5147 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
5149 EndPutM32(tempbuf
, HUNK_EXT
);
5150 DoOutputDirect(tempbuf
,4);
5152 /* here come the XDEF name references */
5154 if(!(Flags
& FLAG_ONLYCNAMES
))
5156 OutputXDEF(0, "%s", name
); /* ASM names */
5157 OutputXDEF(0, "LOC_%s", name
);
5160 OutputXDEF(0, "_%s", name
); /* C names */
5161 OutputXDEF(0, "_LOC_%s", name
);
5163 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5167 /* C++ names no parameters */
5168 OutputXDEF(0, "%s__%sP07Library", name
, str2
);
5169 OutputXDEF(0, "LOC_%s__%sP07Library", name
, str2
);
5171 else if((cd
= GetClibFunc(name
, ap
, flags
)))
5175 txt
= (strptr
) tempbuf
;
5177 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5179 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5180 { /* C++ names with parameters */
5181 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5183 OutputXDEF(0, "%s__%sP07Library%s", name
, str2
, txt
);
5184 OutputXDEF(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5188 OutputXDEF(0, "%s__%s", name
, txt
);
5189 OutputXDEF(0, "LOC_%s__%s", name
, txt
);
5196 EndPutM32(tempbuf
, 0);
5197 DoOutputDirect(tempbuf
,4);
5198 if(!(Flags
& FLAG_NOSYMBOL
))
5200 EndPutM32(tempbuf
, HUNK_SYMBOL
);
5201 DoOutputDirect(tempbuf
,4);
5202 if(!(Flags
& FLAG_ONLYCNAMES
))
5204 OutputSYMBOL(0, "%s", name
); /* ASM names */
5205 OutputSYMBOL(0, "LOC_%s", name
);
5208 OutputSYMBOL(0, "_%s", name
); /* C names */
5209 OutputSYMBOL(0, "_LOC_%s", name
);
5211 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5215 /* C++ names no parameters */
5216 OutputSYMBOL(0, "%s__%sP07Library", name
, str2
);
5217 OutputSYMBOL(0, "LOC_%s__%sP07Library", name
, str2
);
5223 txt
= (strptr
) tempbuf
;
5225 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5227 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5228 { /* C++ names with parameters */
5229 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5231 OutputSYMBOL(0, "%s__%sP07Library%s", name
, str2
, txt
);
5232 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5236 OutputSYMBOL(0, "%s__%s", name
, txt
);
5237 OutputSYMBOL(0, "LOC_%s__%s", name
, txt
);
5244 EndPutM32(tempbuf
, 0);
5245 DoOutputDirect(tempbuf
,4);
5247 EndPutM32(tempbuf
, HUNK_END
);
5248 return DoOutputDirect(tempbuf
,4);
5251 uint32
FuncLocText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5253 struct ClibData
*cd
;
5256 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5259 Flags
|= FLAG_DONE
; /* We did something */
5261 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
5264 OutClibType(&cd
->ReturnType
, 0);
5265 DoOutput(" LOC_%s("/*)*/, name
);
5266 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5268 if(Flags
& FLAG_LOCALREG
)
5269 DoOutput("register __a6 ");
5270 DoOutput("%s libbase", GetBaseType());
5277 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
5279 if(((Flags
& FLAG_LOCALREG
&&
5280 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5281 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
5285 if(flags
& FUNCFLAG_NORMAL
)
5287 if(((Flags
& FLAG_LOCALREG
&&
5288 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5289 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) ||
5290 !DoOutput(/*(*/");\n"))
5294 DoOutput("#define %s("/*)*/, name
);
5295 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5296 DoOutput("%c, ", 'a'+(char)i
);
5297 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i
, name
, BaseName
);
5298 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5299 DoOutput("%c, ",'a'+(char)i
);
5300 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i
);
5304 return DoOutput(/*(*/"...);\n");
5307 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5310 return DoOutput(/*(*/");\n");
5314 uint32
FuncInlineDirect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5316 uint32 a4
= 0, a5
= 0;
5318 int32 i
, maxargs
, reg
=0;
5319 struct ClibData
*cd
;
5321 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
|AMIPRAGFLAG_VARARGS
))
5324 Flags
|= FLAG_DONE
; /* We did something */
5326 if(flags
& FUNCFLAG_ALIAS
)
5328 if(flags
& FUNCFLAG_TAG
)
5329 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5332 DoOutput("#define %s("/*)*/, name
);
5333 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5334 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5335 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5336 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5337 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5338 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5341 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5344 if(flags
& FUNCFLAG_TAG
)
5346 /* do not create some strange functions */
5347 if(IsNoCreateInlineFunc(name
))
5348 DoOutput("#if !defined(NO_INLINE_STDARG) "
5349 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5351 DoOutput("#ifndef NO_INLINE_STDARG\n");
5352 DoOutput("static __inline__ ");
5353 FuncCSTUBS(ap
, flags
|FUNCFLAG_EXTENDMODE
, name
);
5355 DoOutput("#define %s("/*)*/, name
);
5356 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5358 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5362 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name
, ShortBaseNameUpper
);
5363 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5364 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5367 DoOutput(/*(*/")\n");
5368 return DoOutput("#endif\n\n");
5371 DoOutput("#define %s("/*)*/, name
);
5374 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5375 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5376 DoOutput("%s", ap
->Args
[i
].ArgName
);
5378 DoOutput(/*(*/") ({ \\\n"/*})*/);
5380 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5382 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5384 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5385 DoOutput(" = (%s); \\\n", ap
->Args
[i
].ArgName
);
5388 if(Flags
& FLAG_INLINENEW
)
5391 DoOutput(" ({ \\\n"/*})*/);
5392 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name
);
5394 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper
);
5397 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
5399 if(i
== ap
->NumArgs
)
5401 DoOutput("(%s);\\\n", ap
->Args
[i
].ArgName
);
5404 DoOutput(" (("/*))*/);
5405 OutClibType(&cd
->ReturnType
, 0);
5406 DoOutput(" (*)("/*)*/);
5409 DoOutput("char * __asm(\"a6\")");
5413 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5415 OutClibType(&cd
->Args
[i
], 0);
5416 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
5417 if(i
< ap
->NumArgs
-1)
5420 DoOutput(/*((*/")) \\\n");
5421 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name
, ap
->Bias
);
5424 DoOutput("_%s__bn", name
);
5428 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5430 if(ap
->Args
[i
].ArgReg
== REG_A6
)
5431 DoOutput("_%s__bn", name
);
5433 DoOutput("_%s_%s", name
, ap
->Args
[i
].ArgName
);
5434 if(i
< ap
->NumArgs
-1)
5437 DoOutput(/*(*/"); \\\n");
5439 DoOutput(/*({*/"});");
5443 /* do A5 first, as it is more important */
5444 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5446 a5
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5447 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5448 a5
|= 1<<ap
->Args
[i
].ArgReg
;
5452 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A5
]);
5457 for(i
= 0; (a5
& 1) && a5
; ++i
)
5459 a5
= i
; /* this is our A5 swap register */
5462 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5464 a4
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5467 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5468 a4
|= 1<<ap
->Args
[i
].ArgReg
;
5472 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A4
]);
5477 for(i
= 0; (a4
& 1) && a4
; ++i
)
5479 a4
= i
; /* this is our A4 swap register */
5482 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5483 noret
= 1; /* this is a void function */
5485 if(ap
->NumArgs
|| !noret
)
5486 DoOutput(" %s{ \\\n", noret
? "" : "(" /*})*/);
5489 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5491 " register int _d1 __asm(\"d1\"); \\\n"
5492 " register int _a0 __asm(\"a0\"); \\\n"
5493 " register int _a1 __asm(\"a1\"); \\\n");
5496 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5497 GetBaseType(), name
, ShortBaseNameUpper
);
5501 sprintf((strptr
)tempbuf
, "__%s__re", name
);
5502 DoOutput(" register ");
5503 OutClibType(&cd
->ReturnType
, (strptr
) tempbuf
);
5504 DoOutput(" __asm(\"d0\"); \\\n");
5506 if((maxargs
= ap
->NumArgs
) >= 9 && (Flags
& FLAG_STORMGCC
))
5508 for(i
= 0; i
< maxargs
; ++i
)
5510 reg
= ap
->Args
[i
].ArgReg
;
5511 if(a5
&& reg
== REG_A5
) reg
= a5
; /* we need to switch */
5512 if(a4
&& reg
== REG_A4
) reg
= a4
; /* we need to switch */
5514 sprintf((strptr
)tempbuf
, "__%s_%s", name
, ap
->Args
[i
].ArgName
);
5515 DoOutput(" register ");
5516 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5517 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames
[reg
],
5518 (strptr
) (tempbuf
+1));
5520 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5522 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name
);
5523 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5525 DoOutput(" ULONG __%s_%s; \\\n", name
, ap
->Args
[i
].ArgName
);
5526 reg
= ap
->Args
[i
].ArgReg
;
5531 else if(reg
== REG_A5
)
5536 /* reg is now either the last register argument or its a4/a5 redirect */
5537 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name
);
5538 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5540 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5541 DoOutput("(ULONG)(%s)%s", (strptr
)tempbuf
, i
== ap
->NumArgs
-1 ?
5544 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5545 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name
, name
,
5546 RegNames
[reg
], name
);
5548 DoOutput(" __asm volatile (\""/*)*/);
5549 if(a5
) DoOutput("exg a5,%s\\n\\t", RegNames
[a5
]);
5550 if(a4
) DoOutput("exg a4,%s\\n\\t", RegNames
[a4
]);
5551 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5553 DoOutput("movem.l ");
5554 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5556 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5557 i
== ap
->NumArgs
-1 ? "" : "/");
5559 DoOutput(",-(a7)\\n\\t");
5560 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5563 DoOutput("move.l (%s),%s\\n\\t", RegNames
[reg
],
5564 RegNames
[ap
->Args
[i
].ArgReg
]);
5566 DoOutput("move.l %ld(%s),%s\\n\\t", (i
-maxargs
)*4, RegNames
[reg
],
5567 RegNames
[ap
->Args
[i
].ArgReg
]);
5570 DoOutput("jsr a6@(-%d:W)", ap
->Bias
);
5571 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5573 DoOutput("\\n\\tmovem.l (a7)+,");
5574 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5576 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5577 i
== ap
->NumArgs
-1 ? "" : "/");
5580 if(a4
) DoOutput("\\n\\texg a4,%s", RegNames
[a4
]);
5581 if(a5
) DoOutput("\\n\\texg a5,%s", RegNames
[a5
]);
5582 DoOutput("\" \\\n");
5585 DoOutput(" : \"=r\" (_d0)");
5587 DoOutput(" : \"=r\"(__%s__re)", name
);
5588 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5590 DoOutput(" \"r\"(__%s__bn)%s", name
, ap
->NumArgs
? "," : "");
5591 for(i
= 0; i
< maxargs
; ++i
)
5593 DoOutput(" \"rf\"(__%s_%s)", name
, ap
->Args
[i
].ArgName
);
5594 if(i
< ap
->NumArgs
-1)
5597 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5598 DoOutput(" \"r\"(__%s__ArgsPtr)", name
);
5599 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5601 if(ap
->NumArgs
|| !noret
)
5602 DoOutput(/*({*/" }%s \\\n", noret
? "" : ");");
5605 return DoOutput(/*({*/"})\n\n");
5608 uint32
FuncInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5610 uint32 noret
= 0, a45
= 0, j
;
5612 struct ClibData
*cd
;
5614 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5617 if(!(Flags
& FLAG_INLINENEW
) && CheckError(ap
, AMIPRAGFLAG_MOSBASESYSV
))
5620 Flags
|= FLAG_DONE
; /* We did something */
5622 if(flags
& FUNCFLAG_ALIAS
)
5624 if(flags
& FUNCFLAG_TAG
)
5625 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5626 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
5628 DoOutput("#define %s("/*)*/, name
);
5629 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5630 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5631 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5632 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5633 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5634 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5637 if(!(cd
= GetClibFunc(ap
->Flags
& AMIPRAGFLAG_VARARGS
?
5638 ap
->TagName
: ap
->FuncName
, ap
, flags
)))
5641 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5642 noret
= 1; /* this is a void function */
5644 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5646 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5650 DoError(ERR_INLINE_A4_AND_A5
, ap
->Line
);
5651 return 1; /* skip this entry */
5655 if(a45
&& (ap
->Flags
& AMIPRAGFLAG_D7USE
))
5657 DoError(ERR_INLINE_D7_AND_A45
, ap
->Line
);
5658 return 1; /* skip this entry */
5661 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
5663 if(Flags
& FLAG_INLINENEW
)
5665 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5666 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "");
5667 if(IsNoCreateInlineFunc(name
))
5669 DoOutput("__inline ");
5670 FuncCSTUBS(ap
, flags
, name
);
5671 /* call CSTUBS, as this equals the method used there */
5675 DoOutput("#define %s("/*)*/, name
);
5676 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5678 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5680 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5682 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5683 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5685 OutClibType(&cd
->Args
[i
], 0);
5686 DoOutput(/*({((*/") _tags);})\n");
5688 return DoOutput("#endif\n\n");
5690 else if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5691 == (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5693 int32 n
, d
, tagl
, local
;
5697 tagl
= 8 + (Flags2
& FLAG2_DIRECTVARARGS
? 0 : 64);
5698 local
= (n
* 4+d
+8+15) & ~15; /* size of the stack frame */
5701 * 0- 3: next frame ptr
5704 * 72-72+n*4+d+8-1: tag list start
5705 * ?-local-1: padding
5708 DoOutput("asm(\"\n"/*)*/
5711 "\t.type\t%s,@function\n"
5713 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5715 "\tstw\t0,%ld(1)\n",
5716 name
, name
, name
, local
, local
+4);
5718 /* If n is odd, one tag is split between regs and stack.
5719 * Copy its ti_Data together with the ti_Tag. */
5721 DoOutput("\tlwz\t0,%ld(1)\n", local
+8); /* read ti_Data */
5723 /* Save the registers */
5724 for(i
= ap
->NumArgs
; i
<= 8; ++i
)
5725 DoOutput("\tstw\t%ld,%ld(1)\n", i
+2, (i
-ap
->NumArgs
) * 4+tagl
);
5728 DoOutput("\tstw\t0,%ld(1)\n", tagl
+n
* 4); /* write ti_Data */
5731 DoOutput("\tli\t0,2\n"
5732 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5734 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5735 tagl
+n
* 4+d
, local
+8+d
, tagl
+n
* 4+d
+4);
5737 if(Flags2
& FLAG2_DIRECTVARARGS
)
5739 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5740 "\tbl\t%s\n", ap
->NumArgs
+2, tagl
, name
);
5747 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
5750 /* Caos.Offset = -fD_GetOffset(obj) */
5751 DoOutput("\tli\t0,%d\n"
5752 "\tstw\t0,8(1)\n", -ap
->Bias
);
5754 /* Save the non-varargs registers in the Caos struct. */
5755 for(i
=0; i
< ap
->NumArgs
-1; ++i
)
5757 DoOutput("\tstw\t%ld,%d(1)\n", i
+3, 8+4+(ap
->Args
[i
].ArgReg
* 4));
5760 DoOutput("\taddi\t0,1,%ld\n"
5762 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5763 "\tlwz\t12,%s@l(3)\n"
5765 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5768 "\tbctrl\n", /* EmulCallOS() */
5769 tagl
, BaseName
, 12+(4 * ap
->Args
[i
].ArgReg
), BaseName
);
5771 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5775 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local
+4, local
, name
, name
);
5779 DoOutput("%s%s__inline ", Flags
& FLAG_INLINESTUB
? "" : "extern ",
5780 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5781 return FuncCSTUBS(ap
, flags
, name
);
5782 /* call CSTUBS, as this equals the method used there */
5786 if(Flags
& FLAG_INLINENEW
) /* new style */
5788 strptr funcpar
= "";
5789 DoOutput("#define %s("/*)*/, name
);
5791 for(i
= 0; i
< cd
->NumArgs
; ++i
)
5793 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5799 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5800 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5801 DoOutput("%s", ap
->Args
[i
].ArgName
);
5803 DoOutput(/*(*/") \\\n\t");
5804 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
5806 DoOutput("((("/*)))*/);
5807 OutClibType(&cd
->ReturnType
, 0);
5808 DoOutput(" (*)("/*)*/);
5809 DoOutput("%s", GetBaseType());
5810 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5813 OutClibType(&cd
->Args
[i
], 0);
5815 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5816 "(%s_BASE_NAME",/*)*/
5817 ShortBaseNameUpper
, ap
->Bias
-2, ShortBaseNameUpper
);
5819 for(i
= 0; i
< ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0); ++i
)
5820 DoOutput(", %s", ap
->Args
[i
].ArgName
);
5821 if(flags
& FUNCFLAG_TAG
)
5822 DoOutput(", __VA_ARGS__");
5823 return DoOutput(/*((*/"))\n\n");
5825 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap
->NumArgs
,
5826 (noret
? "NR" : ""), (a45
? RegNamesUpper
[a45
] : (strptr
) ""),
5827 (BaseName
? "" : "UB"), funcpar
, ap
->Bias
);
5830 OutClibType(&cd
->ReturnType
, 0);
5833 DoOutput("%s, ", name
);
5835 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5837 j
= ap
->Args
[i
].ArgReg
;
5838 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5840 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5844 DoError(ERR_MULTIPLEFUNCTION
, ap
->Line
);
5849 DoOutput("__fpt"); fp
= i
;
5853 OutClibType(&cd
->Args
[i
], 0);
5855 DoOutput(", %s, %s%s", ap
->Args
[i
].ArgName
, RegNames
[j
],
5856 (i
== ap
->NumArgs
-1 && !BaseName
? "" : ", "));
5859 if(BaseName
) /* was "##base" used? */
5860 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper
);
5865 OutClibType(&cd
->Args
[fp
], "__fpt");
5868 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
5869 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5871 return DoOutput(/*(*/")\n\n");
5874 /* old mode or stubs mode */
5876 if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
)) != (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5877 DoOutput("%s%s__inline ", Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
) ?
5878 "" : "extern ", Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5879 OutClibType(&cd
->ReturnType
, 0);
5880 DoOutput("\n%s(%s"/*)*/, name
, (BaseName
?
5881 (ap
->NumArgs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5883 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5885 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5886 if(i
< ap
->NumArgs
-1)
5890 if(Flags
& FLAG_POWERUP
)
5892 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5893 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5894 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5895 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5896 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5897 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5898 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5902 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5904 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5905 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5909 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5912 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper
);
5913 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5914 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5917 DoOutput("\treturn(("/*))*/);
5918 OutClibType(&cd
->ReturnType
, 0);
5919 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5921 return Output_Error
;
5923 else if(Flags
& FLAG_MORPHOS
)
5925 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5929 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5931 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5932 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5936 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5938 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5939 ShortBaseNameUpper
);
5941 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5942 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5945 DoOutput("\treturn(("/*))*/);
5946 OutClibType(&cd
->ReturnType
, 0);
5947 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5949 return Output_Error
;
5952 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName
? " BASE_EXT_DECL\n" : ""));
5956 DoOutput(" register ");
5957 OutClibType(&cd
->ReturnType
, "res");
5958 DoOutput(" __asm(\"d0\");\n");
5962 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5963 GetBaseType(), ShortBaseNameUpper
);
5965 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5967 j
= ap
->Args
[i
].ArgReg
;
5968 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5971 DoOutput(" register ");
5972 OutClibType(&cd
->Args
[i
], RegNames
[j
]);
5973 DoOutput(" __asm(\"%s\") = %s;\n", RegNames
[j
], ap
->Args
[i
].ArgName
);
5978 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
5979 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames
[a45
],
5980 ap
->Bias
, RegNames
[a45
]);
5983 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap
->Bias
);
5985 DoOutput(noret
? " : /* No Output */\n" : " : \"=r\" (res)\n");
5989 DoOutput("\"r\" (a6)%s", (ap
->NumArgs
? ", ": ""));
5991 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5993 j
= ap
->Args
[i
].ArgReg
;
5994 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5997 DoOutput("\"r\" (%s)%s", RegNames
[j
], (i
< ap
->NumArgs
-1 ? ", " : ""));
6000 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6003 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6005 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6009 /* new style inlines designed by Bernardo Innocenti */
6010 uint32
FuncInlineNS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6013 struct ClibData
*cd
;
6015 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6018 Flags
|= FLAG_DONE
; /* We did something */
6020 if(flags
& FUNCFLAG_ALIAS
)
6022 if(flags
& FUNCFLAG_TAG
)
6023 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6026 DoOutput("#define %s("/*)*/, name
);
6027 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6028 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6029 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6030 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6031 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6032 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6035 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6038 if((flags
& FUNCFLAG_TAG
))
6040 if(!(Flags2
& FLAG2_INLINEMAC
))
6042 DoOutput("static __inline ");
6043 return FuncCSTUBS(ap
, flags
, name
);
6044 /* call CSTUBS, as this equals the method used there */
6048 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6049 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
6050 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6051 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6052 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6054 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6055 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6057 OutClibType(&cd
->Args
[i
], 0);
6058 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6062 if(Flags2
& FLAG2_INLINEMAC
)
6064 DoOutput("#define %s("/*)*/, name
);
6065 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6067 DoOutput("%s", ap
->Args
[i
].ArgName
);
6068 if(i
< ap
->NumArgs
-1)
6071 DoOutput(/*(*/") \\\n\t");
6075 DoOutput("static __inline ");
6076 OutClibType(&cd
->ReturnType
, 0);
6077 DoOutput(" %s("/*)*/, name
);
6078 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6080 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6081 if(i
< ap
->NumArgs
-1)
6084 DoOutput(/*(*/")\n{\n "/*}*/);
6085 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6086 DoOutput("return ");
6088 DoOutput("(("/*))*/);
6089 OutClibType(&cd
->ReturnType
, 0);
6090 DoOutput(" (*)("/*)*/);
6091 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6093 OutClibType(&cd
->Args
[i
], 0);
6094 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
6095 if(i
< ap
->NumArgs
-1)
6102 DoOutput("%s __asm(\"a6\")", GetBaseType());
6104 DoOutput(/*((*/"))");
6105 if(Flags2
& FLAG2_INLINEMAC
)
6108 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6109 ShortBaseNameUpper
, ap
->Bias
);
6112 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
6114 if(i
== ap
->NumArgs
)
6116 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap
->Args
[i
].ArgName
,
6119 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6121 DoOutput("%s", ap
->Args
[i
].ArgName
);
6122 if(i
< ap
->NumArgs
-1)
6129 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
6132 if(Flags2
& FLAG2_INLINEMAC
)
6133 DoOutput(/*(*/")\n");
6135 DoOutput(/*{(*/");\n}\n");
6137 return DoOutput("\n");
6140 uint32
FuncPowerUP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6143 struct ClibData
*cd
;
6145 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6148 Flags
|= FLAG_DONE
; /* We did something */
6150 if(flags
& FUNCFLAG_ALIAS
)
6152 if(flags
& FUNCFLAG_TAG
)
6153 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6156 DoOutput("#define %s("/*)*/, name
);
6157 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6158 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6159 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6160 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6161 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6162 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6165 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6168 if(flags
& FUNCFLAG_TAG
)
6170 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name
);
6171 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6172 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6173 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6175 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6176 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6178 OutClibType(&cd
->Args
[i
], 0);
6179 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6182 DoOutput("#define\t%s("/*)*/, name
);
6187 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6188 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6189 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap
->Args
[i
].ArgName
, name
);
6192 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper
);
6194 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6195 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6196 DoOutput(/*(*/"%s)\n\n", ap
->Args
[i
].ArgName
);
6199 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name
, ShortBaseNameUpper
);
6201 DoOutput(/*(*/")\t_%s()\n\n", name
);
6203 DoOutput("static __inline ");
6204 OutClibType(&cd
->ReturnType
, 0);
6206 DoOutput("\n_%s("/*)*/, name
);
6208 DoOutput("void * %s%s", BaseName
, ap
->NumArgs
? ", " : "");
6210 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6212 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6213 if(i
< ap
->NumArgs
-1)
6217 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6218 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6219 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6220 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6221 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6222 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6223 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6227 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6229 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6230 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
6234 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
6237 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName
);
6238 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6239 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6242 DoOutput("\treturn(("/*))*/);
6243 OutClibType(&cd
->ReturnType
, 0);
6244 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6246 return Output_Error
;
6249 uint32
FuncFPCUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6252 struct ClibData
*cd
;
6254 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6256 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6259 if(!FuncFPCType(ap
, flags
, name
))
6262 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6264 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6265 DoOutput("\tMOVE%s.L\t%s,%s\n", ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "",
6266 ap
->Args
[i
].ArgName
, RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
6269 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName
);
6270 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap
->Bias
);
6272 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6274 if(!cd
->ReturnType
.PointerDepth
&&
6275 cd
->ReturnType
.Flags
== CPP_FLAG_BOOLEAN
)
6276 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6277 " @end:\tMOVE.B\tD0,@RESULT\n");
6279 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6281 return DoOutput(" END;\nEND;\n\n");
6284 uint32
FuncFPCType(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6288 struct ClibData
*cd
;
6290 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6292 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6295 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6297 ret
= 0; DoOutput("PROCEDURE %s", name
);
6300 DoOutput("FUNCTION %s", name
);
6305 for(i
= 0; i
< ap
->NumArgs
;)
6307 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6308 if(++i
!= ap
->NumArgs
)
6315 OutPASCALType(&cd
->ReturnType
, "", 1);
6317 Flags
|= FLAG_DONE
; /* We did something */
6319 return DoOutput(";\n");
6322 uint32
FuncFPCTypeTags(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6326 struct ClibData
*cd
;
6328 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6330 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6333 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6335 ret
= 0; DoOutput("PROCEDURE %s", name
);
6338 DoOutput("FUNCTION %s", name
);
6343 for(i
= 0; i
< ap
->NumArgs
-1;)
6345 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6346 if(++i
!= ap
->NumArgs
)
6349 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6354 OutPASCALType(&cd
->ReturnType
, "", 1);
6356 Flags
|= FLAG_DONE
; /* We did something */
6358 return DoOutput(";\n");
6361 uint32
FuncFPCTypeTagsUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6365 struct ClibData
*cd
;
6367 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6369 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6372 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6374 ret
= 0; DoOutput("PROCEDURE %s", name
);
6377 DoOutput("FUNCTION %s", name
);
6382 for(i
= 0; i
< ap
->NumArgs
-1;)
6384 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6385 if(++i
!= ap
->NumArgs
)
6388 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6393 OutPASCALType(&cd
->ReturnType
, "", 1);
6395 DoOutput(";\nbegin\n");
6398 DoOutput(" %s := %s",name
, ap
->FuncName
);
6399 else DoOutput(" %s", ap
->FuncName
);
6404 for(i
= 0; i
< ap
->NumArgs
-1;)
6406 DoOutput("%s ", ap
->Args
[i
].ArgName
);
6407 if(++i
!= ap
->NumArgs
)
6410 DoOutput("readintags(%s)",ap
->Args
[i
].ArgName
);
6411 DoOutput(/*(*/");");
6416 Flags
|= FLAG_DONE
; /* We did something */
6418 return DoOutput(";\n\n");
6422 uint32
FuncBMAP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6426 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_A5USE
6430 Flags
|= FLAG_DONE
; /* We did something */
6432 for(i
= 0; BMAPSpecial
[i
]; ++i
)
6434 if(!stricmp(name
, BMAPSpecial
[i
]))
6436 DoOutput("x"); break;
6440 DoOutput("%s",name
);
6441 reg
= 0; DoOutputDirect(®
, 1);
6442 reg
= (-ap
->Bias
)>>8; DoOutputDirect(®
, 1);
6443 reg
= -ap
->Bias
; DoOutputDirect(®
, 1);
6444 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6446 reg
= 1+ap
->Args
[i
].ArgReg
; DoOutputDirect(®
, 1);
6449 return DoOutputDirect(®
, 1);
6452 uint32
FuncVBCCInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6454 struct ClibData
*cd
;
6458 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6461 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6464 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
6465 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
6467 Flags
|= FLAG_DONE
; /* We did something */
6469 if(flags
& FUNCFLAG_TAG
)
6471 if(IsNoCreateInlineFunc(name
))
6472 return 1; /* do not create some strange functions */
6473 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6474 "(__STDC_VERSION__ >= 199901L)\n");
6477 if(flags
& FUNCFLAG_ALIAS
)
6479 DoOutput("#define %s("/*)*/, name
);
6480 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6481 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6482 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6483 if(Flags2
& FLAG2_OLDVBCC
)
6485 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6486 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6487 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6492 DoOutput("%s", BaseName
);
6493 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6494 DoOutput(", (%s)", ap
->Args
[i
].ArgName
);
6495 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
?
6500 OutClibType(&cd
->ReturnType
, 0);
6501 DoOutput(" __%s("/*)*/, name
);
6503 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6505 DoOutput("__reg(\"a6\") %s", GetBaseType());
6510 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6511 for(i
= 0; i
< k
; ++i
)
6513 DoOutput("__reg(\"%s\") ", RegNames
[ap
->Args
[i
].ArgReg
]);
6514 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6515 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6517 DoOutput("void * %s", ap
->Args
[i
].ArgName
);
6520 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6521 if(i
< ap
->NumArgs
-1)
6525 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6529 DoOutput("__reg(\"a6\") %s", GetBaseType());
6532 if(flags
& FUNCFLAG_TAG
)
6534 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6536 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6539 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6540 RegNames
[ap
->Args
[k
].ArgReg
]);
6542 if(ap
->Args
[k
].ArgReg
> 7)
6543 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1
, c2
,
6544 RegNames
[ap
->Args
[k
].ArgReg
]);
6546 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6547 RegNames
[ap
->Args
[k
].ArgReg
], RegNames
[ap
->Args
[k
].ArgReg
]);
6549 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6550 "\\tmove%s.l\\t(a7)+,%s\";\n", c1
, ap
->Bias
, c2
,
6551 ap
->Args
[k
].ArgReg
>= REG_A0
? "a" : "", RegNames
[ap
->Args
[k
].ArgReg
]);
6554 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1
, ap
->Bias
, c2
);
6556 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6557 DoOutput("#define %s("/*)*/, name
);
6558 for(i
= 0; i
< k
; ++i
)
6560 DoOutput("%s", ap
->Args
[i
].ArgName
);
6561 if(i
< ap
->NumArgs
-1)
6564 if(flags
& FUNCFLAG_TAG
)
6566 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6567 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6570 DoOutput(/*(*/") __%s("/*)*/, name
);
6571 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6573 DoOutput("%s", BaseName
);
6577 for(i
= 0; i
< k
; ++i
)
6579 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6580 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6582 DoOutput("(void *)");
6584 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6585 if(i
< ap
->NumArgs
-1)
6588 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6592 DoOutput("%s", BaseName
);
6594 if(flags
& FUNCFLAG_TAG
)
6596 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6597 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6598 DoOutput("__VA_ARGS__");
6601 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6604 uint32
FuncVBCCWOSInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6606 struct ClibData
*cd
;
6609 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_M68K
))
6612 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6615 Flags
|= FLAG_DONE
; /* We did something */
6617 if(flags
& FUNCFLAG_TAG
)
6619 if(IsNoCreateInlineFunc(name
))
6620 return 1; /* do not create some strange functions */
6621 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6622 "(__STDC_VERSION__ >= 199901L)\n");
6625 if(flags
& FUNCFLAG_ALIAS
)
6627 DoOutput("#define %s("/*)*/, name
);
6628 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6629 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6630 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6631 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6632 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6633 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6637 OutClibType(&cd
->ReturnType
, 0);
6638 DoOutput(" __%s("/*)*/, name
);
6640 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6642 DoOutput("%s", GetBaseType());
6648 for(i
= 0; i
< k
; ++i
)
6650 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6654 if(flags
& FUNCFLAG_TAG
)
6655 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6657 DoOutput(/*(*/")=\"");
6658 if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6660 DoOutput("\\t.extern\\t_%s\\n", BaseName
);
6661 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6663 /* save tag1 and load taglist-pointer */
6664 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6665 "\\taddi\\t%s%d,%s1,%d\\n",
6666 PPCRegPrefix
, (int)k
+2, 20+(int)k
*4, PPCRegPrefix
, PPCRegPrefix
,
6667 (int)k
+2, PPCRegPrefix
, 20+(int)k
*4);
6669 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6670 "\\tlwz\\t%s0,-%d(%s11)\\n"
6673 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
,
6674 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6676 else if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6678 /* @@@ tagcall handling? */
6679 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6680 "\\t.extern\\t_%s\\n"
6681 "\\tlwz\\t%s2,_%s(%s2)\\n"
6682 "\\tlwz\\t%s0,-%d(%s2)\\n"
6685 "\\tlwz\\t%s2,20(%s1)",
6686 PPCRegPrefix
, PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
,
6687 PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
6688 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6692 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6694 /* save tag1 and load taglist-pointer */
6695 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6696 "\\taddi\\t%s%d,%s1,%d\\n",
6697 PPCRegPrefix
, (int)k
+3, 24+(int)k
*4, PPCRegPrefix
, PPCRegPrefix
,
6698 (int)k
+3, PPCRegPrefix
, 24+(int)k
*4);
6700 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6703 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6707 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6708 DoOutput("#define %s("/*)*/, name
);
6709 for(i
= 0; i
< k
; ++i
)
6711 DoOutput("%s", ap
->Args
[i
].ArgName
);
6712 if(i
< ap
->NumArgs
-1)
6715 if(flags
& FUNCFLAG_TAG
)
6717 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6718 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6721 DoOutput(/*(*/") __%s("/*)*/, name
);
6722 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6724 DoOutput("%s", BaseName
);
6728 for(i
= 0; i
< k
; ++i
)
6730 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6731 if(i
< ap
->NumArgs
-1)
6734 if(flags
& FUNCFLAG_TAG
)
6736 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6737 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6738 DoOutput("__VA_ARGS__");
6741 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6744 uint32
FuncVBCCMorphInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6746 struct ClibData
*cd
;
6749 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6752 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6755 Flags
|= FLAG_DONE
; /* We did something */
6757 if(flags
& FUNCFLAG_TAG
)
6759 if(IsNoCreateInlineFunc(name
))
6760 return 1; /* do not create some strange functions */
6761 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6762 "(__STDC_VERSION__ >= 199901L)\n");
6765 if(flags
& FUNCFLAG_ALIAS
)
6767 DoOutput("#define %s("/*)*/, name
);
6768 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6769 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6770 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6771 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6772 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6773 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6777 OutClibType(&cd
->ReturnType
, 0);
6778 if((flags
& FUNCFLAG_TAG
) && (Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6779 DoOutput(" __linearvarargs");
6781 DoOutput(" __%s("/*)*/, name
);
6783 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6785 DoOutput("%s", GetBaseType());
6790 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6792 if((flags
& FUNCFLAG_TAG
) &&
6793 !(ap
->Flags
& AMIPRAGFLAG_MOS_ALL
))
6795 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6800 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6801 for(i
= 0; i
< k
; ++i
)
6803 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6804 if(i
< ap
->NumArgs
-1)
6808 if(flags
& FUNCFLAG_TAG
)
6810 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6812 if((ap
->Flags
& AMIPRAGFLAG_MOS_ALL
)
6813 && !(ap
->Flags
& AMIPRAGFLAG_VARARGS
))
6815 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6818 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6820 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6828 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
6830 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6831 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6832 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6834 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6835 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6837 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6838 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6840 else if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
6844 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6845 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6846 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6847 PPCRegPrefix
, BaseName
,
6848 PPCRegPrefix
, BaseName
, PPCRegPrefix
,
6849 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6851 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6853 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6854 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6856 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6857 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6861 int ofs
= 4, fix
= 0;
6862 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6863 PPCRegPrefix
, PPCRegPrefix
);
6867 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix
, k
++,
6870 if(Flags2
& FLAG2_SHORTPPCVBCCINLINE
)
6873 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6876 else if(flags
& FUNCFLAG_TAG
)
6878 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6882 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix
);
6883 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6885 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
6888 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix
, k
++);
6890 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6891 PPCRegPrefix
, 8+(k
++-11)*4, PPCRegPrefix
, PPCRegPrefix
);
6895 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6896 PPCRegPrefix
, ofs
, PPCRegPrefix
, (2+k
+fix
-11)*4, PPCRegPrefix
, ofs
);
6898 DoOutput("%d(%s2)\\n\"\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6900 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix
,
6904 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6905 DoOutput("#define %s("/*)*/, name
);
6906 for(i
= 0; i
< k
; ++i
)
6908 DoOutput("%s", ap
->Args
[i
].ArgName
);
6909 if(i
< ap
->NumArgs
-1)
6912 if(flags
& FUNCFLAG_TAG
)
6914 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6915 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6918 DoOutput(/*(*/") __%s("/*)*/, name
);
6919 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6921 DoOutput("%s", BaseName
);
6925 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6927 if(flags
& FUNCFLAG_TAG
&& !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
6929 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6933 for(i
= 0; i
< k
; ++i
)
6935 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6936 if(i
< ap
->NumArgs
-1)
6939 if(flags
& FUNCFLAG_TAG
)
6941 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6942 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6943 DoOutput("__VA_ARGS__");
6946 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6949 uint32
FuncVBCCWOSText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6951 uint32 i
, k
, count
, ofs
;
6952 struct ClibData
*cd
= 0;
6954 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
6957 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
6958 !(cd
= GetClibFunc(name
, ap
, flags
)))
6961 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
6962 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
6963 !(Flags
& FLAG_WOSLIBBASE
)))
6965 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
6971 if(Flags
& FLAG_SINGLEFILE
)
6973 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
6978 DoOutputDirect(HEADER
, headersize
);
6982 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
6983 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
6985 if(Flags
& FLAG_SINGLEFILE
)
6986 DoOutput("\t.file\t\"%s.o\"\n", name
);
6987 DoOutput("\t.align\t3\n");
6988 if(Flags
& FLAG_WOSLIBBASE
) /* PPCBase already in r3, LibBase in r4 */
6990 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
6991 DoOutput("\t.extern _%s\n", BaseName
);
6992 DoOutput("\t.global __%s\n__%s:\n", name
, name
);
6997 DoOutput("\t.extern _%s\n", BaseName
);
6998 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
6999 DoOutput("\t.extern _PowerPCBase\n");
7000 DoOutput("\t.global _%s\n_%s:\n", name
, name
);
7003 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7005 DoOutput("\tstw\t%s2,20(%s1)\n"
7007 "\tstw\t%s0,16(%s1)\n"
7008 "\tlwz\t%s2,_%s(%s2)\n"
7009 "\tlwz\t%s0,-%d(%s2)\n"
7012 "\tlwz\t%s0,16(%s1)\n"
7013 "\tlwz\t%s2,20(%s1)\n"
7016 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7017 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2,
7018 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7019 PPCRegPrefix
, PPCRegPrefix
);
7021 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7023 DoOutput("\tmflr\t%s0\n", PPCRegPrefix
);
7024 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7026 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7027 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7028 PPCRegPrefix
, (int)ap
->NumArgs
+2,
7029 20+(int)ap
->NumArgs
*4, PPCRegPrefix
, PPCRegPrefix
,
7030 (int)ap
->NumArgs
+2, PPCRegPrefix
, 20+(int)ap
->NumArgs
*4);
7032 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7033 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7034 "\tlwz\t%s11,_%s(%s2)\n"
7035 "\tlwz\t%s0,-%d(%s11)\n"
7038 "\tlwz\t%s0,40(%s1)\n"
7039 "\taddi\t%s1,%s1,32\n"
7042 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7043 BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
7044 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7047 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7049 count
= ap
->NumArgs
;
7050 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7052 /* init stack frame */
7053 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7054 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7055 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7059 /* extra arguments must be passed on the stack */
7060 k
= 32-(count
-8); /* firstreg */
7062 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7063 PPCRegPrefix
, k
, 56+(count
-8)*4, PPCRegPrefix
, PPCRegPrefix
, k
,
7064 i
+56, PPCRegPrefix
);
7065 if(flags
& FUNCFLAG_TAG
)
7066 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7068 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7070 else if(flags
& FUNCFLAG_TAG
)
7072 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7073 PPCRegPrefix
, i
+20+count
*4);
7077 else /* Args must be shifted! */
7079 /* init stack frame */
7080 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7081 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7082 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7086 /* extra arguments must be passed on the stack */
7089 /* special case: move 8th argument into stack frame */
7090 if(flags
& FUNCFLAG_TAG
)
7091 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7093 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7097 k
= 32-(count
-7); /* firstreg */
7099 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7100 "\tmr\t%s%ld,%s10\n"
7101 "\tlmw\t%s%ld,%ld(%s1)\n",
7102 PPCRegPrefix
, k
, 56+(count
-7)*4, PPCRegPrefix
,
7103 PPCRegPrefix
, k
, PPCRegPrefix
, PPCRegPrefix
, k
+1,
7104 i
+56, PPCRegPrefix
);
7105 if(flags
& FUNCFLAG_TAG
)
7106 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
,
7107 PPCRegPrefix
, i
+20+count
*4);
7108 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7111 else if(flags
& FUNCFLAG_TAG
)
7113 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7114 PPCRegPrefix
, i
+20+count
*4);
7118 /* shift all arguments into their following register */
7119 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7120 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix
, 3+k
, PPCRegPrefix
, 2+k
);
7122 /* load library base and LVO, then call LVO via LR */
7123 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7127 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix
,
7128 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
7130 /* cleanup stack frame and return */
7133 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7134 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, 32-(count
-k
),
7135 56+(count
-k
)*4, PPCRegPrefix
);
7138 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7139 PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7143 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7144 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7146 /* clear PP_Flags, PP_Stack and PP_StackSize */
7147 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7148 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7149 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7151 if(Flags
& FLAG_WOSLIBBASE
)
7152 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7153 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix
, ap
->Bias
, PPCRegPrefix
,
7154 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7156 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix
,
7157 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
);
7159 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7160 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7161 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
,
7162 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7165 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7166 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7167 for(i
= 0; i
< k
; ++i
)
7171 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7172 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7174 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3+ofs
);
7178 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix
, (i
+1+ofs
)*4+196,
7180 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7181 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7182 DoOutput("\tstw\t%s11,", PPCRegPrefix
);
7184 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7186 if(flags
& FUNCFLAG_TAG
)
7188 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7189 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7190 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7191 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix
,
7192 PPCRegPrefix
, 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7193 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7196 if(!(Flags
& FLAG_WOSLIBBASE
))
7197 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
7199 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7200 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7201 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7202 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7203 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7206 if(Flags
& FLAG_WOSLIBBASE
)
7207 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7210 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7214 uint32
FuncVBCCWOSCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7216 uint32 i
, j
, k
, ofs
, count
;
7217 uint8
*data
, *basepos
= 0, *pbasepos
= 0;
7218 struct ClibData
*cd
= 0;
7220 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
7223 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
7224 !(cd
= GetClibFunc(name
, ap
, flags
)))
7227 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
7228 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
7229 !(Flags
& FLAG_WOSLIBBASE
)))
7231 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
7235 Flags
|= FLAG_DONE
; /* We did something */
7237 i
= strlen(name
) + 2;
7238 EndPutM32(tempbuf
, HUNK_UNIT
);
7239 EndPutM32(tempbuf
+4, (i
+3)>>2);
7240 DoOutputDirect(tempbuf
, 8);
7241 DoOutput("%s.o", name
);
7242 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7244 i
= strlen(hunkname
);
7245 EndPutM32(tempbuf
, HUNK_NAME
);
7246 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
7247 DoOutputDirect(tempbuf
, 8);
7248 DoOutputDirect(hunkname
, i
);
7249 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7251 data
= tempbuf
+8; /* we need HUNK_PPC_CODE + size at start */
7253 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7255 EndPutM32Inc(data
, 0x90410014); /* stw r2,20(r1) */
7256 /* mflr r0 = mfspr r0,8 = get link register */
7257 EndPutM32Inc(data
, 0x7C0802A6);
7258 EndPutM32Inc(data
, 0x90010010); /* stw r0,16(r1) */
7260 EndPutM32Inc(data
, 0x80420000); /* lwz r2,BaseName(r2) */
7261 EndPutM32Inc(data
, 0x80030000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r2) */
7262 /* mtlr r0 = mtspr 8,r0 = restore link register */
7263 EndPutM32Inc(data
, 0x7C0803A6);
7264 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7265 EndPutM32Inc(data
, 0x80010010); /* lwz r0,16(r1) */
7266 EndPutM32Inc(data
, 0x80410014); /* lwz r2,20(r1) */
7267 /* mtlr r0 = mtspr 8,r0 = restore link register */
7268 EndPutM32Inc(data
, 0x7C0803A6);
7269 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7271 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7274 /* mflr r0 = mfspr r0,8 = get link register */
7275 EndPutM32Inc(data
, 0x7C0802A6);
7276 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7278 EndPutM32Inc(data
, 0x90010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7279 (uint32
)(20+ap
->NumArgs
*4)); /* stw rN,d(r1) */
7280 EndPutM32Inc(data
, 0x38010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7281 (uint32
)(20+ap
->NumArgs
*4)); /* addi rN,r1,d */
7283 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7284 EndPutM32Inc(data
, 0x9421FFCE); /* stwu r1,-32(r1) */
7285 EndPutM32Inc(data
, 0x81620000); /* lwz r11,BaseName(r2) */
7286 EndPutM32Inc(data
, 0x800C0000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r11) */
7287 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7288 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7289 EndPutM32Inc(data
, 0x80010028); /* lwz r0,40(r1) */
7290 EndPutM32Inc(data
, 0x38210020); /* addi r1,r1,32 */
7291 /* mtlr r0 = mtspr 8,r0 = restore link register */
7292 EndPutM32Inc(data
, 0x7C0803A6);
7293 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7295 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7297 count
= ap
->NumArgs
;
7298 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7300 /* init stack frame */
7301 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7302 /* mflr r0 = mfspr r0,8 = get link register */
7303 EndPutM32Inc(data
, 0x7C0802A6);
7304 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7305 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7309 /* extra arguments must be passed on the stack */
7310 k
= 32-(count
-8); /* firstreg */
7312 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-8)*4));
7313 EndPutM32Inc(data
, 0xB8010000 + (k
<< 21) + (i
+56)); /* lmw rk,Y(r1) */
7314 if(flags
& FUNCFLAG_TAG
)
7315 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4)); /* addi r31,r1,X */
7316 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7318 else if(flags
& FUNCFLAG_TAG
)
7321 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7325 else /* Args must be shifted! */
7327 /* init stack frame */
7328 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7329 /* mflr r0 = mfspr r0,8 = get link register */
7330 EndPutM32Inc(data
, 0x7C0802A6);
7331 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7332 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7336 /* extra arguments must be passed on the stack */
7339 /* special case: move 8th argument into stack frame */
7340 if(flags
& FUNCFLAG_TAG
)
7341 EndPutM32Inc(data
, 0x39410000 + (i
+20+count
*4)); /* addi r10,r1,X */
7342 EndPutM32Inc(data
, 0x91410038); /* stw r10,56(r1) */
7346 k
= 32-(count
-7); /* firstreg */
7349 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-7)*4));
7350 /* mr rk,r10 = or rk,r10,r10 */
7351 EndPutM32Inc(data
, 0x7D405378 + (k
<<16));
7353 EndPutM32Inc(data
, 0xB8010000 + ((k
+1) << 21) + (i
+56));
7354 if(flags
& FUNCFLAG_TAG
)
7357 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4));
7359 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7362 else if(flags
& FUNCFLAG_TAG
)
7365 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7369 /* shift all arguments into their following register */
7370 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7371 EndPutM32Inc(data
, 0x7C000378 + ((3+k
)<<16) + ((2+k
)<<21) + ((2+k
)<<11)); /* mr rX,rY = or rX,rY,rY */
7373 /* load library base and LVO, then call LVO via LR */
7375 EndPutM32Inc(data
, 0x80620000); /* lwz r3,BaseName(r2) */
7378 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7379 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7380 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7383 /* cleanup stack frame and return */
7386 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7387 EndPutM32Inc(data
, 0xB8010000 + ((32-(count
-k
))<<21) + (56+(count
-k
)*4)); /* lmw rX,Y(r1) */
7389 EndPutM32Inc(data
, 0x38210000 + i
); /* addi r1,r1,i */
7390 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) */
7391 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7392 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7396 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7397 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7398 EndPutM32Inc(data
, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7400 EndPutM32Inc(data
, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7401 EndPutM32Inc(data
, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7402 EndPutM32Inc(data
, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7403 EndPutM32Inc(data
, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7405 if(Flags
& FLAG_WOSLIBBASE
)
7407 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7408 EndPutM32Inc(data
, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7409 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7410 EndPutM32Inc(data
, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7414 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7415 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7420 EndPutM32Inc(data
, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7421 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7422 EndPutM32Inc(data
, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7423 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7424 EndPutM32Inc(data
, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7427 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7428 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7429 for(i
= 0; i
< k
; ++i
)
7431 j
= 0x34+4*ap
->Args
[i
].ArgReg
; /* PP_Regs offset */
7434 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7435 EndPutM32Inc(data
, 0x90010020 + ((i
+3+ofs
)<<21)); /* stw rX,0x20(r1) */
7436 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7440 EndPutM32Inc(data
, 0x81610000 + ((i
+1+ofs
)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7441 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7442 EndPutM32Inc(data
, 0x91610020); /* stw r11,0x20(r1) */
7443 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7446 if(flags
& FUNCFLAG_TAG
)
7448 j
= (ap
->NumArgs
+ofs
)*4+0xC4;
7450 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7451 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7452 EndPutM32Inc(data
, 0x39610000 + j
); /* addi r11,r1,j */
7453 EndPutM32Inc(data
, 0x91610000 + (0x34+4*ap
->Args
[i
].ArgReg
)); /* stw r11,X(r1) */
7456 if(!(Flags
& FLAG_WOSLIBBASE
))
7458 pbasepos
= data
; /* store 16BIT reloc offset */
7459 EndPutM32Inc(data
, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7461 EndPutM32Inc(data
, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7462 EndPutM32Inc(data
, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7463 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7464 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7465 EndPutM32Inc(data
, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7466 EndPutM32Inc(data
, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7467 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) = get old link register */
7468 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7469 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump back */
7472 EndPutM32(tempbuf
, HUNK_PPC_CODE
);
7473 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
7474 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
7476 EndPutM32(tempbuf
, HUNK_EXT
);
7477 DoOutputDirect(tempbuf
,4);
7479 /* here come the XDEF name references */
7481 if(Flags
& FLAG_WOSLIBBASE
)
7483 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
7484 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7485 OutputXDEF(0, "__%s", name
);
7490 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7491 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7492 OutputXREF((pbasepos
-tempbuf
-8)+2, EXT_DEXT16
, "_PowerPCBase");
7493 OutputXDEF(0, "_%s", name
);
7495 EndPutM32(tempbuf
, 0);
7496 DoOutputDirect(tempbuf
,4);
7497 if(!(Flags
& FLAG_NOSYMBOL
))
7499 EndPutM32(tempbuf
, HUNK_SYMBOL
);
7500 DoOutputDirect(tempbuf
,4);
7501 if(Flags
& FLAG_WOSLIBBASE
)
7502 OutputSYMBOL(0, "__%s", name
);
7504 OutputSYMBOL(0, "_%s", name
);
7505 EndPutM32(tempbuf
, 0);
7506 DoOutputDirect(tempbuf
,4);
7508 EndPutM32(tempbuf
, HUNK_END
);
7510 return DoOutputDirect(tempbuf
,4);
7513 uint32
FuncVBCCPUPText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7517 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7522 if(Flags
& FLAG_SINGLEFILE
)
7524 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7529 DoOutputDirect(HEADER
, headersize
);
7533 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7534 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7536 if(Flags
& FLAG_SINGLEFILE
)
7537 DoOutput("\t.file\t\"%s.o\"\n", name
);
7539 DoOutput("\t.global %s\n", BaseName
);
7540 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7541 "\t.align\t3\n%s:\n",name
, name
);
7543 if(flags
& FUNCFLAG_TAG
)
7545 /* Hack the stack-frame for varargs.
7546 Build stack-frame, but save LR in our own stack-frame,
7547 because we have to overwrite the lower 8 bytes of the
7549 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7550 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7552 /* Save the caller's saved SP in our own stack-frame. */
7553 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix
,
7554 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7556 /* Store r3-r8 at the top of our stack-frame and r9-r10
7557 at the low 8 bytes of the caller's frame. This way all
7558 arguments will reside in one continuous area. */
7559 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7560 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
, 104+4*(i
-3),
7564 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7565 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7567 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7569 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7572 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
7574 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
7575 100+(i
+1-8)*4, PPCRegPrefix
, PPCRegPrefix
);
7578 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix
,
7579 PPCRegPrefix
, 100+ap
->NumArgs
*4, PPCRegPrefix
);
7580 DoOutput("%d(%s1)\n", 36+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7583 /* Now place the real function call */
7584 /* store offset in Chaos->caos_Un.Offset */
7585 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7586 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix
,
7587 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7588 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7589 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7593 if(Flags
& FLAG_SMALLDATA
)
7594 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix
, BaseName
,
7597 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix
,
7598 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7599 /* store basepointer in A6 */
7600 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7603 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix
, PPCRegPrefix
);
7604 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7605 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7606 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7607 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7608 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7610 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7611 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7613 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name
,
7617 uint32
FuncVBCCPUPCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7619 int32 i
, j
=0, k
, size
;
7620 uint8
*data
, *data2
, *data3
;
7621 struct ArHeader
*arh
;
7625 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7630 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7631 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7632 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7633 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7634 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
7635 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
7636 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
7637 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7638 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7639 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7640 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
7641 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
7642 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
7643 EndPutM32Inc(data
, 0); /* eeh->e_entry */
7644 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
7645 data2
= data
; data
+= 4;
7646 EndPutM32Inc(data
, 0); /* eeh->e_flags */
7647 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
7648 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
7649 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
7650 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
7651 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
7652 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
7655 if(flags
& FUNCFLAG_TAG
)
7657 /* Hack the stack-frame for varargs.
7658 Build stack-frame, but save LR in our own stack-frame,
7659 because we have to overwrite the lower 8 bytes of the
7661 EndPutM32Inc(data
, 0x9421FF80); /* stwu r1,-128(r1) */
7662 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7663 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7665 /* Save the caller's saved SP in our own stack-frame. */
7666 EndPutM32Inc(data
, 0x81610080); /* lwz r11,128(r1) */
7667 EndPutM32Inc(data
, 0x91610060); /* stw r11,96(r1) */
7669 /* Store r3-r8 at the top of our stack-frame and r9-r10
7670 at the low 8 bytes of the caller's frame. This way all
7671 arguments will reside in one continuous area. */
7672 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7673 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (104+4*(i
-3))); /* stw rX,Y(r1) */
7677 EndPutM32Inc(data
, 0x9421FFA0); /* stwu r1,-96(r1) */
7678 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7679 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7682 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7684 j
= 36+4*ap
->Args
[i
].ArgReg
;
7685 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7689 EndPutM32Inc(data
, 0x90010000 + ((i
+3)<<21) + j
); /* stw rX,j(r1) */
7693 EndPutM32Inc(data
, 0x81610000 + (100+(i
+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7694 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7699 EndPutM32Inc(data
, 0x39610000 + (100+ap
->NumArgs
*4)); /* addi r11,r1,X */
7700 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,X(r1) */
7704 /* Now place the real function call */
7705 EndPutM32Inc(data
, 0x39610000 - ap
->Bias
); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7706 EndPutM32Inc(data
, 0x91610008); /* stw r11,8(r1) */
7707 EndPutM32Inc(data
, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7708 EndPutM32Inc(data
, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7709 EndPutM32Inc(data
, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7713 if(Flags
& FLAG_SMALLDATA
)
7715 j
= (data
-data3
)+2; /* store reloc offset */
7716 EndPutM32Inc(data
, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7720 j
= (data
-data3
)+2; /* store reloc offset */
7721 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7722 EndPutM32Inc(data
, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7724 EndPutM32Inc(data
, 0x9161005C); /* stw r11,92(r1) */
7727 EndPutM32Inc(data
, 0x38610008); /* addi r3,r1,8 */
7728 k
= (data
-data3
); /* store reloc offset */
7729 EndPutM32Inc(data
, 0x48000001); /* bl PPCCallOS */
7730 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7732 EndPutM32Inc(data
, 0x81610060); /* lwz r11,96(r1) */
7733 EndPutM32Inc(data
, 0x91610080); /* stw r11,128(r1) */
7734 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7735 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7736 EndPutM32Inc(data
, 0x38210080); /* addi r1,r1,128 */
7740 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7741 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7742 EndPutM32Inc(data
, 0x38210060); /* addi r1,r1,96 */
7745 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
7747 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7748 data
+= 44; /* 1 9 17 27 33 */
7750 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
7753 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
7754 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
7755 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7756 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7757 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
7758 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
7759 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7760 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7761 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
7762 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7765 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
7766 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
7767 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
7768 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
7769 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
7770 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
7771 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
7772 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
7773 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
7774 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
7777 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
7778 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
7779 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
7780 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
7781 data
+= 4; /* esh[2].sh_offset */
7782 data
+= 4; /* esh[2].sh_size */
7783 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7784 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
7785 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
7786 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7788 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
7789 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
7790 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
7791 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
7792 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
7793 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
7794 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
7795 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
7796 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
7797 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
7799 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
7800 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
7801 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
7802 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
7803 data
+= 4; /* esh[4].sh_offset */
7804 data
+= 4; /* esh[4].sh_size */
7805 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
7806 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7807 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
7808 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7810 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
7811 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
7812 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7813 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7814 data
+= 4; /* esh[0].sh_offset */
7815 data
+= 4; /* esh[0].sh_size */
7816 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7817 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7818 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
7819 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7821 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
7822 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 6*16 : 5*16); /* esh[4].sh_size */
7825 data
+= BaseName
? 6*16 : 5*16;
7827 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
7830 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
7831 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
7832 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
7833 *(data2
++) = 0; /* esym[0].st_info */
7834 *(data2
++) = 0; /* esym[0].st_other */
7835 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
7839 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
7840 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
7841 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
7842 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
7843 *(data2
++) = 0; /* esym[1].st_other */
7844 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
7846 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
++]) ; /* get next store space */
7847 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
7848 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
7849 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
7850 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
7851 *(data2
++) = 0; /* esym[2].st_other */
7852 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
7854 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
7855 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
7856 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
7857 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
7858 *(data2
++) = 0; /* esym[3].st_other */
7859 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
7861 sprintf((strptr
)data
+i
, "%s", name
); while(data
[i
++]) ; /* get next store space */
7862 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
7863 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
7864 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
7865 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
7866 *(data2
++) = 0; /* esym[4].st_other */
7867 EndPutM16Inc(data2
, 0); /* esym[4].st_shndx */
7869 sprintf((strptr
)data
+i
, "PPCCallOS"); while(data
[i
++]) ; /* get next store space */
7872 EndPutM32Inc(data2
, i
); /* esym[5].st_name */
7873 EndPutM32Inc(data2
, 0); /* esym[5].st_value */
7874 EndPutM32Inc(data2
, 0); /* esym[5].st_size */
7875 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[5].st_info */
7876 *(data2
++) = 0; /* esym[5].st_other */
7877 EndPutM16
/*Inc*/(data2
, 0); /* esym[5].st_shndx */
7879 sprintf((strptr
)data
+i
, "%s", BaseName
); while(data
[i
++]) ; /* get next store space */
7881 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
7882 while(i
&3) /* long aligned */
7886 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
7890 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7891 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_REL24
)); /* erel[0].r_info - entry 4, type 10 */
7892 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7896 if(Flags
& FLAG_SMALLDATA
)
7898 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7899 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_SDAREL16
)); /* erel[1].r_info - entry 5, type 32 */
7900 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7904 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7905 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_HA
)); /* erel[1].r_info - entry 5, type 6 */
7906 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7907 EndPutM32Inc(data
, j
+4); /* erel[2].r_offset */
7908 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_LO
)); /* erel[2].r_info - entry 5, type 4 */
7909 EndPutM32Inc(data
, 0); /* erel[2].r_addend */
7912 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
7914 /* make ar header and store all */
7915 arh
= (struct ArHeader
*) (data
+20);
7916 memset(arh
, ' ', sizeof(struct ArHeader
));
7918 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
7919 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
7920 arh
->ar_mode
[2] = '0';
7921 arh
->ar_mode
[0] = '6';
7922 arh
->ar_fmag
[0] = 96;
7923 arh
->ar_fmag
[1] = '\n';
7925 if((k
= strlen(name
) + 2) >= 16)
7927 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
7932 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
7935 j
= k
+ (data
-tempbuf
);
7936 for(i
= 9; j
; --i
) /* make decimal number */
7938 data
[i
] = (j
%10)+'0';
7941 for(j
= 0; i
< 9; ++j
)
7942 arh
->ar_size
[j
] = data
[++i
];
7944 DoOutputDirect(arh
, sizeof(struct ArHeader
));
7948 DoOutput("%s.o", name
);
7950 *(data
++) = 0x0A; /* alignment byte! */
7953 return DoOutputDirect(tempbuf
, data
-tempbuf
);
7956 uint32
FuncVBCCMorphText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7958 int32 i
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
7960 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7965 if(Flags
& FLAG_SINGLEFILE
)
7967 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7972 DoOutputDirect(HEADER
, headersize
);
7976 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7977 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7979 if(Flags
& FLAG_SINGLEFILE
)
7980 DoOutput("\t.file\t\"%s.o\"\n", name
);
7982 DoOutput("\t.global %s\n", BaseName
);
7983 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name
, name
);
7985 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
7987 if(Flags
& FLAG_SMALLDATA
)
7988 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
7989 PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7991 DoOutput("\tlis\t%s11,%s@ha\n"
7992 "\tlwz\t%s12,%s@l(%s11)\n",
7993 PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7995 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
7996 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8001 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8003 if(flags
& FUNCFLAG_TAG
)
8007 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8008 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8009 "\tstw\t%s0,4(%s1)\n"
8010 "\tsub\t%s11,%s1,%s12\n"
8011 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8012 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8013 "\tsrwi\t%s12,%s12,2\n"
8014 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8015 "\taddi\t%s12,%s1,4\n"
8016 "\tmr\t%s1,%s11\n" /* new stack frame */
8017 "\taddi\t%s11,%s11,8\n"
8020 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8021 "\tstwu\t%s0,4(%s11)\n"
8022 "\tbdnz\t.copyloop_%s\n"
8023 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8024 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8025 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8026 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8027 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8028 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8029 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8030 PPCRegPrefix
, PPCRegPrefix
, name
,
8031 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8032 name
, PPCRegPrefix
, PPCRegPrefix
);
8034 else if(ap
->NumArgs
>= 8)
8036 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8039 "\tstwu\t%s1,-%ld(%s1)\n"
8040 "\tstw\t%s0,%ld(%s1)\n",
8041 PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
,
8042 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8046 else if(flags
& FUNCFLAG_TAG
)
8048 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8049 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8051 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8052 || ap
->NumArgs
>= 8))
8054 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8056 PPCRegPrefix
, stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
);
8061 /* Hack the stack-frame for varargs.
8062 Build stack-frame, but save LR in our own stack-frame,
8063 because we have to overwrite the lower 8 bytes of the
8065 /* Save the caller's saved SP in our own stack-frame. */
8066 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix
,
8067 stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
);
8069 /* Store r3-r8 at the top of our stack-frame and r9-r10
8070 at the low 8 bytes of the caller's frame. This way all
8071 arguments will reside in one continuous area.
8072 Only copy the really relevant parts. */
8073 for(i
= 10; i
> 10-nrcopyar
; --i
)
8074 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
,
8075 stcksize
+4*(i
-1+nrcopyar
-8),PPCRegPrefix
);
8078 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8080 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8082 for(i
= ap
->NumArgs
-1; i
; --i
)
8086 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, 3+i
, PPCRegPrefix
,
8091 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
8095 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8096 PPCRegPrefix
, stcksize
+((i
-8)+3)*4, PPCRegPrefix
, PPCRegPrefix
,
8097 ((i
-8)+3)*4, PPCRegPrefix
);
8103 /* shift all the arguments one field */
8104 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8106 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, i
, PPCRegPrefix
, i
-1);
8111 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8112 || ap
->NumArgs
>= 8))
8113 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8117 if(Flags
& FLAG_SMALLDATA
)
8118 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix
, basereg
,
8119 BaseName
, PPCRegPrefix
);
8121 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8122 PPCRegPrefix
, basereg
, BaseName
, PPCRegPrefix
, basereg
, BaseName
,
8123 PPCRegPrefix
, basereg
);
8126 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8128 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8129 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8133 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8135 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8138 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
8140 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
8141 stcksize
+(i
+2-8)*4, PPCRegPrefix
, PPCRegPrefix
);
8144 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix
,
8145 PPCRegPrefix
, stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0),
8147 DoOutput("%d(%s2)\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
8150 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8151 PPCRegPrefix
, PPCRegPrefix
);
8153 /* store basepointer in A6 */
8155 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
8157 /* Now place the real function call */
8158 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8159 PPCRegPrefix
, ap
->Bias
);
8161 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix
);
8164 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8166 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8167 PPCRegPrefix
, stcksize
, PPCRegPrefix
, PPCRegPrefix
,
8168 stcksize
+nrcopyar
*4,PPCRegPrefix
);
8171 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8172 || ap
->NumArgs
>= 8))
8174 if(ap
->NumArgs
>= 8)
8177 "\tlwz\t%s0,%ld(%s1)\n"
8178 "\taddi\t%s1,%s1,%ld\n"
8180 PPCRegPrefix
,stcksize
+4,PPCRegPrefix
,PPCRegPrefix
,PPCRegPrefix
,
8181 stcksize
,PPCRegPrefix
);
8186 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8187 "\tlwz\t%s0,4(%s1)\n"
8188 "\tmtlr\t%s0\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8189 PPCRegPrefix
, PPCRegPrefix
);
8194 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8195 "\taddi\t%s1,%s1,%ld\n"
8197 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8198 stcksize
+nrcopyar
*4, PPCRegPrefix
);
8201 DoOutput("\tblr\n");
8204 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8208 uint32
FuncVBCCMorphCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8210 int32 i
, j
, k
=0, size
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
8211 uint8
*data
, *data2
, *data3
;
8212 struct ArHeader
*arh
;
8216 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
8221 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8222 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8223 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8224 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8225 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
8226 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
8227 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
8228 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8229 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8230 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8231 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
8232 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
8233 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
8234 EndPutM32Inc(data
, 0); /* eeh->e_entry */
8235 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
8236 data2
= data
; data
+= 4;
8237 EndPutM32Inc(data
, 0); /* eeh->e_flags */
8238 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
8239 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
8240 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
8241 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
8242 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
8243 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
8247 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
8249 if(Flags
& FLAG_SMALLDATA
)
8251 k
= (data
-data3
)+2; /* store reloc offset */
8252 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8256 k
= (data
-data3
)+2; /* store reloc offset */
8257 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8258 EndPutM32Inc(data
, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8261 EndPutM32Inc(data
, 0x800c0000 - (ap
->Bias
-2));
8262 EndPutM32Inc(data
, 0x7c0903a6); /* mtctr r0 */
8263 EndPutM32Inc(data
, 0x4e800420); /* bctr */
8268 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8270 if(flags
& FUNCFLAG_TAG
)
8272 /* mflr r0 = mfspr r0,8 = get link register */
8273 EndPutM32Inc(data
, 0x7C0802A6);
8274 /* backchain to next frame: lwz r11,0(r1) */
8275 EndPutM32Inc(data
, 0x81610000);
8276 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8277 EndPutM32Inc(data
, 0x7D815850);
8278 EndPutM32Inc(data
, 0x90010004); /* stw r0,4(r1) */
8279 EndPutM32Inc(data
, 0x7D6C0850); /* sub r11,r1,r12 */
8280 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8281 EndPutM32Inc(data
, 0x396BFFF0);
8282 EndPutM32Inc(data
, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8283 EndPutM32Inc(data
, 0x558CF0BE); /* srwi r12,r12,2 */
8284 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8285 EndPutM32Inc(data
, 0x380CFFFE);
8286 EndPutM32Inc(data
, 0x39810004); /* addi r12,r1,4 */
8287 EndPutM32Inc(data
, 0x7D615B78); /* mr r1,r11 - new stack frame */
8288 EndPutM32Inc(data
, 0x396B0008); /* addi r11,r11,8 */
8289 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8290 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8291 EndPutM32Inc(data
, 0x840C0004);
8292 EndPutM32Inc(data
, 0x940B0004); /* stwu r0,4(r11) */
8293 EndPutM32Inc(data
, 0x4200FFF8); /* bdnz .l */
8294 /* stw r10,8(r1) - last register into stack */
8295 EndPutM32Inc(data
, 0x91410008);
8297 else if(ap
->NumArgs
>= 8)
8299 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8300 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 */
8301 EndPutM32Inc(data
, 0x94220000 - stcksize
); /* stwu r1,-X(r1) */
8302 EndPutM32Inc(data
, 0x90010000 + stcksize
+ 4); /* stw r0,Y(r1) */
8306 else if(flags
& FUNCFLAG_TAG
)
8308 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8309 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8312 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8313 || ap
->NumArgs
>= 8))
8315 EndPutM32Inc(data
, 0x94210000+0x10000-(stcksize
+nrcopyar
*4)); /* stwu r1,-%d(r1) */
8316 /* mflr r0 = mfspr r0,8 = get link register */
8317 EndPutM32Inc(data
, 0x7C0802A6);
8322 /* Hack the stack-frame for varargs.
8323 Build stack-frame, but save LR in our own stack-frame,
8324 because we have to overwrite the lower 8 bytes of the
8326 /* Save the caller's saved SP in our own stack-frame. */
8327 EndPutM32Inc(data
, 0x81610000+stcksize
+nrcopyar
*4); /* lwz r11,%d(r1) */
8328 EndPutM32Inc(data
, 0x91610000+stcksize
); /* stw r11,%d(r1) */
8330 /* Store r3-r8 at the top of our stack-frame and r9-r10
8331 at the low 8 bytes of the caller's frame. This way all
8332 arguments will reside in one continuous area.
8333 Only copy the really relevant parts. */
8334 for(i
= 10; i
> 10-nrcopyar
; --i
)
8335 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (stcksize
+4*(i
-1+nrcopyar
-8))); /* stw rX,Y(r1) */
8338 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8340 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8342 for(i
= ap
->NumArgs
-1; i
; --i
)
8347 EndPutM32Inc(data
, 0x7C000378 + ((3+i
)<<21) + ((3+i
-1)<<16) + ((3+i
-1)<<11));
8352 EndPutM32Inc(data
, 0x91410008);
8357 EndPutM32Inc(data
, 0x81610000 + (stcksize
+((i
-8)+3)*4));
8358 EndPutM32Inc(data
, 0x91620000 + ((i
-8)+3)*4); /* stw r11,j(r1) */
8364 /* shift all the arguments one field */
8365 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8368 EndPutM32Inc(data
, 0x7C000378 + (i
<<21) + ((i
-1)<<16) + ((i
-1)<<11));
8373 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8374 || ap
->NumArgs
>= 8))
8375 EndPutM32Inc(data
, 0x90010000+stcksize
+4); /* stw r0,%d(r1) */
8379 if(Flags
& FLAG_SMALLDATA
)
8381 k
= (data
-data3
)+2; /* store reloc offset */
8382 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8386 k
= (data
-data3
)+2; /* store reloc offset */
8387 EndPutM32Inc(data
, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8388 EndPutM32Inc(data
, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8392 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8395 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2));
8396 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8397 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8401 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8403 j
= 4*ap
->Args
[i
].ArgReg
;
8404 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8408 EndPutM32Inc(data
, 0x90020000 + ((i
+3)<<21) + j
); /* stw rX,j(r2) */
8412 EndPutM32Inc(data
, 0x81610000 + (stcksize
+(i
+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8413 EndPutM32Inc(data
, 0x91620000 + j
); /* stw r11,j(r1) */
8418 EndPutM32Inc(data
, 0x38810000 + (stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0))); /* addi r4,r1,X */
8419 EndPutM32Inc(data
, 0x90820000 + j
); /* stw r4,X(r2) */
8424 EndPutM32Inc(data
, 0x81620064); /* lwz r11,100(r2) */
8427 EndPutM32Inc(data
, 0x91820038); /* stw r12,56(r2) */
8429 /* Now place the real function call */
8430 EndPutM32Inc(data
, 0x38600000 + 0x10000 - ap
->Bias
); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8432 EndPutM32Inc(data
, 0x7D6903A6); /* mtctr r11 */
8433 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8435 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8437 EndPutM32Inc(data
, 0x81610000 + stcksize
); /* lwz r11,X(r1) */
8438 EndPutM32Inc(data
, 0x91610000 + (stcksize
+nrcopyar
*4)); /* stw r11,Y(r1) */
8441 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8442 || ap
->NumArgs
>= 8))
8444 if(ap
->NumArgs
>= 8)
8446 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8447 EndPutM32Inc(data
, 0x38210000 + stcksize
); /* addi r1,r1,Y */
8448 /* mtlr r0 = mtspr 8,r0 = restore link register */
8449 EndPutM32Inc(data
, 0x7C0803A6);
8453 /* restore old stack frame: lwz r1,0(r1) */
8454 EndPutM32Inc(data
, 0x80210000);
8455 EndPutM32Inc(data
, 0x80010004); /* lwz r0,4(r1) */
8456 /* mtlr r0 = mtspr 8,r0 = restore link register */
8457 EndPutM32Inc(data
, 0x7C0803A6);
8462 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8463 EndPutM32Inc(data
, 0x38210000 + (stcksize
+nrcopyar
*4)); /* addi r1,r1,Y */
8464 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8467 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
8470 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8471 data
+= 44; /* 1 9 17 27 33 */
8473 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
8476 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
8477 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
8478 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8479 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8480 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
8481 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
8482 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8483 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8484 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
8485 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8488 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
8489 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
8490 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
8491 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
8492 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
8493 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
8494 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
8495 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
8496 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
8497 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
8500 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
8501 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
8502 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
8503 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
8504 data
+= 4; /* esh[2].sh_offset */
8505 data
+= 4; /* esh[2].sh_size */
8506 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8507 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
8508 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
8509 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8511 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
8512 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
8513 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
8514 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
8515 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
8516 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
8517 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
8518 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
8519 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
8520 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
8522 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
8523 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
8524 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
8525 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
8526 data
+= 4; /* esh[4].sh_offset */
8527 data
+= 4; /* esh[4].sh_size */
8528 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
8529 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8530 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
8531 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8533 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
8534 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
8535 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8536 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8537 data
+= 4; /* esh[0].sh_offset */
8538 data
+= 4; /* esh[0].sh_size */
8539 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8540 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8541 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
8542 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8544 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
8545 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 5*16 : 4*16); /* esh[4].sh_size */
8548 data
+= BaseName
? 5*16 : 4*16;
8550 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
8553 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
8554 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
8555 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
8556 *(data2
++) = 0; /* esym[0].st_info */
8557 *(data2
++) = 0; /* esym[0].st_other */
8558 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
8562 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
8563 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
8564 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
8565 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
8566 *(data2
++) = 0; /* esym[1].st_other */
8567 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
8569 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
++]) ; /* get next store space */
8570 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
8571 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
8572 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
8573 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
8574 *(data2
++) = 0; /* esym[2].st_other */
8575 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
8577 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
8578 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
8579 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
8580 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
8581 *(data2
++) = 0; /* esym[3].st_other */
8582 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
8584 sprintf((strptr
)data
+i
, "%s", name
); while(data
[i
++]) ; /* get next store space */
8587 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
8588 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
8589 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
8590 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
8591 *(data2
++) = 0; /* esym[4].st_other */
8592 EndPutM16
/*Inc*/(data2
, 0); /* esym[4].st_shndx */
8594 sprintf((strptr
)data
+i
, "%s", BaseName
); while(data
[i
++]) ; /* get next store space */
8596 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
8597 while(i
&3) /* long aligned */
8601 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
8607 if(Flags
& FLAG_SMALLDATA
)
8609 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8610 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_SDAREL16
)); /* erel[0].r_info - entry 4, type 32 */
8611 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8615 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8616 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_HA
)); /* erel[0].r_info - entry 4, type 6 */
8617 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8618 EndPutM32Inc(data
, k
+4); /* erel[1].r_offset */
8619 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_LO
)); /* erel[1].r_info - entry 4, type 4 */
8620 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
8623 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
8625 /* make ar header and store all */
8626 arh
= (struct ArHeader
*) (data
+20);
8627 memset(arh
, ' ', sizeof(struct ArHeader
));
8629 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
8630 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
8631 arh
->ar_mode
[2] = '0';
8632 arh
->ar_mode
[0] = '6';
8633 arh
->ar_fmag
[0] = 96;
8634 arh
->ar_fmag
[1] = '\n';
8636 if((k
= strlen(name
) + 2) >= 16)
8638 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
8643 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
8646 j
= k
+ (data
-tempbuf
);
8647 for(i
= 9; j
; --i
) /* make decimal number */
8649 data
[i
] = (j
%10)+'0';
8652 for(j
= 0; i
< 9; ++j
)
8653 arh
->ar_size
[j
] = data
[++i
];
8655 DoOutputDirect(arh
, sizeof(struct ArHeader
));
8659 DoOutput("%s.o", name
);
8661 *(data
++) = 0x0A; /* alignment byte! */
8664 return DoOutputDirect(tempbuf
, data
-tempbuf
);
8667 uint32
FuncEModule(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8671 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_PPC
) ||
8672 (flags
& FUNCFLAG_ALIAS
))
8675 if(LastBias
>= ap
->Bias
)
8676 DoError(ERR_ILLEGAL_FUNCTION_POSITION
, ap
->Line
, name
);
8679 Flags
|= FLAG_DONE
; /* We did something */
8681 for(LastBias
+= BIAS_OFFSET
; LastBias
< ap
->Bias
; LastBias
+= BIAS_OFFSET
)
8682 DoOutputDirect("Dum\x10", 4);
8684 DoOutput("%c", toupper(name
[0]));
8687 DoOutput("%c", tolower(name
[1]));
8689 DoOutput("%s", name
+2);
8692 DoOutputDirect("\x10", 1);
8695 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8697 r
= ap
->Args
[i
].ArgReg
;
8698 DoOutputDirect(&r
, 1);
8705 uint32
FuncFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8709 Flags
|= FLAG_DONE
; /* We did something */
8711 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8713 if(Flags
& FLAG_ISPRIVATE
)
8715 Flags
^= FLAG_ISPRIVATE
;
8716 DoOutput("##public\n");
8721 if(!(Flags
& FLAG_ISPRIVATE
))
8722 DoOutput("##private\n");
8723 Flags
|= FLAG_ISPRIVATE
;
8726 LastBias
+= BIAS_OFFSET
;
8727 if(LastBias
!= ap
->Bias
)
8729 DoOutput("##bias %d\n", ap
->Bias
);
8730 LastBias
= ap
->Bias
;
8733 if(ap
->Abi
!= CurrentABI
)
8737 case ABI_M68K
: DoOutput("##abi M68k\n"); break;
8738 case ABI_PPC0
: DoOutput("##abi PPC0\n"); break;
8739 case ABI_PPC2
: DoOutput("##abi PPC2\n"); break;
8740 case ABI_PPC
: DoOutput("##abi PPC\n"); break;
8742 CurrentABI
= ap
->Abi
;
8745 DoOutput("%s("/*)*/, name
);
8746 for(i
= 0; i
< ap
->CallArgs
; i
++)
8747 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->CallArgs
-1 ? "," : "");
8748 DoOutput(/*(*/")("/*)*/);
8750 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8752 for(i
= 0; i
< ap
->CallArgs
; i
++)
8754 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], i
< ap
->CallArgs
-1 ?
8755 (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
? "/" : ",") : "");
8758 return DoOutput(/*(*/")\n");
8761 /* called from FuncSFD directly */
8762 uint32
FuncClib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8764 struct ClibData
*cd
;
8767 Flags
|= FLAG_DONE
; /* We did something */
8769 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8772 s
= MakeClibType(tempbuf
, &cd
->ReturnType
, 0);
8773 DoOutputDirect(tempbuf
, s
);
8774 DoOutput(" %s("/*)*/, name
);
8778 for(i
= 0; i
< cd
->NumArgs
; i
++)
8780 c
= MakeClibType(tempbuf
, &cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8783 DoOutput(i
? ",\n\t" : "\n\t"); s
= 8;
8787 DoOutput(", "); s
+= 2;
8789 DoOutputDirect(tempbuf
, c
);
8793 else if(Flags2
& FLAG2_CLIBOUT
)
8795 return DoOutput(/*(*/")%s", Flags2
& FLAG2_CLIBOUT
? ";\n" : "");
8798 uint32
FuncSFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8800 struct ClibData
*cd
;
8803 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8806 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8808 if(Flags
& FLAG_ISPRIVATE
)
8810 Flags
^= FLAG_ISPRIVATE
;
8811 DoOutput("==public\n");
8816 if(!(Flags
& FLAG_ISPRIVATE
))
8817 DoOutput("==private\n");
8818 Flags
|= FLAG_ISPRIVATE
;
8821 if(ap
->Abi
!= CurrentABI
)
8825 case ABI_M68K
: DoOutput("==abi M68k\n"); break;
8826 case ABI_PPC0
: DoOutput("==abi PPC0\n"); break;
8827 case ABI_PPC2
: DoOutput("==abi PPC2\n"); break;
8828 case ABI_PPC
: DoOutput("==abi PPC\n"); break;
8830 CurrentABI
= ap
->Abi
;
8833 if(LastBias
+BIAS_OFFSET
< ap
->Bias
)
8835 DoOutput("==reserve %ld\n", ((ap
->Bias
-LastBias
)/BIAS_OFFSET
)-1);
8836 LastBias
= ap
->Bias
;
8838 else if(flags
& FUNCFLAG_TAG
)
8839 DoOutput("==varargs\n");
8840 else if((flags
& FUNCFLAG_ALIAS
) || LastBias
== ap
->Bias
)
8841 DoOutput("==alias\n");
8843 LastBias
+= BIAS_OFFSET
;
8845 if(!FuncClib(ap
, flags
, name
))
8848 DoOutput(" ("/*)*/);
8849 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8853 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8854 in step one, so the "-" can be placed at proper position. */
8855 for(j
= i
= 0; i
< ap
->NumArgs
; i
++)
8857 if(i
== ap
->NumArgs
-1)
8861 else if(IsCPPType(&cd
->Args
[j
>>1], CPP_TYPE_DOUBLE
) && ap
->Args
[i
].ArgReg
< REG_FP0
)
8863 s
= (j
&1) ? "," : "-"; ++j
;
8869 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], s
);
8872 return DoOutput(/*(*/")\n");
8875 uint32
FuncOS4PPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8877 struct ClibData
*cd
;
8878 int32 i
, noret
= 0, registers
;
8880 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
8883 Flags
|= FLAG_DONE
; /* We did something */
8885 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8888 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
8889 noret
= 1; /* this is a void function */
8891 sprintf((strptr
)tempbuf
, "_%s_%s", GetIFXName(), name
);
8892 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
8894 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8895 ap
->NumArgs
? "," : "");
8896 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8899 if(i
== ap
->NumArgs
- 1 && (flags
& FUNCFLAG_TAG
))
8905 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8906 if(i
< ap
->NumArgs
-1)
8910 if(flags
& FUNCFLAG_TAG
)
8912 struct ClibData
*cd2
;
8914 if(!(cd2
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
8917 DoOutput(/*(*/")\n{\n"/*}*/
8919 " va_startlinear(ap, colorMap);\n"
8922 DoOutput("return ");
8923 DoOutput("Self->%s(\n"/*)*/, ap
->FuncName
);
8924 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8926 DoOutput(" %s,\n", ap
->Args
[i
].ArgName
);
8928 DoOutput(" va_getlinearva(ap, "/*)*/);
8929 OutClibType(&cd2
->Args
[i
], 0);
8930 DoOutput(/*((*/"));\n");
8934 DoOutput(/*(*/")\n{\n"/*}*/
8935 " struct Library *LibBase = Self->Data.LibBase;\n"
8936 " struct ExecIFace *IExec = (struct ExecIFace *)"
8937 "Self->Data.IExecPrivate;\n");
8942 OutClibType(&cd
->ReturnType
, "retval");
8947 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8949 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8952 registers
= GetRegisterData(ap
) | 0x40000002; /* set A6 everytime */
8953 for(i
= 0; i
<= 15; ++i
)
8955 if(registers
& (1<< (16+i
)))
8956 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames
[i
], i
);
8962 DoOutput("retval = ("/*)*/);
8963 OutClibType(&cd
->ReturnType
, 0);
8967 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
8968 " ET_Offset, -%d,\n"/*)*/,ap
->Bias
);
8969 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8971 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
],
8972 ap
->Args
[i
].ArgName
);
8974 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
8975 for(i
= 0; i
<= 15; ++i
)
8977 if(registers
& (1<< (16+i
)))
8978 DoOutput(" regs[%ld] = save_%s;\n", i
, RegNames
[i
]);
8982 DoOutput(" return retval;\n");
8984 return DoOutput(/*{*/"}\n\n");
8987 uint32
FuncOS4M68KCSTUB(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8989 struct ClibData
*cd
;
8992 if(ap
->NumArgs
<= 7)
8995 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
8998 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9001 Flags
|= FLAG_DONE
; /* We did something */
9003 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9004 noret
= 1; /* this is a void function */
9006 sprintf((strptr
)tempbuf
, "Cstub_%s", name
);
9007 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
9009 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9010 " struct ExecIFace *IExec = (struct ExecIFace *)"
9011 "Interface->Data.IExecPrivate;\n"
9012 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9013 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9016 DoOutput("return ");
9018 DoOutput("Interface->%s(\n"/*)*/,(flags
& FUNCFLAG_TAG
) ? ap
->FuncName
9020 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9022 DoOutput(" ("/*)*/);
9023 OutClibType(&cd
->Args
[i
], 0);
9024 DoOutput(/*(*/") regarray[%d]", ap
->Args
[i
].ArgReg
);
9025 if(i
< ap
->NumArgs
-1)
9028 return DoOutput(/*{(*/");\n}\n\n");
9031 uint32
FuncOS4M68K(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9033 struct ClibData
*cd
;
9036 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9039 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9042 Flags
|= FLAG_DONE
; /* We did something */
9045 "\t.section .data\n"
9046 "\t.globl\tstub_%s\n"
9047 "\t.type\tstub_%s,@function\n"
9050 "\t.short\t0x4ef8\n"
9053 "\t.globl\tstub_%sPPC\n"
9054 "\t.long\tstub_%sPPC\n",name
, name
, name
, name
, name
);
9058 Flags2
|= FLAG2_OS4M68KCSTUB
;
9060 "\t.byte\t2\n" /* Rest of parameters in C */
9061 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9062 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9067 "\t.byte\t%d\n" /* Rest of parameters in C */
9068 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9069 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9071 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9073 DoOutput("\t.byte\t%d,REG68K_%s\n",i
+4,
9074 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9078 "\t.section .text\n"
9082 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9083 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9084 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9085 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9086 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9087 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9088 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9089 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9090 name
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9091 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9092 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9093 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
9097 /* Since this function has 11 arguments, we need a C stub */
9099 "\t.globl\tCstub_%s\n"
9100 "\tlis\t%s4,Cstub_%s@h\n"
9101 "\tori\t%s4,%s4,Cstub_%s@l\n"
9104 name
, PPCRegPrefix
, name
, PPCRegPrefix
, PPCRegPrefix
, name
, PPCRegPrefix
);
9108 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name
);
9111 "\tlwz\t%s11,12(%s1)\n"
9113 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9114 "\tblrl\n" /* Return to emulation */
9116 "\t.globl\tstub_%s68K\n"
9117 "\t.long\tstub_%s68K\n"
9118 "\t.byte\t0\n", /* Flags */
9119 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, name
,
9122 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9125 "\t.byte\t1\n" /* One register (a7 only) */
9126 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9132 "\t.byte\t1,REG68K_A7\n"
9133 "\t.byte\t3,REG68K_D0\n");
9137 "\t.section .data\n"
9141 "\t.short\t0x4e75\n" /* RTS */
9145 uint32
FuncOS4M68KVect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9147 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9150 while(LastBias
+ BIAS_OFFSET
< ap
->Bias
)
9152 DoOutput("\t.long\tstub_Reserved\n");
9153 LastBias
+= BIAS_OFFSET
;
9155 LastBias
= ap
->Bias
;
9157 return DoOutput("\t.long\tstub_%s\n", name
);
9160 uint32
FuncXML(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9162 struct ClibData
*cd
;
9165 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9168 if(flags
& FUNCFLAG_ALIAS
)
9169 DoError(ERR_ALIASES_NOT_SUPPORTED
, ap
->Line
);
9171 Flags
|= FLAG_DONE
; /* We did something */
9173 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
9176 while(LastBias
+BIAS_OFFSET
< ap
->Bias
)
9178 LastBias
+= BIAS_OFFSET
;
9179 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9180 " status=\"unimplemented\"/>\n", LastBias
);
9182 LastBias
= ap
->Bias
;
9184 DoOutput("\t\t<method name=\"%s\" result=\"", name
);
9185 OutClibType(&cd
->ReturnType
, 0);
9187 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9189 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9190 i
== ap
->NumArgs
-1 && (flags
& FUNCFLAG_TAG
) ? "var" : "",
9191 ap
->Args
[i
].ArgName
);
9192 OutClibType(&cd
->Args
[i
], 0);
9195 return DoOutput("\t\t</method>\n");
9198 uint32
FuncGateStubs(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9200 struct ClibData
*cd
;
9201 strptr ret
= "return ";
9204 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
9207 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9210 Flags
|= FLAG_DONE
; /* We did something */
9212 if(flags
& FUNCFLAG_ALIAS
)
9214 if(flags
& FUNCFLAG_TAG
)
9215 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9216 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
9218 DoOutput("#define %s("/*)*/, name
);
9219 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9220 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9221 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
9222 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9223 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9224 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
9227 if((flags
& FUNCFLAG_TAG
))
9229 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9230 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
9231 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9233 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9235 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9237 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9238 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9240 OutClibType(&cd
->Args
[i
], 0);
9241 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9244 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9247 if(!OutClibType(&cd
->ReturnType
, 0))
9250 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix
, name
);
9252 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9255 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
9256 DoOutput(" = ("/*)*/);
9257 OutClibType(&cd
->Args
[i
], 0);
9258 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9259 if((Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
)) && (Flags2
& FLAG2_REGLIB
))
9260 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9262 DoOutput(" %s%s%s("/*)*/, ret
, subprefix
, name
);
9265 if(Flags2
& FLAG2_PRELIB
)
9267 if(Flags2
& FLAG2_REGLIB
)
9268 DoOutput("___RegBase,");
9270 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper
);
9273 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9275 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9277 if(Flags2
& FLAG2_POSTLIB
)
9279 if(Flags2
& FLAG2_REGLIB
)
9280 DoOutput("%s, ___RegBase", ap
->Args
[i
].ArgName
);
9282 DoOutput("%s, %s_BASE_NAME", ap
->Args
[i
].ArgName
, ShortBaseNameUpper
);
9285 DoOutput("%s", ap
->Args
[i
].ArgName
);
9289 if(Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
))
9291 if(Flags2
& FLAG2_REGLIB
)
9292 DoOutput("___RegBase");
9294 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
9297 return DoOutput(/*(({*/"));\n}\n");
9300 static uint32
DoCallFunc(struct AmiPragma
*ap
, uint32 flags
, strptr name
, FuncType Func
)
9304 if(Flags
& FLAG_SINGLEFILE
)
9306 sprintf(filename
, filenamefmt
, name
);
9307 if(!OpenDest(filename
))
9310 res
= Func(ap
, flags
, name
);
9311 if(Flags
& FLAG_SINGLEFILE
)
9313 CloseDest(filename
);
9318 static uint32
PrintComment(struct Comment
*com
, strptr comment
)
9320 if(com
->Private
&& !(Flags
& FLAG_PRIVATE
))
9322 else if((Flags2
& FLAG2_SFDOUT
) && com
->Version
)
9324 return DoOutput("==version %d\n", com
->Version
);
9326 else if((Flags2
& FLAG2_SFDOUT
) && com
->ReservedNum
)
9328 LastBias
+= BIAS_OFFSET
*com
->ReservedNum
;
9329 return DoOutput("==reserve %d\n", com
->ReservedNum
);
9331 else if(!(Flags
& FLAG_DOCOMMENT
) || !comment
)
9336 if(!DoOutput(comment
, com
->Data
))
9339 else if(com
->ReservedNum
)
9342 sprintf(temp
, "* --- (%u function slot%s reserved here) ---", com
->ReservedNum
,
9343 com
->ReservedNum
== 1 ? "" : "s");
9344 if(!DoOutput(comment
, temp
))
9347 else if(com
->Version
)
9350 if(com
->Version
>= FIRST_KNOWN_RELEASE
&& com
->Version
<= LAST_KNOWN_RELEASE
&&
9351 (Flags2
& FLAG2_SYSTEMRELEASE
))
9352 sprintf(temp
, "* --- functions in V%u or higher %s ---", com
->Version
,
9353 Release
[com
->Version
-FIRST_KNOWN_RELEASE
]);
9355 sprintf(temp
, "* --- functions in V%u or higher ---", com
->Version
);
9357 if(!DoOutput(comment
, temp
))
9363 static uint32
CallFunc(uint32 tagmode
, strptr comment
, FuncType Func
)
9365 struct Comment
*com
;
9367 struct AmiPragma
*ap
;
9369 com
= (struct Comment
*) Comment
.First
;
9371 for(ap
= (struct AmiPragma
*) AmiPragma
.First
; ap
;
9372 ap
= (struct AmiPragma
*) ap
->List
.Next
)
9374 if(BaseName
&& (ap
->Flags
& AMIPRAGFLAG_A6USE
))
9376 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
9378 else if((ap
->Flags
& AMIPRAGFLAG_PUBLIC
) || (Flags
& FLAG_PRIVATE
))
9380 while(com
&& com
->Bias
<= ap
->Bias
)
9382 if(!PrintComment(com
, comment
))
9384 com
= (struct Comment
*) com
->List
.Next
;
9385 } /* comment loop */
9388 printf("Processing %s - %s\n", ap
->FuncName
? ap
->FuncName
: "",
9389 ap
->TagName
? ap
->TagName
: "");
9392 if(tagmode
!= TAGMODE_TAGS
)
9394 if(ap
->FuncName
&& !DoCallFunc(ap
, FUNCFLAG_NORMAL
, ap
->FuncName
, Func
))
9397 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9399 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_NORMAL
)
9401 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9409 if(ap
->TagName
&& !DoCallFunc(ap
, FUNCFLAG_TAG
, ap
->TagName
, Func
))
9412 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9414 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_TAG
)
9416 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9425 if(!PrintComment(com
, comment
))
9427 com
= (struct Comment
*) com
->List
.Next
;
9428 } /* comment loop */
9432 static uint32
PrintIncludes(void) /* copies the include lines */
9434 struct Include
*inc
;
9437 inc
= (struct Include
*) Includes
.First
;
9441 s2
= (strptr
) tempbuf
;
9442 for(s
= inc
->Include
; *s
; ++s
)
9446 case '<': *(s2
++) = ' '; break;
9448 case '.': *(s2
++) = '_'; break;
9450 default: *(s2
++) = toupper(*s
);
9454 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf
, inc
->Include
);
9455 inc
= (struct Include
*) inc
->List
.Next
;
9458 DoOutput("#include <exec/types.h>\n");
9459 return DoOutput("\n");
9462 /* ------------------------------------------------------------------ */
9464 static int32
AddClibEntry(strptr buffer
, strptr bufend
, uint32 linenum
)
9466 strptr buf
= buffer
;
9467 struct ClibData d
, *f
;
9469 memset(&d
, 0, sizeof(struct ClibData
));
9470 buf
= SkipBlanksRet(buf
);
9471 if(*buf
== '#') /* preprocessor lines */
9474 printf("Found non-function bracket in preprocessor line %ld\n", linenum
);
9476 while(buf
< bufend
&& *buf
!= '\n')
9480 if(!strnicmp(buf
, "ASM", 3))
9481 buf
= SkipBlanks(buf
+3);
9482 /* else if(!strnicmp(buf, "STACK", 5))
9483 buf = SkipBlanks(buf+5);
9485 else if(!strnicmp(buf
, "REGS", 4))
9486 buf
= SkipBlanks(buf
+4);
9488 if(!strnicmp(buf
, "extern", 6))
9490 buf
= SkipBlanksRet(buf
+6);
9491 if(!strnicmp(buf
, "\"C\"", 3)) /* CPP: extern "C" */
9493 buf
= SkipBlanksRet(buf
+3);
9496 buf
= SkipBlanksRet(buf
+1);
9501 if(!GetCPPType(&d
.ReturnType
, buf
, 1, 1))
9503 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE
, linenum
);
9506 else if(d
.ReturnType
.Unknown
)
9507 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, linenum
,
9508 d
.ReturnType
.Unknown
);
9510 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9512 strptr r
= d
.ReturnType
.TypeStart
;
9513 while(*r
!= '('/*)*/) ++r
;
9514 r
= SkipBlanks(++r
); /* the bracket */
9515 d
.FuncName
= SkipBlanks(++r
); /* the asterisk */
9518 d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
+d
.ReturnType
.FullLength
);
9520 while(*(buf
++) != '('/*)*/)
9522 *(SkipName(d
.FuncName
)) = 0;
9526 printf("Found non-function bracket in line %ld\n", linenum
);
9528 while(buf
< bufend
&& *buf
!= '\n')
9532 buf
= SkipBlanksRet(buf
);
9534 while(*buf
!= /*(*/')' && buf
< bufend
)
9536 if(d
.NumArgs
== MAXREGPPC
+1)
9538 DoError(ERROFFSET_CLIB
| ERR_TO_MUCH_ARGUMENTS
, linenum
);
9541 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 0, 1))
9543 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE
, linenum
, d
.NumArgs
);
9546 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
9547 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE_INT
, linenum
,
9548 d
.NumArgs
, d
.Args
[d
.NumArgs
-1].Unknown
);
9550 buf
= d
.Args
[d
.NumArgs
-1].TypeStart
+ d
.Args
[d
.NumArgs
-1].FullLength
;
9551 while(*buf
!= ',' && *buf
!= /*(*/')' && buf
< bufend
)
9554 printf("Added argument %d for %s (%d bytes)\n", d
.NumArgs
, d
.FuncName
,
9555 d
.Args
[d
.NumArgs
-1].FullLength
);
9558 buf
= SkipBlanksRet(++buf
);
9561 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9562 d
.NumArgs
= 0; /* void arguments are no arguments */
9564 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9567 memcpy(f
, &d
, sizeof(struct ClibData
));
9573 struct ClibData
*e
= clibdata
;
9578 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9580 int numclose
= 2, numopen
= 1;
9581 while(buf
< bufend
&& (numclose
|| numopen
> 0))
9583 if(*buf
== '('/*)*/) { ++numclose
; --numopen
; }
9584 else if(*buf
== /*(*/')') --numclose
;
9590 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9591 f
->FuncName
, linenum
, buf
-buffer
, f
->NumArgs
);
9596 static int32
ScanClibFile(strptr buf
, strptr bufend
)
9598 strptr linestart
= buf
;
9602 /* remove comments and other not so nice characters */
9605 if(*buf
== '\t' || *buf
== '\r' || *buf
== (string
)0xA0)
9607 else if(buf
[0] == '/' && buf
< bufend
-1)
9611 while(buf
< bufend
-1 && (buf
[0] != '*' || buf
[1] != '/'))
9620 else if(buf
[1] == '/')
9622 while(buf
< bufend
&& buf
[0] != '\n')
9629 else if(buf
[0] == '#' && strncmp("#include", buf
, 8))
9631 while(buf
< bufend
&& buf
[0] != '\n')
9640 printf("-----------\n%s-----------\n", linestart
);
9655 else if(!strncmp("#include", buf
, 8))
9659 if(!(d
= (struct Include
*) NewItem(&Includes
)))
9661 d
->Include
= buf
= SkipBlanks(buf
+8);
9662 AddItem(&Includes
, (struct ShortList
*) d
);
9663 while(*buf
&& *buf
!= '>' && *buf
!= '\n')
9671 printf("Added Include line %s\n", d
->Include
);
9675 else if(*buf
== '('/*)*/)
9679 if((i
= AddClibEntry(linestart
, bufend
, linenum
)) == -1) /* no memory */
9683 while(buf
< bufend
&& *buf
!= '\n')
9684 ++buf
; /* skip this line */
9689 while(buf
< bufend
&& i
-- > 0)
9691 if(*(buf
++) == '\n')
9695 } /* skip this function */
9706 static int32
IsCPPType(struct CPP_NameType
*data
, uint8 type
)
9708 if(!data
|| data
->Flags
|| data
->Type
!= type
|| data
->PointerDepth
)
9713 static uint32
CheckRegisterNum(strptr string
, struct CPP_NameType
*data
)
9717 for(i
= 0; i
< MAXREG
; ++i
)
9719 j
= strlen(RegNames
[i
]);
9720 if(!strnicmp(string
, RegNames
[i
], j
))
9723 if(*string
== ' ' || *string
== '\t' || *string
== '\n' || *string
== /*(*/')')
9726 data
->Flags
|= CPP_FLAG_REGISTER
;
9734 static uint32
ParseFuncPtrArgs(strptr buffer
, struct CPP_NameType
*data
)
9736 strptr buf
= buffer
;
9739 memset(&d
, 0, sizeof(struct ClibData
));
9740 while(*buf
!= /*(*/')')
9742 if(d
.NumArgs
== MAXREGPPC
+1)
9744 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 1, 1))
9747 buf
+= d
.Args
[d
.NumArgs
-1].FullLength
;
9748 while(*buf
!= ',' && *buf
!= /*(*/')')
9751 buf
= SkipBlanksRet(++buf
);
9754 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9755 d
.NumArgs
= 0; /* void arguments are no arguments */
9757 if(d
.NumArgs
) /* no need to allocate structure for nothing */
9759 if(!(data
->FuncPtr
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9762 memcpy(data
->FuncPtr
, &d
, sizeof(struct ClibData
));
9764 return (uint32
) (buf
+1-buffer
);
9767 /* rettype turns on usage of "extern" specifier */
9768 static int32
GetCPPType(struct CPP_NameType
*data
, strptr start
, uint32 rettype
, uint32 small
)
9775 data
->TypeStart
= start
= SkipBlanks(start
);
9777 if(!strncmp(start
, "REG", 3) && (start
[3] == ' ' || start
[3] == '\t' || start
[3] == '\n' || start
[3] == '('/*)*/))
9779 u
= SkipBlanksRet(start
+3);
9782 u
= SkipBlanks(u
+1);
9783 if((j
= CheckRegisterNum(u
, data
)))
9785 u
= SkipBlanks(u
+j
);
9787 start
= SkipBlanks(u
+1);
9791 data
->TypeStart
= start
;
9795 start
= SkipBlanks((u
= start
));
9796 if(!strncmp("...",start
,3))
9798 data
->Type
= CPP_TYPE_VARARGS
;
9799 data
->TypeLength
= start
+3 - (data
->TypeStart
);
9800 data
->FullLength
= data
->TypeLength
;
9803 if(CheckKeyword(start
, "const", 5) || CheckKeyword(start
, "CONST", 5))
9805 data
->Flags
|= CPP_FLAG_CONST
; start
+= 5;
9807 else if(rettype
&& CheckKeyword(start
, "extern", 6))
9809 start
+= 6; /* ignore it */
9811 else if(CheckKeyword(start
, "long", 4))
9813 if(data
->Flags
& CPP_FLAG_LONG
)
9814 data
->Type
= CPP_TYPE_LONGLONG
;
9816 data
->Flags
|= CPP_FLAG_LONG
;
9820 else if(CheckKeyword(start
, "signed", 6))
9822 else if(CheckKeyword(start
, "unsigned", 8))
9824 data
->Flags
|= CPP_FLAG_UNSIGNED
; start
+= 8;
9826 else if(CheckKeyword(start
, "register", 8))
9828 data
->Flags
|= CPP_FLAG_REGISTER
; start
+= 8;
9829 data
->Register
= UNDEFREGISTER
;
9831 else if(CheckKeyword(start
, "struct", 6))
9833 start
= SkipBlanks(start
+6);
9834 data
->Flags
|= CPP_FLAG_STRUCT
;
9835 if(*start
== '?') /* ? for external types */
9837 data
->StructureLength
= 0;
9838 data
->StructureName
= "";
9841 else if(*start
== '!') /* ! for typedef types */
9843 data
->Flags
|= CPP_FLAG_TYPEDEFNAME
;
9845 /* structure name and length already set */
9849 start
= SkipName((data
->StructureName
= start
));
9850 data
->StructureLength
= start
-data
->StructureName
;
9853 else if(CheckKeyword(start
, "union", 5))
9855 start
= SkipBlanks(start
+5);
9856 data
->Flags
|= CPP_FLAG_UNION
;
9857 if(*start
!= '?') /* ? for external types */
9859 start
= SkipName((data
->StructureName
= start
));
9860 data
->StructureLength
= start
-data
->StructureName
;
9864 data
->StructureLength
= 0;
9865 data
->StructureName
= "";
9869 else if(CheckKeyword(start
, "enum", 4))
9871 start
= SkipBlanks(start
+4);
9872 data
->Flags
|= CPP_FLAG_ENUM
;
9873 if(*start
!= '?') /* ? for external types */
9875 start
= SkipName((data
->StructureName
= start
));
9876 data
->StructureLength
= start
-data
->StructureName
;
9880 data
->StructureLength
= 0;
9881 data
->StructureName
= "";
9885 else if(*start
== '*')
9887 ++start
; ++data
->PointerDepth
;
9889 else if(*start
== '[')
9891 data
->Flags
|= CPP_FLAG_ARRAY
;
9892 while(*start
&& *start
!= ']')
9897 else if(start
[0] == '_' && start
[1] == '_' && (j
= CheckRegisterNum(start
+2, data
)))
9899 else if(!data
->Type
)
9903 for(i
= 0; CPP_Field
[i
].Text
; ++i
)
9905 if(!strncmp(start
, CPP_Field
[i
].Text
, CPP_Field
[i
].Length
) &&
9906 (start
[CPP_Field
[i
].Length
] == ' ' ||
9907 start
[CPP_Field
[i
].Length
] == '\t' ||
9908 start
[CPP_Field
[i
].Length
] == '\n' ||
9909 start
[CPP_Field
[i
].Length
] == ',' ||
9910 start
[CPP_Field
[i
].Length
] == /*(*/')' ||
9911 start
[CPP_Field
[i
].Length
] == '('/*)*/ ||
9912 start
[CPP_Field
[i
].Length
] == '*'))
9914 start
+= CPP_Field
[i
].Length
;
9915 data
->Type
= CPP_Field
[i
].Type
;
9916 data
->Flags
|= CPP_Field
[i
].Flags
;
9917 if(CPP_Field
[i
].Flags
& CPP_FLAG_POINTER
)
9918 ++data
->PointerDepth
;
9922 if(CPP_Field
[i
].Text
)
9926 struct CPP_ExternNames
*a
= extnames
;
9930 i
= strlen(a
->Type
);
9931 if(!strncmp(a
->Type
, start
, i
) && !isalnum(start
[i
]) &&
9935 data
->StructureName
= a
->NameType
.StructureName
;
9936 data
->FuncPtr
= a
->NameType
.FuncPtr
;
9937 data
->StructureLength
= a
->NameType
.StructureLength
;
9938 data
->PointerDepth
+= a
->NameType
.PointerDepth
;
9939 data
->Type
= a
->NameType
.Type
;
9940 data
->Flags
|= a
->NameType
.Flags
;
9941 data
->FuncArgs
= a
->NameType
.FuncArgs
;
9942 data
->ArgsLength
= a
->NameType
.ArgsLength
;
9946 /* check types here */
9951 else if((!data
->Type
) && (!data
->Flags
))
9954 struct CPP_Unknown
*u
;
9956 data
->Type
= CPP_TYPE_INT
;
9957 size
= SkipName(start
)-start
;
9958 for(u
= unknown
; u
&& strncmp(u
->Unknown
, start
, size
); u
= u
->Next
)
9962 data
->Unknown
= DupString(start
, size
);
9963 if((u
= (struct CPP_Unknown
*) AllocListMem(sizeof(struct CPP_Unknown
))))
9966 u
->Unknown
= data
->Unknown
;
9980 if(start
!= SkipBlanks(u
)) /* we broke the loop after increasing start */
9983 data
->TypeLength
= u
- (data
->TypeStart
);
9984 data
->FullLength
= data
->TypeLength
;
9991 u
= SkipBlanksRet(++u
);
9996 ++data
->FuncPointerDepth
; ++u
;
9998 u
= SkipBlanksRet(u
);
9999 if(CheckKeyword(u
, "const", 5) || CheckKeyword(u
, "CONST", 5))
10001 data
->Flags
|= CPP_FLAG_CONST
; u
+= 6;
10003 u
= SkipBlanksRet(u
);
10005 data
->FunctionName
= u
;
10006 u
= SkipBlanksRet(SkipName(u
));
10011 while(*u
&& numclose
)
10013 if(*u
== '('/*)*/) ++numclose
;
10014 else if(*u
== /*(*/')') --numclose
;
10020 u
= SkipBlanksRet(++u
);
10023 data
->Flags
|= CPP_FLAG_FUNCTION
;
10025 if((j
= ParseFuncPtrArgs(u
+1, data
)))
10027 data
->FuncArgs
= u
;
10028 data
->ArgsLength
= j
+1;
10029 data
->FullLength
= u
+data
->ArgsLength
- (data
->TypeStart
);
10035 if(data
->PointerDepth
)
10036 data
->Flags
|= CPP_FLAG_POINTER
;
10038 if(!(Flags2
& FLAG2_SMALLTYPES
) && !small
)
10040 if(!(data
->Flags
& (CPP_FLAG_STRPTR
|CPP_FLAG_POINTER
|CPP_FLAG_ENUM
10041 |CPP_FLAG_STRUCT
|CPP_FLAG_UNION
|CPP_FLAG_FUNCTION
|CPP_FLAG_REGISTER
)))
10043 if(data
->Type
== CPP_TYPE_BYTE
|| data
->Type
== CPP_TYPE_WORD
|| data
->Type
== CPP_TYPE_INT
)
10045 if(data
->Flags
& CPP_FLAG_UNSIGNED
)
10046 data
->Replace
= "const ULONG";
10048 data
->Replace
= "const LONG";
10049 data
->Type
= CPP_TYPE_LONG
;
10050 if(!(data
->Flags
& CPP_FLAG_CONST
))
10051 data
->Replace
+= 6;
10056 if(!data
->Type
&& (data
->Flags
& CPP_FLAG_LONG
))
10057 data
->Type
= CPP_TYPE_LONG
;
10059 if((!data
->Type
&& !data
->Flags
) || !ok
)
10064 static struct ClibData
*GetClibFunc(strptr name
, struct AmiPragma
*ap
, uint32 flags
)
10066 struct ClibData
*d
= clibdata
;
10070 DoError(ERR_ILLEGAL_INTERNAL_VALUE
, 0);
10074 while(d
&& strcmp(name
, d
->FuncName
))
10079 if(!(ap
->Flags
& AMIPRAGFLAG_NOCLIB
))
10081 DoError(ERR_PROTOTYPE_MISSING
, 0, name
);
10082 ap
->Flags
|= AMIPRAGFLAG_NOCLIB
;
10085 else if(ap
->CallArgs
!= d
->NumArgs
&& (!(flags
& FUNCFLAG_TAG
) ||
10086 ap
->CallArgs
+1 != d
->NumArgs
))
10088 if(!(ap
->Flags
& (AMIPRAGFLAG_CLIBARGCNT
|AMIPRAGFLAG_DIDARGWARN
)))
10090 DoError(ERR_CLIB_ARG_COUNT
, 0, name
, d
->NumArgs
, ap
->NumArgs
);
10091 ap
->Flags
|= AMIPRAGFLAG_CLIBARGCNT
;
10099 static int32
CheckKeyword(strptr string
, strptr keyword
, int32 size
)
10101 if(!strncmp(string
, keyword
, size
))
10104 if(*string
== ' ' || *string
== '\t' || *string
== '\n')
10110 /* return nonzero, when usable, zero, when string already emitted */
10111 static uint32
CopyCPPType(strptr buffer
, uint32 pass
, struct ClibData
*cd
,
10112 struct AmiArgs
*args
)
10114 uint32 ret
= 0, reg
;
10115 uint32 i
, j
, k
= 0;
10117 /* pass 0: signed strptr, MaxonC++ high args */
10118 /* pass 1: unsigned strptr, MaxonC++ high args */
10119 /* pass 2: signed strptr, StormC++ high args */
10120 /* pass 3: unsigned strptr, StormC++ high args */
10122 for(i
= 0; i
< cd
->NumArgs
; ++i
)
10124 struct CPP_NameType
*nt
;
10128 if(args
&& (Flags
& FLAG_LOCALREG
) && (nt
->Type
!= CPP_TYPE_VARARGS
))
10129 reg
= 1 + args
[k
].ArgReg
;
10130 else if((nt
->Flags
& CPP_FLAG_REGISTER
) && nt
->Register
!= UNDEFREGISTER
)
10131 reg
= 1 + nt
->Register
;
10135 if(reg
--) /* subtract the added 1 */
10137 *(buffer
++) = CPP_TYPE_REGISTER
;
10142 *(buffer
++) = reg
/10 + '0';
10143 *(buffer
++) = reg
%10 + '0';
10147 *(buffer
++) = reg
+ (reg
< 10 ? '0' : 'A'-10);
10150 *(buffer
++) = reg
+ '0';
10153 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10155 for(j
= 0; j
< nt
->FuncPointerDepth
; ++j
)
10156 *(buffer
++) = CPP_TYPE_POINTER
;
10157 *(buffer
++) = CPP_TYPE_FUNCTION
;
10159 for(j
= 0; j
< nt
->PointerDepth
; ++j
)
10160 *(buffer
++) = CPP_TYPE_POINTER
;
10161 if(nt
->Flags
& CPP_FLAG_CONST
)
10162 *(buffer
++) = CPP_TYPE_CONST
;
10163 if(nt
->Flags
& CPP_FLAG_UNSIGNED
)
10164 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10165 else if((nt
->Flags
& CPP_FLAG_STRPTR
) && (pass
& 1))
10167 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10168 ret
|= 1; /* we really use this pass */
10170 if(nt
->Flags
& CPP_FLAG_ENUM
)
10171 *(buffer
++) = CPP_TYPE_ENUM
;
10173 *(buffer
++) = cd
->Args
[i
].Type
;
10177 sprintf(buffer
, "%02lu", (uint32
) nt
->StructureLength
); buffer
+= 2;
10178 for(i
= 0; i
< nt
->StructureLength
; ++i
)
10179 *(buffer
++) = nt
->StructureName
[i
];
10181 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10185 ret
|= CopyCPPType(buffer
, pass
, nt
->FuncPtr
, 0);
10187 ++buffer
; /* skip to the new end */
10189 *(buffer
++) = CPP_TYPE_FUNCEND
;
10192 if(IsCPPType(nt
, CPP_TYPE_DOUBLE
)) /* double needs 2 registers */
10203 return ret
; /* return nozero if this pass should be used */
10206 static uint32
OutClibType(struct CPP_NameType
*nt
, strptr txt
)
10209 DoOutput("%s", nt
->Replace
);
10211 DoOutputDirect(nt
->TypeStart
, nt
->TypeLength
);
10212 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10214 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10217 DoOutput(" ("/*)*/);
10218 for(i
= 0; i
< nt
->FuncPointerDepth
; ++i
)
10220 DoOutput(/*((*/txt
? "%s)" : ")", txt
);
10222 return DoOutputDirect(nt
->FuncArgs
, nt
->ArgsLength
);
10224 return DoOutput("()");
10227 return DoOutput(" %s", txt
);
10233 static uint32
MakeClibType(strptr dest
, struct CPP_NameType
*nt
, strptr txt
)
10241 i
= strlen(nt
->Replace
);
10242 memcpy(a
, nt
->Replace
, i
);
10247 memcpy(a
, nt
->TypeStart
, nt
->TypeLength
);
10248 a
+= nt
->TypeLength
;
10251 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10253 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10255 a
+= sprintf(a
, (txt
? " (*%s)" : " (*)"), txt
);
10258 memcpy(a
, nt
->FuncArgs
, nt
->ArgsLength
);
10259 a
+= nt
->ArgsLength
;
10262 a
+= sprintf(a
, "()");
10265 a
+= sprintf(a
, " %s", txt
);
10267 return (uint32
)(a
-dest
);
10270 static uint32
OutPASCALType(struct CPP_NameType
*t
, strptr txt
, uint32 ret
)
10272 int32 i
= t
->PointerDepth
;
10274 if(t
->Flags
& CPP_FLAG_CONST
)
10275 DoOutput("CONST ");
10276 if(!ret
&& i
== 1 &&
10277 (t
->Type
== CPP_TYPE_LONG
|| t
->Type
== CPP_TYPE_WORD
))
10279 DoOutput("VAR "); --i
;
10282 DoOutput("%s : ", txt
);
10284 if(!i
&& t
->Flags
== CPP_FLAG_BOOLEAN
)
10285 return DoOutput("BOOLEAN");
10286 else if(i
&& t
->Type
== CPP_TYPE_VOID
)
10287 return DoOutput("POINTER");
10288 else if(t
->Flags
& CPP_FLAG_FUNCTION
)
10289 return DoOutput("tPROCEDURE");
10294 if((t
->Flags
& (CPP_FLAG_STRUCT
|CPP_FLAG_UNION
)) && t
->StructureLength
)
10296 if(!t
->PointerDepth
)
10298 return DoOutputDirect(t
->StructureName
, t
->StructureLength
);
10301 if(t
->Flags
& CPP_FLAG_UNSIGNED
)
10303 if(t
->Type
== CPP_TYPE_LONG
)
10304 return DoOutput("CARDINAL");
10305 if(t
->Type
== CPP_TYPE_WORD
)
10306 return DoOutput("int16");
10307 if(t
->Type
== CPP_TYPE_BYTE
)
10308 return DoOutput(t
->PointerDepth
== 1 ? "CHAR" : "int8");
10310 else if(t
->Type
== CPP_TYPE_WORD
)
10311 return DoOutput("INTEGER");
10312 else if(t
->Type
== CPP_TYPE_BYTE
)
10313 return DoOutput("SHORTINT");
10314 return DoOutput("int32INT");
10317 /* ------------------------------------------------------------------ */
10319 static uint32
CallPrag(uint32 tagmode
, strptr type
, FuncType Func
)
10322 if((*type
&& !DoOutput("#if%s\n", type
)) ||
10323 !(CallFunc(tagmode
, tagmode
? 0 : "/%s */\n", Func
)) ||
10324 (*type
&& !DoOutput("#endif\n")))
10329 static uint32
CreatePragmaFile(strptr amicall
, strptr libcall
, strptr amitags
,
10330 strptr libtags
, uint32 mode
)
10332 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10336 case PRAGMODE_PRAGLIB
: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10337 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper
,
10338 ShortBaseNameUpper
); break;
10339 case PRAGMODE_PRAGSLIB
: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10340 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10341 case PRAGMODE_PRAGSPRAGS
: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10342 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10343 case PRAGMODE_NONE
: break;
10350 DoOutputDirect(HEADER
, headersize
);
10353 if(mode
!= PRAGMODE_NONE
&& !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10354 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10357 if((Flags
& FLAG_EXTERNC
) &&
10358 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10361 if(Flags
& FLAG_GNUPRAG
)
10363 DoOutput("#ifdef " TEXT_GNUC
"\n#ifdef NO_OBSOLETE\n"
10364 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10365 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName
);
10366 Flags
|= FLAG_DONE
;
10370 !CallPrag(TAGMODE_NORMAL
, amicall
, FuncAMICALL
) ||
10371 !CallPrag(TAGMODE_NORMAL
, libcall
, FuncLIBCALL
))
10377 !CallPrag(TAGMODE_TAGS
, amitags
, FuncAMICALL
) ||
10378 !CallPrag(TAGMODE_TAGS
, libtags
, FuncLIBCALL
))
10382 if((Flags
& FLAG_EXTERNC
) &&
10383 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10388 case PRAGMODE_PRAGLIB
: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10389 ShortBaseNameUpper
); break;
10390 case PRAGMODE_PRAGSLIB
: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10391 ShortBaseNameUpper
); break;
10392 case PRAGMODE_PRAGSPRAGS
: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10393 ShortBaseNameUpper
); break;
10394 case PRAGMODE_NONE
: break;
10397 return Output_Error
;
10400 static uint32
CreateCSTUBSFile(void)
10402 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10404 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10405 ShortBaseNameUpper
, ShortBaseNameUpper
);
10409 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10415 DoOutputDirect(HEADER
, headersize
);
10418 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10419 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10422 if(!CallFunc(TAGMODE_TAGS
, "/%s */\n", FuncCSTUBS
))
10425 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10426 ShortBaseNameUpper
);
10429 static uint32
CreateLVOFile(uint32 mode
)
10431 strptr data
= "_LVO_I";
10433 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10435 if(mode
== 2 || mode
== 4)
10438 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10439 ShortBaseNameUpper
, data
, ShortBaseNameUpper
, data
) ||
10440 (HEADER
&& (!DoOutput("\n") || !DoOutputDirect(HEADER
, headersize
))) ||
10441 (mode
<= 2 && !CallFunc(TAGMODE_NORMAL
, 0, FuncLVOXDEF
)) ||
10442 !CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVO
) ||
10443 !DoOutput("\n\n\t\tENDC\n"))
10449 static uint32
CreateLVOFilePPC(uint32 mode
)
10451 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10453 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10454 ShortBaseNameUpper
, ShortBaseNameUpper
))
10459 DoOutputDirect(HEADER
, headersize
);
10463 case 0: CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCXDEF
);
10464 case 1: CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVOPPC
);
10466 return DoOutput("\n\t.endif\n");
10469 static uint32
CreateAsmStubs(uint32 mode
, uint32 callmode
)
10471 if(mode
== 1 && (Flags2
& FLAG2_AUTOHEADER
)) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10473 /* 1 = Text, 2 = Code */
10480 DoOutputDirect(HEADER
, headersize
);
10483 if(!(Flags
& FLAG_ASMSECTION
))
10484 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
10485 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
10486 if(!CallFunc(callmode
, "\n%s", FuncAsmText
))
10490 if(!CallFunc(callmode
, 0, FuncAsmCode
))
10498 static uint32
CreateProtoFile(uint32 Type
)
10500 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10502 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper
,
10503 ShortBaseNameUpper
);
10508 DoOutputDirect(HEADER
, headersize
);
10511 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10513 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC
")\n"
10514 "#include <clib/%s_protos.h>\n#endif\n",
10515 ShortBaseNameUpper
, ShortBaseName
);
10519 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10521 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10523 DoOutput("%s;\n#endif\n", BaseName
);
10530 DoOutput("\n#ifdef " TEXT_GNUC
"\n");
10532 DoOutput("#ifndef __cplusplus\n");
10533 DoOutput("#ifdef __AROS__\n");
10534 DoOutput("#include <defines/%s.h>\n", ShortBaseName
);
10535 DoOutput("#else\n");
10536 DoOutput("#include <inline/%s.h>\n", ShortBaseName
);
10537 DoOutput("#endif\n");
10539 DoOutput("#endif\n");
10543 DoOutput("#elif defined(" TEXT_VBCC
")\n"
10544 "#include <inline/%s_protos.h>\n#else", ShortBaseName
);
10546 DoOutput("#elif !defined(" TEXT_VBCC
")");
10550 DoOutput("\n#ifndef __PPC__");
10553 strptr str1
= "pragma", str2
= "lib";
10557 case 4: str1
= "pragmas"; /* no break; */
10558 case 2: str2
= "pragmas"; break;
10559 case 3: str1
= "pragmas"; break;
10560 case 5: str1
= "local"; str2
= "loc"; break;
10562 DoOutput("\n#include <%s/%s_%s.h>\n", str1
, ShortBaseName
, str2
);
10565 DoOutput("#endif\n");
10567 DoOutput("#endif\n");
10570 Flags
|= FLAG_DONE
;
10572 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10575 static uint32
CreateLocalData(strptr to
, uint32 callmode
)
10577 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10579 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10580 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10581 ShortBaseNameUpper
, ShortBaseNameUpper
);
10586 DoOutputDirect(HEADER
, headersize
);
10592 if((Flags
& FLAG_EXTERNC
) &&
10593 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10596 if(!CallFunc(callmode
, "/%s */\n", FuncLocText
))
10599 if((Flags
& FLAG_EXTERNC
) &&
10600 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10603 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper
);
10605 sprintf(filename
, "%s_loc.lib", ShortBaseName
);
10606 if(!CloseDest(to
) || !OpenDest(filename
))
10609 CallFunc(callmode
, 0, FuncLocCode
);
10611 return CloseDest(filename
);
10614 static uint32
CreateInline(uint32 mode
, uint32 callmode
)
10616 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10620 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10623 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10624 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
,
10625 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10630 DoOutputDirect(HEADER
, headersize
);
10635 /* prevent loading of clib-file after inline */
10636 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10637 ShortBaseNameUpper
, ShortBaseNameUpper
);
10641 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10642 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10643 "#include <ppcinline/macros.h>\n#endif\n\n");
10645 DoOutput("#ifndef __INLINE_MACROS_H\n"
10646 "#include <inline/macros.h>\n#endif\n\n");
10647 Flags
|= FLAG_INLINENEW
;
10651 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10652 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10653 "#include <ppcinline/stubs.h>\n#endif\n\n");
10655 DoOutput("#ifndef __INLINE_STUB_H\n"
10656 "#include <inline/stubs.h>\n#endif\n\n");
10658 Flags
|= FLAG_INLINESTUB
;
10661 Flags2
|= FLAG2_INLINEMAC
;
10665 if((Flags
& FLAG_EXTERNC
) &&
10666 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10671 if(mode
&& mode
<= 2)
10673 if(Flags
& FLAG_MORPHOS
)
10674 DoOutput("#include <emul/emulregs.h>\n");
10675 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10676 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10677 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10678 "#define BASE_PAR_DECL0 void\n#endif\n"
10679 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10680 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10683 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10684 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10689 if(!CallFunc(callmode
, "/%s */\n", FuncInline
))
10695 Flags
|= FLAG_INLINENEW
;
10696 if(!CallFunc(callmode
, "/%s */\n", FuncInlineDirect
))
10701 if(!CallFunc(callmode
, "/%s */\n", FuncInlineNS
))
10705 if(mode
&& mode
<= 2 && BaseName
)
10706 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10707 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper
);
10709 if((Flags
& FLAG_EXTERNC
) &&
10710 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10713 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10714 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10717 static uint32
CreateGateStubs(uint32 callmode
)
10719 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10723 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10725 if(!prefix
[0] && !subprefix
[0])
10727 DoError(ERR_PREFIX
, 0); return 1;
10730 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10731 ShortBaseNameUpper
, ShortBaseNameUpper
);
10733 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10734 premacro
, ShortBaseName
);
10739 DoOutputDirect(HEADER
, headersize
);
10744 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10745 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10746 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10747 "#define BASE_PAR_DECL0 void\n#endif\n"
10748 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10749 "BASE_EXT_DECL0\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10754 if(!CallFunc(callmode
, "/%s */\n", FuncGateStubs
))
10757 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper
);
10760 static uint32
CreateSASPowerUP(uint32 callmode
)
10762 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10764 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10765 ShortBaseNameUpper
, ShortBaseNameUpper
);
10770 DoOutputDirect(HEADER
, headersize
);
10773 DoOutput("\n#ifdef __GNUC__\n"
10774 "#ifndef _PPCINLINE__%s_H\n"
10775 "#include <ppcinline/%s.h>\n"
10778 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10779 "#include <ppclib/interface.h>\n"
10781 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10782 "#include <gcclib/powerup_protos.h>\n"
10784 "#ifndef NO_PPCINLINE_STDARG\n"
10785 "#define NO_PPCINLINE_STDARG\n"
10786 "#endif /* SAS-C PPC inlines */\n\n",
10787 ShortBaseNameUpper
, ShortBaseName
);
10791 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10792 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10795 if(!CallFunc(callmode
, "/%s */\n", FuncPowerUP
))
10798 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10799 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper
);
10802 static uint32
CreateProtoPowerUP(void)
10804 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10806 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10807 ShortBaseNameUpper
, ShortBaseNameUpper
);
10812 DoOutputDirect(HEADER
, headersize
);
10815 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName
);
10819 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10820 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10821 "#endif\n%s;\n#endif\n", BaseName
);
10824 DoOutput("\n#ifdef " TEXT_GNUC
"\n"
10825 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10826 "#else\n#include <inline/%s.h>\n#endif\n"
10827 "#else /* SAS-C */\n"
10828 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10829 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10830 ShortBaseName
, ShortBaseName
, ShortBaseName
, ShortBaseName
);
10832 Flags
|= FLAG_DONE
;
10834 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10837 static uint32
CreateFPCUnit(void)
10840 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT
);
10844 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10848 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName
);
10853 DoOutputDirect(HEADER
, headersize
);
10856 DoOutput("**********************************************************************}\n\n");
10857 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10858 DoOutput("{$mode objfpc}\n");
10859 DoOutput("{$I useamigasmartlink.inc}\n");
10860 DoOutput("{$ifdef use_amiga_smartlink}\n");
10861 DoOutput(" {$smartlink on}\n");
10862 DoOutput("{$endif use_amiga_smartlink}\n\n");
10864 DoOutput("UNIT %s;\n", ShortBaseNameUpper
);
10866 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName
, GetBaseTypeLib());
10868 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper
,ShortBaseName
);
10869 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName
);
10870 DoOutput("{$I %s.inc}\n\n",ShortBaseName
);
10872 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncFPCType
))
10875 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10876 if(!CallFunc(TAGMODE_TAGS
, 0, FuncFPCTypeTags
))
10879 DoOutput("\n{Here we read how to compile this unit}\n");
10880 DoOutput("{You can remove this include and use a define instead}\n");
10881 DoOutput("{$I useautoopenlib.inc}\n");
10882 DoOutput("{$ifdef use_init_openlib}\n");
10883 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10884 DoOutput("{$endif use_init_openlib}\n");
10885 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10886 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper
);
10887 DoOutput("\nIMPLEMENTATION\n\n");
10888 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10889 DoOutput("uses \n");
10890 DoOutput("{$ifndef dont_use_openlib}\n");
10891 DoOutput("msgbox, \n");
10892 DoOutput("{$endif dont_use_openlib}\n");
10893 DoOutput("tagsarray;\n\n");
10895 if(!CallFunc(TAGMODE_NORMAL
, "(%s *)\n", FuncFPCUnit
))
10898 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10899 if(!CallFunc(TAGMODE_TAGS
,"(%s *)\n", FuncFPCTypeTagsUnit
))
10902 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10903 DoOutput(" VERSION : string[2] = '0';\n");
10904 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10906 DoOutput("{$ifdef use_init_openlib}\n");
10907 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName
);
10908 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper
);
10910 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10911 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10912 DoOutput("begin\n");
10913 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10914 DoOutput(" if %s <> nil then begin\n",BaseName
);
10915 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10916 DoOutput(" %s := nil;\n",BaseName
);
10917 DoOutput(" end;\n");
10918 DoOutput("end;\n\n");
10919 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10920 DoOutput("begin\n %s := nil;\n",BaseName
);
10921 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10922 DoOutput(" if %s <> nil then begin\n",BaseName
);
10923 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10924 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10925 DoOutput(" end else begin\n");
10926 DoOutput(" MessageBox('FPC Pascal Error',\n");
10927 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10928 DoOutput(" 'Deallocating resources and closing down',\n");
10929 DoOutput(" 'Oops');\n");
10930 DoOutput(" halt(20);\n");
10931 DoOutput(" end;\n");
10932 DoOutput("end;\n\n");
10933 DoOutput("begin\n");
10934 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper
);
10935 DoOutput("{$endif use_init_openlib}\n\n");
10937 DoOutput("{$ifdef use_auto_openlib}\n");
10938 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName
);
10940 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10941 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10942 DoOutput("begin\n");
10943 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10944 DoOutput(" if %s <> nil then begin\n",BaseName
);
10945 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10946 DoOutput(" %s := nil;\n",BaseName
);
10947 DoOutput(" end;\n");
10948 DoOutput("end;\n\n");
10949 DoOutput("begin\n %s := nil;\n",BaseName
);
10950 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10951 DoOutput(" if %s <> nil then begin\n",BaseName
);
10952 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10953 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10954 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper
);
10955 DoOutput(" end else begin\n");
10956 DoOutput(" MessageBox('FPC Pascal Error',\n");
10957 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10958 DoOutput(" 'Deallocating resources and closing down',\n");
10959 DoOutput(" 'Oops');\n");
10960 DoOutput(" halt(20);\n");
10961 DoOutput(" end;\n\n");
10962 DoOutput("{$endif use_auto_openlib}\n\n");
10964 DoOutput("{$ifdef dont_use_openlib}\n");
10965 DoOutput("begin\n");
10966 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper
);
10967 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName
);
10968 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName
);
10969 DoOutput("{$endif dont_use_openlib}\n\n");
10971 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper
);
10974 static uint32
CreateBMAP(void)
10976 return CallFunc(TAGMODE_NORMAL
, 0, FuncBMAP
);
10979 static uint32
CreateLVOLib(void)
10983 i
= strlen(ShortBaseNameUpper
);
10984 EndPutM32(tempbuf
, HUNK_UNIT
);
10985 EndPutM32(tempbuf
+4, (i
+3)>>2);
10986 DoOutputDirect(tempbuf
, 8);
10987 DoOutputDirect(ShortBaseNameUpper
, i
);
10988 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10990 i
= strlen(hunkname
);
10991 EndPutM32(tempbuf
, HUNK_NAME
);
10992 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
10993 DoOutputDirect(tempbuf
, 8);
10994 DoOutputDirect(hunkname
, i
);
10995 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
10997 EndPutM32(tempbuf
, HUNK_CODE
);
10998 EndPutM32(tempbuf
+4, 0);
10999 EndPutM32(tempbuf
+8, HUNK_EXT
);
11000 DoOutputDirect(tempbuf
, 12);
11002 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOLib
))
11005 EndPutM32(tempbuf
, 0);
11006 EndPutM32(tempbuf
+4, HUNK_END
);
11007 return DoOutputDirect(tempbuf
, 8);
11010 static uint32
CreateLVOLibPPC(void)
11012 uint8
*data
= tempbuf
, *data2
, *data3
;
11014 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11015 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11016 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11017 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11018 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
11019 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
11020 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
11021 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11022 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11023 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11024 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
11025 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
11026 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
11027 EndPutM32Inc(data
, 0); /* eeh->e_entry */
11028 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
11029 data2
= data
; data
+= 4;
11030 EndPutM32Inc(data
, 0); /* eeh->e_flags */
11031 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
11032 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
11033 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
11034 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
11035 EndPutM16Inc(data
, 4); /* eeh->e_shnum */
11036 EndPutM16Inc(data
, 1); /* eeh->e_shstrndx - first table is string table */
11039 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11040 data
+= 28; /* 1 9 17*/
11041 EndPutM32(data2
, data
-tempbuf
); /* store the entry */
11043 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
11044 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
11045 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11046 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11047 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
11048 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
11049 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11050 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11051 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
11052 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11054 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
11055 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
11056 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
11057 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
11058 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[3].sh_offset */
11059 EndPutM32Inc(data
, 27); /* esh[3].sh_size */
11060 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
11061 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
11062 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
11063 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
11065 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
11066 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
11067 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
11068 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
11070 data
+= 4; /* esh[4].sh_offset */
11071 data
+= 4; /* esh[4].sh_size */
11072 EndPutM32Inc(data
, 3); /* esh[4].sh_link - the third entry is our string table */
11073 EndPutM32Inc(data
, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11074 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
11075 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11077 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
11078 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
11079 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11080 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11082 data
+= 4; /* esh[0].sh_offset */
11083 data
+= 4; /* esh[0].sh_size */
11084 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11085 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11086 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
11087 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11089 EndPutM32Inc(data2
, data
-tempbuf
);
11091 EndPutM32Inc(data
,0);
11092 EndPutM32Inc(data
,0); /* first entry is empty */
11093 EndPutM32Inc(data
,0);
11094 EndPutM32Inc(data
,0);
11096 symoffset
= 1; /* initial value */
11099 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCBias
))
11101 EndPutM32(data2
, elfbufpos
-data
+16);
11102 EndPutM32Inc(data3
, elfbufpos
-tempbuf
);
11103 EndPutM32(data3
, symoffset
);
11105 *(elfbufpos
++) = 0; /* first sym entry */
11106 if(!DoOutputDirect(tempbuf
, elfbufpos
-tempbuf
))
11109 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCName
))
11112 while((symoffset
++)&3)
11114 if(!DoOutputDirect("", 1))
11121 static uint32
CreateVBCCInline(uint32 mode
, uint32 callmode
)
11123 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11127 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11130 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11131 ShortBaseNameUpper
, ShortBaseNameUpper
);
11133 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11136 /* always include emul/emulregs.h in MorphOS inlines,
11137 gcc-based sources might depend on it :| */
11138 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11144 DoOutputDirect(HEADER
, headersize
);
11149 if(!CallFunc(callmode
, "/%s */\n", mode
? (mode
== 2 ? FuncVBCCMorphInline
11150 : FuncVBCCWOSInline
) : FuncVBCCInline
))
11153 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper
);
11156 static uint32
CreateVBCC(uint32 mode
, uint32 callmode
)
11160 if(mode
!= 2 && mode
!= 3)
11162 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11167 DoOutputDirect(HEADER
, headersize
);
11173 case 4: res
= CallFunc(callmode
, 0, FuncVBCCPUPText
); break;
11175 case 3: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11176 case 2: res
= CallFunc(callmode
, 0, FuncVBCCWOSCode
); break;
11178 case 1: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11179 case 0: res
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
); break;
11184 static uint32
CreateVBCCPUPLib(uint32 callmode
)
11186 /* output header */
11187 DoOutput("!<arch>\n");
11189 return CallFunc(callmode
, 0, FuncVBCCPUPCode
);
11192 static uint32
CreateVBCCMorphCode(uint32 callmode
)
11194 /* output header */
11195 DoOutput("!<arch>\n");
11197 return CallFunc(callmode
, 0, FuncVBCCMorphCode
);
11200 static uint32
CreateEModule(uint32 sorted
)
11204 DoError(ERR_NO_SORTED
, 0);
11207 DoOutputDirect("EMOD\0\x06", 6);
11208 for(res
= 0; res
< 2; ++res
)
11210 for(i
= 0; BaseName
[i
]; ++i
)
11211 DoOutput("%c", tolower(BaseName
[i
]));
11212 DoOutputDirect("\x00",1);
11214 LastBias
= BIAS_START
-BIAS_OFFSET
;
11215 CallFunc(TAGMODE_NORMAL
, 0, FuncEModule
);
11216 res
= DoOutputDirect("\xFF",1);
11221 static uint32
CreateProtoRedirect(void)
11223 Flags
|= FLAG_DONE
;
11224 return DoOutput("#ifdef NO_OBSOLETE\n"
11225 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11226 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName
);
11229 static uint32
CreateSFD(uint32 callmode
)
11231 struct Include
*inc
;
11232 struct AmiPragma
*ap
;
11235 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11238 if((ap
= (struct AmiPragma
*) AmiPragma
.First
))
11239 LastBias
= ap
->Bias
-BIAS_OFFSET
;
11240 else /* only security, never used normally */
11242 CurrentABI
= ABI_M68K
;
11245 DoOutput("==id %s\n", IDstring
);
11252 tim
= localtime(&t
);
11254 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11255 "noname Exp $\n", '$', filename
, tim
->tm_year
+1900, tim
->tm_mon
+1,
11256 tim
->tm_mday
, tim
->tm_hour
, tim
->tm_min
, tim
->tm_sec
);
11260 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11261 GetLibraryName(), BaseName
, GetBaseType(), GetLibraryName());
11262 DoOutput("==bias %ld\n==public\n", LastBias
+BIAS_OFFSET
);
11264 for(inc
= (struct Include
*) Includes
.First
; inc
; inc
= (struct Include
*) inc
->List
.Next
)
11265 DoOutput("==include %s\n", inc
->Include
);
11266 if(!Includes
.First
)
11267 DoOutput("==include <exec/types.h>\n");
11269 CallFunc(callmode
, "%s\n", FuncSFD
);
11271 return DoOutput("==end\n");
11274 static uint32
CreateClib(uint32 callmode
)
11278 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11281 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11283 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper
,
11284 ShortBaseNameUpper
);
11289 DoOutputDirect(HEADER
, headersize
);
11298 tim
= localtime(&t
);
11302 s
= SkipBlanks(IDstring
+4);
11303 while(*s
&& *s
!= ' ')
11310 if(Flags2
& FLAG2_SYSTEMRELEASE
)
11312 DoOutput("\n/*\n**\t$Id: %s %s\n", filename
, s
);
11319 while(*t
&& *t
!= ' ')
11323 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename
, s
,
11324 tim
->tm_mday
, tim
->tm_mon
+1, tim
->tm_year
+1900);
11326 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11327 if(!Copyright
|| (Copyright
&& strncmp("Copyright ", Copyright
, 10)))
11328 DoOutput("Copyright © %d ", tim
->tm_year
+1900);
11329 DoOutput("%s\n", Copyright
? Copyright
: Flags2
& FLAG2_SYSTEMRELEASE
?
11330 "Amiga, Inc." : "");
11331 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11336 if((Flags
& FLAG_EXTERNC
) &&
11337 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11340 CallFunc(callmode
, "\n/%s */\n\n", FuncClib
);
11342 if((Flags
& FLAG_EXTERNC
) &&
11343 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11346 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper
);
11349 static uint32
CreateFD(void)
11352 CurrentABI
= ABI_M68K
;
11355 DoOutput("##base _%s\n", BaseName
);
11356 DoOutput("##public\n");
11358 CallFunc(TAGMODE_NORMAL
, "%s\n", FuncFD
);
11360 return DoOutput("##end\n");
11363 static uint32
CreateGenAuto(strptr to
, uint32 type
)
11365 strptr name
, btype
;
11367 uint32 i
, verref
, exitfuncref
, sysref2
, exitref
, rel1
, rel2
, nameref
;
11368 if(!(name
= GetLibraryName()))
11370 btype
= GetBaseType();
11375 Flags
|= FLAG_DONE
;
11376 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11377 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11378 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11379 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11380 btype
, BaseName
, BaseName
,
11381 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", name
, BaseName
,
11382 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", BaseName
)))
11384 sprintf(filename
, "%s_autoopenver.c", ShortBaseName
);
11385 if(!CloseDest(to
) || !OpenDest(filename
))
11387 Flags
|= FLAG_DONE
;
11388 return DoOutput("unsigned long _%sVer = 0;\n", BaseName
);
11391 Flags
|= FLAG_DONE
;
11392 i
= strlen(filename
)-4; /* remove .lib extension */
11393 EndPutM32(tempbuf
, HUNK_UNIT
);
11394 EndPutM32(tempbuf
+4, (i
+3)>>2);
11395 DoOutputDirect(tempbuf
, 8);
11396 DoOutputDirect(filename
, i
);
11397 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11399 i
= strlen(hunkname
);
11400 EndPutM32(tempbuf
, HUNK_NAME
);
11401 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11402 DoOutputDirect(tempbuf
, 8);
11403 DoOutputDirect(hunkname
, i
);
11404 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11406 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
11407 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11409 if(Flags
& FLAG_SMALLDATA
)
11411 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11412 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11416 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11417 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11419 verref
= data
-tempbuf
-8+2;
11420 if(Flags
& FLAG_SMALLDATA
)
11422 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11423 EndPutM16Inc(data
, 0); /* place for basevers reference */
11427 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11428 EndPutM32Inc(data
, 0); /* place for basevers reference */
11430 EndPutM32Inc(data
, 0x43FA0030 + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2) + ((Flags
& FLAG_SMALLDATA
) ? 0 : 6));
11431 EndPutM32Inc(data
, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11433 rel1
= data
-tempbuf
-8+2;
11434 if(Flags
& FLAG_SMALLDATA
)
11436 EndPutM16Inc(data
, 0x2940); /* MOVE.L D0,xxx(A4) */
11437 EndPutM16Inc(data
, 0);
11441 EndPutM16Inc(data
, 0x23C0); /* MOVE.L D0,xxx */
11442 EndPutM32Inc(data
, 0);
11444 EndPutM16Inc(data
, 0x660A + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2)); /* BNE.B .lib */
11445 EndPutM32Inc(data
, 0x48780014); /* PEA 20 */
11447 exitfuncref
= data
-tempbuf
-8+2;
11448 if(Flags2
& FLAG2_SMALLCODE
)
11450 EndPutM16Inc(data
, 0x4EBA); /* JSR _exit(PC) */
11451 EndPutM16Inc(data
, 0); /* place for base reference */
11455 EndPutM16Inc(data
, 0x4EB9); /* JSR _exit */
11456 EndPutM32Inc(data
, 0); /* place for base reference */
11458 EndPutM16Inc(data
, 0x584F); /* ADDQ.W, #4,A7 */
11459 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11460 EndPutM16Inc(data
,0x4E75); /* RTS */
11461 exitref
= data
-tempbuf
-8;
11463 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11464 sysref2
= data
-tempbuf
-8+2;
11466 if(Flags
& FLAG_SMALLDATA
)
11468 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11469 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11473 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11474 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11476 rel2
= data
-tempbuf
-8+2;
11477 if(Flags
& FLAG_SMALLDATA
)
11479 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11480 EndPutM16Inc(data
, 0); /* place for base reference */
11484 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11485 EndPutM32Inc(data
, 0); /* place for base reference */
11487 EndPutM16Inc(data
, 0x6606); /* BNE.B .nolib */
11488 EndPutM16Inc(data
, 0x2240); /* MOVEA.L D0,A1 */
11490 EndPutM32Inc(data
, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11491 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11492 EndPutM16Inc(data
,0x4E75); /* RTS */
11493 nameref
= data
-tempbuf
-8;
11494 memcpy(data
, name
, strlen(name
));
11495 data
+= strlen(name
);
11496 do { *(data
++) = 0; } while((data
-tempbuf
)&3);
11498 EndPutM32(tempbuf
, HUNK_CODE
);
11499 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
11500 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
11502 if(Flags
& FLAG_SMALLDATA
)
11504 EndPutM32(tempbuf
, HUNK_DREL16
);
11508 EndPutM32(tempbuf
, HUNK_ABSRELOC32
);
11510 EndPutM32(tempbuf
+4, 2); /* 2 entries */
11511 EndPutM32(tempbuf
+8, 1); /* to hunk 1 */
11512 EndPutM32(tempbuf
+12, rel1
); /* address 0 */
11513 EndPutM32(tempbuf
+16, rel2
); /* address 0 */
11514 EndPutM32(tempbuf
+20, 0); /* end of reloc hunk */
11515 DoOutputDirect(tempbuf
, 24);
11517 /* extern references */
11518 EndPutM32(tempbuf
, HUNK_EXT
);
11519 DoOutputDirect(tempbuf
, 4);
11521 OutputXREF2(4, sysref2
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "_SysBase");
11522 OutputXREF(verref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "__%sVer", BaseName
);
11523 OutputXREF(exitfuncref
, (Flags2
& FLAG2_SMALLCODE
? EXT_DEXT16
: EXT_REF32
), "_exit");
11524 OutputXDEF(0, "__INIT_%ld_%s", priority
, BaseName
);
11525 OutputXDEF(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11526 OutputXDEF(nameref
, "%sname", ShortBaseName
);
11527 EndPutM32(tempbuf
, 0); /* ext end */
11528 DoOutputDirect(tempbuf
, 4);
11530 if(!(Flags
& FLAG_NOSYMBOL
))
11532 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11533 DoOutputDirect(tempbuf
, 4);
11534 OutputSYMBOL(0, "__INIT_%ld_%s", priority
, BaseName
);
11535 OutputSYMBOL(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11536 OutputSYMBOL(nameref
, "%sname", ShortBaseName
);
11537 EndPutM32(tempbuf
, 0);
11538 DoOutputDirect(tempbuf
, 4);
11541 EndPutM32(tempbuf
, HUNK_END
);
11542 DoOutputDirect(tempbuf
, 4);
11544 i
= strlen(datahunkname
);
11545 EndPutM32(tempbuf
, HUNK_NAME
);
11546 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11547 DoOutputDirect(tempbuf
, 8);
11548 DoOutputDirect(datahunkname
, i
);
11549 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11551 EndPutM32(tempbuf
, HUNK_BSS
);
11552 EndPutM32(tempbuf
+4, 1);
11553 DoOutputDirect(tempbuf
, 8);
11555 EndPutM32(tempbuf
, HUNK_EXT
);
11556 DoOutputDirect(tempbuf
, 4);
11557 OutputXDEF(0, "_%s", BaseName
);
11558 EndPutM32(tempbuf
, 0); /* ext end */
11559 DoOutputDirect(tempbuf
, 4);
11561 if(!(Flags
& FLAG_NOSYMBOL
))
11563 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11564 DoOutputDirect(tempbuf
, 4);
11565 OutputSYMBOL(0, "_%s", BaseName
);
11566 EndPutM32(tempbuf
, 0);
11567 DoOutputDirect(tempbuf
, 4);
11570 EndPutM32(tempbuf
, HUNK_END
);
11571 DoOutputDirect(tempbuf
, 4);
11573 sprintf(filename
, "%s_autoopenver", ShortBaseName
);
11574 i
= strlen(filename
);
11575 EndPutM32(tempbuf
, HUNK_UNIT
);
11576 EndPutM32(tempbuf
+4, (i
+3)>>2);
11577 DoOutputDirect(tempbuf
, 8);
11578 DoOutputDirect(filename
, i
);
11579 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11581 i
= strlen(datahunkname
);
11582 EndPutM32(tempbuf
, HUNK_NAME
);
11583 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11584 DoOutputDirect(tempbuf
, 8);
11585 DoOutputDirect(datahunkname
, i
);
11586 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11588 EndPutM32(tempbuf
, HUNK_BSS
);
11589 EndPutM32(tempbuf
+4, 1);
11590 DoOutputDirect(tempbuf
, 8);
11592 EndPutM32(tempbuf
, HUNK_EXT
);
11593 DoOutputDirect(tempbuf
, 4);
11594 OutputXDEF(0, "_%sVer", BaseName
);
11595 EndPutM32(tempbuf
, 0); /* ext end */
11596 DoOutputDirect(tempbuf
, 4);
11598 if(!(Flags
& FLAG_NOSYMBOL
))
11600 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11601 DoOutputDirect(tempbuf
, 4);
11602 OutputSYMBOL(0, "_%sVer", BaseName
);
11603 EndPutM32(tempbuf
, 0);
11604 DoOutputDirect(tempbuf
, 4);
11607 EndPutM32(tempbuf
, HUNK_END
);
11608 return DoOutputDirect(tempbuf
, 4);
11615 static uint32
CreateXML(void)
11617 struct Include
*inc
;
11621 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11622 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11623 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11624 ShortBaseName
, BaseName
, GetLibraryName());
11625 if(GetBaseTypeLib() != "Library")
11626 DoOutput(" basetype=\"%s\"", GetBaseTypeLib());
11628 for(inc
= (struct Include
*) Includes
.First
; inc
;
11629 inc
= (struct Include
*) inc
->List
.Next
)
11630 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc
->Include
)-2),
11632 if(!Includes
.First
)
11633 DoOutput("\t<include>exec/types.h</include>\n");
11635 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11636 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11637 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11639 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11640 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11641 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11642 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11643 " status=\"unimplemented\"/>\n");
11645 CallFunc(TAGMODE_BOTH
, 0, FuncXML
);
11647 return DoOutput("\t</interface>\n</library>\n");
11650 static uint32
CreateOS4PPC(uint32 callmode
)
11652 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11657 DoOutputDirect(HEADER
, headersize
);
11663 "#include <stdarg.h>\n"
11664 "#include <exec/types.h>\n"
11665 "#include <exec/interfaces.h>\n"
11666 "#include <exec/emulation.h>\n"
11667 "#include <interfaces/exec.h>\n");
11669 if(!stricmp("exec",ShortBaseName
))
11670 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName
);
11672 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName
);
11674 CallFunc(callmode
, "\n/%s */\n\n", FuncOS4PPC
);
11677 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11678 " return Self->Data.RefCount++;\n}\n\n"
11679 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11680 " return Self->Data.RefCount--;\n}\n\n"
11681 "#define LIBNAME \"%s\"\n"
11682 "#define LIBVERSION 0\n"
11683 "#define IFACENAME \"%s.main\"\n\n",
11684 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11685 GetLibraryName(), GetLibraryName());
11687 /* following text is constant */
11689 "static void InitFunction(APTR dummy, ULONG SegList, "
11690 "struct ExecBase *ExecBase)\n{\n"
11691 " struct Library *LibBase;\n"
11692 " struct ExecIFace *IExec = (struct ExecIFace *)"
11693 "ExecBase->MainInterface;\n"
11694 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11696 " struct Interface *NewInterface;\n"
11697 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11698 " MIT_VectorTable, main_vectors,\n"
11699 " MIT_Version, 1,\n"
11700 " MIT_Name, IFACENAME,\n"
11703 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11704 " IExec->AddInterface(LibBase, NewInterface);\n"
11708 "volatile static struct Resident MyResident =\n{\n"
11709 " RTC_MATCHWORD,\n"
11710 " (struct Resident *)&MyResident,\n"
11711 " (APTR)(&MyResident+1),\n"
11720 "void _start(void)\n"
11721 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11725 static uint32
CreateOS4M68K(void)
11727 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11732 DoOutputDirect(HEADER
, headersize
);
11735 "#include \"exec/interfaces.i\"\n"
11736 "#include \"exec/libraries.i\"\n"
11737 "#include \"exec/emulation.i\"\n"
11738 "#include \"interfaces/%s.i\"\n\n",ShortBaseName
);
11741 "\t.section .data\n"
11742 "\t.globl\tstub_Open\n"
11743 "\t.type\tstub_Open,@function\n"
11746 "\t.short\t0x4ef8\n" /* JMP.w */
11747 "\t.short\t0\n" /* Indicate switch */
11748 "\t.short\t1\n" /* Trap type */
11749 "\t.globl\tstub_OpenPPC\n"
11750 "\t.long\tstub_OpenPPC\n"
11751 "\t.byte\t2\n" /* Register mapping */
11752 "\t.byte\t1,REG68K_A7\n"
11753 "\t.byte\t3,REG68K_A6\n"
11754 "\t.section .text\n"
11758 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11759 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11760 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11761 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11762 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11763 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11764 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11765 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11766 "\tCallLib\tlmi_Open\n"
11767 "\tlwz\t%s11,%s12(%s1)\n"
11769 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11770 "\tblrl\n" /* Return to emulation */
11772 "\t.globl\tstub_Open68K\n"
11773 "\t.long\tstub_Open68K\n"
11774 "\t.byte\t0\n" /* Flags */
11775 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11776 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11777 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11778 "\t.section .data\n"
11782 "\t.short\t0x4e75\n" /* RTS */
11784 "\t.section .data\n"
11785 "\t.globl\tstub_Close\n"
11786 "\t.type\tstub_Close,@function\n"
11789 "\t.short\t0x4ef8\n" /* JMP.w */
11790 "\t.short\t0\n" /* Indicate switch */
11791 "\t.short\t1\n" /* Trap type */
11792 "\t.globl\tstub_ClosePPC\n"
11793 "\t.long\tstub_ClosePPC\n"
11794 "\t.byte\t2\n" /* Register mapping */
11795 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11796 "\t.byte\t3,REG68K_A6\n"
11797 "\t.section .text\n"
11801 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11802 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11803 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11804 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11805 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11806 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11807 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11808 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11809 "\tCallLib\tlmi_Close\n"
11810 "\tlwz\t%s11,12(%s1)\n"
11812 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11813 "\tblrl\n" /* Return to emulation */
11815 "\t.globl\tstub_Close68K\n"
11816 "\t.long\tstub_Close68K\n"
11817 "\t.byte\t0\n" /* Flags */
11818 "\t.byte\t1\n" /* One register (a7 only) */
11819 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11820 "\t.section .data\n"
11824 "\t.short\t0x4e75\n" /* RTS */
11826 "\t.section .data\n"
11827 "\t.globl\tstub_Expunge\n"
11828 "\t.type\tstub_Expunge,@function\n"
11831 "\t.short\t0x7000\n" /* moveq #0, d0 */
11832 "\t.short\t0x4e75\n" /* RTS */
11834 "\t.section .data\n"
11835 "\t.globl\tstub_Reserved\n"
11836 "\t.type\tstub_Reserved,@function\n"
11839 "\t.short\t0x7000\n" /* moveq #0, d0 */
11840 "\t.short\t0x4e75\n\n", /* RTS */
11841 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11842 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11843 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11844 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11845 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11846 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11847 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11848 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11849 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
11851 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68K
);
11853 "\t.globl\tVector68K\n"
11854 "\t.globl\tVecTable68K\n"
11856 "\t.long\tVecTable68K\n"
11858 "\t.long\tstub_Open\n"
11859 "\t.long\tstub_Close\n"
11860 "\t.long\tstub_Expunge\n"
11861 "\t.long\tstub_Reserved\n");
11864 CallFunc(TAGMODE_NORMAL
, 0, FuncOS4M68KVect
);
11865 DoOutput("\t.long\t-1\n");
11867 CloseDest(filename
);
11869 if(Flags2
& FLAG2_OS4M68KCSTUB
)
11871 sprintf(filename
, "%s_68k.c", ShortBaseName
);
11872 if(!OpenDest(filename
))
11874 Flags
&= ~(FLAG_DONE
);
11875 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11880 DoOutputDirect(HEADER
, headersize
);
11884 "#ifdef __USE_INLINE__\n"
11885 "#undef __USE_INLINE__\n"
11887 "#ifndef __NOGLOBALIFACE__\n"
11888 "#define __NOGLOBALIFACE__\n"
11890 "#include <exec/interfaces.h>\n"
11891 "#include <exec/libraries.h>\n"
11892 "#include <exec/emulation.h>\n"
11893 "#include <interfaces/exec.h>\n"
11894 "#include <interfaces/%s.h>\n"
11895 "#include <proto/%s.h>\n\n", ShortBaseName
, ShortBaseName
);
11897 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68KCSTUB
);
11899 return Output_Error
;
11902 /* ------------------------------------------------------------------ */
11904 static uint32
GetName(struct NameList
*t
, struct ShortListRoot
*p
, uint32 args
)
11906 struct NameList
*p2
= (struct NameList
*) p
->First
;
11907 struct AmiPragma ap
;
11908 memset(&ap
, 0, sizeof(struct AmiPragma
));
11909 ap
.FuncName
= t
->NormName
;
11912 ap
.Args
[0].ArgName
= (args
? "args" : "tags");
11913 if(!MakeTagFunction(&ap
))
11919 while(p2
&& (!p2
->PragName
|| strcmp(p2
->PragName
, ap
.TagName
)))
11920 p2
= (struct NameList
*) p2
->List
.Next
;
11925 t
->Type
= (args
? NTP_ARGS
: NTP_TAGS
);
11926 t
->PragName
= ap
.TagName
;
11927 RemoveItem(p
, (struct ShortList
*) p2
);
11930 printf("GetName: name matches - %s _ %s\n", t
->NormName
, t
->PragName
);
11936 static void OptimizeFDData(struct PragData
*pd
)
11939 printf("OptimizeFDData\n");
11944 if(pd
->NumNames
> 1)
11946 struct ShortListRoot n
= {0,0,0}, p
= {0,0,0};
11947 struct NameList
*t
;
11948 while(pd
->Name
.First
) /* sorts in AmiCall and TagCall */
11950 t
= (struct NameList
*) pd
->Name
.First
;
11952 RemoveItem(&pd
->Name
, (struct ShortList
*) t
);
11953 AddItem(t
->PragName
? &p
: &n
, (struct ShortList
*) t
);
11958 t
= (struct NameList
*) n
.First
;
11959 while(p
.First
&& t
)
11961 if(!GetName(t
, &p
, 0))
11967 struct NameList
*t2
= (struct NameList
*) t
->List
.Next
;
11968 RemoveItem(&n
, (struct ShortList
*)t
);
11969 AddItem(&pd
->Name
, (struct ShortList
*) t
);
11973 t
= (struct NameList
*) t
->List
.Next
;
11979 t
= (struct NameList
*) n
.First
;
11980 t
->PragName
= ((struct NameList
*)(p
.First
))->PragName
;
11981 RemoveItem(&n
, (struct ShortList
*) t
);
11983 printf("OptimizeFDData: names together - %s _ %s\n", t
->NormName
, t
->PragName
);
11985 t
->Type
= NTP_UNKNOWN
;
11991 t
= (struct NameList
*) p
.First
;
11992 i
= strlen(t
->PragName
);
11993 t
->NormName
= DupString(t
->PragName
, i
+1);
11994 t
->NormName
[i
++] = 'A';
11995 t
->NormName
[i
] = 0;
11996 t
->Type
= NTP_TAGS
;
11998 printf("OptimizeFDData: NormName created - %s _ %s\n", t
->NormName
, t
->PragName
);
12002 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12003 RemoveItem(&p
, p
.First
);
12007 AddItem(&pd
->Name
, n
.First
); /* add left NormNames */
12009 pd
= (struct PragData
*) pd
->List
.Next
;
12013 static uint32
MakeFD(struct PragList
*pl
)
12015 struct PragData
*pd
= (struct PragData
*) pl
->Data
.First
;
12019 printf("MakeFD\n");
12023 OptimizeFDData(pd
);
12025 printf("MakeFD: after Optimizing\n");
12027 DoOutput("##base _%s\n##bias %ld\n##public\n", pl
->Basename
, bias
);
12029 while(pd
&& Output_Error
)
12031 struct NameList
*n
= (struct NameList
*) pd
->Name
.First
;
12033 if(bias
!= pd
->Bias
)
12034 DoOutput("##bias %ld\n", (bias
= pd
->Bias
));
12038 strptr lastpar
= "last";
12041 if(n
->Type
== NTP_TAGS
)
12043 else if(n
->Type
== NTP_ARGS
)
12046 DoOutput("%s("/*)*/,n
->NormName
);
12048 DoOutput(/*(*/")()\n");
12051 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12052 DoOutput("par%ld,",i
+1);
12053 DoOutput(/*(*/"%s)("/*)*/, lastpar
);
12054 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12055 DoOutput("%s,", RegNames
[pd
->ArgReg
[i
]]);
12056 DoOutput(/*(*/"%s)\n", RegNames
[pd
->ArgReg
[i
]]);
12058 if(n
->Type
== NTP_UNKNOWN
)
12061 for(i
= 0; n
->NormName
[i
] == n
->PragName
[i
]; ++i
)
12063 DoOutput("*tagcall");
12065 DoOutput("-%s", n
->NormName
+i
);
12067 DoOutput("+%s", n
->PragName
+i
);
12072 if((n
= (struct NameList
*) n
->List
.Next
))
12073 DoOutput("##bias %ld\n", pd
->Bias
);
12074 Flags
|= FLAG_DONE
;
12077 pd
= (struct PragData
*)pd
->List
.Next
; bias
+= BIAS_OFFSET
;
12080 DoOutput("##end\n");
12082 return Output_Error
;
12085 static uint32
AddFDData(struct ShortListRoot
*pls
, struct FDData
*fd
)
12087 struct NameList
*t
;
12088 struct PragList
*pl
= (struct PragList
*) pls
->First
;
12089 struct PragData
*pd
;
12091 while(pl
&& strcmp(pl
->Basename
, fd
->Basename
))
12092 pl
= (struct PragList
*) pl
->List
.Next
;
12097 printf("AddFDData: New PragList - %s\n", fd
->Basename
);
12099 if(!(pl
= (struct PragList
*) NewItem(pls
)))
12101 pl
->Basename
= fd
->Basename
;
12102 pl
->Data
.Size
= sizeof(struct PragData
);
12103 AddItem(pls
, (struct ShortList
*) pl
);
12106 if((pd
= (struct PragData
*) pl
->Data
.First
))
12108 while(pd
->List
.Next
&& ((struct PragData
*) pd
->List
.Next
)->Bias
12110 pd
= (struct PragData
*) pd
->List
.Next
;
12113 if(!pd
|| pd
->Bias
!= fd
->Bias
)
12115 struct PragData
*pd2
;
12117 printf("AddFDData: New PragData - %ld, %ld\n", fd
->Bias
, fd
->NumArgs
);
12119 if(!(pd2
= (struct PragData
*) NewItem(&pl
->Data
)))
12121 pd2
->Bias
= fd
->Bias
;
12122 memcpy(pd2
->ArgReg
, fd
->ArgReg
, MAXREG
);
12123 pd2
->NumArgs
= fd
->NumArgs
;
12124 pd2
->Name
.Size
= sizeof(struct NameList
);
12126 AddItem(&pl
->Data
, (struct ShortList
*) pd2
);
12127 else if(pd
->Bias
> fd
->Bias
) /* Insert at start */
12129 pd2
->List
.Next
= pl
->Data
.First
;
12130 pl
->Data
.First
= (struct ShortList
*) pd2
;
12132 else /* Insert the entry */
12134 pd2
->List
.Next
= pd
->List
.Next
;
12135 pd
->List
.Next
= (struct ShortList
*) pd2
;
12141 uint32 i
= fd
->NumArgs
;
12142 if(fd
->NumArgs
!= pd
->NumArgs
)
12145 printf("ArgNum %ld != %ld\n", fd
->NumArgs
, pd
->NumArgs
);
12147 return ERR_DIFFERENT_TO_PREVIOUS
;
12152 if(fd
->ArgReg
[i
] != pd
->ArgReg
[i
])
12155 printf("ArgReg %x != %x\n", fd
->ArgReg
[i
], pd
->ArgReg
[i
]);
12157 return ERR_DIFFERENT_TO_PREVIOUS
;
12162 t
= (struct NameList
*) pd
->Name
.First
; /* skips same names */
12163 while(t
&& (!(fd
->Mode
? t
->PragName
: t
->NormName
) ||
12164 strcmp(fd
->Name
, fd
->Mode
? t
->PragName
: t
->NormName
)))
12165 t
= (struct NameList
*) t
->List
.Next
;
12170 if(!(t
= (struct NameList
*) NewItem(&pd
->Name
)))
12173 t
->PragName
= fd
->Name
;
12175 t
->NormName
= fd
->Name
;
12176 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12179 printf("AddFDData: New NameList - %s\n", fd
->Name
);
12184 static string
GetHexValue(string data
)
12187 return (string
) (data
- 'a' + 10);
12188 else if(data
>= 'A')
12189 return (string
) (data
- 'A' + 10);
12191 return (string
) (data
- '0');
12194 static string
GetDoubleHexValue(strptr data
)
12196 return (string
)((GetHexValue(*data
)<<4)+GetHexValue(data
[1]));
12199 static uint32
GetLibData(struct FDData
*fd
)
12202 fd
->Name
= SkipBlanks(in
.pos
);
12203 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12204 in
.pos
= SkipBlanks(in
.pos
);
12205 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12206 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
)));
12207 if((fd
->NumArgs
= GetHexValue(*(--in
.pos
))) > MAXREGNF
- 2)
12208 return ERR_TO_MUCH_ARGUMENTS
;
12209 --in
.pos
; /* skips return register */
12210 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12212 if((fd
->ArgReg
[i
] = GetHexValue(*(--in
.pos
))) > REG_A5
)
12213 return ERR_EXPECTED_REGISTER_NAME
;
12218 static uint32
GetFlibData(struct FDData
*fd
)
12221 fd
->Name
= SkipBlanks(in
.pos
);
12222 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12223 in
.pos
= SkipBlanks(in
.pos
);
12224 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12225 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
))) - 2;
12226 if((fd
->NumArgs
= GetDoubleHexValue(in
.pos
)) > MAXREG
-2)
12227 return ERR_TO_MUCH_ARGUMENTS
;
12228 in
.pos
-= 2; /* skips return register */
12229 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12232 if((fd
->ArgReg
[i
] = GetDoubleHexValue(in
.pos
)) >= MAXREG
)
12233 return ERR_EXPECTED_REGISTER_NAME
;
12234 else if(fd
->ArgReg
[i
] >= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12235 return ERR_FLOATARG_NOT_ALLOWED
;
12240 static uint32
GetAmiData(struct FDData
*fd
)
12243 in
.pos
= SkipBlanks(in
.pos
);
12244 if(*in
.pos
!= '('/*)*/)
12245 return ERR_EXPECTED_OPEN_BRACKET
;
12246 fd
->Basename
= ++in
.pos
;
12247 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12249 return ERR_EXPECTED_COMMA
;
12251 in
.pos
= SkipBlanks(++in
.pos
);
12252 if(!strncmp(in
.pos
, "0x", 2))
12253 fd
->Bias
= strtoul(in
.pos
+2, 0, 16);
12255 fd
->Bias
= strtoul(in
.pos
, 0, 10);
12257 in
.pos
= SkipBlanks(SkipName(in
.pos
));
12259 return ERR_EXPECTED_COMMA
;
12260 fd
->Name
= in
.pos
= SkipBlanks(++in
.pos
);
12261 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12262 if(*in
.pos
!= '('/*)*/)
12263 return ERR_EXPECTED_OPEN_BRACKET
;
12265 in
.pos
= SkipBlanks(++in
.pos
);
12266 if(*in
.pos
== /*(*/')')
12269 while(*in
.pos
!= /*(*/')')
12272 in
.pos
= SkipBlanks(in
.pos
+1);
12274 for(i
= 0; i
< REG_FP0
; i
++)
12275 if(!strnicmp(RegNames
[i
], in
.pos
, 2))
12279 for(; i
< MAXREG
; i
++)
12280 if(!strnicmp(RegNames
[i
], in
.pos
, 3))
12285 return ERR_EXPECTED_REGISTER_NAME
;
12286 else if(i
>= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12287 return ERR_FLOATARG_NOT_ALLOWED
;
12289 fd
->ArgReg
[fd
->NumArgs
] = i
; ++fd
->NumArgs
;
12291 if(fd
->NumArgs
> MAXREG
-2)
12292 return ERR_TO_MUCH_ARGUMENTS
;
12294 in
.pos
= SkipBlanks(in
.pos
+(i
>= REG_FP0
? 3 : 2));
12296 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
12297 return ERR_EXPECTED_CLOSE_BRACKET
;
12299 in
.pos
= SkipBlanks(in
.pos
+1);
12300 if(*in
.pos
!= /*(*/')')
12301 return ERR_EXPECTED_CLOSE_BRACKET
;
12305 static uint32
CreateFDFile(void)
12307 struct ShortListRoot pl
= {0, 0, sizeof(struct PragList
)};
12308 uint32 linenum
, err
= 0, skip
;
12311 ptr
= p2
= args
.infile
;
12314 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
12318 for(p2
= ptr
; *p2
&& *p2
!= '_' && *p2
!= '.'; ++p2
)
12322 ShortBaseName
= ptr
;
12326 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
12328 in
.pos
= SkipBlanks(in
.pos
);
12329 if(!strncmp("#pragma", in
.pos
, 7))
12334 memset(&fd
, 0, sizeof(struct FDData
));
12336 in
.pos
= SkipBlanks(in
.pos
+7);
12337 if(!strncmp("tagcall", in
.pos
, 7))
12340 in
.pos
= SkipBlanks(in
.pos
+7);
12341 if(*in
.pos
== '(' /*)*/) /* Storm method */
12342 err
= GetAmiData(&fd
);
12343 else /* SAS method */
12345 fd
.Basename
= in
.pos
;
12346 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12347 err
= GetLibData(&fd
);
12350 else if(!strncmp("amicall", in
.pos
, 7)) /* Storm method */
12353 err
= GetAmiData(&fd
);
12355 else if(!strncmp("libcall", in
.pos
, 7)) /* SAS method */
12357 fd
.Basename
= SkipBlanks(in
.pos
+7);
12358 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12359 err
= GetLibData(&fd
);
12361 else if(!strncmp("flibcall", in
.pos
, 8)) /* SAS method */
12363 fd
.Basename
= SkipBlanks(in
.pos
+8);
12364 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12365 err
= GetFlibData(&fd
);
12367 else if(!strncmp("syscall", in
.pos
, 7)) /* SAS method */
12369 fd
.Basename
= "SysBase";
12370 err
= GetLibData(&fd
);
12376 DoError(err
, linenum
);
12379 else if((err
= AddFDData(&pl
, &fd
)))
12382 DoError(err
, linenum
);
12386 while(*(in
.pos
++)) /* jumps to first char of next line */
12392 struct PragList
*p
= (struct PragList
*) pl
.First
;
12400 text
= ShortBaseName
; i
= strlen(text
);
12404 text
= p
->Basename
; i
= strlen(text
)-4;
12407 to
= DupString(text
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12408 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12423 i
= strlen(p
->Basename
) - 4;
12424 to
= DupString(p
->Basename
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12425 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12432 p
= (struct PragList
*) p
->List
.Next
;
12440 #ifdef FD2PRAGMA_READARGS
12441 #include <proto/dos.h>
12443 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12444 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12445 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12446 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12447 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12449 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12450 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12451 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12452 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12480 uint32 NOPPCREGNAME
;
12491 uint32 SYSTEMRELEASE
;
12496 static const strptr helptext
=
12497 "INFILE: the input file which should be used\n"
12498 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12499 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12500 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12501 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12502 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12503 "\t 6 - pragma for all compilers [default]\n"
12504 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12505 "\t10 - stub-functions for C - C text\n"
12506 "\t11 - stub-functions for C - assembler text\n"
12507 "\t12 - stub-functions for C - link library\n"
12508 "\t13 - defines and link library for local library base (register call)\n"
12509 "\t14 - defines and link library for local library base (stack call)\n"
12510 "\t15 - stub-functions for Pascal - assembler text\n"
12511 "\t16 - stub-functions for Pascal - link library\n"
12512 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12513 "\t18 - module for AmigaE\n"
12514 "\t20 - assembler lvo _lvo.i file\n"
12515 "\t21 - assembler lvo _lib.i file\n"
12516 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12517 "\t23 - assembler lvo _lib.i file no XDEF\n"
12518 "\t24 - assembler lvo link library\n"
12519 "\t30 - proto file with pragma/..._lib.h call\n"
12520 "\t31 - proto file with pragma/..._pragmas.h call\n"
12521 "\t32 - proto file with pragmas/..._lib.h call\n"
12522 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12523 "\t34 - proto file with local/..._loc.h call\n"
12524 "\t35 - proto file for all compilers (VBCC stubs)\n"
12525 "\t36 - proto file for GNU-C compiler only\n"
12526 "\t37 - proto file without lib definitions\n"
12527 "\t38 - proto file for all compilers (VBCC inline)\n"
12528 "\t39 - proto file with special PPC related checks\n"
12529 "\t40 - GCC inline file (preprocessor based)\n"
12530 "\t41 - GCC inline file (old type - inline based)\n"
12531 "\t42 - GCC inline file (library stubs)\n"
12532 "\t43 - GCC inline file (new style - macro)\n"
12533 "\t44 - GCC inline file (new style - inline)\n"
12534 "\t45 - GCC inline file (new style - inline with include lines)\n"
12535 "\t46 - GCC inline file (preprocessor based, direct)\n"
12536 "\t47 - GCC inline file (new style, direct)\n"
12537 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12538 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12539 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12540 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12541 "\t53 - SAS-C include file for PowerUP\n"
12542 "\t54 - Proto file for PowerUP\n"
12543 "\t60 - FPC pascal unit text\n"
12544 "\t70 - VBCC inline files\n"
12545 "\t71 - VBCC WOS stub-functions - assembler text\n"
12546 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12547 "\t73 - VBCC WOS stub-functions - link library\n"
12548 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12549 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12550 "\t76 - VBCC PowerUP stub-functions - link library\n"
12551 "\t77 - VBCC WOS inline files\n"
12552 "\t78 - VBCC MorphOS stub-functions - link library\n"
12553 "\t79 - VBCC old inline files\n"
12554 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12555 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12556 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12557 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12558 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12559 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12560 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12561 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12562 " 100 - PPC assembler lvo file\n"
12563 " 101 - PPC assembler lvo file no XDEF\n"
12564 " 102 - PPC assembler lvo ELF link library\n"
12565 " 103 - PPC assembler lvo EHF link library\n"
12566 " 104 - PPC V.4-ABI assembler file\n"
12567 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12568 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12569 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12571 " 111 - CLIB file\n"
12572 " 112 - SFD file\n"
12573 " 120 - VBCC auto libopen files (C source)\n"
12574 " 121 - VBCC auto libopen files (m68k link library)\n"
12575 " 122 - VBCC MorphOS inline files\n"
12576 " 123 - VBCC new MorphOS inline files\n"
12577 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12578 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12579 " 132 - GCC inline files for MorphOS (library stubs)\n"
12580 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12581 " 134 - MorphOS gate stubs\n"
12582 " 135 - MorphOS gate stubs (prelib)\n"
12583 " 136 - MorphOS gate stubs (postlib)\n"
12584 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12585 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12586 " 140 - OS4 XML file\n"
12587 " 141 - OS4 PPC->M68K cross-call stubs\n"
12588 " 142 - OS4 M68K->PPC cross-call stubs\n"
12589 " 200 - FD file (source is a pragma file!)\n"
12590 "MODE: SPECIAL 1-7:\n"
12591 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12592 " 2: _PRAGMAS_..._LIB_H definition method\n"
12593 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12594 " 4: no definition\n"
12595 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12597 " 1: all functions, normal interface\n"
12598 " 2: only tag-functions, tagcall interface\n"
12599 " 3: all functions, normal and tagcall interface [default]\n"
12600 "TO: the destination directory (self creation of filename)\n"
12601 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12602 "CLIB: name of the prototypes file in clib directory\n"
12603 "COPYRIGHT: the copyright text for CLIB files\n"
12604 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12605 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12606 "BASENAME: name of library base without '_'\n"
12607 "LIBNAME: name of the library (.e.g. dos.library)\n"
12608 "LIBTYPE: type of base library structure\n"
12609 "PRIORITY: priority for auto open files\n"
12610 "PREFIX: MorphOS gate prefix\n"
12611 "SUBPREFIX: MorphOS gate sub prefix\n"
12612 "PREMACRO: MorphOS gate file start macro\n"
12614 "AUTOHEADER add the typical automatic generated header\n"
12615 "COMMENT: copy comments found in input file\n"
12616 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12617 "FPUONLY: work only with functions using FPU register arguments\n"
12618 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12619 "NOFPU: disable usage of FPU register arguments\n"
12620 "NOPPC: disable usage of PPC-ABI functions\n"
12621 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12622 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12623 "ONLYCNAMES: do not create C++ or ASM names\n"
12624 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12625 "PPCONLY: only use PPC-ABI functions\n"
12626 "PRIVATE: includes private declared functions\n"
12627 "SECTION: add section statements to asm texts\n"
12628 "SMALLCODE: generate small code link libraries or assembler text\n"
12629 "SMALLDATA: generate small data link libraries or assembler text\n"
12630 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12631 "SORTED: sort generated files by name and not by bias value\n"
12632 "SYSTEMRELEASE: special handling of comments for system includes\n"
12633 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12634 "VOIDBASE: library bases are of type void *\n";
12636 /* print the help text */
12637 static void printhelp(void)
12639 printf("%s\n%s\n\n%s", version
+6, PARAM
, helptext
);
12643 /* initializes the arguments and starts argument parsing */
12644 static void GetArgs(int argc
, char **argv
)
12646 struct RDArgs
*rda
;
12647 struct AmiArg amiargs
;
12650 if((rda
= (struct RDArgs
*) AllocDosObject(DOS_RDARGS
, 0)))
12652 rda
->RDA_ExtHelp
= helptext
;
12653 memset(&amiargs
, 0, sizeof(struct AmiArg
));
12654 if(ReadArgs(PARAM
, (int32
*) &amiargs
, rda
))
12659 l
= strlen(amiargs
.TO
? amiargs
.TO
: "") + 1
12660 + strlen(amiargs
.CLIB
? amiargs
.CLIB
: "") + 1
12661 + strlen(amiargs
.HEADER
? amiargs
.HEADER
: "") + 1
12662 + strlen(amiargs
.ABI
? amiargs
.ABI
: "") + 1
12663 + strlen(amiargs
.HUNKNAME
? amiargs
.HUNKNAME
: "") + 1
12664 + strlen(amiargs
.BASENAME
? amiargs
.BASENAME
: "") + 1
12665 + strlen(amiargs
.LIBTYPE
? amiargs
.LIBTYPE
: "") + 1
12666 + strlen(amiargs
.LIBNAME
? amiargs
.LIBNAME
: "") + 1
12667 + strlen(amiargs
.COPYRIGHT
? amiargs
.COPYRIGHT
: "") + 1
12668 + strlen(amiargs
.PREFIX
? amiargs
.PREFIX
: "") + 1
12669 + strlen(amiargs
.SUBPREFIX
? amiargs
.SUBPREFIX
: "") + 1
12670 + strlen(amiargs
.PREMACRO
? amiargs
.PREMACRO
: "") + 1
12671 + strlen(amiargs
.INFILE
) + 1;
12672 if((d
= AllocListMem(l
)))
12676 s
= amiargs
.INFILE
;
12677 args
.infile
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12678 if((s
= amiargs
.TO
))
12680 args
.to
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12682 if((s
= amiargs
.HEADER
))
12684 args
.header
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12686 if((s
= amiargs
.CLIB
))
12688 args
.clib
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12690 if((s
= amiargs
.HUNKNAME
))
12692 hunkname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12694 if((s
= amiargs
.BASENAME
))
12696 Flags
|= FLAG_BASENAME
;
12697 BaseName
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12699 if((s
= amiargs
.LIBTYPE
))
12701 Flags2
|= FLAG2_LIBTYPE
;
12702 libtype
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12704 if((s
= amiargs
.LIBNAME
))
12706 Flags2
|= FLAG2_LIBNAME
;
12707 libname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12709 if((s
= amiargs
.PREFIX
))
12711 prefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12713 if((s
= amiargs
.SUBPREFIX
))
12715 subprefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12717 if((s
= amiargs
.PREMACRO
))
12719 premacro
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12721 if((s
= amiargs
.COPYRIGHT
))
12723 Copyright
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12725 if((s
= amiargs
.ABI
))
12727 defabi
= d
; while(*s
) *(d
++) = *(s
++); *d
= 0;
12729 if(amiargs
.EXTERNC
) Flags
^= FLAG_EXTERNC
;
12730 if(amiargs
.PRIVATE
) Flags
^= FLAG_PRIVATE
;
12731 if(amiargs
.NEWSYNTAX
) Flags
^= FLAG_NEWSYNTAX
;
12732 if(amiargs
.SMALLDATA
) Flags
^= FLAG_SMALLDATA
;
12733 if(amiargs
.SMALLCODE
) Flags2
^= FLAG2_SMALLCODE
;
12734 if(amiargs
.SMALLTYPES
) Flags2
^= FLAG2_SMALLTYPES
;
12735 if(amiargs
.USESYSCALL
) Flags
^= FLAG_SYSCALL
;
12736 if(amiargs
.OPT040
) Flags
^= FLAG_NOMOVEM
;
12737 if(amiargs
.NOFPU
) Flags
^= FLAG_NOFPU
;
12738 if(amiargs
.FPUONLY
) Flags
^= FLAG_FPUONLY
;
12739 if(amiargs
.NOPPC
) Flags
^= FLAG_NOPPC
;
12740 if(amiargs
.NOSYMBOL
) Flags
^= FLAG_NOSYMBOL
;
12741 if(amiargs
.PPCONLY
) Flags
^= FLAG_PPCONLY
;
12742 if(amiargs
.SECTION
) Flags
^= FLAG_ASMSECTION
;
12743 if(amiargs
.COMMENT
) Flags
^= FLAG_DOCOMMENT
;
12744 if(amiargs
.SORTED
) Flags
^= FLAG_SORTED
;
12745 if(amiargs
.ONLYCNAMES
) Flags
^= FLAG_ONLYCNAMES
;
12746 if(amiargs
.SYSTEMRELEASE
) Flags2
^= FLAG2_SYSTEMRELEASE
;
12747 if(amiargs
.VOIDBASE
) Flags2
^= FLAG2_VOIDBASE
;
12748 if(amiargs
.NOPPCREGNAME
) PPCRegPrefix
= "";
12749 if(amiargs
.AUTOHEADER
) Flags2
^= FLAG2_AUTOHEADER
;
12750 if(amiargs
.SPECIAL
)
12751 args
.special
= *amiargs
.SPECIAL
;
12753 args
.mode
= *amiargs
.MODE
;
12754 if(amiargs
.PRIORITY
)
12755 priority
= *amiargs
.PRIORITY
;
12760 PrintFault(IoErr(), 0);
12761 FreeDosObject(DOS_RDARGS
, rda
);
12770 static const strptr helptext
=
12772 " -i,--infile <input filename>\n"
12773 " -s,--special <number>\n"
12774 " -m,--mode <number>\n"
12775 " -t,--to <destination directory>\n"
12776 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12777 " -c,--clib <clib prototypes filename>\n"
12778 " -d,--header <header file or \"\">\n"
12779 " -i,--libname <name of library>\n"
12780 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12781 " -b,--basename <name of library base without '_'>\n"
12782 " -l,--libtype <name of base library type>\n"
12783 " -p,--priority <priority for auto open files>\n"
12784 " -r,--copyright<copyright text>\n"
12785 " --prefix <MorphOS gate prefix>\n"
12786 " --subprefix<MorphOS gate sub prefix>\n"
12787 " --premacro <MorphOS gate file start macro>\n"
12790 "--autoheader add the typical automatic generated header\n"
12791 "--comment copy comments found in input file\n"
12792 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12793 "--fpuonly work only with functions using FPU register arguments\n"
12794 "--newsyntax uses new Motorola syntax for asm files\n"
12795 "--nofpu disable usage of FPU register arguments\n"
12796 "--noppc disable usage of PPC-ABI functions\n"
12797 "--noppcregname do not add 'r' to PPC register names\n"
12798 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12799 "--onlycnames do not create C++ or ASM names\n"
12800 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12801 "--ppconly only use PPC-ABI functions\n"
12802 "--private includes private declared functions\n"
12803 "--section add section statements to asm texts\n"
12804 "--smallcode generate small code link libraries or assembler text\n"
12805 "--smalldata generate small data link libraries or assembler text\n"
12806 "--smalltypes allow 8 and 16 bit types in registers\n"
12807 "--sorted sort generated files by name and not by bias value\n"
12808 "--systemrelease special handling of comments for system includes\n"
12809 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12810 "--voidbase library bases are of type void *\n"
12812 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12813 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12814 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12815 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12816 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12817 " 6 - pragma for all compilers [default]\n"
12818 " 7 - all compilers with pragma to inline redirect for GCC\n"
12819 " 10 - stub-functions for C - C text\n"
12820 " 11 - stub-functions for C - assembler text\n"
12821 " 12 - stub-functions for C - link library\n"
12822 " 13 - defines and link library for local library base (register call)\n"
12823 " 14 - defines and link library for local library base (stack call)\n"
12824 " 15 - stub-functions for Pascal - assembler text\n"
12825 " 16 - stub-functions for Pascal - link library\n"
12826 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12827 " 18 - module for AmigaE\n"
12828 " 20 - assembler lvo _lvo.i file\n"
12829 " 21 - assembler lvo _lib.i file\n"
12830 " 22 - assembler lvo _lvo.i file no XDEF\n"
12831 " 23 - assembler lvo _lib.i file no XDEF\n"
12832 " 24 - assembler lvo link library\n"
12833 " 30 - proto file with pragma/..._lib.h call\n"
12834 " 31 - proto file with pragma/..._pragmas.h call\n"
12835 " 32 - proto file with pragmas/..._lib.h call\n"
12836 " 33 - proto file with pragmas/..._pragmas.h call\n"
12837 " 34 - proto file with local/..._loc.h call\n"
12838 " 35 - proto file for all compilers (VBCC stubs)\n"
12839 " 36 - proto file for GNU-C compiler only\n"
12840 " 37 - proto file without lib definitions\n"
12841 " 38 - proto file for all compilers (VBCC inline)\n"
12842 " 39 - proto file with special PPC related checks\n"
12843 " 40 - GCC inline file (preprocessor based)\n"
12844 " 41 - GCC inline file (old type - inline based)\n"
12845 " 42 - GCC inline file (library stubs)\n"
12846 " 43 - GCC inline file (new style - macro)\n"
12847 " 44 - GCC inline file (new style - inline)\n"
12848 " 45 - GCC inline file (new style - inline with include lines)\n"
12849 " 46 - GCC inline file (preprocessor based, direct)\n"
12850 " 47 - GCC inline file (new style, direct)\n"
12851 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12852 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12853 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12854 " 52 - GCC inline files for PowerUP (library stubs)\n"
12855 " 53 - SAS-C include file for PowerUP\n"
12856 " 54 - Proto file for PowerUP\n"
12857 " 60 - FPC pascal unit text\n"
12858 " 70 - VBCC inline files\n"
12859 " 71 - VBCC WOS stub-functions - assembler text\n"
12860 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12861 " 73 - VBCC WOS stub-functions - link library\n"
12862 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12863 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12864 " 76 - VBCC PowerUP stub-functions - link library\n"
12865 " 77 - VBCC WOS inline files\n"
12866 " 78 - VBCC MorphOS stub-functions - link library\n"
12867 " 79 - VBCC old inline files\n"
12868 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12869 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12870 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12871 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12872 " 90 - stub-functions for C - assembler text (multiple files)\n"
12873 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12874 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12875 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12876 " 100 - PPC assembler lvo file\n"
12877 " 101 - PPC assembler lvo file no XDEF\n"
12878 " 102 - PPC assembler lvo ELF link library\n"
12879 " 103 - PPC assembler lvo EHF link library\n"
12880 " 104 - PPC V.4-ABI assembler file\n"
12881 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12882 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12883 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12885 " 111 - CLIB file\n"
12886 " 112 - SFD file\n"
12887 " 120 - VBCC auto libopen files (C source)\n"
12888 " 121 - VBCC auto libopen files (m68k link library)\n"
12889 " 122 - VBCC MorphOS inline files\n"
12890 " 123 - VBCC new MorphOS inline files\n"
12891 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12892 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12893 " 132 - GCC inline files for MorphOS (library stubs)\n"
12894 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12895 " 134 - MorphOS gate stubs\n"
12896 " 135 - MorphOS gate stubs (prelib)\n"
12897 " 136 - MorphOS gate stubs (postlib)\n"
12898 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12899 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12900 " 140 - OS4 XML file\n"
12901 " 141 - OS4 PPC->M68K cross-call stubs\n"
12902 " 142 - OS4 M68K->PPC cross-call stubs\n"
12903 " 200 - FD file (source is a pragma file!)\n"
12904 "mode: special 1-7\n"
12905 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12906 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12907 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12908 " 4 - no definition\n"
12909 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12911 " 1 - all functions, normal interface\n"
12912 " 2 - only tag-functions, tagcall interface\n"
12913 " 3 - all functions, normal and tagcall interface [default]\n";
12915 /* print the help text */
12916 static void printhelp(void)
12918 printf("%s\n%s", version
+6, helptext
);
12931 ARG_HELP
, ARG_INFILE
, ARG_SPECIAL
, ARG_MODE
, ARG_TO
, ARG_CLIB
, ARG_ABI
, ARG_COPYRIGHT
,
12932 ARG_HEADER
, ARG_HUNKNAME
, ARG_BASENAME
, ARG_LIBTYPE
,
12933 ARG_COMMENT
, ARG_EXTERNC
, ARG_FPUONLY
, ARG_NEWSYNTAX
, ARG_NOFPU
, ARG_NOPPC
,
12934 ARG_NOSYMBOL
, ARG_ONLYCNAMES
, ARG_OPT040
, ARG_PPCONLY
, ARG_PRIVATE
, ARG_SECTION
,
12935 ARG_SMALLDATA
, ARG_SORTED
, ARG_USESYSCALL
, ARG_NOPPCREGNAME
,
12936 ARG_SYSTEMRELEASE
, ARG_PRIORITY
, ARG_LIBNAME
, ARG_SMALLCODE
, ARG_VOIDBASE
,
12937 ARG_PREFIX
, ARG_SUBPREFIX
, ARG_PREMACRO
, ARG_SMALLTYPES
, ARG_AUTOHEADER
12940 /* argument definition array */
12941 static const struct ArgData argtexts
[] = {
12942 {"help", 'h', 4, ARG_HELP
},
12943 {"infile", 'i', 6, ARG_INFILE
},
12944 {"special", 's', 7, ARG_SPECIAL
},
12945 {"mode", 'm', 4, ARG_MODE
},
12946 {"to", 't', 2, ARG_TO
},
12947 {"clib", 'c', 4, ARG_CLIB
},
12948 {"abi", 'a', 3, ARG_ABI
},
12949 {"copyright", 'r', 9, ARG_COPYRIGHT
},
12950 {"header", 'd', 6, ARG_HEADER
},
12951 {"hunkname", 'n', 8, ARG_HUNKNAME
},
12952 {"basename", 'b', 8, ARG_BASENAME
},
12953 {"libtype", 'l', 7, ARG_LIBTYPE
},
12954 {"libname", 'i', 7, ARG_LIBNAME
},
12955 {"priority", 'p', 8, ARG_PRIORITY
},
12956 {"autoheader", 0, 10, ARG_AUTOHEADER
},
12957 {"comment", 0, 7, ARG_COMMENT
},
12958 {"externc", 0, 7, ARG_EXTERNC
},
12959 {"fpuonly", 0, 7, ARG_FPUONLY
},
12960 {"newsyntax", 0, 9, ARG_NEWSYNTAX
},
12961 {"nofpu", 0, 5, ARG_NOFPU
},
12962 {"noppc", 0, 5, ARG_NOPPC
},
12963 {"noppcregname", 0, 12, ARG_NOPPCREGNAME
},
12964 {"nosymbol", 0, 8, ARG_NOSYMBOL
},
12965 {"onlycnames", 0, 10, ARG_ONLYCNAMES
},
12966 {"opt040", 0, 6, ARG_OPT040
},
12967 {"ppconly", 0, 7, ARG_PPCONLY
},
12968 {"private", 0, 7, ARG_PRIVATE
},
12969 {"section", 0, 7, ARG_SECTION
},
12970 {"smalldata", 0, 9, ARG_SMALLDATA
},
12971 {"smalltypes", 0, 10, ARG_SMALLTYPES
},
12972 {"smallcode", 0, 9, ARG_SMALLCODE
},
12973 {"sorted", 0, 6, ARG_SORTED
},
12974 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE
},
12975 {"usesyscall", 0, 10, ARG_USESYSCALL
},
12976 {"voidbase", 0, 8, ARG_VOIDBASE
},
12977 {"prefix", 0, 6, ARG_PREFIX
},
12978 {"subprefix", 0, 9, ARG_SUBPREFIX
},
12979 {"premacro", 0, 8, ARG_PREMACRO
},
12980 {0,0,0,0}, /* end marker */
12983 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
12984 static uint32
ParseArgEntry(uint32 argc
, strptr
*argv
)
12986 uint32 numentries
= 1, l
;
12988 const struct ArgData
*ad
;
12990 if((*argv
)[0] != '-' || !(*argv
)[1])
12996 if((*argv
)[1] == ad
->ArgChar
|| ((*argv
)[1] == '-' && !strncmp(ad
->ArgName
, (*argv
)+2, ad
->ArgNameLen
)))
13004 case ARG_HELP
: printhelp(); break;
13005 case ARG_EXTERNC
: Flags
^= FLAG_EXTERNC
; break;
13006 case ARG_PRIVATE
: Flags
^= FLAG_PRIVATE
; break;
13007 case ARG_NEWSYNTAX
: Flags
^= FLAG_NEWSYNTAX
; break;
13008 case ARG_SMALLDATA
: Flags
^= FLAG_SMALLDATA
; break;
13009 case ARG_SMALLCODE
: Flags2
^= FLAG2_SMALLCODE
; break;
13010 case ARG_SMALLTYPES
: Flags2
^= FLAG2_SMALLTYPES
; break;
13011 case ARG_USESYSCALL
: Flags
^= FLAG_SYSCALL
; break;
13012 case ARG_OPT040
: Flags
^= FLAG_NOMOVEM
; break;
13013 case ARG_NOFPU
: Flags
^= FLAG_NOFPU
; break;
13014 case ARG_FPUONLY
: Flags
^= FLAG_FPUONLY
; break;
13015 case ARG_NOPPC
: Flags
^= FLAG_NOPPC
; break;
13016 case ARG_NOSYMBOL
: Flags
^= FLAG_NOSYMBOL
; break;
13017 case ARG_PPCONLY
: Flags
^= FLAG_PPCONLY
; break;
13018 case ARG_SECTION
: Flags
^= FLAG_ASMSECTION
; break;
13019 case ARG_COMMENT
: Flags
^= FLAG_DOCOMMENT
; break;
13020 case ARG_SORTED
: Flags
^= FLAG_SORTED
; break;
13021 case ARG_ONLYCNAMES
: Flags
^= FLAG_ONLYCNAMES
; break;
13022 case ARG_SYSTEMRELEASE
: Flags2
^= FLAG2_SYSTEMRELEASE
; break;
13023 case ARG_VOIDBASE
: Flags2
^= FLAG2_VOIDBASE
; break;
13024 case ARG_AUTOHEADER
: Flags2
^= FLAG2_AUTOHEADER
; break;
13025 case ARG_NOPPCREGNAME
: PPCRegPrefix
= "";
13027 a
= *argv
+((*argv
)[1] == '-' ? ad
->ArgNameLen
+2 : 2);
13030 if(argc
> 1) { a
= argv
[1]; numentries
= 2; }
13031 else { a
= 0; numentries
= 0;}
13041 a
[--l
] = 0; /* remove second " */
13045 case ARG_INFILE
: args
.infile
= a
; break;
13046 case ARG_COPYRIGHT
: Copyright
= a
; break;
13047 case ARG_TO
: args
.to
= a
; break;
13048 case ARG_ABI
: defabi
= a
; break;
13049 case ARG_CLIB
: args
.clib
= a
; break;
13050 case ARG_HEADER
: args
.header
= a
; break;
13051 case ARG_HUNKNAME
: hunkname
= a
; break;
13052 case ARG_PREFIX
: prefix
= a
; break;
13053 case ARG_SUBPREFIX
: subprefix
= a
; break;
13054 case ARG_PREMACRO
: premacro
= a
; break;
13055 case ARG_LIBTYPE
: libtype
= a
; Flags2
|= FLAG2_LIBTYPE
; break;
13056 case ARG_LIBNAME
: libname
= a
; Flags2
|= FLAG2_LIBNAME
; break;
13057 case ARG_BASENAME
: BaseName
= a
; Flags
|= FLAG_BASENAME
; break;
13059 args
.special
= strtoul(a
, &b
, 10);
13064 priority
= strtoul(a
, &b
, 10);
13069 args
.mode
= strtoul(a
, &b
, 10);
13070 if(*b
|| args
.mode
< 1 || args
.mode
> 3)
13079 /* initializes the arguments and starts argument parsing */
13080 static void GetArgs(int argc
, char **argv
)
13085 while(i
< argc
&& res
)
13087 if((j
= ParseArgEntry(argc
-i
, argv
+i
)) < 1)
13092 if(!res
|| !args
.infile
)
13098 static strptr
mygetfile(strptr name
, size_t *len
)
13103 if((infile
= fopen(name
, "rb")))
13105 if(!fseek(infile
, 0, SEEK_END
))
13107 *len
= ftell(infile
);
13108 if(!fseek(infile
, 0, SEEK_SET
))
13110 if((ptr
= AllocListMem(*len
+1)))
13114 printf("mygetfile: '%s' size %d\n", name
, *len
);
13116 if(fread(ptr
, *len
, 1, infile
) != 1)
13126 int main(int argc
, char **argv
)
13128 uint32 mode
= 0, pragmode
= PRAGMODE_PRAGLIB
, callmode
= TAGMODE_BOTH
;
13129 strptr amicall
= 0, libcall
= 0, amitags
= 0, libtags
= 0;
13131 size_t clibsize
= 0;
13133 GetArgs(argc
, argv
);
13135 if((tempbuf
= (uint8
*) AllocListMem(TEMPSIZE
)))
13137 if(!(in
.pos
= in
.buf
= mygetfile(args
.infile
, &in
.size
)))
13139 if(args
.special
== 200)
13141 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13146 sprintf((strptr
)tempbuf
, "%s" SFDFILEEXTENSION
, args
.infile
);
13147 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13149 sprintf((strptr
)tempbuf
, "%s" FDFILEEXTENSION
, args
.infile
);
13150 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13152 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13156 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13159 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13162 printf("SourceFile: %s\n", args
.infile
);
13164 MakeLines(in
.pos
, in
.size
);
13166 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SORTED
)) /* is not possible to use both */
13168 DoError(ERR_SORTED_COMMENT
, 0);
13169 Flags
&= (~FLAG_SORTED
);
13172 if(args
.special
== 200)
13186 if(Flags2
& FLAG2_SFDMODE
)
13187 DoError(ERR_SFD_AND_CLIB
, 0);
13190 sprintf((strptr
)tempbuf
, "%s_protos.h", args
.clib
);
13191 if(!(clibbuf
= mygetfile(args
.clib
, &clibsize
)) && !(clibbuf
= mygetfile((strptr
)tempbuf
, &clibsize
)))
13193 DoError(ERR_OPEN_FILE
, 0, args
.clib
);
13196 ScanClibFile(clibbuf
, clibbuf
+clibsize
);
13200 if(!MakeShortBaseName())
13202 DoError(ERR_MISSING_SHORTBASENAME
, 0);
13206 /* WARN when requesting obsolete types! */
13207 switch(args
.special
)
13209 case 1: case 2: case 3: case 4: case 5: case 7:
13210 printf("You use obsolete data type %ld, better use type 6!\n", args
.special
);
13212 case 11: case 15: case 71: case 72: case 75:
13213 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13214 "link libraries!\n", args
.special
);
13216 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13217 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args
.special
);
13220 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13224 if(args
.special
< 10) /* the pragma area is up to 9 */
13226 mode
= MODUS_PRAGMA
;
13227 sprintf(filename
, "%s_lib.h", ShortBaseName
);
13229 switch(args
.special
)
13232 case 1: pragmode
= PRAGMODE_PRAGSLIB
; amicall
= ""; break;
13233 case 2: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13234 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= ""; break;
13235 case 3: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13236 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= "";
13237 libtags
= "def " TEXT_SAS_60
; break;
13238 case 4: amicall
= ""; break;
13239 case 5: amicall
= amitags
= ""; break;
13240 case 7: Flags
|= FLAG_GNUPRAG
; /* no break ! */
13241 case 6: amicall
= " defined(" TEXT_AZTEC
") || defined("
13242 TEXT_MAXON
") || defined(" TEXT_STORM
")";
13243 libcall
= " defined(" TEXT_DICE
") || defined(" TEXT_SAS
")";
13244 libtags
= "def " TEXT_SAS_60
; amitags
="def " TEXT_STORM
; break;
13245 default: mode
= MODUS_ERROR
; break;
13248 if(args
.mode
> 0 && args
.mode
< 5)
13249 pragmode
= args
.mode
;
13251 else if(args
.special
< 20) /* the misc area is up to 19 */
13253 if(args
.mode
> 0 && args
.mode
< 4)
13254 callmode
= args
.mode
- 1;
13255 switch(args
.special
)
13257 case 10: mode
= MODUS_CSTUB
;
13258 sprintf(filename
, "%s_cstub.h", ShortBaseName
); break;
13259 case 11: mode
= MODUS_STUBTEXT
;
13260 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13261 case 12: mode
= MODUS_STUBCODE
;
13262 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13263 case 13: Flags
|= FLAG_LOCALREG
; /* no break ! */
13264 case 14: mode
= MODUS_LOCALDATA
;
13265 sprintf(filename
, "%s_loc.h", ShortBaseName
); break;
13266 case 15: mode
= MODUS_STUBTEXT
; callmode
= TAGMODE_NORMAL
;
13267 Flags
^= FLAG_PASCAL
;
13268 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13269 case 16: mode
= MODUS_STUBCODE
; callmode
= TAGMODE_NORMAL
;
13270 Flags
^= FLAG_PASCAL
;
13271 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13272 case 17: mode
= MODUS_BMAP
; callmode
= TAGMODE_NORMAL
;
13273 sprintf(filename
, "%s.bmap", ShortBaseName
); break;
13274 case 18: mode
= MODUS_EMODULE
;
13275 sprintf(filename
, "%s.m", ShortBaseName
); break;
13276 default: mode
= MODUS_ERROR
; break;
13279 else if(args
.special
< 30) /* the lvo area is up to 29 */
13281 switch(args
.special
)
13283 case 20: case 22: mode
= MODUS_LVO
+args
.special
-20;
13284 sprintf(filename
, "%s_lvo.i", ShortBaseName
); break;
13285 case 21: case 23: mode
= MODUS_LVO
+args
.special
-20;
13286 sprintf(filename
, "%s_lib.i", ShortBaseName
); break;
13287 case 24: mode
= MODUS_LVOLIB
;
13288 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13289 default: mode
= MODUS_ERROR
; break;
13292 else if(args
.special
< 40) /* the proto area is up to 39 */
13294 if(args
.special
< 40)
13296 mode
= MODUS_PROTO
+args
.special
-30;
13297 sprintf(filename
, "%s.h", ShortBaseName
);
13300 mode
= MODUS_ERROR
;
13302 else if(args
.special
< 50) /* the inline area is up to 49 */
13304 if(args
.mode
> 0 && args
.mode
< 4)
13305 callmode
= args
.mode
- 1;
13307 switch(args
.special
)
13309 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13311 mode
= MODUS_INLINE
+args
.special
-40;
13312 sprintf(filename
, "%s.h", ShortBaseName
); break;
13314 Flags
|= FLAG_STORMGCC
;
13315 /* the same mode as for 46, but additional flag */
13316 mode
= MODUS_INLINE
+args
.special
-40-2;
13317 sprintf(filename
, "%s.h", ShortBaseName
); break;
13318 default: mode
= MODUS_ERROR
; break;
13321 else if(args
.special
< 60) /* the PowerUP area is up to 59 */
13323 if(args
.mode
> 0 && args
.mode
< 4)
13324 callmode
= args
.mode
- 1;
13326 switch(args
.special
)
13328 case 50: case 51: case 52: mode
= MODUS_INLINE
+args
.special
-50;
13329 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_POWERUP
;
13332 sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13333 mode
= MODUS_SASPOWER
; break;
13335 sprintf(filename
, "%s.h", ShortBaseName
);
13336 mode
= MODUS_PROTOPOWER
; break;
13337 default: mode
= MODUS_ERROR
; break;
13340 else if(args
.special
< 70) /* the PASCAL stuff */
13342 if(args
.special
== 60)
13344 mode
= MODUS_PASCAL
;
13345 sprintf(filename
, "%s.pas", ShortBaseName
);
13348 mode
= MODUS_ERROR
;
13350 else if(args
.special
< 80) /* the VBCC stuff */
13352 if(args
.mode
> 0 && args
.mode
< 4)
13353 callmode
= args
.mode
- 1;
13355 switch(args
.special
)
13357 case 70: mode
= MODUS_VBCCINLINE
;
13358 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13359 case 71: case 72: case 75:
13360 mode
= MODUS_VBCC
+args
.special
-71;
13361 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13363 mode
= MODUS_VBCC
+args
.special
-71;
13364 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13366 mode
= MODUS_VBCCPUPLIB
;
13367 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13368 case 77: mode
= MODUS_VBCCWOSINLINE
;
13369 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13370 case 78: mode
= MODUS_VBCCMORPHCODE
;
13371 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13372 case 79: mode
= MODUS_VBCCINLINE
;
13373 Flags2
|= FLAG2_OLDVBCC
;
13374 callmode
= TAGMODE_NORMAL
;
13375 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13376 default: mode
= MODUS_ERROR
; break;
13379 else if(args
.special
< 90) /* redirect stuff */
13381 mode
= MODUS_REDIRECT
;
13382 switch(args
.special
)
13384 case 80: sprintf(filename
, "%s_pragmas.h", ShortBaseName
); break;
13385 case 81: sprintf(filename
, "%s_lib.h", ShortBaseName
); break;
13386 case 82: sprintf(filename
, "%s.h", ShortBaseName
); break;
13387 case 83: sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13388 default: mode
= MODUS_ERROR
; break;
13391 else if(args
.special
< 100) /* multifile stuff */
13393 Flags
|= FLAG_SINGLEFILE
;
13394 switch(args
.special
)
13397 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13398 mode
= MODUS_ASMTEXTSF
; filenamefmt
= "%s.s";
13401 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13402 mode
= MODUS_VBCCPUPTEXTSF
; filenamefmt
= "%s.s";
13405 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13406 mode
= MODUS_VBCCWOSTEXTSF
; filenamefmt
= "%s.s";
13409 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13410 mode
= MODUS_VBCCMORPHTEXTSF
; filenamefmt
= "%s.s";
13412 default: mode
= MODUS_ERROR
; break;
13415 else if(args
.special
< 110) /* PPC lvo's */
13417 switch(args
.special
)
13419 case 100: case 101: mode
= MODUS_LVOPPC
+args
.special
-100;
13420 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13422 case 104: case 105: mode
= MODUS_LVOPPC
+args
.special
-104;
13423 Flags
|= FLAG_ABIV4
;
13424 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13426 case 103: mode
= MODUS_LVOLIB
;
13427 sprintf(filename
, "%slvo.o", ShortBaseName
);
13429 case 107: mode
= MODUS_LVOLIB
;
13430 Flags
|= FLAG_ABIV4
;
13431 sprintf(filename
, "%slvo.o", ShortBaseName
);
13433 case 102: mode
= MODUS_LVOLIBPPC
;
13434 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13435 case 106: mode
= MODUS_LVOLIBPPC
;
13436 Flags
|= FLAG_ABIV4
;
13437 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13438 default: mode
= MODUS_ERROR
; break;
13441 else if(args
.special
< 120) /* different files */
13443 if(args
.mode
> 0 && args
.mode
< 4)
13444 callmode
= args
.mode
- 1;
13446 switch(args
.special
)
13448 case 110: mode
= MODUS_FD
;
13449 sprintf(filename
, "%s_lib.fd", ShortBaseName
);
13450 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13452 DoError(ERR_SORTED_SFD_FD
, 0);
13453 Flags
&= (~FLAG_SORTED
);
13456 case 111: mode
= MODUS_CLIB
; Flags2
|= FLAG2_CLIBOUT
;
13457 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13459 case 112: mode
= MODUS_SFD
; Flags2
|= FLAG2_SFDOUT
;
13460 sprintf(filename
, "%s_lib.sfd", ShortBaseName
);
13464 DoError(ERR_ONLYTAGMODE_NOTALLOWED
, 0);
13467 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13469 DoError(ERR_SORTED_SFD_FD
, 0);
13470 Flags
&= (~FLAG_SORTED
);
13473 default: mode
= MODUS_ERROR
; break;
13476 else if(args
.special
< 130) /* auto libopen files */
13478 if(args
.mode
> 0 && args
.mode
< 4) /* for 122 */
13479 callmode
= args
.mode
- 1;
13481 switch(args
.special
)
13483 case 120: mode
= MODUS_GENAUTO
;
13484 sprintf(filename
, "%s_autoopenlib.c", ShortBaseName
);
13486 case 121: mode
= MODUS_GENAUTO
+(args
.special
-120);
13487 sprintf(filename
, "%s_autoopenlib.lib", ShortBaseName
);
13489 case 123: Flags2
|= FLAG2_SHORTPPCVBCCINLINE
; /* no break */
13490 case 122: mode
= MODUS_VBCCMORPHINLINE
;
13491 PPCRegPrefix
= ""; /* no "r" allowed */
13492 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13494 default: mode
= MODUS_ERROR
; break;
13497 else if(args
.special
< 140) /* the MorphOS area is up to 139 */
13499 if(args
.mode
> 0 && args
.mode
< 4)
13500 callmode
= args
.mode
- 1;
13502 switch(args
.special
)
13504 case 130: case 131: case 132: mode
= MODUS_INLINE
+args
.special
-130;
13505 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13507 case 133: mode
= MODUS_INLINE
+2;
13508 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13509 Flags2
|= FLAG2_DIRECTVARARGS
;
13511 case 134: mode
= MODUS_GATESTUBS
;
13512 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13514 case 135: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
;
13515 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13517 case 136: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
;
13518 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13520 case 137: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
|FLAG2_REGLIB
;
13521 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13523 case 138: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
|FLAG2_REGLIB
;
13524 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13526 default: mode
= MODUS_ERROR
; break;
13529 else if(args
.special
< 150) /* the OS4 area is up to 139 */
13531 if(args
.mode
> 0 && args
.mode
< 4)
13532 callmode
= args
.mode
- 1;
13534 switch(args
.special
)
13538 sprintf(filename
, "%s.xml", ShortBaseName
);
13540 case 141: /* OS4 PPC->M68K cross-call stubs */
13541 mode
= MODUS_OS4_PPCSTUBS
;
13542 sprintf(filename
, "%s.c", ShortBaseName
);
13544 case 142: /* OS4 M68K->PPC cross-call stubs */
13545 mode
= MODUS_OS4_68KSTUBS
;
13546 sprintf(filename
, "%s_68k.s", ShortBaseName
);
13548 default: mode
= MODUS_ERROR
; break;
13551 if(Flags
& FLAG_SORTED
)
13554 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SINGLEFILE
)) /* is not possible to use both */
13556 DoError(ERR_COMMENT_SINGLEFILE
, 0);
13557 Flags
&= (~FLAG_DOCOMMENT
);
13560 if(!mode
|| mode
== MODUS_ERROR
)
13563 /* These modes need BaseName always. */
13564 if(!BaseName
&& (mode
== MODUS_PRAGMA
|| mode
== MODUS_STUBTEXT
||
13565 mode
== MODUS_STUBCODE
|| mode
== MODUS_EMODULE
|| (mode
>= MODUS_GENAUTO
&&
13566 mode
<= MODUS_GENAUTO
+9)))
13568 DoError(ERR_MISSING_BASENAME
, 0);
13572 if(args
.header
&& args
.header
[0] && (args
.header
[0] != '@' || args
.header
[1]))
13574 HEADER
= mygetfile(args
.header
, &headersize
);
13578 if(!(Flags
& FLAG_SINGLEFILE
))
13580 if(!OpenDest(filename
))
13584 /* from here mode is used as return result */
13585 if(mode
>= MODUS_GENAUTO
)
13586 mode
= CreateGenAuto(filename
, mode
-MODUS_GENAUTO
);
13587 else if(mode
>= MODUS_LVOPPC
)
13588 mode
= CreateLVOFilePPC(mode
-MODUS_LVOPPC
);
13589 else if(mode
>= MODUS_VBCC
)
13590 mode
= CreateVBCC(mode
-MODUS_VBCC
, callmode
);
13591 else if(mode
>= MODUS_INLINE
)
13592 mode
= CreateInline(mode
-MODUS_INLINE
, callmode
);
13593 else if(mode
>= MODUS_PROTO
)
13594 mode
= CreateProtoFile(mode
-MODUS_PROTO
+1);
13595 else if(mode
>= MODUS_LVO
)
13596 mode
= CreateLVOFile(mode
-MODUS_LVO
+1);
13597 else if(mode
== MODUS_VBCCMORPHINLINE
)
13598 mode
= CreateVBCCInline(2, callmode
);
13599 else if(mode
== MODUS_XML
)
13600 mode
= CreateXML();
13601 else if(mode
== MODUS_OS4_PPCSTUBS
)
13602 mode
= CreateOS4PPC(callmode
);
13603 else if(mode
== MODUS_OS4_68KSTUBS
)
13604 mode
= CreateOS4M68K();
13605 else if(mode
== MODUS_GATESTUBS
)
13606 mode
= CreateGateStubs(callmode
);
13607 else if(mode
== MODUS_SFD
)
13608 mode
= CreateSFD(callmode
);
13609 else if(mode
== MODUS_CLIB
)
13610 mode
= CreateClib(callmode
);
13611 else if(mode
== MODUS_FD
)
13613 else if(mode
== MODUS_LVOLIBPPC
)
13614 mode
= CreateLVOLibPPC();
13615 else if(mode
== MODUS_VBCCMORPHCODE
)
13616 mode
= CreateVBCCMorphCode(callmode
);
13617 else if(mode
== MODUS_VBCCMORPHTEXTSF
) /* single files */
13618 mode
= CallFunc(callmode
, "\n%s", FuncVBCCMorphText
);
13619 else if(mode
== MODUS_VBCCWOSINLINE
)
13620 mode
= CreateVBCCInline(1, callmode
);
13621 else if(mode
== MODUS_VBCCWOSTEXTSF
) /* single files */
13622 mode
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
);
13623 else if(mode
== MODUS_VBCCPUPTEXTSF
) /* single files */
13624 mode
= CallFunc(callmode
, "\n%s", FuncVBCCPUPText
);
13625 else if(mode
== MODUS_ASMTEXTSF
) /* single files */
13626 mode
= CallFunc(callmode
, "\n%s", FuncAsmText
);
13627 else if(mode
== MODUS_REDIRECT
)
13628 mode
= CreateProtoRedirect();
13629 else if(mode
== MODUS_EMODULE
)
13630 mode
= CreateEModule(Flags
& FLAG_SORTED
);
13631 else if(mode
== MODUS_LVOLIB
)
13632 mode
= CreateLVOLib();
13633 else if(mode
== MODUS_VBCCPUPLIB
)
13634 mode
= CreateVBCCPUPLib(callmode
);
13635 else if(mode
== MODUS_VBCCINLINE
)
13636 mode
= CreateVBCCInline(0, callmode
);
13637 else if(mode
== MODUS_PASCAL
)
13638 mode
= CreateFPCUnit();
13639 else if(mode
== MODUS_BMAP
)
13640 mode
= CreateBMAP();
13641 else if(mode
== MODUS_PROTOPOWER
)
13642 mode
= CreateProtoPowerUP();
13643 else if(mode
== MODUS_SASPOWER
)
13644 mode
= CreateSASPowerUP(callmode
);
13645 else if(mode
== MODUS_CSTUB
)
13646 mode
= CreateCSTUBSFile();
13647 else if(mode
== MODUS_PRAGMA
)
13648 mode
= CreatePragmaFile(amicall
, libcall
, amitags
, libtags
, pragmode
);
13649 else if(mode
== MODUS_LOCALDATA
)
13650 mode
= CreateLocalData(filename
, callmode
);
13651 else if(mode
) /* MODUS_STUBTEXT starts with 1 */
13652 mode
= CreateAsmStubs(mode
, callmode
);
13654 CloseDest(filename
);
13658 DoError(Output_Error
? ERR_UNKNOWN_ERROR
: ERR_WRITING_FILE
, 0);