2 static const char version
[] =
3 "$VER: fd2pragma 2.194 (02.01.2011) by Dirk Stoecker <software@dstoecker.de>";
5 /* There are four defines, which alter the result which is produced after
6 compiling this piece of code. */
8 /* turns on usage of Amiga ReadArgs-system (requires <proto/dos.h> include) */
9 /* #define FD2PRAGMA_READARGS */
11 /* enables Amiga style file name (only relevant for fd2pragma.types file) */
12 /* #define FD2PRAGMA_AMIGA */
14 /* debugging output */
17 /* more debugging output */
18 /* #define DEBUG_OLD */
25 Description: creates pragmas files, lvo files, ...
29 1.2 : added pragmas for the Dice compiler. Available via switch "Dice".
30 added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
31 turn on the default (except that Maxon expects pragma files to be
32 called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
33 Dice, except that SAS supports the pragma tagcall.
34 2.0 : Added support for tag functions. See the docs for details.
35 Author until this version:
38 72555 Metzingen (Germany)
40 2.1 19.08.96 : now made by SDI, added correct __MAXON__ support and
41 support for StormC++, added auto recognition of tagcall functions
42 changed the CLI interface completely
43 2.2 21.08.96 : fixed a lot of errors, added debug code
44 2.3 22.08.96 : little changes
45 2.4 24.08.96 : added proto-file creation
46 2.5 25.08.96 : added syscall and fix for functions ending in ...DMA
47 2.6 26.08.96 : fixed some errors, added CLIB parameter (used later for
49 2.7 01.09.96 : added correct Storm definition, added CLIB scan
50 2.8 02.09.96 : added assembler stub functions, added first ASM-stub code
51 2.9 04.09.96 : added Comment-Support
52 2.10 05.09.96 : changed CSTUB creation a bit
53 2.11 07.09.96 : speeded up output, reduced number of strndup calls
54 2.12 26.09.96 : pressing CTRL-C in early startup brought a wrong error
56 2.13 30.09.96 : made RegNames field to RegNames string - shorter Exe-file
57 2.14 01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
58 2.15 13.10.96 : corrected an error text
59 2.16 14.10.96 : added correct comment support and PRIVATE option
60 2.17 19.10.96 : now Maxon-compiled in Small data mode
61 2.18 22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
62 the texts, again SAS compiled
63 2.19 26.10.96 : added option to create FD files out of pragma files,
64 reworked a lot in the source
65 2.20 27.10.96 : fixed errors of previous version
66 2.21 28.10.96 : fixed error in CLIB scan
67 2.22 27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
68 bug in Tag function stubs
69 2.23 06.12.96 : lib and stub creation still was wrong
70 2.24 31.12.96 : formed stub libs matching C++ file names, corrected CLIB
72 2.25 04.01.97 : added HEADER option (I was asked for)
73 2.26 05.01.97 : added HEADER scan (in old file) and auto inserting
74 2.27 10.01.97 : stub functions missed register saving, outfuncs skip now,
75 when error occured (makes lots of error checking obsolete)
76 2.28 11.01.97 : forgot to add offset made by register saving
77 2.29 18.01.97 : now libtags and amitags defines only, when at least 1
79 2.30 13.02.97 : added local library base functions, rearranged SPECIAL
80 options, fixed some bugs
81 2.31 15.02.97 : corrected bugs inserted in previous version
82 2.32 16.02.97 : and again bug fixes, still didn't work
83 2.33 18.02.97 : corrected texts, added SPECIAL 28
84 2.34 25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
85 2.35 26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
86 2.36 29.03.97 : corrected *tagcall scan a bit
87 2.37 20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
88 2.38 01.07.97 : fixed ##end handling
89 2.39 20.07.97 : added better proto file (__GNUC__ inline and pragma call),
91 2.40 24.11.97 : added new basenames to the list (devices and resources),
92 added tag-exception name checking (dos, utility libraries)
93 2.41 27.11.97 : fixed little bug with private functions, CSTUBS now
94 special option and no longer commandline arg, SPECIAL 10-15 got
96 2.42 28.11.97 : Added two new warnings for CLIB
97 2.43 12.12.97 : faster FD file scan, one new warning
98 2.44 19.12.97 : fixed MODE settings for SPECIAL 15,16
99 2.45 30.01.98 : added function recognition, included inline creation,
100 inline stuff is based on fd2inline 1.11 (incomplete)
101 2.46 31.01.98 : continued inline stuff, fixed clib functions
102 2.47 05.02.98 : completed inline stuff, added alias names for dos functions
103 2.48 06.02.98 : changed Func interface - flags instead of tagmode
104 2.49 10.02.98 : fixed inline generation a bit, added SORTED argument,
105 RegNames got strings again
106 2.50 11.02.98 : bug-fixes, still did not work completely, hopefully got
108 2.51 12.02.98 : and bug-fixes again :-(
109 2.52 15.02.98 : changed sorting order of arguments
110 2.53 20.02.98 : some code style changes
111 2.54 25.02.98 : added SMALLDATA model, removed 5 global variables (better
112 style), stub libs use MOVEM when possible, own MemRemember function
113 2.55 26.02.98 : bug fixes
114 2.56 15.03.98 : added FPU support
115 2.57 17.03.98 : added NOFPU keyword
116 2.58 19.03.98 : little fixes
117 2.59 20.03.98 : added enum and external type definitions defines
118 2.60 22.03.98 : added external types file scan
119 2.61 23.03.98 : fixed SAS flibcall, added FPU stubs
120 2.62 28.03.98 : bug fix with NOFPU and new option FPUONLY, total new clib
122 2.63 29.03.98 : really lots of bug fixes, There are so much problems.
123 A better definition format would have been wonderful.
124 2.64 05.04.98 : bug fixes
125 2.65 07.04.98 : fixed Enforcer hit
126 2.66 08.04.98 : bug fix with type detection
127 2.67 20.04.98 : added GNU-only stuff
128 2.68 28.04.98 : SPECIAL 8 defaults to SAS-C names now
129 2.69 25.05.98 : added PowerUP stuff support
130 2.70 28.05.98 : added SAS PowerUP stuff, fixed error with function
131 detection in CLIB scan
132 2.71 30.05.98 : added PowerUP Inlines
133 2.72 12.06.98 : sorting turns of COMMENT now
134 2.73 05.07.98 : added first FPC stuff, added HEADER to PowerUP stuff,
135 added PASCAL header scan
136 2.74 06.07.98 : finished FPC stuff
137 2.75 07.07.98 : bug fixes for FPC stuff
138 2.76 09.07.98 : style changes for FPC stuff, bug fixes
139 2.77 11.07.98 : hopefully last FPC bug removed
140 2.78 23.07.98 : style changes and bug fixes for FPC stuff, more comments
141 2.79 10.08.98 : bug fix, when TO was used with a directory, clib got
142 wrong path if it was a relative path description
143 2.80 16.08.98 : now prints better error when filopen failed
144 2.81 26.10.98 : added BMAP files for BASIC, CODE needs to use large mode
146 2.82 28.10.98 : optimizations and bug fixes
147 2.83 31.12.98 : fixed powerup stuff a bit
148 2.84 05.01.99 : fixed bug in Lib creation, when Dx/Ax and FPx were mixed
149 2.85 06.01.99 : added recognition of names ending in MESA, added notagcall
150 comment support, void functions no longer can be tagcall
151 2.86 10.01.99 : added BGUI special funcs, fixed bug in SPECIAL 42 code
152 2.87 12.01.99 : added asm-text (SECTION), moved 12-17 to 13-18
153 2.88 17.01.99 : better type detection, added some more basenames, some
154 little bug fixes, new makefile reduces file size a lot
155 2.89 17.07.99 : added union support
156 2.90 12.11.99 : added new motorola syntax, opt040 and vbcc inlines
157 2.91 13.11.99 : Now supports changes in OS3.5 includes, why the hell must
158 such changes be? I thought new includes will bring cleanup and not
159 cleandown. And the reported bugs are still unfixed, but there are
161 2.92 14.11.99 : added PPC-WOS library text and code, FD-creation moved from
162 80 to 200 (now finally! - there should be enough free number space),
163 added VBCC-PUP text generation
164 2.93 15.11.99 : added CheckError function, moved DisplayInfoHandle to
165 types definition file
166 2.94 16.11.99 : added first VBCC-PowerUP-Lib production stuff, only ELF
168 2.95 17.11.99 : finished PowerUP stub stuff, startet PPC-ABI stuff
169 2.96 18.11.99 : little bug fixes
170 2.97 19.11.99 : added SECTION keyword, moved 11-18 to 12-17, ahh 3 releases
171 more and we get an anniversary, my first program using third revision
173 2.98 20.11.99 : added VBCC-WOS-Code for PPC libs
174 2.99 25.11.99 : bug fixes
175 2.100 17.02.00 : fixed bug for VBCC inlines
176 2.101 29.02.00 : fixed name for VBCC inlines
177 2.102 13.03.00 : added new style GCC inlines
178 2.103 21.03.00 : bug fixed, SPECIAL 35 has VBCC stuff now.
179 2.104 25.03.00 : fixed path lock problem
180 2.105 11.04.00 : library HUNK_UNIT get functionname now
181 2.106 13.07.00 : added E-Modules
182 2.107 06.08.00 : removed VBCC inline support from 35 and moved it to 38, 35
183 does now skip pragma/inline files for VBCC
184 2.108 18.08.00 : added new ppc modification proto file 39, modified protos a
185 bit, support for register types and function pointer args, int got
186 internally type CPP_TYPE_INT
187 2.109 19.08.00 : bug fixes
188 2.110 24.08.00 : fixed SPECIAL 7,40-44, added SPECIAL 80-83
189 2.111 31.08.00 : bug fixes
190 2.112 03.09.00 : FD2Pragma.types scanner no longer accepts multi-word types.
191 2.113 29.12.00 : added extern keword support for return types.
192 2.114 07.01.01 : made FD2Pragma partly portable, removed 4 direct pragma
194 2.115 14.01.01 : lots of bug fixes, renamed from FD2Pragma to fd2pragma
195 2.116 28.01.01 : added internal types, SPECIAL 90, NOCPPNAMES and bug fixes,
196 VBCC inlines fix for data in A-regs
197 2.117 04.02.01 : changed NOCPPNAMES to ONLYCNAMES, added HUNKNAME, LocCode is
198 portable, added BASENAME, added VBCCWOSInlines
199 2.118 07.02.01 : added destination file printout, LIBTYPE, fixes VBCC-PUP-Code
200 2.119 11.02.01 : bug fixes
201 2.120 17.02.01 : added NOPPCREGNAME, bug fixes
202 2.121 04.03.01 : added MorphOS text
203 2.122 11.03.01 : little bug fixes
204 2.123 03.04.01 : now uses EXT_DEXT16 instead of EXT_REF16 also for 68k files
205 2.124 08.04.01 : bug fixes, added MorphOS binary mode, finally full portable
206 2.125 28.04.01 : added LVO's for PPC, started support for SFD format
207 2.126 29.05.01 : fixed PPC LVO's, removed STORMFD Option (auto detection),
208 now handles up to 5 alias names, finished SFD format read, added FD
209 creation, added keyword checks for argument names, lots of optimizations
210 and fixes, which came in hand with SFD inclusion.
211 Thanks Olaf Barthel for making the SFD stuff possible.
212 2.127 30.04.01 : private comments are skipped now, finished SFD production,
213 fixed bugs, removed SPECIAL 8 redirect (is replaced by 80-83)
214 2.128 01.05.01 : bug fixes
215 2.129 03.06.01 : included support for files previous made by vbcc genauto tool
216 2.130 04.06.01 : bug fixes in genauto stuff
217 2.131 11.06.01 : newer types handle cia now correct
218 2.132 27.06.01 : fixed crash caused by illegal interpretation of ANSI-C :-)
219 2.133 28.06.01 : added VOIDBASE argument
220 2.134 01.07.01 : added MorphOS types, fixed PowerUp stuff
221 2.135 28.07.01 : added VBCC inline varargs support
222 2.136 30.07.01 : fixed VBCC inline varargs
223 2.137 18.11.01 : little bug-fix
224 2.138 30.11.01 : fixed CLIB scanning (now a preparser cleans the file a lot)
225 2.139 13.12.01 : fixed ==libname scan and xvsBase
226 2.140 21.12.01 : fixed some uint32 in created files, which have been wrongly
227 introduced in 2.1xx versions when making tool portable
228 2.141 04.01.02 : fixed problem with multiple pointer function args like in
229 "void (**func)(void)"
230 2.142 07.01.02 : started new direct inline types 46 and 47.
231 2.143 08.01.02 : Fixed warnings, bugs, card.resouce entry and added
232 ==copyright directive
233 2.144 09.01.02 : Fixed MUI varargs inlines
234 2.145 03.03.02 : Some bug fixes
235 2.146 20.05.02 : one little bug fix, added support for missing empty () in
237 2.147 01.05.02 : now continues when detecting no fd-arg name
238 2.148 09.06.02 : fixed problem with MorphOS stubs, added AUTOHEADER keyword,
239 added auto type defaults to int, fixed bug with STACK type
240 2.149 24.06.02 : fixed lots of problems found when converting amissl includes
241 2.150 08.08.02 : fixed inline files a bit
242 2.151 31.08.02 : fixed SPECIAL 46 files (error when no args, but return value)
243 2.152 01.09.02 : bug-fix with SPECIAL 47
244 2.153 11.09.02 : modified SPECIAL 46 varargs on request of Sebastian Bauer
246 2.154 03.10.02 : added VBCC MorphOS inlines (SPECIAL 122). Thanks Frank Wille
248 2.155 04.10.02 : optimized VBCC MorphOS text (SPECIAL 93), fixed VBCC MorphOS
250 2.156 06.10.02 : added warning about obsolete types, fixed VBCC MorphOS Code
252 2.157 12.10.02 : Fixed CLIB scan problem
253 2.158 19.10.02 : added CLIB define in SPECIAL 46
254 2.159 16.11.02 : bugfix with SPECIAL 46 varargs redefine
255 2.160 04.12.02 : fixed bug in MorphOS-vbcc code
256 2.161 15.12.02 : now no longer includes clib files for GCC, the GCC inlines
257 include the needed include lines directly
258 2.162 26.01.03 : bug fixes, added updated fpc code made by Nils Sjöholm (it
259 is not that complicated to do fixes yourself, fd2pragma's inner
260 structure is really easy)
261 2.163 28.01.03 : little fixes
262 2.164 15.02.03 : fixed DirectInline for GCC mode, changed FPC layout
263 2.165 04.01.04 : fixed VBCC TAG inlines (SPECIAL 70), added modified MorphOS
264 FD file types, fixed GCC direct inlines for GCC 3
265 2.166 06.01.04 : added first set of OS4 filetypes
266 2.167 09.01.04 : more OS4 stuff, added library name comment scanning for SFD
267 2.168 19.01.04 : some fixes (a lot of thanks to Frank Wille)
268 2.169 22.01.04 : completed OS4 stuff
269 2.170 28.01.04 : some more VBCC-MOS things
270 2.171 26.02.04 : finished VBCC-MOS text
271 2.172 09.05.04 : (phx) fixed clib-parsing problem with splitted function
272 name and arguments over two lines, more flexible "base,sysv"
273 recognition for MorphOS, never use "Device *" pointer in a proto file
274 - should be "Library *"
275 2.173 10.05.04 : fixed MOS-base,sysv to allow autodetected Tag-Functions
276 2.174 23.05.04 : some fixes for MorphOS and VBCC
277 2.175 11.07.04 : (phx) has to recognize and skip 'extern "C" {', as a
278 result of my modifications in 2.172.
279 2.176 21.09.04 : added new MorphOS VBCC inlines and some other OS4 fixes
280 2.177 23.09.04 : minor bugfix
281 2.178 09.10.04 : (phx) vbcc: use __linearvarargs instead of __aos4varargs
282 2.179 09.11.04 : (phx) make it compile natively under AmigaOS 4.x
283 2.180 07.12.04 : (phx) don't create vbcc inlines for MUI_NewObject &
284 PM_MakeItem - otherwise the preprocessor gets confused
285 2.181 20.12.04 : made test for MUI_NewObject and PM_MakeItem based on a field
286 containing the names - allows easier expansion
287 2.182 16.01.05 : (phx) experimental MorphOS "(sysv)" support, which doesn't
288 need a base-register passed as first argument
289 2.183 24.01.05 : added support for long long types, nevertheless files using
290 that will not produce correct results for now
291 2.184 07.02.05 : (phx) Fixed FuncVBCCWOSCode() (special 73) to read the
292 function ptr from (bias-2) instead from (bias) for PPC0/2-ABI.
294 2.185 08.02.05 : (phx) Special 38 (proto with vbcc inline) always generates
295 an inline-include now, and is no longer restricted to MorphOS & 68k.
296 Special Warp3DPPC support.
297 Marked some powerpc.library functions, which were erroneously
298 detected as tag functions.
299 2.186 17.02.05 : fixed PPC0-mode VBCC WOS stubs
300 2.187 26.03.05 : (phx) "(sysv,r12base)" in MorphOS FD-files is supported.
301 I made it identical to (sysv), which both load the library base
302 to r12 (correct in (sysv,r12base) mode and can't hurt in (sysv) mode).
303 Allow "(void)" instead of "()" as parameter list.
304 Function-pointer types can extend over multiple lines now (does
305 this make sense for other types too?).
306 New SDL-types: FPSmanager, Mix_Chunk, Mix_Music, Mix_MusicType,
307 Mix_EffectFunc_t, Mix_EffectDone_t, Mix_Fading, IPaddress,
308 TCPsocket, UDPpacket, UDPsocket, SDLNet_SocketSet,
309 SDLNet_GenericSocket, TTF_Font.
310 Put some of SDL-gfx functions ("...RGBA()") in the exceptions list.
311 2.188 30.03.05 : (phx) Put NewObject() into the NoInline-list.
312 2.189 21.05.05 : (phx) Always include emul/emulregs.h in vbcc/MOS inlines.
313 2.190 23.08.05 : (phx) Use ".file <name>.o" in assembler sources, HUNK_NAME
314 and ELF ST_FILE symbols. It was "<name>.s" before, which is wrong.
315 2.191 01.11.05 : (phx) Rewrote FuncVBCCWOSInline() based on the MOSInline-
316 function, to be able to handle varargs functions correctly.
317 Also fixed WOS-text and -code generation for PPC0-ABI.
318 2.192 06.01.10 : (phx) Do vbcc MorphOS OS-calls with BCTRL instead of BLRL
319 to avoid messing up the LR-stack of more recent PowerPCs (G4+).
320 2.193 18.09.10 : (phx) GLContext type (tinygl).
321 2.194 03.01.11 : (mazze) Fix for building it on CYGWIN.
322 Added AROS support in the proto file.
325 /* A short note, how fd2pragma works.
326 Working mode for SPECIAL 200 is a bit different!
327 The main function parses arguments. Switches are converted into FLAG_XXX
328 values and stored in global "Flags" or "Flags2" variable. SPECIAL numbers
329 are parsed and are used to call a CreateXXX function, with its interface
330 depending on the need of arguments (Some have 2, some none, ...). Before
331 SPECIAL arguments are parsed, fd2pragma loads (S)FD file and scans it using
332 Scan(S)FDFile(). If SORTED is specified, the list gets sorted nearly directly
333 afterwards. IF CLIB argument is given, the clib file is scanned after FD file
334 and a clib list is created. Now SPECIAL is parsed and mode is set to any of
335 the MODUS_XXX values. Also the destination file name is created if not given.
336 The destination file is opened now.
338 The mode variable is used to determine the correct CreateXXX function,
339 which is called afterwards. This function produces file headers and stuff
340 like that and calls CallFunc to process each FD entry.
342 CallFunc gets 3 arguments. First the workmode (TAG, NORMAL, BOTH).
343 Second the comment method (for C it is "/%s *\x2F\n", for ASM it is "\n%s",
344 no comment is reached with 0 argument). The last is most important. It is the
345 function pointer to a function creating the entries. These functions have
346 always the same interface and are called through CallFunc only! They create
347 an entry for the specified function (e.g. FD entry). Parsing special
348 functions, adding comments, checking for tag-functions, ... is done by
349 CallFunc. It is no problem to call CallFunc multiple with different function
350 pointers (as is done for SPECIAL 6 pragmas).
351 This is also the method if information abount the type or number of functions
352 is needed somewhere in the begin of the output file. A special function to
353 collect this data needs to be started before doing real output. Althought I
354 do not like it much, global variables or flags can be used to store that
357 The functions can use DoOutput to output texts in printf style or
358 DoOutputDirect to output all data in fwrite style. Buffering is done
361 fd2pragma has its own memory managment. All memory must be allocated using
362 AllocListMem and is freed automatically. This is especially useful for
363 DupString function, which is used in FD, SFD and CLIB scanner.
365 Normally this source-file is to big and should be splitted into different
366 files compiled alone and linked together. :-) It takes about 20 minutes to
367 compile it on my Amiga system with optimizations turned on.
369 There are lots of different input and output types and some combinations
370 are really useless or wrong. fd2pragma has the mechanisms to catch these
371 cases properly, but not all cases are really checked, as there are too many
372 of them and each new input type increases the number of combinations.
373 Also not all useful combinations me be handled correctly. If you find a
374 case which really matters please inform me. All the others require the
375 users to use their brains :-)
385 /* These are the only allowed variable types of all related programs! */
387 #include <exec/types.h>
389 typedef signed char int8
; /* signed 8 bit */
390 typedef unsigned char uint8
; /* unsigned 8 bit */
391 typedef signed short int int16
; /* signed 16 bit */
392 typedef unsigned short int uint16
; /* unsigned 16 bit */
393 typedef signed long int int32
; /* signed 32 bit */
394 typedef unsigned long int uint32
; /* unsigned 32 bit */
396 typedef float fl32
; /* 32 bit IEEE float value */
397 typedef double fl64
; /* 64 bit IEEE double value */
398 typedef char string
; /* the string datatype [e.g. one character of string!] */
399 typedef char * strptr
; /* and an string pointer */
401 #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
402 (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
403 #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
404 #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
405 (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
406 #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
408 #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
409 #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
410 #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
411 #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
413 #define TEXT_SAS "__SASC" /* verified */
414 #define TEXT_SAS_60 "__SASC_60" /* verified */
415 #define TEXT_MAXON "__MAXON__" /* verified */
416 #define TEXT_STORM "__STORM__" /* verified */
417 #define TEXT_DICE "_DCC" /* in 2.0 code */
418 #define TEXT_AZTEC "AZTEC_C" /* verified */
419 #define TEXT_GNUC "__GNUC__" /* verified */
420 #define TEXT_VBCC "__VBCC__" /* verified */
422 #define TEMPSIZE 20480
424 #define FLAG_EXTERNC (1<< 0) /* add externc statements */
425 #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
426 #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
427 #define FLAG_PRIVATE (1<< 3) /* also use private functions */
428 #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
429 #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
430 #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
431 #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
432 #define FLAG_DONE (1<< 8) /* destination file is not empty */
433 #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
434 #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
435 #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
436 #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
437 #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
438 #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
439 #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
440 #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
441 #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
442 #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
443 #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
444 #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
445 #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
446 #define FLAG_STORMGCC (1<<22) /* special workaround for StormGCC */
447 #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
448 #define FLAG_MORPHOS (1<<24) /* create MorphOS files */
449 #define FLAG_SORTED (1<<25) /* sort the functions by name */
450 #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
451 #define FLAG_SINGLEFILE (1<<27) /* create single files */
452 #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
453 #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
454 #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
455 #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
457 #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
458 #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
459 #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
460 #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
461 #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
462 #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
463 #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
464 #define FLAG2_VOIDBASE (1<< 7) /* library base should be of type "void *" */
465 #define FLAG2_INLINEMAC (1<< 8) /* use inline macro instead of function */
466 #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
467 #define FLAG2_PRELIB (1<<10) /* MorphOS gate PRELIB flag */
468 #define FLAG2_POSTLIB (1<<11) /* MorphOS gate POSTLIB flag */
469 #define FLAG2_REGLIB (1<<12) /* MorphOS gate REGLIB flag */
470 #define FLAG2_OLDVBCC (1<<13) /* old VBCC style */
471 #define FLAG2_SMALLTYPES (1<<14) /* allow small data types */
472 #define FLAG2_AUTOHEADER (1<<15) /* creates auto generated header */
473 #define FLAG2_LIBNAMECOM (1<<16) /* libname was specified in SFD comment */
474 #define FLAG2_OS4M68KCSTUB (1<<17) /* OS4 M68K stub needs C */
475 #define FLAG2_SHORTPPCVBCCINLINE (1<<18) /* shorter PPC inline using argument */
477 #define FUNCFLAG_NORMAL (1<<0) /* normal function */
478 #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
479 #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
480 #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
482 /* Different modes the main program uses, one for each different file
483 type (except for those done with one function and flag settings). */
484 #define MODUS_STUBTEXT 1
485 #define MODUS_STUBCODE 2
486 #define MODUS_LOCALDATA 3
487 #define MODUS_PRAGMA 4
488 #define MODUS_CSTUB 5
489 #define MODUS_SASPOWER 6
490 #define MODUS_PROTOPOWER 7
492 #define MODUS_PASCAL 9
493 #define MODUS_VBCCINLINE 10
494 #define MODUS_VBCCPUPLIB 11
495 #define MODUS_LVOLIB 12
496 #define MODUS_EMODULE 13
497 #define MODUS_REDIRECT 14
498 #define MODUS_ASMTEXTSF 15
499 #define MODUS_VBCCPUPTEXTSF 16
500 #define MODUS_VBCCWOSTEXTSF 17
501 #define MODUS_VBCCWOSINLINE 18
502 #define MODUS_VBCCMORPHTEXTSF 19
503 #define MODUS_VBCCMORPHCODE 20
504 #define MODUS_LVOLIBPPC 21
506 #define MODUS_CLIB 23
508 #define MODUS_GATESTUBS 25
509 #define MODUS_VBCCMORPHINLINE 26
511 #define MODUS_OS4_PPCSTUBS 28
512 #define MODUS_OS4_68KSTUBS 29
513 #define MODUS_LVO 50 /* and 51 and 52 and 53 */
514 #define MODUS_PROTO 60 /* and 61 to 69 */
515 /* new protos start with 90, but are added to MODUS_PROTO ! */
516 #define MODUS_INLINE 80 /* and 81 to 86 */
517 #define MODUS_VBCC 90 /* and 91 to 94 */
518 #define MODUS_LVOPPC 100 /* and 101 */
519 #define MODUS_GENAUTO 110 /* and 111 to 113 */
520 #define MODUS_ERROR 200
522 enum ABI
{ABI_M68K
, ABI_PPC
, ABI_PPC2
, ABI_PPC0
};
524 /* call types for CallFunc */
525 #define TAGMODE_NORMAL 0 /* produce normal functions only */
526 #define TAGMODE_TAGS 1 /* produce only tag functions */
527 #define TAGMODE_BOTH 2 /* produce both types */
529 /* types specifying name method for pragma creation */
530 #define PRAGMODE_PRAGLIB 1
531 #define PRAGMODE_PRAGSLIB 2
532 #define PRAGMODE_PRAGSPRAGS 3
533 #define PRAGMODE_NONE 4
535 #define BIAS_START 30 /* the library start offset */
536 #define BIAS_OFFSET 6 /* value to switch from one to next function */
538 #ifndef FD2PRAGMA_AMIGA
539 #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
542 #define EXTTYPESFILE "fd2pragma.types"
544 #ifndef EXTTYPESFILE2
545 #ifdef FD2PRAGMA_AMIGA
546 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
548 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
552 #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
554 #define FDFILEEXTENSION "_lib.fd"
555 #define SFDFILEEXTENSION "_lib.sfd"
557 static const strptr RegNames
[] = {
558 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
559 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
560 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
563 static const strptr RegNamesUpper
[] = {
564 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
565 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
566 "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
570 REG_D0
, REG_D1
, REG_D2
, REG_D3
, REG_D4
, REG_D5
, REG_D6
, REG_D7
,
571 REG_A0
, REG_A1
, REG_A2
, REG_A3
, REG_A4
, REG_A5
, REG_A6
, REG_A7
,
572 REG_FP0
, REG_FP1
, REG_FP2
, REG_FP3
, REG_FP4
, REG_FP5
, REG_FP6
, REG_FP7
575 #define MAXREG 24 /* maximum registers of 68K */
576 #define MAXREGNF 16 /* maximum register number without float regs */
577 #define UNDEFREGISTER 255 /* for type scanner */
589 struct ShortList
*Next
;
592 struct ShortListRoot
{
593 struct ShortList
*First
;
594 struct ShortList
*Last
;
598 #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
599 #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
600 #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
601 #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
602 #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
603 #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
604 #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
605 #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
606 #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
607 #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
608 #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
609 #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
610 #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
611 #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
612 #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
613 #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
614 #define AMIPRAGFLAG_MOSSYSV (1<<16) /* MorphOS(sysv) type */
615 #define AMIPRAGFLAG_MOSSYSVR12 (1<<17) /* MorphOS(sysv,r12base) type */
616 #define AMIPRAGFLAG_MOSBASESYSV (1<<18) /* MorphOS(base,sysv) type */
617 #define AMIPRAGFLAG_VARARGS (1<<19) /* last argument is ... */
619 #define AMIPRAGFLAG_MOS_ALL (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12|AMIPRAGFLAG_MOSBASESYSV)
626 #define NUMALIASNAMES 5
629 struct ShortList List
;
634 struct Pragma_AliasName
* AliasName
[NUMALIASNAMES
]; /* alias names */
635 uint16 NumArgs
; /* register numbers */
636 uint16 CallArgs
; /* argument number in fd file */
640 struct AmiArgs Args
[MAXREGPPC
];
644 struct ShortList List
;
649 uint8 Private
; /* is a flag only */
653 struct ShortList List
;
658 struct ShortList List
;
659 struct ShortListRoot Data
; /* contains list of PragData */
664 struct ShortList List
;
665 struct ShortListRoot Name
;
669 uint8 ArgReg
[MAXREG
];
676 uint32 Mode
; /* 0 = Normal, != 0 is TagName */
678 uint8 ArgReg
[MAXREG
];
681 /* NOTE: string creation for CPP-Functions probably does not work at all
682 at the moment, as every compiler uses different systems which seem to
683 change constantly. */
685 /* These CPP types match the strings used for CPP name creation. The
686 defines are used both for name creation and type specification. */
687 #define CPP_TYPE_VOID 'v' /* void, VOID */
688 #define CPP_TYPE_BYTE 'c' /* char, int8 */
689 #define CPP_TYPE_WORD 's' /* short, int16 */
690 #define CPP_TYPE_LONG 'j' /* long, int32 */
691 #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
692 #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
693 #define CPP_TYPE_INT 'i' /* int */
694 #define CPP_TYPE_STRUCTURE 0
695 #define CPP_TYPE_VARARGS 'e'
696 #define CPP_TYPE_LONGLONG 'l' /* long long, int64 */
698 /* These types are for string creation only. */
699 #define CPP_TYPE_ENUM 'E'
700 #define CPP_TYPE_CONST 'C'
701 #define CPP_TYPE_FUNCTION 'F'
702 #define CPP_TYPE_POINTER 'P'
703 #define CPP_TYPE_UNSIGNED 'U'
704 #define CPP_TYPE_FUNCEND 'p'
705 #define CPP_TYPE_REGISTER 'r'
707 /* Some flags to be used in CPP_NameType->Flags. */
708 #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
709 #define CPP_FLAG_CONST (1<<1) /* type is const */
710 #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
711 #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
712 #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
713 #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
714 #define CPP_FLAG_UNION (1<<6) /* it is a union */
715 #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
716 #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
717 #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
718 #define CPP_FLAG_TYPEDEFNAME (1<<10) /* name is created from typedef */
719 #define CPP_FLAG_ARRAY (1<<11) /* this type is an array */
720 #define CPP_FLAG_LONG (1<<12) /* type is long */
721 /* STRPTR is defined different under C and CPP -> I have to create two
722 names, one time unsigned char *, one time signed char *, when somewhere
725 #define COPYCPP_PASSES 4
727 struct CPP_NameType
{ /* structure to describe a argument type */
728 strptr StructureName
; /* if a structure or enum only */
729 strptr FuncArgs
; /* arguments of function - unterminated */
730 strptr TypeStart
; /* start of this type */
731 strptr Replace
; /* replacement of type for SFD files */
732 strptr Unknown
; /* unknown type handled as int */
733 strptr FunctionName
; /* Argument name of function argument */
734 struct ClibData
*FuncPtr
; /* if it is a function pointer */
735 uint16 StructureLength
; /* length of the structure name */
736 uint16 ArgsLength
; /* length of FuncArgs */
737 uint16 TypeLength
; /* length of this type */
738 uint16 FullLength
; /* length of complete type */
739 uint16 PointerDepth
; /* number of * in type */
740 uint16 FuncPointerDepth
; /* number of * in function pointer */
741 uint16 Flags
; /* see above flags */
742 uint8 Type
; /* see above defines */
743 uint8 Register
; /* register number */
746 struct ClibData
{ /* structure to describe data in CLIB file */
747 struct ClibData
* Next
; /* The next entry in this list */
748 strptr FuncName
; /* name of the function */
749 struct CPP_NameType ReturnType
; /* data for return type */
750 struct CPP_NameType Args
[MAXREGPPC
+1]; /* data for argument types */
751 uint16 NumArgs
; /* number of arguments */
754 struct CPP_ExternNames
{ /* structure for EXTTYPESFILE data */
755 struct CPP_ExternNames
* Next
; /* The next entry in this list */
756 strptr Type
; /* The unknown type */
757 struct CPP_NameType NameType
; /* The replacement */
760 struct CPP_TypeField
{ /* structure for internal defined types */
761 strptr Text
; /* name of the type */
762 uint16 Length
; /* length of the name string */
763 uint16 Flags
; /* CPP_FLAG flags */
764 uint8 Type
; /* CPP_TYPE value */
768 struct CPP_Unknown
*Next
;
772 struct Proto_LibType
{ /* structure to define structure type of base vars */
773 strptr BaseName
; /* name of the library base */
774 strptr StructureName
; /* name of the structure to be used (0 for default) */
775 strptr LibraryName
; /* name of the library (maybe 0 for default method) */
776 strptr ShortBaseName
; /* short name of the library base */
779 struct Pragma_ExecpName
{ /* structure to specify special tagnames */
780 strptr FunctionName
; /* function name */
781 strptr TagName
; /* tag name to be used for this function */
782 }; /* TagName 0 is valid as well to disable tagfunctions */
784 struct Pragma_AliasName
{
790 #define NTP_NORMAL 0 /* no tags/args */
791 #define NTP_TAGS 1 /* TagFunction */
792 #define NTP_ARGS 2 /* ArgFunction */
793 #define NTP_UNKNOWN 3 /* CommentFunction */
796 struct ShortList List
;
797 uint32 Type
; /* set by OptimizeFDData */
808 /* EHF definitions! */
809 #define HUNK_PPC_CODE 0x4E9
810 #define HUNK_RELRELOC26 0x4EC
811 #define EXT_RELREF26 229
813 /* ------------------------------------------------------------------ */
814 /* A short set of ELF definitions, see pasm sources in vbcc release for an
815 more complete set of stuff or get elf documentation. These are needed for
816 VBCCPUPCode function. */
818 #define ELFDATA2MSB 2
819 #define EV_CURRENT 1 /* version information */
820 #define ET_REL 1 /* type information */
821 #define EM_POWERPC 20
823 #define SHT_NULL 0 /* inactive */
824 #define SHT_PROGBITS 1 /* program information */
825 #define SHT_SYMTAB 2 /* symbol table */
826 #define SHT_STRTAB 3 /* string table */
827 #define SHT_RELA 4 /* relocation */
829 #define SHF_ALLOC 0x2 /* needs memory when started */
830 #define SHF_EXECINSTR 0x4 /* executable instructions */
832 #define SHN_ABS 0xFFF1
847 #define STT_SECTION 3
849 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
850 #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
852 #define R_PPC_ADDR16_LO 4
853 #define R_PPC_ADDR16_HA 6
854 #define R_PPC_REL24 10
855 #define R_PPC_SDAREL16 32
858 string ar_name
[16]; /* name */
859 string ar_time
[12]; /* modification time */
860 string ar_uid
[6]; /* user id */
861 string ar_gid
[6]; /* group id */
862 string ar_mode
[8]; /* octal file permissions */
863 string ar_size
[10]; /* size in bytes */
864 string ar_fmag
[2]; /* consistency check */
867 /* AmigaOS hunk structure definitions */
869 #include <dos/doshunks.h>
871 #define HUNK_UNIT 999
872 #define HUNK_NAME 1000
873 #define HUNK_CODE 1001
874 #define HUNK_BSS 1003
875 #define HUNK_ABSRELOC32 1004
876 #define HUNK_EXT 1007
877 #define HUNK_SYMBOL 1008
878 #define HUNK_END 1010
879 #define HUNK_DREL16 1016
881 #define EXT_DEF 1 /* normal definition */
882 #define EXT_ABS 2 /* Absolute definition */
883 #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
884 #define EXT_DEXT16 134 /* 16 bit data relative reference */
886 /* ------------------------------------------------------------------ */
888 static struct Args args
= {0,0,0,0,6,0};
889 static struct InFile in
= {0,0,0};
890 static FILE * outfile
;
891 static struct ClibData
* clibdata
= 0;
892 static struct ShortListRoot AmiPragma
= {0,0,sizeof(struct AmiPragma
)},
893 Comment
= {0,0,sizeof(struct Comment
)},
894 Includes
= {0,0,sizeof(struct Include
)};
895 static struct CPP_ExternNames
*extnames
= 0;
896 static struct CPP_Unknown
*unknown
= 0;
897 static strptr BaseName
= 0; /* the correct basename */
898 /* the filename part of basename without Base */
899 static strptr ShortBaseName
= 0;
900 /* like ShortBaseName, but upper case */
901 static strptr ShortBaseNameUpper
= 0;
902 static strptr HEADER
= 0;
903 static strptr Copyright
= 0;
904 static strptr filenamefmt
= 0;
905 static strptr libtype
= 0;
906 static strptr libname
= 0;
907 static strptr defabi
= 0;
908 static strptr hunkname
= ".text";
909 static strptr datahunkname
= "__MERGED";
910 static strptr PPCRegPrefix
= "r";
911 static strptr IDstring
= 0;
912 static strptr prefix
= "";
913 static strptr subprefix
= "";
914 static strptr premacro
= "";
915 static uint8
* tempbuf
= 0;
916 static size_t headersize
= 0;
917 static uint32 Flags
= 0;
918 static uint32 Flags2
= 0;
919 /* Output error occured when 0 */
920 static uint32 Output_Error
= 1;
921 /* are there some tagfuncs in FD */
922 static uint32 tagfuncs
= 0;
923 /* priority for auto libopen */
924 static uint32 priority
= 5;
925 /* needed for filename */
926 static string filename
[255];
928 /* Only for E-Stuff, FD, SFD, XML creation */
929 static int32 LastBias
= 0;
930 /* Only for PPC-LVO Lib's */
931 static uint8
* elfbufpos
= 0;
932 /* Only for PPC-LVO Lib's */
933 static uint32 symoffset
= 0;
934 /* Only for FD, SFD creation */
935 static enum ABI CurrentABI
= ABI_M68K
;
937 /* Prototypes for the functions */
938 static strptr
DupString(strptr
, size_t);
939 static strptr
AllocListMem(size_t);
940 static strptr
SkipBlanks(strptr
);
941 static strptr
SkipBlanksRet(strptr
);
942 static strptr
SkipName(strptr
);
943 static uint32
GetTypes(void);
944 static strptr
GetBaseType(void);
945 static strptr
GetBaseTypeLib(void);
946 static strptr
GetLibraryName(void);
947 static strptr
GetIFXName(void);
948 static int32
MakeShortBaseName(void);
949 static uint32
OpenDest(strptr
);
950 static uint32
CloseDest(strptr
);
951 static uint32
MakeTagFunction(struct AmiPragma
*);
952 static void MakeLines(strptr
, uint32
);
953 static uint32
SpecialFuncs(void);
954 static void SortFDList(void);
955 static void AddAliasName(struct AmiPragma
*, struct Pragma_AliasName
*,
957 static uint32
CheckNames(struct AmiPragma
*);
958 static uint32
ScanSFDFile(enum ABI
);
959 static uint32
ScanFDFile(void);
960 static int32
ScanTypes(strptr
, uint32
);
961 static void FindHeader(void);
962 static uint32
GetRegisterData(struct AmiPragma
*);
963 static uint16
GetFRegisterData(struct AmiPragma
*);
964 static uint32
OutputXDEF(uint32
, strptr
, ...);
965 static uint32
OutputXREF(uint32
, uint32
, strptr
, ...);
966 static uint32
OutputXREF2(uint32
, uint32
, uint32
, strptr
, ...);
967 static uint32
OutputSYMBOL(uint32
, strptr
, ...);
968 static uint8
* AsmStackCopy(uint8
*, struct AmiPragma
*, uint32
, uint32
);
969 /* ------------------------------------------------------------------ */
970 static void DoError(uint32
, uint32
, ...);
971 static uint32
CheckError(struct AmiPragma
*, uint32
);
972 static uint32
DoOutputDirect(void *, size_t);
974 #if defined(__GNUC__)
975 static uint32
DoOutput(strptr
, ...) __attribute__ ((format(printf
, 1, 2)));
977 static uint32
DoOutput(strptr
, ...);
979 /* ------------------------------------------------------------------ */
980 static struct ShortList
*NewItem(struct ShortListRoot
*);
981 static struct ShortList
*RemoveItem(struct ShortListRoot
*, struct ShortList
*);
982 static void AddItem(struct ShortListRoot
*, struct ShortList
*);
983 /* ------------------------------------------------------------------ */
984 typedef uint32 (*FuncType
)(struct AmiPragma
*, uint32
, strptr
);
986 uint32
FuncAMICALL (struct AmiPragma
*, uint32
, strptr
);
987 uint32
FuncLIBCALL (struct AmiPragma
*, uint32
, strptr
);
988 uint32
FuncAsmText (struct AmiPragma
*, uint32
, strptr
);
989 uint32
FuncAsmCode (struct AmiPragma
*, uint32
, strptr
);
990 uint32
FuncCSTUBS (struct AmiPragma
*, uint32
, strptr
);
991 uint32
FuncLVOXDEF (struct AmiPragma
*, uint32
, strptr
);
992 uint32
FuncLVO (struct AmiPragma
*, uint32
, strptr
);
993 uint32
FuncLVOPPCXDEF (struct AmiPragma
*, uint32
, strptr
);
994 uint32
FuncLVOPPC (struct AmiPragma
*, uint32
, strptr
);
995 uint32
FuncLVOPPCBias (struct AmiPragma
*, uint32
, strptr
);
996 uint32
FuncLVOPPCName (struct AmiPragma
*, uint32
, strptr
);
997 uint32
FuncLVOLib (struct AmiPragma
*, uint32
, strptr
);
998 uint32
FuncLocCode (struct AmiPragma
*, uint32
, strptr
);
999 uint32
FuncLocText (struct AmiPragma
*, uint32
, strptr
);
1000 uint32
FuncInline (struct AmiPragma
*, uint32
, strptr
);
1001 uint32
FuncInlineDirect (struct AmiPragma
*, uint32
, strptr
);
1002 uint32
FuncInlineNS (struct AmiPragma
*, uint32
, strptr
);
1003 uint32
FuncPowerUP (struct AmiPragma
*, uint32
, strptr
);
1004 uint32
FuncFPCUnit (struct AmiPragma
*, uint32
, strptr
);
1005 uint32
FuncFPCType (struct AmiPragma
*, uint32
, strptr
);
1006 uint32
FuncFPCTypeTags (struct AmiPragma
*, uint32
, strptr
);
1007 uint32
FuncFPCTypeTagsUnit (struct AmiPragma
*, uint32
, strptr
);
1008 uint32
FuncBMAP (struct AmiPragma
*, uint32
, strptr
);
1009 uint32
FuncVBCCInline (struct AmiPragma
*, uint32
, strptr
);
1010 uint32
FuncVBCCWOSInline (struct AmiPragma
*, uint32
, strptr
);
1011 uint32
FuncVBCCMorphInline (struct AmiPragma
*, uint32
, strptr
);
1012 uint32
FuncVBCCWOSText (struct AmiPragma
*, uint32
, strptr
);
1013 uint32
FuncVBCCWOSCode (struct AmiPragma
*, uint32
, strptr
);
1014 uint32
FuncVBCCPUPText (struct AmiPragma
*, uint32
, strptr
);
1015 uint32
FuncVBCCPUPCode (struct AmiPragma
*, uint32
, strptr
);
1016 uint32
FuncEModule (struct AmiPragma
*, uint32
, strptr
);
1017 uint32
FuncVBCCMorphText (struct AmiPragma
*, uint32
, strptr
);
1018 uint32
FuncVBCCMorphCode (struct AmiPragma
*, uint32
, strptr
);
1019 uint32
FuncFD (struct AmiPragma
*, uint32
, strptr
);
1020 uint32
FuncClib (struct AmiPragma
*, uint32
, strptr
);
1021 uint32
FuncSFD (struct AmiPragma
*, uint32
, strptr
);
1022 uint32
FuncXML (struct AmiPragma
*, uint32
, strptr
);
1023 uint32
FuncOS4PPC (struct AmiPragma
*, uint32
, strptr
);
1024 uint32
FuncOS4M68KCSTUB (struct AmiPragma
*, uint32
, strptr
);
1025 uint32
FuncOS4M68K (struct AmiPragma
*, uint32
, strptr
);
1026 uint32
FuncOS4M68KVect (struct AmiPragma
*, uint32
, strptr
);
1027 uint32
FuncGateStubs (struct AmiPragma
*, uint32
, strptr
);
1028 static uint32
PrintComment (struct Comment
*, strptr
);
1029 static uint32
DoCallFunc (struct AmiPragma
*, uint32
, strptr
, FuncType
);
1030 static uint32
CallFunc (uint32
, strptr
, FuncType
);
1031 static uint32
PrintIncludes(void);
1032 /* ------------------------------------------------------------------ */
1033 static int32
AddClibEntry(strptr
, strptr
, uint32
);
1034 static int32
ScanClibFile(strptr
, strptr
);
1035 static int32
IsCPPType(struct CPP_NameType
*, uint8
);
1036 static uint32
CheckRegisterNum(strptr
, struct CPP_NameType
*);
1037 static uint32
ParseFuncPtrArgs(strptr
, struct CPP_NameType
*);
1038 static int32
GetCPPType(struct CPP_NameType
*, strptr
, uint32
, uint32
);
1039 static struct ClibData
*GetClibFunc(strptr
, struct AmiPragma
*, uint32
);
1040 static int32
CheckKeyword(strptr
, strptr
, int32
);
1041 static uint32
CopyCPPType(strptr
, uint32
, struct ClibData
*, struct AmiArgs
*);
1042 static uint32
OutClibType(struct CPP_NameType
*, strptr
);
1043 static uint32
MakeClibType(strptr
, struct CPP_NameType
*, strptr
);
1044 static uint32
OutPASCALType(struct CPP_NameType
*, strptr
, uint32
);
1045 /* ------------------------------------------------------------------ */
1046 static uint32
CallPrag(uint32
, strptr
, FuncType
);
1047 static uint32
CreatePragmaFile(strptr
, strptr
, strptr
, strptr
, uint32
);
1048 static uint32
CreateCSTUBSFile(void);
1049 static uint32
CreateLVOFile(uint32
);
1050 static uint32
CreateLVOFilePPC(uint32
);
1051 static uint32
CreateAsmStubs(uint32
, uint32
);
1052 static uint32
CreateProtoFile(uint32
);
1053 static uint32
CreateLocalData(strptr
, uint32
);
1054 static uint32
CreateInline(uint32
, uint32
);
1055 static uint32
CreateGateStubs(uint32
);
1056 static uint32
CreateSASPowerUP(uint32
);
1057 static uint32
CreateProtoPowerUP(void);
1058 static uint32
CreateFPCUnit(void);
1059 static uint32
CreateBMAP(void);
1060 static uint32
CreateLVOLib(void);
1061 static uint32
CreateLVOLibPPC(void);
1062 static uint32
CreateVBCCInline(uint32
, uint32
);
1063 static uint32
CreateVBCC(uint32
, uint32
);
1064 static uint32
CreateVBCCPUPLib(uint32
);
1065 static uint32
CreateVBCCMorphCode(uint32
);
1066 static uint32
CreateEModule(uint32
);
1067 static uint32
CreateProtoRedirect(void);
1068 static uint32
CreateFD(void);
1069 static uint32
CreateSFD(uint32
);
1070 static uint32
CreateClib(uint32
);
1071 static uint32
CreateGenAuto(strptr
, uint32
);
1072 static uint32
CreateXML(void);
1073 static uint32
CreateOS4PPC(uint32
);
1074 static uint32
CreateOS4M68K(void);
1075 /* ------------------------------------------------------------------ */
1076 static uint32
GetName(struct NameList
*, struct ShortListRoot
*, uint32
);
1077 static uint32
MakeFD(struct PragList
*);
1078 static void OptimizeFDData(struct PragData
*);
1079 static string
GetHexValue(string
);
1080 static string
GetDoubleHexValue(strptr
);
1081 static uint32
AddFDData(struct ShortListRoot
*, struct FDData
*);
1082 static uint32
GetLibData(struct FDData
*);
1083 static uint32
GetFlibData(struct FDData
*);
1084 static uint32
GetAmiData(struct FDData
*);
1085 static uint32
CreateFDFile(void);
1086 /* ------------------------------------------------------------------ */
1087 static void GetArgs(int argc
, char **argv
);
1088 static strptr
mygetfile(strptr name
, size_t *len
);
1090 #define ERROFFSET_CLIB (1<<31)
1093 ERR_TAGFUNC_NEEDS_ARGUMENT
,
1094 ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
,
1095 ERR_TAG_DEF_WITHOUT_PRAGMA
,
1096 ERR_BASENAME_DECLARED_TWICE
,
1097 ERR_EXPECTED_SLASH_IN_BASENAME
,
1098 ERR_EXPECTED_BASENAME
,
1099 ERR_EXPECTED_BIAS_VALUE
,
1100 ERR_ASSUMING_POSITIVE_BIAS_VALUE
,
1101 ERR_MISSING_FUNCTION_NAME
,
1102 ERR_EXPECTED_OPEN_BRACKET
,
1103 ERR_TO_MUCH_ARGUMENTS
,
1104 ERR_EXPECTED_ARGUMENT_NAME
,
1105 ERR_EXPECTED_CLOSE_BRACKET
,
1106 ERR_EXPECTED_REGISTER_NAME
,
1108 ERR_REGISTER_USED_TWICE
,
1109 ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
,
1110 ERR_ASSUMING_BIAS_OF_30
,
1111 ERR_EXTRA_CHARACTERS
,
1112 ERR_MISSING_BASENAME
,
1115 ERR_DIFFERENT_TO_PREVIOUS
,
1116 ERR_UNKNOWN_VARIABLE_TYPE
,
1119 ERR_PROTOTYPE_MISSING
,
1120 ERR_NOPROTOTYPES_FILE
,
1121 ERR_UNKNOWN_DIRECTIVE
,
1122 ERR_INLINE_A4_AND_A5
,
1123 ERR_INLINE_D7_AND_A45
,
1124 ERR_MISSING_SHORTBASENAME
,
1127 ERR_FLOATARG_NOT_ALLOWED
,
1128 ERR_WRONG_TYPES_LINE
,
1133 ERR_PPC_FUNCTION_NOT_SUPPORTED
,
1136 ERR_ILLEGAL_FUNCTION_POSITION
,
1138 ERR_COMMENT_SINGLEFILE
,
1139 ERR_NOFD2PRAGMATYPES
,
1140 ERR_M68K_FUNCTION_NOT_SUPPORTED
,
1141 ERR_UNKNOWN_RETURNVALUE_TYPE
,
1143 ERR_EXCPECTED_IDSTRING
,
1144 ERR_EXPECTED_ID_ENDSIGN
,
1146 ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
,
1147 ERR_IDSTRING_DECLARED_TWICE
,
1148 ERR_COMMANDLINE_LIBTYPE
,
1149 ERR_COMMANDLINE_BASENAME
,
1150 ERR_LIBTYPE_DECLARED_TWICE
,
1151 ERR_EXPECTED_LIBTYPE
,
1155 ERR_VARARGS_ARGUMENTS_DIFFER
,
1156 ERR_UNEXPECTED_FILEEND
,
1157 ERR_VARARGS_ALIAS_FIRST
,
1159 ERR_EXPECTED_STRUCT
,
1160 ERR_EXPECTED_POINTERSIGN
,
1161 ERR_ARGNAME_KEYWORD_CONFLICT
,
1162 ERR_ARGNAME_ARGNAME_CONFLICT
,
1163 ERR_ONLYTAGMODE_NOTALLOWED
,
1164 ERR_COMMANDLINE_LIBNAME
,
1165 ERR_LIBNAME_DECLARED_TWICE
,
1166 ERR_EXPECTED_LIBNAME
,
1168 ERR_MULTIPLEFUNCTION
,
1169 ERR_INLINE_AX_SWAPREG
,
1171 ERR_ILLEGAL_CHARACTER_DETECTED
,
1172 ERR_UNKNOWN_VARIABLE_TYPE_INT
,
1173 ERR_UNKNOWN_RETURNVALUE_TYPE_INT
,
1174 ERR_ILLEGAL_INTERNAL_VALUE
,
1175 ERR_MOSBASESYSV_NOT_SUPPORTED
,
1176 ERR_ALIASES_NOT_SUPPORTED
,
1177 ERR_FUNCTION_NOT_SUPPORTED
,
1180 static const struct ErrField
{
1181 uint8 Type
; /* 0 = Error, 1 = Warning */
1185 {1, 1, "Tag function must have arguments."},
1186 {1, 1, "Cannot convert pragma name into tag name."},
1187 {1, 1, "Tag definition without preceding Pragma."},
1188 {1, 0, "Basename declared twice."},
1189 {1, 0, "Expected preceding _ in Basename."},
1190 {1, 1, "Expected Basename."},
1191 {1, 0, "Expected Bias value."},
1192 {1, 0, "Assuming positive bias value."},
1193 {1, 1, "Missing function name."},
1194 {1, 1, "Expected '('."},
1195 {1, 1, "Too much arguments."},
1196 {1, 1, "Expected argument name."},
1197 {1, 1, "Expected ')'."},
1198 {1, 1, "Expected register name."},
1199 {1, 1, "A7 not allowed as argument register."},
1200 {1, 1, "Register used twice."},
1201 {1, 0, "Number of arguments != number of registers."},
1202 {1, 0, "Assuming bias of 30."},
1203 {1, 1, "Extra characters."},
1204 {0, 0, "Missing Basename in FD file."},
1205 {0, 0, "Failed to write destination file."},
1206 {1, 1, "Expected ','."},
1207 {0, 1, "Data different to previous given."},
1208 {1, 0, "Unknown type of argument %ld."},
1209 {0, 0, "Unknown problem: program error or corrupt input data."},
1210 {1, 0, "Missing ##end."},
1211 {1, 0, "Prototype for function \"%s\" not found."},
1212 {0, 0, "No prototypes file (CLIB parameter) was specified."},
1213 {1, 1, "Unknown directive '%s' found."},
1214 {1, 0, "Usage of both A4 and A5 is not supported."},
1215 {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
1216 {0, 0, "Missing Basename in FD file and FD filename."},
1217 {1, 0, "A6 not allowed as argument register."},
1218 {1, 0, "Empty or partial file deleted."},
1219 {1, 1, "Floating point arguments not allowed."},
1220 {0, 0, "Wrong definition in external type definition file."},
1221 {1, 0, "Cannot determine if FPU argument is double or single."},
1222 {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
1223 {0, 0, "Could not open file \"%s\"."},
1224 {1, 0, "A5 cannot be used as argument register."},
1225 {1, 0, "Format supports no PPC functions."},
1226 {1, 0, "Unknown ABI '%s' found."},
1227 {0, 0, "SORTED cannot be used with that type."},
1228 {1, 0, "Position of function %s not supported with that type."},
1229 {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
1230 {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
1231 {1, 0, "Missing the types definition file. Using internal defaults."},
1232 {1, 0, "Format supports no M68k functions."},
1233 {1, 0, "Unknown type of return value."},
1234 {1, 0, "With SFD as input CLIB file is ignored."},
1235 {1, 0, "Expected $Id: in ID string."},
1236 {1, 0, "Expected $ at end of ID string."},
1237 {1, 0, "Missing ==end."},
1238 {1, 1, "Expected positive decimal number."},
1239 {1, 0, "ID string declared twice."},
1240 {1, 1, "Library type of commandline overwrites file settings."},
1241 {1, 1, "Basename of commandline overwrites file settings."},
1242 {1, 0, "Library type declared twice."},
1243 {1, 1, "Expected library type definition."},
1244 {1, 1, "SORTED cannot be used with SFD and FD output."},
1245 {1, 0, "Function expected before ##shadow."},
1246 {1, 1, "There is already a varargs function, handling as alias."},
1247 {1, 0, "Varargs function cannot have different arguments."},
1248 {1, 0, "Unexpected end of file."},
1249 {1, 0, "Commands varargs and alias cannot be at file start."},
1250 {1, 0, "Only %d alias names supported."},
1251 {1, 1, "Expected struct keyword in library type."},
1252 {1, 0, "Expected '*' at end of library type definition."},
1253 {1, 1, "Name of argument %d conflicts with keyword '%s'."},
1254 {1, 1, "Name of argument %d conflicts with argument %d."},
1255 {1, 0, "SFD files cannot consist only of varargs functions."},
1256 {1, 1, "Library name of commandline overwrites file settings."},
1257 {1, 0, "Library name declared twice."},
1258 {1, 1, "Expected library name definition."},
1259 {1, 0, "Neither prefix nor subprefix specified."},
1260 {1, 0, "Format supports single function pointer only (void * used)."},
1261 {1, 0, "No swap register left for %s."},
1262 {1, 0, "SFD files should always start with ==id directive."},
1263 {1, 0, "Illegal character detected."},
1264 {1, 0, "Unknown type of argument %ld (%s) handled as int."},
1265 {1, 0, "Unknown type of return value (%s) handled as int."},
1266 {1, 0, "Illegal internal value."},
1267 {1, 0, "Format supports no MorphOS (base,sysv) functions."},
1268 {1, 0, "Format supports no alias names."},
1269 {1, 0, "Format cannot support function %s."},
1275 static uint8 InternalTypes
[] = {
1276 "IX:struct InputXpression\n"
1278 "Class:struct IClass\n"
1279 "BootBlock:struct bootblock\n"
1280 "ValidIDstruct:struct ValidIDstruct\n"
1281 "DisplayInfoHandle:void *\n"
1282 "RESOURCEFILE:void *\n"
1283 "RESOURCEID:unsigned long\n"
1285 "GLbitfield:unsigned long\n"
1286 "GLbyte:signed char\n"
1289 "GLsizei:unsigned long\n"
1290 "GLubyte:unsigned char\n"
1291 "GLushort:unsigned short\n"
1292 "GLuint:unsigned long\n"
1297 "GLboolean:enum ?\n"
1299 "GLlookAt:struct GLlookAt\n"
1300 "GLproject:struct GLproject\n"
1301 "GLunProject:struct GLunProject\n"
1302 "GLfrustum:struct GLfrustum\n"
1303 "GLortho:struct GLortho\n"
1304 "GLbitmap:struct GLbitmap\n"
1305 "GLUquadricObj:struct GLUquadricObj\n"
1306 "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
1307 "GLUnurbsObj:struct GLUnurbsObj\n"
1308 "GLvisual:struct gl_visual\n"
1309 "GLframebuffer:struct gl_frame_buffer\n"
1310 "GLcontext:struct gl_context\n"
1311 "GLContext:struct !\n"
1312 "HGIDA_Stack:unsigned long *\n"
1313 "HGIDA_BoundedStack:unsigned long *\n"
1314 "HGIDA_Queue:unsigned long *\n"
1315 "HGIDA_BoundedQueue:unsigned long *\n"
1316 "HGIDA_List:unsigned long *\n"
1317 "HGIDA_ListItem:unsigned long *\n"
1318 "HGIDA_Error:enum ?\n"
1319 "HGIDA_Direction:enum ?\n"
1322 "mode_t:unsigned short\n"
1323 "pid_t:struct Task *\n"
1324 "fd_set:struct fd_set\n"
1325 "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 "
1326 "unsigned long, register __a1 const unsigned char *, register __a2 struct "
1327 "CSource *, register __a3 struct CSource *)\n"
1328 "pcap_t:struct pcap\n"
1329 "pcap_dumper_t:struct pcap_dumper\n"
1330 "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const "
1331 "unsigned char *)\n"
1332 "u_char:unsigned char\n"
1333 "bpf_u_int32:unsigned long\n"
1336 "MPEGA_STREAM:struct MPEGA_STREAM\n"
1337 "MPEGA_CTRL:struct MPEGA_CTRL\n"
1338 "W3D_Context:struct W3DContext\n"
1339 "W3D_Driver:struct W3DDriver\n"
1340 "W3D_Texture:struct W3DTexture\n"
1341 "W3D_Scissor:struct W3DScissor\n"
1342 "W3D_Line:struct W3D_Line\n"
1343 "W3D_Point:struct W3D_Point\n"
1344 "W3D_Triangle:struct W3D_Triangle\n"
1345 "W3D_Triangles:struct W3D_Triangles\n"
1347 "W3D_Bitmap:struct W3D_Bitmap\n"
1348 "W3D_Fog:struct W3D_Fog\n"
1350 "W3D_Double:double\n"
1351 "W3D_TriangleV:struct W3D_TriangleV\n"
1352 "W3D_TrianglesV:struct W3D_TriangleV\n"
1353 "W3D_ScreenMode:struct W3D_Screenmode\n"
1354 "W3D_Color:struct W3D_Color\n"
1355 "W3D_Lines:struct W3D_Lines\n"
1357 "DITHERINFO:void *\n"
1361 "size_t:unsigned int\n"
1363 "uint8:unsigned char\n"
1364 "uint16:unsigned short\n"
1365 "uint32:unsigned long\n"
1370 "PtrBigNum:struct BigNum *\n"
1371 "BF_KEY:struct bf_key_st\n"
1372 "BF_LONG:unsigned long\n"
1373 "CAST_KEY:struct cast_key_st\n"
1374 "CAST_LONG:unsigned long\n"
1375 "DES_LONG:unsigned long\n"
1376 "des_key_schedule:struct des_ks_struct\n"
1377 "const_des_cblock:unsigned char [8]\n"
1378 "des_cblock:unsigned char [8]\n"
1379 "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
1380 "MD2_CTX:struct MD2state_st\n"
1381 "MD5_CTX:struct MD5state_st\n"
1382 "MDC2_CTX:struct mdc2_ctx_st\n"
1383 "RC2_KEY:struct rc2_key_st\n"
1384 "RC4_KEY:struct rc4_key_st\n"
1385 "RC5_32_KEY:struct rc5_key_st\n"
1386 "RIPEMD160_CTX:struct RIPEMD160state_st\n"
1387 "SHA_CTX:struct SHAstate_st\n"
1388 "ASN1_CTX:struct asn1_ctx_st\n"
1389 "ASN1_OBJECT:struct asn1_object_st\n"
1390 "ASN1_STRING:struct asn1_string_st\n"
1391 "ASN1_TYPE:struct asn1_type_st\n"
1392 "ASN1_METHOD:struct asn1_method_st\n"
1393 "ASN1_HEADER:struct asn1_header_st\n"
1394 "ASN1_INTEGER:struct asn1_string_st\n"
1395 "ASN1_ENUMERATED:struct asn1_string_st\n"
1396 "ASN1_BIT_STRING:struct asn1_string_st\n"
1397 "ASN1_OCTET_STRING:struct asn1_string_st\n"
1398 "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
1399 "ASN1_T61STRING:struct asn1_string_st\n"
1400 "ASN1_IA5STRING:struct asn1_string_st\n"
1401 "ASN1_UTCTIME:struct asn1_string_st\n"
1402 "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
1403 "ASN1_TIME:struct asn1_string_st\n"
1404 "ASN1_GENERALSTRING:struct asn1_string_st\n"
1405 "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
1406 "ASN1_BMPSTRING:struct asn1_string_st\n"
1407 "ASN1_VISIBLESTRING:struct asn1_string_st\n"
1408 "ASN1_UTF8STRING:struct asn1_string_st\n"
1409 "BIO:struct bio_st\n"
1410 "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
1411 "BIO_METHOD:struct bio_method_st\n"
1412 "BIGNUM:struct bignum_st\n"
1413 "BN_CTX:struct bignum_ctx\n"
1414 "BN_ULONG:unsigned long\n"
1415 "BN_MONT_CTX:struct bn_mont_ctx_st\n"
1416 "BN_BLINDING:struct bn_blinding_st\n"
1417 "BN_RECP_CTX:struct bn_recp_ctx_st\n"
1418 "BUF_MEM:struct buf_mem_st\n"
1419 "COMP_METHOD:struct comp_method_st\n"
1420 "COMP_CTX:struct comp_ctx_st\n"
1421 "CONF_VALUE:struct !\n"
1422 "LHASH_NODE:struct lhash_node_st\n"
1423 "LHASH:struct lhash_st\n"
1424 "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
1425 "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
1427 "DSA:struct dsa_st\n"
1428 "DSA_SIG:struct DSA_SIG_st\n"
1429 "ERR_STATE:struct err_state_st\n"
1430 "ERR_STRING_DATA:struct ERR_string_data_st\n"
1431 "EVP_PKEY:struct evp_pkey_st\n"
1432 "EVP_MD:struct env_md_st\n"
1433 "EVP_MD_CTX:struct env_md_ctx_st\n"
1434 "EVP_CIPHER:struct evp_cipher_st\n"
1435 "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
1436 "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
1437 "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
1438 "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char "
1439 "*pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st "
1440 "*cipher, struct env_md_st *md, int en_de)\n"
1441 "HMAC_CTX:struct hmac_ctx_st\n"
1442 "OBJ_NAME:struct obj_name_st\n"
1443 "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
1444 "PEM_USER:struct pem_recip_st\n"
1445 "PEM_CTX:struct pem_ctx_st\n"
1446 "PKCS12_MAC_DATA:struct !\n"
1448 "PKCS12_SAFEBAG:struct !\n"
1449 "PKCS12_BAGS:struct pkcs12_bag_st\n"
1450 "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
1451 "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
1452 "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
1453 "PKCS7_SIGNED:struct pkcs7_signed_st\n"
1454 "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
1455 "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
1456 "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
1457 "PKCS7_DIGEST:struct pkcs7_digest_st\n"
1458 "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
1459 "PKCS7:struct pkcs7_st\n"
1460 "RAND_METHOD:struct rand_meth_st\n"
1461 "RSA:struct rsa_st\n"
1462 "RSA_METHOD:struct rsa_meth_st\n"
1463 "TXT_DB:struct txt_db_st\n"
1464 "X509_OBJECTS:struct X509_objects_st\n"
1465 "X509_ALGOR:struct X509_algor_st\n"
1466 "X509_VAL:struct X509_val_st\n"
1467 "X509_PUBKEY:struct X509_pubkey_st\n"
1468 "X509_SIG:struct X509_sig_st\n"
1469 "X509_NAME_ENTRY:struct X509_name_entry_st\n"
1470 "X509_NAME:struct X509_name_st\n"
1471 "X509_EXTENSION:struct X509_extension_st\n"
1472 "X509_ATTRIBUTE:struct x509_attributes_st\n"
1473 "X509_REQ_INFO:struct X509_req_info_st\n"
1474 "X509_REQ:struct X509_req_st\n"
1475 "X509_CINF:struct x509_cinf_st\n"
1476 "X509:struct x509_st\n"
1477 "X509_REVOKED:struct X509_revoked_st\n"
1478 "X509_CRL_INFO:struct X509_crl_info_st\n"
1479 "X509_CRL:struct X509_crl_st\n"
1480 "X509_PKEY:struct private_key_st\n"
1481 "X509_INFO:struct X509_info_st\n"
1482 "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
1483 "NETSCAPE_SPKI:struct Netscape_spki_st\n"
1484 "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
1485 "CBC_PARAM:struct CBCParameter_st\n"
1486 "PBEPARAM:struct PBEPARAM_st\n"
1487 "PBE2PARAM:struct PBE2PARAM_st\n"
1488 "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
1489 "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
1490 "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
1491 "X509V3_EXT_METHOD:struct v3_ext_method\n"
1492 "X509V3_CTX:struct v3_ext_ctx\n"
1493 "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
1494 "X509_CERT_FILE_CTX:struct x509_file_st\n"
1495 "X509_OBJECT:struct X509_objects_st\n"
1496 "X509_LOOKUP:struct x509_lookup_st\n"
1497 "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
1498 "X509_STORE_CTX:struct x509_store_state_st\n"
1499 "X509_STORE:struct x509_store_st\n"
1500 "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
1501 "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
1502 "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
1503 "GENERAL_NAME:struct GENERAL_NAME_st\n"
1504 "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
1505 "DIST_POINT:struct DIST_POINT_st\n"
1506 "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
1507 "SXNETID:struct SXNET_ID_st\n"
1508 "SXNET:struct SXNET_st\n"
1509 "NOTICEREF:struct NOTICEREF_st\n"
1510 "USERNOTICE:struct USERNOTICE_st\n"
1511 "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
1512 "POLICYINFO:struct POLICYINFO_st\n"
1513 "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
1514 "SSL_CIPHER:struct ssl_cipher_st\n"
1515 "SSL:struct ssl_st\n"
1516 "SSL_CTX:struct ssl_ctx_st\n"
1517 "SSL_METHOD:struct ssl_method_st\n"
1518 "SSL_SESSION:struct ssl_session_st\n"
1519 "SSL_COMP:struct ssl_comp_st\n"
1520 "SSL2_CTX:struct ssl2_ctx_st\n"
1521 "SSL3_RECORD:struct ssl3_record_st\n"
1522 "SSL3_BUFFER:struct ssl3_buffer_st\n"
1523 "SSL3_CTX:struct ssl3_ctx_st\n"
1524 "CERT_PKEY:struct cert_pkey_st\n"
1525 "CERT:struct cert_st\n"
1526 "SESS_CERT:struct sess_cert_st\n"
1527 "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
1528 "SSL3_COMP:struct ssl3_comp_st\n"
1529 "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
1530 "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
1531 "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
1532 "STACK_OF(X509):struct stack_st_X509\n"
1533 "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
1534 "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
1535 "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
1536 "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
1537 "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
1538 "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
1539 "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
1540 "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
1541 "STACK:struct stack_st\n"
1543 "Uint8:unsigned char\n"
1544 "Sint8:signed char\n"
1545 "Uint16:unsigned short\n"
1546 "Sint16:signed short\n"
1547 "Uint32:unsigned long\n"
1548 "Sint32:signed long\n"
1549 "Uint64:unsigned long long\n"
1550 "Sint64:signed long long\n"
1551 "SDL_version:struct !\n"
1552 "SDL_RWops:struct SDL_RWops\n"
1553 "SDL_Rect:struct !\n"
1554 "SDL_Color:struct !\n"
1555 "SDL_Palette:struct !\n"
1556 "SDL_PixelFormat:struct SDL_PixelFormat\n"
1557 "SDL_blit:int (*)(struct SDL_Surface *src,void *srcrect,"
1558 "struct SDL_Surface *dst,void *dstrect)\n"
1559 "SDL_Surface:struct SDL_Surface\n"
1560 "SDL_VideoInfo:struct !\n"
1561 "SDL_Overlay:struct SDL_Overlay\n"
1562 "SDL_GLattr:enum ?\n"
1563 "SDL_GrabMode:enum ?\n"
1564 "SDL_audiostatus:enum ?\n"
1565 "SDL_AudioSpec:struct !\n"
1566 "SDL_AudioCVT:struct SDL_AudioCVT\n"
1568 "SDL_CDtrack:struct !\n"
1569 "SDL_CD:struct SDL_CD\n"
1570 "SDL_Joystick:struct _SDL_Joystick\n"
1573 "SDL_keysym:struct !\n"
1574 "SDL_ActiveEvent:struct !\n"
1575 "SDL_KeyboardEvent:struct !\n"
1576 "SDL_MouseMotionEvent:struct !\n"
1577 "SDL_MouseButtonEvent:struct !\n"
1578 "SDL_JoyAxisEvent:struct !\n"
1579 "SDL_JoyBallEvent:struct !\n"
1580 "SDL_JoyHatEvent:struct !\n"
1581 "SDL_JoyButtonEvent:struct !\n"
1582 "SDL_ResizeEvent:struct !\n"
1583 "SDL_ExposeEvent:struct !\n"
1584 "SDL_QuitEvent:struct !\n"
1585 "SDL_UserEvent:struct !\n"
1586 "SDL_SysWMmsg:struct SDL_SysWMmsg\n"
1587 "SDL_SysWMEvent:struct !\n"
1588 "SDL_Event:union ?\n"
1589 "SDL_eventaction:enum ?\n"
1590 "SDL_EventFilter:void *\n"
1591 "WMcursor:struct WMcursor\n"
1592 "SDL_Cursor:struct !\n"
1593 "SDL_mutex:struct SDL_mutex\n"
1594 "SDL_sem:struct SDL_semaphore\n"
1595 "SDL_cond:struct SDL_cond\n"
1596 "SDL_Thread:struct SDL_Thread\n"
1597 "SDL_TimerCallback:unsigned long (*)(unsigned long)\n"
1598 "SDL_NewTimerCallback:unsigned long (*)(unsigned long,void *)\n"
1599 "SDL_TimerID:struct _SDL_TimerID\n"
1600 "SDL_errorcode:enum ?\n"
1601 "FPSmanager:struct !\n"
1602 "Mix_Chunk:struct !\n"
1603 "Mix_Music:struct !\n"
1604 "Mix_MusicType:enum ?\n"
1605 "Mix_EffectFunc_t:void (*)(int,void *,int,void *)\n"
1606 "Mix_EffectDone_t:void (*)(int,void *)\n"
1607 "Mix_Fading:enum ?\n"
1608 "IPaddress:struct !\n"
1609 "TCPsocket:void *\n"
1610 "UDPpacket:struct !\n"
1611 "UDPsocket:void *\n"
1612 "SDLNet_SocketSet:void *\n"
1613 "SDLNet_GenericSocket:void *\n"
1614 "TTF_Font:struct !\n"
1617 static const struct CPP_TypeField CPP_Field
[] = {
1618 {"int", 3, 0, CPP_TYPE_INT
},
1619 /* long needs special handling due to the fact it is a modifier and a type */
1620 /*{"long", 4, 0, CPP_TYPE_LONG}, */
1621 {"LONG", 4, 0, CPP_TYPE_LONG
},
1622 {"BPTR", 4, 0, CPP_TYPE_LONG
},
1623 {"BSTR", 4, 0, CPP_TYPE_LONG
},
1624 {"CxObj", 5, 0, CPP_TYPE_LONG
},
1625 {"CxMsg", 5, 0, CPP_TYPE_LONG
},
1626 {"ULONG", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1627 {"LONGBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1628 {"CPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1629 {"Tag", 3, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1630 {"Object", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1631 {"short", 5, 0, CPP_TYPE_WORD
},
1632 {"SHORT", 5, 0, CPP_TYPE_WORD
},
1633 {"COUNT", 5, 0, CPP_TYPE_WORD
},
1634 {"WORD", 4, 0, CPP_TYPE_WORD
},
1635 {"USHORT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1636 {"UWORD", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1637 {"UCOUNT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1638 {"WORDBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1639 {"RPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1640 {"BOOL", 4, CPP_FLAG_BOOLEAN
, CPP_TYPE_WORD
},
1641 {"char", 4, 0, CPP_TYPE_BYTE
},
1642 {"BYTE", 4, 0, CPP_TYPE_BYTE
},
1643 {"UBYTE", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1644 {"TEXT", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1645 {"BYTEBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1646 {"float", 5, 0, CPP_TYPE_FLOAT
},
1647 {"FLOAT", 5, 0, CPP_TYPE_FLOAT
},
1648 {"double", 6, 0, CPP_TYPE_DOUBLE
},
1649 {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE
},
1650 {"void", 4, 0, CPP_TYPE_VOID
},
1651 {"VOID", 4, 0, CPP_TYPE_VOID
},
1652 {"APTR", 4, CPP_FLAG_POINTER
, CPP_TYPE_VOID
},
1653 {"STRPTR", 6, CPP_FLAG_POINTER
|CPP_FLAG_STRPTR
, CPP_TYPE_BYTE
},
1654 {"CONST_STRPTR",12,CPP_FLAG_POINTER
|CPP_FLAG_CONST
, CPP_TYPE_BYTE
},
1655 {"ClassID", 7, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1656 {"PLANEPTR", 8, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1660 /* defaults: "Library" shortbname+".library" basename-last 4 chars */
1661 static const struct Proto_LibType Proto_LibTypes
[] = {
1662 {"DOSBase", "DosLibrary", 0, 0},
1663 {"SysBase", "ExecBase", 0, 0},
1664 {"ExpansionBase", "ExpansionBase", 0, 0},
1665 {"GfxBase", "GfxBase", "graphics.library", "graphics"},
1666 {"IntuitionBase", "IntuitionBase", 0, 0},
1667 {"LocaleBase", "LocaleBase", 0, 0},
1668 {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
1669 {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
1670 {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
1671 {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
1672 {"RealTimeBase", "RealTimeBase", 0, 0},
1673 {"RexxSysBase", "RxsLib", 0, 0},
1674 {"UtilityBase", "UtilityBase", 0, 0},
1675 {"WorkbenchBase", 0, "workbench.library", "wb"},
1676 /* resources - The Node entries may be correct, but I don't know it. */
1677 {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
1678 {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
1679 {"CardResource", 0/*"Node"*/, "card.resource", "cardres"},
1680 {"DiskBase", "DiskResource", "disk.resource", 0},
1681 {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
1682 {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
1684 {"ConsoleDevice", 0/*"Device"*/, "console.device", "console"},
1685 {"InputBase", 0/*"Device"*/, "input.device", 0},
1686 {"RamdriveDevice", 0/*"Device"*/, "ramdrive.device", "ramdrive"},
1687 {"TimerBase", 0/*"Device"*/, "timer.device", 0},
1688 /* non default Basenames */
1689 {"DatamasterBase", "DatamasterBase", 0, 0},
1690 {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
1691 {"ReqToolsBase", "ReqToolsBase", 0, 0},
1692 {"UnpackBase", "UnpackLibrary", 0, 0},
1693 {"xfdMasterBase", "xfdMasterBase", 0, 0},
1694 {"xadMasterBase", "xadMasterBase", 0, 0},
1695 /*{"xvsBase", "xvsBase", 0, 0}, now completely private */
1696 {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
1697 {"ArpBase", "ArpBase", 0, 0},
1698 {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
1699 {"PowerPCBase", "PPCBase", 0, 0},
1700 {"MC68060Base", 0, "68060.library", "mc68060"},
1701 {"MC68040Base", 0, "68040.library", "mc68040"},
1702 {"MC680x0Base", 0, "680x0.library", "mc680x0"},
1703 {"P96Base", 0, "Picasso96API.library","Picasso96"},
1704 {"Warp3DPPCBase", 0, "Warp3DPPC.library" ,"Warp3D"},
1705 {"CyberGfxBase", 0, "cybergraphics.library", "cybergraphics"},
1709 /* CachePostDMA, CachePreDMA are done by #?DMA check */
1710 static const struct Pragma_ExecpName Pragma_ExecpNames
[] = {
1711 {"VFWritef", "FWritef"},
1712 {"VFPrintf", "FPrintf"},
1713 {"VPrintf", "Printf"},
1716 {"CloneTagItems", 0},
1718 {"FreeTagItems", 0},
1720 {"PackBoolTags", 0},
1721 {"PackStructureTags", 0},
1722 {"UnpackStructureTags", 0},
1723 {"BGUI_PackStructureTags", 0},
1724 {"BGUI_UnpackStructureTags", 0},
1725 {"Inet_NtoA", 0}, /* socket.library */
1726 {"vsyslog", "syslog"},
1727 {"NewPPCStackSwap", 0},
1728 {"FindTagItemPPC", 0},
1729 {"GetTagDataPPC", 0},
1732 {"SetScheduling", 0},
1733 {"W3D_CreateContext", "W3D_CreateContextTags"},
1734 {"W3D_RequestMode", "W3D_RequestModeTags"},
1735 {"W3D_AllocTexObj", "W3D_AllocTexObjTags"},
1736 {"W3D_BestModeID", "W3D_BestModeIDTags"},
1740 /* This field contains functions, which should not be created as inlines with
1741 some targets. At the moment these are varargs functions, which are used in
1742 the MUI style using complicated defines. Theses functions are disabled in
1743 certain GCC and VBCC environments. */
1744 static const strptr NoCreateInlineFuncs
[] = {
1751 /* For double tagcall names (currently only necessary for dos.library and
1752 datatypes.library). Only one alias supported for a function! */
1753 static const struct Pragma_AliasName Pragma_AliasNames
[] = {
1754 {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL
},
1755 {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL
},
1756 {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL
},
1757 {"SystemTagList", "System", FUNCFLAG_NORMAL
},
1758 {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG
},
1762 /* special names, which get an x before name in BMAP files */
1763 static const strptr BMAPSpecial
[] =
1764 {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
1765 "Translate", "Wait", "Write", 0};
1767 #define FIRST_KNOWN_RELEASE 30
1768 #define LAST_KNOWN_RELEASE 45
1769 static const strptr Release
[] =
1771 "Release 1.0", /* V30 */
1772 "Release 1.1", /* V31 */
1773 "Preliminary Release 1.2", /* V32 */
1774 "Release 1.2", /* V33 */
1775 "Release 1.3", /* V34 */
1776 "Release 1.3 A2024", /* V35 */
1777 "Release 2.0", /* V36 */
1778 "Release 2.04", /* V37 */
1779 "Release 2.1", /* V38 */
1780 "Release 3.0", /* V39 */
1781 "Release 3.1", /* V40 */
1782 "Transitional Release 3.2", /* V41 */
1783 "Transitional Release 3.3", /* V42 */
1784 "Transitional Release 3.4", /* V43 */
1785 "Release 3.5", /* V44 */
1786 "Release 3.9", /* V45 */
1789 /* Keywords, which cannot be argument names. They are used case_insensitive to
1790 be sure they make no conflicts in non-C-languages as well.
1791 Currently these are mostly C keywords.
1793 static const strptr Keywords
[] =
1795 "and", "and_eq", "asm", "auto", "bitand",
1796 "bitor", "break", "case", "catch", "char",
1797 "class", "compl", "const", "continue", "default",
1798 "delete", "do", "double", "else", "enum",
1799 "extern", "false", "float", "for", "friend",
1800 "goto", "if", "inline", "int", "long",
1801 "new", "not", "not_eq", "operator", "or",
1802 "or_eq", "private", "protected", "public", "register",
1803 "return", "short", "signed", "sizeof", "static",
1804 "struct", "switch", "template", "this", "throw",
1805 "true", "try", "typedef", "union", "unsigned",
1806 "virtual", "void", "volatile", "wchar_t", "while",
1807 "xor", "xor_eq", "RastPort", "Tag",
1811 #if !defined __SASC && !defined __AROS__ && !defined _WIN32 && !defined __CYGWIN__
1812 static int stricmp(const char *a
, const char *b
)
1814 while(*a
&& tolower(*a
) == tolower(*b
))
1818 return (tolower(*a
) - tolower(*b
));
1821 static int strnicmp(const char *a
, const char *b
, size_t num
)
1823 while(num
&& *a
&& tolower(*a
) == tolower(*b
))
1827 return num
? (tolower(*a
) - tolower(*b
)) : 0;
1831 static strptr
DupString(strptr Str
, size_t Len
)
1834 if((res
= r
= AllocListMem(Len
+1)))
1836 while(Len
-- && *Str
)
1841 printf("DupString %s.\n", res
);
1846 static strptr
AllocListMem(size_t size
)
1850 printf("AllocListMem Size %d.\n", size
);
1852 if((a
= (strptr
) malloc(size
)))
1857 static strptr
SkipBlanks(strptr OldPtr
)
1859 while(*OldPtr
== ' ' || *OldPtr
== '\t')
1864 static strptr
SkipBlanksRet(strptr OldPtr
)
1866 while(*OldPtr
== ' ' || *OldPtr
== '\t' || *OldPtr
== '\n')
1872 This function is used to skip over variable names.
1874 Inputs: OldPtr - pointer to the beginning of a string.
1876 Result: Pointer to the first character of the string, that is not one
1877 of a-z, A-Z, 0-9 or the underscore.
1880 static strptr
SkipName(strptr OldPtr
)
1882 while(isalnum(*OldPtr
) || *OldPtr
== '_')
1887 static int IsNoCreateInlineFunc(const strptr name
)
1890 for(a
= NoCreateInlineFuncs
; *a
; ++a
)
1892 if(!strcmp(name
, *a
))
1898 static uint32
GetTypes(void)
1904 if(!(ptr
= mygetfile(EXTTYPESFILE
, &len
)))
1906 #ifdef EXTTYPESFILEHIDDEN
1907 if((ptr
= getenv("HOME")))
1909 strptr ptrh
= EXTTYPESFILEHIDDEN
;
1912 ptr
= DupString(ptr
, i
+ sizeof(EXTTYPESFILEHIDDEN
) + 1);
1913 if(i
&& ptr
[i
-1] != '/')
1916 ptr
[i
++] = *(ptrh
++);
1918 ptr
= mygetfile(ptr
, &len
);
1920 if(!ptr
) /* disabled following if ptr != 0 */
1922 if(!(ptr
= mygetfile(EXTTYPESFILE2
, &len
)))
1924 DoError(ERR_NOFD2PRAGMATYPES
, 0);
1925 ptr
= (strptr
) InternalTypes
;
1926 len
= sizeof(InternalTypes
)-1;
1929 if((i
= ScanTypes(ptr
, len
)) > 0)
1931 DoError(ERR_WRONG_TYPES_LINE
, i
);
1937 static strptr
GetBaseType(void)
1939 static strptr basetype
= 0;
1942 if(Flags2
& FLAG2_VOIDBASE
)
1943 basetype
= "void *";
1946 for(i
= 0; !libtype
&& BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1948 if(!(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1950 libtype
= Proto_LibTypes
[i
].StructureName
;
1954 if(libtype
&& (basetype
= malloc(strlen(libtype
) + 9+1)))
1956 sprintf(basetype
, "struct %s *", libtype
);
1959 basetype
= "struct Library *";
1965 static strptr
GetBaseTypeLib(void)
1972 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1974 if(Proto_LibTypes
[i
].StructureName
&&
1975 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1977 return Proto_LibTypes
[i
].StructureName
;
1983 static strptr
GetLibraryName(void)
1990 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1992 if(Proto_LibTypes
[i
].LibraryName
&&
1993 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1995 return (libname
= Proto_LibTypes
[i
].LibraryName
);
1998 if(!(libname
= malloc(strlen(ShortBaseName
)+9)))
2001 /* auto create name */
2002 for(i
= 0; ShortBaseName
[i
]; ++i
)
2003 libname
[i
] = ShortBaseName
[i
];
2004 strcpy(libname
+i
,".library");
2008 static strptr
GetIFXName(void)
2010 static char IFXName
[256];
2011 sprintf(IFXName
, "%c%s", toupper(ShortBaseName
[0]), ShortBaseName
+1);
2015 static int32
MakeShortBaseName(void)
2020 ptr
= p2
= args
.infile
;
2023 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
2028 /* first get name from file */
2030 p2
-= (sizeof(SFDFILEEXTENSION
)-1);
2031 if(p2
> ptr
&& !stricmp(p2
, SFDFILEEXTENSION
))
2032 ShortBaseName
= DupString(ptr
, p2
-ptr
);
2033 p2
+= sizeof(SFDFILEEXTENSION
)-sizeof(FDFILEEXTENSION
);
2034 if(p2
> ptr
&& !stricmp(p2
, FDFILEEXTENSION
))
2035 ShortBaseName
= DupString(ptr
, p2
-ptr
);
2037 /* then try exceptions (overriding filename) */
2040 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
2042 if(Proto_LibTypes
[i
].ShortBaseName
&&
2043 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
2045 if(!(ShortBaseName
= DupString(Proto_LibTypes
[i
].ShortBaseName
,
2046 strlen(Proto_LibTypes
[i
].ShortBaseName
))))
2051 /* and last use default method */
2053 ShortBaseName
= DupString(BaseName
, strlen(BaseName
)-4);
2059 ptr
= ShortBaseName
;
2060 while((*ptr
= tolower(*ptr
))) /* Convert to lowercase */
2063 if((ShortBaseNameUpper
= DupString(ShortBaseName
, strlen(ShortBaseName
))))
2065 ptr
= ShortBaseNameUpper
;
2066 while((*ptr
= toupper(*ptr
))) /* Convert to uppercase */
2075 static uint32
OpenDest(strptr name
)
2077 static uint8 printedname
= 0;
2080 t
= (strptr
) tempbuf
;
2081 if((b
= args
.to
) && *b
)
2085 if(*(t
-1) != ':' && *(t
-1) != '/')
2090 if(!(Flags
& FLAG_SINGLEFILE
))
2091 printf("ResultFile: %s%s\n", tempbuf
, name
);
2092 else if(!printedname
++)
2094 printf("ResultType: %s", tempbuf
); printf(filenamefmt
, "*");
2104 HEADER
= mygetfile((strptr
)tempbuf
, &headersize
);
2108 if((outfile
= fopen((strptr
)tempbuf
, "wb")))
2110 DoError(ERR_OPEN_FILE
, 0, tempbuf
);
2114 static uint32
CloseDest(strptr name
)
2121 if(!(Flags
& FLAG_DONE
) || !Output_Error
)
2124 if(!Output_Error
|| !(Flags
& FLAG_SINGLEFILE
))
2125 DoError(ERR_EMPTY_FILE
, 0);
2127 t
= (strptr
) tempbuf
;
2128 if((b
= args
.to
) && *b
)
2132 if(*(t
-1) != ':' && *(t
-1) != '/')
2139 remove((strptr
)tempbuf
);
2142 Flags
&= ~FLAG_DONE
; /* clear the flag */
2149 static uint32
MakeTagFunction(struct AmiPragma
*ap
)
2151 size_t len
= strlen(ap
->FuncName
);
2155 printf("MakeTagFunction:\n");
2158 if(!ap
->NumArgs
|| ap
->TagName
)
2162 ap
->Flags
|= AMIPRAGFLAG_OWNTAGFUNC
;
2164 while(Pragma_ExecpNames
[i
].FunctionName
&& /* check the exception names */
2165 strcmp(ap
->FuncName
, Pragma_ExecpNames
[i
].FunctionName
))
2168 if(Pragma_ExecpNames
[i
].FunctionName
)
2170 if(!(ap
->TagName
= Pragma_ExecpNames
[i
].TagName
))
2172 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
2176 else if(ap
->FuncName
[len
-1] == 'A')
2178 /* skip names with DMA or MESA at end */
2179 if(!strcmp(ap
->FuncName
+len
-3, "DMA") ||
2180 !strcmp(ap
->FuncName
+len
-4, "MESA") ||
2181 !strcmp(ap
->FuncName
+len
-4, "RGBA") ||
2182 !strcmp(ap
->FuncName
+len
-5, "AMIGA"))
2183 { ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
; --tagfuncs
; return 1;}
2184 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-1)))
2187 else if(!strcmp(ap
->FuncName
+ len
-7, "TagList"))
2189 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-3)))
2191 ap
->TagName
[len
-4] = 's';
2193 else if(!strcmp(ap
->FuncName
+ len
-4, "Args"))
2195 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-4)))
2198 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "tags") ||
2199 !stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "taglist"))
2201 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
2203 memcpy(ap
->TagName
+ len
, "Tags", 5);
2205 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "args"))
2207 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
2209 memcpy(ap
->TagName
+ len
, "Args", 5);
2213 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
2214 --tagfuncs
; /* not a tagfunction, incrementing was false, undo it */
2219 printf("MakeTagFunction: %s / %s (...%s)\n", ap
->TagName
,
2220 ap
->FuncName
, ap
->Args
[ap
->CallArgs
-1].ArgName
);
2226 static void MakeLines(strptr buffer
, uint32 size
)
2230 /* make a real C++ zero string ending line */
2241 /* Do any special functions, which cannot be done with other exception
2242 stuff - currently only dos.library DoPkt function. */
2243 static uint32
SpecialFuncs(void)
2245 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
,
2246 *ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2248 /* first let one more go away, so we can detect if the DoPkt parts are
2249 already inserted in the FD file */
2251 while(ap2
&& (struct AmiPragma
*)(ap2
->List
.Next
) != ap
)
2252 ap2
= (struct AmiPragma
*)(ap2
->List
.Next
);
2254 if(ap2
&& ap2
->Bias
== 0xF0 && ap
->Bias
!= 0xF0 &&
2255 !strcmp("DoPkt", ap2
->FuncName
))
2257 struct AmiPragma
*d
;
2260 RemoveItem(&AmiPragma
, (struct ShortList
*) ap
); /* add in correct order */
2261 for(i
= 0; i
< 5; ++i
)
2263 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
2265 memcpy(d
, ap2
, sizeof(struct AmiPragma
));
2266 d
->FuncName
= DupString(ap2
->FuncName
, 6);
2267 d
->FuncName
[5] = '0'+i
;
2268 d
->NumArgs
= d
->CallArgs
= i
+ 2;
2269 AddItem(&AmiPragma
, (struct ShortList
*) d
);
2271 AddItem(&AmiPragma
, (struct ShortList
*) ap
);
2276 static void SortFDList(void)
2278 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.First
, *ap2
, *ap3
;
2279 AmiPragma
.First
= AmiPragma
.Last
= 0;
2284 ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2286 /* for FD2Inline style we need to use strcmp instead of stricmp here */
2287 while(ap2
&& stricmp(ap2
->FuncName
, ap
->FuncName
) < 0)
2290 ap2
= (struct AmiPragma
*) ap2
->List
.Next
;
2294 ap
= (struct AmiPragma
*) ap
->List
.Next
;
2298 ap2
->List
.Next
= (struct ShortList
*) ap3
->List
.Next
;
2299 ap3
->List
.Next
= (struct ShortList
*) ap2
;
2303 ap2
->List
.Next
= AmiPragma
.First
;
2304 AmiPragma
.First
= (struct ShortList
*) ap2
;
2306 if(ap
&& !ap
->List
.Next
)
2307 AmiPragma
.Last
= (struct ShortList
*) ap2
;
2311 static void AddAliasName(struct AmiPragma
*ap
, struct Pragma_AliasName
*alias
,
2316 if(ap
->NumAlias
> NUMALIASNAMES
)
2317 DoError(ERR_ALIASNAMES
, linenum
, NUMALIASNAMES
);
2320 /* prevent double names */
2321 for(i
= 0; i
< ap
->NumAlias
; ++i
)
2323 if(!strcmp(ap
->AliasName
[i
]->AliasName
, alias
->AliasName
))
2326 ap
->AliasName
[ap
->NumAlias
++] = alias
;
2330 static uint32
CheckNames(struct AmiPragma
*ap
)
2336 printf("CheckNames\n");
2338 for(i
= 0; i
< ap
->CallArgs
; ++i
)
2340 if(!ap
->Args
[i
].ArgName
)
2342 if(!(ap
->Args
[i
].ArgName
= (strptr
)
2343 AllocListMem(4+strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2345 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2349 for(k
= Keywords
; *k
; ++k
)
2351 if(!stricmp(ap
->Args
[i
].ArgName
, *k
))
2353 DoError(ERR_ARGNAME_KEYWORD_CONFLICT
, ap
->Line
, i
, *k
);
2354 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4
2355 +strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2357 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2360 for(j
= 0; j
< i
; ++j
)
2362 if(!stricmp(ap
->Args
[i
].ArgName
, ap
->Args
[j
].ArgName
))
2364 DoError(ERR_ARGNAME_ARGNAME_CONFLICT
, ap
->Line
, i
+1, j
+1);
2365 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4
2366 +strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2368 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2373 /* NOTE: the replaced argument names aren't checked for conflicts */
2374 /* replaced names are of style a0arg */
2378 static uint32
ScanSFDFile(enum ABI abi
)
2384 uint32 functype
= 0;
2386 Flags2
|= FLAG2_SFDMODE
;
2388 if(strncmp("==id", in
.pos
, 4))
2389 DoError(ERR_SFD_START
, 1);
2391 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
2395 if(linenum
< 5 && in
.pos
[1] == ' ' && in
.pos
[2] == '\"')
2399 for(s
= in
.pos
; *s
&& *s
!= '"'; ++s
)
2401 if(*s
) /* library name */
2404 printf("ScanSFDFile: found library name comment\n");
2409 *(s
++) = 0; /* clear the " */
2411 Flags2
|= FLAG2_LIBNAMECOM
;
2422 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2428 d
->Private
= _public
? 0 : 1;
2429 AddItem(&Comment
, (struct ShortList
*) d
);
2436 else if(*in
.pos
== '=' && in
.pos
[1] == '=')
2439 actcom
= 0; /* no Comment */
2441 if(!strnicmp(in
.pos
, "basetype", 8))
2444 printf("ScanSFDFile: found ==basetype\n");
2446 if(!(Flags2
& FLAG2_LIBTYPE
))
2449 DoError(ERR_LIBTYPE_DECLARED_TWICE
, linenum
);
2451 in
.pos
= SkipBlanks(in
.pos
+8);
2452 if(strncmp(in
.pos
, "struct", 6))
2453 DoError(ERR_EXPECTED_STRUCT
, linenum
);
2456 in
.pos
= SkipBlanks(in
.pos
+6);
2458 DoError(ERR_EXPECTED_LIBTYPE
, linenum
);
2462 in
.pos
= SkipName(libtype
);
2463 if(*SkipBlanks(in
.pos
) != '*')
2464 DoError(ERR_EXPECTED_POINTERSIGN
, linenum
);
2471 DoError(ERR_COMMANDLINE_LIBTYPE
, linenum
);
2475 else if(!strnicmp(in
.pos
, "copyright", 9))
2477 Copyright
= SkipBlanks(in
.pos
+9);
2481 else if(!strnicmp(in
.pos
, "libname", 7))
2484 printf("ScanSFDFile: found ==libname\n");
2486 if(!(Flags2
& FLAG2_LIBNAME
))
2488 if(libname
&& !(Flags2
& FLAG2_LIBNAMECOM
))
2489 DoError(ERR_LIBNAME_DECLARED_TWICE
, linenum
);
2491 in
.pos
= SkipBlanks(in
.pos
+7);
2493 DoError(ERR_EXPECTED_LIBNAME
, linenum
);
2495 in
.pos
= SkipName(libname
= in
.pos
);
2498 DoError(ERR_COMMANDLINE_LIBNAME
, linenum
);
2502 else if(!strnicmp(in
.pos
, "base", 4))
2507 printf("ScanSFDFile: found ==base\n");
2509 if(!(Flags
& FLAG_BASENAME
))
2512 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
2514 in
.pos
= SkipBlanks(in
.pos
+4);
2516 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
2520 BaseName
= oldptr
= in
.pos
;
2521 in
.pos
= SkipName(in
.pos
);
2522 if(!(in
.pos
-oldptr
))
2523 DoError(ERR_EXPECTED_BASENAME
, linenum
);
2527 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
2532 else if(!strnicmp(in
.pos
, "bias", 4))
2538 printf("ScanSFDFile: found ==bias\n");
2541 newbias
= strtol(in
.pos
, &ptr
, 10);
2543 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
2544 else if(newbias
< 0)
2546 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
2551 in
.pos
= SkipName(in
.pos
);
2553 else if(!strnicmp(in
.pos
, "end", 3))
2557 else if(!strnicmp(in
.pos
, "public", 6))
2562 else if(!strnicmp(in
.pos
, "private", 7))
2567 else if(!strnicmp(in
.pos
, "abi", 3))
2570 printf("ScanSFDFile: found ==abi\n");
2572 in
.pos
= SkipBlanks(in
.pos
+3);
2573 if(!strnicmp(in
.pos
, "M68k", 4))
2575 abi
= ABI_M68K
; in
.pos
+= 4;
2577 else if(!strnicmp(in
.pos
, "PPC0", 4))
2579 abi
= ABI_PPC0
; in
.pos
+= 4;
2581 else if(!strnicmp(in
.pos
, "PPC2", 4))
2583 abi
= ABI_PPC2
; in
.pos
+= 4;
2585 else if(!strnicmp(in
.pos
, "PPC", 3))
2587 abi
= ABI_PPC
; in
.pos
+= 3;
2590 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
2592 else if(!strnicmp(in
.pos
, "id", 2))
2595 DoError(ERR_IDSTRING_DECLARED_TWICE
, linenum
);
2596 IDstring
= in
.pos
= SkipBlanks(in
.pos
+2);
2597 if(strncmp(in
.pos
, "$Id: ", 5))
2599 DoError(ERR_EXCPECTED_IDSTRING
, linenum
);
2603 if(*(in
.pos
-1) != '$')
2604 DoError(ERR_EXPECTED_ID_ENDSIGN
, linenum
);
2606 else if(!strnicmp(in
.pos
, "include", 7))
2610 if(!(d
= (struct Include
*) NewItem(&Includes
)))
2612 d
->Include
= SkipBlanks(in
.pos
+7);
2613 AddItem(&Includes
, (struct ShortList
*) d
);
2617 else if(!strnicmp(in
.pos
, "varargs", 7))
2620 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2624 bias
-= BIAS_OFFSET
;
2625 functype
|= FUNCFLAG_TAG
;
2629 else if(!strnicmp(in
.pos
, "alias", 5))
2632 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2636 bias
-= BIAS_OFFSET
;
2637 functype
|= FUNCFLAG_ALIAS
;
2641 else if(!strnicmp(in
.pos
, "version", 7))
2643 /* store version entries as comments */
2648 in
.pos
= SkipBlanks(in
.pos
+7);
2649 v
= strtol(in
.pos
, &ptr
, 10);
2651 printf("ScanSFDFile: found ==version %d\n", v
);
2653 if(ptr
== in
.pos
|| v
< 0)
2654 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2657 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2663 d
->Private
= _public
? 0 : 1;
2664 AddItem(&Comment
, (struct ShortList
*) d
);
2665 in
.pos
= SkipName(in
.pos
);
2668 else if(!strnicmp(in
.pos
, "reserve", 7))
2670 /* store reserved entries as comments */
2675 in
.pos
= SkipBlanks(in
.pos
+7);
2676 v
= strtol(in
.pos
, &ptr
, 10);
2678 printf("ScanSFDFile: found ==reserve %d\n", v
);
2682 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
2686 if(ptr
== in
.pos
|| v
< 0)
2687 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2690 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2696 d
->Private
= _public
? 0 : 1;
2697 AddItem(&Comment
, (struct ShortList
*) d
);
2698 in
.pos
= SkipName(in
.pos
);
2699 bias
+= BIAS_OFFSET
*v
;
2703 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
2707 uint32 ft
, startlinenum
;
2708 struct AmiPragma ap
, *ap2
;
2709 struct ClibData d
, *f
;
2715 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
2716 /* join lines, if necessary */
2717 startlinenum
= linenum
;
2719 /* first open bracket */
2720 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
)
2721 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2723 ft
= 0; /* this is needed for function pointer types, which have own
2725 /* first close bracket */
2726 while((*data
!= /*(*/')' || ft
) && data
< in
.buf
+ in
.size
)
2733 else if(*data
== '('/*)*/)
2735 else if(*data
== /*(*/')')
2739 /* second open bracket */
2740 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
)
2741 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2742 /* second close bracket */
2743 while(*data
!= /*(*/')' && data
< in
.buf
+ in
.size
)
2744 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2745 if(data
== in
.buf
+ in
.size
)
2748 DoError(ERR_UNEXPECTED_FILEEND
, linenum
);
2752 ft
= functype
; functype
= 0;
2753 memset(&ap
, 0, sizeof(struct AmiPragma
));
2754 memset(&d
, 0, sizeof(struct ClibData
));
2755 if(!GetCPPType(&d
.ReturnType
, in
.pos
, 1, 1))
2757 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE
, startlinenum
);
2762 else if(d
.ReturnType
.Unknown
)
2763 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, startlinenum
,
2764 d
.ReturnType
.Unknown
);
2766 ap
.FuncName
= d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
2767 +d
.ReturnType
.FullLength
);
2768 in
.pos
= SkipBlanks(SkipName(d
.FuncName
));
2770 if(*in
.pos
!= '('/*)*/)
2772 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2776 *(SkipName(d
.FuncName
)) = 0;
2777 in
.pos
= SkipBlanks(++in
.pos
);
2780 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2782 oldptr
= (strptr
) 1;
2783 if(d
.NumArgs
>= maxreg
)
2785 DoError(ERR_TO_MUCH_ARGUMENTS
, startlinenum
);
2788 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], in
.pos
, 0, 0))
2790 DoError(ERR_UNKNOWN_VARIABLE_TYPE
, startlinenum
, d
.NumArgs
);
2793 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
2794 DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT
, startlinenum
, d
.NumArgs
,
2795 d
.Args
[d
.NumArgs
-1].Unknown
);
2797 oldptr
= in
.pos
= SkipBlanks(d
.Args
[d
.NumArgs
-1].TypeStart
2798 + d
.Args
[d
.NumArgs
-1].FullLength
);
2799 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
2801 if(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
)
2803 oldptr
= d
.Args
[d
.NumArgs
-1].FunctionName
;
2806 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2809 else if(!(oldptr
= DupString(oldptr
, SkipName(oldptr
)-oldptr
)))
2811 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
2815 ap
.Args
[ap
.CallArgs
++].ArgName
= in
.pos
;
2816 in
.pos
= SkipName(in
.pos
);
2818 if(in
.pos
== oldptr
)
2820 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2828 in
.pos
= SkipBlanks(in
.pos
);
2829 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
2831 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2836 in
.pos
= SkipBlanks(++in
.pos
);
2837 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
&&
2838 !(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
))
2839 *(SkipName(oldptr
)) = 0;
2841 printf("Added last argument %d (%s) for %s (%d bytes)\n", d
.NumArgs
,
2842 oldptr
, d
.FuncName
, d
.Args
[d
.NumArgs
-1].FullLength
);
2849 in
.pos
= SkipBlanks(++in
.pos
);
2850 *(SkipName(oldptr
)) = 0;
2852 printf("Added argument %d (%s) for %s (%d bytes)\n", d
.NumArgs
,
2853 oldptr
, d
.FuncName
, d
.Args
[d
.NumArgs
-1].FullLength
);
2857 if(*in
.pos
== /*(*/')')
2859 if(!oldptr
) /* oldptr == 0 means parsing was valid */
2861 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
2864 memcpy(f
, &d
, sizeof(struct ClibData
));
2870 struct ClibData
*e
= clibdata
;
2877 printf("Added prototype for %s (line %ld) with %d args\n", f
->FuncName
,
2878 startlinenum
, f
->NumArgs
);
2880 if(*(in
.pos
= SkipBlanks(in
.pos
)) != '('/*)*/)
2882 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2889 DoError(ERR_ASSUMING_BIAS_OF_30
, startlinenum
);
2895 ap
.Line
= startlinenum
;
2896 bias
+= BIAS_OFFSET
;
2899 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
2903 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2905 if(*in
.pos
!= /*(*/')')
2907 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2912 ap
.NumArgs
= ap
.CallArgs
;
2914 ap
.Flags
|= AMIPRAGFLAG_PPC
;
2916 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
2917 else if(abi
== ABI_PPC2
)
2918 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
2928 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
2930 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
2933 in
.pos
= SkipName(oldptr
);
2934 len
= in
.pos
-oldptr
;
2936 for(i
= 0; i
< MAXREG
; ++i
)
2937 if(!strnicmp(RegNames
[i
], oldptr
, len
))
2942 DoError(ERR_EXPECTED_REGISTER_NAME
, startlinenum
);
2945 else if(i
== REG_A6
)
2946 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
2947 else if(i
== REG_A5
)
2948 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
2949 else if(i
== REG_A4
)
2950 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
2951 else if(i
== REG_D7
)
2952 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
2953 else if(i
== REG_A7
)
2955 DoError(ERR_A7_NOT_ALLOWED
, startlinenum
);
2958 else if(i
>= REG_FP0
)
2959 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
2961 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
2963 for(i
= 0; i
< ap
.NumArgs
; i
++)
2965 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
2967 DoError(ERR_REGISTER_USED_TWICE
, startlinenum
);
2976 in
.pos
= SkipBlanks(in
.pos
);
2977 if(*in
.pos
!= ',' && *in
.pos
!= '-' && *in
.pos
!= '/' &&
2978 *in
.pos
!= /*(*/')')
2980 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2983 } while(*in
.pos
!= /*(*/')');
2985 if(*in
.pos
!= /*(*/')')
2994 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
2995 if(ft
&& !(ft
& FUNCFLAG_TAG
) && ap
.NumArgs
!= ap2
->NumArgs
)
2996 ft
= 0; /* like DoPkt, handle as seperate function */
2997 if(ft
) /* handle alias and varargs */
2999 if(ap2
->TagName
|| (ft
& FUNCFLAG_ALIAS
))
3001 struct Pragma_AliasName
*p
;
3003 if((p
= (struct Pragma_AliasName
*)
3004 AllocListMem(sizeof(struct Pragma_AliasName
))))
3006 p
->FunctionName
= ap2
->TagName
;
3007 p
->AliasName
= ap
.FuncName
;
3008 p
->Type
= (ft
& FUNCFLAG_TAG
) ? FUNCFLAG_TAG
: FUNCFLAG_NORMAL
;
3009 AddAliasName(ap2
, p
, startlinenum
);
3016 ap2
->TagName
= ap
.FuncName
;
3019 if(ap
.CallArgs
!= ap2
->CallArgs
)
3021 if(ap2
->CallArgs
+ 1 == ap
.CallArgs
&& d
.Args
[d
.NumArgs
-1].Type
3022 == CPP_TYPE_VARARGS
)
3029 if(ap
.NumArgs
!= ap2
->NumArgs
)
3031 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
3033 else if(abi
== ABI_M68K
)
3037 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3039 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3041 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
3047 else if(abi
== ABI_M68K
)
3049 if(ap
.CallArgs
!= ap
.NumArgs
)
3050 { /* this is surely no longer necessary, as there wont be any
3051 varargs functions here */
3052 if(ap
.CallArgs
== ap
.NumArgs
+1 && d
.Args
[d
.NumArgs
-1].Type
3053 == CPP_TYPE_VARARGS
)
3056 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3059 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3061 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3062 DoError(ERR_FLOATARG_NOT_ALLOWED
, startlinenum
);
3063 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3064 && !(Flags
& FLAG_PPCONLY
))
3065 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3066 struct AmiPragma
*d
;
3067 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3069 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3072 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3077 if(!(Flags
& FLAG_NOPPC
))
3079 struct AmiPragma
*d
;
3080 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3082 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3085 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3091 in
.pos
= SkipBlanks(in
.pos
);
3093 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3094 ++in
.pos
; /* skip '\0' */
3098 DoError(ERR_MISSING_SFDEND
, 0);
3103 static uint32
ScanFDFile(void)
3110 uint32 shadowmode
= 0;
3111 enum ABI abi
= ABI_M68K
;
3115 if(!stricmp(defabi
, "M68k"))
3117 else if(!stricmp(defabi
, "PPC0"))
3119 else if(!stricmp(defabi
, "PPC2"))
3121 else if(!stricmp(defabi
, "PPC"))
3124 DoError(ERR_UNKNOWN_ABI
, 0, defabi
);
3127 if(in
.size
> 10 && in
.pos
[0] == '=' && in
.pos
[1] == '=')
3128 return ScanSFDFile(abi
);
3131 printf("ScanFDFile:\n");
3134 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
3136 if(*in
.pos
== '*') /* Comment */
3138 strptr oldpos
= in
.pos
;
3140 printf("ScanFDFile: found a comment\n");
3142 in
.pos
= SkipBlanks(in
.pos
+1);
3143 if(!strnicmp(in
.pos
, "notagcall", 9))
3145 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
;
3149 --tagfuncs
; ap
->TagName
= 0;
3150 ap
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3152 in
.pos
= SkipBlanks(in
.pos
+ 9);
3154 else if(!strnicmp(in
.pos
, "tagcall", 7)) /* Tag to create? */
3156 struct AmiPragma
*prevpragma
= (struct AmiPragma
*) AmiPragma
.Last
;
3158 in
.pos
= SkipBlanks(in
.pos
+ 7);
3161 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA
, linenum
);
3166 if(!prevpragma
->NumArgs
)
3168 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT
, linenum
);
3173 /* Get the tag functions name. */
3175 if(!prevpragma
->TagName
&& (_public
|| (Flags
& FLAG_PRIVATE
)))
3180 strptr oldptr
, tptr
= prevpragma
->TagName
;
3182 len
= strlen(prevpragma
->FuncName
)+strlen(in
.pos
)+1;
3183 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
)))
3190 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3191 in
.pos
= SkipName(in
.pos
);
3192 if((len
= in
.pos
-oldptr
))
3194 removeptr
= prevpragma
->TagName
+strlen(prevpragma
->TagName
)-len
;
3195 if(strncmp(removeptr
, oldptr
, len
))
3198 printf("ScanFDFile: *tagcall -: %s, %s, %d\n", removeptr
, oldptr
, len
);
3200 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
, linenum
);
3201 prevpragma
->TagName
= tptr
;
3208 in
.pos
= SkipBlanks(in
.pos
);
3211 in
.pos
= SkipBlanks(in
.pos
+1);
3213 *in
.pos
= toupper(*in
.pos
);
3215 in
.pos
= SkipName((oldptr
= in
.pos
));
3216 len
= in
.pos
-oldptr
;
3219 uint32 a
= strlen(prevpragma
->TagName
);
3220 memcpy(prevpragma
->TagName
+a
, oldptr
, len
);
3221 prevpragma
->TagName
[a
+len
] = '\0';
3224 else if(!prevpragma
->TagName
)
3226 len
= strlen(prevpragma
->FuncName
);
3227 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
+4)))
3229 memcpy(prevpragma
->TagName
+ len
, "Tags", 5);
3239 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
3245 d
->Private
= _public
? 0 : 1;
3246 AddItem(&Comment
, (struct ShortList
*) d
);
3253 else if(*in
.pos
== '#' && in
.pos
[1] == '#')
3256 actcom
= 0; /* no Comment */
3258 if(!strnicmp(in
.pos
, "base", 4))
3263 printf("ScanFDFile: found ##base\n");
3265 if(!(Flags
& FLAG_BASENAME
))
3268 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
3270 in
.pos
= SkipBlanks(in
.pos
+4);
3272 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
3276 BaseName
= oldptr
= in
.pos
;
3277 in
.pos
= SkipName(in
.pos
);
3278 if(!(in
.pos
-oldptr
))
3279 DoError(ERR_EXPECTED_BASENAME
, linenum
);
3283 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
3288 else if(!strnicmp(in
.pos
, "bias", 4))
3294 printf("ScanFDFile: found ##bias\n");
3297 newbias
= strtol(in
.pos
, &ptr
, 10);
3299 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
3300 else if(newbias
< 0)
3302 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
3307 in
.pos
= SkipName(in
.pos
);
3309 else if(!strnicmp(in
.pos
, "end", 3))
3313 else if(!strnicmp(in
.pos
, "shadow", 6)) /* introduced by Storm */
3316 if(bias
== -1 || !AmiPragma
.First
)
3317 DoError(ERR_EARLY_SHADOW
, linenum
);
3320 bias
-= BIAS_OFFSET
;
3324 else if(!strnicmp(in
.pos
, "public", 6))
3329 else if(!strnicmp(in
.pos
, "private", 7))
3334 else if(!strnicmp(in
.pos
, "abi", 3))
3337 printf("ScanFDFile: found ##abi\n");
3339 in
.pos
= SkipBlanks(in
.pos
+3);
3340 if(!strnicmp(in
.pos
, "M68k", 4))
3342 abi
= ABI_M68K
; in
.pos
+= 4;
3344 else if(!strnicmp(in
.pos
, "PPC0", 4))
3346 abi
= ABI_PPC0
; in
.pos
+= 4;
3348 else if(!strnicmp(in
.pos
, "PPC2", 4))
3350 abi
= ABI_PPC2
; in
.pos
+= 4;
3352 else if(!strnicmp(in
.pos
, "PPC", 3))
3354 abi
= ABI_PPC
; in
.pos
+= 3;
3357 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
3360 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
3366 struct AmiPragma ap
, *ap2
;
3369 printf("ScanFDFile: scan Function\n");
3371 memset(&ap
, 0, sizeof(struct AmiPragma
));
3374 oldptr
= in
.pos
= SkipBlanks(in
.pos
);
3375 in
.pos
= SkipName(oldptr
);
3376 if(!(len
= in
.pos
-oldptr
))
3378 DoError(ERR_MISSING_FUNCTION_NAME
, linenum
);
3383 ap
.FuncName
= oldptr
;
3385 in
.pos
= SkipBlanks(in
.pos
);
3386 if(*in
.pos
!= '('/*)*/)
3388 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3393 oldptr
[len
] = '\0'; /* create c string of FunctionName */
3396 printf("ScanFDFile: found function %s\n", ap
.FuncName
);
3399 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
3402 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3404 if(*in
.pos
== '*') /* strange OS3.9 files */
3406 DoError(ERR_ILLEGAL_CHARACTER_DETECTED
, linenum
);
3407 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3410 if(*in
.pos
== /*(*/')' && !ap
.CallArgs
)
3413 if(ap
.CallArgs
>= maxreg
)
3415 DoError(ERR_TO_MUCH_ARGUMENTS
, linenum
); break;
3418 if(!strncmp(in
.pos
, "void", 4))
3420 /* allows "(void)" instead of ()" */
3421 in
.pos
= SkipBlanks(in
.pos
+ 4);
3422 if(*in
.pos
!= /*(*/')')
3423 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3427 if(!strncmp(in
.pos
, "...", 3))
3429 ap
.Flags
= AMIPRAGFLAG_VARARGS
;
3430 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3431 in
.pos
= SkipBlanks(in
.pos
+3);
3432 if(*in
.pos
!= /*(*/')')
3433 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3437 in
.pos
= SkipName(oldptr
);
3440 if(!(len
= in
.pos
-oldptr
))
3442 DoError(ERR_EXPECTED_ARGUMENT_NAME
, linenum
);
3443 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3447 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
3449 in
.pos
= SkipBlanks(in
.pos
);
3451 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3453 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3456 if(*in
.pos
!= /*(*/')') /* create c string ending */
3458 } while(*in
.pos
!= /*(*/')');
3460 if(*in
.pos
!= /*(*/')')
3467 *oldptr
= '\0'; /* create c string ending for last argument */
3471 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
3478 bias
+= BIAS_OFFSET
;
3481 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
3483 in
.pos
= SkipBlanks(in
.pos
+1);
3485 if(*in
.pos
|| ap
.CallArgs
)
3486 /* support for FD's without second empty bracket pair */
3488 if(*in
.pos
!= '('/*)*/)
3490 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3501 oldptr
= in
.pos
= SkipBlanks(in
.pos
+ 1);
3503 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
3506 if(!strncmp(in
.pos
, "base", 4))
3508 in
.pos
= SkipBlanks(in
.pos
+ 4);
3511 in
.pos
= SkipBlanks(in
.pos
+ 1);
3512 if(!strncmp(in
.pos
, "sysv",4))
3514 /* MorphOS V.4 with base in r3: (base,sysv) */
3515 ap
.Flags
|= AMIPRAGFLAG_MOSBASESYSV
;
3516 ap
.NumArgs
= ap
.CallArgs
;
3517 in
.pos
= SkipBlanks(in
.pos
+ 4);
3518 if(*in
.pos
!= /*(*/')')
3519 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3524 else if(!strncmp(in
.pos
, "sysv", 4))
3526 in
.pos
= SkipBlanks(in
.pos
+ 4);
3529 in
.pos
= SkipBlanks(in
.pos
+ 1);
3530 if(!strncmp(in
.pos
, "r12base",7))
3532 /* MorphOS V.4 without passing base: (sysv) */
3533 ap
.Flags
|= AMIPRAGFLAG_MOSSYSVR12
;
3534 ap
.NumArgs
= ap
.CallArgs
;
3535 in
.pos
= SkipBlanks(in
.pos
+ 7);
3536 if(*in
.pos
!= /*(*/')')
3537 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3541 else if (*in
.pos
== /*(*/')')
3543 /* MorphOS V.4 without passing base: (sysv) */
3544 ap
.Flags
|= AMIPRAGFLAG_MOSSYSV
;
3545 ap
.NumArgs
= ap
.CallArgs
;
3550 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3555 in
.pos
= SkipName(oldptr
);
3556 len
= in
.pos
-oldptr
;
3558 for(i
= 0; i
< MAXREG
; ++i
)
3559 if(!strnicmp(RegNames
[i
], oldptr
, len
))
3564 DoError(ERR_EXPECTED_REGISTER_NAME
, linenum
);
3567 else if(i
== REG_A6
)
3568 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
3569 else if(i
== REG_A5
)
3570 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
3571 else if(i
== REG_A4
)
3572 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
3573 else if(i
== REG_D7
)
3574 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
3575 else if(i
== REG_A7
)
3577 DoError(ERR_A7_NOT_ALLOWED
, linenum
);
3580 else if(i
>= REG_FP0
)
3581 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
3583 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
3585 for(i
= 0; i
< ap
.NumArgs
; i
++)
3587 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
3589 DoError(ERR_REGISTER_USED_TWICE
, linenum
);
3598 in
.pos
= SkipBlanks(in
.pos
);
3599 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3601 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3604 } while(*in
.pos
!= /*(*/')');
3606 if(*in
.pos
!= /*(*/')')
3617 while(*in
.pos
&& *in
.pos
!= /*(*/')')
3619 if(*in
.pos
!= /*(*/')')
3621 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3626 ap
.NumArgs
= ap
.CallArgs
;
3628 ap
.Flags
|= AMIPRAGFLAG_PPC
;
3630 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
3631 else if(abi
== ABI_PPC2
)
3632 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
3636 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3638 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
3641 if(ap2
->TagName
&& !(ap2
->Flags
& AMIPRAGFLAG_OWNTAGFUNC
))
3643 struct Pragma_AliasName
*p
;
3644 DoError(ERR_DOUBLE_VARARGS
, linenum
);
3646 if((p
= (struct Pragma_AliasName
*)
3647 AllocListMem(sizeof(struct Pragma_AliasName
))))
3649 p
->FunctionName
= ap2
->TagName
;
3650 p
->AliasName
= ap
.FuncName
;
3651 p
->Type
= FUNCFLAG_TAG
;
3652 AddAliasName(ap2
, p
, linenum
);
3657 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2
->TagName
);
3663 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2
->TagName
);
3665 ap2
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3666 ap2
->TagName
= ap
.FuncName
;
3669 if(ap
.NumArgs
!= ap2
->NumArgs
)
3670 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3671 else if(abi
== ABI_M68K
)
3675 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3677 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3679 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3685 /* handle them as alias instead seperate */
3686 else if(ap2
&& ap2
->Bias
== ap
.Bias
&& ap2
->NumArgs
== ap
.NumArgs
)
3688 struct Pragma_AliasName
*p
;
3690 if((p
= (struct Pragma_AliasName
*)
3691 AllocListMem(sizeof(struct Pragma_AliasName
))))
3693 p
->FunctionName
= ap2
->TagName
;
3694 p
->AliasName
= ap
.FuncName
;
3695 p
->Type
= FUNCFLAG_NORMAL
;
3696 AddAliasName(ap2
, p
, linenum
);
3702 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3704 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3706 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3714 if(ap
.Flags
& AMIPRAGFLAG_VARARGS
)
3716 ap
.TagName
= ap
.FuncName
;
3719 else if((_public
|| (Flags
& FLAG_PRIVATE
)) &&
3720 !MakeTagFunction(&ap
))
3722 else /* check the alias names */
3726 while(Pragma_AliasNames
[i
].FunctionName
)
3728 if(!strcmp(ap
.FuncName
, Pragma_AliasNames
[i
].FunctionName
) ||
3729 (ap
.TagName
&& !strcmp(ap
.TagName
,
3730 Pragma_AliasNames
[i
].FunctionName
)))
3732 AddAliasName(&ap
, (struct Pragma_AliasName
*)
3733 &Pragma_AliasNames
[i
], linenum
);
3741 if(ap
.CallArgs
!= ap
.NumArgs
)
3742 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3744 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3746 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3747 DoError(ERR_FLOATARG_NOT_ALLOWED
, linenum
);
3748 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3749 && !(Flags
& FLAG_PPCONLY
))
3750 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3751 struct AmiPragma
*d
;
3752 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3754 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3757 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3764 if(!(Flags
& FLAG_NOPPC
))
3766 struct AmiPragma
*d
;
3767 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3769 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3772 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3783 in
.pos
= SkipBlanks(in
.pos
);
3785 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3786 ++in
.pos
; /* skip '\0' */
3790 DoError(ERR_MISSING_END
, 0);
3795 static int32
ScanTypes(strptr ptr
, uint32 size
)
3797 struct CPP_ExternNames
*a
= 0, *b
= 0;
3798 strptr endptr
= ptr
+size
;
3801 for(line
= 1; ptr
< endptr
; ++line
)
3803 struct CPP_ExternNames
*n
;
3805 if(*ptr
== '*') /* skip comments */
3807 while(ptr
< endptr
&& *(ptr
++) != '\n')
3810 else if((n
= (struct CPP_ExternNames
*)
3811 AllocListMem(sizeof(struct CPP_ExternNames
))))
3815 n
->Type
= ptr
; /* store start */
3817 while(ptr
< endptr
&& *ptr
!= ':' && *ptr
!= '\n' && *ptr
!= '\t'
3820 wptr
= SkipBlanks(ptr
);
3821 if(*(wptr
++) != ':')
3825 n
->NameType
.StructureName
= n
->Type
;
3826 n
->NameType
.StructureLength
= ptr
-n
->Type
; /* for struct ! types */
3828 if(!GetCPPType(&n
->NameType
, (ptr
= SkipBlanks(wptr
)), 0, 1))
3831 printf("'%20s', slen %2d, typelen %3d, pntd %d, type %c, sn '%.3s'\n",
3832 n
->Type
, n
->NameType
.StructureLength
, n
->NameType
.FullLength
,
3833 n
->NameType
.PointerDepth
, n
->NameType
.Type
? n
->NameType
.Type
: 's',
3834 n
->NameType
.StructureName
? n
->NameType
.StructureName
: "<e>");
3836 ptr
= SkipBlanks(n
->NameType
.TypeStart
+n
->NameType
.FullLength
);
3837 if(*(ptr
++) != '\n')
3840 printf("%.30s\n", ptr
);
3854 extnames
= b
; /* now store the list */
3858 static void FindHeader(void)
3860 strptr str
= HEADER
;
3875 else if(*str
== '/')
3878 else if(*str
== '*' || *str
== ';')
3880 else if(*str
== '{'/*}*/)
3884 else if(*str
== '('/*)*/ && *(++str
) == '*')
3890 while(*str
&& *(str
++) != '\n')
3896 while(*str
&& (*(str
-1) != '*' || *str
!= '/'))
3898 while(*str
&& *(str
++) != '\n')
3903 while(*str
&& *str
!= /*{*/'}')
3905 while(*str
&& *(str
++) != '\n')
3910 while(*str
&& (*(str
-1) != '*' || *str
!= /*(*/')'))
3912 while(*str
&& *(str
++) != '\n')
3917 headersize
= str
-HEADER
;
3920 HEADER
= 0; headersize
= 0;
3924 /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
3925 static uint32
GetRegisterData(struct AmiPragma
*ap
)
3928 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
3929 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
3931 register uint32 i
, data
= 0, reg
;
3933 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3935 if((reg
= ap
->Args
[i
].ArgReg
) <= REG_FP0
)
3937 if(reg
>= 10 || (reg
>= 2 && reg
<= 7)) /* A2-A7 and D2-D7 */
3938 data
|= (1 << (reg
+ 16)) + (1 << (15 - reg
));
3941 if(data
) /* set A6 only when other register used */
3946 static uint16
GetFRegisterData(struct AmiPragma
*ap
)
3949 F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
3950 F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
3952 register uint32 i
, reg
;
3953 register uint16 data
= 0;
3955 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3957 if((reg
= ap
->Args
[i
].ArgReg
) >= REG_FP2
)
3960 data
|= (1 << (reg
+ 8)) + (1 << (7 - reg
));
3966 static uint32
OutputXDEF(uint32 offset
, strptr format
, ...)
3972 va_start(a
, format
);
3973 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3977 EndPutM32(buf
+4+i
, offset
); /* the definition offset */
3979 EndPutM32(buf
, (EXT_DEF
<<24) + (i
>>2));
3981 return DoOutputDirect(buf
, i
+8);
3984 static uint32
OutputXREF(uint32 offset
, uint32 type
, strptr format
, ...)
3990 va_start(a
, format
);
3991 i
= vsprintf((strptr
)(buf
+4), format
, a
);
3995 EndPutM32(buf
+4+i
, 1); /* 1 reference */
3996 EndPutM32(buf
+8+i
, offset
); /* the definition offset */
3998 EndPutM32(buf
, (type
<< 24) + (i
>>2));
4000 return DoOutputDirect(buf
, i
+12);
4003 static uint32
OutputXREF2(uint32 offset1
, uint32 offset2
, uint32 type
,
4010 va_start(a
, format
);
4011 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4015 EndPutM32(buf
+4+i
, 2); /* 2 references */
4016 EndPutM32(buf
+8+i
, offset1
); /* the definition offset */
4017 EndPutM32(buf
+12+i
, offset2
); /* the definition offset */
4019 EndPutM32(buf
, (type
<< 24) + (i
>>2));
4021 return DoOutputDirect(buf
, i
+16);
4024 static uint32
OutputSYMBOL(uint32 offset
, strptr format
, ...)
4030 va_start(a
, format
);
4031 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4035 EndPutM32(buf
+4+i
, offset
);
4037 EndPutM32(buf
, (0 << 24) + (i
>>2));
4039 return DoOutputDirect(buf
, i
+8);
4042 static uint8
*AsmStackCopy(uint8
*data
, struct AmiPragma
*ap
, uint32 flags
,
4045 uint32 i
, j
, k
, l
, tofs
;
4047 if(Flags
& FLAG_PASCAL
)
4053 if(ap
->Args
[k
-1].ArgReg
>= REG_FP0
)
4055 struct ClibData
*cd
;
4057 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
4058 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
4060 if(cd
&& IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_DOUBLE
))
4062 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
4063 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
4068 if(!cd
|| !IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_FLOAT
))
4069 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4070 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
4071 EndPutM16Inc(data
, (ofs
++) << 2);
4074 else if((k
>= 2) && (ap
->Args
[k
-1].ArgReg
< ap
->Args
[k
-2].ArgReg
)
4075 && ap
->Args
[k
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4080 j
= ap
->Args
[--k
].ArgReg
;
4084 } while(k
&& j
< ap
->Args
[k
-1].ArgReg
4085 && ap
->Args
[k
-1].ArgReg
< REG_FP0
);
4086 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4087 EndPutM16Inc(data
, l
);
4088 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
4092 l
= 0x202F; /* MOVE.L offs(A7),xxx */
4094 if((j
= ap
->Args
[--k
].ArgReg
) > 7)
4096 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
4098 /* set destination register and store */
4099 EndPutM16Inc(data
, l
| (j
<< 9));
4100 EndPutM16Inc(data
, (ofs
++) << 2);
4108 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4112 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4114 struct ClibData
*cd
;
4116 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
4117 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
4119 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4121 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
4122 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
4127 if(!cd
|| !IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4128 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4129 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
4130 EndPutM16Inc(data
, (ofs
++) << 2);
4133 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
)
4134 && ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4139 j
= ap
->Args
[i
++].ArgReg
;
4143 } while(i
< k
&& j
< ap
->Args
[i
].ArgReg
4144 && ap
->Args
[i
].ArgReg
< REG_FP0
);
4145 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4146 EndPutM16Inc(data
, l
); /* Store MOVEM.L data */
4147 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
4151 l
= 0x202F; /* MOVE.L offs(A7),xxx */
4153 if((j
= ap
->Args
[i
++].ArgReg
) > 7)
4155 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
4157 /* set destination register and store */
4158 EndPutM16Inc(data
, l
| (j
<< 9));
4159 EndPutM16Inc(data
, (ofs
++) << 2);
4165 if((j
= ap
->Args
[i
].ArgReg
) > 7)
4167 EndPutM16Inc(data
, 0x41EF | ((j
-8) << 9)); /* LEA xxx(A7),Ax */
4168 EndPutM16Inc(data
, ofs
<< 2);
4172 EndPutM16Inc(data
, 0x200F | (j
<< 9)); /* MOVE.L A7,Dx */
4173 EndPutM16Inc(data
, 0x5080 | j
); /* ADDQ.L #8,Dx */
4177 EndPutM16Inc(data
, 0x486F); /* PEA xxx(A7) */
4178 EndPutM16Inc(data
, ofs
<< 2);
4179 EndPutM16Inc(data
, 0x201F | j
<< 9); /* MOVE.L offs(A7),Dx */
4186 /* ------------------------------------------------------------------ */
4188 static void DoError(uint32 errnum
, uint32 line
, ...)
4190 uint32 err
= errnum
& 0xFFFF;
4193 if(Flags
& FLAG_DIDERROR
)
4196 if(!Errors
[err
].Type
)
4197 Flags
|= FLAG_DIDERROR
;
4202 printf("%s %ld in line %ld%s: ",
4203 (Errors
[err
].Type
? "Warning" : "Error"),
4205 errnum
& ERROFFSET_CLIB
? " of clib file" : "");
4209 printf("%s %ld : ", (Errors
[err
].Type
? "Warning" : "Error"), err
);
4211 vprintf(Errors
[err
].Error
, a
);
4213 if(line
&& Errors
[err
].Skip
)
4221 static uint32
CheckError(struct AmiPragma
*ap
, uint32 errflags
)
4223 errflags
&= ap
->Flags
;
4225 if(errflags
& AMIPRAGFLAG_ARGCOUNT
)
4227 if(!(ap
->Flags
& AMIPRAGFLAG_DIDARGWARN
))
4229 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
, ap
->Line
);
4230 ap
->Flags
|= AMIPRAGFLAG_DIDARGWARN
;
4234 else if(errflags
& AMIPRAGFLAG_FLOATARG
)
4236 if(!(ap
->Flags
& AMIPRAGFLAG_DIDFLOATWARN
))
4238 DoError(ERR_FLOATARG_NOT_ALLOWED
, ap
->Line
);
4239 ap
->Flags
|= AMIPRAGFLAG_DIDFLOATWARN
;
4243 else if(errflags
& AMIPRAGFLAG_A6USE
)
4245 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
4248 else if(errflags
& AMIPRAGFLAG_A5USE
)
4250 DoError(ERR_A5_NOT_ALLOWED
, ap
->Line
);
4253 else if(errflags
& AMIPRAGFLAG_PPC
)
4255 if(!(Flags
& FLAG_DIDPPCWARN
))
4257 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4258 Flags
|= FLAG_DIDPPCWARN
;
4262 else if(errflags
& AMIPRAGFLAG_M68K
)
4264 if(!(Flags
& FLAG_DIDM68KWARN
))
4266 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4267 Flags
|= FLAG_DIDM68KWARN
;
4271 else if(errflags
& AMIPRAGFLAG_MOSBASESYSV
)
4273 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED
, ap
->Line
);
4280 static uint32
DoOutput(strptr format
, ...)
4287 va_start(a
, format
);
4288 if(vfprintf(outfile
, format
, a
) < 0)
4292 return Output_Error
;
4295 static uint32
DoOutputDirect(void * data
, size_t size
)
4301 if(fwrite(data
, size
, 1, outfile
) != 1)
4304 return Output_Error
;
4307 /* ------------------------------------------------------------------ */
4309 static struct ShortList
*NewItem(struct ShortListRoot
*list
)
4311 struct ShortList
*item
;
4312 if(!list
|| !list
->Size
)
4314 if(!(item
= (struct ShortList
*) AllocListMem(list
->Size
)))
4319 static struct ShortList
*RemoveItem(struct ShortListRoot
*list
,
4320 struct ShortList
*item
)
4322 struct ShortList
*n
= list
->First
;
4325 list
->First
= item
->Next
;
4328 while(n
&& n
->Next
!= item
)
4332 if(!(n
->Next
= item
->Next
))
4339 static void AddItem(struct ShortListRoot
*list
, struct ShortList
*item
)
4342 list
->First
= list
->Last
= item
;
4345 list
->Last
->Next
= item
;
4350 /* ------------------------------------------------------------------ */
4352 uint32
FuncAMICALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4356 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4359 Flags
|= FLAG_DONE
; /* We did something */
4361 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags
& FUNCFLAG_TAG
?
4362 "tagcall" : "amicall", BaseName
, ap
->Bias
, name
);
4364 for(i
= 0; i
< ap
->NumArgs
; ++i
)
4366 DoOutput("%s",RegNames
[ap
->Args
[i
].ArgReg
]);
4367 if(i
+1 < ap
->NumArgs
)
4371 return DoOutput(/*((*/"))\n");
4374 uint32
FuncLIBCALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4378 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4381 Flags
|= FLAG_DONE
; /* We did something */
4383 if(ap
->Flags
& AMIPRAGFLAG_FLOATARG
)
4385 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName
, name
, ap
->Bias
);
4386 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4387 DoOutput("%02x", ap
->Args
[i
].ArgReg
);
4389 return DoOutput("00%02x\n", ap
->NumArgs
);
4392 if((Flags
& FLAG_SYSCALL
) && !strcmp(BaseName
,"SysBase") &&
4393 (flags
& FUNCFLAG_NORMAL
))
4394 DoOutput("#pragma syscall %-22s %03x ", name
, ap
->Bias
);
4396 DoOutput("#pragma %s %s %-22s %03x ", (flags
& FUNCFLAG_TAG
) ?
4397 "tagcall" : "libcall", BaseName
, name
, ap
->Bias
);
4399 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4400 DoOutput("%x", ap
->Args
[i
].ArgReg
);
4402 return DoOutput("0%x\n", ap
->NumArgs
);
4405 uint32
FuncAsmText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4412 struct ClibData
*cd
;
4414 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4417 Flags
|= FLAG_DONE
; /* We did something */
4419 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
4420 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
4422 if(Flags
& FLAG_SINGLEFILE
)
4424 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
4429 DoOutputDirect(HEADER
, headersize
);
4433 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
4435 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
4436 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
4439 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name
, name
);
4440 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4442 DoOutput("\tXDEF\t%s\n%s:\n",name
, name
);
4446 DoOutput("\tXDEF\t%s_\n%s_:\n",name
, name
);
4447 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4452 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4454 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4455 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name
, txt
, name
, txt
);
4461 if((registers
= GetRegisterData(ap
) >> 16))
4463 if(Flags
& FLAG_NOMOVEM
)
4465 for(i
= 0; i
<= 15; ++i
)
4467 if(registers
& (1 << i
))
4470 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper
[i
]);
4476 uint16 l
= registers
;
4478 DoOutput("\tMOVEM.L\t");
4480 for(i
= 0; i
<= 15; ++i
)
4486 DoOutput("%s",RegNamesUpper
[i
]);
4491 DoOutput(",-(A7)\n");
4496 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset
;
4499 if((fregs
= GetFRegisterData(ap
) >> 8))
4503 DoOutput("\tFMOVEM.X\t");
4505 for(i
= 0; i
<= 7; ++i
)
4511 DoOutput("%s",RegNamesUpper
[REG_FP0
+ i
]);
4516 DoOutput(",-(A7)\n");
4519 if(Flags
& FLAG_SMALLDATA
)
4521 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1
, BaseName
, c2
);
4524 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName
);
4526 if(!(Flags
& FLAG_PASCAL
))
4530 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4534 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4537 struct ClibData
*cd
;
4539 cd
= GetClibFunc(name
, ap
, flags
);
4540 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4541 t
= CPP_TYPE_DOUBLE
;
4542 else if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4546 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4550 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
4551 ? 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4553 if(t
== CPP_TYPE_DOUBLE
)
4557 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
) &&
4558 ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4560 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4561 RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4565 DoOutput("/%s", RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4567 } while((i
< k
) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
].ArgReg
) &&
4568 ap
->Args
[i
].ArgReg
< REG_FP0
);
4573 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4574 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4575 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4582 if(ap
->Args
[i
].ArgReg
> 7)
4583 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1
, offset
<<2, c2
,
4584 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4585 else if(offset
<= 2)
4586 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4587 RegNamesUpper
[ap
->Args
[i
].ArgReg
],offset
<<2,
4588 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4590 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1
,
4591 offset
<<2, c2
,RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4600 if(ap
->Args
[i
-1].ArgReg
>= REG_FP0
)
4603 struct ClibData
*cd
;
4605 cd
= GetClibFunc(name
, ap
, flags
);
4607 if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_DOUBLE
))
4608 t
= CPP_TYPE_DOUBLE
;
4609 else if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_FLOAT
))
4613 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4617 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
?
4618 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4619 if(t
== CPP_TYPE_DOUBLE
)
4623 else if((i
>= 2) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
-2].ArgReg
) &&
4624 ap
->Args
[i
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4626 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4627 RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4631 DoOutput("/%s", RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4633 } while(i
&& (ap
->Args
[i
].ArgReg
< ap
->Args
[i
-1].ArgReg
) &&
4634 ap
->Args
[i
-1].ArgReg
< REG_FP0
);
4640 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4641 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4642 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4647 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1
, ap
->Bias
, c2
);
4651 DoOutput("\tFMOVEM.X\t(A7)+,");
4653 for(i
= 0; i
<= 7; ++i
)
4655 if(fregs
& (1 << i
))
4658 DoOutput("%s",RegNamesUpper
[REG_FP0
+ i
]);
4668 if(Flags
& FLAG_NOMOVEM
)
4670 for(i
= 15; i
>= 0; --i
)
4672 if(registers
& (1 << i
))
4673 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i
>= REG_A0
? "A" : "",
4679 DoOutput("\tMOVEM.L\t(A7)+,");
4681 for(i
= 0; i
<= 15; ++i
)
4683 if(registers
& (1 << i
))
4685 registers
^= 1 << i
;
4686 DoOutput("%s",RegNamesUpper
[i
]);
4695 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4697 return DoOutput("\tRTS\n");
4700 uint32
FuncAsmCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4702 uint32 registers
, offset
= 1, baseref
;
4707 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4710 Flags
|= FLAG_DONE
; /* We did something */
4712 registers
= GetRegisterData(ap
);
4713 fregs
= GetFRegisterData(ap
);
4715 i
= strlen(name
) + 2;
4716 EndPutM32(tempbuf
, HUNK_UNIT
);
4717 EndPutM32(tempbuf
+4, (i
+3)>>2);
4718 DoOutputDirect(tempbuf
, 8);
4719 DoOutput("%s.o", name
);
4720 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4722 i
= strlen(hunkname
);
4723 EndPutM32(tempbuf
, HUNK_NAME
);
4724 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
4725 DoOutputDirect(tempbuf
, 8);
4726 DoOutputDirect(hunkname
, i
);
4727 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4729 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
4733 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
4734 ++offset
; /* one long more on stack */
4738 if(Flags
& FLAG_NOMOVEM
)
4740 for(i
= 0; i
<= 15; ++i
)
4742 if(registers
& (1<< (16+i
)))
4744 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
4752 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
4753 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
4754 for(l
= (uint16
) registers
; l
; l
>>= 1)
4757 ++offset
; /* get offset addition */
4765 EndPutM16Inc(data
, 0xF227); /* FMOVEM.X xxx,-(A7) */
4766 EndPutM16Inc(data
, 0xE000 + ((fregs
>>8)&0xFF));
4767 for(l
= (uint8
) fregs
; l
; l
>>= 1)
4770 offset
+=3; /* get offset addition */
4774 baseref
= (data
-tempbuf
)-8+2; /* one word later (MOVE) - 2 header longs */
4775 if(Flags
& FLAG_SMALLDATA
)
4777 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
4778 EndPutM16Inc(data
, 0); /* place for base reference */
4782 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
4783 EndPutM32Inc(data
, 0); /* place for base reference */
4786 data
= AsmStackCopy(data
, ap
, flags
, offset
);
4788 /* here comes the base reference */
4789 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
4790 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
4794 EndPutM16Inc(data
, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4795 EndPutM16Inc(data
, 0xD000 + (fregs
&0xFF));
4800 if(Flags
& FLAG_NOMOVEM
)
4803 for(i
= 15; i
>= 0; --i
)
4805 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
4806 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
4811 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4812 EndPutM16Inc(data
, (registers
>> 16)); /* store MOVEM.L registers */
4816 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
4817 EndPutM16Inc(data
, 0x4E75); /* RTS */
4819 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
4821 EndPutM32(tempbuf
, HUNK_CODE
);
4822 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
4823 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
4825 EndPutM32(tempbuf
, HUNK_EXT
);
4826 DoOutputDirect(tempbuf
, 4);
4828 OutputXREF(baseref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
),
4830 /* here come the XDEF name references */
4831 OutputXDEF(0, "_%s", name
); /* C name */
4833 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4835 struct ClibData
*cd
;
4836 OutputXDEF(0, "%s", name
); /* ASM name */
4841 OutputXDEF(0, "%s_", name
); /* C++ name no parameters */
4842 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4844 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4846 if(CopyCPPType((strptr
)tempbuf
, i
, cd
, ap
->Args
))
4847 OutputXDEF(0, "%s__%s", name
, tempbuf
);
4853 EndPutM32(tempbuf
, 0);
4854 DoOutputDirect(tempbuf
, 4);
4855 if(!(Flags
& FLAG_NOSYMBOL
))
4857 EndPutM32(tempbuf
, HUNK_SYMBOL
);
4858 DoOutputDirect(tempbuf
, 4);
4859 OutputSYMBOL(0, "_%s", name
); /* C name */
4861 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4863 struct ClibData
*cd
;
4864 OutputSYMBOL(0, "%s", name
); /* ASM name */
4869 OutputSYMBOL(0, "%s_", name
); /* C++ name no parameters */
4870 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4872 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4874 if(CopyCPPType((strptr
) data
, i
, cd
, ap
->Args
))
4875 OutputSYMBOL(0, "%s__%s", name
, (strptr
) data
);
4881 EndPutM32(tempbuf
, 0);
4882 DoOutputDirect(tempbuf
, 4);
4885 EndPutM32(tempbuf
, HUNK_END
);
4886 return DoOutputDirect(tempbuf
, 4);
4889 /* Directly called by FuncInline and FuncInlineDirect also! */
4890 uint32
FuncCSTUBS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4892 struct ClibData
*f
, *t
;
4893 strptr ret
= "return ";
4896 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4899 Flags
|= FLAG_DONE
; /* We did something */
4901 if(!(f
= GetClibFunc(ap
->FuncName
, ap
, 0)))
4903 t
= GetClibFunc(name
, ap
, flags
);
4905 if(flags
& FUNCFLAG_EXTENDMODE
)
4907 sprintf(tempbuf
, "___%s", name
);
4911 if(IsCPPType(&f
->ReturnType
, CPP_TYPE_VOID
))
4914 if(!OutClibType(&f
->ReturnType
, name
) || !DoOutput("("/*)*/))
4916 if(flags
& FUNCFLAG_EXTENDMODE
)
4918 DoOutput("%s %s, ", GetBaseType(), BaseName
);
4921 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4923 if(!OutClibType(&f
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4926 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4928 if(!OutClibType(&t
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4931 else if(ap
->NumArgs
== 1 && !DoOutput("ULONG tag, "))
4934 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret
, ap
->FuncName
))
4936 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4938 if(!DoOutput("%s, ", ap
->Args
[i
].ArgName
))
4941 if(!DoOutput("("/*)*/) || !OutClibType(&f
->Args
[ap
->NumArgs
-1],0))
4944 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4946 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap
->Args
[ap
->NumArgs
-1].ArgName
))
4949 else if(ap
->NumArgs
== 1)
4951 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4954 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4955 ap
->Args
[ap
->NumArgs
-2].ArgName
) || !OutClibType(&f
->Args
[ap
->NumArgs
-2],0)
4956 || !DoOutput(/*(((*/")));\n}\n\n"))
4961 uint32
FuncLVOXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4963 Flags
|= FLAG_DONE
; /* We did something */
4964 return DoOutput("\t\tXDEF\t_LVO%s\n", name
);
4967 uint32
FuncLVO(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4969 Flags
|= FLAG_DONE
; /* We did something */
4970 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name
, ap
->Bias
);
4973 uint32
FuncLVOPPCXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4975 Flags
|= FLAG_DONE
; /* We did something */
4976 return DoOutput("\t.globl\t%sLVO%s\n", Flags
& FLAG_ABIV4
? "" : "_", name
);
4979 uint32
FuncLVOPPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4981 Flags
|= FLAG_DONE
; /* We did something */
4982 return DoOutput(".set\t%sLVO%s,-%d\n", Flags
& FLAG_ABIV4
? "" : "_", name
,
4986 uint32
FuncLVOPPCBias(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4988 Flags
|= FLAG_DONE
; /* We did something */
4990 EndPutM32Inc(elfbufpos
, symoffset
); /* st_name */
4991 symoffset
+= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1) + 1;
4992 EndPutM32Inc(elfbufpos
, -ap
->Bias
); /* st_value */
4993 EndPutM32Inc(elfbufpos
, 0); /* st_size */
4994 *(elfbufpos
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* st_info */
4995 *(elfbufpos
++) = 0; /* st_other */
4996 EndPutM16Inc(elfbufpos
, SHN_ABS
); /* st_shndx */
5001 uint32
FuncLVOPPCName(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5003 Flags
|= FLAG_DONE
; /* We did something */
5004 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5005 return DoOutputDirect("", 1);
5008 uint32
FuncLVOLib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5012 Flags
|= FLAG_DONE
; /* We did something */
5013 j
= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1);
5014 EndPutM32(tempbuf
, (EXT_ABS
<< 24) + ((j
+3)>>2));
5016 DoOutputDirect(tempbuf
, 4);
5017 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5018 DoOutputDirect("\0\0\0", ((j
+3)&(~3))-j
);
5019 EndPutM32(tempbuf
, -ap
->Bias
);
5020 return DoOutputDirect(tempbuf
, 4);
5023 uint32
FuncLocCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5025 strptr str2
= Flags
& FLAG_LOCALREG
? "rE" : "";
5028 struct ClibData
*cd
= 0;
5030 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
5033 Flags
|= FLAG_DONE
; /* We did something */
5035 i
= strlen(name
) + 2;
5036 EndPutM32(tempbuf
, HUNK_UNIT
);
5037 EndPutM32(tempbuf
+4, (i
+3)>>2);
5038 DoOutputDirect(tempbuf
, 8);
5039 DoOutput("%s.o", name
);
5040 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5042 i
= strlen(hunkname
);
5043 EndPutM32(tempbuf
, HUNK_NAME
);
5044 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
5045 DoOutputDirect(tempbuf
, 8);
5046 DoOutputDirect(hunkname
, i
);
5047 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5049 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
5051 if(Flags
& FLAG_LOCALREG
)
5053 if((flags
& FUNCFLAG_TAG
))
5055 i
= ap
->Args
[ap
->NumArgs
-1].ArgReg
;
5056 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE <ea>,-(A7) */
5060 EndPutM16Inc(data
, 0x41EF | ((i
-8) << 9)); /* LEA 8(A7),Ax */
5061 EndPutM16Inc(data
, 8);
5065 EndPutM16Inc(data
, 0x200F | (i
<< 9)); /* MOVE.L A7,Dx */
5066 EndPutM16Inc(data
, 0x5080 | i
); /* ADDQ.L #8,Dx */
5069 EndPutM16Inc(data
, 0x4EAE);
5070 EndPutM16Inc(data
, -ap
->Bias
); /* JSR instruction */
5072 /* MOVE (A7)+,<ea> */
5073 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5074 EndPutM16Inc(data
, 0x4E75); /* RTS */
5078 EndPutM16Inc(data
, 0x4EEE);
5079 EndPutM16Inc(data
, -ap
->Bias
); /* JMP instruction */
5084 uint32 registers
, offset
= 1;
5086 registers
= GetRegisterData(ap
);
5088 if(!registers
) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5090 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
5091 ++offset
; /* one long more on stack */
5095 if(Flags
& FLAG_NOMOVEM
)
5097 for(i
= 0; i
<= 15; ++i
)
5099 if(registers
& (1<< (16+i
)))
5101 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
5108 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
5109 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
5110 for(i
= registers
&0xFFFF; i
; i
>>= 1)
5113 ++offset
; /* get offset addition */
5118 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
)) /* store library base in A6 */
5120 EndPutM16Inc(data
, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5121 EndPutM16Inc(data
, (offset
++) << 2);
5124 data
= AsmStackCopy(data
, ap
, flags
, offset
);
5126 /* here comes the base reference */
5127 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
5128 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
5131 if(Flags
& FLAG_NOMOVEM
)
5133 for(i
= 15; i
>= 0; --i
)
5135 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
5136 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5141 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5142 EndPutM16Inc(data
, registers
>> 16); /* store MOVEM.L registers */
5146 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
5148 EndPutM16Inc(data
, 0x4E75); /* RTS */
5151 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
5153 EndPutM32(tempbuf
, HUNK_CODE
);
5154 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
5155 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
5157 EndPutM32(tempbuf
, HUNK_EXT
);
5158 DoOutputDirect(tempbuf
,4);
5160 /* here come the XDEF name references */
5162 if(!(Flags
& FLAG_ONLYCNAMES
))
5164 OutputXDEF(0, "%s", name
); /* ASM names */
5165 OutputXDEF(0, "LOC_%s", name
);
5168 OutputXDEF(0, "_%s", name
); /* C names */
5169 OutputXDEF(0, "_LOC_%s", name
);
5171 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5175 /* C++ names no parameters */
5176 OutputXDEF(0, "%s__%sP07Library", name
, str2
);
5177 OutputXDEF(0, "LOC_%s__%sP07Library", name
, str2
);
5179 else if((cd
= GetClibFunc(name
, ap
, flags
)))
5183 txt
= (strptr
) tempbuf
;
5185 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5187 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5188 { /* C++ names with parameters */
5189 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5191 OutputXDEF(0, "%s__%sP07Library%s", name
, str2
, txt
);
5192 OutputXDEF(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5196 OutputXDEF(0, "%s__%s", name
, txt
);
5197 OutputXDEF(0, "LOC_%s__%s", name
, txt
);
5204 EndPutM32(tempbuf
, 0);
5205 DoOutputDirect(tempbuf
,4);
5206 if(!(Flags
& FLAG_NOSYMBOL
))
5208 EndPutM32(tempbuf
, HUNK_SYMBOL
);
5209 DoOutputDirect(tempbuf
,4);
5210 if(!(Flags
& FLAG_ONLYCNAMES
))
5212 OutputSYMBOL(0, "%s", name
); /* ASM names */
5213 OutputSYMBOL(0, "LOC_%s", name
);
5216 OutputSYMBOL(0, "_%s", name
); /* C names */
5217 OutputSYMBOL(0, "_LOC_%s", name
);
5219 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5223 /* C++ names no parameters */
5224 OutputSYMBOL(0, "%s__%sP07Library", name
, str2
);
5225 OutputSYMBOL(0, "LOC_%s__%sP07Library", name
, str2
);
5231 txt
= (strptr
) tempbuf
;
5233 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5235 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5236 { /* C++ names with parameters */
5237 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5239 OutputSYMBOL(0, "%s__%sP07Library%s", name
, str2
, txt
);
5240 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5244 OutputSYMBOL(0, "%s__%s", name
, txt
);
5245 OutputSYMBOL(0, "LOC_%s__%s", name
, txt
);
5252 EndPutM32(tempbuf
, 0);
5253 DoOutputDirect(tempbuf
,4);
5255 EndPutM32(tempbuf
, HUNK_END
);
5256 return DoOutputDirect(tempbuf
,4);
5259 uint32
FuncLocText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5261 struct ClibData
*cd
;
5264 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5267 Flags
|= FLAG_DONE
; /* We did something */
5269 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
5272 OutClibType(&cd
->ReturnType
, 0);
5273 DoOutput(" LOC_%s("/*)*/, name
);
5274 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5276 if(Flags
& FLAG_LOCALREG
)
5277 DoOutput("register __a6 ");
5278 DoOutput("%s libbase", GetBaseType());
5285 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
5287 if(((Flags
& FLAG_LOCALREG
&&
5288 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5289 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
5293 if(flags
& FUNCFLAG_NORMAL
)
5295 if(((Flags
& FLAG_LOCALREG
&&
5296 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5297 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) ||
5298 !DoOutput(/*(*/");\n"))
5302 DoOutput("#define %s("/*)*/, name
);
5303 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5304 DoOutput("%c, ", 'a'+(char)i
);
5305 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i
, name
, BaseName
);
5306 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5307 DoOutput("%c, ",'a'+(char)i
);
5308 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i
);
5312 return DoOutput(/*(*/"...);\n");
5315 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5318 return DoOutput(/*(*/");\n");
5322 uint32
FuncInlineDirect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5324 uint32 a4
= 0, a5
= 0;
5326 int32 i
, maxargs
, reg
=0;
5327 struct ClibData
*cd
;
5329 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
|AMIPRAGFLAG_VARARGS
))
5332 Flags
|= FLAG_DONE
; /* We did something */
5334 if(flags
& FUNCFLAG_ALIAS
)
5336 if(flags
& FUNCFLAG_TAG
)
5337 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5340 DoOutput("#define %s("/*)*/, name
);
5341 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5342 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5343 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5344 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5345 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5346 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5349 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5352 if(flags
& FUNCFLAG_TAG
)
5354 /* do not create some strange functions */
5355 if(IsNoCreateInlineFunc(name
))
5356 DoOutput("#if !defined(NO_INLINE_STDARG) "
5357 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5359 DoOutput("#ifndef NO_INLINE_STDARG\n");
5360 DoOutput("static __inline__ ");
5361 FuncCSTUBS(ap
, flags
|FUNCFLAG_EXTENDMODE
, name
);
5363 DoOutput("#define %s("/*)*/, name
);
5364 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5366 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5370 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name
, ShortBaseNameUpper
);
5371 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5372 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5375 DoOutput(/*(*/")\n");
5376 return DoOutput("#endif\n\n");
5379 DoOutput("#define %s("/*)*/, name
);
5382 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5383 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5384 DoOutput("%s", ap
->Args
[i
].ArgName
);
5386 DoOutput(/*(*/") ({ \\\n"/*})*/);
5388 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5390 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5392 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5393 DoOutput(" = (%s); \\\n", ap
->Args
[i
].ArgName
);
5396 if(Flags
& FLAG_INLINENEW
)
5399 DoOutput(" ({ \\\n"/*})*/);
5400 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name
);
5402 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper
);
5405 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
5407 if(i
== ap
->NumArgs
)
5409 DoOutput("(%s);\\\n", ap
->Args
[i
].ArgName
);
5412 DoOutput(" (("/*))*/);
5413 OutClibType(&cd
->ReturnType
, 0);
5414 DoOutput(" (*)("/*)*/);
5417 DoOutput("char * __asm(\"a6\")");
5421 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5423 OutClibType(&cd
->Args
[i
], 0);
5424 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
5425 if(i
< ap
->NumArgs
-1)
5428 DoOutput(/*((*/")) \\\n");
5429 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name
, ap
->Bias
);
5432 DoOutput("_%s__bn", name
);
5436 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5438 if(ap
->Args
[i
].ArgReg
== REG_A6
)
5439 DoOutput("_%s__bn", name
);
5441 DoOutput("_%s_%s", name
, ap
->Args
[i
].ArgName
);
5442 if(i
< ap
->NumArgs
-1)
5445 DoOutput(/*(*/"); \\\n");
5447 DoOutput(/*({*/"});");
5451 /* do A5 first, as it is more important */
5452 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5454 a5
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5455 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5456 a5
|= 1<<ap
->Args
[i
].ArgReg
;
5460 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A5
]);
5465 for(i
= 0; (a5
& 1) && a5
; ++i
)
5467 a5
= i
; /* this is our A5 swap register */
5470 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5472 a4
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5475 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5476 a4
|= 1<<ap
->Args
[i
].ArgReg
;
5480 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A4
]);
5485 for(i
= 0; (a4
& 1) && a4
; ++i
)
5487 a4
= i
; /* this is our A4 swap register */
5490 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5491 noret
= 1; /* this is a void function */
5493 if(ap
->NumArgs
|| !noret
)
5494 DoOutput(" %s{ \\\n", noret
? "" : "(" /*})*/);
5497 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5499 " register int _d1 __asm(\"d1\"); \\\n"
5500 " register int _a0 __asm(\"a0\"); \\\n"
5501 " register int _a1 __asm(\"a1\"); \\\n");
5504 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5505 GetBaseType(), name
, ShortBaseNameUpper
);
5509 sprintf((strptr
)tempbuf
, "__%s__re", name
);
5510 DoOutput(" register ");
5511 OutClibType(&cd
->ReturnType
, (strptr
) tempbuf
);
5512 DoOutput(" __asm(\"d0\"); \\\n");
5514 if((maxargs
= ap
->NumArgs
) >= 9 && (Flags
& FLAG_STORMGCC
))
5516 for(i
= 0; i
< maxargs
; ++i
)
5518 reg
= ap
->Args
[i
].ArgReg
;
5519 if(a5
&& reg
== REG_A5
) reg
= a5
; /* we need to switch */
5520 if(a4
&& reg
== REG_A4
) reg
= a4
; /* we need to switch */
5522 sprintf((strptr
)tempbuf
, "__%s_%s", name
, ap
->Args
[i
].ArgName
);
5523 DoOutput(" register ");
5524 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5525 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames
[reg
],
5526 (strptr
) (tempbuf
+1));
5528 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5530 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name
);
5531 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5533 DoOutput(" ULONG __%s_%s; \\\n", name
, ap
->Args
[i
].ArgName
);
5534 reg
= ap
->Args
[i
].ArgReg
;
5539 else if(reg
== REG_A5
)
5544 /* reg is now either the last register argument or its a4/a5 redirect */
5545 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name
);
5546 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5548 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5549 DoOutput("(ULONG)(%s)%s", (strptr
)tempbuf
, i
== ap
->NumArgs
-1 ?
5552 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5553 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name
, name
,
5554 RegNames
[reg
], name
);
5556 DoOutput(" __asm volatile (\""/*)*/);
5557 if(a5
) DoOutput("exg a5,%s\\n\\t", RegNames
[a5
]);
5558 if(a4
) DoOutput("exg a4,%s\\n\\t", RegNames
[a4
]);
5559 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5561 DoOutput("movem.l ");
5562 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5564 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5565 i
== ap
->NumArgs
-1 ? "" : "/");
5567 DoOutput(",-(a7)\\n\\t");
5568 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5571 DoOutput("move.l (%s),%s\\n\\t", RegNames
[reg
],
5572 RegNames
[ap
->Args
[i
].ArgReg
]);
5574 DoOutput("move.l %ld(%s),%s\\n\\t", (i
-maxargs
)*4, RegNames
[reg
],
5575 RegNames
[ap
->Args
[i
].ArgReg
]);
5578 DoOutput("jsr a6@(-%d:W)", ap
->Bias
);
5579 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5581 DoOutput("\\n\\tmovem.l (a7)+,");
5582 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5584 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5585 i
== ap
->NumArgs
-1 ? "" : "/");
5588 if(a4
) DoOutput("\\n\\texg a4,%s", RegNames
[a4
]);
5589 if(a5
) DoOutput("\\n\\texg a5,%s", RegNames
[a5
]);
5590 DoOutput("\" \\\n");
5593 DoOutput(" : \"=r\" (_d0)");
5595 DoOutput(" : \"=r\"(__%s__re)", name
);
5596 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5598 DoOutput(" \"r\"(__%s__bn)%s", name
, ap
->NumArgs
? "," : "");
5599 for(i
= 0; i
< maxargs
; ++i
)
5601 DoOutput(" \"rf\"(__%s_%s)", name
, ap
->Args
[i
].ArgName
);
5602 if(i
< ap
->NumArgs
-1)
5605 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5606 DoOutput(" \"r\"(__%s__ArgsPtr)", name
);
5607 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5609 if(ap
->NumArgs
|| !noret
)
5610 DoOutput(/*({*/" }%s \\\n", noret
? "" : ");");
5613 return DoOutput(/*({*/"})\n\n");
5616 uint32
FuncInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5618 uint32 noret
= 0, a45
= 0, j
;
5620 struct ClibData
*cd
;
5622 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5625 if(!(Flags
& FLAG_INLINENEW
) && CheckError(ap
, AMIPRAGFLAG_MOSBASESYSV
))
5628 Flags
|= FLAG_DONE
; /* We did something */
5630 if(flags
& FUNCFLAG_ALIAS
)
5632 if(flags
& FUNCFLAG_TAG
)
5633 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5634 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
5636 DoOutput("#define %s("/*)*/, name
);
5637 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5638 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5639 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5640 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5641 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5642 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5645 if(!(cd
= GetClibFunc(ap
->Flags
& AMIPRAGFLAG_VARARGS
?
5646 ap
->TagName
: ap
->FuncName
, ap
, flags
)))
5649 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5650 noret
= 1; /* this is a void function */
5652 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5654 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5658 DoError(ERR_INLINE_A4_AND_A5
, ap
->Line
);
5659 return 1; /* skip this entry */
5663 if(a45
&& (ap
->Flags
& AMIPRAGFLAG_D7USE
))
5665 DoError(ERR_INLINE_D7_AND_A45
, ap
->Line
);
5666 return 1; /* skip this entry */
5669 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
5671 if(Flags
& FLAG_INLINENEW
)
5673 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5674 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "");
5675 if(IsNoCreateInlineFunc(name
))
5677 DoOutput("__inline ");
5678 FuncCSTUBS(ap
, flags
, name
);
5679 /* call CSTUBS, as this equals the method used there */
5683 DoOutput("#define %s("/*)*/, name
);
5684 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5686 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5688 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5690 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5691 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5693 OutClibType(&cd
->Args
[i
], 0);
5694 DoOutput(/*({((*/") _tags);})\n");
5696 return DoOutput("#endif\n\n");
5698 else if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5699 == (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5701 int32 n
, d
, tagl
, local
;
5705 tagl
= 8 + (Flags2
& FLAG2_DIRECTVARARGS
? 0 : 64);
5706 local
= (n
* 4+d
+8+15) & ~15; /* size of the stack frame */
5709 * 0- 3: next frame ptr
5712 * 72-72+n*4+d+8-1: tag list start
5713 * ?-local-1: padding
5716 DoOutput("asm(\"\n"/*)*/
5719 "\t.type\t%s,@function\n"
5721 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5723 "\tstw\t0,%ld(1)\n",
5724 name
, name
, name
, local
, local
+4);
5726 /* If n is odd, one tag is split between regs and stack.
5727 * Copy its ti_Data together with the ti_Tag. */
5729 DoOutput("\tlwz\t0,%ld(1)\n", local
+8); /* read ti_Data */
5731 /* Save the registers */
5732 for(i
= ap
->NumArgs
; i
<= 8; ++i
)
5733 DoOutput("\tstw\t%ld,%ld(1)\n", i
+2, (i
-ap
->NumArgs
) * 4+tagl
);
5736 DoOutput("\tstw\t0,%ld(1)\n", tagl
+n
* 4); /* write ti_Data */
5739 DoOutput("\tli\t0,2\n"
5740 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5742 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5743 tagl
+n
* 4+d
, local
+8+d
, tagl
+n
* 4+d
+4);
5745 if(Flags2
& FLAG2_DIRECTVARARGS
)
5747 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5748 "\tbl\t%s\n", ap
->NumArgs
+2, tagl
, name
);
5755 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
5758 /* Caos.Offset = -fD_GetOffset(obj) */
5759 DoOutput("\tli\t0,%d\n"
5760 "\tstw\t0,8(1)\n", -ap
->Bias
);
5762 /* Save the non-varargs registers in the Caos struct. */
5763 for(i
=0; i
< ap
->NumArgs
-1; ++i
)
5765 DoOutput("\tstw\t%ld,%d(1)\n", i
+3, 8+4+(ap
->Args
[i
].ArgReg
* 4));
5768 DoOutput("\taddi\t0,1,%ld\n"
5770 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5771 "\tlwz\t12,%s@l(3)\n"
5773 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5776 "\tbctrl\n", /* EmulCallOS() */
5777 tagl
, BaseName
, 12+(4 * ap
->Args
[i
].ArgReg
), BaseName
);
5779 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5783 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local
+4, local
, name
, name
);
5787 DoOutput("%s%s__inline ", Flags
& FLAG_INLINESTUB
? "" : "extern ",
5788 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5789 return FuncCSTUBS(ap
, flags
, name
);
5790 /* call CSTUBS, as this equals the method used there */
5794 if(Flags
& FLAG_INLINENEW
) /* new style */
5796 strptr funcpar
= "";
5797 DoOutput("#define %s("/*)*/, name
);
5799 for(i
= 0; i
< cd
->NumArgs
; ++i
)
5801 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5807 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5808 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5809 DoOutput("%s", ap
->Args
[i
].ArgName
);
5811 DoOutput(/*(*/") \\\n\t");
5812 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
5814 DoOutput("((("/*)))*/);
5815 OutClibType(&cd
->ReturnType
, 0);
5816 DoOutput(" (*)("/*)*/);
5817 DoOutput("%s", GetBaseType());
5818 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5821 OutClibType(&cd
->Args
[i
], 0);
5823 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5824 "(%s_BASE_NAME",/*)*/
5825 ShortBaseNameUpper
, ap
->Bias
-2, ShortBaseNameUpper
);
5827 for(i
= 0; i
< ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0); ++i
)
5828 DoOutput(", %s", ap
->Args
[i
].ArgName
);
5829 if(flags
& FUNCFLAG_TAG
)
5830 DoOutput(", __VA_ARGS__");
5831 return DoOutput(/*((*/"))\n\n");
5833 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap
->NumArgs
,
5834 (noret
? "NR" : ""), (a45
? RegNamesUpper
[a45
] : (strptr
) ""),
5835 (BaseName
? "" : "UB"), funcpar
, ap
->Bias
);
5838 OutClibType(&cd
->ReturnType
, 0);
5841 DoOutput("%s, ", name
);
5843 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5845 j
= ap
->Args
[i
].ArgReg
;
5846 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5848 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5852 DoError(ERR_MULTIPLEFUNCTION
, ap
->Line
);
5857 DoOutput("__fpt"); fp
= i
;
5861 OutClibType(&cd
->Args
[i
], 0);
5863 DoOutput(", %s, %s%s", ap
->Args
[i
].ArgName
, RegNames
[j
],
5864 (i
== ap
->NumArgs
-1 && !BaseName
? "" : ", "));
5867 if(BaseName
) /* was "##base" used? */
5868 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper
);
5873 OutClibType(&cd
->Args
[fp
], "__fpt");
5876 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
5877 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5879 return DoOutput(/*(*/")\n\n");
5882 /* old mode or stubs mode */
5884 if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
)) != (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5885 DoOutput("%s%s__inline ", Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
) ?
5886 "" : "extern ", Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5887 OutClibType(&cd
->ReturnType
, 0);
5888 DoOutput("\n%s(%s"/*)*/, name
, (BaseName
?
5889 (ap
->NumArgs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5891 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5893 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5894 if(i
< ap
->NumArgs
-1)
5898 if(Flags
& FLAG_POWERUP
)
5900 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5901 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5902 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5903 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5904 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5905 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5906 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5910 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5912 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5913 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5917 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5920 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper
);
5921 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5922 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5925 DoOutput("\treturn(("/*))*/);
5926 OutClibType(&cd
->ReturnType
, 0);
5927 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5929 return Output_Error
;
5931 else if(Flags
& FLAG_MORPHOS
)
5933 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5937 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5939 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5940 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5944 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5946 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5947 ShortBaseNameUpper
);
5949 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5950 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5953 DoOutput("\treturn(("/*))*/);
5954 OutClibType(&cd
->ReturnType
, 0);
5955 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5957 return Output_Error
;
5960 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName
? " BASE_EXT_DECL\n" : ""));
5964 DoOutput(" register ");
5965 OutClibType(&cd
->ReturnType
, "res");
5966 DoOutput(" __asm(\"d0\");\n");
5970 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5971 GetBaseType(), ShortBaseNameUpper
);
5973 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5975 j
= ap
->Args
[i
].ArgReg
;
5976 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5979 DoOutput(" register ");
5980 OutClibType(&cd
->Args
[i
], RegNames
[j
]);
5981 DoOutput(" __asm(\"%s\") = %s;\n", RegNames
[j
], ap
->Args
[i
].ArgName
);
5986 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
5987 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames
[a45
],
5988 ap
->Bias
, RegNames
[a45
]);
5991 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap
->Bias
);
5993 DoOutput(noret
? " : /* No Output */\n" : " : \"=r\" (res)\n");
5997 DoOutput("\"r\" (a6)%s", (ap
->NumArgs
? ", ": ""));
5999 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6001 j
= ap
->Args
[i
].ArgReg
;
6002 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
6005 DoOutput("\"r\" (%s)%s", RegNames
[j
], (i
< ap
->NumArgs
-1 ? ", " : ""));
6008 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6011 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6013 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6017 /* new style inlines designed by Bernardo Innocenti */
6018 uint32
FuncInlineNS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6021 struct ClibData
*cd
;
6023 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6026 Flags
|= FLAG_DONE
; /* We did something */
6028 if(flags
& FUNCFLAG_ALIAS
)
6030 if(flags
& FUNCFLAG_TAG
)
6031 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6034 DoOutput("#define %s("/*)*/, name
);
6035 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6036 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6037 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6038 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6039 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6040 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6043 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6046 if((flags
& FUNCFLAG_TAG
))
6048 if(!(Flags2
& FLAG2_INLINEMAC
))
6050 DoOutput("static __inline ");
6051 return FuncCSTUBS(ap
, flags
, name
);
6052 /* call CSTUBS, as this equals the method used there */
6056 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6057 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
6058 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6059 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6060 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6062 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6063 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6065 OutClibType(&cd
->Args
[i
], 0);
6066 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6070 if(Flags2
& FLAG2_INLINEMAC
)
6072 DoOutput("#define %s("/*)*/, name
);
6073 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6075 DoOutput("%s", ap
->Args
[i
].ArgName
);
6076 if(i
< ap
->NumArgs
-1)
6079 DoOutput(/*(*/") \\\n\t");
6083 DoOutput("static __inline ");
6084 OutClibType(&cd
->ReturnType
, 0);
6085 DoOutput(" %s("/*)*/, name
);
6086 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6088 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6089 if(i
< ap
->NumArgs
-1)
6092 DoOutput(/*(*/")\n{\n "/*}*/);
6093 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6094 DoOutput("return ");
6096 DoOutput("(("/*))*/);
6097 OutClibType(&cd
->ReturnType
, 0);
6098 DoOutput(" (*)("/*)*/);
6099 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6101 OutClibType(&cd
->Args
[i
], 0);
6102 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
6103 if(i
< ap
->NumArgs
-1)
6110 DoOutput("%s __asm(\"a6\")", GetBaseType());
6112 DoOutput(/*((*/"))");
6113 if(Flags2
& FLAG2_INLINEMAC
)
6116 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6117 ShortBaseNameUpper
, ap
->Bias
);
6120 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
6122 if(i
== ap
->NumArgs
)
6124 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap
->Args
[i
].ArgName
,
6127 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6129 DoOutput("%s", ap
->Args
[i
].ArgName
);
6130 if(i
< ap
->NumArgs
-1)
6137 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
6140 if(Flags2
& FLAG2_INLINEMAC
)
6141 DoOutput(/*(*/")\n");
6143 DoOutput(/*{(*/");\n}\n");
6145 return DoOutput("\n");
6148 uint32
FuncPowerUP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6151 struct ClibData
*cd
;
6153 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6156 Flags
|= FLAG_DONE
; /* We did something */
6158 if(flags
& FUNCFLAG_ALIAS
)
6160 if(flags
& FUNCFLAG_TAG
)
6161 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6164 DoOutput("#define %s("/*)*/, name
);
6165 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6166 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6167 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6168 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6169 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6170 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6173 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6176 if(flags
& FUNCFLAG_TAG
)
6178 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name
);
6179 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6180 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6181 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6183 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6184 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6186 OutClibType(&cd
->Args
[i
], 0);
6187 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6190 DoOutput("#define\t%s("/*)*/, name
);
6195 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6196 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6197 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap
->Args
[i
].ArgName
, name
);
6200 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper
);
6202 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6203 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6204 DoOutput(/*(*/"%s)\n\n", ap
->Args
[i
].ArgName
);
6207 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name
, ShortBaseNameUpper
);
6209 DoOutput(/*(*/")\t_%s()\n\n", name
);
6211 DoOutput("static __inline ");
6212 OutClibType(&cd
->ReturnType
, 0);
6214 DoOutput("\n_%s("/*)*/, name
);
6216 DoOutput("void * %s%s", BaseName
, ap
->NumArgs
? ", " : "");
6218 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6220 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6221 if(i
< ap
->NumArgs
-1)
6225 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6226 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6227 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6228 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6229 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6230 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6231 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6235 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6237 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6238 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
6242 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
6245 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName
);
6246 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6247 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6250 DoOutput("\treturn(("/*))*/);
6251 OutClibType(&cd
->ReturnType
, 0);
6252 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6254 return Output_Error
;
6257 uint32
FuncFPCUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6260 struct ClibData
*cd
;
6262 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6264 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6267 if(!FuncFPCType(ap
, flags
, name
))
6270 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6272 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6273 DoOutput("\tMOVE%s.L\t%s,%s\n", ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "",
6274 ap
->Args
[i
].ArgName
, RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
6277 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName
);
6278 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap
->Bias
);
6280 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6282 if(!cd
->ReturnType
.PointerDepth
&&
6283 cd
->ReturnType
.Flags
== CPP_FLAG_BOOLEAN
)
6284 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6285 " @end:\tMOVE.B\tD0,@RESULT\n");
6287 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6289 return DoOutput(" END;\nEND;\n\n");
6292 uint32
FuncFPCType(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6296 struct ClibData
*cd
;
6298 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6300 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6303 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6305 ret
= 0; DoOutput("PROCEDURE %s", name
);
6308 DoOutput("FUNCTION %s", name
);
6313 for(i
= 0; i
< ap
->NumArgs
;)
6315 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6316 if(++i
!= ap
->NumArgs
)
6323 OutPASCALType(&cd
->ReturnType
, "", 1);
6325 Flags
|= FLAG_DONE
; /* We did something */
6327 return DoOutput(";\n");
6330 uint32
FuncFPCTypeTags(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6334 struct ClibData
*cd
;
6336 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6338 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6341 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6343 ret
= 0; DoOutput("PROCEDURE %s", name
);
6346 DoOutput("FUNCTION %s", name
);
6351 for(i
= 0; i
< ap
->NumArgs
-1;)
6353 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6354 if(++i
!= ap
->NumArgs
)
6357 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6362 OutPASCALType(&cd
->ReturnType
, "", 1);
6364 Flags
|= FLAG_DONE
; /* We did something */
6366 return DoOutput(";\n");
6369 uint32
FuncFPCTypeTagsUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6373 struct ClibData
*cd
;
6375 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6377 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6380 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6382 ret
= 0; DoOutput("PROCEDURE %s", name
);
6385 DoOutput("FUNCTION %s", name
);
6390 for(i
= 0; i
< ap
->NumArgs
-1;)
6392 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6393 if(++i
!= ap
->NumArgs
)
6396 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6401 OutPASCALType(&cd
->ReturnType
, "", 1);
6403 DoOutput(";\nbegin\n");
6406 DoOutput(" %s := %s",name
, ap
->FuncName
);
6407 else DoOutput(" %s", ap
->FuncName
);
6412 for(i
= 0; i
< ap
->NumArgs
-1;)
6414 DoOutput("%s ", ap
->Args
[i
].ArgName
);
6415 if(++i
!= ap
->NumArgs
)
6418 DoOutput("readintags(%s)",ap
->Args
[i
].ArgName
);
6419 DoOutput(/*(*/");");
6424 Flags
|= FLAG_DONE
; /* We did something */
6426 return DoOutput(";\n\n");
6430 uint32
FuncBMAP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6434 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_A5USE
6438 Flags
|= FLAG_DONE
; /* We did something */
6440 for(i
= 0; BMAPSpecial
[i
]; ++i
)
6442 if(!stricmp(name
, BMAPSpecial
[i
]))
6444 DoOutput("x"); break;
6448 DoOutput("%s",name
);
6449 reg
= 0; DoOutputDirect(®
, 1);
6450 reg
= (-ap
->Bias
)>>8; DoOutputDirect(®
, 1);
6451 reg
= -ap
->Bias
; DoOutputDirect(®
, 1);
6452 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6454 reg
= 1+ap
->Args
[i
].ArgReg
; DoOutputDirect(®
, 1);
6457 return DoOutputDirect(®
, 1);
6460 uint32
FuncVBCCInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6462 struct ClibData
*cd
;
6466 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6469 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6472 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
6473 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
6475 Flags
|= FLAG_DONE
; /* We did something */
6477 if(flags
& FUNCFLAG_TAG
)
6479 if(IsNoCreateInlineFunc(name
))
6480 return 1; /* do not create some strange functions */
6481 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6482 "(__STDC_VERSION__ >= 199901L)\n");
6485 if(flags
& FUNCFLAG_ALIAS
)
6487 DoOutput("#define %s("/*)*/, name
);
6488 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6489 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6490 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6491 if(Flags2
& FLAG2_OLDVBCC
)
6493 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6494 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6495 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6500 DoOutput("%s", BaseName
);
6501 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6502 DoOutput(", (%s)", ap
->Args
[i
].ArgName
);
6503 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
?
6508 OutClibType(&cd
->ReturnType
, 0);
6509 DoOutput(" __%s("/*)*/, name
);
6511 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6513 DoOutput("__reg(\"a6\") %s", GetBaseType());
6518 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6519 for(i
= 0; i
< k
; ++i
)
6521 DoOutput("__reg(\"%s\") ", RegNames
[ap
->Args
[i
].ArgReg
]);
6522 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6523 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6525 DoOutput("void * %s", ap
->Args
[i
].ArgName
);
6528 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6529 if(i
< ap
->NumArgs
-1)
6533 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6537 DoOutput("__reg(\"a6\") %s", GetBaseType());
6540 if(flags
& FUNCFLAG_TAG
)
6542 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6544 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6547 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6548 RegNames
[ap
->Args
[k
].ArgReg
]);
6550 if(ap
->Args
[k
].ArgReg
> 7)
6551 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1
, c2
,
6552 RegNames
[ap
->Args
[k
].ArgReg
]);
6554 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6555 RegNames
[ap
->Args
[k
].ArgReg
], RegNames
[ap
->Args
[k
].ArgReg
]);
6557 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6558 "\\tmove%s.l\\t(a7)+,%s\";\n", c1
, ap
->Bias
, c2
,
6559 ap
->Args
[k
].ArgReg
>= REG_A0
? "a" : "", RegNames
[ap
->Args
[k
].ArgReg
]);
6562 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1
, ap
->Bias
, c2
);
6564 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6565 DoOutput("#define %s("/*)*/, name
);
6566 for(i
= 0; i
< k
; ++i
)
6568 DoOutput("%s", ap
->Args
[i
].ArgName
);
6569 if(i
< ap
->NumArgs
-1)
6572 if(flags
& FUNCFLAG_TAG
)
6574 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6575 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6578 DoOutput(/*(*/") __%s("/*)*/, name
);
6579 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6581 DoOutput("%s", BaseName
);
6585 for(i
= 0; i
< k
; ++i
)
6587 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6588 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6590 DoOutput("(void *)");
6592 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6593 if(i
< ap
->NumArgs
-1)
6596 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6600 DoOutput("%s", BaseName
);
6602 if(flags
& FUNCFLAG_TAG
)
6604 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6605 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6606 DoOutput("__VA_ARGS__");
6609 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6612 uint32
FuncVBCCWOSInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6614 struct ClibData
*cd
;
6617 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_M68K
))
6620 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6623 Flags
|= FLAG_DONE
; /* We did something */
6625 if(flags
& FUNCFLAG_TAG
)
6627 if(IsNoCreateInlineFunc(name
))
6628 return 1; /* do not create some strange functions */
6629 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6630 "(__STDC_VERSION__ >= 199901L)\n");
6633 if(flags
& FUNCFLAG_ALIAS
)
6635 DoOutput("#define %s("/*)*/, name
);
6636 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6637 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6638 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6639 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6640 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6641 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6645 OutClibType(&cd
->ReturnType
, 0);
6646 DoOutput(" __%s("/*)*/, name
);
6648 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6650 DoOutput("%s", GetBaseType());
6656 for(i
= 0; i
< k
; ++i
)
6658 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6662 if(flags
& FUNCFLAG_TAG
)
6663 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6665 DoOutput(/*(*/")=\"");
6666 if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6668 DoOutput("\\t.extern\\t_%s\\n", BaseName
);
6669 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6671 /* save tag1 and load taglist-pointer */
6672 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6673 "\\taddi\\t%s%d,%s1,%d\\n",
6674 PPCRegPrefix
, (int)k
+2, 20+(int)k
*4, PPCRegPrefix
, PPCRegPrefix
,
6675 (int)k
+2, PPCRegPrefix
, 20+(int)k
*4);
6677 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6678 "\\tlwz\\t%s0,-%d(%s11)\\n"
6681 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
,
6682 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6684 else if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6686 /* @@@ tagcall handling? */
6687 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6688 "\\t.extern\\t_%s\\n"
6689 "\\tlwz\\t%s2,_%s(%s2)\\n"
6690 "\\tlwz\\t%s0,-%d(%s2)\\n"
6693 "\\tlwz\\t%s2,20(%s1)",
6694 PPCRegPrefix
, PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
,
6695 PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
6696 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6700 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6702 /* save tag1 and load taglist-pointer */
6703 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6704 "\\taddi\\t%s%d,%s1,%d\\n",
6705 PPCRegPrefix
, (int)k
+3, 24+(int)k
*4, PPCRegPrefix
, PPCRegPrefix
,
6706 (int)k
+3, PPCRegPrefix
, 24+(int)k
*4);
6708 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6711 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6715 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6716 DoOutput("#define %s("/*)*/, name
);
6717 for(i
= 0; i
< k
; ++i
)
6719 DoOutput("%s", ap
->Args
[i
].ArgName
);
6720 if(i
< ap
->NumArgs
-1)
6723 if(flags
& FUNCFLAG_TAG
)
6725 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6726 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6729 DoOutput(/*(*/") __%s("/*)*/, name
);
6730 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6732 DoOutput("%s", BaseName
);
6736 for(i
= 0; i
< k
; ++i
)
6738 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6739 if(i
< ap
->NumArgs
-1)
6742 if(flags
& FUNCFLAG_TAG
)
6744 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6745 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6746 DoOutput("__VA_ARGS__");
6749 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6752 uint32
FuncVBCCMorphInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6754 struct ClibData
*cd
;
6757 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6760 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6763 Flags
|= FLAG_DONE
; /* We did something */
6765 if(flags
& FUNCFLAG_TAG
)
6767 if(IsNoCreateInlineFunc(name
))
6768 return 1; /* do not create some strange functions */
6769 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6770 "(__STDC_VERSION__ >= 199901L)\n");
6773 if(flags
& FUNCFLAG_ALIAS
)
6775 DoOutput("#define %s("/*)*/, name
);
6776 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6777 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6778 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6779 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6780 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6781 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6785 OutClibType(&cd
->ReturnType
, 0);
6786 if((flags
& FUNCFLAG_TAG
) && (Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6787 DoOutput(" __linearvarargs");
6789 DoOutput(" __%s("/*)*/, name
);
6791 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6793 DoOutput("%s", GetBaseType());
6798 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6800 if((flags
& FUNCFLAG_TAG
) &&
6801 !(ap
->Flags
& AMIPRAGFLAG_MOS_ALL
))
6803 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6808 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6809 for(i
= 0; i
< k
; ++i
)
6811 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6812 if(i
< ap
->NumArgs
-1)
6816 if(flags
& FUNCFLAG_TAG
)
6818 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6820 if((ap
->Flags
& AMIPRAGFLAG_MOS_ALL
)
6821 && !(ap
->Flags
& AMIPRAGFLAG_VARARGS
))
6823 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6826 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6828 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6836 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
6838 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6839 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6840 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6842 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6843 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6845 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6846 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6848 else if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
6852 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6853 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6854 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6855 PPCRegPrefix
, BaseName
,
6856 PPCRegPrefix
, BaseName
, PPCRegPrefix
,
6857 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6859 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6861 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6862 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6864 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6865 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6869 int ofs
= 4, fix
= 0;
6870 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6871 PPCRegPrefix
, PPCRegPrefix
);
6875 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix
, k
++,
6878 if(Flags2
& FLAG2_SHORTPPCVBCCINLINE
)
6881 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6884 else if(flags
& FUNCFLAG_TAG
)
6886 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6890 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix
);
6891 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6893 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
6896 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix
, k
++);
6898 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6899 PPCRegPrefix
, 8+(k
++-11)*4, PPCRegPrefix
, PPCRegPrefix
);
6903 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6904 PPCRegPrefix
, ofs
, PPCRegPrefix
, (2+k
+fix
-11)*4, PPCRegPrefix
, ofs
);
6906 DoOutput("%d(%s2)\\n\"\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6908 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix
,
6912 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6913 DoOutput("#define %s("/*)*/, name
);
6914 for(i
= 0; i
< k
; ++i
)
6916 DoOutput("%s", ap
->Args
[i
].ArgName
);
6917 if(i
< ap
->NumArgs
-1)
6920 if(flags
& FUNCFLAG_TAG
)
6922 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6923 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6926 DoOutput(/*(*/") __%s("/*)*/, name
);
6927 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6929 DoOutput("%s", BaseName
);
6933 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6935 if(flags
& FUNCFLAG_TAG
&& !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
6937 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6941 for(i
= 0; i
< k
; ++i
)
6943 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6944 if(i
< ap
->NumArgs
-1)
6947 if(flags
& FUNCFLAG_TAG
)
6949 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6950 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6951 DoOutput("__VA_ARGS__");
6954 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6957 uint32
FuncVBCCWOSText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6959 uint32 i
, k
, count
, ofs
;
6960 struct ClibData
*cd
= 0;
6962 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
6965 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
6966 !(cd
= GetClibFunc(name
, ap
, flags
)))
6969 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
6970 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
6971 !(Flags
& FLAG_WOSLIBBASE
)))
6973 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
6979 if(Flags
& FLAG_SINGLEFILE
)
6981 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
6986 DoOutputDirect(HEADER
, headersize
);
6990 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
6991 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
6993 if(Flags
& FLAG_SINGLEFILE
)
6994 DoOutput("\t.file\t\"%s.o\"\n", name
);
6995 DoOutput("\t.align\t3\n");
6996 if(Flags
& FLAG_WOSLIBBASE
) /* PPCBase already in r3, LibBase in r4 */
6998 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
6999 DoOutput("\t.extern _%s\n", BaseName
);
7000 DoOutput("\t.global __%s\n__%s:\n", name
, name
);
7005 DoOutput("\t.extern _%s\n", BaseName
);
7006 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7007 DoOutput("\t.extern _PowerPCBase\n");
7008 DoOutput("\t.global _%s\n_%s:\n", name
, name
);
7011 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7013 DoOutput("\tstw\t%s2,20(%s1)\n"
7015 "\tstw\t%s0,16(%s1)\n"
7016 "\tlwz\t%s2,_%s(%s2)\n"
7017 "\tlwz\t%s0,-%d(%s2)\n"
7020 "\tlwz\t%s0,16(%s1)\n"
7021 "\tlwz\t%s2,20(%s1)\n"
7024 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7025 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2,
7026 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7027 PPCRegPrefix
, PPCRegPrefix
);
7029 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7031 DoOutput("\tmflr\t%s0\n", PPCRegPrefix
);
7032 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7034 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7035 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7036 PPCRegPrefix
, (int)ap
->NumArgs
+2,
7037 20+(int)ap
->NumArgs
*4, PPCRegPrefix
, PPCRegPrefix
,
7038 (int)ap
->NumArgs
+2, PPCRegPrefix
, 20+(int)ap
->NumArgs
*4);
7040 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7041 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7042 "\tlwz\t%s11,_%s(%s2)\n"
7043 "\tlwz\t%s0,-%d(%s11)\n"
7046 "\tlwz\t%s0,40(%s1)\n"
7047 "\taddi\t%s1,%s1,32\n"
7050 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7051 BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
7052 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7055 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7057 count
= ap
->NumArgs
;
7058 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7060 /* init stack frame */
7061 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7062 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7063 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7067 /* extra arguments must be passed on the stack */
7068 k
= 32-(count
-8); /* firstreg */
7070 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7071 PPCRegPrefix
, k
, 56+(count
-8)*4, PPCRegPrefix
, PPCRegPrefix
, k
,
7072 i
+56, PPCRegPrefix
);
7073 if(flags
& FUNCFLAG_TAG
)
7074 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7076 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7078 else if(flags
& FUNCFLAG_TAG
)
7080 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7081 PPCRegPrefix
, i
+20+count
*4);
7085 else /* Args must be shifted! */
7087 /* init stack frame */
7088 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7089 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7090 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7094 /* extra arguments must be passed on the stack */
7097 /* special case: move 8th argument into stack frame */
7098 if(flags
& FUNCFLAG_TAG
)
7099 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7101 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7105 k
= 32-(count
-7); /* firstreg */
7107 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7108 "\tmr\t%s%ld,%s10\n"
7109 "\tlmw\t%s%ld,%ld(%s1)\n",
7110 PPCRegPrefix
, k
, 56+(count
-7)*4, PPCRegPrefix
,
7111 PPCRegPrefix
, k
, PPCRegPrefix
, PPCRegPrefix
, k
+1,
7112 i
+56, PPCRegPrefix
);
7113 if(flags
& FUNCFLAG_TAG
)
7114 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
,
7115 PPCRegPrefix
, i
+20+count
*4);
7116 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7119 else if(flags
& FUNCFLAG_TAG
)
7121 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7122 PPCRegPrefix
, i
+20+count
*4);
7126 /* shift all arguments into their following register */
7127 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7128 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix
, 3+k
, PPCRegPrefix
, 2+k
);
7130 /* load library base and LVO, then call LVO via LR */
7131 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7135 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix
,
7136 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
7138 /* cleanup stack frame and return */
7141 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7142 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, 32-(count
-k
),
7143 56+(count
-k
)*4, PPCRegPrefix
);
7146 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7147 PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7151 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7152 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7154 /* clear PP_Flags, PP_Stack and PP_StackSize */
7155 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7156 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7157 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7159 if(Flags
& FLAG_WOSLIBBASE
)
7160 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7161 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix
, ap
->Bias
, PPCRegPrefix
,
7162 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7164 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix
,
7165 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
);
7167 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7168 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7169 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
,
7170 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7173 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7174 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7175 for(i
= 0; i
< k
; ++i
)
7179 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7180 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7182 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3+ofs
);
7186 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix
, (i
+1+ofs
)*4+196,
7188 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7189 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7190 DoOutput("\tstw\t%s11,", PPCRegPrefix
);
7192 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7194 if(flags
& FUNCFLAG_TAG
)
7196 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7197 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7198 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7199 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix
,
7200 PPCRegPrefix
, 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7201 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7204 if(!(Flags
& FLAG_WOSLIBBASE
))
7205 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
7207 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7208 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7209 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7210 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7211 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7214 if(Flags
& FLAG_WOSLIBBASE
)
7215 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7218 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7222 uint32
FuncVBCCWOSCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7224 uint32 i
, j
, k
, ofs
, count
;
7225 uint8
*data
, *basepos
= 0, *pbasepos
= 0;
7226 struct ClibData
*cd
= 0;
7228 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
7231 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
7232 !(cd
= GetClibFunc(name
, ap
, flags
)))
7235 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
7236 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
7237 !(Flags
& FLAG_WOSLIBBASE
)))
7239 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
7243 Flags
|= FLAG_DONE
; /* We did something */
7245 i
= strlen(name
) + 2;
7246 EndPutM32(tempbuf
, HUNK_UNIT
);
7247 EndPutM32(tempbuf
+4, (i
+3)>>2);
7248 DoOutputDirect(tempbuf
, 8);
7249 DoOutput("%s.o", name
);
7250 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7252 i
= strlen(hunkname
);
7253 EndPutM32(tempbuf
, HUNK_NAME
);
7254 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
7255 DoOutputDirect(tempbuf
, 8);
7256 DoOutputDirect(hunkname
, i
);
7257 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7259 data
= tempbuf
+8; /* we need HUNK_PPC_CODE + size at start */
7261 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7263 EndPutM32Inc(data
, 0x90410014); /* stw r2,20(r1) */
7264 /* mflr r0 = mfspr r0,8 = get link register */
7265 EndPutM32Inc(data
, 0x7C0802A6);
7266 EndPutM32Inc(data
, 0x90010010); /* stw r0,16(r1) */
7268 EndPutM32Inc(data
, 0x80420000); /* lwz r2,BaseName(r2) */
7269 EndPutM32Inc(data
, 0x80030000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r2) */
7270 /* mtlr r0 = mtspr 8,r0 = restore link register */
7271 EndPutM32Inc(data
, 0x7C0803A6);
7272 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7273 EndPutM32Inc(data
, 0x80010010); /* lwz r0,16(r1) */
7274 EndPutM32Inc(data
, 0x80410014); /* lwz r2,20(r1) */
7275 /* mtlr r0 = mtspr 8,r0 = restore link register */
7276 EndPutM32Inc(data
, 0x7C0803A6);
7277 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7279 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7282 /* mflr r0 = mfspr r0,8 = get link register */
7283 EndPutM32Inc(data
, 0x7C0802A6);
7284 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7286 EndPutM32Inc(data
, 0x90010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7287 (uint32
)(20+ap
->NumArgs
*4)); /* stw rN,d(r1) */
7288 EndPutM32Inc(data
, 0x38010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7289 (uint32
)(20+ap
->NumArgs
*4)); /* addi rN,r1,d */
7291 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7292 EndPutM32Inc(data
, 0x9421FFCE); /* stwu r1,-32(r1) */
7293 EndPutM32Inc(data
, 0x81620000); /* lwz r11,BaseName(r2) */
7294 EndPutM32Inc(data
, 0x800C0000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r11) */
7295 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7296 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7297 EndPutM32Inc(data
, 0x80010028); /* lwz r0,40(r1) */
7298 EndPutM32Inc(data
, 0x38210020); /* addi r1,r1,32 */
7299 /* mtlr r0 = mtspr 8,r0 = restore link register */
7300 EndPutM32Inc(data
, 0x7C0803A6);
7301 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7303 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7305 count
= ap
->NumArgs
;
7306 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7308 /* init stack frame */
7309 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7310 /* mflr r0 = mfspr r0,8 = get link register */
7311 EndPutM32Inc(data
, 0x7C0802A6);
7312 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7313 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7317 /* extra arguments must be passed on the stack */
7318 k
= 32-(count
-8); /* firstreg */
7320 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-8)*4));
7321 EndPutM32Inc(data
, 0xB8010000 + (k
<< 21) + (i
+56)); /* lmw rk,Y(r1) */
7322 if(flags
& FUNCFLAG_TAG
)
7323 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4)); /* addi r31,r1,X */
7324 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7326 else if(flags
& FUNCFLAG_TAG
)
7329 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7333 else /* Args must be shifted! */
7335 /* init stack frame */
7336 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7337 /* mflr r0 = mfspr r0,8 = get link register */
7338 EndPutM32Inc(data
, 0x7C0802A6);
7339 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7340 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7344 /* extra arguments must be passed on the stack */
7347 /* special case: move 8th argument into stack frame */
7348 if(flags
& FUNCFLAG_TAG
)
7349 EndPutM32Inc(data
, 0x39410000 + (i
+20+count
*4)); /* addi r10,r1,X */
7350 EndPutM32Inc(data
, 0x91410038); /* stw r10,56(r1) */
7354 k
= 32-(count
-7); /* firstreg */
7357 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-7)*4));
7358 /* mr rk,r10 = or rk,r10,r10 */
7359 EndPutM32Inc(data
, 0x7D405378 + (k
<<16));
7361 EndPutM32Inc(data
, 0xB8010000 + ((k
+1) << 21) + (i
+56));
7362 if(flags
& FUNCFLAG_TAG
)
7365 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4));
7367 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7370 else if(flags
& FUNCFLAG_TAG
)
7373 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7377 /* shift all arguments into their following register */
7378 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7379 EndPutM32Inc(data
, 0x7C000378 + ((3+k
)<<16) + ((2+k
)<<21) + ((2+k
)<<11)); /* mr rX,rY = or rX,rY,rY */
7381 /* load library base and LVO, then call LVO via LR */
7383 EndPutM32Inc(data
, 0x80620000); /* lwz r3,BaseName(r2) */
7386 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7387 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7388 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7391 /* cleanup stack frame and return */
7394 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7395 EndPutM32Inc(data
, 0xB8010000 + ((32-(count
-k
))<<21) + (56+(count
-k
)*4)); /* lmw rX,Y(r1) */
7397 EndPutM32Inc(data
, 0x38210000 + i
); /* addi r1,r1,i */
7398 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) */
7399 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7400 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7404 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7405 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7406 EndPutM32Inc(data
, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7408 EndPutM32Inc(data
, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7409 EndPutM32Inc(data
, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7410 EndPutM32Inc(data
, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7411 EndPutM32Inc(data
, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7413 if(Flags
& FLAG_WOSLIBBASE
)
7415 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7416 EndPutM32Inc(data
, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7417 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7418 EndPutM32Inc(data
, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7422 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7423 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7428 EndPutM32Inc(data
, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7429 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7430 EndPutM32Inc(data
, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7431 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7432 EndPutM32Inc(data
, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7435 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7436 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7437 for(i
= 0; i
< k
; ++i
)
7439 j
= 0x34+4*ap
->Args
[i
].ArgReg
; /* PP_Regs offset */
7442 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7443 EndPutM32Inc(data
, 0x90010020 + ((i
+3+ofs
)<<21)); /* stw rX,0x20(r1) */
7444 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7448 EndPutM32Inc(data
, 0x81610000 + ((i
+1+ofs
)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7449 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7450 EndPutM32Inc(data
, 0x91610020); /* stw r11,0x20(r1) */
7451 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7454 if(flags
& FUNCFLAG_TAG
)
7456 j
= (ap
->NumArgs
+ofs
)*4+0xC4;
7458 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7459 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7460 EndPutM32Inc(data
, 0x39610000 + j
); /* addi r11,r1,j */
7461 EndPutM32Inc(data
, 0x91610000 + (0x34+4*ap
->Args
[i
].ArgReg
)); /* stw r11,X(r1) */
7464 if(!(Flags
& FLAG_WOSLIBBASE
))
7466 pbasepos
= data
; /* store 16BIT reloc offset */
7467 EndPutM32Inc(data
, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7469 EndPutM32Inc(data
, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7470 EndPutM32Inc(data
, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7471 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7472 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7473 EndPutM32Inc(data
, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7474 EndPutM32Inc(data
, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7475 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) = get old link register */
7476 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7477 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump back */
7480 EndPutM32(tempbuf
, HUNK_PPC_CODE
);
7481 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
7482 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
7484 EndPutM32(tempbuf
, HUNK_EXT
);
7485 DoOutputDirect(tempbuf
,4);
7487 /* here come the XDEF name references */
7489 if(Flags
& FLAG_WOSLIBBASE
)
7491 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
7492 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7493 OutputXDEF(0, "__%s", name
);
7498 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7499 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7500 OutputXREF((pbasepos
-tempbuf
-8)+2, EXT_DEXT16
, "_PowerPCBase");
7501 OutputXDEF(0, "_%s", name
);
7503 EndPutM32(tempbuf
, 0);
7504 DoOutputDirect(tempbuf
,4);
7505 if(!(Flags
& FLAG_NOSYMBOL
))
7507 EndPutM32(tempbuf
, HUNK_SYMBOL
);
7508 DoOutputDirect(tempbuf
,4);
7509 if(Flags
& FLAG_WOSLIBBASE
)
7510 OutputSYMBOL(0, "__%s", name
);
7512 OutputSYMBOL(0, "_%s", name
);
7513 EndPutM32(tempbuf
, 0);
7514 DoOutputDirect(tempbuf
,4);
7516 EndPutM32(tempbuf
, HUNK_END
);
7518 return DoOutputDirect(tempbuf
,4);
7521 uint32
FuncVBCCPUPText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7525 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7530 if(Flags
& FLAG_SINGLEFILE
)
7532 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7537 DoOutputDirect(HEADER
, headersize
);
7541 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7542 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7544 if(Flags
& FLAG_SINGLEFILE
)
7545 DoOutput("\t.file\t\"%s.o\"\n", name
);
7547 DoOutput("\t.global %s\n", BaseName
);
7548 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7549 "\t.align\t3\n%s:\n",name
, name
);
7551 if(flags
& FUNCFLAG_TAG
)
7553 /* Hack the stack-frame for varargs.
7554 Build stack-frame, but save LR in our own stack-frame,
7555 because we have to overwrite the lower 8 bytes of the
7557 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7558 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7560 /* Save the caller's saved SP in our own stack-frame. */
7561 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix
,
7562 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7564 /* Store r3-r8 at the top of our stack-frame and r9-r10
7565 at the low 8 bytes of the caller's frame. This way all
7566 arguments will reside in one continuous area. */
7567 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7568 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
, 104+4*(i
-3),
7572 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7573 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7575 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7577 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7580 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
7582 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
7583 100+(i
+1-8)*4, PPCRegPrefix
, PPCRegPrefix
);
7586 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix
,
7587 PPCRegPrefix
, 100+ap
->NumArgs
*4, PPCRegPrefix
);
7588 DoOutput("%d(%s1)\n", 36+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7591 /* Now place the real function call */
7592 /* store offset in Chaos->caos_Un.Offset */
7593 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7594 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix
,
7595 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7596 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7597 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7601 if(Flags
& FLAG_SMALLDATA
)
7602 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix
, BaseName
,
7605 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix
,
7606 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7607 /* store basepointer in A6 */
7608 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7611 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix
, PPCRegPrefix
);
7612 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7613 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7614 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7615 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7616 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7618 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7619 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7621 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name
,
7625 uint32
FuncVBCCPUPCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7627 int32 i
, j
=0, k
, size
;
7628 uint8
*data
, *data2
, *data3
;
7629 struct ArHeader
*arh
;
7633 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7638 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7639 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7640 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7641 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7642 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
7643 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
7644 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
7645 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7646 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7647 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7648 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
7649 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
7650 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
7651 EndPutM32Inc(data
, 0); /* eeh->e_entry */
7652 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
7653 data2
= data
; data
+= 4;
7654 EndPutM32Inc(data
, 0); /* eeh->e_flags */
7655 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
7656 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
7657 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
7658 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
7659 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
7660 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
7663 if(flags
& FUNCFLAG_TAG
)
7665 /* Hack the stack-frame for varargs.
7666 Build stack-frame, but save LR in our own stack-frame,
7667 because we have to overwrite the lower 8 bytes of the
7669 EndPutM32Inc(data
, 0x9421FF80); /* stwu r1,-128(r1) */
7670 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7671 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7673 /* Save the caller's saved SP in our own stack-frame. */
7674 EndPutM32Inc(data
, 0x81610080); /* lwz r11,128(r1) */
7675 EndPutM32Inc(data
, 0x91610060); /* stw r11,96(r1) */
7677 /* Store r3-r8 at the top of our stack-frame and r9-r10
7678 at the low 8 bytes of the caller's frame. This way all
7679 arguments will reside in one continuous area. */
7680 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7681 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (104+4*(i
-3))); /* stw rX,Y(r1) */
7685 EndPutM32Inc(data
, 0x9421FFA0); /* stwu r1,-96(r1) */
7686 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7687 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7690 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7692 j
= 36+4*ap
->Args
[i
].ArgReg
;
7693 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7697 EndPutM32Inc(data
, 0x90010000 + ((i
+3)<<21) + j
); /* stw rX,j(r1) */
7701 EndPutM32Inc(data
, 0x81610000 + (100+(i
+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7702 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7707 EndPutM32Inc(data
, 0x39610000 + (100+ap
->NumArgs
*4)); /* addi r11,r1,X */
7708 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,X(r1) */
7712 /* Now place the real function call */
7713 EndPutM32Inc(data
, 0x39610000 - ap
->Bias
); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7714 EndPutM32Inc(data
, 0x91610008); /* stw r11,8(r1) */
7715 EndPutM32Inc(data
, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7716 EndPutM32Inc(data
, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7717 EndPutM32Inc(data
, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7721 if(Flags
& FLAG_SMALLDATA
)
7723 j
= (data
-data3
)+2; /* store reloc offset */
7724 EndPutM32Inc(data
, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7728 j
= (data
-data3
)+2; /* store reloc offset */
7729 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7730 EndPutM32Inc(data
, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7732 EndPutM32Inc(data
, 0x9161005C); /* stw r11,92(r1) */
7735 EndPutM32Inc(data
, 0x38610008); /* addi r3,r1,8 */
7736 k
= (data
-data3
); /* store reloc offset */
7737 EndPutM32Inc(data
, 0x48000001); /* bl PPCCallOS */
7738 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7740 EndPutM32Inc(data
, 0x81610060); /* lwz r11,96(r1) */
7741 EndPutM32Inc(data
, 0x91610080); /* stw r11,128(r1) */
7742 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7743 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7744 EndPutM32Inc(data
, 0x38210080); /* addi r1,r1,128 */
7748 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7749 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7750 EndPutM32Inc(data
, 0x38210060); /* addi r1,r1,96 */
7753 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
7755 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7756 data
+= 44; /* 1 9 17 27 33 */
7758 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
7761 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
7762 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
7763 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7764 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7765 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
7766 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
7767 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7768 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7769 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
7770 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7773 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
7774 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
7775 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
7776 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
7777 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
7778 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
7779 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
7780 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
7781 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
7782 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
7785 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
7786 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
7787 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
7788 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
7789 data
+= 4; /* esh[2].sh_offset */
7790 data
+= 4; /* esh[2].sh_size */
7791 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7792 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
7793 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
7794 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7796 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
7797 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
7798 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
7799 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
7800 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
7801 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
7802 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
7803 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
7804 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
7805 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
7807 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
7808 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
7809 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
7810 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
7811 data
+= 4; /* esh[4].sh_offset */
7812 data
+= 4; /* esh[4].sh_size */
7813 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
7814 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7815 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
7816 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7818 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
7819 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
7820 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7821 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7822 data
+= 4; /* esh[0].sh_offset */
7823 data
+= 4; /* esh[0].sh_size */
7824 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7825 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7826 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
7827 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7829 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
7830 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 6*16 : 5*16); /* esh[4].sh_size */
7833 data
+= BaseName
? 6*16 : 5*16;
7835 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
7838 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
7839 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
7840 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
7841 *(data2
++) = 0; /* esym[0].st_info */
7842 *(data2
++) = 0; /* esym[0].st_other */
7843 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
7847 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
7848 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
7849 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
7850 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
7851 *(data2
++) = 0; /* esym[1].st_other */
7852 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
7854 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
]) { i
++;} ; /* get next store space */
7855 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
7856 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
7857 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
7858 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
7859 *(data2
++) = 0; /* esym[2].st_other */
7860 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
7862 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
7863 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
7864 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
7865 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
7866 *(data2
++) = 0; /* esym[3].st_other */
7867 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
7869 sprintf((strptr
)data
+i
, "%s", name
); while(data
[i
]) { i
++;} ; /* get next store space */
7870 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
7871 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
7872 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
7873 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
7874 *(data2
++) = 0; /* esym[4].st_other */
7875 EndPutM16Inc(data2
, 0); /* esym[4].st_shndx */
7877 sprintf((strptr
)data
+i
, "PPCCallOS"); while(data
[i
]) { i
++;} ; /* get next store space */
7880 EndPutM32Inc(data2
, i
); /* esym[5].st_name */
7881 EndPutM32Inc(data2
, 0); /* esym[5].st_value */
7882 EndPutM32Inc(data2
, 0); /* esym[5].st_size */
7883 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[5].st_info */
7884 *(data2
++) = 0; /* esym[5].st_other */
7885 EndPutM16
/*Inc*/(data2
, 0); /* esym[5].st_shndx */
7887 sprintf((strptr
)data
+i
, "%s", BaseName
); while(data
[i
]) { i
++;} ; /* get next store space */
7889 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
7890 while(i
&3) /* long aligned */
7894 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
7898 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7899 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_REL24
)); /* erel[0].r_info - entry 4, type 10 */
7900 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7904 if(Flags
& FLAG_SMALLDATA
)
7906 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7907 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_SDAREL16
)); /* erel[1].r_info - entry 5, type 32 */
7908 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7912 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7913 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_HA
)); /* erel[1].r_info - entry 5, type 6 */
7914 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7915 EndPutM32Inc(data
, j
+4); /* erel[2].r_offset */
7916 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_LO
)); /* erel[2].r_info - entry 5, type 4 */
7917 EndPutM32Inc(data
, 0); /* erel[2].r_addend */
7920 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
7922 /* make ar header and store all */
7923 arh
= (struct ArHeader
*) (data
+20);
7924 memset(arh
, ' ', sizeof(struct ArHeader
));
7926 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
7927 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
7928 arh
->ar_mode
[2] = '0';
7929 arh
->ar_mode
[0] = '6';
7930 arh
->ar_fmag
[0] = 96;
7931 arh
->ar_fmag
[1] = '\n';
7933 if((k
= strlen(name
) + 2) >= 16)
7935 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
7940 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
7943 j
= k
+ (data
-tempbuf
);
7944 for(i
= 9; j
; --i
) /* make decimal number */
7946 data
[i
] = (j
%10)+'0';
7949 for(j
= 0; i
< 9; ++j
)
7950 arh
->ar_size
[j
] = data
[++i
];
7952 DoOutputDirect(arh
, sizeof(struct ArHeader
));
7956 DoOutput("%s.o", name
);
7958 *(data
++) = 0x0A; /* alignment byte! */
7961 return DoOutputDirect(tempbuf
, data
-tempbuf
);
7964 uint32
FuncVBCCMorphText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7966 int32 i
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
7968 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7973 if(Flags
& FLAG_SINGLEFILE
)
7975 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7980 DoOutputDirect(HEADER
, headersize
);
7984 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7985 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7987 if(Flags
& FLAG_SINGLEFILE
)
7988 DoOutput("\t.file\t\"%s.o\"\n", name
);
7990 DoOutput("\t.global %s\n", BaseName
);
7991 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name
, name
);
7993 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
7995 if(Flags
& FLAG_SMALLDATA
)
7996 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
7997 PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7999 DoOutput("\tlis\t%s11,%s@ha\n"
8000 "\tlwz\t%s12,%s@l(%s11)\n",
8001 PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
8003 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
8004 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8009 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8011 if(flags
& FUNCFLAG_TAG
)
8015 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8016 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8017 "\tstw\t%s0,4(%s1)\n"
8018 "\tsub\t%s11,%s1,%s12\n"
8019 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8020 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8021 "\tsrwi\t%s12,%s12,2\n"
8022 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8023 "\taddi\t%s12,%s1,4\n"
8024 "\tmr\t%s1,%s11\n" /* new stack frame */
8025 "\taddi\t%s11,%s11,8\n"
8028 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8029 "\tstwu\t%s0,4(%s11)\n"
8030 "\tbdnz\t.copyloop_%s\n"
8031 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8032 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8033 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8034 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8035 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8036 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8037 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8038 PPCRegPrefix
, PPCRegPrefix
, name
,
8039 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8040 name
, PPCRegPrefix
, PPCRegPrefix
);
8042 else if(ap
->NumArgs
>= 8)
8044 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8047 "\tstwu\t%s1,-%ld(%s1)\n"
8048 "\tstw\t%s0,%ld(%s1)\n",
8049 PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
,
8050 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8054 else if(flags
& FUNCFLAG_TAG
)
8056 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8057 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8059 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8060 || ap
->NumArgs
>= 8))
8062 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8064 PPCRegPrefix
, stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
);
8069 /* Hack the stack-frame for varargs.
8070 Build stack-frame, but save LR in our own stack-frame,
8071 because we have to overwrite the lower 8 bytes of the
8073 /* Save the caller's saved SP in our own stack-frame. */
8074 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix
,
8075 stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
);
8077 /* Store r3-r8 at the top of our stack-frame and r9-r10
8078 at the low 8 bytes of the caller's frame. This way all
8079 arguments will reside in one continuous area.
8080 Only copy the really relevant parts. */
8081 for(i
= 10; i
> 10-nrcopyar
; --i
)
8082 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
,
8083 stcksize
+4*(i
-1+nrcopyar
-8),PPCRegPrefix
);
8086 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8088 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8090 for(i
= ap
->NumArgs
-1; i
; --i
)
8094 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, 3+i
, PPCRegPrefix
,
8099 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
8103 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8104 PPCRegPrefix
, stcksize
+((i
-8)+3)*4, PPCRegPrefix
, PPCRegPrefix
,
8105 ((i
-8)+3)*4, PPCRegPrefix
);
8111 /* shift all the arguments one field */
8112 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8114 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, i
, PPCRegPrefix
, i
-1);
8119 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8120 || ap
->NumArgs
>= 8))
8121 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8125 if(Flags
& FLAG_SMALLDATA
)
8126 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix
, basereg
,
8127 BaseName
, PPCRegPrefix
);
8129 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8130 PPCRegPrefix
, basereg
, BaseName
, PPCRegPrefix
, basereg
, BaseName
,
8131 PPCRegPrefix
, basereg
);
8134 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8136 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8137 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8141 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8143 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8146 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
8148 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
8149 stcksize
+(i
+2-8)*4, PPCRegPrefix
, PPCRegPrefix
);
8152 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix
,
8153 PPCRegPrefix
, stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0),
8155 DoOutput("%d(%s2)\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
8158 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8159 PPCRegPrefix
, PPCRegPrefix
);
8161 /* store basepointer in A6 */
8163 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
8165 /* Now place the real function call */
8166 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8167 PPCRegPrefix
, ap
->Bias
);
8169 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix
);
8172 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8174 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8175 PPCRegPrefix
, stcksize
, PPCRegPrefix
, PPCRegPrefix
,
8176 stcksize
+nrcopyar
*4,PPCRegPrefix
);
8179 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8180 || ap
->NumArgs
>= 8))
8182 if(ap
->NumArgs
>= 8)
8185 "\tlwz\t%s0,%ld(%s1)\n"
8186 "\taddi\t%s1,%s1,%ld\n"
8188 PPCRegPrefix
,stcksize
+4,PPCRegPrefix
,PPCRegPrefix
,PPCRegPrefix
,
8189 stcksize
,PPCRegPrefix
);
8194 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8195 "\tlwz\t%s0,4(%s1)\n"
8196 "\tmtlr\t%s0\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8197 PPCRegPrefix
, PPCRegPrefix
);
8202 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8203 "\taddi\t%s1,%s1,%ld\n"
8205 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8206 stcksize
+nrcopyar
*4, PPCRegPrefix
);
8209 DoOutput("\tblr\n");
8212 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8216 uint32
FuncVBCCMorphCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8218 int32 i
, j
, k
=0, size
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
8219 uint8
*data
, *data2
, *data3
;
8220 struct ArHeader
*arh
;
8224 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
8229 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8230 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8231 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8232 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8233 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
8234 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
8235 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
8236 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8237 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8238 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8239 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
8240 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
8241 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
8242 EndPutM32Inc(data
, 0); /* eeh->e_entry */
8243 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
8244 data2
= data
; data
+= 4;
8245 EndPutM32Inc(data
, 0); /* eeh->e_flags */
8246 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
8247 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
8248 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
8249 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
8250 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
8251 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
8255 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
8257 if(Flags
& FLAG_SMALLDATA
)
8259 k
= (data
-data3
)+2; /* store reloc offset */
8260 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8264 k
= (data
-data3
)+2; /* store reloc offset */
8265 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8266 EndPutM32Inc(data
, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8269 EndPutM32Inc(data
, 0x800c0000 - (ap
->Bias
-2));
8270 EndPutM32Inc(data
, 0x7c0903a6); /* mtctr r0 */
8271 EndPutM32Inc(data
, 0x4e800420); /* bctr */
8276 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8278 if(flags
& FUNCFLAG_TAG
)
8280 /* mflr r0 = mfspr r0,8 = get link register */
8281 EndPutM32Inc(data
, 0x7C0802A6);
8282 /* backchain to next frame: lwz r11,0(r1) */
8283 EndPutM32Inc(data
, 0x81610000);
8284 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8285 EndPutM32Inc(data
, 0x7D815850);
8286 EndPutM32Inc(data
, 0x90010004); /* stw r0,4(r1) */
8287 EndPutM32Inc(data
, 0x7D6C0850); /* sub r11,r1,r12 */
8288 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8289 EndPutM32Inc(data
, 0x396BFFF0);
8290 EndPutM32Inc(data
, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8291 EndPutM32Inc(data
, 0x558CF0BE); /* srwi r12,r12,2 */
8292 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8293 EndPutM32Inc(data
, 0x380CFFFE);
8294 EndPutM32Inc(data
, 0x39810004); /* addi r12,r1,4 */
8295 EndPutM32Inc(data
, 0x7D615B78); /* mr r1,r11 - new stack frame */
8296 EndPutM32Inc(data
, 0x396B0008); /* addi r11,r11,8 */
8297 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8298 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8299 EndPutM32Inc(data
, 0x840C0004);
8300 EndPutM32Inc(data
, 0x940B0004); /* stwu r0,4(r11) */
8301 EndPutM32Inc(data
, 0x4200FFF8); /* bdnz .l */
8302 /* stw r10,8(r1) - last register into stack */
8303 EndPutM32Inc(data
, 0x91410008);
8305 else if(ap
->NumArgs
>= 8)
8307 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8308 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 */
8309 EndPutM32Inc(data
, 0x94220000 - stcksize
); /* stwu r1,-X(r1) */
8310 EndPutM32Inc(data
, 0x90010000 + stcksize
+ 4); /* stw r0,Y(r1) */
8314 else if(flags
& FUNCFLAG_TAG
)
8316 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8317 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8320 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8321 || ap
->NumArgs
>= 8))
8323 EndPutM32Inc(data
, 0x94210000+0x10000-(stcksize
+nrcopyar
*4)); /* stwu r1,-%d(r1) */
8324 /* mflr r0 = mfspr r0,8 = get link register */
8325 EndPutM32Inc(data
, 0x7C0802A6);
8330 /* Hack the stack-frame for varargs.
8331 Build stack-frame, but save LR in our own stack-frame,
8332 because we have to overwrite the lower 8 bytes of the
8334 /* Save the caller's saved SP in our own stack-frame. */
8335 EndPutM32Inc(data
, 0x81610000+stcksize
+nrcopyar
*4); /* lwz r11,%d(r1) */
8336 EndPutM32Inc(data
, 0x91610000+stcksize
); /* stw r11,%d(r1) */
8338 /* Store r3-r8 at the top of our stack-frame and r9-r10
8339 at the low 8 bytes of the caller's frame. This way all
8340 arguments will reside in one continuous area.
8341 Only copy the really relevant parts. */
8342 for(i
= 10; i
> 10-nrcopyar
; --i
)
8343 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (stcksize
+4*(i
-1+nrcopyar
-8))); /* stw rX,Y(r1) */
8346 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8348 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8350 for(i
= ap
->NumArgs
-1; i
; --i
)
8355 EndPutM32Inc(data
, 0x7C000378 + ((3+i
)<<21) + ((3+i
-1)<<16) + ((3+i
-1)<<11));
8360 EndPutM32Inc(data
, 0x91410008);
8365 EndPutM32Inc(data
, 0x81610000 + (stcksize
+((i
-8)+3)*4));
8366 EndPutM32Inc(data
, 0x91620000 + ((i
-8)+3)*4); /* stw r11,j(r1) */
8372 /* shift all the arguments one field */
8373 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8376 EndPutM32Inc(data
, 0x7C000378 + (i
<<21) + ((i
-1)<<16) + ((i
-1)<<11));
8381 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8382 || ap
->NumArgs
>= 8))
8383 EndPutM32Inc(data
, 0x90010000+stcksize
+4); /* stw r0,%d(r1) */
8387 if(Flags
& FLAG_SMALLDATA
)
8389 k
= (data
-data3
)+2; /* store reloc offset */
8390 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8394 k
= (data
-data3
)+2; /* store reloc offset */
8395 EndPutM32Inc(data
, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8396 EndPutM32Inc(data
, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8400 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8403 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2));
8404 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8405 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8409 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8411 j
= 4*ap
->Args
[i
].ArgReg
;
8412 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8416 EndPutM32Inc(data
, 0x90020000 + ((i
+3)<<21) + j
); /* stw rX,j(r2) */
8420 EndPutM32Inc(data
, 0x81610000 + (stcksize
+(i
+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8421 EndPutM32Inc(data
, 0x91620000 + j
); /* stw r11,j(r1) */
8426 EndPutM32Inc(data
, 0x38810000 + (stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0))); /* addi r4,r1,X */
8427 EndPutM32Inc(data
, 0x90820000 + j
); /* stw r4,X(r2) */
8432 EndPutM32Inc(data
, 0x81620064); /* lwz r11,100(r2) */
8435 EndPutM32Inc(data
, 0x91820038); /* stw r12,56(r2) */
8437 /* Now place the real function call */
8438 EndPutM32Inc(data
, 0x38600000 + 0x10000 - ap
->Bias
); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8440 EndPutM32Inc(data
, 0x7D6903A6); /* mtctr r11 */
8441 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8443 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8445 EndPutM32Inc(data
, 0x81610000 + stcksize
); /* lwz r11,X(r1) */
8446 EndPutM32Inc(data
, 0x91610000 + (stcksize
+nrcopyar
*4)); /* stw r11,Y(r1) */
8449 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8450 || ap
->NumArgs
>= 8))
8452 if(ap
->NumArgs
>= 8)
8454 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8455 EndPutM32Inc(data
, 0x38210000 + stcksize
); /* addi r1,r1,Y */
8456 /* mtlr r0 = mtspr 8,r0 = restore link register */
8457 EndPutM32Inc(data
, 0x7C0803A6);
8461 /* restore old stack frame: lwz r1,0(r1) */
8462 EndPutM32Inc(data
, 0x80210000);
8463 EndPutM32Inc(data
, 0x80010004); /* lwz r0,4(r1) */
8464 /* mtlr r0 = mtspr 8,r0 = restore link register */
8465 EndPutM32Inc(data
, 0x7C0803A6);
8470 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8471 EndPutM32Inc(data
, 0x38210000 + (stcksize
+nrcopyar
*4)); /* addi r1,r1,Y */
8472 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8475 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
8478 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8479 data
+= 44; /* 1 9 17 27 33 */
8481 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
8484 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
8485 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
8486 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8487 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8488 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
8489 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
8490 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8491 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8492 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
8493 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8496 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
8497 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
8498 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
8499 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
8500 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
8501 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
8502 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
8503 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
8504 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
8505 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
8508 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
8509 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
8510 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
8511 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
8512 data
+= 4; /* esh[2].sh_offset */
8513 data
+= 4; /* esh[2].sh_size */
8514 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8515 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
8516 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
8517 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8519 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
8520 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
8521 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
8522 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
8523 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
8524 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
8525 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
8526 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
8527 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
8528 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
8530 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
8531 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
8532 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
8533 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
8534 data
+= 4; /* esh[4].sh_offset */
8535 data
+= 4; /* esh[4].sh_size */
8536 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
8537 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8538 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
8539 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8541 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
8542 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
8543 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8544 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8545 data
+= 4; /* esh[0].sh_offset */
8546 data
+= 4; /* esh[0].sh_size */
8547 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8548 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8549 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
8550 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8552 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
8553 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 5*16 : 4*16); /* esh[4].sh_size */
8556 data
+= BaseName
? 5*16 : 4*16;
8558 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
8561 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
8562 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
8563 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
8564 *(data2
++) = 0; /* esym[0].st_info */
8565 *(data2
++) = 0; /* esym[0].st_other */
8566 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
8570 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
8571 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
8572 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
8573 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
8574 *(data2
++) = 0; /* esym[1].st_other */
8575 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
8577 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
]) { i
++;} ; /* get next store space */
8578 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
8579 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
8580 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
8581 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
8582 *(data2
++) = 0; /* esym[2].st_other */
8583 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
8585 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
8586 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
8587 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
8588 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
8589 *(data2
++) = 0; /* esym[3].st_other */
8590 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
8592 sprintf((strptr
)data
+i
, "%s", name
); while(data
[i
]) { i
++;} ; /* get next store space */
8595 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
8596 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
8597 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
8598 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
8599 *(data2
++) = 0; /* esym[4].st_other */
8600 EndPutM16
/*Inc*/(data2
, 0); /* esym[4].st_shndx */
8602 sprintf((strptr
)data
+i
, "%s", BaseName
); while(data
[i
]) { i
++;} ; /* get next store space */
8604 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
8605 while(i
&3) /* long aligned */
8609 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
8615 if(Flags
& FLAG_SMALLDATA
)
8617 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8618 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_SDAREL16
)); /* erel[0].r_info - entry 4, type 32 */
8619 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8623 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8624 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_HA
)); /* erel[0].r_info - entry 4, type 6 */
8625 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8626 EndPutM32Inc(data
, k
+4); /* erel[1].r_offset */
8627 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_LO
)); /* erel[1].r_info - entry 4, type 4 */
8628 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
8631 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
8633 /* make ar header and store all */
8634 arh
= (struct ArHeader
*) (data
+20);
8635 memset(arh
, ' ', sizeof(struct ArHeader
));
8637 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
8638 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
8639 arh
->ar_mode
[2] = '0';
8640 arh
->ar_mode
[0] = '6';
8641 arh
->ar_fmag
[0] = 96;
8642 arh
->ar_fmag
[1] = '\n';
8644 if((k
= strlen(name
) + 2) >= 16)
8646 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
8651 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
8654 j
= k
+ (data
-tempbuf
);
8655 for(i
= 9; j
; --i
) /* make decimal number */
8657 data
[i
] = (j
%10)+'0';
8660 for(j
= 0; i
< 9; ++j
)
8661 arh
->ar_size
[j
] = data
[++i
];
8663 DoOutputDirect(arh
, sizeof(struct ArHeader
));
8667 DoOutput("%s.o", name
);
8669 *(data
++) = 0x0A; /* alignment byte! */
8672 return DoOutputDirect(tempbuf
, data
-tempbuf
);
8675 uint32
FuncEModule(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8679 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_PPC
) ||
8680 (flags
& FUNCFLAG_ALIAS
))
8683 if(LastBias
>= ap
->Bias
)
8684 DoError(ERR_ILLEGAL_FUNCTION_POSITION
, ap
->Line
, name
);
8687 Flags
|= FLAG_DONE
; /* We did something */
8689 for(LastBias
+= BIAS_OFFSET
; LastBias
< ap
->Bias
; LastBias
+= BIAS_OFFSET
)
8690 DoOutputDirect("Dum\x10", 4);
8692 DoOutput("%c", toupper(name
[0]));
8695 DoOutput("%c", tolower(name
[1]));
8697 DoOutput("%s", name
+2);
8700 DoOutputDirect("\x10", 1);
8703 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8705 r
= ap
->Args
[i
].ArgReg
;
8706 DoOutputDirect(&r
, 1);
8713 uint32
FuncFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8717 Flags
|= FLAG_DONE
; /* We did something */
8719 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8721 if(Flags
& FLAG_ISPRIVATE
)
8723 Flags
^= FLAG_ISPRIVATE
;
8724 DoOutput("##public\n");
8729 if(!(Flags
& FLAG_ISPRIVATE
))
8730 DoOutput("##private\n");
8731 Flags
|= FLAG_ISPRIVATE
;
8734 LastBias
+= BIAS_OFFSET
;
8735 if(LastBias
!= ap
->Bias
)
8737 DoOutput("##bias %d\n", ap
->Bias
);
8738 LastBias
= ap
->Bias
;
8741 if(ap
->Abi
!= CurrentABI
)
8745 case ABI_M68K
: DoOutput("##abi M68k\n"); break;
8746 case ABI_PPC0
: DoOutput("##abi PPC0\n"); break;
8747 case ABI_PPC2
: DoOutput("##abi PPC2\n"); break;
8748 case ABI_PPC
: DoOutput("##abi PPC\n"); break;
8750 CurrentABI
= ap
->Abi
;
8753 DoOutput("%s("/*)*/, name
);
8754 for(i
= 0; i
< ap
->CallArgs
; i
++)
8755 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->CallArgs
-1 ? "," : "");
8756 DoOutput(/*(*/")("/*)*/);
8758 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8760 for(i
= 0; i
< ap
->CallArgs
; i
++)
8762 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], i
< ap
->CallArgs
-1 ?
8763 (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
? "/" : ",") : "");
8766 return DoOutput(/*(*/")\n");
8769 /* called from FuncSFD directly */
8770 uint32
FuncClib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8772 struct ClibData
*cd
;
8775 Flags
|= FLAG_DONE
; /* We did something */
8777 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8780 s
= MakeClibType(tempbuf
, &cd
->ReturnType
, 0);
8781 DoOutputDirect(tempbuf
, s
);
8782 DoOutput(" %s("/*)*/, name
);
8786 for(i
= 0; i
< cd
->NumArgs
; i
++)
8788 c
= MakeClibType(tempbuf
, &cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8791 DoOutput(i
? ",\n\t" : "\n\t"); s
= 8;
8795 DoOutput(", "); s
+= 2;
8797 DoOutputDirect(tempbuf
, c
);
8801 else if(Flags2
& FLAG2_CLIBOUT
)
8803 return DoOutput(/*(*/")%s", Flags2
& FLAG2_CLIBOUT
? ";\n" : "");
8806 uint32
FuncSFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8808 struct ClibData
*cd
;
8811 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8814 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8816 if(Flags
& FLAG_ISPRIVATE
)
8818 Flags
^= FLAG_ISPRIVATE
;
8819 DoOutput("==public\n");
8824 if(!(Flags
& FLAG_ISPRIVATE
))
8825 DoOutput("==private\n");
8826 Flags
|= FLAG_ISPRIVATE
;
8829 if(ap
->Abi
!= CurrentABI
)
8833 case ABI_M68K
: DoOutput("==abi M68k\n"); break;
8834 case ABI_PPC0
: DoOutput("==abi PPC0\n"); break;
8835 case ABI_PPC2
: DoOutput("==abi PPC2\n"); break;
8836 case ABI_PPC
: DoOutput("==abi PPC\n"); break;
8838 CurrentABI
= ap
->Abi
;
8841 if(LastBias
+BIAS_OFFSET
< ap
->Bias
)
8843 DoOutput("==reserve %ld\n", ((ap
->Bias
-LastBias
)/BIAS_OFFSET
)-1);
8844 LastBias
= ap
->Bias
;
8846 else if(flags
& FUNCFLAG_TAG
)
8847 DoOutput("==varargs\n");
8848 else if((flags
& FUNCFLAG_ALIAS
) || LastBias
== ap
->Bias
)
8849 DoOutput("==alias\n");
8851 LastBias
+= BIAS_OFFSET
;
8853 if(!FuncClib(ap
, flags
, name
))
8856 DoOutput(" ("/*)*/);
8857 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8861 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8862 in step one, so the "-" can be placed at proper position. */
8863 for(j
= i
= 0; i
< ap
->NumArgs
; i
++)
8865 if(i
== ap
->NumArgs
-1)
8869 else if(IsCPPType(&cd
->Args
[j
>>1], CPP_TYPE_DOUBLE
) && ap
->Args
[i
].ArgReg
< REG_FP0
)
8871 s
= (j
&1) ? "," : "-"; ++j
;
8877 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], s
);
8880 return DoOutput(/*(*/")\n");
8883 uint32
FuncOS4PPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8885 struct ClibData
*cd
;
8886 int32 i
, noret
= 0, registers
;
8888 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
8891 Flags
|= FLAG_DONE
; /* We did something */
8893 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8896 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
8897 noret
= 1; /* this is a void function */
8899 sprintf((strptr
)tempbuf
, "_%s_%s", GetIFXName(), name
);
8900 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
8902 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8903 ap
->NumArgs
? "," : "");
8904 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8907 if(i
== ap
->NumArgs
- 1 && (flags
& FUNCFLAG_TAG
))
8913 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8914 if(i
< ap
->NumArgs
-1)
8918 if(flags
& FUNCFLAG_TAG
)
8920 struct ClibData
*cd2
;
8922 if(!(cd2
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
8925 DoOutput(/*(*/")\n{\n"/*}*/
8927 " va_startlinear(ap, colorMap);\n"
8930 DoOutput("return ");
8931 DoOutput("Self->%s(\n"/*)*/, ap
->FuncName
);
8932 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8934 DoOutput(" %s,\n", ap
->Args
[i
].ArgName
);
8936 DoOutput(" va_getlinearva(ap, "/*)*/);
8937 OutClibType(&cd2
->Args
[i
], 0);
8938 DoOutput(/*((*/"));\n");
8942 DoOutput(/*(*/")\n{\n"/*}*/
8943 " struct Library *LibBase = Self->Data.LibBase;\n"
8944 " struct ExecIFace *IExec = (struct ExecIFace *)"
8945 "Self->Data.IExecPrivate;\n");
8950 OutClibType(&cd
->ReturnType
, "retval");
8955 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8957 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8960 registers
= GetRegisterData(ap
) | 0x40000002; /* set A6 everytime */
8961 for(i
= 0; i
<= 15; ++i
)
8963 if(registers
& (1<< (16+i
)))
8964 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames
[i
], i
);
8970 DoOutput("retval = ("/*)*/);
8971 OutClibType(&cd
->ReturnType
, 0);
8975 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
8976 " ET_Offset, -%d,\n"/*)*/,ap
->Bias
);
8977 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8979 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
],
8980 ap
->Args
[i
].ArgName
);
8982 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
8983 for(i
= 0; i
<= 15; ++i
)
8985 if(registers
& (1<< (16+i
)))
8986 DoOutput(" regs[%ld] = save_%s;\n", i
, RegNames
[i
]);
8990 DoOutput(" return retval;\n");
8992 return DoOutput(/*{*/"}\n\n");
8995 uint32
FuncOS4M68KCSTUB(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8997 struct ClibData
*cd
;
9000 if(ap
->NumArgs
<= 7)
9003 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9006 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9009 Flags
|= FLAG_DONE
; /* We did something */
9011 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9012 noret
= 1; /* this is a void function */
9014 sprintf((strptr
)tempbuf
, "Cstub_%s", name
);
9015 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
9017 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9018 " struct ExecIFace *IExec = (struct ExecIFace *)"
9019 "Interface->Data.IExecPrivate;\n"
9020 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9021 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9024 DoOutput("return ");
9026 DoOutput("Interface->%s(\n"/*)*/,(flags
& FUNCFLAG_TAG
) ? ap
->FuncName
9028 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9030 DoOutput(" ("/*)*/);
9031 OutClibType(&cd
->Args
[i
], 0);
9032 DoOutput(/*(*/") regarray[%d]", ap
->Args
[i
].ArgReg
);
9033 if(i
< ap
->NumArgs
-1)
9036 return DoOutput(/*{(*/");\n}\n\n");
9039 uint32
FuncOS4M68K(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9041 struct ClibData
*cd
;
9044 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9047 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9050 Flags
|= FLAG_DONE
; /* We did something */
9053 "\t.section .data\n"
9054 "\t.globl\tstub_%s\n"
9055 "\t.type\tstub_%s,@function\n"
9058 "\t.short\t0x4ef8\n"
9061 "\t.globl\tstub_%sPPC\n"
9062 "\t.long\tstub_%sPPC\n",name
, name
, name
, name
, name
);
9066 Flags2
|= FLAG2_OS4M68KCSTUB
;
9068 "\t.byte\t2\n" /* Rest of parameters in C */
9069 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9070 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9075 "\t.byte\t%d\n" /* Rest of parameters in C */
9076 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9077 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9079 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9081 DoOutput("\t.byte\t%d,REG68K_%s\n",i
+4,
9082 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9086 "\t.section .text\n"
9090 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9091 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9092 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9093 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9094 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9095 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9096 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9097 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9098 name
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9099 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9100 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9101 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
9105 /* Since this function has 11 arguments, we need a C stub */
9107 "\t.globl\tCstub_%s\n"
9108 "\tlis\t%s4,Cstub_%s@h\n"
9109 "\tori\t%s4,%s4,Cstub_%s@l\n"
9112 name
, PPCRegPrefix
, name
, PPCRegPrefix
, PPCRegPrefix
, name
, PPCRegPrefix
);
9116 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name
);
9119 "\tlwz\t%s11,12(%s1)\n"
9121 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9122 "\tblrl\n" /* Return to emulation */
9124 "\t.globl\tstub_%s68K\n"
9125 "\t.long\tstub_%s68K\n"
9126 "\t.byte\t0\n", /* Flags */
9127 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, name
,
9130 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9133 "\t.byte\t1\n" /* One register (a7 only) */
9134 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9140 "\t.byte\t1,REG68K_A7\n"
9141 "\t.byte\t3,REG68K_D0\n");
9145 "\t.section .data\n"
9149 "\t.short\t0x4e75\n" /* RTS */
9153 uint32
FuncOS4M68KVect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9155 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9158 while(LastBias
+ BIAS_OFFSET
< ap
->Bias
)
9160 DoOutput("\t.long\tstub_Reserved\n");
9161 LastBias
+= BIAS_OFFSET
;
9163 LastBias
= ap
->Bias
;
9165 return DoOutput("\t.long\tstub_%s\n", name
);
9168 uint32
FuncXML(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9170 struct ClibData
*cd
;
9173 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9176 if(flags
& FUNCFLAG_ALIAS
)
9177 DoError(ERR_ALIASES_NOT_SUPPORTED
, ap
->Line
);
9179 Flags
|= FLAG_DONE
; /* We did something */
9181 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
9184 while(LastBias
+BIAS_OFFSET
< ap
->Bias
)
9186 LastBias
+= BIAS_OFFSET
;
9187 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9188 " status=\"unimplemented\"/>\n", LastBias
);
9190 LastBias
= ap
->Bias
;
9192 DoOutput("\t\t<method name=\"%s\" result=\"", name
);
9193 OutClibType(&cd
->ReturnType
, 0);
9195 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9197 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9198 i
== ap
->NumArgs
-1 && (flags
& FUNCFLAG_TAG
) ? "var" : "",
9199 ap
->Args
[i
].ArgName
);
9200 OutClibType(&cd
->Args
[i
], 0);
9203 return DoOutput("\t\t</method>\n");
9206 uint32
FuncGateStubs(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9208 struct ClibData
*cd
;
9209 strptr ret
= "return ";
9212 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
9215 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9218 Flags
|= FLAG_DONE
; /* We did something */
9220 if(flags
& FUNCFLAG_ALIAS
)
9222 if(flags
& FUNCFLAG_TAG
)
9223 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9224 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
9226 DoOutput("#define %s("/*)*/, name
);
9227 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9228 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9229 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
9230 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9231 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9232 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
9235 if((flags
& FUNCFLAG_TAG
))
9237 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9238 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
9239 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9241 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9243 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9245 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9246 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9248 OutClibType(&cd
->Args
[i
], 0);
9249 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9252 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9255 if(!OutClibType(&cd
->ReturnType
, 0))
9258 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix
, name
);
9260 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9263 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
9264 DoOutput(" = ("/*)*/);
9265 OutClibType(&cd
->Args
[i
], 0);
9266 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9267 if((Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
)) && (Flags2
& FLAG2_REGLIB
))
9268 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9270 DoOutput(" %s%s%s("/*)*/, ret
, subprefix
, name
);
9273 if(Flags2
& FLAG2_PRELIB
)
9275 if(Flags2
& FLAG2_REGLIB
)
9276 DoOutput("___RegBase,");
9278 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper
);
9281 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9283 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9285 if(Flags2
& FLAG2_POSTLIB
)
9287 if(Flags2
& FLAG2_REGLIB
)
9288 DoOutput("%s, ___RegBase", ap
->Args
[i
].ArgName
);
9290 DoOutput("%s, %s_BASE_NAME", ap
->Args
[i
].ArgName
, ShortBaseNameUpper
);
9293 DoOutput("%s", ap
->Args
[i
].ArgName
);
9297 if(Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
))
9299 if(Flags2
& FLAG2_REGLIB
)
9300 DoOutput("___RegBase");
9302 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
9305 return DoOutput(/*(({*/"));\n}\n");
9308 static uint32
DoCallFunc(struct AmiPragma
*ap
, uint32 flags
, strptr name
, FuncType Func
)
9312 if(Flags
& FLAG_SINGLEFILE
)
9314 sprintf(filename
, filenamefmt
, name
);
9315 if(!OpenDest(filename
))
9318 res
= Func(ap
, flags
, name
);
9319 if(Flags
& FLAG_SINGLEFILE
)
9321 CloseDest(filename
);
9326 static uint32
PrintComment(struct Comment
*com
, strptr comment
)
9328 if(com
->Private
&& !(Flags
& FLAG_PRIVATE
))
9330 else if((Flags2
& FLAG2_SFDOUT
) && com
->Version
)
9332 return DoOutput("==version %d\n", com
->Version
);
9334 else if((Flags2
& FLAG2_SFDOUT
) && com
->ReservedNum
)
9336 LastBias
+= BIAS_OFFSET
*com
->ReservedNum
;
9337 return DoOutput("==reserve %d\n", com
->ReservedNum
);
9339 else if(!(Flags
& FLAG_DOCOMMENT
) || !comment
)
9344 if(!DoOutput(comment
, com
->Data
))
9347 else if(com
->ReservedNum
)
9350 sprintf(temp
, "* --- (%u function slot%s reserved here) ---", com
->ReservedNum
,
9351 com
->ReservedNum
== 1 ? "" : "s");
9352 if(!DoOutput(comment
, temp
))
9355 else if(com
->Version
)
9358 if(com
->Version
>= FIRST_KNOWN_RELEASE
&& com
->Version
<= LAST_KNOWN_RELEASE
&&
9359 (Flags2
& FLAG2_SYSTEMRELEASE
))
9360 sprintf(temp
, "* --- functions in V%u or higher %s ---", com
->Version
,
9361 Release
[com
->Version
-FIRST_KNOWN_RELEASE
]);
9363 sprintf(temp
, "* --- functions in V%u or higher ---", com
->Version
);
9365 if(!DoOutput(comment
, temp
))
9371 static uint32
CallFunc(uint32 tagmode
, strptr comment
, FuncType Func
)
9373 struct Comment
*com
;
9375 struct AmiPragma
*ap
;
9377 com
= (struct Comment
*) Comment
.First
;
9379 for(ap
= (struct AmiPragma
*) AmiPragma
.First
; ap
;
9380 ap
= (struct AmiPragma
*) ap
->List
.Next
)
9382 if(BaseName
&& (ap
->Flags
& AMIPRAGFLAG_A6USE
))
9384 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
9386 else if((ap
->Flags
& AMIPRAGFLAG_PUBLIC
) || (Flags
& FLAG_PRIVATE
))
9388 while(com
&& com
->Bias
<= ap
->Bias
)
9390 if(!PrintComment(com
, comment
))
9392 com
= (struct Comment
*) com
->List
.Next
;
9393 } /* comment loop */
9396 printf("Processing %s - %s\n", ap
->FuncName
? ap
->FuncName
: "",
9397 ap
->TagName
? ap
->TagName
: "");
9400 if(tagmode
!= TAGMODE_TAGS
)
9402 if(ap
->FuncName
&& !DoCallFunc(ap
, FUNCFLAG_NORMAL
, ap
->FuncName
, Func
))
9405 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9407 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_NORMAL
)
9409 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9417 if(ap
->TagName
&& !DoCallFunc(ap
, FUNCFLAG_TAG
, ap
->TagName
, Func
))
9420 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9422 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_TAG
)
9424 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9433 if(!PrintComment(com
, comment
))
9435 com
= (struct Comment
*) com
->List
.Next
;
9436 } /* comment loop */
9440 static uint32
PrintIncludes(void) /* copies the include lines */
9442 struct Include
*inc
;
9445 inc
= (struct Include
*) Includes
.First
;
9449 s2
= (strptr
) tempbuf
;
9450 for(s
= inc
->Include
; *s
; ++s
)
9454 case '<': *(s2
++) = ' '; break;
9456 case '.': *(s2
++) = '_'; break;
9458 default: *(s2
++) = toupper(*s
);
9462 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf
, inc
->Include
);
9463 inc
= (struct Include
*) inc
->List
.Next
;
9466 DoOutput("#include <exec/types.h>\n");
9467 return DoOutput("\n");
9470 /* ------------------------------------------------------------------ */
9472 static int32
AddClibEntry(strptr buffer
, strptr bufend
, uint32 linenum
)
9474 strptr buf
= buffer
;
9475 struct ClibData d
, *f
;
9477 memset(&d
, 0, sizeof(struct ClibData
));
9478 buf
= SkipBlanksRet(buf
);
9479 if(*buf
== '#') /* preprocessor lines */
9482 printf("Found non-function bracket in preprocessor line %ld\n", linenum
);
9484 while(buf
< bufend
&& *buf
!= '\n')
9488 if(!strnicmp(buf
, "ASM", 3))
9489 buf
= SkipBlanks(buf
+3);
9490 /* else if(!strnicmp(buf, "STACK", 5))
9491 buf = SkipBlanks(buf+5);
9493 else if(!strnicmp(buf
, "REGS", 4))
9494 buf
= SkipBlanks(buf
+4);
9496 if(!strnicmp(buf
, "extern", 6))
9498 buf
= SkipBlanksRet(buf
+6);
9499 if(!strnicmp(buf
, "\"C\"", 3)) /* CPP: extern "C" */
9501 buf
= SkipBlanksRet(buf
+3);
9504 buf
= SkipBlanksRet(buf
+1);
9509 if(!GetCPPType(&d
.ReturnType
, buf
, 1, 1))
9511 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE
, linenum
);
9514 else if(d
.ReturnType
.Unknown
)
9515 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, linenum
,
9516 d
.ReturnType
.Unknown
);
9518 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9520 strptr r
= d
.ReturnType
.TypeStart
;
9521 while(*r
!= '('/*)*/) ++r
;
9522 r
= SkipBlanks(++r
); /* the bracket */
9523 d
.FuncName
= SkipBlanks(++r
); /* the asterisk */
9526 d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
+d
.ReturnType
.FullLength
);
9528 while(*(buf
++) != '('/*)*/)
9530 *(SkipName(d
.FuncName
)) = 0;
9534 printf("Found non-function bracket in line %ld\n", linenum
);
9536 while(buf
< bufend
&& *buf
!= '\n')
9540 buf
= SkipBlanksRet(buf
);
9542 while(*buf
!= /*(*/')' && buf
< bufend
)
9544 if(d
.NumArgs
== MAXREGPPC
+1)
9546 DoError(ERROFFSET_CLIB
| ERR_TO_MUCH_ARGUMENTS
, linenum
);
9549 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 0, 1))
9551 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE
, linenum
, d
.NumArgs
);
9554 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
9555 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE_INT
, linenum
,
9556 d
.NumArgs
, d
.Args
[d
.NumArgs
-1].Unknown
);
9558 buf
= d
.Args
[d
.NumArgs
-1].TypeStart
+ d
.Args
[d
.NumArgs
-1].FullLength
;
9559 while(*buf
!= ',' && *buf
!= /*(*/')' && buf
< bufend
)
9562 printf("Added argument %d for %s (%d bytes)\n", d
.NumArgs
, d
.FuncName
,
9563 d
.Args
[d
.NumArgs
-1].FullLength
);
9566 buf
= SkipBlanksRet(++buf
);
9569 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9570 d
.NumArgs
= 0; /* void arguments are no arguments */
9572 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9575 memcpy(f
, &d
, sizeof(struct ClibData
));
9581 struct ClibData
*e
= clibdata
;
9586 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9588 int numclose
= 2, numopen
= 1;
9589 while(buf
< bufend
&& (numclose
|| numopen
> 0))
9591 if(*buf
== '('/*)*/) { ++numclose
; --numopen
; }
9592 else if(*buf
== /*(*/')') --numclose
;
9598 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9599 f
->FuncName
, linenum
, buf
-buffer
, f
->NumArgs
);
9604 static int32
ScanClibFile(strptr buf
, strptr bufend
)
9606 strptr linestart
= buf
;
9610 /* remove comments and other not so nice characters */
9613 if(*buf
== '\t' || *buf
== '\r' || *buf
== (string
)0xA0)
9615 else if(buf
[0] == '/' && buf
< bufend
-1)
9619 while(buf
< bufend
-1 && (buf
[0] != '*' || buf
[1] != '/'))
9628 else if(buf
[1] == '/')
9630 while(buf
< bufend
&& buf
[0] != '\n')
9637 else if(buf
[0] == '#' && strncmp("#include", buf
, 8))
9639 while(buf
< bufend
&& buf
[0] != '\n')
9648 printf("-----------\n%s-----------\n", linestart
);
9663 else if(!strncmp("#include", buf
, 8))
9667 if(!(d
= (struct Include
*) NewItem(&Includes
)))
9669 d
->Include
= buf
= SkipBlanks(buf
+8);
9670 AddItem(&Includes
, (struct ShortList
*) d
);
9671 while(*buf
&& *buf
!= '>' && *buf
!= '\n')
9679 printf("Added Include line %s\n", d
->Include
);
9683 else if(*buf
== '('/*)*/)
9687 if((i
= AddClibEntry(linestart
, bufend
, linenum
)) == -1) /* no memory */
9691 while(buf
< bufend
&& *buf
!= '\n')
9692 ++buf
; /* skip this line */
9697 while(buf
< bufend
&& i
-- > 0)
9699 if(*(buf
++) == '\n')
9703 } /* skip this function */
9714 static int32
IsCPPType(struct CPP_NameType
*data
, uint8 type
)
9716 if(!data
|| data
->Flags
|| data
->Type
!= type
|| data
->PointerDepth
)
9721 static uint32
CheckRegisterNum(strptr string
, struct CPP_NameType
*data
)
9725 for(i
= 0; i
< MAXREG
; ++i
)
9727 j
= strlen(RegNames
[i
]);
9728 if(!strnicmp(string
, RegNames
[i
], j
))
9731 if(*string
== ' ' || *string
== '\t' || *string
== '\n' || *string
== /*(*/')')
9734 data
->Flags
|= CPP_FLAG_REGISTER
;
9742 static uint32
ParseFuncPtrArgs(strptr buffer
, struct CPP_NameType
*data
)
9744 strptr buf
= buffer
;
9747 memset(&d
, 0, sizeof(struct ClibData
));
9748 while(*buf
!= /*(*/')')
9750 if(d
.NumArgs
== MAXREGPPC
+1)
9752 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 1, 1))
9755 buf
+= d
.Args
[d
.NumArgs
-1].FullLength
;
9756 while(*buf
!= ',' && *buf
!= /*(*/')')
9759 buf
= SkipBlanksRet(++buf
);
9762 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9763 d
.NumArgs
= 0; /* void arguments are no arguments */
9765 if(d
.NumArgs
) /* no need to allocate structure for nothing */
9767 if(!(data
->FuncPtr
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9770 memcpy(data
->FuncPtr
, &d
, sizeof(struct ClibData
));
9772 return (uint32
) (buf
+1-buffer
);
9775 /* rettype turns on usage of "extern" specifier */
9776 static int32
GetCPPType(struct CPP_NameType
*data
, strptr start
, uint32 rettype
, uint32 small
)
9783 data
->TypeStart
= start
= SkipBlanks(start
);
9785 if(!strncmp(start
, "REG", 3) && (start
[3] == ' ' || start
[3] == '\t' || start
[3] == '\n' || start
[3] == '('/*)*/))
9787 u
= SkipBlanksRet(start
+3);
9790 u
= SkipBlanks(u
+1);
9791 if((j
= CheckRegisterNum(u
, data
)))
9793 u
= SkipBlanks(u
+j
);
9795 start
= SkipBlanks(u
+1);
9799 data
->TypeStart
= start
;
9803 start
= SkipBlanks((u
= start
));
9804 if(!strncmp("...",start
,3))
9806 data
->Type
= CPP_TYPE_VARARGS
;
9807 data
->TypeLength
= start
+3 - (data
->TypeStart
);
9808 data
->FullLength
= data
->TypeLength
;
9811 if(CheckKeyword(start
, "const", 5) || CheckKeyword(start
, "CONST", 5))
9813 data
->Flags
|= CPP_FLAG_CONST
; start
+= 5;
9815 else if(rettype
&& CheckKeyword(start
, "extern", 6))
9817 start
+= 6; /* ignore it */
9819 else if(CheckKeyword(start
, "long", 4))
9821 if(data
->Flags
& CPP_FLAG_LONG
)
9822 data
->Type
= CPP_TYPE_LONGLONG
;
9824 data
->Flags
|= CPP_FLAG_LONG
;
9828 else if(CheckKeyword(start
, "signed", 6))
9830 else if(CheckKeyword(start
, "unsigned", 8))
9832 data
->Flags
|= CPP_FLAG_UNSIGNED
; start
+= 8;
9834 else if(CheckKeyword(start
, "register", 8))
9836 data
->Flags
|= CPP_FLAG_REGISTER
; start
+= 8;
9837 data
->Register
= UNDEFREGISTER
;
9839 else if(CheckKeyword(start
, "struct", 6))
9841 start
= SkipBlanks(start
+6);
9842 data
->Flags
|= CPP_FLAG_STRUCT
;
9843 if(*start
== '?') /* ? for external types */
9845 data
->StructureLength
= 0;
9846 data
->StructureName
= "";
9849 else if(*start
== '!') /* ! for typedef types */
9851 data
->Flags
|= CPP_FLAG_TYPEDEFNAME
;
9853 /* structure name and length already set */
9857 start
= SkipName((data
->StructureName
= start
));
9858 data
->StructureLength
= start
-data
->StructureName
;
9861 else if(CheckKeyword(start
, "union", 5))
9863 start
= SkipBlanks(start
+5);
9864 data
->Flags
|= CPP_FLAG_UNION
;
9865 if(*start
!= '?') /* ? for external types */
9867 start
= SkipName((data
->StructureName
= start
));
9868 data
->StructureLength
= start
-data
->StructureName
;
9872 data
->StructureLength
= 0;
9873 data
->StructureName
= "";
9877 else if(CheckKeyword(start
, "enum", 4))
9879 start
= SkipBlanks(start
+4);
9880 data
->Flags
|= CPP_FLAG_ENUM
;
9881 if(*start
!= '?') /* ? for external types */
9883 start
= SkipName((data
->StructureName
= start
));
9884 data
->StructureLength
= start
-data
->StructureName
;
9888 data
->StructureLength
= 0;
9889 data
->StructureName
= "";
9893 else if(*start
== '*')
9895 ++start
; ++data
->PointerDepth
;
9897 else if(*start
== '[')
9899 data
->Flags
|= CPP_FLAG_ARRAY
;
9900 while(*start
&& *start
!= ']')
9905 else if(start
[0] == '_' && start
[1] == '_' && (j
= CheckRegisterNum(start
+2, data
)))
9907 else if(!data
->Type
)
9911 for(i
= 0; CPP_Field
[i
].Text
; ++i
)
9913 if(!strncmp(start
, CPP_Field
[i
].Text
, CPP_Field
[i
].Length
) &&
9914 (start
[CPP_Field
[i
].Length
] == ' ' ||
9915 start
[CPP_Field
[i
].Length
] == '\t' ||
9916 start
[CPP_Field
[i
].Length
] == '\n' ||
9917 start
[CPP_Field
[i
].Length
] == ',' ||
9918 start
[CPP_Field
[i
].Length
] == /*(*/')' ||
9919 start
[CPP_Field
[i
].Length
] == '('/*)*/ ||
9920 start
[CPP_Field
[i
].Length
] == '*'))
9922 start
+= CPP_Field
[i
].Length
;
9923 data
->Type
= CPP_Field
[i
].Type
;
9924 data
->Flags
|= CPP_Field
[i
].Flags
;
9925 if(CPP_Field
[i
].Flags
& CPP_FLAG_POINTER
)
9926 ++data
->PointerDepth
;
9930 if(CPP_Field
[i
].Text
)
9934 struct CPP_ExternNames
*a
= extnames
;
9938 i
= strlen(a
->Type
);
9939 if(!strncmp(a
->Type
, start
, i
) && !isalnum(start
[i
]) &&
9943 data
->StructureName
= a
->NameType
.StructureName
;
9944 data
->FuncPtr
= a
->NameType
.FuncPtr
;
9945 data
->StructureLength
= a
->NameType
.StructureLength
;
9946 data
->PointerDepth
+= a
->NameType
.PointerDepth
;
9947 data
->Type
= a
->NameType
.Type
;
9948 data
->Flags
|= a
->NameType
.Flags
;
9949 data
->FuncArgs
= a
->NameType
.FuncArgs
;
9950 data
->ArgsLength
= a
->NameType
.ArgsLength
;
9954 /* check types here */
9959 else if((!data
->Type
) && (!data
->Flags
))
9962 struct CPP_Unknown
*u
;
9964 data
->Type
= CPP_TYPE_INT
;
9965 size
= SkipName(start
)-start
;
9966 for(u
= unknown
; u
&& strncmp(u
->Unknown
, start
, size
); u
= u
->Next
)
9970 data
->Unknown
= DupString(start
, size
);
9971 if((u
= (struct CPP_Unknown
*) AllocListMem(sizeof(struct CPP_Unknown
))))
9974 u
->Unknown
= data
->Unknown
;
9988 if(start
!= SkipBlanks(u
)) /* we broke the loop after increasing start */
9991 data
->TypeLength
= u
- (data
->TypeStart
);
9992 data
->FullLength
= data
->TypeLength
;
9999 u
= SkipBlanksRet(++u
);
10004 ++data
->FuncPointerDepth
; ++u
;
10006 u
= SkipBlanksRet(u
);
10007 if(CheckKeyword(u
, "const", 5) || CheckKeyword(u
, "CONST", 5))
10009 data
->Flags
|= CPP_FLAG_CONST
; u
+= 6;
10011 u
= SkipBlanksRet(u
);
10013 data
->FunctionName
= u
;
10014 u
= SkipBlanksRet(SkipName(u
));
10019 while(*u
&& numclose
)
10021 if(*u
== '('/*)*/) ++numclose
;
10022 else if(*u
== /*(*/')') --numclose
;
10028 u
= SkipBlanksRet(++u
);
10031 data
->Flags
|= CPP_FLAG_FUNCTION
;
10033 if((j
= ParseFuncPtrArgs(u
+1, data
)))
10035 data
->FuncArgs
= u
;
10036 data
->ArgsLength
= j
+1;
10037 data
->FullLength
= u
+data
->ArgsLength
- (data
->TypeStart
);
10043 if(data
->PointerDepth
)
10044 data
->Flags
|= CPP_FLAG_POINTER
;
10046 if(!(Flags2
& FLAG2_SMALLTYPES
) && !small
)
10048 if(!(data
->Flags
& (CPP_FLAG_STRPTR
|CPP_FLAG_POINTER
|CPP_FLAG_ENUM
10049 |CPP_FLAG_STRUCT
|CPP_FLAG_UNION
|CPP_FLAG_FUNCTION
|CPP_FLAG_REGISTER
)))
10051 if(data
->Type
== CPP_TYPE_BYTE
|| data
->Type
== CPP_TYPE_WORD
|| data
->Type
== CPP_TYPE_INT
)
10053 if(data
->Flags
& CPP_FLAG_UNSIGNED
)
10054 data
->Replace
= "const ULONG";
10056 data
->Replace
= "const LONG";
10057 data
->Type
= CPP_TYPE_LONG
;
10058 if(!(data
->Flags
& CPP_FLAG_CONST
))
10059 data
->Replace
+= 6;
10064 if(!data
->Type
&& (data
->Flags
& CPP_FLAG_LONG
))
10065 data
->Type
= CPP_TYPE_LONG
;
10067 if((!data
->Type
&& !data
->Flags
) || !ok
)
10072 static struct ClibData
*GetClibFunc(strptr name
, struct AmiPragma
*ap
, uint32 flags
)
10074 struct ClibData
*d
= clibdata
;
10078 DoError(ERR_ILLEGAL_INTERNAL_VALUE
, 0);
10082 while(d
&& strcmp(name
, d
->FuncName
))
10087 if(!(ap
->Flags
& AMIPRAGFLAG_NOCLIB
))
10089 DoError(ERR_PROTOTYPE_MISSING
, 0, name
);
10090 ap
->Flags
|= AMIPRAGFLAG_NOCLIB
;
10093 else if(ap
->CallArgs
!= d
->NumArgs
&& (!(flags
& FUNCFLAG_TAG
) ||
10094 ap
->CallArgs
+1 != d
->NumArgs
))
10096 if(!(ap
->Flags
& (AMIPRAGFLAG_CLIBARGCNT
|AMIPRAGFLAG_DIDARGWARN
)))
10098 DoError(ERR_CLIB_ARG_COUNT
, 0, name
, d
->NumArgs
, ap
->NumArgs
);
10099 ap
->Flags
|= AMIPRAGFLAG_CLIBARGCNT
;
10107 static int32
CheckKeyword(strptr string
, strptr keyword
, int32 size
)
10109 if(!strncmp(string
, keyword
, size
))
10112 if(*string
== ' ' || *string
== '\t' || *string
== '\n')
10118 /* return nonzero, when usable, zero, when string already emitted */
10119 static uint32
CopyCPPType(strptr buffer
, uint32 pass
, struct ClibData
*cd
,
10120 struct AmiArgs
*args
)
10122 uint32 ret
= 0, reg
;
10123 uint32 i
, j
, k
= 0;
10125 /* pass 0: signed strptr, MaxonC++ high args */
10126 /* pass 1: unsigned strptr, MaxonC++ high args */
10127 /* pass 2: signed strptr, StormC++ high args */
10128 /* pass 3: unsigned strptr, StormC++ high args */
10130 for(i
= 0; i
< cd
->NumArgs
; ++i
)
10132 struct CPP_NameType
*nt
;
10136 if(args
&& (Flags
& FLAG_LOCALREG
) && (nt
->Type
!= CPP_TYPE_VARARGS
))
10137 reg
= 1 + args
[k
].ArgReg
;
10138 else if((nt
->Flags
& CPP_FLAG_REGISTER
) && nt
->Register
!= UNDEFREGISTER
)
10139 reg
= 1 + nt
->Register
;
10143 if(reg
--) /* subtract the added 1 */
10145 *(buffer
++) = CPP_TYPE_REGISTER
;
10150 *(buffer
++) = reg
/10 + '0';
10151 *(buffer
++) = reg
%10 + '0';
10155 *(buffer
++) = reg
+ (reg
< 10 ? '0' : 'A'-10);
10158 *(buffer
++) = reg
+ '0';
10161 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10163 for(j
= 0; j
< nt
->FuncPointerDepth
; ++j
)
10164 *(buffer
++) = CPP_TYPE_POINTER
;
10165 *(buffer
++) = CPP_TYPE_FUNCTION
;
10167 for(j
= 0; j
< nt
->PointerDepth
; ++j
)
10168 *(buffer
++) = CPP_TYPE_POINTER
;
10169 if(nt
->Flags
& CPP_FLAG_CONST
)
10170 *(buffer
++) = CPP_TYPE_CONST
;
10171 if(nt
->Flags
& CPP_FLAG_UNSIGNED
)
10172 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10173 else if((nt
->Flags
& CPP_FLAG_STRPTR
) && (pass
& 1))
10175 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10176 ret
|= 1; /* we really use this pass */
10178 if(nt
->Flags
& CPP_FLAG_ENUM
)
10179 *(buffer
++) = CPP_TYPE_ENUM
;
10181 *(buffer
++) = cd
->Args
[i
].Type
;
10185 sprintf(buffer
, "%02lu", (uint32
) nt
->StructureLength
); buffer
+= 2;
10186 for(i
= 0; i
< nt
->StructureLength
; ++i
)
10187 *(buffer
++) = nt
->StructureName
[i
];
10189 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10193 ret
|= CopyCPPType(buffer
, pass
, nt
->FuncPtr
, 0);
10195 ++buffer
; /* skip to the new end */
10197 *(buffer
++) = CPP_TYPE_FUNCEND
;
10200 if(IsCPPType(nt
, CPP_TYPE_DOUBLE
)) /* double needs 2 registers */
10211 return ret
; /* return nozero if this pass should be used */
10214 static uint32
OutClibType(struct CPP_NameType
*nt
, strptr txt
)
10217 DoOutput("%s", nt
->Replace
);
10219 DoOutputDirect(nt
->TypeStart
, nt
->TypeLength
);
10220 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10222 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10225 DoOutput(" ("/*)*/);
10226 for(i
= 0; i
< nt
->FuncPointerDepth
; ++i
)
10229 DoOutput("%s)", txt
);
10233 return DoOutputDirect(nt
->FuncArgs
, nt
->ArgsLength
);
10235 return DoOutput("()");
10238 return DoOutput(" %s", txt
);
10244 static uint32
MakeClibType(strptr dest
, struct CPP_NameType
*nt
, strptr txt
)
10252 i
= strlen(nt
->Replace
);
10253 memcpy(a
, nt
->Replace
, i
);
10258 memcpy(a
, nt
->TypeStart
, nt
->TypeLength
);
10259 a
+= nt
->TypeLength
;
10262 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10264 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10267 a
+= sprintf(a
, " (*%s)", txt
);
10269 a
+= sprintf(a
, " (*)");
10272 memcpy(a
, nt
->FuncArgs
, nt
->ArgsLength
);
10273 a
+= nt
->ArgsLength
;
10276 a
+= sprintf(a
, "()");
10279 a
+= sprintf(a
, " %s", txt
);
10281 return (uint32
)(a
-dest
);
10284 static uint32
OutPASCALType(struct CPP_NameType
*t
, strptr txt
, uint32 ret
)
10286 int32 i
= t
->PointerDepth
;
10288 if(t
->Flags
& CPP_FLAG_CONST
)
10289 DoOutput("CONST ");
10290 if(!ret
&& i
== 1 &&
10291 (t
->Type
== CPP_TYPE_LONG
|| t
->Type
== CPP_TYPE_WORD
))
10293 DoOutput("VAR "); --i
;
10296 DoOutput("%s : ", txt
);
10298 if(!i
&& t
->Flags
== CPP_FLAG_BOOLEAN
)
10299 return DoOutput("BOOLEAN");
10300 else if(i
&& t
->Type
== CPP_TYPE_VOID
)
10301 return DoOutput("POINTER");
10302 else if(t
->Flags
& CPP_FLAG_FUNCTION
)
10303 return DoOutput("tPROCEDURE");
10308 if((t
->Flags
& (CPP_FLAG_STRUCT
|CPP_FLAG_UNION
)) && t
->StructureLength
)
10310 if(!t
->PointerDepth
)
10312 return DoOutputDirect(t
->StructureName
, t
->StructureLength
);
10315 if(t
->Flags
& CPP_FLAG_UNSIGNED
)
10317 if(t
->Type
== CPP_TYPE_LONG
)
10318 return DoOutput("CARDINAL");
10319 if(t
->Type
== CPP_TYPE_WORD
)
10320 return DoOutput("int16");
10321 if(t
->Type
== CPP_TYPE_BYTE
)
10322 return DoOutput(t
->PointerDepth
== 1 ? "CHAR" : "int8");
10324 else if(t
->Type
== CPP_TYPE_WORD
)
10325 return DoOutput("INTEGER");
10326 else if(t
->Type
== CPP_TYPE_BYTE
)
10327 return DoOutput("SHORTINT");
10328 return DoOutput("int32INT");
10331 /* ------------------------------------------------------------------ */
10333 static uint32
CallPrag(uint32 tagmode
, strptr type
, FuncType Func
)
10336 if((*type
&& !DoOutput("#if%s\n", type
)) ||
10337 !(CallFunc(tagmode
, tagmode
? 0 : "/%s */\n", Func
)) ||
10338 (*type
&& !DoOutput("#endif\n")))
10343 static uint32
CreatePragmaFile(strptr amicall
, strptr libcall
, strptr amitags
,
10344 strptr libtags
, uint32 mode
)
10346 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10350 case PRAGMODE_PRAGLIB
: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10351 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper
,
10352 ShortBaseNameUpper
); break;
10353 case PRAGMODE_PRAGSLIB
: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10354 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10355 case PRAGMODE_PRAGSPRAGS
: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10356 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10357 case PRAGMODE_NONE
: break;
10364 DoOutputDirect(HEADER
, headersize
);
10367 if(mode
!= PRAGMODE_NONE
&& !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10368 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10371 if((Flags
& FLAG_EXTERNC
) &&
10372 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10375 if(Flags
& FLAG_GNUPRAG
)
10377 DoOutput("#ifdef " TEXT_GNUC
"\n#ifdef NO_OBSOLETE\n"
10378 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10379 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName
);
10380 Flags
|= FLAG_DONE
;
10384 !CallPrag(TAGMODE_NORMAL
, amicall
, FuncAMICALL
) ||
10385 !CallPrag(TAGMODE_NORMAL
, libcall
, FuncLIBCALL
))
10391 !CallPrag(TAGMODE_TAGS
, amitags
, FuncAMICALL
) ||
10392 !CallPrag(TAGMODE_TAGS
, libtags
, FuncLIBCALL
))
10396 if((Flags
& FLAG_EXTERNC
) &&
10397 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10402 case PRAGMODE_PRAGLIB
: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10403 ShortBaseNameUpper
); break;
10404 case PRAGMODE_PRAGSLIB
: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10405 ShortBaseNameUpper
); break;
10406 case PRAGMODE_PRAGSPRAGS
: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10407 ShortBaseNameUpper
); break;
10408 case PRAGMODE_NONE
: break;
10411 return Output_Error
;
10414 static uint32
CreateCSTUBSFile(void)
10416 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10418 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10419 ShortBaseNameUpper
, ShortBaseNameUpper
);
10423 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10429 DoOutputDirect(HEADER
, headersize
);
10432 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10433 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10436 if(!CallFunc(TAGMODE_TAGS
, "/%s */\n", FuncCSTUBS
))
10439 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10440 ShortBaseNameUpper
);
10443 static uint32
CreateLVOFile(uint32 mode
)
10445 strptr data
= "_LVO_I";
10447 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10449 if(mode
== 2 || mode
== 4)
10452 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10453 ShortBaseNameUpper
, data
, ShortBaseNameUpper
, data
) ||
10454 (HEADER
&& (!DoOutput("\n") || !DoOutputDirect(HEADER
, headersize
))) ||
10455 (mode
<= 2 && !CallFunc(TAGMODE_NORMAL
, 0, FuncLVOXDEF
)) ||
10456 !CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVO
) ||
10457 !DoOutput("\n\n\t\tENDC\n"))
10463 static uint32
CreateLVOFilePPC(uint32 mode
)
10465 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10467 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10468 ShortBaseNameUpper
, ShortBaseNameUpper
))
10473 DoOutputDirect(HEADER
, headersize
);
10477 case 0: CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCXDEF
);
10478 case 1: CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVOPPC
);
10480 return DoOutput("\n\t.endif\n");
10483 static uint32
CreateAsmStubs(uint32 mode
, uint32 callmode
)
10485 if(mode
== 1 && (Flags2
& FLAG2_AUTOHEADER
)) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10487 /* 1 = Text, 2 = Code */
10494 DoOutputDirect(HEADER
, headersize
);
10497 if(!(Flags
& FLAG_ASMSECTION
))
10498 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
10499 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
10500 if(!CallFunc(callmode
, "\n%s", FuncAsmText
))
10504 if(!CallFunc(callmode
, 0, FuncAsmCode
))
10512 static uint32
CreateProtoFile(uint32 Type
)
10514 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10516 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper
,
10517 ShortBaseNameUpper
);
10522 DoOutputDirect(HEADER
, headersize
);
10525 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10527 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC
")\n"
10528 "#include <clib/%s_protos.h>\n#endif\n",
10529 ShortBaseNameUpper
, ShortBaseName
);
10533 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10535 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10537 DoOutput("%s;\n#endif\n", BaseName
);
10544 DoOutput("\n#ifdef " TEXT_GNUC
"\n");
10546 DoOutput("#ifndef __cplusplus\n");
10547 DoOutput("#ifdef __AROS__\n");
10548 DoOutput("#include <defines/%s.h>\n", ShortBaseName
);
10549 DoOutput("#else\n");
10550 DoOutput("#include <inline/%s.h>\n", ShortBaseName
);
10551 DoOutput("#endif\n");
10553 DoOutput("#endif\n");
10557 DoOutput("#elif defined(" TEXT_VBCC
")\n"
10558 "#include <inline/%s_protos.h>\n#else", ShortBaseName
);
10560 DoOutput("#elif !defined(" TEXT_VBCC
")");
10564 DoOutput("\n#ifndef __PPC__");
10567 strptr str1
= "pragma", str2
= "lib";
10571 case 4: str1
= "pragmas"; /* no break; */
10572 case 2: str2
= "pragmas"; break;
10573 case 3: str1
= "pragmas"; break;
10574 case 5: str1
= "local"; str2
= "loc"; break;
10576 DoOutput("\n#include <%s/%s_%s.h>\n", str1
, ShortBaseName
, str2
);
10579 DoOutput("#endif\n");
10581 DoOutput("#endif\n");
10584 Flags
|= FLAG_DONE
;
10586 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10589 static uint32
CreateLocalData(strptr to
, uint32 callmode
)
10591 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10593 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10594 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10595 ShortBaseNameUpper
, ShortBaseNameUpper
);
10600 DoOutputDirect(HEADER
, headersize
);
10606 if((Flags
& FLAG_EXTERNC
) &&
10607 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10610 if(!CallFunc(callmode
, "/%s */\n", FuncLocText
))
10613 if((Flags
& FLAG_EXTERNC
) &&
10614 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10617 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper
);
10619 sprintf(filename
, "%s_loc.lib", ShortBaseName
);
10620 if(!CloseDest(to
) || !OpenDest(filename
))
10623 CallFunc(callmode
, 0, FuncLocCode
);
10625 return CloseDest(filename
);
10628 static uint32
CreateInline(uint32 mode
, uint32 callmode
)
10630 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10634 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10637 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10638 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
,
10639 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10644 DoOutputDirect(HEADER
, headersize
);
10649 /* prevent loading of clib-file after inline */
10650 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10651 ShortBaseNameUpper
, ShortBaseNameUpper
);
10655 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10656 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10657 "#include <ppcinline/macros.h>\n#endif\n\n");
10659 DoOutput("#ifndef __INLINE_MACROS_H\n"
10660 "#include <inline/macros.h>\n#endif\n\n");
10661 Flags
|= FLAG_INLINENEW
;
10665 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10666 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10667 "#include <ppcinline/stubs.h>\n#endif\n\n");
10669 DoOutput("#ifndef __INLINE_STUB_H\n"
10670 "#include <inline/stubs.h>\n#endif\n\n");
10672 Flags
|= FLAG_INLINESTUB
;
10675 Flags2
|= FLAG2_INLINEMAC
;
10679 if((Flags
& FLAG_EXTERNC
) &&
10680 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10685 if(mode
&& mode
<= 2)
10687 if(Flags
& FLAG_MORPHOS
)
10688 DoOutput("#include <emul/emulregs.h>\n");
10689 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10690 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10691 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10692 "#define BASE_PAR_DECL0 void\n#endif\n"
10693 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10694 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10697 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10698 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10703 if(!CallFunc(callmode
, "/%s */\n", FuncInline
))
10709 Flags
|= FLAG_INLINENEW
;
10710 if(!CallFunc(callmode
, "/%s */\n", FuncInlineDirect
))
10715 if(!CallFunc(callmode
, "/%s */\n", FuncInlineNS
))
10719 if(mode
&& mode
<= 2 && BaseName
)
10720 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10721 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper
);
10723 if((Flags
& FLAG_EXTERNC
) &&
10724 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10727 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10728 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10731 static uint32
CreateGateStubs(uint32 callmode
)
10733 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10737 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10739 if(!prefix
[0] && !subprefix
[0])
10741 DoError(ERR_PREFIX
, 0); return 1;
10744 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10745 ShortBaseNameUpper
, ShortBaseNameUpper
);
10747 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10748 premacro
, ShortBaseName
);
10753 DoOutputDirect(HEADER
, headersize
);
10758 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10759 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10760 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10761 "#define BASE_PAR_DECL0 void\n#endif\n"
10762 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10763 "BASE_EXT_DECL0\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10768 if(!CallFunc(callmode
, "/%s */\n", FuncGateStubs
))
10771 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper
);
10774 static uint32
CreateSASPowerUP(uint32 callmode
)
10776 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10778 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10779 ShortBaseNameUpper
, ShortBaseNameUpper
);
10784 DoOutputDirect(HEADER
, headersize
);
10787 DoOutput("\n#ifdef __GNUC__\n"
10788 "#ifndef _PPCINLINE__%s_H\n"
10789 "#include <ppcinline/%s.h>\n"
10792 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10793 "#include <ppclib/interface.h>\n"
10795 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10796 "#include <gcclib/powerup_protos.h>\n"
10798 "#ifndef NO_PPCINLINE_STDARG\n"
10799 "#define NO_PPCINLINE_STDARG\n"
10800 "#endif /* SAS-C PPC inlines */\n\n",
10801 ShortBaseNameUpper
, ShortBaseName
);
10805 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10806 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10809 if(!CallFunc(callmode
, "/%s */\n", FuncPowerUP
))
10812 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10813 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper
);
10816 static uint32
CreateProtoPowerUP(void)
10818 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10820 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10821 ShortBaseNameUpper
, ShortBaseNameUpper
);
10826 DoOutputDirect(HEADER
, headersize
);
10829 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName
);
10833 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10834 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10835 "#endif\n%s;\n#endif\n", BaseName
);
10838 DoOutput("\n#ifdef " TEXT_GNUC
"\n"
10839 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10840 "#else\n#include <inline/%s.h>\n#endif\n"
10841 "#else /* SAS-C */\n"
10842 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10843 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10844 ShortBaseName
, ShortBaseName
, ShortBaseName
, ShortBaseName
);
10846 Flags
|= FLAG_DONE
;
10848 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10851 static uint32
CreateFPCUnit(void)
10854 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT
);
10858 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10862 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName
);
10867 DoOutputDirect(HEADER
, headersize
);
10870 DoOutput("**********************************************************************}\n\n");
10871 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10872 DoOutput("{$mode objfpc}\n");
10873 DoOutput("{$I useamigasmartlink.inc}\n");
10874 DoOutput("{$ifdef use_amiga_smartlink}\n");
10875 DoOutput(" {$smartlink on}\n");
10876 DoOutput("{$endif use_amiga_smartlink}\n\n");
10878 DoOutput("UNIT %s;\n", ShortBaseNameUpper
);
10880 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName
, GetBaseTypeLib());
10882 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper
,ShortBaseName
);
10883 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName
);
10884 DoOutput("{$I %s.inc}\n\n",ShortBaseName
);
10886 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncFPCType
))
10889 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10890 if(!CallFunc(TAGMODE_TAGS
, 0, FuncFPCTypeTags
))
10893 DoOutput("\n{Here we read how to compile this unit}\n");
10894 DoOutput("{You can remove this include and use a define instead}\n");
10895 DoOutput("{$I useautoopenlib.inc}\n");
10896 DoOutput("{$ifdef use_init_openlib}\n");
10897 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10898 DoOutput("{$endif use_init_openlib}\n");
10899 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10900 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper
);
10901 DoOutput("\nIMPLEMENTATION\n\n");
10902 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10903 DoOutput("uses \n");
10904 DoOutput("{$ifndef dont_use_openlib}\n");
10905 DoOutput("msgbox, \n");
10906 DoOutput("{$endif dont_use_openlib}\n");
10907 DoOutput("tagsarray;\n\n");
10909 if(!CallFunc(TAGMODE_NORMAL
, "(%s *)\n", FuncFPCUnit
))
10912 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10913 if(!CallFunc(TAGMODE_TAGS
,"(%s *)\n", FuncFPCTypeTagsUnit
))
10916 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10917 DoOutput(" VERSION : string[2] = '0';\n");
10918 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10920 DoOutput("{$ifdef use_init_openlib}\n");
10921 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName
);
10922 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper
);
10924 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10925 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10926 DoOutput("begin\n");
10927 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10928 DoOutput(" if %s <> nil then begin\n",BaseName
);
10929 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10930 DoOutput(" %s := nil;\n",BaseName
);
10931 DoOutput(" end;\n");
10932 DoOutput("end;\n\n");
10933 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10934 DoOutput("begin\n %s := nil;\n",BaseName
);
10935 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10936 DoOutput(" if %s <> nil then begin\n",BaseName
);
10937 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10938 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10939 DoOutput(" end else begin\n");
10940 DoOutput(" MessageBox('FPC Pascal Error',\n");
10941 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10942 DoOutput(" 'Deallocating resources and closing down',\n");
10943 DoOutput(" 'Oops');\n");
10944 DoOutput(" halt(20);\n");
10945 DoOutput(" end;\n");
10946 DoOutput("end;\n\n");
10947 DoOutput("begin\n");
10948 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper
);
10949 DoOutput("{$endif use_init_openlib}\n\n");
10951 DoOutput("{$ifdef use_auto_openlib}\n");
10952 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName
);
10954 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10955 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10956 DoOutput("begin\n");
10957 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10958 DoOutput(" if %s <> nil then begin\n",BaseName
);
10959 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10960 DoOutput(" %s := nil;\n",BaseName
);
10961 DoOutput(" end;\n");
10962 DoOutput("end;\n\n");
10963 DoOutput("begin\n %s := nil;\n",BaseName
);
10964 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10965 DoOutput(" if %s <> nil then begin\n",BaseName
);
10966 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10967 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10968 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper
);
10969 DoOutput(" end else begin\n");
10970 DoOutput(" MessageBox('FPC Pascal Error',\n");
10971 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10972 DoOutput(" 'Deallocating resources and closing down',\n");
10973 DoOutput(" 'Oops');\n");
10974 DoOutput(" halt(20);\n");
10975 DoOutput(" end;\n\n");
10976 DoOutput("{$endif use_auto_openlib}\n\n");
10978 DoOutput("{$ifdef dont_use_openlib}\n");
10979 DoOutput("begin\n");
10980 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper
);
10981 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName
);
10982 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName
);
10983 DoOutput("{$endif dont_use_openlib}\n\n");
10985 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper
);
10988 static uint32
CreateBMAP(void)
10990 return CallFunc(TAGMODE_NORMAL
, 0, FuncBMAP
);
10993 static uint32
CreateLVOLib(void)
10997 i
= strlen(ShortBaseNameUpper
);
10998 EndPutM32(tempbuf
, HUNK_UNIT
);
10999 EndPutM32(tempbuf
+4, (i
+3)>>2);
11000 DoOutputDirect(tempbuf
, 8);
11001 DoOutputDirect(ShortBaseNameUpper
, i
);
11002 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11004 i
= strlen(hunkname
);
11005 EndPutM32(tempbuf
, HUNK_NAME
);
11006 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11007 DoOutputDirect(tempbuf
, 8);
11008 DoOutputDirect(hunkname
, i
);
11009 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11011 EndPutM32(tempbuf
, HUNK_CODE
);
11012 EndPutM32(tempbuf
+4, 0);
11013 EndPutM32(tempbuf
+8, HUNK_EXT
);
11014 DoOutputDirect(tempbuf
, 12);
11016 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOLib
))
11019 EndPutM32(tempbuf
, 0);
11020 EndPutM32(tempbuf
+4, HUNK_END
);
11021 return DoOutputDirect(tempbuf
, 8);
11024 static uint32
CreateLVOLibPPC(void)
11026 uint8
*data
= tempbuf
, *data2
, *data3
;
11028 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11029 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11030 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11031 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11032 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
11033 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
11034 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
11035 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11036 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11037 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11038 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
11039 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
11040 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
11041 EndPutM32Inc(data
, 0); /* eeh->e_entry */
11042 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
11043 data2
= data
; data
+= 4;
11044 EndPutM32Inc(data
, 0); /* eeh->e_flags */
11045 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
11046 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
11047 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
11048 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
11049 EndPutM16Inc(data
, 4); /* eeh->e_shnum */
11050 EndPutM16Inc(data
, 1); /* eeh->e_shstrndx - first table is string table */
11053 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11054 data
+= 28; /* 1 9 17*/
11055 EndPutM32(data2
, data
-tempbuf
); /* store the entry */
11057 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
11058 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
11059 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11060 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11061 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
11062 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
11063 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11064 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11065 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
11066 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11068 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
11069 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
11070 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
11071 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
11072 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[3].sh_offset */
11073 EndPutM32Inc(data
, 27); /* esh[3].sh_size */
11074 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
11075 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
11076 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
11077 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
11079 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
11080 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
11081 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
11082 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
11084 data
+= 4; /* esh[4].sh_offset */
11085 data
+= 4; /* esh[4].sh_size */
11086 EndPutM32Inc(data
, 3); /* esh[4].sh_link - the third entry is our string table */
11087 EndPutM32Inc(data
, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11088 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
11089 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11091 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
11092 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
11093 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11094 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11096 data
+= 4; /* esh[0].sh_offset */
11097 data
+= 4; /* esh[0].sh_size */
11098 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11099 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11100 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
11101 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11103 EndPutM32Inc(data2
, data
-tempbuf
);
11105 EndPutM32Inc(data
,0);
11106 EndPutM32Inc(data
,0); /* first entry is empty */
11107 EndPutM32Inc(data
,0);
11108 EndPutM32Inc(data
,0);
11110 symoffset
= 1; /* initial value */
11113 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCBias
))
11115 EndPutM32(data2
, elfbufpos
-data
+16);
11116 EndPutM32Inc(data3
, elfbufpos
-tempbuf
);
11117 EndPutM32(data3
, symoffset
);
11119 *(elfbufpos
++) = 0; /* first sym entry */
11120 if(!DoOutputDirect(tempbuf
, elfbufpos
-tempbuf
))
11123 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCName
))
11126 while((symoffset
++)&3)
11128 if(!DoOutputDirect("", 1))
11135 static uint32
CreateVBCCInline(uint32 mode
, uint32 callmode
)
11137 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11141 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11144 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11145 ShortBaseNameUpper
, ShortBaseNameUpper
);
11147 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11150 /* always include emul/emulregs.h in MorphOS inlines,
11151 gcc-based sources might depend on it :| */
11152 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11158 DoOutputDirect(HEADER
, headersize
);
11163 if(!CallFunc(callmode
, "/%s */\n", mode
? (mode
== 2 ? FuncVBCCMorphInline
11164 : FuncVBCCWOSInline
) : FuncVBCCInline
))
11167 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper
);
11170 static uint32
CreateVBCC(uint32 mode
, uint32 callmode
)
11174 if(mode
!= 2 && mode
!= 3)
11176 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11181 DoOutputDirect(HEADER
, headersize
);
11187 case 4: res
= CallFunc(callmode
, 0, FuncVBCCPUPText
); break;
11189 case 3: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11190 case 2: res
= CallFunc(callmode
, 0, FuncVBCCWOSCode
); break;
11192 case 1: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11193 case 0: res
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
); break;
11198 static uint32
CreateVBCCPUPLib(uint32 callmode
)
11200 /* output header */
11201 DoOutput("!<arch>\n");
11203 return CallFunc(callmode
, 0, FuncVBCCPUPCode
);
11206 static uint32
CreateVBCCMorphCode(uint32 callmode
)
11208 /* output header */
11209 DoOutput("!<arch>\n");
11211 return CallFunc(callmode
, 0, FuncVBCCMorphCode
);
11214 static uint32
CreateEModule(uint32 sorted
)
11218 DoError(ERR_NO_SORTED
, 0);
11221 DoOutputDirect("EMOD\0\x06", 6);
11222 for(res
= 0; res
< 2; ++res
)
11224 for(i
= 0; BaseName
[i
]; ++i
)
11225 DoOutput("%c", tolower(BaseName
[i
]));
11226 DoOutputDirect("\x00",1);
11228 LastBias
= BIAS_START
-BIAS_OFFSET
;
11229 CallFunc(TAGMODE_NORMAL
, 0, FuncEModule
);
11230 res
= DoOutputDirect("\xFF",1);
11235 static uint32
CreateProtoRedirect(void)
11237 Flags
|= FLAG_DONE
;
11238 return DoOutput("#ifdef NO_OBSOLETE\n"
11239 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11240 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName
);
11243 static uint32
CreateSFD(uint32 callmode
)
11245 struct Include
*inc
;
11246 struct AmiPragma
*ap
;
11249 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11252 if((ap
= (struct AmiPragma
*) AmiPragma
.First
))
11253 LastBias
= ap
->Bias
-BIAS_OFFSET
;
11254 else /* only security, never used normally */
11256 CurrentABI
= ABI_M68K
;
11259 DoOutput("==id %s\n", IDstring
);
11266 tim
= localtime(&t
);
11268 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11269 "noname Exp $\n", '$', filename
, tim
->tm_year
+1900, tim
->tm_mon
+1,
11270 tim
->tm_mday
, tim
->tm_hour
, tim
->tm_min
, tim
->tm_sec
);
11274 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11275 GetLibraryName(), BaseName
, GetBaseType(), GetLibraryName());
11276 DoOutput("==bias %ld\n==public\n", LastBias
+BIAS_OFFSET
);
11278 for(inc
= (struct Include
*) Includes
.First
; inc
; inc
= (struct Include
*) inc
->List
.Next
)
11279 DoOutput("==include %s\n", inc
->Include
);
11280 if(!Includes
.First
)
11281 DoOutput("==include <exec/types.h>\n");
11283 CallFunc(callmode
, "%s\n", FuncSFD
);
11285 return DoOutput("==end\n");
11288 static uint32
CreateClib(uint32 callmode
)
11292 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11295 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11297 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper
,
11298 ShortBaseNameUpper
);
11303 DoOutputDirect(HEADER
, headersize
);
11312 tim
= localtime(&t
);
11316 s
= SkipBlanks(IDstring
+4);
11317 while(*s
&& *s
!= ' ')
11324 if(Flags2
& FLAG2_SYSTEMRELEASE
)
11326 DoOutput("\n/*\n**\t$Id: %s %s\n", filename
, s
);
11333 while(*t
&& *t
!= ' ')
11337 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename
, s
,
11338 tim
->tm_mday
, tim
->tm_mon
+1, tim
->tm_year
+1900);
11340 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11341 if(!Copyright
|| (Copyright
&& strncmp("Copyright ", Copyright
, 10)))
11342 DoOutput("Copyright %c %d ", 0xa9, tim
->tm_year
+1900);
11343 DoOutput("%s\n", Copyright
? Copyright
: Flags2
& FLAG2_SYSTEMRELEASE
?
11344 "Amiga, Inc." : "");
11345 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11350 if((Flags
& FLAG_EXTERNC
) &&
11351 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11354 CallFunc(callmode
, "\n/%s */\n\n", FuncClib
);
11356 if((Flags
& FLAG_EXTERNC
) &&
11357 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11360 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper
);
11363 static uint32
CreateFD(void)
11366 CurrentABI
= ABI_M68K
;
11369 DoOutput("##base _%s\n", BaseName
);
11370 DoOutput("##public\n");
11372 CallFunc(TAGMODE_NORMAL
, "%s\n", FuncFD
);
11374 return DoOutput("##end\n");
11377 static uint32
CreateGenAuto(strptr to
, uint32 type
)
11379 strptr name
, btype
;
11381 uint32 i
, verref
, exitfuncref
, sysref2
, exitref
, rel1
, rel2
, nameref
;
11382 if(!(name
= GetLibraryName()))
11384 btype
= GetBaseType();
11389 Flags
|= FLAG_DONE
;
11390 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11391 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11392 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11393 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11394 btype
, BaseName
, BaseName
,
11395 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", name
, BaseName
,
11396 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", BaseName
)))
11398 sprintf(filename
, "%s_autoopenver.c", ShortBaseName
);
11399 if(!CloseDest(to
) || !OpenDest(filename
))
11401 Flags
|= FLAG_DONE
;
11402 return DoOutput("unsigned long _%sVer = 0;\n", BaseName
);
11405 Flags
|= FLAG_DONE
;
11406 i
= strlen(filename
)-4; /* remove .lib extension */
11407 EndPutM32(tempbuf
, HUNK_UNIT
);
11408 EndPutM32(tempbuf
+4, (i
+3)>>2);
11409 DoOutputDirect(tempbuf
, 8);
11410 DoOutputDirect(filename
, i
);
11411 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11413 i
= strlen(hunkname
);
11414 EndPutM32(tempbuf
, HUNK_NAME
);
11415 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11416 DoOutputDirect(tempbuf
, 8);
11417 DoOutputDirect(hunkname
, i
);
11418 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11420 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
11421 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11423 if(Flags
& FLAG_SMALLDATA
)
11425 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11426 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11430 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11431 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11433 verref
= data
-tempbuf
-8+2;
11434 if(Flags
& FLAG_SMALLDATA
)
11436 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11437 EndPutM16Inc(data
, 0); /* place for basevers reference */
11441 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11442 EndPutM32Inc(data
, 0); /* place for basevers reference */
11444 EndPutM32Inc(data
, 0x43FA0030 + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2) + ((Flags
& FLAG_SMALLDATA
) ? 0 : 6));
11445 EndPutM32Inc(data
, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11447 rel1
= data
-tempbuf
-8+2;
11448 if(Flags
& FLAG_SMALLDATA
)
11450 EndPutM16Inc(data
, 0x2940); /* MOVE.L D0,xxx(A4) */
11451 EndPutM16Inc(data
, 0);
11455 EndPutM16Inc(data
, 0x23C0); /* MOVE.L D0,xxx */
11456 EndPutM32Inc(data
, 0);
11458 EndPutM16Inc(data
, 0x660A + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2)); /* BNE.B .lib */
11459 EndPutM32Inc(data
, 0x48780014); /* PEA 20 */
11461 exitfuncref
= data
-tempbuf
-8+2;
11462 if(Flags2
& FLAG2_SMALLCODE
)
11464 EndPutM16Inc(data
, 0x4EBA); /* JSR _exit(PC) */
11465 EndPutM16Inc(data
, 0); /* place for base reference */
11469 EndPutM16Inc(data
, 0x4EB9); /* JSR _exit */
11470 EndPutM32Inc(data
, 0); /* place for base reference */
11472 EndPutM16Inc(data
, 0x584F); /* ADDQ.W, #4,A7 */
11473 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11474 EndPutM16Inc(data
,0x4E75); /* RTS */
11475 exitref
= data
-tempbuf
-8;
11477 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11478 sysref2
= data
-tempbuf
-8+2;
11480 if(Flags
& FLAG_SMALLDATA
)
11482 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11483 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11487 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11488 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11490 rel2
= data
-tempbuf
-8+2;
11491 if(Flags
& FLAG_SMALLDATA
)
11493 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11494 EndPutM16Inc(data
, 0); /* place for base reference */
11498 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11499 EndPutM32Inc(data
, 0); /* place for base reference */
11501 EndPutM16Inc(data
, 0x6606); /* BNE.B .nolib */
11502 EndPutM16Inc(data
, 0x2240); /* MOVEA.L D0,A1 */
11504 EndPutM32Inc(data
, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11505 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11506 EndPutM16Inc(data
,0x4E75); /* RTS */
11507 nameref
= data
-tempbuf
-8;
11508 memcpy(data
, name
, strlen(name
));
11509 data
+= strlen(name
);
11510 do { *(data
++) = 0; } while((data
-tempbuf
)&3);
11512 EndPutM32(tempbuf
, HUNK_CODE
);
11513 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
11514 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
11516 if(Flags
& FLAG_SMALLDATA
)
11518 EndPutM32(tempbuf
, HUNK_DREL16
);
11522 EndPutM32(tempbuf
, HUNK_ABSRELOC32
);
11524 EndPutM32(tempbuf
+4, 2); /* 2 entries */
11525 EndPutM32(tempbuf
+8, 1); /* to hunk 1 */
11526 EndPutM32(tempbuf
+12, rel1
); /* address 0 */
11527 EndPutM32(tempbuf
+16, rel2
); /* address 0 */
11528 EndPutM32(tempbuf
+20, 0); /* end of reloc hunk */
11529 DoOutputDirect(tempbuf
, 24);
11531 /* extern references */
11532 EndPutM32(tempbuf
, HUNK_EXT
);
11533 DoOutputDirect(tempbuf
, 4);
11535 OutputXREF2(4, sysref2
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "_SysBase");
11536 OutputXREF(verref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "__%sVer", BaseName
);
11537 OutputXREF(exitfuncref
, (Flags2
& FLAG2_SMALLCODE
? EXT_DEXT16
: EXT_REF32
), "_exit");
11538 OutputXDEF(0, "__INIT_%ld_%s", priority
, BaseName
);
11539 OutputXDEF(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11540 OutputXDEF(nameref
, "%sname", ShortBaseName
);
11541 EndPutM32(tempbuf
, 0); /* ext end */
11542 DoOutputDirect(tempbuf
, 4);
11544 if(!(Flags
& FLAG_NOSYMBOL
))
11546 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11547 DoOutputDirect(tempbuf
, 4);
11548 OutputSYMBOL(0, "__INIT_%ld_%s", priority
, BaseName
);
11549 OutputSYMBOL(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11550 OutputSYMBOL(nameref
, "%sname", ShortBaseName
);
11551 EndPutM32(tempbuf
, 0);
11552 DoOutputDirect(tempbuf
, 4);
11555 EndPutM32(tempbuf
, HUNK_END
);
11556 DoOutputDirect(tempbuf
, 4);
11558 i
= strlen(datahunkname
);
11559 EndPutM32(tempbuf
, HUNK_NAME
);
11560 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11561 DoOutputDirect(tempbuf
, 8);
11562 DoOutputDirect(datahunkname
, i
);
11563 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11565 EndPutM32(tempbuf
, HUNK_BSS
);
11566 EndPutM32(tempbuf
+4, 1);
11567 DoOutputDirect(tempbuf
, 8);
11569 EndPutM32(tempbuf
, HUNK_EXT
);
11570 DoOutputDirect(tempbuf
, 4);
11571 OutputXDEF(0, "_%s", BaseName
);
11572 EndPutM32(tempbuf
, 0); /* ext end */
11573 DoOutputDirect(tempbuf
, 4);
11575 if(!(Flags
& FLAG_NOSYMBOL
))
11577 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11578 DoOutputDirect(tempbuf
, 4);
11579 OutputSYMBOL(0, "_%s", BaseName
);
11580 EndPutM32(tempbuf
, 0);
11581 DoOutputDirect(tempbuf
, 4);
11584 EndPutM32(tempbuf
, HUNK_END
);
11585 DoOutputDirect(tempbuf
, 4);
11587 sprintf(filename
, "%s_autoopenver", ShortBaseName
);
11588 i
= strlen(filename
);
11589 EndPutM32(tempbuf
, HUNK_UNIT
);
11590 EndPutM32(tempbuf
+4, (i
+3)>>2);
11591 DoOutputDirect(tempbuf
, 8);
11592 DoOutputDirect(filename
, i
);
11593 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11595 i
= strlen(datahunkname
);
11596 EndPutM32(tempbuf
, HUNK_NAME
);
11597 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11598 DoOutputDirect(tempbuf
, 8);
11599 DoOutputDirect(datahunkname
, i
);
11600 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11602 EndPutM32(tempbuf
, HUNK_BSS
);
11603 EndPutM32(tempbuf
+4, 1);
11604 DoOutputDirect(tempbuf
, 8);
11606 EndPutM32(tempbuf
, HUNK_EXT
);
11607 DoOutputDirect(tempbuf
, 4);
11608 OutputXDEF(0, "_%sVer", BaseName
);
11609 EndPutM32(tempbuf
, 0); /* ext end */
11610 DoOutputDirect(tempbuf
, 4);
11612 if(!(Flags
& FLAG_NOSYMBOL
))
11614 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11615 DoOutputDirect(tempbuf
, 4);
11616 OutputSYMBOL(0, "_%sVer", BaseName
);
11617 EndPutM32(tempbuf
, 0);
11618 DoOutputDirect(tempbuf
, 4);
11621 EndPutM32(tempbuf
, HUNK_END
);
11622 return DoOutputDirect(tempbuf
, 4);
11629 static uint32
CreateXML(void)
11631 struct Include
*inc
;
11636 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11637 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11638 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11639 ShortBaseName
, BaseName
, GetLibraryName());
11640 basetypelib
= GetBaseTypeLib();
11641 if(basetypelib
&& (strcmp(basetypelib
, "Library") != 0))
11642 DoOutput(" basetype=\"%s\"", basetypelib
);
11644 for(inc
= (struct Include
*) Includes
.First
; inc
;
11645 inc
= (struct Include
*) inc
->List
.Next
)
11646 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc
->Include
)-2),
11648 if(!Includes
.First
)
11649 DoOutput("\t<include>exec/types.h</include>\n");
11651 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11652 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11653 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11655 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11656 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11657 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11658 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11659 " status=\"unimplemented\"/>\n");
11661 CallFunc(TAGMODE_BOTH
, 0, FuncXML
);
11663 return DoOutput("\t</interface>\n</library>\n");
11666 static uint32
CreateOS4PPC(uint32 callmode
)
11668 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11673 DoOutputDirect(HEADER
, headersize
);
11679 "#include <stdarg.h>\n"
11680 "#include <exec/types.h>\n"
11681 "#include <exec/interfaces.h>\n"
11682 "#include <exec/emulation.h>\n"
11683 "#include <interfaces/exec.h>\n");
11685 if(!stricmp("exec",ShortBaseName
))
11686 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName
);
11688 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName
);
11690 CallFunc(callmode
, "\n/%s */\n\n", FuncOS4PPC
);
11693 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11694 " return Self->Data.RefCount++;\n}\n\n"
11695 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11696 " return Self->Data.RefCount--;\n}\n\n"
11697 "#define LIBNAME \"%s\"\n"
11698 "#define LIBVERSION 0\n"
11699 "#define IFACENAME \"%s.main\"\n\n",
11700 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11701 GetLibraryName(), GetLibraryName());
11703 /* following text is constant */
11705 "static void InitFunction(APTR dummy, ULONG SegList, "
11706 "struct ExecBase *ExecBase)\n{\n"
11707 " struct Library *LibBase;\n"
11708 " struct ExecIFace *IExec = (struct ExecIFace *)"
11709 "ExecBase->MainInterface;\n"
11710 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11712 " struct Interface *NewInterface;\n"
11713 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11714 " MIT_VectorTable, main_vectors,\n"
11715 " MIT_Version, 1,\n"
11716 " MIT_Name, IFACENAME,\n"
11719 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11720 " IExec->AddInterface(LibBase, NewInterface);\n"
11724 "volatile static struct Resident MyResident =\n{\n"
11725 " RTC_MATCHWORD,\n"
11726 " (struct Resident *)&MyResident,\n"
11727 " (APTR)(&MyResident+1),\n"
11736 "void _start(void)\n"
11737 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11741 static uint32
CreateOS4M68K(void)
11743 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11748 DoOutputDirect(HEADER
, headersize
);
11751 "#include \"exec/interfaces.i\"\n"
11752 "#include \"exec/libraries.i\"\n"
11753 "#include \"exec/emulation.i\"\n"
11754 "#include \"interfaces/%s.i\"\n\n",ShortBaseName
);
11757 "\t.section .data\n"
11758 "\t.globl\tstub_Open\n"
11759 "\t.type\tstub_Open,@function\n"
11762 "\t.short\t0x4ef8\n" /* JMP.w */
11763 "\t.short\t0\n" /* Indicate switch */
11764 "\t.short\t1\n" /* Trap type */
11765 "\t.globl\tstub_OpenPPC\n"
11766 "\t.long\tstub_OpenPPC\n"
11767 "\t.byte\t2\n" /* Register mapping */
11768 "\t.byte\t1,REG68K_A7\n"
11769 "\t.byte\t3,REG68K_A6\n"
11770 "\t.section .text\n"
11774 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11775 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11776 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11777 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11778 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11779 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11780 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11781 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11782 "\tCallLib\tlmi_Open\n"
11783 "\tlwz\t%s11,%s12(%s1)\n"
11785 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11786 "\tblrl\n" /* Return to emulation */
11788 "\t.globl\tstub_Open68K\n"
11789 "\t.long\tstub_Open68K\n"
11790 "\t.byte\t0\n" /* Flags */
11791 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11792 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11793 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11794 "\t.section .data\n"
11798 "\t.short\t0x4e75\n" /* RTS */
11800 "\t.section .data\n"
11801 "\t.globl\tstub_Close\n"
11802 "\t.type\tstub_Close,@function\n"
11805 "\t.short\t0x4ef8\n" /* JMP.w */
11806 "\t.short\t0\n" /* Indicate switch */
11807 "\t.short\t1\n" /* Trap type */
11808 "\t.globl\tstub_ClosePPC\n"
11809 "\t.long\tstub_ClosePPC\n"
11810 "\t.byte\t2\n" /* Register mapping */
11811 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11812 "\t.byte\t3,REG68K_A6\n"
11813 "\t.section .text\n"
11817 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11818 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11819 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11820 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11821 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11822 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11823 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11824 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11825 "\tCallLib\tlmi_Close\n"
11826 "\tlwz\t%s11,12(%s1)\n"
11828 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11829 "\tblrl\n" /* Return to emulation */
11831 "\t.globl\tstub_Close68K\n"
11832 "\t.long\tstub_Close68K\n"
11833 "\t.byte\t0\n" /* Flags */
11834 "\t.byte\t1\n" /* One register (a7 only) */
11835 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11836 "\t.section .data\n"
11840 "\t.short\t0x4e75\n" /* RTS */
11842 "\t.section .data\n"
11843 "\t.globl\tstub_Expunge\n"
11844 "\t.type\tstub_Expunge,@function\n"
11847 "\t.short\t0x7000\n" /* moveq #0, d0 */
11848 "\t.short\t0x4e75\n" /* RTS */
11850 "\t.section .data\n"
11851 "\t.globl\tstub_Reserved\n"
11852 "\t.type\tstub_Reserved,@function\n"
11855 "\t.short\t0x7000\n" /* moveq #0, d0 */
11856 "\t.short\t0x4e75\n\n", /* RTS */
11857 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11858 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11859 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11860 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11861 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11862 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11863 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11864 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11865 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
11867 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68K
);
11869 "\t.globl\tVector68K\n"
11870 "\t.globl\tVecTable68K\n"
11872 "\t.long\tVecTable68K\n"
11874 "\t.long\tstub_Open\n"
11875 "\t.long\tstub_Close\n"
11876 "\t.long\tstub_Expunge\n"
11877 "\t.long\tstub_Reserved\n");
11880 CallFunc(TAGMODE_NORMAL
, 0, FuncOS4M68KVect
);
11881 DoOutput("\t.long\t-1\n");
11883 CloseDest(filename
);
11885 if(Flags2
& FLAG2_OS4M68KCSTUB
)
11887 sprintf(filename
, "%s_68k.c", ShortBaseName
);
11888 if(!OpenDest(filename
))
11890 Flags
&= ~(FLAG_DONE
);
11891 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11896 DoOutputDirect(HEADER
, headersize
);
11900 "#ifdef __USE_INLINE__\n"
11901 "#undef __USE_INLINE__\n"
11903 "#ifndef __NOGLOBALIFACE__\n"
11904 "#define __NOGLOBALIFACE__\n"
11906 "#include <exec/interfaces.h>\n"
11907 "#include <exec/libraries.h>\n"
11908 "#include <exec/emulation.h>\n"
11909 "#include <interfaces/exec.h>\n"
11910 "#include <interfaces/%s.h>\n"
11911 "#include <proto/%s.h>\n\n", ShortBaseName
, ShortBaseName
);
11913 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68KCSTUB
);
11915 return Output_Error
;
11918 /* ------------------------------------------------------------------ */
11920 static uint32
GetName(struct NameList
*t
, struct ShortListRoot
*p
, uint32 args
)
11922 struct NameList
*p2
= (struct NameList
*) p
->First
;
11923 struct AmiPragma ap
;
11924 memset(&ap
, 0, sizeof(struct AmiPragma
));
11925 ap
.FuncName
= t
->NormName
;
11928 ap
.Args
[0].ArgName
= (args
? "args" : "tags");
11929 if(!MakeTagFunction(&ap
))
11935 while(p2
&& (!p2
->PragName
|| strcmp(p2
->PragName
, ap
.TagName
)))
11936 p2
= (struct NameList
*) p2
->List
.Next
;
11941 t
->Type
= (args
? NTP_ARGS
: NTP_TAGS
);
11942 t
->PragName
= ap
.TagName
;
11943 RemoveItem(p
, (struct ShortList
*) p2
);
11946 printf("GetName: name matches - %s _ %s\n", t
->NormName
, t
->PragName
);
11952 static void OptimizeFDData(struct PragData
*pd
)
11955 printf("OptimizeFDData\n");
11960 if(pd
->NumNames
> 1)
11962 struct ShortListRoot n
= {0,0,0}, p
= {0,0,0};
11963 struct NameList
*t
;
11964 while(pd
->Name
.First
) /* sorts in AmiCall and TagCall */
11966 t
= (struct NameList
*) pd
->Name
.First
;
11968 RemoveItem(&pd
->Name
, (struct ShortList
*) t
);
11969 AddItem(t
->PragName
? &p
: &n
, (struct ShortList
*) t
);
11974 t
= (struct NameList
*) n
.First
;
11975 while(p
.First
&& t
)
11977 if(!GetName(t
, &p
, 0))
11983 struct NameList
*t2
= (struct NameList
*) t
->List
.Next
;
11984 RemoveItem(&n
, (struct ShortList
*)t
);
11985 AddItem(&pd
->Name
, (struct ShortList
*) t
);
11989 t
= (struct NameList
*) t
->List
.Next
;
11995 t
= (struct NameList
*) n
.First
;
11996 t
->PragName
= ((struct NameList
*)(p
.First
))->PragName
;
11997 RemoveItem(&n
, (struct ShortList
*) t
);
11999 printf("OptimizeFDData: names together - %s _ %s\n", t
->NormName
, t
->PragName
);
12001 t
->Type
= NTP_UNKNOWN
;
12007 t
= (struct NameList
*) p
.First
;
12008 i
= strlen(t
->PragName
);
12009 t
->NormName
= DupString(t
->PragName
, i
+1);
12010 t
->NormName
[i
++] = 'A';
12011 t
->NormName
[i
] = 0;
12012 t
->Type
= NTP_TAGS
;
12014 printf("OptimizeFDData: NormName created - %s _ %s\n", t
->NormName
, t
->PragName
);
12018 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12019 RemoveItem(&p
, p
.First
);
12023 AddItem(&pd
->Name
, n
.First
); /* add left NormNames */
12025 pd
= (struct PragData
*) pd
->List
.Next
;
12029 static uint32
MakeFD(struct PragList
*pl
)
12031 struct PragData
*pd
= (struct PragData
*) pl
->Data
.First
;
12035 printf("MakeFD\n");
12039 OptimizeFDData(pd
);
12041 printf("MakeFD: after Optimizing\n");
12043 DoOutput("##base _%s\n##bias %ld\n##public\n", pl
->Basename
, bias
);
12045 while(pd
&& Output_Error
)
12047 struct NameList
*n
= (struct NameList
*) pd
->Name
.First
;
12049 if(bias
!= pd
->Bias
)
12050 DoOutput("##bias %ld\n", (bias
= pd
->Bias
));
12054 strptr lastpar
= "last";
12057 if(n
->Type
== NTP_TAGS
)
12059 else if(n
->Type
== NTP_ARGS
)
12062 DoOutput("%s("/*)*/,n
->NormName
);
12064 DoOutput(/*(*/")()\n");
12067 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12068 DoOutput("par%ld,",i
+1);
12069 DoOutput(/*(*/"%s)("/*)*/, lastpar
);
12070 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12071 DoOutput("%s,", RegNames
[pd
->ArgReg
[i
]]);
12072 DoOutput(/*(*/"%s)\n", RegNames
[pd
->ArgReg
[i
]]);
12074 if(n
->Type
== NTP_UNKNOWN
)
12077 for(i
= 0; n
->NormName
[i
] == n
->PragName
[i
]; ++i
)
12079 DoOutput("*tagcall");
12081 DoOutput("-%s", n
->NormName
+i
);
12083 DoOutput("+%s", n
->PragName
+i
);
12088 if((n
= (struct NameList
*) n
->List
.Next
))
12089 DoOutput("##bias %ld\n", pd
->Bias
);
12090 Flags
|= FLAG_DONE
;
12093 pd
= (struct PragData
*)pd
->List
.Next
; bias
+= BIAS_OFFSET
;
12096 DoOutput("##end\n");
12098 return Output_Error
;
12101 static uint32
AddFDData(struct ShortListRoot
*pls
, struct FDData
*fd
)
12103 struct NameList
*t
;
12104 struct PragList
*pl
= (struct PragList
*) pls
->First
;
12105 struct PragData
*pd
;
12107 while(pl
&& strcmp(pl
->Basename
, fd
->Basename
))
12108 pl
= (struct PragList
*) pl
->List
.Next
;
12113 printf("AddFDData: New PragList - %s\n", fd
->Basename
);
12115 if(!(pl
= (struct PragList
*) NewItem(pls
)))
12117 pl
->Basename
= fd
->Basename
;
12118 pl
->Data
.Size
= sizeof(struct PragData
);
12119 AddItem(pls
, (struct ShortList
*) pl
);
12122 if((pd
= (struct PragData
*) pl
->Data
.First
))
12124 while(pd
->List
.Next
&& ((struct PragData
*) pd
->List
.Next
)->Bias
12126 pd
= (struct PragData
*) pd
->List
.Next
;
12129 if(!pd
|| pd
->Bias
!= fd
->Bias
)
12131 struct PragData
*pd2
;
12133 printf("AddFDData: New PragData - %ld, %ld\n", fd
->Bias
, fd
->NumArgs
);
12135 if(!(pd2
= (struct PragData
*) NewItem(&pl
->Data
)))
12137 pd2
->Bias
= fd
->Bias
;
12138 memcpy(pd2
->ArgReg
, fd
->ArgReg
, MAXREG
);
12139 pd2
->NumArgs
= fd
->NumArgs
;
12140 pd2
->Name
.Size
= sizeof(struct NameList
);
12142 AddItem(&pl
->Data
, (struct ShortList
*) pd2
);
12143 else if(pd
->Bias
> fd
->Bias
) /* Insert at start */
12145 pd2
->List
.Next
= pl
->Data
.First
;
12146 pl
->Data
.First
= (struct ShortList
*) pd2
;
12148 else /* Insert the entry */
12150 pd2
->List
.Next
= pd
->List
.Next
;
12151 pd
->List
.Next
= (struct ShortList
*) pd2
;
12157 uint32 i
= fd
->NumArgs
;
12158 if(fd
->NumArgs
!= pd
->NumArgs
)
12161 printf("ArgNum %ld != %ld\n", fd
->NumArgs
, pd
->NumArgs
);
12163 return ERR_DIFFERENT_TO_PREVIOUS
;
12168 if(fd
->ArgReg
[i
] != pd
->ArgReg
[i
])
12171 printf("ArgReg %x != %x\n", fd
->ArgReg
[i
], pd
->ArgReg
[i
]);
12173 return ERR_DIFFERENT_TO_PREVIOUS
;
12178 t
= (struct NameList
*) pd
->Name
.First
; /* skips same names */
12179 while(t
&& (!(fd
->Mode
? t
->PragName
: t
->NormName
) ||
12180 strcmp(fd
->Name
, fd
->Mode
? t
->PragName
: t
->NormName
)))
12181 t
= (struct NameList
*) t
->List
.Next
;
12186 if(!(t
= (struct NameList
*) NewItem(&pd
->Name
)))
12189 t
->PragName
= fd
->Name
;
12191 t
->NormName
= fd
->Name
;
12192 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12195 printf("AddFDData: New NameList - %s\n", fd
->Name
);
12200 static string
GetHexValue(string data
)
12203 return (string
) (data
- 'a' + 10);
12204 else if(data
>= 'A')
12205 return (string
) (data
- 'A' + 10);
12207 return (string
) (data
- '0');
12210 static string
GetDoubleHexValue(strptr data
)
12212 return (string
)((GetHexValue(*data
)<<4)+GetHexValue(data
[1]));
12215 static uint32
GetLibData(struct FDData
*fd
)
12218 fd
->Name
= SkipBlanks(in
.pos
);
12219 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12220 in
.pos
= SkipBlanks(in
.pos
);
12221 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12222 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
)));
12223 if((fd
->NumArgs
= GetHexValue(*(--in
.pos
))) > MAXREGNF
- 2)
12224 return ERR_TO_MUCH_ARGUMENTS
;
12225 --in
.pos
; /* skips return register */
12226 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12228 if((fd
->ArgReg
[i
] = GetHexValue(*(--in
.pos
))) > REG_A5
)
12229 return ERR_EXPECTED_REGISTER_NAME
;
12234 static uint32
GetFlibData(struct FDData
*fd
)
12237 fd
->Name
= SkipBlanks(in
.pos
);
12238 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12239 in
.pos
= SkipBlanks(in
.pos
);
12240 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12241 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
))) - 2;
12242 if((fd
->NumArgs
= GetDoubleHexValue(in
.pos
)) > MAXREG
-2)
12243 return ERR_TO_MUCH_ARGUMENTS
;
12244 in
.pos
-= 2; /* skips return register */
12245 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12248 if((fd
->ArgReg
[i
] = GetDoubleHexValue(in
.pos
)) >= MAXREG
)
12249 return ERR_EXPECTED_REGISTER_NAME
;
12250 else if(fd
->ArgReg
[i
] >= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12251 return ERR_FLOATARG_NOT_ALLOWED
;
12256 static uint32
GetAmiData(struct FDData
*fd
)
12259 in
.pos
= SkipBlanks(in
.pos
);
12260 if(*in
.pos
!= '('/*)*/)
12261 return ERR_EXPECTED_OPEN_BRACKET
;
12262 fd
->Basename
= ++in
.pos
;
12263 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12265 return ERR_EXPECTED_COMMA
;
12267 in
.pos
= SkipBlanks(++in
.pos
);
12268 if(!strncmp(in
.pos
, "0x", 2))
12269 fd
->Bias
= strtoul(in
.pos
+2, 0, 16);
12271 fd
->Bias
= strtoul(in
.pos
, 0, 10);
12273 in
.pos
= SkipBlanks(SkipName(in
.pos
));
12275 return ERR_EXPECTED_COMMA
;
12276 fd
->Name
= in
.pos
= SkipBlanks(++in
.pos
);
12277 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12278 if(*in
.pos
!= '('/*)*/)
12279 return ERR_EXPECTED_OPEN_BRACKET
;
12281 in
.pos
= SkipBlanks(++in
.pos
);
12282 if(*in
.pos
== /*(*/')')
12285 while(*in
.pos
!= /*(*/')')
12288 in
.pos
= SkipBlanks(in
.pos
+1);
12290 for(i
= 0; i
< REG_FP0
; i
++)
12291 if(!strnicmp(RegNames
[i
], in
.pos
, 2))
12295 for(; i
< MAXREG
; i
++)
12296 if(!strnicmp(RegNames
[i
], in
.pos
, 3))
12301 return ERR_EXPECTED_REGISTER_NAME
;
12302 else if(i
>= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12303 return ERR_FLOATARG_NOT_ALLOWED
;
12305 fd
->ArgReg
[fd
->NumArgs
] = i
; ++fd
->NumArgs
;
12307 if(fd
->NumArgs
> MAXREG
-2)
12308 return ERR_TO_MUCH_ARGUMENTS
;
12310 in
.pos
= SkipBlanks(in
.pos
+(i
>= REG_FP0
? 3 : 2));
12312 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
12313 return ERR_EXPECTED_CLOSE_BRACKET
;
12315 in
.pos
= SkipBlanks(in
.pos
+1);
12316 if(*in
.pos
!= /*(*/')')
12317 return ERR_EXPECTED_CLOSE_BRACKET
;
12321 static uint32
CreateFDFile(void)
12323 struct ShortListRoot pl
= {0, 0, sizeof(struct PragList
)};
12324 uint32 linenum
, err
= 0, skip
;
12327 ptr
= p2
= args
.infile
;
12330 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
12334 for(p2
= ptr
; *p2
&& *p2
!= '_' && *p2
!= '.'; ++p2
)
12338 ShortBaseName
= ptr
;
12342 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
12344 in
.pos
= SkipBlanks(in
.pos
);
12345 if(!strncmp("#pragma", in
.pos
, 7))
12350 memset(&fd
, 0, sizeof(struct FDData
));
12352 in
.pos
= SkipBlanks(in
.pos
+7);
12353 if(!strncmp("tagcall", in
.pos
, 7))
12356 in
.pos
= SkipBlanks(in
.pos
+7);
12357 if(*in
.pos
== '(' /*)*/) /* Storm method */
12358 err
= GetAmiData(&fd
);
12359 else /* SAS method */
12361 fd
.Basename
= in
.pos
;
12362 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12363 err
= GetLibData(&fd
);
12366 else if(!strncmp("amicall", in
.pos
, 7)) /* Storm method */
12369 err
= GetAmiData(&fd
);
12371 else if(!strncmp("libcall", in
.pos
, 7)) /* SAS method */
12373 fd
.Basename
= SkipBlanks(in
.pos
+7);
12374 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12375 err
= GetLibData(&fd
);
12377 else if(!strncmp("flibcall", in
.pos
, 8)) /* SAS method */
12379 fd
.Basename
= SkipBlanks(in
.pos
+8);
12380 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12381 err
= GetFlibData(&fd
);
12383 else if(!strncmp("syscall", in
.pos
, 7)) /* SAS method */
12385 fd
.Basename
= "SysBase";
12386 err
= GetLibData(&fd
);
12392 DoError(err
, linenum
);
12395 else if((err
= AddFDData(&pl
, &fd
)))
12398 DoError(err
, linenum
);
12402 while(*(in
.pos
++)) /* jumps to first char of next line */
12408 struct PragList
*p
= (struct PragList
*) pl
.First
;
12416 text
= ShortBaseName
; i
= strlen(text
);
12420 text
= p
->Basename
; i
= strlen(text
)-4;
12423 to
= DupString(text
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12424 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12439 i
= strlen(p
->Basename
) - 4;
12440 to
= DupString(p
->Basename
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12441 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12448 p
= (struct PragList
*) p
->List
.Next
;
12456 #ifdef FD2PRAGMA_READARGS
12457 #include <proto/dos.h>
12459 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12460 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12461 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12462 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12463 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12465 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12466 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12467 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12468 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12496 uint32 NOPPCREGNAME
;
12507 uint32 SYSTEMRELEASE
;
12512 static const strptr helptext
=
12513 "INFILE: the input file which should be used\n"
12514 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12515 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12516 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12517 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12518 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12519 "\t 6 - pragma for all compilers [default]\n"
12520 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12521 "\t10 - stub-functions for C - C text\n"
12522 "\t11 - stub-functions for C - assembler text\n"
12523 "\t12 - stub-functions for C - link library\n"
12524 "\t13 - defines and link library for local library base (register call)\n"
12525 "\t14 - defines and link library for local library base (stack call)\n"
12526 "\t15 - stub-functions for Pascal - assembler text\n"
12527 "\t16 - stub-functions for Pascal - link library\n"
12528 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12529 "\t18 - module for AmigaE\n"
12530 "\t20 - assembler lvo _lvo.i file\n"
12531 "\t21 - assembler lvo _lib.i file\n"
12532 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12533 "\t23 - assembler lvo _lib.i file no XDEF\n"
12534 "\t24 - assembler lvo link library\n"
12535 "\t30 - proto file with pragma/..._lib.h call\n"
12536 "\t31 - proto file with pragma/..._pragmas.h call\n"
12537 "\t32 - proto file with pragmas/..._lib.h call\n"
12538 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12539 "\t34 - proto file with local/..._loc.h call\n"
12540 "\t35 - proto file for all compilers (VBCC stubs)\n"
12541 "\t36 - proto file for GNU-C compiler only\n"
12542 "\t37 - proto file without lib definitions\n"
12543 "\t38 - proto file for all compilers (VBCC inline)\n"
12544 "\t39 - proto file with special PPC related checks\n"
12545 "\t40 - GCC inline file (preprocessor based)\n"
12546 "\t41 - GCC inline file (old type - inline based)\n"
12547 "\t42 - GCC inline file (library stubs)\n"
12548 "\t43 - GCC inline file (new style - macro)\n"
12549 "\t44 - GCC inline file (new style - inline)\n"
12550 "\t45 - GCC inline file (new style - inline with include lines)\n"
12551 "\t46 - GCC inline file (preprocessor based, direct)\n"
12552 "\t47 - GCC inline file (new style, direct)\n"
12553 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12554 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12555 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12556 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12557 "\t53 - SAS-C include file for PowerUP\n"
12558 "\t54 - Proto file for PowerUP\n"
12559 "\t60 - FPC pascal unit text\n"
12560 "\t70 - VBCC inline files\n"
12561 "\t71 - VBCC WOS stub-functions - assembler text\n"
12562 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12563 "\t73 - VBCC WOS stub-functions - link library\n"
12564 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12565 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12566 "\t76 - VBCC PowerUP stub-functions - link library\n"
12567 "\t77 - VBCC WOS inline files\n"
12568 "\t78 - VBCC MorphOS stub-functions - link library\n"
12569 "\t79 - VBCC old inline files\n"
12570 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12571 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12572 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12573 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12574 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12575 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12576 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12577 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12578 " 100 - PPC assembler lvo file\n"
12579 " 101 - PPC assembler lvo file no XDEF\n"
12580 " 102 - PPC assembler lvo ELF link library\n"
12581 " 103 - PPC assembler lvo EHF link library\n"
12582 " 104 - PPC V.4-ABI assembler file\n"
12583 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12584 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12585 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12587 " 111 - CLIB file\n"
12588 " 112 - SFD file\n"
12589 " 120 - VBCC auto libopen files (C source)\n"
12590 " 121 - VBCC auto libopen files (m68k link library)\n"
12591 " 122 - VBCC MorphOS inline files\n"
12592 " 123 - VBCC new MorphOS inline files\n"
12593 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12594 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12595 " 132 - GCC inline files for MorphOS (library stubs)\n"
12596 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12597 " 134 - MorphOS gate stubs\n"
12598 " 135 - MorphOS gate stubs (prelib)\n"
12599 " 136 - MorphOS gate stubs (postlib)\n"
12600 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12601 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12602 " 140 - OS4 XML file\n"
12603 " 141 - OS4 PPC->M68K cross-call stubs\n"
12604 " 142 - OS4 M68K->PPC cross-call stubs\n"
12605 " 200 - FD file (source is a pragma file!)\n"
12606 "MODE: SPECIAL 1-7:\n"
12607 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12608 " 2: _PRAGMAS_..._LIB_H definition method\n"
12609 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12610 " 4: no definition\n"
12611 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12613 " 1: all functions, normal interface\n"
12614 " 2: only tag-functions, tagcall interface\n"
12615 " 3: all functions, normal and tagcall interface [default]\n"
12616 "TO: the destination directory (self creation of filename)\n"
12617 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12618 "CLIB: name of the prototypes file in clib directory\n"
12619 "COPYRIGHT: the copyright text for CLIB files\n"
12620 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12621 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12622 "BASENAME: name of library base without '_'\n"
12623 "LIBNAME: name of the library (.e.g. dos.library)\n"
12624 "LIBTYPE: type of base library structure\n"
12625 "PRIORITY: priority for auto open files\n"
12626 "PREFIX: MorphOS gate prefix\n"
12627 "SUBPREFIX: MorphOS gate sub prefix\n"
12628 "PREMACRO: MorphOS gate file start macro\n"
12630 "AUTOHEADER add the typical automatic generated header\n"
12631 "COMMENT: copy comments found in input file\n"
12632 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12633 "FPUONLY: work only with functions using FPU register arguments\n"
12634 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12635 "NOFPU: disable usage of FPU register arguments\n"
12636 "NOPPC: disable usage of PPC-ABI functions\n"
12637 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12638 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12639 "ONLYCNAMES: do not create C++ or ASM names\n"
12640 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12641 "PPCONLY: only use PPC-ABI functions\n"
12642 "PRIVATE: includes private declared functions\n"
12643 "SECTION: add section statements to asm texts\n"
12644 "SMALLCODE: generate small code link libraries or assembler text\n"
12645 "SMALLDATA: generate small data link libraries or assembler text\n"
12646 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12647 "SORTED: sort generated files by name and not by bias value\n"
12648 "SYSTEMRELEASE: special handling of comments for system includes\n"
12649 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12650 "VOIDBASE: library bases are of type void *\n";
12652 /* print the help text */
12653 static void printhelp(void)
12655 printf("%s\n%s\n\n%s", version
+6, PARAM
, helptext
);
12659 /* initializes the arguments and starts argument parsing */
12660 static void GetArgs(int argc
, char **argv
)
12662 struct RDArgs
*rda
;
12663 struct AmiArg amiargs
;
12666 if((rda
= (struct RDArgs
*) AllocDosObject(DOS_RDARGS
, 0)))
12668 rda
->RDA_ExtHelp
= helptext
;
12669 memset(&amiargs
, 0, sizeof(struct AmiArg
));
12670 if(ReadArgs(PARAM
, (int32
*) &amiargs
, rda
))
12675 l
= strlen(amiargs
.TO
? amiargs
.TO
: "") + 1
12676 + strlen(amiargs
.CLIB
? amiargs
.CLIB
: "") + 1
12677 + strlen(amiargs
.HEADER
? amiargs
.HEADER
: "") + 1
12678 + strlen(amiargs
.ABI
? amiargs
.ABI
: "") + 1
12679 + strlen(amiargs
.HUNKNAME
? amiargs
.HUNKNAME
: "") + 1
12680 + strlen(amiargs
.BASENAME
? amiargs
.BASENAME
: "") + 1
12681 + strlen(amiargs
.LIBTYPE
? amiargs
.LIBTYPE
: "") + 1
12682 + strlen(amiargs
.LIBNAME
? amiargs
.LIBNAME
: "") + 1
12683 + strlen(amiargs
.COPYRIGHT
? amiargs
.COPYRIGHT
: "") + 1
12684 + strlen(amiargs
.PREFIX
? amiargs
.PREFIX
: "") + 1
12685 + strlen(amiargs
.SUBPREFIX
? amiargs
.SUBPREFIX
: "") + 1
12686 + strlen(amiargs
.PREMACRO
? amiargs
.PREMACRO
: "") + 1
12687 + strlen(amiargs
.INFILE
) + 1;
12688 if((d
= AllocListMem(l
)))
12692 s
= amiargs
.INFILE
;
12693 args
.infile
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12694 if((s
= amiargs
.TO
))
12696 args
.to
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12698 if((s
= amiargs
.HEADER
))
12700 args
.header
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12702 if((s
= amiargs
.CLIB
))
12704 args
.clib
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12706 if((s
= amiargs
.HUNKNAME
))
12708 hunkname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12710 if((s
= amiargs
.BASENAME
))
12712 Flags
|= FLAG_BASENAME
;
12713 BaseName
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12715 if((s
= amiargs
.LIBTYPE
))
12717 Flags2
|= FLAG2_LIBTYPE
;
12718 libtype
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12720 if((s
= amiargs
.LIBNAME
))
12722 Flags2
|= FLAG2_LIBNAME
;
12723 libname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12725 if((s
= amiargs
.PREFIX
))
12727 prefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12729 if((s
= amiargs
.SUBPREFIX
))
12731 subprefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12733 if((s
= amiargs
.PREMACRO
))
12735 premacro
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12737 if((s
= amiargs
.COPYRIGHT
))
12739 Copyright
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12741 if((s
= amiargs
.ABI
))
12743 defabi
= d
; while(*s
) *(d
++) = *(s
++); *d
= 0;
12745 if(amiargs
.EXTERNC
) Flags
^= FLAG_EXTERNC
;
12746 if(amiargs
.PRIVATE
) Flags
^= FLAG_PRIVATE
;
12747 if(amiargs
.NEWSYNTAX
) Flags
^= FLAG_NEWSYNTAX
;
12748 if(amiargs
.SMALLDATA
) Flags
^= FLAG_SMALLDATA
;
12749 if(amiargs
.SMALLCODE
) Flags2
^= FLAG2_SMALLCODE
;
12750 if(amiargs
.SMALLTYPES
) Flags2
^= FLAG2_SMALLTYPES
;
12751 if(amiargs
.USESYSCALL
) Flags
^= FLAG_SYSCALL
;
12752 if(amiargs
.OPT040
) Flags
^= FLAG_NOMOVEM
;
12753 if(amiargs
.NOFPU
) Flags
^= FLAG_NOFPU
;
12754 if(amiargs
.FPUONLY
) Flags
^= FLAG_FPUONLY
;
12755 if(amiargs
.NOPPC
) Flags
^= FLAG_NOPPC
;
12756 if(amiargs
.NOSYMBOL
) Flags
^= FLAG_NOSYMBOL
;
12757 if(amiargs
.PPCONLY
) Flags
^= FLAG_PPCONLY
;
12758 if(amiargs
.SECTION
) Flags
^= FLAG_ASMSECTION
;
12759 if(amiargs
.COMMENT
) Flags
^= FLAG_DOCOMMENT
;
12760 if(amiargs
.SORTED
) Flags
^= FLAG_SORTED
;
12761 if(amiargs
.ONLYCNAMES
) Flags
^= FLAG_ONLYCNAMES
;
12762 if(amiargs
.SYSTEMRELEASE
) Flags2
^= FLAG2_SYSTEMRELEASE
;
12763 if(amiargs
.VOIDBASE
) Flags2
^= FLAG2_VOIDBASE
;
12764 if(amiargs
.NOPPCREGNAME
) PPCRegPrefix
= "";
12765 if(amiargs
.AUTOHEADER
) Flags2
^= FLAG2_AUTOHEADER
;
12766 if(amiargs
.SPECIAL
)
12767 args
.special
= *amiargs
.SPECIAL
;
12769 args
.mode
= *amiargs
.MODE
;
12770 if(amiargs
.PRIORITY
)
12771 priority
= *amiargs
.PRIORITY
;
12776 PrintFault(IoErr(), 0);
12777 FreeDosObject(DOS_RDARGS
, rda
);
12786 static const strptr helptext
=
12788 " -i,--infile <input filename>\n"
12789 " -s,--special <number>\n"
12790 " -m,--mode <number>\n"
12791 " -t,--to <destination directory>\n"
12792 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12793 " -c,--clib <clib prototypes filename>\n"
12794 " -d,--header <header file or \"\">\n"
12795 " -i,--libname <name of library>\n"
12796 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12797 " -b,--basename <name of library base without '_'>\n"
12798 " -l,--libtype <name of base library type>\n"
12799 " -p,--priority <priority for auto open files>\n"
12800 " -r,--copyright<copyright text>\n"
12801 " --prefix <MorphOS gate prefix>\n"
12802 " --subprefix<MorphOS gate sub prefix>\n"
12803 " --premacro <MorphOS gate file start macro>\n"
12806 "--autoheader add the typical automatic generated header\n"
12807 "--comment copy comments found in input file\n"
12808 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12809 "--fpuonly work only with functions using FPU register arguments\n"
12810 "--newsyntax uses new Motorola syntax for asm files\n"
12811 "--nofpu disable usage of FPU register arguments\n"
12812 "--noppc disable usage of PPC-ABI functions\n"
12813 "--noppcregname do not add 'r' to PPC register names\n"
12814 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12815 "--onlycnames do not create C++ or ASM names\n"
12816 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12817 "--ppconly only use PPC-ABI functions\n"
12818 "--private includes private declared functions\n"
12819 "--section add section statements to asm texts\n"
12820 "--smallcode generate small code link libraries or assembler text\n"
12821 "--smalldata generate small data link libraries or assembler text\n"
12822 "--smalltypes allow 8 and 16 bit types in registers\n"
12823 "--sorted sort generated files by name and not by bias value\n"
12824 "--systemrelease special handling of comments for system includes\n"
12825 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12826 "--voidbase library bases are of type void *\n"
12828 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12829 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12830 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12831 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12832 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12833 " 6 - pragma for all compilers [default]\n"
12834 " 7 - all compilers with pragma to inline redirect for GCC\n"
12835 " 10 - stub-functions for C - C text\n"
12836 " 11 - stub-functions for C - assembler text\n"
12837 " 12 - stub-functions for C - link library\n"
12838 " 13 - defines and link library for local library base (register call)\n"
12839 " 14 - defines and link library for local library base (stack call)\n"
12840 " 15 - stub-functions for Pascal - assembler text\n"
12841 " 16 - stub-functions for Pascal - link library\n"
12842 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12843 " 18 - module for AmigaE\n"
12844 " 20 - assembler lvo _lvo.i file\n"
12845 " 21 - assembler lvo _lib.i file\n"
12846 " 22 - assembler lvo _lvo.i file no XDEF\n"
12847 " 23 - assembler lvo _lib.i file no XDEF\n"
12848 " 24 - assembler lvo link library\n"
12849 " 30 - proto file with pragma/..._lib.h call\n"
12850 " 31 - proto file with pragma/..._pragmas.h call\n"
12851 " 32 - proto file with pragmas/..._lib.h call\n"
12852 " 33 - proto file with pragmas/..._pragmas.h call\n"
12853 " 34 - proto file with local/..._loc.h call\n"
12854 " 35 - proto file for all compilers (VBCC stubs)\n"
12855 " 36 - proto file for GNU-C compiler only\n"
12856 " 37 - proto file without lib definitions\n"
12857 " 38 - proto file for all compilers (VBCC inline)\n"
12858 " 39 - proto file with special PPC related checks\n"
12859 " 40 - GCC inline file (preprocessor based)\n"
12860 " 41 - GCC inline file (old type - inline based)\n"
12861 " 42 - GCC inline file (library stubs)\n"
12862 " 43 - GCC inline file (new style - macro)\n"
12863 " 44 - GCC inline file (new style - inline)\n"
12864 " 45 - GCC inline file (new style - inline with include lines)\n"
12865 " 46 - GCC inline file (preprocessor based, direct)\n"
12866 " 47 - GCC inline file (new style, direct)\n"
12867 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12868 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12869 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12870 " 52 - GCC inline files for PowerUP (library stubs)\n"
12871 " 53 - SAS-C include file for PowerUP\n"
12872 " 54 - Proto file for PowerUP\n"
12873 " 60 - FPC pascal unit text\n"
12874 " 70 - VBCC inline files\n"
12875 " 71 - VBCC WOS stub-functions - assembler text\n"
12876 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12877 " 73 - VBCC WOS stub-functions - link library\n"
12878 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12879 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12880 " 76 - VBCC PowerUP stub-functions - link library\n"
12881 " 77 - VBCC WOS inline files\n"
12882 " 78 - VBCC MorphOS stub-functions - link library\n"
12883 " 79 - VBCC old inline files\n"
12884 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12885 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12886 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12887 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12888 " 90 - stub-functions for C - assembler text (multiple files)\n"
12889 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12890 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12891 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12892 " 100 - PPC assembler lvo file\n"
12893 " 101 - PPC assembler lvo file no XDEF\n"
12894 " 102 - PPC assembler lvo ELF link library\n"
12895 " 103 - PPC assembler lvo EHF link library\n"
12896 " 104 - PPC V.4-ABI assembler file\n"
12897 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12898 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12899 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12901 " 111 - CLIB file\n"
12902 " 112 - SFD file\n"
12903 " 120 - VBCC auto libopen files (C source)\n"
12904 " 121 - VBCC auto libopen files (m68k link library)\n"
12905 " 122 - VBCC MorphOS inline files\n"
12906 " 123 - VBCC new MorphOS inline files\n"
12907 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12908 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12909 " 132 - GCC inline files for MorphOS (library stubs)\n"
12910 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12911 " 134 - MorphOS gate stubs\n"
12912 " 135 - MorphOS gate stubs (prelib)\n"
12913 " 136 - MorphOS gate stubs (postlib)\n"
12914 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12915 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12916 " 140 - OS4 XML file\n"
12917 " 141 - OS4 PPC->M68K cross-call stubs\n"
12918 " 142 - OS4 M68K->PPC cross-call stubs\n"
12919 " 200 - FD file (source is a pragma file!)\n"
12920 "mode: special 1-7\n"
12921 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12922 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12923 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12924 " 4 - no definition\n"
12925 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12927 " 1 - all functions, normal interface\n"
12928 " 2 - only tag-functions, tagcall interface\n"
12929 " 3 - all functions, normal and tagcall interface [default]\n";
12931 /* print the help text */
12932 static void printhelp(void)
12934 printf("%s\n%s", version
+6, helptext
);
12947 ARG_HELP
, ARG_INFILE
, ARG_SPECIAL
, ARG_MODE
, ARG_TO
, ARG_CLIB
, ARG_ABI
, ARG_COPYRIGHT
,
12948 ARG_HEADER
, ARG_HUNKNAME
, ARG_BASENAME
, ARG_LIBTYPE
,
12949 ARG_COMMENT
, ARG_EXTERNC
, ARG_FPUONLY
, ARG_NEWSYNTAX
, ARG_NOFPU
, ARG_NOPPC
,
12950 ARG_NOSYMBOL
, ARG_ONLYCNAMES
, ARG_OPT040
, ARG_PPCONLY
, ARG_PRIVATE
, ARG_SECTION
,
12951 ARG_SMALLDATA
, ARG_SORTED
, ARG_USESYSCALL
, ARG_NOPPCREGNAME
,
12952 ARG_SYSTEMRELEASE
, ARG_PRIORITY
, ARG_LIBNAME
, ARG_SMALLCODE
, ARG_VOIDBASE
,
12953 ARG_PREFIX
, ARG_SUBPREFIX
, ARG_PREMACRO
, ARG_SMALLTYPES
, ARG_AUTOHEADER
12956 /* argument definition array */
12957 static const struct ArgData argtexts
[] = {
12958 {"help", 'h', 4, ARG_HELP
},
12959 {"infile", 'i', 6, ARG_INFILE
},
12960 {"special", 's', 7, ARG_SPECIAL
},
12961 {"mode", 'm', 4, ARG_MODE
},
12962 {"to", 't', 2, ARG_TO
},
12963 {"clib", 'c', 4, ARG_CLIB
},
12964 {"abi", 'a', 3, ARG_ABI
},
12965 {"copyright", 'r', 9, ARG_COPYRIGHT
},
12966 {"header", 'd', 6, ARG_HEADER
},
12967 {"hunkname", 'n', 8, ARG_HUNKNAME
},
12968 {"basename", 'b', 8, ARG_BASENAME
},
12969 {"libtype", 'l', 7, ARG_LIBTYPE
},
12970 {"libname", 'i', 7, ARG_LIBNAME
},
12971 {"priority", 'p', 8, ARG_PRIORITY
},
12972 {"autoheader", 0, 10, ARG_AUTOHEADER
},
12973 {"comment", 0, 7, ARG_COMMENT
},
12974 {"externc", 0, 7, ARG_EXTERNC
},
12975 {"fpuonly", 0, 7, ARG_FPUONLY
},
12976 {"newsyntax", 0, 9, ARG_NEWSYNTAX
},
12977 {"nofpu", 0, 5, ARG_NOFPU
},
12978 {"noppc", 0, 5, ARG_NOPPC
},
12979 {"noppcregname", 0, 12, ARG_NOPPCREGNAME
},
12980 {"nosymbol", 0, 8, ARG_NOSYMBOL
},
12981 {"onlycnames", 0, 10, ARG_ONLYCNAMES
},
12982 {"opt040", 0, 6, ARG_OPT040
},
12983 {"ppconly", 0, 7, ARG_PPCONLY
},
12984 {"private", 0, 7, ARG_PRIVATE
},
12985 {"section", 0, 7, ARG_SECTION
},
12986 {"smalldata", 0, 9, ARG_SMALLDATA
},
12987 {"smalltypes", 0, 10, ARG_SMALLTYPES
},
12988 {"smallcode", 0, 9, ARG_SMALLCODE
},
12989 {"sorted", 0, 6, ARG_SORTED
},
12990 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE
},
12991 {"usesyscall", 0, 10, ARG_USESYSCALL
},
12992 {"voidbase", 0, 8, ARG_VOIDBASE
},
12993 {"prefix", 0, 6, ARG_PREFIX
},
12994 {"subprefix", 0, 9, ARG_SUBPREFIX
},
12995 {"premacro", 0, 8, ARG_PREMACRO
},
12996 {0,0,0,0}, /* end marker */
12999 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
13000 static uint32
ParseArgEntry(uint32 argc
, strptr
*argv
)
13002 uint32 numentries
= 1, l
;
13004 const struct ArgData
*ad
;
13006 if((*argv
)[0] != '-' || !(*argv
)[1])
13012 if((*argv
)[1] == ad
->ArgChar
|| ((*argv
)[1] == '-' && !strncmp(ad
->ArgName
, (*argv
)+2, ad
->ArgNameLen
)))
13020 case ARG_HELP
: printhelp(); break;
13021 case ARG_EXTERNC
: Flags
^= FLAG_EXTERNC
; break;
13022 case ARG_PRIVATE
: Flags
^= FLAG_PRIVATE
; break;
13023 case ARG_NEWSYNTAX
: Flags
^= FLAG_NEWSYNTAX
; break;
13024 case ARG_SMALLDATA
: Flags
^= FLAG_SMALLDATA
; break;
13025 case ARG_SMALLCODE
: Flags2
^= FLAG2_SMALLCODE
; break;
13026 case ARG_SMALLTYPES
: Flags2
^= FLAG2_SMALLTYPES
; break;
13027 case ARG_USESYSCALL
: Flags
^= FLAG_SYSCALL
; break;
13028 case ARG_OPT040
: Flags
^= FLAG_NOMOVEM
; break;
13029 case ARG_NOFPU
: Flags
^= FLAG_NOFPU
; break;
13030 case ARG_FPUONLY
: Flags
^= FLAG_FPUONLY
; break;
13031 case ARG_NOPPC
: Flags
^= FLAG_NOPPC
; break;
13032 case ARG_NOSYMBOL
: Flags
^= FLAG_NOSYMBOL
; break;
13033 case ARG_PPCONLY
: Flags
^= FLAG_PPCONLY
; break;
13034 case ARG_SECTION
: Flags
^= FLAG_ASMSECTION
; break;
13035 case ARG_COMMENT
: Flags
^= FLAG_DOCOMMENT
; break;
13036 case ARG_SORTED
: Flags
^= FLAG_SORTED
; break;
13037 case ARG_ONLYCNAMES
: Flags
^= FLAG_ONLYCNAMES
; break;
13038 case ARG_SYSTEMRELEASE
: Flags2
^= FLAG2_SYSTEMRELEASE
; break;
13039 case ARG_VOIDBASE
: Flags2
^= FLAG2_VOIDBASE
; break;
13040 case ARG_AUTOHEADER
: Flags2
^= FLAG2_AUTOHEADER
; break;
13041 case ARG_NOPPCREGNAME
: PPCRegPrefix
= "";
13043 a
= *argv
+((*argv
)[1] == '-' ? ad
->ArgNameLen
+2 : 2);
13046 if(argc
> 1) { a
= argv
[1]; numentries
= 2; }
13047 else { a
= 0; numentries
= 0;}
13057 a
[--l
] = 0; /* remove second " */
13061 case ARG_INFILE
: args
.infile
= a
; break;
13062 case ARG_COPYRIGHT
: Copyright
= a
; break;
13063 case ARG_TO
: args
.to
= a
; break;
13064 case ARG_ABI
: defabi
= a
; break;
13065 case ARG_CLIB
: args
.clib
= a
; break;
13066 case ARG_HEADER
: args
.header
= a
; break;
13067 case ARG_HUNKNAME
: hunkname
= a
; break;
13068 case ARG_PREFIX
: prefix
= a
; break;
13069 case ARG_SUBPREFIX
: subprefix
= a
; break;
13070 case ARG_PREMACRO
: premacro
= a
; break;
13071 case ARG_LIBTYPE
: libtype
= a
; Flags2
|= FLAG2_LIBTYPE
; break;
13072 case ARG_LIBNAME
: libname
= a
; Flags2
|= FLAG2_LIBNAME
; break;
13073 case ARG_BASENAME
: BaseName
= a
; Flags
|= FLAG_BASENAME
; break;
13075 args
.special
= strtoul(a
, &b
, 10);
13080 priority
= strtoul(a
, &b
, 10);
13085 args
.mode
= strtoul(a
, &b
, 10);
13086 if(*b
|| args
.mode
< 1 || args
.mode
> 3)
13095 /* initializes the arguments and starts argument parsing */
13096 static void GetArgs(int argc
, char **argv
)
13101 while(i
< argc
&& res
)
13103 if((j
= ParseArgEntry(argc
-i
, argv
+i
)) < 1)
13108 if(!res
|| !args
.infile
)
13114 static strptr
mygetfile(strptr name
, size_t *len
)
13119 if((infile
= fopen(name
, "rb")))
13121 if(!fseek(infile
, 0, SEEK_END
))
13123 *len
= ftell(infile
);
13124 if(!fseek(infile
, 0, SEEK_SET
))
13126 if((ptr
= AllocListMem(*len
+1)))
13130 printf("mygetfile: '%s' size %d\n", name
, *len
);
13132 if(fread(ptr
, *len
, 1, infile
) != 1)
13142 int main(int argc
, char **argv
)
13144 uint32 mode
= 0, pragmode
= PRAGMODE_PRAGLIB
, callmode
= TAGMODE_BOTH
;
13145 strptr amicall
= 0, libcall
= 0, amitags
= 0, libtags
= 0;
13147 size_t clibsize
= 0;
13149 GetArgs(argc
, argv
);
13151 if((tempbuf
= (uint8
*) AllocListMem(TEMPSIZE
)))
13153 if(!(in
.pos
= in
.buf
= mygetfile(args
.infile
, &in
.size
)))
13155 if(args
.special
== 200)
13157 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13162 sprintf((strptr
)tempbuf
, "%s" SFDFILEEXTENSION
, args
.infile
);
13163 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13165 sprintf((strptr
)tempbuf
, "%s" FDFILEEXTENSION
, args
.infile
);
13166 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13168 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13172 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13175 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13178 printf("SourceFile: %s\n", args
.infile
);
13180 MakeLines(in
.pos
, in
.size
);
13182 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SORTED
)) /* is not possible to use both */
13184 DoError(ERR_SORTED_COMMENT
, 0);
13185 Flags
&= (~FLAG_SORTED
);
13188 if(args
.special
== 200)
13202 if(Flags2
& FLAG2_SFDMODE
)
13203 DoError(ERR_SFD_AND_CLIB
, 0);
13206 sprintf((strptr
)tempbuf
, "%s_protos.h", args
.clib
);
13207 if(!(clibbuf
= mygetfile(args
.clib
, &clibsize
)) && !(clibbuf
= mygetfile((strptr
)tempbuf
, &clibsize
)))
13209 DoError(ERR_OPEN_FILE
, 0, args
.clib
);
13212 ScanClibFile(clibbuf
, clibbuf
+clibsize
);
13216 if(!MakeShortBaseName())
13218 DoError(ERR_MISSING_SHORTBASENAME
, 0);
13222 /* WARN when requesting obsolete types! */
13223 switch(args
.special
)
13225 case 1: case 2: case 3: case 4: case 5: case 7:
13226 printf("You use obsolete data type %ld, better use type 6!\n", args
.special
);
13228 case 11: case 15: case 71: case 72: case 75:
13229 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13230 "link libraries!\n", args
.special
);
13232 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13233 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args
.special
);
13236 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13240 if(args
.special
< 10) /* the pragma area is up to 9 */
13242 mode
= MODUS_PRAGMA
;
13243 sprintf(filename
, "%s_lib.h", ShortBaseName
);
13245 switch(args
.special
)
13248 case 1: pragmode
= PRAGMODE_PRAGSLIB
; amicall
= ""; break;
13249 case 2: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13250 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= ""; break;
13251 case 3: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13252 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= "";
13253 libtags
= "def " TEXT_SAS_60
; break;
13254 case 4: amicall
= ""; break;
13255 case 5: amicall
= amitags
= ""; break;
13256 case 7: Flags
|= FLAG_GNUPRAG
; /* no break ! */
13257 case 6: amicall
= " defined(" TEXT_AZTEC
") || defined("
13258 TEXT_MAXON
") || defined(" TEXT_STORM
")";
13259 libcall
= " defined(" TEXT_DICE
") || defined(" TEXT_SAS
")";
13260 libtags
= "def " TEXT_SAS_60
; amitags
="def " TEXT_STORM
; break;
13261 default: mode
= MODUS_ERROR
; break;
13264 if(args
.mode
> 0 && args
.mode
< 5)
13265 pragmode
= args
.mode
;
13267 else if(args
.special
< 20) /* the misc area is up to 19 */
13269 if(args
.mode
> 0 && args
.mode
< 4)
13270 callmode
= args
.mode
- 1;
13271 switch(args
.special
)
13273 case 10: mode
= MODUS_CSTUB
;
13274 sprintf(filename
, "%s_cstub.h", ShortBaseName
); break;
13275 case 11: mode
= MODUS_STUBTEXT
;
13276 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13277 case 12: mode
= MODUS_STUBCODE
;
13278 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13279 case 13: Flags
|= FLAG_LOCALREG
; /* no break ! */
13280 case 14: mode
= MODUS_LOCALDATA
;
13281 sprintf(filename
, "%s_loc.h", ShortBaseName
); break;
13282 case 15: mode
= MODUS_STUBTEXT
; callmode
= TAGMODE_NORMAL
;
13283 Flags
^= FLAG_PASCAL
;
13284 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13285 case 16: mode
= MODUS_STUBCODE
; callmode
= TAGMODE_NORMAL
;
13286 Flags
^= FLAG_PASCAL
;
13287 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13288 case 17: mode
= MODUS_BMAP
; callmode
= TAGMODE_NORMAL
;
13289 sprintf(filename
, "%s.bmap", ShortBaseName
); break;
13290 case 18: mode
= MODUS_EMODULE
;
13291 sprintf(filename
, "%s.m", ShortBaseName
); break;
13292 default: mode
= MODUS_ERROR
; break;
13295 else if(args
.special
< 30) /* the lvo area is up to 29 */
13297 switch(args
.special
)
13299 case 20: case 22: mode
= MODUS_LVO
+args
.special
-20;
13300 sprintf(filename
, "%s_lvo.i", ShortBaseName
); break;
13301 case 21: case 23: mode
= MODUS_LVO
+args
.special
-20;
13302 sprintf(filename
, "%s_lib.i", ShortBaseName
); break;
13303 case 24: mode
= MODUS_LVOLIB
;
13304 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13305 default: mode
= MODUS_ERROR
; break;
13308 else if(args
.special
< 40) /* the proto area is up to 39 */
13310 if(args
.special
< 40)
13312 mode
= MODUS_PROTO
+args
.special
-30;
13313 sprintf(filename
, "%s.h", ShortBaseName
);
13316 mode
= MODUS_ERROR
;
13318 else if(args
.special
< 50) /* the inline area is up to 49 */
13320 if(args
.mode
> 0 && args
.mode
< 4)
13321 callmode
= args
.mode
- 1;
13323 switch(args
.special
)
13325 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13327 mode
= MODUS_INLINE
+args
.special
-40;
13328 sprintf(filename
, "%s.h", ShortBaseName
); break;
13330 Flags
|= FLAG_STORMGCC
;
13331 /* the same mode as for 46, but additional flag */
13332 mode
= MODUS_INLINE
+args
.special
-40-2;
13333 sprintf(filename
, "%s.h", ShortBaseName
); break;
13334 default: mode
= MODUS_ERROR
; break;
13337 else if(args
.special
< 60) /* the PowerUP area is up to 59 */
13339 if(args
.mode
> 0 && args
.mode
< 4)
13340 callmode
= args
.mode
- 1;
13342 switch(args
.special
)
13344 case 50: case 51: case 52: mode
= MODUS_INLINE
+args
.special
-50;
13345 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_POWERUP
;
13348 sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13349 mode
= MODUS_SASPOWER
; break;
13351 sprintf(filename
, "%s.h", ShortBaseName
);
13352 mode
= MODUS_PROTOPOWER
; break;
13353 default: mode
= MODUS_ERROR
; break;
13356 else if(args
.special
< 70) /* the PASCAL stuff */
13358 if(args
.special
== 60)
13360 mode
= MODUS_PASCAL
;
13361 sprintf(filename
, "%s.pas", ShortBaseName
);
13364 mode
= MODUS_ERROR
;
13366 else if(args
.special
< 80) /* the VBCC stuff */
13368 if(args
.mode
> 0 && args
.mode
< 4)
13369 callmode
= args
.mode
- 1;
13371 switch(args
.special
)
13373 case 70: mode
= MODUS_VBCCINLINE
;
13374 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13375 case 71: case 72: case 75:
13376 mode
= MODUS_VBCC
+args
.special
-71;
13377 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13379 mode
= MODUS_VBCC
+args
.special
-71;
13380 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13382 mode
= MODUS_VBCCPUPLIB
;
13383 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13384 case 77: mode
= MODUS_VBCCWOSINLINE
;
13385 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13386 case 78: mode
= MODUS_VBCCMORPHCODE
;
13387 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13388 case 79: mode
= MODUS_VBCCINLINE
;
13389 Flags2
|= FLAG2_OLDVBCC
;
13390 callmode
= TAGMODE_NORMAL
;
13391 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13392 default: mode
= MODUS_ERROR
; break;
13395 else if(args
.special
< 90) /* redirect stuff */
13397 mode
= MODUS_REDIRECT
;
13398 switch(args
.special
)
13400 case 80: sprintf(filename
, "%s_pragmas.h", ShortBaseName
); break;
13401 case 81: sprintf(filename
, "%s_lib.h", ShortBaseName
); break;
13402 case 82: sprintf(filename
, "%s.h", ShortBaseName
); break;
13403 case 83: sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13404 default: mode
= MODUS_ERROR
; break;
13407 else if(args
.special
< 100) /* multifile stuff */
13409 Flags
|= FLAG_SINGLEFILE
;
13410 switch(args
.special
)
13413 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13414 mode
= MODUS_ASMTEXTSF
; filenamefmt
= "%s.s";
13417 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13418 mode
= MODUS_VBCCPUPTEXTSF
; filenamefmt
= "%s.s";
13421 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13422 mode
= MODUS_VBCCWOSTEXTSF
; filenamefmt
= "%s.s";
13425 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13426 mode
= MODUS_VBCCMORPHTEXTSF
; filenamefmt
= "%s.s";
13428 default: mode
= MODUS_ERROR
; break;
13431 else if(args
.special
< 110) /* PPC lvo's */
13433 switch(args
.special
)
13435 case 100: case 101: mode
= MODUS_LVOPPC
+args
.special
-100;
13436 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13438 case 104: case 105: mode
= MODUS_LVOPPC
+args
.special
-104;
13439 Flags
|= FLAG_ABIV4
;
13440 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13442 case 103: mode
= MODUS_LVOLIB
;
13443 sprintf(filename
, "%slvo.o", ShortBaseName
);
13445 case 107: mode
= MODUS_LVOLIB
;
13446 Flags
|= FLAG_ABIV4
;
13447 sprintf(filename
, "%slvo.o", ShortBaseName
);
13449 case 102: mode
= MODUS_LVOLIBPPC
;
13450 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13451 case 106: mode
= MODUS_LVOLIBPPC
;
13452 Flags
|= FLAG_ABIV4
;
13453 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13454 default: mode
= MODUS_ERROR
; break;
13457 else if(args
.special
< 120) /* different files */
13459 if(args
.mode
> 0 && args
.mode
< 4)
13460 callmode
= args
.mode
- 1;
13462 switch(args
.special
)
13464 case 110: mode
= MODUS_FD
;
13465 sprintf(filename
, "%s_lib.fd", ShortBaseName
);
13466 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13468 DoError(ERR_SORTED_SFD_FD
, 0);
13469 Flags
&= (~FLAG_SORTED
);
13472 case 111: mode
= MODUS_CLIB
; Flags2
|= FLAG2_CLIBOUT
;
13473 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13475 case 112: mode
= MODUS_SFD
; Flags2
|= FLAG2_SFDOUT
;
13476 sprintf(filename
, "%s_lib.sfd", ShortBaseName
);
13480 DoError(ERR_ONLYTAGMODE_NOTALLOWED
, 0);
13483 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13485 DoError(ERR_SORTED_SFD_FD
, 0);
13486 Flags
&= (~FLAG_SORTED
);
13489 default: mode
= MODUS_ERROR
; break;
13492 else if(args
.special
< 130) /* auto libopen files */
13494 if(args
.mode
> 0 && args
.mode
< 4) /* for 122 */
13495 callmode
= args
.mode
- 1;
13497 switch(args
.special
)
13499 case 120: mode
= MODUS_GENAUTO
;
13500 sprintf(filename
, "%s_autoopenlib.c", ShortBaseName
);
13502 case 121: mode
= MODUS_GENAUTO
+(args
.special
-120);
13503 sprintf(filename
, "%s_autoopenlib.lib", ShortBaseName
);
13505 case 123: Flags2
|= FLAG2_SHORTPPCVBCCINLINE
; /* no break */
13506 case 122: mode
= MODUS_VBCCMORPHINLINE
;
13507 PPCRegPrefix
= ""; /* no "r" allowed */
13508 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13510 default: mode
= MODUS_ERROR
; break;
13513 else if(args
.special
< 140) /* the MorphOS area is up to 139 */
13515 if(args
.mode
> 0 && args
.mode
< 4)
13516 callmode
= args
.mode
- 1;
13518 switch(args
.special
)
13520 case 130: case 131: case 132: mode
= MODUS_INLINE
+args
.special
-130;
13521 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13523 case 133: mode
= MODUS_INLINE
+2;
13524 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13525 Flags2
|= FLAG2_DIRECTVARARGS
;
13527 case 134: mode
= MODUS_GATESTUBS
;
13528 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13530 case 135: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
;
13531 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13533 case 136: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
;
13534 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13536 case 137: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
|FLAG2_REGLIB
;
13537 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13539 case 138: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
|FLAG2_REGLIB
;
13540 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13542 default: mode
= MODUS_ERROR
; break;
13545 else if(args
.special
< 150) /* the OS4 area is up to 139 */
13547 if(args
.mode
> 0 && args
.mode
< 4)
13548 callmode
= args
.mode
- 1;
13550 switch(args
.special
)
13554 sprintf(filename
, "%s.xml", ShortBaseName
);
13556 case 141: /* OS4 PPC->M68K cross-call stubs */
13557 mode
= MODUS_OS4_PPCSTUBS
;
13558 sprintf(filename
, "%s.c", ShortBaseName
);
13560 case 142: /* OS4 M68K->PPC cross-call stubs */
13561 mode
= MODUS_OS4_68KSTUBS
;
13562 sprintf(filename
, "%s_68k.s", ShortBaseName
);
13564 default: mode
= MODUS_ERROR
; break;
13567 if(Flags
& FLAG_SORTED
)
13570 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SINGLEFILE
)) /* is not possible to use both */
13572 DoError(ERR_COMMENT_SINGLEFILE
, 0);
13573 Flags
&= (~FLAG_DOCOMMENT
);
13576 if(!mode
|| mode
== MODUS_ERROR
)
13579 /* These modes need BaseName always. */
13580 if(!BaseName
&& (mode
== MODUS_PRAGMA
|| mode
== MODUS_STUBTEXT
||
13581 mode
== MODUS_STUBCODE
|| mode
== MODUS_EMODULE
|| (mode
>= MODUS_GENAUTO
&&
13582 mode
<= MODUS_GENAUTO
+9)))
13584 DoError(ERR_MISSING_BASENAME
, 0);
13588 if(args
.header
&& args
.header
[0] && (args
.header
[0] != '@' || args
.header
[1]))
13590 HEADER
= mygetfile(args
.header
, &headersize
);
13594 if(!(Flags
& FLAG_SINGLEFILE
))
13596 if(!OpenDest(filename
))
13600 /* from here mode is used as return result */
13601 if(mode
>= MODUS_GENAUTO
)
13602 mode
= CreateGenAuto(filename
, mode
-MODUS_GENAUTO
);
13603 else if(mode
>= MODUS_LVOPPC
)
13604 mode
= CreateLVOFilePPC(mode
-MODUS_LVOPPC
);
13605 else if(mode
>= MODUS_VBCC
)
13606 mode
= CreateVBCC(mode
-MODUS_VBCC
, callmode
);
13607 else if(mode
>= MODUS_INLINE
)
13608 mode
= CreateInline(mode
-MODUS_INLINE
, callmode
);
13609 else if(mode
>= MODUS_PROTO
)
13610 mode
= CreateProtoFile(mode
-MODUS_PROTO
+1);
13611 else if(mode
>= MODUS_LVO
)
13612 mode
= CreateLVOFile(mode
-MODUS_LVO
+1);
13613 else if(mode
== MODUS_VBCCMORPHINLINE
)
13614 mode
= CreateVBCCInline(2, callmode
);
13615 else if(mode
== MODUS_XML
)
13616 mode
= CreateXML();
13617 else if(mode
== MODUS_OS4_PPCSTUBS
)
13618 mode
= CreateOS4PPC(callmode
);
13619 else if(mode
== MODUS_OS4_68KSTUBS
)
13620 mode
= CreateOS4M68K();
13621 else if(mode
== MODUS_GATESTUBS
)
13622 mode
= CreateGateStubs(callmode
);
13623 else if(mode
== MODUS_SFD
)
13624 mode
= CreateSFD(callmode
);
13625 else if(mode
== MODUS_CLIB
)
13626 mode
= CreateClib(callmode
);
13627 else if(mode
== MODUS_FD
)
13629 else if(mode
== MODUS_LVOLIBPPC
)
13630 mode
= CreateLVOLibPPC();
13631 else if(mode
== MODUS_VBCCMORPHCODE
)
13632 mode
= CreateVBCCMorphCode(callmode
);
13633 else if(mode
== MODUS_VBCCMORPHTEXTSF
) /* single files */
13634 mode
= CallFunc(callmode
, "\n%s", FuncVBCCMorphText
);
13635 else if(mode
== MODUS_VBCCWOSINLINE
)
13636 mode
= CreateVBCCInline(1, callmode
);
13637 else if(mode
== MODUS_VBCCWOSTEXTSF
) /* single files */
13638 mode
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
);
13639 else if(mode
== MODUS_VBCCPUPTEXTSF
) /* single files */
13640 mode
= CallFunc(callmode
, "\n%s", FuncVBCCPUPText
);
13641 else if(mode
== MODUS_ASMTEXTSF
) /* single files */
13642 mode
= CallFunc(callmode
, "\n%s", FuncAsmText
);
13643 else if(mode
== MODUS_REDIRECT
)
13644 mode
= CreateProtoRedirect();
13645 else if(mode
== MODUS_EMODULE
)
13646 mode
= CreateEModule(Flags
& FLAG_SORTED
);
13647 else if(mode
== MODUS_LVOLIB
)
13648 mode
= CreateLVOLib();
13649 else if(mode
== MODUS_VBCCPUPLIB
)
13650 mode
= CreateVBCCPUPLib(callmode
);
13651 else if(mode
== MODUS_VBCCINLINE
)
13652 mode
= CreateVBCCInline(0, callmode
);
13653 else if(mode
== MODUS_PASCAL
)
13654 mode
= CreateFPCUnit();
13655 else if(mode
== MODUS_BMAP
)
13656 mode
= CreateBMAP();
13657 else if(mode
== MODUS_PROTOPOWER
)
13658 mode
= CreateProtoPowerUP();
13659 else if(mode
== MODUS_SASPOWER
)
13660 mode
= CreateSASPowerUP(callmode
);
13661 else if(mode
== MODUS_CSTUB
)
13662 mode
= CreateCSTUBSFile();
13663 else if(mode
== MODUS_PRAGMA
)
13664 mode
= CreatePragmaFile(amicall
, libcall
, amitags
, libtags
, pragmode
);
13665 else if(mode
== MODUS_LOCALDATA
)
13666 mode
= CreateLocalData(filename
, callmode
);
13667 else if(mode
) /* MODUS_STUBTEXT starts with 1 */
13668 mode
= CreateAsmStubs(mode
, callmode
);
13670 CloseDest(filename
);
13674 DoError(Output_Error
? ERR_UNKNOWN_ERROR
: ERR_WRITING_FILE
, 0);