2 static const char version
[] =
3 "$VER: fd2pragma 2.195 (24.05.2015) by Dirk Stoecker <software@dstoecker.de>";
5 /* There are four defines, which alter the result which is produced after
6 compiling this piece of code. */
8 /* turns on usage of Amiga ReadArgs-system (requires <proto/dos.h> include) */
9 /* #define FD2PRAGMA_READARGS */
11 /* enables Amiga style file name (only relevant for fd2pragma.types file) */
12 /* #define FD2PRAGMA_AMIGA */
14 /* debugging output */
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.
323 2.195 24.05.15 : (phx) Merge data-register pairs from the FD file for
324 64-bit data types when generating vbcc 68k assembler inlines.
327 /* A short note, how fd2pragma works.
328 Working mode for SPECIAL 200 is a bit different!
329 The main function parses arguments. Switches are converted into FLAG_XXX
330 values and stored in global "Flags" or "Flags2" variable. SPECIAL numbers
331 are parsed and are used to call a CreateXXX function, with its interface
332 depending on the need of arguments (Some have 2, some none, ...). Before
333 SPECIAL arguments are parsed, fd2pragma loads (S)FD file and scans it using
334 Scan(S)FDFile(). If SORTED is specified, the list gets sorted nearly directly
335 afterwards. IF CLIB argument is given, the clib file is scanned after FD file
336 and a clib list is created. Now SPECIAL is parsed and mode is set to any of
337 the MODUS_XXX values. Also the destination file name is created if not given.
338 The destination file is opened now.
340 The mode variable is used to determine the correct CreateXXX function,
341 which is called afterwards. This function produces file headers and stuff
342 like that and calls CallFunc to process each FD entry.
344 CallFunc gets 3 arguments. First the workmode (TAG, NORMAL, BOTH).
345 Second the comment method (for C it is "/%s *\x2F\n", for ASM it is "\n%s",
346 no comment is reached with 0 argument). The last is most important. It is the
347 function pointer to a function creating the entries. These functions have
348 always the same interface and are called through CallFunc only! They create
349 an entry for the specified function (e.g. FD entry). Parsing special
350 functions, adding comments, checking for tag-functions, ... is done by
351 CallFunc. It is no problem to call CallFunc multiple with different function
352 pointers (as is done for SPECIAL 6 pragmas).
353 This is also the method if information abount the type or number of functions
354 is needed somewhere in the begin of the output file. A special function to
355 collect this data needs to be started before doing real output. Althought I
356 do not like it much, global variables or flags can be used to store that
359 The functions can use DoOutput to output texts in printf style or
360 DoOutputDirect to output all data in fwrite style. Buffering is done
363 fd2pragma has its own memory managment. All memory must be allocated using
364 AllocListMem and is freed automatically. This is especially useful for
365 DupString function, which is used in FD, SFD and CLIB scanner.
367 Normally this source-file is to big and should be splitted into different
368 files compiled alone and linked together. :-) It takes about 20 minutes to
369 compile it on my Amiga system with optimizations turned on.
371 There are lots of different input and output types and some combinations
372 are really useless or wrong. fd2pragma has the mechanisms to catch these
373 cases properly, but not all cases are really checked, as there are too many
374 of them and each new input type increases the number of combinations.
375 Also not all useful combinations me be handled correctly. If you find a
376 case which really matters please inform me. All the others require the
377 users to use their brains :-)
387 /* These are the only allowed variable types of all related programs! */
389 #include <exec/types.h>
391 typedef signed char int8
; /* signed 8 bit */
392 typedef unsigned char uint8
; /* unsigned 8 bit */
393 typedef signed short int int16
; /* signed 16 bit */
394 typedef unsigned short int uint16
; /* unsigned 16 bit */
395 typedef signed long int int32
; /* signed 32 bit */
396 typedef unsigned long int uint32
; /* unsigned 32 bit */
398 typedef float fl32
; /* 32 bit IEEE float value */
399 typedef double fl64
; /* 64 bit IEEE double value */
400 typedef char string
; /* the string datatype [e.g. one character of string!] */
401 typedef char * strptr
; /* and an string pointer */
403 #define EndPutM32(a, b) {uint32 epu32 = (b); (a)[0] = (uint8) (epu32 >> 24); (a)[1] = (uint8) (epu32 >> 16); \
404 (a)[2] = (uint8) (epu32 >> 8); (a)[3] = (uint8) epu32;}
405 #define EndPutM16(a, b) {uint16 epu16 = (b); (a)[0] = (uint8) (epu16 >> 8); (a)[1] = (uint8) epu16;}
406 #define EndPutI32(a, b) {uint32 epu32 = (b); (a)[3] = (uint8) (epu32 >> 24); (a)[2] = (uint8) (epu32 >> 16); \
407 (a)[1] = (uint8) (epu32 >> 8); (a)[0] = (uint8) epu32;}
408 #define EndPutI16(a, b) {uint16 epu16 = (b); (a)[1] = (uint8) (epu16 >> 8); (a)[0] = (uint8) epu16;}
410 #define EndPutM32Inc(a, b) {EndPutM32(a,b); (a) += 4;}
411 #define EndPutM16Inc(a, b) {EndPutM16(a,b); (a) += 2;}
412 #define EndPutI32Inc(a, b) {EndPutI32(a,b); (a) += 4;}
413 #define EndPutI16Inc(a, b) {EndPutI16(a,b); (a) += 2;}
415 #define TEXT_SAS "__SASC" /* verified */
416 #define TEXT_SAS_60 "__SASC_60" /* verified */
417 #define TEXT_MAXON "__MAXON__" /* verified */
418 #define TEXT_STORM "__STORM__" /* verified */
419 #define TEXT_DICE "_DCC" /* in 2.0 code */
420 #define TEXT_AZTEC "AZTEC_C" /* verified */
421 #define TEXT_GNUC "__GNUC__" /* verified */
422 #define TEXT_VBCC "__VBCC__" /* verified */
424 #define TEMPSIZE 20480
426 #define FLAG_EXTERNC (1<< 0) /* add externc statements */
427 #define FLAG_SYSCALL (1<< 1) /* create SAS-C syscall pragmas */
428 #define FLAG_DOCOMMENT (1<< 2) /* do comment processing */
429 #define FLAG_PRIVATE (1<< 3) /* also use private functions */
430 #define FLAG_LOCALREG (1<< 4) /* local file uses register call */
431 #define FLAG_ISPRIVATE (1<< 5) /* for FD creation, currently working in private mode */
432 #define FLAG_PASCAL (1<< 6) /* library creation with PASCAL style */
433 #define FLAG_SMALLDATA (1<< 7) /* libraries use small data modell */
434 #define FLAG_DONE (1<< 8) /* destination file is not empty */
435 #define FLAG_INLINENEW (1<< 9) /* produce new style inlines */
436 #define FLAG_INLINESTUB (1<<10) /* produce stubs style inlines */
437 #define FLAG_NOFPU (1<<11) /* do not allow FPU registers */
438 #define FLAG_DIDERROR (1<<12) /* one error already printed, don't print 2nd */
439 #define FLAG_FPUONLY (1<<13) /* only use FPU registers */
440 #define FLAG_GNUPRAG (1<<14) /* insert inline call into pragma file */
441 #define FLAG_POWERUP (1<<15) /* create Phase5 PowerUP files */
442 #define FLAG_ASMSECTION (1<<16) /* create SECTIONS in Asm code */
443 #define FLAG_NEWSYNTAX (1<<17) /* new motorola syntax */
444 #define FLAG_NOMOVEM (1<<18) /* 68040 optimization, don't use MOVEM */
445 #define FLAG_WOSLIBBASE (1<<19) /* first arg is libbase for VBCC WOS */
446 #define FLAG_NOPPC (1<<20) /* do not allow PPC functions */
447 #define FLAG_PPCONLY (1<<21) /* only take PPC functions */
448 #define FLAG_STORMGCC (1<<22) /* special workaround for StormGCC */
449 #define FLAG_NOSYMBOL (1<<23) /* do not create symbol section for libs */
450 #define FLAG_MORPHOS (1<<24) /* create MorphOS files */
451 #define FLAG_SORTED (1<<25) /* sort the functions by name */
452 #define FLAG_DIDPPCWARN (1<<26) /* we already printed ppc warning */
453 #define FLAG_SINGLEFILE (1<<27) /* create single files */
454 #define FLAG_ONLYCNAMES (1<<28) /* do not create C++, ASM names */
455 #define FLAG_BASENAME (1<<29) /* Basename was command-line specified */
456 #define FLAG_DIDM68KWARN (1<<30) /* we already printed M68K warning */
457 #define FLAG_ABIV4 (1<<31) /* ABI V4 design for PPC-LVO */
459 #define FLAG2_SFDMODE (1<< 0) /* input file was SFD file */
460 #define FLAG2_LIBTYPE (1<< 1) /* libtype was specified on command line */
461 #define FLAG2_CLIBOUT (1<< 2) /* output type is CLIB */
462 #define FLAG2_SYSTEMRELEASE (1<< 3) /* systemrelease special comment handling */
463 #define FLAG2_SFDOUT (1<< 4) /* output type is SFD */
464 #define FLAG2_LIBNAME (1<< 5) /* libname was specified on command line */
465 #define FLAG2_SMALLCODE (1<< 6) /* libraries use small code modell */
466 #define FLAG2_VOIDBASE (1<< 7) /* library base should be of type "void *" */
467 #define FLAG2_INLINEMAC (1<< 8) /* use inline macro instead of function */
468 #define FLAG2_DIRECTVARARGS (1<< 9) /* direct varargs for MorphOS stub libs */
469 #define FLAG2_PRELIB (1<<10) /* MorphOS gate PRELIB flag */
470 #define FLAG2_POSTLIB (1<<11) /* MorphOS gate POSTLIB flag */
471 #define FLAG2_REGLIB (1<<12) /* MorphOS gate REGLIB flag */
472 #define FLAG2_OLDVBCC (1<<13) /* old VBCC style */
473 #define FLAG2_SMALLTYPES (1<<14) /* allow small data types */
474 #define FLAG2_AUTOHEADER (1<<15) /* creates auto generated header */
475 #define FLAG2_LIBNAMECOM (1<<16) /* libname was specified in SFD comment */
476 #define FLAG2_OS4M68KCSTUB (1<<17) /* OS4 M68K stub needs C */
477 #define FLAG2_SHORTPPCVBCCINLINE (1<<18) /* shorter PPC inline using argument */
479 #define FUNCFLAG_NORMAL (1<<0) /* normal function */
480 #define FUNCFLAG_TAG (1<<1) /* a tagcall function */
481 #define FUNCFLAG_ALIAS (1<<2) /* an alias name for previous function */
482 #define FUNCFLAG_EXTENDMODE (1<<3) /* name and args extension for CSTUBS */
484 /* Different modes the main program uses, one for each different file
485 type (except for those done with one function and flag settings). */
486 #define MODUS_STUBTEXT 1
487 #define MODUS_STUBCODE 2
488 #define MODUS_LOCALDATA 3
489 #define MODUS_PRAGMA 4
490 #define MODUS_CSTUB 5
491 #define MODUS_SASPOWER 6
492 #define MODUS_PROTOPOWER 7
494 #define MODUS_PASCAL 9
495 #define MODUS_VBCCINLINE 10
496 #define MODUS_VBCCPUPLIB 11
497 #define MODUS_LVOLIB 12
498 #define MODUS_EMODULE 13
499 #define MODUS_REDIRECT 14
500 #define MODUS_ASMTEXTSF 15
501 #define MODUS_VBCCPUPTEXTSF 16
502 #define MODUS_VBCCWOSTEXTSF 17
503 #define MODUS_VBCCWOSINLINE 18
504 #define MODUS_VBCCMORPHTEXTSF 19
505 #define MODUS_VBCCMORPHCODE 20
506 #define MODUS_LVOLIBPPC 21
508 #define MODUS_CLIB 23
510 #define MODUS_GATESTUBS 25
511 #define MODUS_VBCCMORPHINLINE 26
513 #define MODUS_OS4_PPCSTUBS 28
514 #define MODUS_OS4_68KSTUBS 29
515 #define MODUS_LVO 50 /* and 51 and 52 and 53 */
516 #define MODUS_PROTO 60 /* and 61 to 69 */
517 /* new protos start with 90, but are added to MODUS_PROTO ! */
518 #define MODUS_INLINE 80 /* and 81 to 86 */
519 #define MODUS_VBCC 90 /* and 91 to 94 */
520 #define MODUS_LVOPPC 100 /* and 101 */
521 #define MODUS_GENAUTO 110 /* and 111 to 113 */
522 #define MODUS_ERROR 200
524 enum ABI
{ABI_M68K
, ABI_PPC
, ABI_PPC2
, ABI_PPC0
};
526 /* call types for CallFunc */
527 #define TAGMODE_NORMAL 0 /* produce normal functions only */
528 #define TAGMODE_TAGS 1 /* produce only tag functions */
529 #define TAGMODE_BOTH 2 /* produce both types */
531 /* types specifying name method for pragma creation */
532 #define PRAGMODE_PRAGLIB 1
533 #define PRAGMODE_PRAGSLIB 2
534 #define PRAGMODE_PRAGSPRAGS 3
535 #define PRAGMODE_NONE 4
537 #define BIAS_START 30 /* the library start offset */
538 #define BIAS_OFFSET 6 /* value to switch from one to next function */
540 #ifndef FD2PRAGMA_AMIGA
541 #define EXTTYPESFILEHIDDEN ".fd2pragma.types"
544 #define EXTTYPESFILE "fd2pragma.types"
546 #ifndef EXTTYPESFILE2
547 #ifdef FD2PRAGMA_AMIGA
548 #define EXTTYPESFILE2 "PROGDIR:fd2pragma.types"
550 #define EXTTYPESFILE2 "/usr/local/share/fd2pragma.types"
554 #define AUTOHEADERTEXT "Automatically generated header! Do not edit!"
556 #define FDFILEEXTENSION "_lib.fd"
557 #define SFDFILEEXTENSION "_lib.sfd"
559 static const strptr libstring
= "Library";
561 static const strptr RegNames
[] = {
562 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
563 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
564 "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
565 "d0/d1", "d2/d3", "d4/d5", "d6/d7",
568 static const strptr RegNamesUpper
[] = {
569 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
570 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
571 "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
572 "D0/D1", "D2/D3", "D4/D5", "D6/D7",
576 REG_D0
, REG_D1
, REG_D2
, REG_D3
, REG_D4
, REG_D5
, REG_D6
, REG_D7
,
577 REG_A0
, REG_A1
, REG_A2
, REG_A3
, REG_A4
, REG_A5
, REG_A6
, REG_A7
,
578 REG_FP0
, REG_FP1
, REG_FP2
, REG_FP3
, REG_FP4
, REG_FP5
, REG_FP6
, REG_FP7
,
579 REG_D0D1
, REG_D2D3
, REG_D4D5
, REG_D6D7
582 #define MAXREG 24 /* maximum registers of 68K */
583 #define MAXREGNF 16 /* maximum register number without float regs */
584 #define UNDEFREGISTER 255 /* for type scanner */
596 struct ShortList
*Next
;
599 struct ShortListRoot
{
600 struct ShortList
*First
;
601 struct ShortList
*Last
;
605 #define AMIPRAGFLAG_PUBLIC (1<< 0) /* is a public function */
606 #define AMIPRAGFLAG_A6USE (1<< 1) /* A6 is used for this function */
607 #define AMIPRAGFLAG_A5USE (1<< 2) /* A5 is used */
608 #define AMIPRAGFLAG_A4USE (1<< 3) /* A4 is used */
609 #define AMIPRAGFLAG_D7USE (1<< 4) /* D7 is used */
610 #define AMIPRAGFLAG_ARGCOUNT (1<< 5) /* when double args, ... */
611 #define AMIPRAGFLAG_DIDARGWARN (1<< 6) /* We printed a argcount warning */
612 #define AMIPRAGFLAG_FLOATARG (1<< 7) /* It has a float argument */
613 #define AMIPRAGFLAG_DIDFLOATWARN (1<< 8) /* We printed a float warning */
614 #define AMIPRAGFLAG_NOCLIB (1<< 9) /* No clib definition found */
615 #define AMIPRAGFLAG_CLIBARGCNT (1<<10) /* CLIB argument count error */
616 #define AMIPRAGFLAG_PPC (1<<11) /* This is an PPC function */
617 #define AMIPRAGFLAG_PPC0 (1<<12) /* type PPC0 */
618 #define AMIPRAGFLAG_PPC2 (1<<13) /* type PPC2 */
619 #define AMIPRAGFLAG_M68K (1<<14) /* This is an M68K function */
620 #define AMIPRAGFLAG_OWNTAGFUNC (1<<15) /* MakeTagFunction create tag */
621 #define AMIPRAGFLAG_MOSSYSV (1<<16) /* MorphOS(sysv) type */
622 #define AMIPRAGFLAG_MOSSYSVR12 (1<<17) /* MorphOS(sysv,r12base) type */
623 #define AMIPRAGFLAG_MOSBASESYSV (1<<18) /* MorphOS(base,sysv) type */
624 #define AMIPRAGFLAG_VARARGS (1<<19) /* last argument is ... */
626 #define AMIPRAGFLAG_MOS_ALL (AMIPRAGFLAG_MOSSYSV|AMIPRAGFLAG_MOSSYSVR12|AMIPRAGFLAG_MOSBASESYSV)
633 #define NUMALIASNAMES 5
636 struct ShortList List
;
641 struct Pragma_AliasName
* AliasName
[NUMALIASNAMES
]; /* alias names */
642 uint16 NumArgs
; /* register numbers */
643 uint16 CallArgs
; /* argument number in fd file */
647 struct AmiArgs Args
[MAXREGPPC
];
651 struct ShortList List
;
656 uint8 Private
; /* is a flag only */
660 struct ShortList List
;
665 struct ShortList List
;
666 struct ShortListRoot Data
; /* contains list of PragData */
671 struct ShortList List
;
672 struct ShortListRoot Name
;
676 uint8 ArgReg
[MAXREG
];
683 uint32 Mode
; /* 0 = Normal, != 0 is TagName */
685 uint8 ArgReg
[MAXREG
];
688 /* NOTE: string creation for CPP-Functions probably does not work at all
689 at the moment, as every compiler uses different systems which seem to
690 change constantly. */
692 /* These CPP types match the strings used for CPP name creation. The
693 defines are used both for name creation and type specification. */
694 #define CPP_TYPE_VOID 'v' /* void, VOID */
695 #define CPP_TYPE_BYTE 'c' /* char, int8 */
696 #define CPP_TYPE_WORD 's' /* short, int16 */
697 #define CPP_TYPE_LONG 'j' /* long, int32 */
698 #define CPP_TYPE_FLOAT 'f' /* float, FLOAT */
699 #define CPP_TYPE_DOUBLE 'd' /* double, DOUBLE */
700 #define CPP_TYPE_INT 'i' /* int */
701 #define CPP_TYPE_STRUCTURE 0
702 #define CPP_TYPE_VARARGS 'e'
703 #define CPP_TYPE_LONGLONG 'l' /* long long, int64 */
705 /* These types are for string creation only. */
706 #define CPP_TYPE_ENUM 'E'
707 #define CPP_TYPE_CONST 'C'
708 #define CPP_TYPE_FUNCTION 'F'
709 #define CPP_TYPE_POINTER 'P'
710 #define CPP_TYPE_UNSIGNED 'U'
711 #define CPP_TYPE_FUNCEND 'p'
712 #define CPP_TYPE_REGISTER 'r'
714 /* Some flags to be used in CPP_NameType->Flags. */
715 #define CPP_FLAG_UNSIGNED (1<<0) /* is an unsigned variable */
716 #define CPP_FLAG_CONST (1<<1) /* type is const */
717 #define CPP_FLAG_STRPTR (1<<2) /* this variable contains a strptr */
718 #define CPP_FLAG_POINTER (1<<3) /* the variable is a pointer */
719 #define CPP_FLAG_ENUM (1<<4) /* it is a enumeration */
720 #define CPP_FLAG_STRUCT (1<<5) /* it is a structure */
721 #define CPP_FLAG_UNION (1<<6) /* it is a union */
722 #define CPP_FLAG_FUNCTION (1<<7) /* it is a function */
723 #define CPP_FLAG_BOOLEAN (1<<8) /* in truth this element is bool */
724 #define CPP_FLAG_REGISTER (1<<9) /* argument is register type */
725 #define CPP_FLAG_TYPEDEFNAME (1<<10) /* name is created from typedef */
726 #define CPP_FLAG_ARRAY (1<<11) /* this type is an array */
727 #define CPP_FLAG_LONG (1<<12) /* type is long */
728 /* STRPTR is defined different under C and CPP -> I have to create two
729 names, one time unsigned char *, one time signed char *, when somewhere
732 #define COPYCPP_PASSES 4
734 struct CPP_NameType
{ /* structure to describe a argument type */
735 strptr StructureName
; /* if a structure or enum only */
736 strptr FuncArgs
; /* arguments of function - unterminated */
737 strptr TypeStart
; /* start of this type */
738 strptr Replace
; /* replacement of type for SFD files */
739 strptr Unknown
; /* unknown type handled as int */
740 strptr FunctionName
; /* Argument name of function argument */
741 struct ClibData
*FuncPtr
; /* if it is a function pointer */
742 uint16 StructureLength
; /* length of the structure name */
743 uint16 ArgsLength
; /* length of FuncArgs */
744 uint16 TypeLength
; /* length of this type */
745 uint16 FullLength
; /* length of complete type */
746 uint16 PointerDepth
; /* number of * in type */
747 uint16 FuncPointerDepth
; /* number of * in function pointer */
748 uint16 Flags
; /* see above flags */
749 uint8 Type
; /* see above defines */
750 uint8 Register
; /* register number */
753 struct ClibData
{ /* structure to describe data in CLIB file */
754 struct ClibData
* Next
; /* The next entry in this list */
755 strptr FuncName
; /* name of the function */
756 struct CPP_NameType ReturnType
; /* data for return type */
757 struct CPP_NameType Args
[MAXREGPPC
+1]; /* data for argument types */
758 uint16 NumArgs
; /* number of arguments */
761 struct CPP_ExternNames
{ /* structure for EXTTYPESFILE data */
762 struct CPP_ExternNames
* Next
; /* The next entry in this list */
763 strptr Type
; /* The unknown type */
764 struct CPP_NameType NameType
; /* The replacement */
767 struct CPP_TypeField
{ /* structure for internal defined types */
768 strptr Text
; /* name of the type */
769 uint16 Length
; /* length of the name string */
770 uint16 Flags
; /* CPP_FLAG flags */
771 uint8 Type
; /* CPP_TYPE value */
775 struct CPP_Unknown
*Next
;
779 struct Proto_LibType
{ /* structure to define structure type of base vars */
780 strptr BaseName
; /* name of the library base */
781 strptr StructureName
; /* name of the structure to be used (0 for default) */
782 strptr LibraryName
; /* name of the library (maybe 0 for default method) */
783 strptr ShortBaseName
; /* short name of the library base */
786 struct Pragma_ExecpName
{ /* structure to specify special tagnames */
787 strptr FunctionName
; /* function name */
788 strptr TagName
; /* tag name to be used for this function */
789 }; /* TagName 0 is valid as well to disable tagfunctions */
791 struct Pragma_AliasName
{
797 #define NTP_NORMAL 0 /* no tags/args */
798 #define NTP_TAGS 1 /* TagFunction */
799 #define NTP_ARGS 2 /* ArgFunction */
800 #define NTP_UNKNOWN 3 /* CommentFunction */
803 struct ShortList List
;
804 uint32 Type
; /* set by OptimizeFDData */
815 /* EHF definitions! */
816 #define HUNK_PPC_CODE 0x4E9
817 #define HUNK_RELRELOC26 0x4EC
818 #define EXT_RELREF26 229
820 /* ------------------------------------------------------------------ */
821 /* A short set of ELF definitions, see pasm sources in vbcc release for an
822 more complete set of stuff or get elf documentation. These are needed for
823 VBCCPUPCode function. */
825 #define ELFDATA2MSB 2
826 #define EV_CURRENT 1 /* version information */
827 #define ET_REL 1 /* type information */
828 #define EM_POWERPC 20
830 #define SHT_NULL 0 /* inactive */
831 #define SHT_PROGBITS 1 /* program information */
832 #define SHT_SYMTAB 2 /* symbol table */
833 #define SHT_STRTAB 3 /* string table */
834 #define SHT_RELA 4 /* relocation */
836 #define SHF_ALLOC 0x2 /* needs memory when started */
837 #define SHF_EXECINSTR 0x4 /* executable instructions */
839 #define SHN_ABS 0xFFF1
854 #define STT_SECTION 3
856 #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
857 #define ELF32_R_INFO(s,t) (((s)<<8)+(uint8)(t))
859 #define R_PPC_ADDR16_LO 4
860 #define R_PPC_ADDR16_HA 6
861 #define R_PPC_REL24 10
862 #define R_PPC_SDAREL16 32
865 string ar_name
[16]; /* name */
866 string ar_time
[12]; /* modification time */
867 string ar_uid
[6]; /* user id */
868 string ar_gid
[6]; /* group id */
869 string ar_mode
[8]; /* octal file permissions */
870 string ar_size
[10]; /* size in bytes */
871 string ar_fmag
[2]; /* consistency check */
874 /* AmigaOS hunk structure definitions */
876 #include <dos/doshunks.h>
878 #define HUNK_UNIT 999
879 #define HUNK_NAME 1000
880 #define HUNK_CODE 1001
881 #define HUNK_BSS 1003
882 #define HUNK_ABSRELOC32 1004
883 #define HUNK_EXT 1007
884 #define HUNK_SYMBOL 1008
885 #define HUNK_END 1010
886 #define HUNK_DREL16 1016
888 #define EXT_DEF 1 /* normal definition */
889 #define EXT_ABS 2 /* Absolute definition */
890 #define EXT_REF32 129 /* 32 bit absolute reference to symbol */
891 #define EXT_DEXT16 134 /* 16 bit data relative reference */
893 /* ------------------------------------------------------------------ */
895 static struct Args args
= {0,0,0,0,6,0};
896 static struct InFile in
= {0,0,0};
897 static FILE * outfile
;
898 static struct ClibData
* clibdata
= 0;
899 static struct ShortListRoot AmiPragma
= {0,0,sizeof(struct AmiPragma
)},
900 Comment
= {0,0,sizeof(struct Comment
)},
901 Includes
= {0,0,sizeof(struct Include
)};
902 static struct CPP_ExternNames
*extnames
= 0;
903 static struct CPP_Unknown
*unknown
= 0;
904 static strptr BaseName
= 0; /* the correct basename */
905 /* the filename part of basename without Base */
906 static strptr ShortBaseName
= 0;
907 /* like ShortBaseName, but upper case */
908 static strptr ShortBaseNameUpper
= 0;
909 static strptr HEADER
= 0;
910 static strptr Copyright
= 0;
911 static strptr filenamefmt
= 0;
912 static strptr libtype
= 0;
913 static strptr libname
= 0;
914 static strptr defabi
= 0;
915 static strptr hunkname
= ".text";
916 static strptr datahunkname
= "__MERGED";
917 static strptr PPCRegPrefix
= "r";
918 static strptr IDstring
= 0;
919 static strptr prefix
= "";
920 static strptr subprefix
= "";
921 static strptr premacro
= "";
922 static uint8
* tempbuf
= 0;
923 static size_t headersize
= 0;
924 static uint32 Flags
= 0;
925 static uint32 Flags2
= 0;
926 /* Output error occured when 0 */
927 static uint32 Output_Error
= 1;
928 /* are there some tagfuncs in FD */
929 static uint32 tagfuncs
= 0;
930 /* priority for auto libopen */
931 static uint32 priority
= 5;
932 /* needed for filename */
933 static string filename
[255];
935 /* Only for E-Stuff, FD, SFD, XML creation */
936 static int32 LastBias
= 0;
937 /* Only for PPC-LVO Lib's */
938 static uint8
* elfbufpos
= 0;
939 /* Only for PPC-LVO Lib's */
940 static uint32 symoffset
= 0;
941 /* Only for FD, SFD creation */
942 static enum ABI CurrentABI
= ABI_M68K
;
944 /* Prototypes for the functions */
945 static strptr
DupString(strptr
, size_t);
946 static strptr
AllocListMem(size_t);
947 static strptr
SkipBlanks(strptr
);
948 static strptr
SkipBlanksRet(strptr
);
949 static strptr
SkipName(strptr
);
950 static uint32
GetTypes(void);
951 static strptr
GetBaseType(void);
952 static strptr
GetBaseTypeLib(void);
953 static strptr
GetLibraryName(void);
954 static strptr
GetIFXName(void);
955 static int32
MakeShortBaseName(void);
956 static uint32
OpenDest(strptr
);
957 static uint32
CloseDest(strptr
);
958 static uint32
MakeTagFunction(struct AmiPragma
*);
959 static void MakeLines(strptr
, uint32
);
960 static uint32
SpecialFuncs(void);
961 static void SortFDList(void);
962 static void AddAliasName(struct AmiPragma
*, struct Pragma_AliasName
*,
964 static uint32
CheckNames(struct AmiPragma
*);
965 static uint32
ScanSFDFile(enum ABI
);
966 static uint32
ScanFDFile(void);
967 static int32
ScanTypes(strptr
, uint32
);
968 static void FindHeader(void);
969 static uint32
GetRegisterData(struct AmiPragma
*);
970 static uint16
GetFRegisterData(struct AmiPragma
*);
971 static uint32
OutputXDEF(uint32
, strptr
, ...);
972 static uint32
OutputXREF(uint32
, uint32
, strptr
, ...);
973 static uint32
OutputXREF2(uint32
, uint32
, uint32
, strptr
, ...);
974 static uint32
OutputSYMBOL(uint32
, strptr
, ...);
975 static uint8
* AsmStackCopy(uint8
*, struct AmiPragma
*, uint32
, uint32
);
976 /* ------------------------------------------------------------------ */
977 static void DoError(uint32
, uint32
, ...);
978 static uint32
CheckError(struct AmiPragma
*, uint32
);
979 static uint32
DoOutputDirect(void *, size_t);
981 #if defined(__GNUC__)
982 static uint32
DoOutput(strptr
, ...) __attribute__ ((format(printf
, 1, 2)));
984 static uint32
DoOutput(strptr
, ...);
986 /* ------------------------------------------------------------------ */
987 static struct ShortList
*NewItem(struct ShortListRoot
*);
988 static struct ShortList
*RemoveItem(struct ShortListRoot
*, struct ShortList
*);
989 static void AddItem(struct ShortListRoot
*, struct ShortList
*);
990 /* ------------------------------------------------------------------ */
991 typedef uint32 (*FuncType
)(struct AmiPragma
*, uint32
, strptr
);
993 uint32
FuncAMICALL (struct AmiPragma
*, uint32
, strptr
);
994 uint32
FuncLIBCALL (struct AmiPragma
*, uint32
, strptr
);
995 uint32
FuncAsmText (struct AmiPragma
*, uint32
, strptr
);
996 uint32
FuncAsmCode (struct AmiPragma
*, uint32
, strptr
);
997 uint32
FuncCSTUBS (struct AmiPragma
*, uint32
, strptr
);
998 uint32
FuncLVOXDEF (struct AmiPragma
*, uint32
, strptr
);
999 uint32
FuncLVO (struct AmiPragma
*, uint32
, strptr
);
1000 uint32
FuncLVOPPCXDEF (struct AmiPragma
*, uint32
, strptr
);
1001 uint32
FuncLVOPPC (struct AmiPragma
*, uint32
, strptr
);
1002 uint32
FuncLVOPPCBias (struct AmiPragma
*, uint32
, strptr
);
1003 uint32
FuncLVOPPCName (struct AmiPragma
*, uint32
, strptr
);
1004 uint32
FuncLVOLib (struct AmiPragma
*, uint32
, strptr
);
1005 uint32
FuncLocCode (struct AmiPragma
*, uint32
, strptr
);
1006 uint32
FuncLocText (struct AmiPragma
*, uint32
, strptr
);
1007 uint32
FuncInline (struct AmiPragma
*, uint32
, strptr
);
1008 uint32
FuncInlineDirect (struct AmiPragma
*, uint32
, strptr
);
1009 uint32
FuncInlineNS (struct AmiPragma
*, uint32
, strptr
);
1010 uint32
FuncPowerUP (struct AmiPragma
*, uint32
, strptr
);
1011 uint32
FuncFPCUnit (struct AmiPragma
*, uint32
, strptr
);
1012 uint32
FuncFPCType (struct AmiPragma
*, uint32
, strptr
);
1013 uint32
FuncFPCTypeTags (struct AmiPragma
*, uint32
, strptr
);
1014 uint32
FuncFPCTypeTagsUnit (struct AmiPragma
*, uint32
, strptr
);
1015 uint32
FuncBMAP (struct AmiPragma
*, uint32
, strptr
);
1016 uint32
FuncVBCCInline (struct AmiPragma
*, uint32
, strptr
);
1017 uint32
FuncVBCCWOSInline (struct AmiPragma
*, uint32
, strptr
);
1018 uint32
FuncVBCCMorphInline (struct AmiPragma
*, uint32
, strptr
);
1019 uint32
FuncVBCCWOSText (struct AmiPragma
*, uint32
, strptr
);
1020 uint32
FuncVBCCWOSCode (struct AmiPragma
*, uint32
, strptr
);
1021 uint32
FuncVBCCPUPText (struct AmiPragma
*, uint32
, strptr
);
1022 uint32
FuncVBCCPUPCode (struct AmiPragma
*, uint32
, strptr
);
1023 uint32
FuncEModule (struct AmiPragma
*, uint32
, strptr
);
1024 uint32
FuncVBCCMorphText (struct AmiPragma
*, uint32
, strptr
);
1025 uint32
FuncVBCCMorphCode (struct AmiPragma
*, uint32
, strptr
);
1026 uint32
FuncFD (struct AmiPragma
*, uint32
, strptr
);
1027 uint32
FuncClib (struct AmiPragma
*, uint32
, strptr
);
1028 uint32
FuncSFD (struct AmiPragma
*, uint32
, strptr
);
1029 uint32
FuncXML (struct AmiPragma
*, uint32
, strptr
);
1030 uint32
FuncOS4PPC (struct AmiPragma
*, uint32
, strptr
);
1031 uint32
FuncOS4M68KCSTUB (struct AmiPragma
*, uint32
, strptr
);
1032 uint32
FuncOS4M68K (struct AmiPragma
*, uint32
, strptr
);
1033 uint32
FuncOS4M68KVect (struct AmiPragma
*, uint32
, strptr
);
1034 uint32
FuncGateStubs (struct AmiPragma
*, uint32
, strptr
);
1035 static uint32
PrintComment (struct Comment
*, strptr
);
1036 static uint32
DoCallFunc (struct AmiPragma
*, uint32
, strptr
, FuncType
);
1037 static uint32
CallFunc (uint32
, strptr
, FuncType
);
1038 static uint32
PrintIncludes(void);
1039 /* ------------------------------------------------------------------ */
1040 static int32
AddClibEntry(strptr
, strptr
, uint32
);
1041 static int32
ScanClibFile(strptr
, strptr
);
1042 static int32
IsCPPType(struct CPP_NameType
*, uint8
);
1043 static uint32
CheckRegisterNum(strptr
, struct CPP_NameType
*);
1044 static uint32
ParseFuncPtrArgs(strptr
, struct CPP_NameType
*);
1045 static int32
GetCPPType(struct CPP_NameType
*, strptr
, uint32
, uint32
);
1046 static struct ClibData
*GetClibFunc(strptr
, struct AmiPragma
*, uint32
);
1047 static int32
CheckKeyword(strptr
, strptr
, int32
);
1048 static uint32
CopyCPPType(strptr
, uint32
, struct ClibData
*, struct AmiArgs
*);
1049 static uint32
OutClibType(struct CPP_NameType
*, strptr
);
1050 static uint32
MakeClibType(strptr
, struct CPP_NameType
*, strptr
);
1051 static uint32
OutPASCALType(struct CPP_NameType
*, strptr
, uint32
);
1052 /* ------------------------------------------------------------------ */
1053 static uint32
CallPrag(uint32
, strptr
, FuncType
);
1054 static uint32
CreatePragmaFile(strptr
, strptr
, strptr
, strptr
, uint32
);
1055 static uint32
CreateCSTUBSFile(void);
1056 static uint32
CreateLVOFile(uint32
);
1057 static uint32
CreateLVOFilePPC(uint32
);
1058 static uint32
CreateAsmStubs(uint32
, uint32
);
1059 static uint32
CreateProtoFile(uint32
);
1060 static uint32
CreateLocalData(strptr
, uint32
);
1061 static uint32
CreateInline(uint32
, uint32
);
1062 static uint32
CreateGateStubs(uint32
);
1063 static uint32
CreateSASPowerUP(uint32
);
1064 static uint32
CreateProtoPowerUP(void);
1065 static uint32
CreateFPCUnit(void);
1066 static uint32
CreateBMAP(void);
1067 static uint32
CreateLVOLib(void);
1068 static uint32
CreateLVOLibPPC(void);
1069 static uint32
CreateVBCCInline(uint32
, uint32
);
1070 static uint32
CreateVBCC(uint32
, uint32
);
1071 static uint32
CreateVBCCPUPLib(uint32
);
1072 static uint32
CreateVBCCMorphCode(uint32
);
1073 static uint32
CreateEModule(uint32
);
1074 static uint32
CreateProtoRedirect(void);
1075 static uint32
CreateFD(void);
1076 static uint32
CreateSFD(uint32
);
1077 static uint32
CreateClib(uint32
);
1078 static uint32
CreateGenAuto(strptr
, uint32
);
1079 static uint32
CreateXML(void);
1080 static uint32
CreateOS4PPC(uint32
);
1081 static uint32
CreateOS4M68K(void);
1082 /* ------------------------------------------------------------------ */
1083 static uint32
GetName(struct NameList
*, struct ShortListRoot
*, uint32
);
1084 static uint32
MakeFD(struct PragList
*);
1085 static void OptimizeFDData(struct PragData
*);
1086 static string
GetHexValue(string
);
1087 static string
GetDoubleHexValue(strptr
);
1088 static uint32
AddFDData(struct ShortListRoot
*, struct FDData
*);
1089 static uint32
GetLibData(struct FDData
*);
1090 static uint32
GetFlibData(struct FDData
*);
1091 static uint32
GetAmiData(struct FDData
*);
1092 static uint32
CreateFDFile(void);
1093 /* ------------------------------------------------------------------ */
1094 static void GetArgs(int argc
, char **argv
);
1095 static strptr
mygetfile(strptr name
, size_t *len
);
1097 #define ERROFFSET_CLIB (1<<31)
1100 ERR_TAGFUNC_NEEDS_ARGUMENT
,
1101 ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
,
1102 ERR_TAG_DEF_WITHOUT_PRAGMA
,
1103 ERR_BASENAME_DECLARED_TWICE
,
1104 ERR_EXPECTED_SLASH_IN_BASENAME
,
1105 ERR_EXPECTED_BASENAME
,
1106 ERR_EXPECTED_BIAS_VALUE
,
1107 ERR_ASSUMING_POSITIVE_BIAS_VALUE
,
1108 ERR_MISSING_FUNCTION_NAME
,
1109 ERR_EXPECTED_OPEN_BRACKET
,
1110 ERR_TO_MUCH_ARGUMENTS
,
1111 ERR_EXPECTED_ARGUMENT_NAME
,
1112 ERR_EXPECTED_CLOSE_BRACKET
,
1113 ERR_EXPECTED_REGISTER_NAME
,
1115 ERR_REGISTER_USED_TWICE
,
1116 ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
,
1117 ERR_ASSUMING_BIAS_OF_30
,
1118 ERR_EXTRA_CHARACTERS
,
1119 ERR_MISSING_BASENAME
,
1122 ERR_DIFFERENT_TO_PREVIOUS
,
1123 ERR_UNKNOWN_VARIABLE_TYPE
,
1126 ERR_PROTOTYPE_MISSING
,
1127 ERR_NOPROTOTYPES_FILE
,
1128 ERR_UNKNOWN_DIRECTIVE
,
1129 ERR_INLINE_A4_AND_A5
,
1130 ERR_INLINE_D7_AND_A45
,
1131 ERR_MISSING_SHORTBASENAME
,
1134 ERR_FLOATARG_NOT_ALLOWED
,
1135 ERR_WRONG_TYPES_LINE
,
1140 ERR_PPC_FUNCTION_NOT_SUPPORTED
,
1143 ERR_ILLEGAL_FUNCTION_POSITION
,
1145 ERR_COMMENT_SINGLEFILE
,
1146 ERR_NOFD2PRAGMATYPES
,
1147 ERR_M68K_FUNCTION_NOT_SUPPORTED
,
1148 ERR_UNKNOWN_RETURNVALUE_TYPE
,
1150 ERR_EXCPECTED_IDSTRING
,
1151 ERR_EXPECTED_ID_ENDSIGN
,
1153 ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
,
1154 ERR_IDSTRING_DECLARED_TWICE
,
1155 ERR_COMMANDLINE_LIBTYPE
,
1156 ERR_COMMANDLINE_BASENAME
,
1157 ERR_LIBTYPE_DECLARED_TWICE
,
1158 ERR_EXPECTED_LIBTYPE
,
1162 ERR_VARARGS_ARGUMENTS_DIFFER
,
1163 ERR_UNEXPECTED_FILEEND
,
1164 ERR_VARARGS_ALIAS_FIRST
,
1166 ERR_EXPECTED_STRUCT
,
1167 ERR_EXPECTED_POINTERSIGN
,
1168 ERR_ARGNAME_KEYWORD_CONFLICT
,
1169 ERR_ARGNAME_ARGNAME_CONFLICT
,
1170 ERR_ONLYTAGMODE_NOTALLOWED
,
1171 ERR_COMMANDLINE_LIBNAME
,
1172 ERR_LIBNAME_DECLARED_TWICE
,
1173 ERR_EXPECTED_LIBNAME
,
1175 ERR_MULTIPLEFUNCTION
,
1176 ERR_INLINE_AX_SWAPREG
,
1178 ERR_ILLEGAL_CHARACTER_DETECTED
,
1179 ERR_UNKNOWN_VARIABLE_TYPE_INT
,
1180 ERR_UNKNOWN_RETURNVALUE_TYPE_INT
,
1181 ERR_ILLEGAL_INTERNAL_VALUE
,
1182 ERR_MOSBASESYSV_NOT_SUPPORTED
,
1183 ERR_ALIASES_NOT_SUPPORTED
,
1184 ERR_FUNCTION_NOT_SUPPORTED
,
1187 static const struct ErrField
{
1188 uint8 Type
; /* 0 = Error, 1 = Warning */
1192 {1, 1, "Tag function must have arguments."},
1193 {1, 1, "Cannot convert pragma name into tag name."},
1194 {1, 1, "Tag definition without preceding Pragma."},
1195 {1, 0, "Basename declared twice."},
1196 {1, 0, "Expected preceding _ in Basename."},
1197 {1, 1, "Expected Basename."},
1198 {1, 0, "Expected Bias value."},
1199 {1, 0, "Assuming positive bias value."},
1200 {1, 1, "Missing function name."},
1201 {1, 1, "Expected '('."},
1202 {1, 1, "Too much arguments."},
1203 {1, 1, "Expected argument name."},
1204 {1, 1, "Expected ')'."},
1205 {1, 1, "Expected register name."},
1206 {1, 1, "A7 not allowed as argument register."},
1207 {1, 1, "Register used twice."},
1208 {1, 0, "Number of arguments != number of registers."},
1209 {1, 0, "Assuming bias of 30."},
1210 {1, 1, "Extra characters."},
1211 {0, 0, "Missing Basename in FD file."},
1212 {0, 0, "Failed to write destination file."},
1213 {1, 1, "Expected ','."},
1214 {0, 1, "Data different to previous given."},
1215 {1, 0, "Unknown type of argument %ld."},
1216 {0, 0, "Unknown problem: program error or corrupt input data."},
1217 {1, 0, "Missing ##end."},
1218 {1, 0, "Prototype for function \"%s\" not found."},
1219 {0, 0, "No prototypes file (CLIB parameter) was specified."},
1220 {1, 1, "Unknown directive '%s' found."},
1221 {1, 0, "Usage of both A4 and A5 is not supported."},
1222 {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
1223 {0, 0, "Missing Basename in FD file and FD filename."},
1224 {1, 0, "A6 not allowed as argument register."},
1225 {1, 0, "Empty or partial file deleted."},
1226 {1, 1, "Floating point arguments not allowed."},
1227 {0, 0, "Wrong definition in external type definition file."},
1228 {1, 0, "Cannot determine if FPU argument is double or single."},
1229 {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
1230 {0, 0, "Could not open file \"%s\"."},
1231 {1, 0, "A5 cannot be used as argument register."},
1232 {1, 0, "Format supports no PPC functions."},
1233 {1, 0, "Unknown ABI '%s' found."},
1234 {0, 0, "SORTED cannot be used with that type."},
1235 {1, 0, "Position of function %s not supported with that type."},
1236 {1, 1, "COMMENT and SORTED cannot be used both. Ignoring SORTED."},
1237 {1, 0, "COMMENT cannot be used in single file mode, ignoring."},
1238 {1, 0, "Missing the types definition file. Using internal defaults."},
1239 {1, 0, "Format supports no M68k functions."},
1240 {1, 0, "Unknown type of return value."},
1241 {1, 0, "With SFD as input CLIB file is ignored."},
1242 {1, 0, "Expected $Id: in ID string."},
1243 {1, 0, "Expected $ at end of ID string."},
1244 {1, 0, "Missing ==end."},
1245 {1, 1, "Expected positive decimal number."},
1246 {1, 0, "ID string declared twice."},
1247 {1, 1, "Library type of commandline overwrites file settings."},
1248 {1, 1, "Basename of commandline overwrites file settings."},
1249 {1, 0, "Library type declared twice."},
1250 {1, 1, "Expected library type definition."},
1251 {1, 1, "SORTED cannot be used with SFD and FD output."},
1252 {1, 0, "Function expected before ##shadow."},
1253 {1, 1, "There is already a varargs function, handling as alias."},
1254 {1, 0, "Varargs function cannot have different arguments."},
1255 {1, 0, "Unexpected end of file."},
1256 {1, 0, "Commands varargs and alias cannot be at file start."},
1257 {1, 0, "Only %d alias names supported."},
1258 {1, 1, "Expected struct keyword in library type."},
1259 {1, 0, "Expected '*' at end of library type definition."},
1260 {1, 1, "Name of argument %d conflicts with keyword '%s'."},
1261 {1, 1, "Name of argument %d conflicts with argument %d."},
1262 {1, 0, "SFD files cannot consist only of varargs functions."},
1263 {1, 1, "Library name of commandline overwrites file settings."},
1264 {1, 0, "Library name declared twice."},
1265 {1, 1, "Expected library name definition."},
1266 {1, 0, "Neither prefix nor subprefix specified."},
1267 {1, 0, "Format supports single function pointer only (void * used)."},
1268 {1, 0, "No swap register left for %s."},
1269 {1, 0, "SFD files should always start with ==id directive."},
1270 {1, 0, "Illegal character detected."},
1271 {1, 0, "Unknown type of argument %ld (%s) handled as int."},
1272 {1, 0, "Unknown type of return value (%s) handled as int."},
1273 {1, 0, "Illegal internal value."},
1274 {1, 0, "Format supports no MorphOS (base,sysv) functions."},
1275 {1, 0, "Format supports no alias names."},
1276 {1, 0, "Format cannot support function %s."},
1282 static uint8 InternalTypes
[] = {
1283 "IX:struct InputXpression\n"
1285 "Class:struct IClass\n"
1286 "BootBlock:struct bootblock\n"
1287 "ValidIDstruct:struct ValidIDstruct\n"
1288 "DisplayInfoHandle:void *\n"
1289 "RESOURCEFILE:void *\n"
1290 "RESOURCEID:unsigned long\n"
1292 "GLbitfield:unsigned long\n"
1293 "GLbyte:signed char\n"
1296 "GLsizei:unsigned long\n"
1297 "GLubyte:unsigned char\n"
1298 "GLushort:unsigned short\n"
1299 "GLuint:unsigned long\n"
1304 "GLboolean:enum ?\n"
1306 "GLlookAt:struct GLlookAt\n"
1307 "GLproject:struct GLproject\n"
1308 "GLunProject:struct GLunProject\n"
1309 "GLfrustum:struct GLfrustum\n"
1310 "GLortho:struct GLortho\n"
1311 "GLbitmap:struct GLbitmap\n"
1312 "GLUquadricObj:struct GLUquadricObj\n"
1313 "GLUtriangulatorObj:struct GLUtriangulatorObj\n"
1314 "GLUnurbsObj:struct GLUnurbsObj\n"
1315 "GLvisual:struct gl_visual\n"
1316 "GLframebuffer:struct gl_frame_buffer\n"
1317 "GLcontext:struct gl_context\n"
1318 "GLContext:struct !\n"
1319 "HGIDA_Stack:unsigned long *\n"
1320 "HGIDA_BoundedStack:unsigned long *\n"
1321 "HGIDA_Queue:unsigned long *\n"
1322 "HGIDA_BoundedQueue:unsigned long *\n"
1323 "HGIDA_List:unsigned long *\n"
1324 "HGIDA_ListItem:unsigned long *\n"
1325 "HGIDA_Error:enum ?\n"
1326 "HGIDA_Direction:enum ?\n"
1329 "mode_t:unsigned short\n"
1330 "pid_t:struct Task *\n"
1331 "fd_set:struct fd_set\n"
1332 "SerScriptCallback_t:unsigned long (*)(register __a0 void *, register __d0 "
1333 "unsigned long, register __a1 const unsigned char *, register __a2 struct "
1334 "CSource *, register __a3 struct CSource *)\n"
1335 "pcap_t:struct pcap\n"
1336 "pcap_dumper_t:struct pcap_dumper\n"
1337 "pcap_handler:void (*)(unsigned char *, const struct pcap_pkthdr *, const "
1338 "unsigned char *)\n"
1339 "u_char:unsigned char\n"
1340 "bpf_u_int32:unsigned long\n"
1343 "MPEGA_STREAM:struct MPEGA_STREAM\n"
1344 "MPEGA_CTRL:struct MPEGA_CTRL\n"
1345 "W3D_Context:struct W3DContext\n"
1346 "W3D_Driver:struct W3DDriver\n"
1347 "W3D_Texture:struct W3DTexture\n"
1348 "W3D_Scissor:struct W3DScissor\n"
1349 "W3D_Line:struct W3D_Line\n"
1350 "W3D_Point:struct W3D_Point\n"
1351 "W3D_Triangle:struct W3D_Triangle\n"
1352 "W3D_Triangles:struct W3D_Triangles\n"
1354 "W3D_Bitmap:struct W3D_Bitmap\n"
1355 "W3D_Fog:struct W3D_Fog\n"
1357 "W3D_Double:double\n"
1358 "W3D_TriangleV:struct W3D_TriangleV\n"
1359 "W3D_TrianglesV:struct W3D_TriangleV\n"
1360 "W3D_ScreenMode:struct W3D_Screenmode\n"
1361 "W3D_Color:struct W3D_Color\n"
1362 "W3D_Lines:struct W3D_Lines\n"
1364 "DITHERINFO:void *\n"
1368 "size_t:unsigned int\n"
1370 "uint8:unsigned char\n"
1371 "uint16:unsigned short\n"
1372 "uint32:unsigned long\n"
1377 "PtrBigNum:struct BigNum *\n"
1378 "BF_KEY:struct bf_key_st\n"
1379 "BF_LONG:unsigned long\n"
1380 "CAST_KEY:struct cast_key_st\n"
1381 "CAST_LONG:unsigned long\n"
1382 "DES_LONG:unsigned long\n"
1383 "des_key_schedule:struct des_ks_struct\n"
1384 "const_des_cblock:unsigned char [8]\n"
1385 "des_cblock:unsigned char [8]\n"
1386 "IDEA_KEY_SCHEDULE:struct idea_key_st\n"
1387 "MD2_CTX:struct MD2state_st\n"
1388 "MD5_CTX:struct MD5state_st\n"
1389 "MDC2_CTX:struct mdc2_ctx_st\n"
1390 "RC2_KEY:struct rc2_key_st\n"
1391 "RC4_KEY:struct rc4_key_st\n"
1392 "RC5_32_KEY:struct rc5_key_st\n"
1393 "RIPEMD160_CTX:struct RIPEMD160state_st\n"
1394 "SHA_CTX:struct SHAstate_st\n"
1395 "ASN1_CTX:struct asn1_ctx_st\n"
1396 "ASN1_OBJECT:struct asn1_object_st\n"
1397 "ASN1_STRING:struct asn1_string_st\n"
1398 "ASN1_TYPE:struct asn1_type_st\n"
1399 "ASN1_METHOD:struct asn1_method_st\n"
1400 "ASN1_HEADER:struct asn1_header_st\n"
1401 "ASN1_INTEGER:struct asn1_string_st\n"
1402 "ASN1_ENUMERATED:struct asn1_string_st\n"
1403 "ASN1_BIT_STRING:struct asn1_string_st\n"
1404 "ASN1_OCTET_STRING:struct asn1_string_st\n"
1405 "ASN1_PRINTABLESTRING:struct asn1_string_st\n"
1406 "ASN1_T61STRING:struct asn1_string_st\n"
1407 "ASN1_IA5STRING:struct asn1_string_st\n"
1408 "ASN1_UTCTIME:struct asn1_string_st\n"
1409 "ASN1_GENERALIZEDTIME:struct asn1_string_st\n"
1410 "ASN1_TIME:struct asn1_string_st\n"
1411 "ASN1_GENERALSTRING:struct asn1_string_st\n"
1412 "ASN1_UNIVERSALSTRING:struct asn1_string_st\n"
1413 "ASN1_BMPSTRING:struct asn1_string_st\n"
1414 "ASN1_VISIBLESTRING:struct asn1_string_st\n"
1415 "ASN1_UTF8STRING:struct asn1_string_st\n"
1416 "BIO:struct bio_st\n"
1417 "BIO_F_BUFFER_CTX:struct bio_f_buffer_ctx_struct\n"
1418 "BIO_METHOD:struct bio_method_st\n"
1419 "BIGNUM:struct bignum_st\n"
1420 "BN_CTX:struct bignum_ctx\n"
1421 "BN_ULONG:unsigned long\n"
1422 "BN_MONT_CTX:struct bn_mont_ctx_st\n"
1423 "BN_BLINDING:struct bn_blinding_st\n"
1424 "BN_RECP_CTX:struct bn_recp_ctx_st\n"
1425 "BUF_MEM:struct buf_mem_st\n"
1426 "COMP_METHOD:struct comp_method_st\n"
1427 "COMP_CTX:struct comp_ctx_st\n"
1428 "CONF_VALUE:struct !\n"
1429 "LHASH_NODE:struct lhash_node_st\n"
1430 "LHASH:struct lhash_st\n"
1431 "CRYPTO_EX_DATA:struct crypto_ex_data_st\n"
1432 "CRYPTO_EX_DATA_FUNCS:struct crypto_ex_data_func_st\n"
1434 "DSA:struct dsa_st\n"
1435 "DSA_SIG:struct DSA_SIG_st\n"
1436 "ERR_STATE:struct err_state_st\n"
1437 "ERR_STRING_DATA:struct ERR_string_data_st\n"
1438 "EVP_PKEY:struct evp_pkey_st\n"
1439 "EVP_MD:struct env_md_st\n"
1440 "EVP_MD_CTX:struct env_md_ctx_st\n"
1441 "EVP_CIPHER:struct evp_cipher_st\n"
1442 "EVP_CIPHER_INFO:struct evp_cipher_info_st\n"
1443 "EVP_CIPHER_CTX:struct evp_cipher_ctx_st\n"
1444 "EVP_ENCODE_CTX:struct evp_Encode_Ctx_st\n"
1445 "EVP_PBE_KEYGEN:struct int (*)(struct evp_cipher_ctx_st *ctx, const char "
1446 "*pass, int passlen, struct asn1_type_st *param, struct evp_cipher_st "
1447 "*cipher, struct env_md_st *md, int en_de)\n"
1448 "HMAC_CTX:struct hmac_ctx_st\n"
1449 "OBJ_NAME:struct obj_name_st\n"
1450 "PEM_ENCODE_SEAL_CTX:struct PEM_Encode_Seal_st\n"
1451 "PEM_USER:struct pem_recip_st\n"
1452 "PEM_CTX:struct pem_ctx_st\n"
1453 "PKCS12_MAC_DATA:struct !\n"
1455 "PKCS12_SAFEBAG:struct !\n"
1456 "PKCS12_BAGS:struct pkcs12_bag_st\n"
1457 "PKCS7_ISSUER_AND_SERIAL:struct pkcs7_issuer_and_serial_st\n"
1458 "PKCS7_SIGNER_INFO:struct pkcs7_signer_info_st\n"
1459 "PKCS7_RECIP_INFO:struct pkcs7_recip_info_st\n"
1460 "PKCS7_SIGNED:struct pkcs7_signed_st\n"
1461 "PKCS7_ENC_CONTENT:struct pkcs7_enc_content_st\n"
1462 "PKCS7_ENVELOPE:struct pkcs7_enveloped_st\n"
1463 "PKCS7_SIGN_ENVELOPE:struct pkcs7_signedandenveloped_st\n"
1464 "PKCS7_DIGEST:struct pkcs7_digest_st\n"
1465 "PKCS7_ENCRYPT:struct pkcs7_encrypted_st\n"
1466 "PKCS7:struct pkcs7_st\n"
1467 "RAND_METHOD:struct rand_meth_st\n"
1468 "RSA:struct rsa_st\n"
1469 "RSA_METHOD:struct rsa_meth_st\n"
1470 "TXT_DB:struct txt_db_st\n"
1471 "X509_OBJECTS:struct X509_objects_st\n"
1472 "X509_ALGOR:struct X509_algor_st\n"
1473 "X509_VAL:struct X509_val_st\n"
1474 "X509_PUBKEY:struct X509_pubkey_st\n"
1475 "X509_SIG:struct X509_sig_st\n"
1476 "X509_NAME_ENTRY:struct X509_name_entry_st\n"
1477 "X509_NAME:struct X509_name_st\n"
1478 "X509_EXTENSION:struct X509_extension_st\n"
1479 "X509_ATTRIBUTE:struct x509_attributes_st\n"
1480 "X509_REQ_INFO:struct X509_req_info_st\n"
1481 "X509_REQ:struct X509_req_st\n"
1482 "X509_CINF:struct x509_cinf_st\n"
1483 "X509:struct x509_st\n"
1484 "X509_REVOKED:struct X509_revoked_st\n"
1485 "X509_CRL_INFO:struct X509_crl_info_st\n"
1486 "X509_CRL:struct X509_crl_st\n"
1487 "X509_PKEY:struct private_key_st\n"
1488 "X509_INFO:struct X509_info_st\n"
1489 "NETSCAPE_SPKAC:struct Netscape_spkac_st\n"
1490 "NETSCAPE_SPKI:struct Netscape_spki_st\n"
1491 "NETSCAPE_CERT_SEQUENCE:struct Netscape_certificate_sequence\n"
1492 "CBC_PARAM:struct CBCParameter_st\n"
1493 "PBEPARAM:struct PBEPARAM_st\n"
1494 "PBE2PARAM:struct PBE2PARAM_st\n"
1495 "PBKDF2PARAM:struct PBKDF2PARAM_st\n"
1496 "PKCS8_PRIV_KEY_INFO:struct pkcs8_priv_key_info_st\n"
1497 "X509V3_CONF_METHOD:struct X509V3_CONF_METHOD_st\n"
1498 "X509V3_EXT_METHOD:struct v3_ext_method\n"
1499 "X509V3_CTX:struct v3_ext_ctx\n"
1500 "X509_HASH_DIR_CTX:struct x509_hash_dir_st\n"
1501 "X509_CERT_FILE_CTX:struct x509_file_st\n"
1502 "X509_OBJECT:struct X509_objects_st\n"
1503 "X509_LOOKUP:struct x509_lookup_st\n"
1504 "X509_LOOKUP_METHOD:struct x509_lookup_method_st\n"
1505 "X509_STORE_CTX:struct x509_store_state_st\n"
1506 "X509_STORE:struct x509_store_st\n"
1507 "BIT_STRING_BITNAME:struct BIT_STRING_BITNAME_st\n"
1508 "BASIC_CONSTRAINTS:struct BASIC_CONSTRAINTS_st\n"
1509 "PKEY_USAGE_PERIOD:struct PKEY_USAGE_PERIOD_st\n"
1510 "GENERAL_NAME:struct GENERAL_NAME_st\n"
1511 "DIST_POINT_NAME:struct DIST_POINT_NAME_st\n"
1512 "DIST_POINT:struct DIST_POINT_st\n"
1513 "AUTHORITY_KEYID:struct AUTHORITY_KEYID_st\n"
1514 "SXNETID:struct SXNET_ID_st\n"
1515 "SXNET:struct SXNET_st\n"
1516 "NOTICEREF:struct NOTICEREF_st\n"
1517 "USERNOTICE:struct USERNOTICE_st\n"
1518 "POLICYQUALINFO:struct POLICYQUALINFO_st\n"
1519 "POLICYINFO:struct POLICYINFO_st\n"
1520 "pem_password_cb:int (*)(char *buf, int size, int rwflag, void *userdata)\n"
1521 "SSL_CIPHER:struct ssl_cipher_st\n"
1522 "SSL:struct ssl_st\n"
1523 "SSL_CTX:struct ssl_ctx_st\n"
1524 "SSL_METHOD:struct ssl_method_st\n"
1525 "SSL_SESSION:struct ssl_session_st\n"
1526 "SSL_COMP:struct ssl_comp_st\n"
1527 "SSL2_CTX:struct ssl2_ctx_st\n"
1528 "SSL3_RECORD:struct ssl3_record_st\n"
1529 "SSL3_BUFFER:struct ssl3_buffer_st\n"
1530 "SSL3_CTX:struct ssl3_ctx_st\n"
1531 "CERT_PKEY:struct cert_pkey_st\n"
1532 "CERT:struct cert_st\n"
1533 "SESS_CERT:struct sess_cert_st\n"
1534 "SSL3_ENC_METHOD:struct ssl3_enc_method\n"
1535 "SSL3_COMP:struct ssl3_comp_st\n"
1536 "STACK_OF(X509_ATTRIBUTE):struct stack_st_X509_ATTRIBUTE\n"
1537 "STACK_OF(X509_INFO):struct stack_st_X509_INFO\n"
1538 "STACK_OF(X509_NAME):struct stack_st_X509_NAME\n"
1539 "STACK_OF(X509):struct stack_st_X509\n"
1540 "STACK_OF(PKCS7_SIGNER_INFO):struct stack_st_PKCS7_SIGNER_INFO\n"
1541 "STACK_OF(SSL_CIPHER):struct stack_st_SSL_CIPHER\n"
1542 "STACK_OF(GENERAL_NAME):struct stack_st_GENERAL_NAME\n"
1543 "STACK_OF(CONF_VALUE):struct stack_st_CONF_VALUE\n"
1544 "STACK_OF(ASN1_OBJECT):struct stack_st_ASN1_OBJECT\n"
1545 "STACK_OF(POLICYINFO):struct stack_st_POLICYINFO\n"
1546 "STACK_OF(DIST_POINT):struct stack_st_DIST_POINT\n"
1547 "STACK_OF(X509_EXTENSION):struct stack_st_X509_EXTENSION\n"
1548 "STACK:struct stack_st\n"
1550 "Uint8:unsigned char\n"
1551 "Sint8:signed char\n"
1552 "Uint16:unsigned short\n"
1553 "Sint16:signed short\n"
1554 "Uint32:unsigned long\n"
1555 "Sint32:signed long\n"
1556 "Uint64:unsigned long long\n"
1557 "Sint64:signed long long\n"
1558 "SDL_version:struct !\n"
1559 "SDL_RWops:struct SDL_RWops\n"
1560 "SDL_Rect:struct !\n"
1561 "SDL_Color:struct !\n"
1562 "SDL_Palette:struct !\n"
1563 "SDL_PixelFormat:struct SDL_PixelFormat\n"
1564 "SDL_blit:int (*)(struct SDL_Surface *src,void *srcrect,"
1565 "struct SDL_Surface *dst,void *dstrect)\n"
1566 "SDL_Surface:struct SDL_Surface\n"
1567 "SDL_VideoInfo:struct !\n"
1568 "SDL_Overlay:struct SDL_Overlay\n"
1569 "SDL_GLattr:enum ?\n"
1570 "SDL_GrabMode:enum ?\n"
1571 "SDL_audiostatus:enum ?\n"
1572 "SDL_AudioSpec:struct !\n"
1573 "SDL_AudioCVT:struct SDL_AudioCVT\n"
1575 "SDL_CDtrack:struct !\n"
1576 "SDL_CD:struct SDL_CD\n"
1577 "SDL_Joystick:struct _SDL_Joystick\n"
1580 "SDL_keysym:struct !\n"
1581 "SDL_ActiveEvent:struct !\n"
1582 "SDL_KeyboardEvent:struct !\n"
1583 "SDL_MouseMotionEvent:struct !\n"
1584 "SDL_MouseButtonEvent:struct !\n"
1585 "SDL_JoyAxisEvent:struct !\n"
1586 "SDL_JoyBallEvent:struct !\n"
1587 "SDL_JoyHatEvent:struct !\n"
1588 "SDL_JoyButtonEvent:struct !\n"
1589 "SDL_ResizeEvent:struct !\n"
1590 "SDL_ExposeEvent:struct !\n"
1591 "SDL_QuitEvent:struct !\n"
1592 "SDL_UserEvent:struct !\n"
1593 "SDL_SysWMmsg:struct SDL_SysWMmsg\n"
1594 "SDL_SysWMEvent:struct !\n"
1595 "SDL_Event:union ?\n"
1596 "SDL_eventaction:enum ?\n"
1597 "SDL_EventFilter:void *\n"
1598 "WMcursor:struct WMcursor\n"
1599 "SDL_Cursor:struct !\n"
1600 "SDL_mutex:struct SDL_mutex\n"
1601 "SDL_sem:struct SDL_semaphore\n"
1602 "SDL_cond:struct SDL_cond\n"
1603 "SDL_Thread:struct SDL_Thread\n"
1604 "SDL_TimerCallback:unsigned long (*)(unsigned long)\n"
1605 "SDL_NewTimerCallback:unsigned long (*)(unsigned long,void *)\n"
1606 "SDL_TimerID:struct _SDL_TimerID\n"
1607 "SDL_errorcode:enum ?\n"
1608 "FPSmanager:struct !\n"
1609 "Mix_Chunk:struct !\n"
1610 "Mix_Music:struct !\n"
1611 "Mix_MusicType:enum ?\n"
1612 "Mix_EffectFunc_t:void (*)(int,void *,int,void *)\n"
1613 "Mix_EffectDone_t:void (*)(int,void *)\n"
1614 "Mix_Fading:enum ?\n"
1615 "IPaddress:struct !\n"
1616 "TCPsocket:void *\n"
1617 "UDPpacket:struct !\n"
1618 "UDPsocket:void *\n"
1619 "SDLNet_SocketSet:void *\n"
1620 "SDLNet_GenericSocket:void *\n"
1621 "TTF_Font:struct !\n"
1624 static const struct CPP_TypeField CPP_Field
[] = {
1625 {"int", 3, 0, CPP_TYPE_INT
},
1626 /* long needs special handling due to the fact it is a modifier and a type */
1627 /*{"long", 4, 0, CPP_TYPE_LONG}, */
1628 {"LONG", 4, 0, CPP_TYPE_LONG
},
1629 {"BPTR", 4, 0, CPP_TYPE_LONG
},
1630 {"BSTR", 4, 0, CPP_TYPE_LONG
},
1631 {"CxObj", 5, 0, CPP_TYPE_LONG
},
1632 {"CxMsg", 5, 0, CPP_TYPE_LONG
},
1633 {"ULONG", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1634 {"LONGBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1635 {"CPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1636 {"Tag", 3, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1637 {"Object", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_LONG
},
1638 {"short", 5, 0, CPP_TYPE_WORD
},
1639 {"SHORT", 5, 0, CPP_TYPE_WORD
},
1640 {"COUNT", 5, 0, CPP_TYPE_WORD
},
1641 {"WORD", 4, 0, CPP_TYPE_WORD
},
1642 {"USHORT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1643 {"UWORD", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1644 {"UCOUNT", 6, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1645 {"WORDBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1646 {"RPTR", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_WORD
},
1647 {"BOOL", 4, CPP_FLAG_BOOLEAN
, CPP_TYPE_WORD
},
1648 {"char", 4, 0, CPP_TYPE_BYTE
},
1649 {"BYTE", 4, 0, CPP_TYPE_BYTE
},
1650 {"UBYTE", 5, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1651 {"TEXT", 4, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1652 {"BYTEBITS", 8, CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1653 {"float", 5, 0, CPP_TYPE_FLOAT
},
1654 {"FLOAT", 5, 0, CPP_TYPE_FLOAT
},
1655 {"double", 6, 0, CPP_TYPE_DOUBLE
},
1656 {"DOUBLE", 6, 0, CPP_TYPE_DOUBLE
},
1657 {"void", 4, 0, CPP_TYPE_VOID
},
1658 {"VOID", 4, 0, CPP_TYPE_VOID
},
1659 {"APTR", 4, CPP_FLAG_POINTER
, CPP_TYPE_VOID
},
1660 {"STRPTR", 6, CPP_FLAG_POINTER
|CPP_FLAG_STRPTR
, CPP_TYPE_BYTE
},
1661 {"CONST_STRPTR",12,CPP_FLAG_POINTER
|CPP_FLAG_CONST
, CPP_TYPE_BYTE
},
1662 {"ClassID", 7, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1663 {"PLANEPTR", 8, CPP_FLAG_POINTER
|CPP_FLAG_UNSIGNED
, CPP_TYPE_BYTE
},
1667 /* defaults: "Library" shortbname+".library" basename-last 4 chars */
1668 static const struct Proto_LibType Proto_LibTypes
[] = {
1669 {"DOSBase", "DosLibrary", 0, 0},
1670 {"SysBase", "ExecBase", 0, 0},
1671 {"ExpansionBase", "ExpansionBase", 0, 0},
1672 {"GfxBase", "GfxBase", "graphics.library", "graphics"},
1673 {"IntuitionBase", "IntuitionBase", 0, 0},
1674 {"LocaleBase", "LocaleBase", 0, 0},
1675 {"MathIeeeDoubBasBase", "MathIEEEBase", 0, 0},
1676 {"MathIeeeDoubTransBase", "MathIEEEBase", 0, 0},
1677 {"MathIeeeSingBasBase", "MathIEEEBase", 0, 0},
1678 {"MathIeeeSingTransBase", "MathIEEEBase", 0, 0},
1679 {"RealTimeBase", "RealTimeBase", 0, 0},
1680 {"RexxSysBase", "RxsLib", 0, 0},
1681 {"UtilityBase", "UtilityBase", 0, 0},
1682 {"WorkbenchBase", 0, "workbench.library", "wb"},
1683 /* resources - The Node entries may be correct, but I don't know it. */
1684 {"BattClockBase", 0/*"Node"*/, "battclock.resource", 0},
1685 {"BattMemBase", 0/*"Node"*/, "battmem.resource", 0},
1686 {"CardResource", 0/*"Node"*/, "card.resource", "cardres"},
1687 {"DiskBase", "DiskResource", "disk.resource", 0},
1688 {"MiscBase", 0/*"Node"*/, "misc.resource", 0},
1689 {"PotgoBase", 0/*"Node"*/, "potgo.resource", 0},
1691 {"ConsoleDevice", 0/*"Device"*/, "console.device", "console"},
1692 {"InputBase", 0/*"Device"*/, "input.device", 0},
1693 {"RamdriveDevice", 0/*"Device"*/, "ramdrive.device", "ramdrive"},
1694 {"TimerBase", 0/*"Device"*/, "timer.device", 0},
1695 /* non default Basenames */
1696 {"DatamasterBase", "DatamasterBase", 0, 0},
1697 {"PPBase", "PPBase", "powerpacker.library", "powerpacker"},
1698 {"ReqToolsBase", "ReqToolsBase", 0, 0},
1699 {"UnpackBase", "UnpackLibrary", 0, 0},
1700 {"xfdMasterBase", "xfdMasterBase", 0, 0},
1701 {"xadMasterBase", "xadMasterBase", 0, 0},
1702 /*{"xvsBase", "xvsBase", 0, 0}, now completely private */
1703 {"GTXBase", "GTXBase", "gadtoolsbox.library", "gtx"},
1704 {"ArpBase", "ArpBase", 0, 0},
1705 {"PopupMenuBase", "PopupMenuBase", 0, "pm"},
1706 {"PowerPCBase", "PPCBase", 0, 0},
1707 {"MC68060Base", 0, "68060.library", "mc68060"},
1708 {"MC68040Base", 0, "68040.library", "mc68040"},
1709 {"MC680x0Base", 0, "680x0.library", "mc680x0"},
1710 {"P96Base", 0, "Picasso96API.library","Picasso96"},
1711 {"Warp3DPPCBase", 0, "Warp3DPPC.library" ,"Warp3D"},
1712 {"CyberGfxBase", 0, "cybergraphics.library", "cybergraphics"},
1716 /* CachePostDMA, CachePreDMA are done by #?DMA check */
1717 static const struct Pragma_ExecpName Pragma_ExecpNames
[] = {
1718 {"VFWritef", "FWritef"},
1719 {"VFPrintf", "FPrintf"},
1720 {"VPrintf", "Printf"},
1723 {"CloneTagItems", 0},
1725 {"FreeTagItems", 0},
1727 {"PackBoolTags", 0},
1728 {"PackStructureTags", 0},
1729 {"UnpackStructureTags", 0},
1730 {"BGUI_PackStructureTags", 0},
1731 {"BGUI_UnpackStructureTags", 0},
1732 {"Inet_NtoA", 0}, /* socket.library */
1733 {"vsyslog", "syslog"},
1734 {"NewPPCStackSwap", 0},
1735 {"FindTagItemPPC", 0},
1736 {"GetTagDataPPC", 0},
1739 {"SetScheduling", 0},
1740 {"W3D_CreateContext", "W3D_CreateContextTags"},
1741 {"W3D_RequestMode", "W3D_RequestModeTags"},
1742 {"W3D_AllocTexObj", "W3D_AllocTexObjTags"},
1743 {"W3D_BestModeID", "W3D_BestModeIDTags"},
1747 /* This field contains functions, which should not be created as inlines with
1748 some targets. At the moment these are varargs functions, which are used in
1749 the MUI style using complicated defines. Theses functions are disabled in
1750 certain GCC and VBCC environments. */
1751 static const strptr NoCreateInlineFuncs
[] = {
1758 /* For double tagcall names (currently only necessary for dos.library and
1759 datatypes.library). Only one alias supported for a function! */
1760 static const struct Pragma_AliasName Pragma_AliasNames
[] = {
1761 {"AllocDosObject", "AllocDosObjectTagList", FUNCFLAG_NORMAL
},
1762 {"CreateNewProc", "CreateNewProcTagList", FUNCFLAG_NORMAL
},
1763 {"NewLoadSeg", "NewLoadSegTagList", FUNCFLAG_NORMAL
},
1764 {"SystemTagList", "System", FUNCFLAG_NORMAL
},
1765 {"RefreshDTObject", "RefreshDTObjects", FUNCFLAG_TAG
},
1769 /* special names, which get an x before name in BMAP files */
1770 static const strptr BMAPSpecial
[] =
1771 {"abs", "Close", "Exit", "Input", "Open", "Output", "Read", "tan",
1772 "Translate", "Wait", "Write", 0};
1774 #define FIRST_KNOWN_RELEASE 30
1775 #define LAST_KNOWN_RELEASE 45
1776 static const strptr Release
[] =
1778 "Release 1.0", /* V30 */
1779 "Release 1.1", /* V31 */
1780 "Preliminary Release 1.2", /* V32 */
1781 "Release 1.2", /* V33 */
1782 "Release 1.3", /* V34 */
1783 "Release 1.3 A2024", /* V35 */
1784 "Release 2.0", /* V36 */
1785 "Release 2.04", /* V37 */
1786 "Release 2.1", /* V38 */
1787 "Release 3.0", /* V39 */
1788 "Release 3.1", /* V40 */
1789 "Transitional Release 3.2", /* V41 */
1790 "Transitional Release 3.3", /* V42 */
1791 "Transitional Release 3.4", /* V43 */
1792 "Release 3.5", /* V44 */
1793 "Release 3.9", /* V45 */
1796 /* Keywords, which cannot be argument names. They are used case_insensitive to
1797 be sure they make no conflicts in non-C-languages as well.
1798 Currently these are mostly C keywords.
1800 static const strptr Keywords
[] =
1802 "and", "and_eq", "asm", "auto", "bitand",
1803 "bitor", "break", "case", "catch", "char",
1804 "class", "compl", "const", "continue", "default",
1805 "delete", "do", "double", "else", "enum",
1806 "extern", "false", "float", "for", "friend",
1807 "goto", "if", "inline", "int", "long",
1808 "new", "not", "not_eq", "operator", "or",
1809 "or_eq", "private", "protected", "public", "register",
1810 "return", "short", "signed", "sizeof", "static",
1811 "struct", "switch", "template", "this", "throw",
1812 "true", "try", "typedef", "union", "unsigned",
1813 "virtual", "void", "volatile", "wchar_t", "while",
1814 "xor", "xor_eq", "RastPort", "Tag",
1818 #if !defined __SASC && !defined __AROS__ && !defined _WIN32 && !defined __CYGWIN__
1819 static int stricmp(const char *a
, const char *b
)
1821 while(*a
&& tolower(*a
) == tolower(*b
))
1825 return (tolower(*a
) - tolower(*b
));
1828 static int strnicmp(const char *a
, const char *b
, size_t num
)
1830 while(num
&& *a
&& tolower(*a
) == tolower(*b
))
1834 return num
? (tolower(*a
) - tolower(*b
)) : 0;
1838 static strptr
DupString(strptr Str
, size_t Len
)
1841 if((res
= r
= AllocListMem(Len
+1)))
1843 while(Len
-- && *Str
)
1848 printf("DupString %s.\n", res
);
1853 static strptr
AllocListMem(size_t size
)
1857 printf("AllocListMem Size %d.\n", size
);
1859 if((a
= (strptr
) malloc(size
)))
1864 static strptr
SkipBlanks(strptr OldPtr
)
1866 while(*OldPtr
== ' ' || *OldPtr
== '\t')
1871 static strptr
SkipBlanksRet(strptr OldPtr
)
1873 while(*OldPtr
== ' ' || *OldPtr
== '\t' || *OldPtr
== '\n')
1879 This function is used to skip over variable names.
1881 Inputs: OldPtr - pointer to the beginning of a string.
1883 Result: Pointer to the first character of the string, that is not one
1884 of a-z, A-Z, 0-9 or the underscore.
1887 static strptr
SkipName(strptr OldPtr
)
1889 while(isalnum(*OldPtr
) || *OldPtr
== '_')
1894 static int IsNoCreateInlineFunc(const strptr name
)
1897 for(a
= NoCreateInlineFuncs
; *a
; ++a
)
1899 if(!strcmp(name
, *a
))
1905 static uint32
GetTypes(void)
1911 if(!(ptr
= mygetfile(EXTTYPESFILE
, &len
)))
1913 #ifdef EXTTYPESFILEHIDDEN
1914 if((ptr
= getenv("HOME")))
1916 strptr ptrh
= EXTTYPESFILEHIDDEN
;
1919 ptr
= DupString(ptr
, i
+ sizeof(EXTTYPESFILEHIDDEN
) + 1);
1920 if(i
&& ptr
[i
-1] != '/')
1923 ptr
[i
++] = *(ptrh
++);
1925 ptr
= mygetfile(ptr
, &len
);
1927 if(!ptr
) /* disabled following if ptr != 0 */
1929 if(!(ptr
= mygetfile(EXTTYPESFILE2
, &len
)))
1931 DoError(ERR_NOFD2PRAGMATYPES
, 0);
1932 ptr
= (strptr
) InternalTypes
;
1933 len
= sizeof(InternalTypes
)-1;
1936 if((i
= ScanTypes(ptr
, len
)) > 0)
1938 DoError(ERR_WRONG_TYPES_LINE
, i
);
1944 static strptr
GetBaseType(void)
1946 static strptr basetype
= 0;
1949 if(Flags2
& FLAG2_VOIDBASE
)
1950 basetype
= "void *";
1953 for(i
= 0; !libtype
&& BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1955 if(!(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1957 libtype
= Proto_LibTypes
[i
].StructureName
;
1961 if(libtype
&& (basetype
= malloc(strlen(libtype
) + 9+1)))
1963 sprintf(basetype
, "struct %s *", libtype
);
1966 basetype
= "struct Library *";
1972 static strptr
GetBaseTypeLib(void)
1979 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1981 if(Proto_LibTypes
[i
].StructureName
&&
1982 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
1984 return Proto_LibTypes
[i
].StructureName
;
1990 static strptr
GetLibraryName(void)
1997 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
1999 if(Proto_LibTypes
[i
].LibraryName
&&
2000 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
2002 return (libname
= Proto_LibTypes
[i
].LibraryName
);
2005 if(!(libname
= malloc(strlen(ShortBaseName
)+9)))
2008 /* auto create name */
2009 for(i
= 0; ShortBaseName
[i
]; ++i
)
2010 libname
[i
] = ShortBaseName
[i
];
2011 strcpy(libname
+i
,".library");
2015 static strptr
GetIFXName(void)
2017 static char IFXName
[256];
2018 sprintf(IFXName
, "%c%s", toupper(ShortBaseName
[0]), ShortBaseName
+1);
2022 static int32
MakeShortBaseName(void)
2027 ptr
= p2
= args
.infile
;
2030 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
2035 /* first get name from file */
2037 p2
-= (sizeof(SFDFILEEXTENSION
)-1);
2038 if(p2
> ptr
&& !stricmp(p2
, SFDFILEEXTENSION
))
2039 ShortBaseName
= DupString(ptr
, p2
-ptr
);
2040 p2
+= sizeof(SFDFILEEXTENSION
)-sizeof(FDFILEEXTENSION
);
2041 if(p2
> ptr
&& !stricmp(p2
, FDFILEEXTENSION
))
2042 ShortBaseName
= DupString(ptr
, p2
-ptr
);
2044 /* then try exceptions (overriding filename) */
2047 for(i
= 0; BaseName
&& Proto_LibTypes
[i
].BaseName
; ++i
)
2049 if(Proto_LibTypes
[i
].ShortBaseName
&&
2050 !(strcmp(Proto_LibTypes
[i
].BaseName
, BaseName
)))
2052 if(!(ShortBaseName
= DupString(Proto_LibTypes
[i
].ShortBaseName
,
2053 strlen(Proto_LibTypes
[i
].ShortBaseName
))))
2058 /* and last use default method */
2060 ShortBaseName
= DupString(BaseName
, strlen(BaseName
)-4);
2066 ptr
= ShortBaseName
;
2067 while((*ptr
= tolower(*ptr
))) /* Convert to lowercase */
2070 if((ShortBaseNameUpper
= DupString(ShortBaseName
, strlen(ShortBaseName
))))
2072 ptr
= ShortBaseNameUpper
;
2073 while((*ptr
= toupper(*ptr
))) /* Convert to uppercase */
2082 static uint32
OpenDest(strptr name
)
2084 static uint8 printedname
= 0;
2087 t
= (strptr
) tempbuf
;
2088 if((b
= args
.to
) && *b
)
2092 if(*(t
-1) != ':' && *(t
-1) != '/')
2097 if(!(Flags
& FLAG_SINGLEFILE
))
2098 printf("ResultFile: %s%s\n", tempbuf
, name
);
2099 else if(!printedname
++)
2101 printf("ResultType: %s", tempbuf
); printf(filenamefmt
, "*");
2111 HEADER
= mygetfile((strptr
)tempbuf
, &headersize
);
2115 if((outfile
= fopen((strptr
)tempbuf
, "wb")))
2117 DoError(ERR_OPEN_FILE
, 0, tempbuf
);
2121 static uint32
CloseDest(strptr name
)
2128 if(!(Flags
& FLAG_DONE
) || !Output_Error
)
2131 if(!Output_Error
|| !(Flags
& FLAG_SINGLEFILE
))
2132 DoError(ERR_EMPTY_FILE
, 0);
2134 t
= (strptr
) tempbuf
;
2135 if((b
= args
.to
) && *b
)
2139 if(*(t
-1) != ':' && *(t
-1) != '/')
2146 remove((strptr
)tempbuf
);
2149 Flags
&= ~FLAG_DONE
; /* clear the flag */
2156 static uint32
MakeTagFunction(struct AmiPragma
*ap
)
2158 size_t len
= strlen(ap
->FuncName
);
2162 printf("MakeTagFunction:\n");
2165 if(!ap
->NumArgs
|| ap
->TagName
)
2169 ap
->Flags
|= AMIPRAGFLAG_OWNTAGFUNC
;
2171 while(Pragma_ExecpNames
[i
].FunctionName
&& /* check the exception names */
2172 strcmp(ap
->FuncName
, Pragma_ExecpNames
[i
].FunctionName
))
2175 if(Pragma_ExecpNames
[i
].FunctionName
)
2177 if(!(ap
->TagName
= Pragma_ExecpNames
[i
].TagName
))
2179 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
2183 else if(ap
->FuncName
[len
-1] == 'A')
2185 /* skip names with DMA or MESA at end */
2186 if(!strcmp(ap
->FuncName
+len
-3, "DMA") ||
2187 !strcmp(ap
->FuncName
+len
-4, "MESA") ||
2188 !strcmp(ap
->FuncName
+len
-4, "RGBA") ||
2189 !strcmp(ap
->FuncName
+len
-5, "AMIGA"))
2190 { ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
; --tagfuncs
; return 1;}
2191 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-1)))
2194 else if(!strcmp(ap
->FuncName
+ len
-7, "TagList"))
2196 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-3)))
2198 ap
->TagName
[len
-4] = 's';
2200 else if(!strcmp(ap
->FuncName
+ len
-4, "Args"))
2202 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
-4)))
2205 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "tags") ||
2206 !stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "taglist"))
2208 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
2210 memcpy(ap
->TagName
+ len
, "Tags", 5);
2212 else if(!stricmp(ap
->Args
[ap
->CallArgs
-1].ArgName
, "args"))
2214 if(!(ap
->TagName
= DupString(ap
->FuncName
, len
+4)))
2216 memcpy(ap
->TagName
+ len
, "Args", 5);
2220 ap
->Flags
^= AMIPRAGFLAG_OWNTAGFUNC
;
2221 --tagfuncs
; /* not a tagfunction, incrementing was false, undo it */
2226 printf("MakeTagFunction: %s / %s (...%s)\n", ap
->TagName
,
2227 ap
->FuncName
, ap
->Args
[ap
->CallArgs
-1].ArgName
);
2233 static void MakeLines(strptr buffer
, uint32 size
)
2237 /* make a real C++ zero string ending line */
2248 /* Do any special functions, which cannot be done with other exception
2249 stuff - currently only dos.library DoPkt function. */
2250 static uint32
SpecialFuncs(void)
2252 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
,
2253 *ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2255 /* first let one more go away, so we can detect if the DoPkt parts are
2256 already inserted in the FD file */
2258 while(ap2
&& (struct AmiPragma
*)(ap2
->List
.Next
) != ap
)
2259 ap2
= (struct AmiPragma
*)(ap2
->List
.Next
);
2261 if(ap2
&& ap2
->Bias
== 0xF0 && ap
->Bias
!= 0xF0 &&
2262 !strcmp("DoPkt", ap2
->FuncName
))
2264 struct AmiPragma
*d
;
2267 RemoveItem(&AmiPragma
, (struct ShortList
*) ap
); /* add in correct order */
2268 for(i
= 0; i
< 5; ++i
)
2270 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
2272 memcpy(d
, ap2
, sizeof(struct AmiPragma
));
2273 d
->FuncName
= DupString(ap2
->FuncName
, 6);
2274 d
->FuncName
[5] = '0'+i
;
2275 d
->NumArgs
= d
->CallArgs
= i
+ 2;
2276 AddItem(&AmiPragma
, (struct ShortList
*) d
);
2278 AddItem(&AmiPragma
, (struct ShortList
*) ap
);
2283 static void SortFDList(void)
2285 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.First
, *ap2
, *ap3
;
2286 AmiPragma
.First
= AmiPragma
.Last
= 0;
2291 ap2
= (struct AmiPragma
*) AmiPragma
.First
;
2293 /* for FD2Inline style we need to use strcmp instead of stricmp here */
2294 while(ap2
&& stricmp(ap2
->FuncName
, ap
->FuncName
) < 0)
2297 ap2
= (struct AmiPragma
*) ap2
->List
.Next
;
2301 ap
= (struct AmiPragma
*) ap
->List
.Next
;
2305 ap2
->List
.Next
= (struct ShortList
*) ap3
->List
.Next
;
2306 ap3
->List
.Next
= (struct ShortList
*) ap2
;
2310 ap2
->List
.Next
= AmiPragma
.First
;
2311 AmiPragma
.First
= (struct ShortList
*) ap2
;
2313 if(ap
&& !ap
->List
.Next
)
2314 AmiPragma
.Last
= (struct ShortList
*) ap2
;
2318 static void AddAliasName(struct AmiPragma
*ap
, struct Pragma_AliasName
*alias
,
2323 if(ap
->NumAlias
> NUMALIASNAMES
)
2324 DoError(ERR_ALIASNAMES
, linenum
, NUMALIASNAMES
);
2327 /* prevent double names */
2328 for(i
= 0; i
< ap
->NumAlias
; ++i
)
2330 if(!strcmp(ap
->AliasName
[i
]->AliasName
, alias
->AliasName
))
2333 ap
->AliasName
[ap
->NumAlias
++] = alias
;
2337 static uint32
CheckNames(struct AmiPragma
*ap
)
2343 printf("CheckNames\n");
2345 for(i
= 0; i
< ap
->CallArgs
; ++i
)
2347 if(!ap
->Args
[i
].ArgName
)
2349 if(!(ap
->Args
[i
].ArgName
= (strptr
)
2350 AllocListMem(4+strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2352 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2356 for(k
= Keywords
; *k
; ++k
)
2358 if(!stricmp(ap
->Args
[i
].ArgName
, *k
))
2360 DoError(ERR_ARGNAME_KEYWORD_CONFLICT
, ap
->Line
, i
, *k
);
2361 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4
2362 +strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2364 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2367 for(j
= 0; j
< i
; ++j
)
2369 if(!stricmp(ap
->Args
[i
].ArgName
, ap
->Args
[j
].ArgName
))
2371 DoError(ERR_ARGNAME_ARGNAME_CONFLICT
, ap
->Line
, i
+1, j
+1);
2372 if(!(ap
->Args
[i
].ArgName
= (strptr
) AllocListMem(4
2373 +strlen(RegNames
[ap
->Args
[i
].ArgReg
]))))
2375 sprintf(ap
->Args
[i
].ArgName
, "%sarg", RegNames
[ap
->Args
[i
].ArgReg
]);
2380 /* NOTE: the replaced argument names aren't checked for conflicts */
2381 /* replaced names are of style a0arg */
2385 static uint32
ScanSFDFile(enum ABI abi
)
2391 uint32 functype
= 0;
2393 Flags2
|= FLAG2_SFDMODE
;
2395 if(strncmp("==id", in
.pos
, 4))
2396 DoError(ERR_SFD_START
, 1);
2398 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
2402 if(linenum
< 5 && in
.pos
[1] == ' ' && in
.pos
[2] == '\"')
2406 for(s
= in
.pos
; *s
&& *s
!= '"'; ++s
)
2408 if(*s
) /* library name */
2411 printf("ScanSFDFile: found library name comment\n");
2416 *(s
++) = 0; /* clear the " */
2418 Flags2
|= FLAG2_LIBNAMECOM
;
2429 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2435 d
->Private
= _public
? 0 : 1;
2436 AddItem(&Comment
, (struct ShortList
*) d
);
2443 else if(*in
.pos
== '=' && in
.pos
[1] == '=')
2446 actcom
= 0; /* no Comment */
2448 if(!strnicmp(in
.pos
, "basetype", 8))
2451 printf("ScanSFDFile: found ==basetype\n");
2453 if(!(Flags2
& FLAG2_LIBTYPE
))
2456 DoError(ERR_LIBTYPE_DECLARED_TWICE
, linenum
);
2458 in
.pos
= SkipBlanks(in
.pos
+8);
2459 if(strncmp(in
.pos
, "struct", 6))
2460 DoError(ERR_EXPECTED_STRUCT
, linenum
);
2463 in
.pos
= SkipBlanks(in
.pos
+6);
2465 DoError(ERR_EXPECTED_LIBTYPE
, linenum
);
2469 in
.pos
= SkipName(libtype
);
2470 if(*SkipBlanks(in
.pos
) != '*')
2471 DoError(ERR_EXPECTED_POINTERSIGN
, linenum
);
2478 DoError(ERR_COMMANDLINE_LIBTYPE
, linenum
);
2482 else if(!strnicmp(in
.pos
, "copyright", 9))
2484 Copyright
= SkipBlanks(in
.pos
+9);
2488 else if(!strnicmp(in
.pos
, "libname", 7))
2491 printf("ScanSFDFile: found ==libname\n");
2493 if(!(Flags2
& FLAG2_LIBNAME
))
2495 if(libname
&& !(Flags2
& FLAG2_LIBNAMECOM
))
2496 DoError(ERR_LIBNAME_DECLARED_TWICE
, linenum
);
2498 in
.pos
= SkipBlanks(in
.pos
+7);
2500 DoError(ERR_EXPECTED_LIBNAME
, linenum
);
2502 in
.pos
= SkipName(libname
= in
.pos
);
2505 DoError(ERR_COMMANDLINE_LIBNAME
, linenum
);
2509 else if(!strnicmp(in
.pos
, "base", 4))
2514 printf("ScanSFDFile: found ==base\n");
2516 if(!(Flags
& FLAG_BASENAME
))
2519 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
2521 in
.pos
= SkipBlanks(in
.pos
+4);
2523 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
2527 BaseName
= oldptr
= in
.pos
;
2528 in
.pos
= SkipName(in
.pos
);
2529 if(!(in
.pos
-oldptr
))
2530 DoError(ERR_EXPECTED_BASENAME
, linenum
);
2534 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
2539 else if(!strnicmp(in
.pos
, "bias", 4))
2545 printf("ScanSFDFile: found ==bias\n");
2548 newbias
= strtol(in
.pos
, &ptr
, 10);
2550 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
2551 else if(newbias
< 0)
2553 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
2558 in
.pos
= SkipName(in
.pos
);
2560 else if(!strnicmp(in
.pos
, "end", 3))
2564 else if(!strnicmp(in
.pos
, "public", 6))
2569 else if(!strnicmp(in
.pos
, "private", 7))
2574 else if(!strnicmp(in
.pos
, "abi", 3))
2577 printf("ScanSFDFile: found ==abi\n");
2579 in
.pos
= SkipBlanks(in
.pos
+3);
2580 if(!strnicmp(in
.pos
, "M68k", 4))
2582 abi
= ABI_M68K
; in
.pos
+= 4;
2584 else if(!strnicmp(in
.pos
, "PPC0", 4))
2586 abi
= ABI_PPC0
; in
.pos
+= 4;
2588 else if(!strnicmp(in
.pos
, "PPC2", 4))
2590 abi
= ABI_PPC2
; in
.pos
+= 4;
2592 else if(!strnicmp(in
.pos
, "PPC", 3))
2594 abi
= ABI_PPC
; in
.pos
+= 3;
2597 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
2599 else if(!strnicmp(in
.pos
, "id", 2))
2602 DoError(ERR_IDSTRING_DECLARED_TWICE
, linenum
);
2603 IDstring
= in
.pos
= SkipBlanks(in
.pos
+2);
2604 if(strncmp(in
.pos
, "$Id: ", 5))
2606 DoError(ERR_EXCPECTED_IDSTRING
, linenum
);
2610 if(*(in
.pos
-1) != '$')
2611 DoError(ERR_EXPECTED_ID_ENDSIGN
, linenum
);
2613 else if(!strnicmp(in
.pos
, "include", 7))
2617 if(!(d
= (struct Include
*) NewItem(&Includes
)))
2619 d
->Include
= SkipBlanks(in
.pos
+7);
2620 AddItem(&Includes
, (struct ShortList
*) d
);
2624 else if(!strnicmp(in
.pos
, "varargs", 7))
2627 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2631 bias
-= BIAS_OFFSET
;
2632 functype
|= FUNCFLAG_TAG
;
2636 else if(!strnicmp(in
.pos
, "alias", 5))
2639 DoError(ERR_VARARGS_ALIAS_FIRST
, linenum
);
2643 bias
-= BIAS_OFFSET
;
2644 functype
|= FUNCFLAG_ALIAS
;
2648 else if(!strnicmp(in
.pos
, "version", 7))
2650 /* store version entries as comments */
2655 in
.pos
= SkipBlanks(in
.pos
+7);
2656 v
= strtol(in
.pos
, &ptr
, 10);
2658 printf("ScanSFDFile: found ==version %d\n", v
);
2660 if(ptr
== in
.pos
|| v
< 0)
2661 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2664 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2670 d
->Private
= _public
? 0 : 1;
2671 AddItem(&Comment
, (struct ShortList
*) d
);
2672 in
.pos
= SkipName(in
.pos
);
2675 else if(!strnicmp(in
.pos
, "reserve", 7))
2677 /* store reserved entries as comments */
2682 in
.pos
= SkipBlanks(in
.pos
+7);
2683 v
= strtol(in
.pos
, &ptr
, 10);
2685 printf("ScanSFDFile: found ==reserve %d\n", v
);
2689 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
2693 if(ptr
== in
.pos
|| v
< 0)
2694 DoError(ERR_EXPECTED_POSITIVE_DECIMAL_NUMBER
, linenum
);
2697 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
2703 d
->Private
= _public
? 0 : 1;
2704 AddItem(&Comment
, (struct ShortList
*) d
);
2705 in
.pos
= SkipName(in
.pos
);
2706 bias
+= BIAS_OFFSET
*v
;
2710 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
2714 uint32 ft
, startlinenum
;
2715 struct AmiPragma ap
, *ap2
;
2716 struct ClibData d
, *f
;
2722 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
2723 /* join lines, if necessary */
2724 startlinenum
= linenum
;
2726 /* first open bracket */
2727 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
)
2728 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2730 ft
= 0; /* this is needed for function pointer types, which have own
2732 /* first close bracket */
2733 while((*data
!= /*(*/')' || ft
) && data
< in
.buf
+ in
.size
)
2740 else if(*data
== '('/*)*/)
2742 else if(*data
== /*(*/')')
2746 /* second open bracket */
2747 while(*data
!= '('/*)*/ && data
< in
.buf
+ in
.size
)
2748 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2749 /* second close bracket */
2750 while(*data
!= /*(*/')' && data
< in
.buf
+ in
.size
)
2751 { if(!*data
) {*data
= ' '; ++linenum
; } ++data
; }
2752 if(data
== in
.buf
+ in
.size
)
2755 DoError(ERR_UNEXPECTED_FILEEND
, linenum
);
2759 ft
= functype
; functype
= 0;
2760 memset(&ap
, 0, sizeof(struct AmiPragma
));
2761 memset(&d
, 0, sizeof(struct ClibData
));
2762 if(!GetCPPType(&d
.ReturnType
, in
.pos
, 1, 1))
2764 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE
, startlinenum
);
2769 else if(d
.ReturnType
.Unknown
)
2770 DoError(ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, startlinenum
,
2771 d
.ReturnType
.Unknown
);
2773 ap
.FuncName
= d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
2774 +d
.ReturnType
.FullLength
);
2775 in
.pos
= SkipBlanks(SkipName(d
.FuncName
));
2777 if(*in
.pos
!= '('/*)*/)
2779 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2783 *(SkipName(d
.FuncName
)) = 0;
2784 in
.pos
= SkipBlanks(++in
.pos
);
2787 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2789 oldptr
= (strptr
) 1;
2790 if(d
.NumArgs
>= maxreg
)
2792 DoError(ERR_TO_MUCH_ARGUMENTS
, startlinenum
);
2795 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], in
.pos
, 0, 0))
2797 DoError(ERR_UNKNOWN_VARIABLE_TYPE
, startlinenum
, d
.NumArgs
);
2800 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
2801 DoError(ERR_UNKNOWN_VARIABLE_TYPE_INT
, startlinenum
, d
.NumArgs
,
2802 d
.Args
[d
.NumArgs
-1].Unknown
);
2804 oldptr
= in
.pos
= SkipBlanks(d
.Args
[d
.NumArgs
-1].TypeStart
2805 + d
.Args
[d
.NumArgs
-1].FullLength
);
2806 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
2808 if(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
)
2810 oldptr
= d
.Args
[d
.NumArgs
-1].FunctionName
;
2813 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2816 else if(!(oldptr
= DupString(oldptr
, SkipName(oldptr
)-oldptr
)))
2818 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
2822 ap
.Args
[ap
.CallArgs
++].ArgName
= in
.pos
;
2823 in
.pos
= SkipName(in
.pos
);
2825 if(in
.pos
== oldptr
)
2827 DoError(ERR_EXPECTED_ARGUMENT_NAME
, startlinenum
);
2835 in
.pos
= SkipBlanks(in
.pos
);
2836 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
2838 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2843 in
.pos
= SkipBlanks(++in
.pos
);
2844 if(d
.Args
[d
.NumArgs
-1].Type
!= CPP_TYPE_VARARGS
&&
2845 !(d
.Args
[d
.NumArgs
-1].Flags
& CPP_FLAG_FUNCTION
))
2846 *(SkipName(oldptr
)) = 0;
2848 printf("Added last argument %d (%s) for %s (%d bytes)\n", d
.NumArgs
,
2849 oldptr
, d
.FuncName
, d
.Args
[d
.NumArgs
-1].FullLength
);
2856 in
.pos
= SkipBlanks(++in
.pos
);
2857 *(SkipName(oldptr
)) = 0;
2859 printf("Added argument %d (%s) for %s (%d bytes)\n", d
.NumArgs
,
2860 oldptr
, d
.FuncName
, d
.Args
[d
.NumArgs
-1].FullLength
);
2864 if(*in
.pos
== /*(*/')')
2866 if(!oldptr
) /* oldptr == 0 means parsing was valid */
2868 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
2871 memcpy(f
, &d
, sizeof(struct ClibData
));
2877 struct ClibData
*e
= clibdata
;
2884 printf("Added prototype for %s (line %ld) with %d args\n", f
->FuncName
,
2885 startlinenum
, f
->NumArgs
);
2887 if(*(in
.pos
= SkipBlanks(in
.pos
)) != '('/*)*/)
2889 DoError(ERR_EXPECTED_OPEN_BRACKET
, startlinenum
);
2896 DoError(ERR_ASSUMING_BIAS_OF_30
, startlinenum
);
2902 ap
.Line
= startlinenum
;
2903 bias
+= BIAS_OFFSET
;
2906 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
2910 while(*in
.pos
&& *in
.pos
!= /*(*/')')
2912 if(*in
.pos
!= /*(*/')')
2914 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2919 ap
.NumArgs
= ap
.CallArgs
;
2921 ap
.Flags
|= AMIPRAGFLAG_PPC
;
2923 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
2924 else if(abi
== ABI_PPC2
)
2925 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
2935 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
2937 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
2940 in
.pos
= SkipName(oldptr
);
2941 len
= in
.pos
-oldptr
;
2943 for(i
= 0; i
< MAXREG
; ++i
)
2944 if(!strnicmp(RegNames
[i
], oldptr
, len
))
2949 DoError(ERR_EXPECTED_REGISTER_NAME
, startlinenum
);
2952 else if(i
== REG_A6
)
2953 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
2954 else if(i
== REG_A5
)
2955 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
2956 else if(i
== REG_A4
)
2957 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
2958 else if(i
== REG_D7
)
2959 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
2960 else if(i
== REG_A7
)
2962 DoError(ERR_A7_NOT_ALLOWED
, startlinenum
);
2965 else if(i
>= REG_FP0
)
2966 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
2968 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
2970 for(i
= 0; i
< ap
.NumArgs
; i
++)
2972 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
2974 DoError(ERR_REGISTER_USED_TWICE
, startlinenum
);
2983 in
.pos
= SkipBlanks(in
.pos
);
2984 if(*in
.pos
!= ',' && *in
.pos
!= '-' && *in
.pos
!= '/' &&
2985 *in
.pos
!= /*(*/')')
2987 DoError(ERR_EXPECTED_CLOSE_BRACKET
, startlinenum
);
2990 } while(*in
.pos
!= /*(*/')');
2992 if(*in
.pos
!= /*(*/')')
3001 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
3002 if(ft
&& !(ft
& FUNCFLAG_TAG
) && ap
.NumArgs
!= ap2
->NumArgs
)
3003 ft
= 0; /* like DoPkt, handle as seperate function */
3004 if(ft
) /* handle alias and varargs */
3006 if(ap2
->TagName
|| (ft
& FUNCFLAG_ALIAS
))
3008 struct Pragma_AliasName
*p
;
3010 if((p
= (struct Pragma_AliasName
*)
3011 AllocListMem(sizeof(struct Pragma_AliasName
))))
3013 p
->FunctionName
= ap2
->TagName
;
3014 p
->AliasName
= ap
.FuncName
;
3015 p
->Type
= (ft
& FUNCFLAG_TAG
) ? FUNCFLAG_TAG
: FUNCFLAG_NORMAL
;
3016 AddAliasName(ap2
, p
, startlinenum
);
3023 ap2
->TagName
= ap
.FuncName
;
3026 if(ap
.CallArgs
!= ap2
->CallArgs
)
3028 if(ap2
->CallArgs
+ 1 == ap
.CallArgs
&& d
.Args
[d
.NumArgs
-1].Type
3029 == CPP_TYPE_VARARGS
)
3036 if(ap
.NumArgs
!= ap2
->NumArgs
)
3038 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
3040 else if(abi
== ABI_M68K
)
3044 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3046 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3048 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, startlinenum
);
3054 else if(abi
== ABI_M68K
)
3056 if(ap
.CallArgs
!= ap
.NumArgs
)
3057 { /* this is surely no longer necessary, as there wont be any
3058 varargs functions here */
3059 if(ap
.CallArgs
== ap
.NumArgs
+1 && d
.Args
[d
.NumArgs
-1].Type
3060 == CPP_TYPE_VARARGS
)
3063 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3066 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3068 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3069 DoError(ERR_FLOATARG_NOT_ALLOWED
, startlinenum
);
3070 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3071 && !(Flags
& FLAG_PPCONLY
))
3072 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3073 struct AmiPragma
*d
;
3074 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3076 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3079 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3084 if(!(Flags
& FLAG_NOPPC
))
3086 struct AmiPragma
*d
;
3087 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3089 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3092 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3098 in
.pos
= SkipBlanks(in
.pos
);
3100 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3101 ++in
.pos
; /* skip '\0' */
3105 DoError(ERR_MISSING_SFDEND
, 0);
3110 static uint32
ScanFDFile(void)
3117 uint32 shadowmode
= 0;
3118 enum ABI abi
= ABI_M68K
;
3122 if(!stricmp(defabi
, "M68k"))
3124 else if(!stricmp(defabi
, "PPC0"))
3126 else if(!stricmp(defabi
, "PPC2"))
3128 else if(!stricmp(defabi
, "PPC"))
3131 DoError(ERR_UNKNOWN_ABI
, 0, defabi
);
3134 if(in
.size
> 10 && in
.pos
[0] == '=' && in
.pos
[1] == '=')
3135 return ScanSFDFile(abi
);
3138 printf("ScanFDFile:\n");
3141 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
3143 if(*in
.pos
== '*') /* Comment */
3145 strptr oldpos
= in
.pos
;
3147 printf("ScanFDFile: found a comment\n");
3149 in
.pos
= SkipBlanks(in
.pos
+1);
3150 if(!strnicmp(in
.pos
, "notagcall", 9))
3152 struct AmiPragma
*ap
= (struct AmiPragma
*) AmiPragma
.Last
;
3156 --tagfuncs
; ap
->TagName
= 0;
3157 ap
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3159 in
.pos
= SkipBlanks(in
.pos
+ 9);
3161 else if(!strnicmp(in
.pos
, "tagcall", 7)) /* Tag to create? */
3163 struct AmiPragma
*prevpragma
= (struct AmiPragma
*) AmiPragma
.Last
;
3165 in
.pos
= SkipBlanks(in
.pos
+ 7);
3168 DoError(ERR_TAG_DEF_WITHOUT_PRAGMA
, linenum
);
3173 if(!prevpragma
->NumArgs
)
3175 DoError(ERR_TAGFUNC_NEEDS_ARGUMENT
, linenum
);
3180 /* Get the tag functions name. */
3182 if(!prevpragma
->TagName
&& (_public
|| (Flags
& FLAG_PRIVATE
)))
3187 strptr oldptr
, tptr
= prevpragma
->TagName
;
3189 len
= strlen(prevpragma
->FuncName
)+strlen(in
.pos
)+1;
3190 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
)))
3197 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3198 in
.pos
= SkipName(in
.pos
);
3199 if((len
= in
.pos
-oldptr
))
3201 removeptr
= prevpragma
->TagName
+strlen(prevpragma
->TagName
)-len
;
3202 if(strncmp(removeptr
, oldptr
, len
))
3205 printf("ScanFDFile: *tagcall -: %s, %s, %d\n", removeptr
, oldptr
, len
);
3207 DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL
, linenum
);
3208 prevpragma
->TagName
= tptr
;
3215 in
.pos
= SkipBlanks(in
.pos
);
3218 in
.pos
= SkipBlanks(in
.pos
+1);
3220 *in
.pos
= toupper(*in
.pos
);
3222 in
.pos
= SkipName((oldptr
= in
.pos
));
3223 len
= in
.pos
-oldptr
;
3226 uint32 a
= strlen(prevpragma
->TagName
);
3227 memcpy(prevpragma
->TagName
+a
, oldptr
, len
);
3228 prevpragma
->TagName
[a
+len
] = '\0';
3231 else if(!prevpragma
->TagName
)
3233 len
= strlen(prevpragma
->FuncName
);
3234 if(!(prevpragma
->TagName
= DupString(prevpragma
->FuncName
, len
+4)))
3236 memcpy(prevpragma
->TagName
+ len
, "Tags", 5);
3246 if(!(d
= (struct Comment
*) NewItem(&Comment
)))
3252 d
->Private
= _public
? 0 : 1;
3253 AddItem(&Comment
, (struct ShortList
*) d
);
3260 else if(*in
.pos
== '#' && in
.pos
[1] == '#')
3263 actcom
= 0; /* no Comment */
3265 if(!strnicmp(in
.pos
, "base", 4))
3270 printf("ScanFDFile: found ##base\n");
3272 if(!(Flags
& FLAG_BASENAME
))
3275 DoError(ERR_BASENAME_DECLARED_TWICE
, linenum
);
3277 in
.pos
= SkipBlanks(in
.pos
+4);
3279 DoError(ERR_EXPECTED_SLASH_IN_BASENAME
, linenum
);
3283 BaseName
= oldptr
= in
.pos
;
3284 in
.pos
= SkipName(in
.pos
);
3285 if(!(in
.pos
-oldptr
))
3286 DoError(ERR_EXPECTED_BASENAME
, linenum
);
3290 DoError(ERR_COMMANDLINE_BASENAME
, linenum
);
3295 else if(!strnicmp(in
.pos
, "bias", 4))
3301 printf("ScanFDFile: found ##bias\n");
3304 newbias
= strtol(in
.pos
, &ptr
, 10);
3306 DoError(ERR_EXPECTED_BIAS_VALUE
, linenum
);
3307 else if(newbias
< 0)
3309 DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE
, linenum
);
3314 in
.pos
= SkipName(in
.pos
);
3316 else if(!strnicmp(in
.pos
, "end", 3))
3320 else if(!strnicmp(in
.pos
, "shadow", 6)) /* introduced by Storm */
3323 if(bias
== -1 || !AmiPragma
.First
)
3324 DoError(ERR_EARLY_SHADOW
, linenum
);
3327 bias
-= BIAS_OFFSET
;
3331 else if(!strnicmp(in
.pos
, "public", 6))
3336 else if(!strnicmp(in
.pos
, "private", 7))
3341 else if(!strnicmp(in
.pos
, "abi", 3))
3344 printf("ScanFDFile: found ##abi\n");
3346 in
.pos
= SkipBlanks(in
.pos
+3);
3347 if(!strnicmp(in
.pos
, "M68k", 4))
3349 abi
= ABI_M68K
; in
.pos
+= 4;
3351 else if(!strnicmp(in
.pos
, "PPC0", 4))
3353 abi
= ABI_PPC0
; in
.pos
+= 4;
3355 else if(!strnicmp(in
.pos
, "PPC2", 4))
3357 abi
= ABI_PPC2
; in
.pos
+= 4;
3359 else if(!strnicmp(in
.pos
, "PPC", 3))
3361 abi
= ABI_PPC
; in
.pos
+= 3;
3364 DoError(ERR_UNKNOWN_ABI
, linenum
, in
.pos
);
3367 DoError(ERR_UNKNOWN_DIRECTIVE
, linenum
, in
.pos
-2);
3373 struct AmiPragma ap
, *ap2
;
3376 printf("ScanFDFile: scan Function\n");
3378 memset(&ap
, 0, sizeof(struct AmiPragma
));
3381 oldptr
= in
.pos
= SkipBlanks(in
.pos
);
3382 in
.pos
= SkipName(oldptr
);
3383 if(!(len
= in
.pos
-oldptr
))
3385 DoError(ERR_MISSING_FUNCTION_NAME
, linenum
);
3390 ap
.FuncName
= oldptr
;
3392 in
.pos
= SkipBlanks(in
.pos
);
3393 if(*in
.pos
!= '('/*)*/)
3395 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3400 oldptr
[len
] = '\0'; /* create c string of FunctionName */
3403 printf("ScanFDFile: found function %s\n", ap
.FuncName
);
3406 maxreg
= ((abi
== ABI_M68K
) ? MAXREG
-2 : MAXREGPPC
);
3409 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3411 if(*in
.pos
== '*') /* strange OS3.9 files */
3413 DoError(ERR_ILLEGAL_CHARACTER_DETECTED
, linenum
);
3414 oldptr
= in
.pos
= SkipBlanks(in
.pos
+1);
3417 if(*in
.pos
== /*(*/')' && !ap
.CallArgs
)
3420 if(ap
.CallArgs
>= maxreg
)
3422 DoError(ERR_TO_MUCH_ARGUMENTS
, linenum
); break;
3425 if(!strncmp(in
.pos
, "void", 4))
3427 /* allows "(void)" instead of ()" */
3428 in
.pos
= SkipBlanks(in
.pos
+ 4);
3429 if(*in
.pos
!= /*(*/')')
3430 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3434 if(!strncmp(in
.pos
, "...", 3))
3436 ap
.Flags
= AMIPRAGFLAG_VARARGS
;
3437 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3438 in
.pos
= SkipBlanks(in
.pos
+3);
3439 if(*in
.pos
!= /*(*/')')
3440 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3444 in
.pos
= SkipName(oldptr
);
3447 if(!(len
= in
.pos
-oldptr
))
3449 DoError(ERR_EXPECTED_ARGUMENT_NAME
, linenum
);
3450 ap
.Args
[ap
.CallArgs
++].ArgName
= 0;
3454 ap
.Args
[ap
.CallArgs
++].ArgName
= oldptr
;
3456 in
.pos
= SkipBlanks(in
.pos
);
3458 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3460 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3463 if(*in
.pos
!= /*(*/')') /* create c string ending */
3465 } while(*in
.pos
!= /*(*/')');
3467 if(*in
.pos
!= /*(*/')')
3474 *oldptr
= '\0'; /* create c string ending for last argument */
3478 DoError(ERR_ASSUMING_BIAS_OF_30
, linenum
);
3485 bias
+= BIAS_OFFSET
;
3488 ap
.Flags
|= AMIPRAGFLAG_PUBLIC
;
3490 in
.pos
= SkipBlanks(in
.pos
+1);
3492 if(*in
.pos
|| ap
.CallArgs
)
3493 /* support for FD's without second empty bracket pair */
3495 if(*in
.pos
!= '('/*)*/)
3497 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3508 oldptr
= in
.pos
= SkipBlanks(in
.pos
+ 1);
3510 if(*in
.pos
== /*(*/')' && !ap
.NumArgs
)
3513 if(!strncmp(in
.pos
, "base", 4))
3515 in
.pos
= SkipBlanks(in
.pos
+ 4);
3518 in
.pos
= SkipBlanks(in
.pos
+ 1);
3519 if(!strncmp(in
.pos
, "sysv",4))
3521 /* MorphOS V.4 with base in r3: (base,sysv) */
3522 ap
.Flags
|= AMIPRAGFLAG_MOSBASESYSV
;
3523 ap
.NumArgs
= ap
.CallArgs
;
3524 in
.pos
= SkipBlanks(in
.pos
+ 4);
3525 if(*in
.pos
!= /*(*/')')
3526 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3531 else if(!strncmp(in
.pos
, "sysv", 4))
3533 in
.pos
= SkipBlanks(in
.pos
+ 4);
3536 in
.pos
= SkipBlanks(in
.pos
+ 1);
3537 if(!strncmp(in
.pos
, "r12base",7))
3539 /* MorphOS V.4 without passing base: (sysv) */
3540 ap
.Flags
|= AMIPRAGFLAG_MOSSYSVR12
;
3541 ap
.NumArgs
= ap
.CallArgs
;
3542 in
.pos
= SkipBlanks(in
.pos
+ 7);
3543 if(*in
.pos
!= /*(*/')')
3544 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3548 else if (*in
.pos
== /*(*/')')
3550 /* MorphOS V.4 without passing base: (sysv) */
3551 ap
.Flags
|= AMIPRAGFLAG_MOSSYSV
;
3552 ap
.NumArgs
= ap
.CallArgs
;
3557 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3562 in
.pos
= SkipName(oldptr
);
3563 len
= in
.pos
-oldptr
;
3565 for(i
= 0; i
< MAXREG
; ++i
)
3566 if(!strnicmp(RegNames
[i
], oldptr
, len
))
3571 DoError(ERR_EXPECTED_REGISTER_NAME
, linenum
);
3574 else if(i
== REG_A6
)
3575 ap
.Flags
|= AMIPRAGFLAG_A6USE
;
3576 else if(i
== REG_A5
)
3577 ap
.Flags
|= AMIPRAGFLAG_A5USE
;
3578 else if(i
== REG_A4
)
3579 ap
.Flags
|= AMIPRAGFLAG_A4USE
;
3580 else if(i
== REG_D7
)
3581 ap
.Flags
|= AMIPRAGFLAG_D7USE
;
3582 else if(i
== REG_A7
)
3584 DoError(ERR_A7_NOT_ALLOWED
, linenum
);
3587 else if(i
>= REG_FP0
)
3588 ap
.Flags
|= AMIPRAGFLAG_FLOATARG
;
3590 ap
.Args
[ap
.NumArgs
].ArgReg
= i
;
3592 for(i
= 0; i
< ap
.NumArgs
; i
++)
3594 if(ap
.Args
[ap
.NumArgs
].ArgReg
== ap
.Args
[i
].ArgReg
)
3596 DoError(ERR_REGISTER_USED_TWICE
, linenum
);
3605 in
.pos
= SkipBlanks(in
.pos
);
3606 if(*in
.pos
!= ',' && *in
.pos
!= '/' && *in
.pos
!= /*(*/')')
3608 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3611 } while(*in
.pos
!= /*(*/')');
3613 if(*in
.pos
!= /*(*/')')
3624 while(*in
.pos
&& *in
.pos
!= /*(*/')')
3626 if(*in
.pos
!= /*(*/')')
3628 DoError(ERR_EXPECTED_CLOSE_BRACKET
, linenum
);
3633 ap
.NumArgs
= ap
.CallArgs
;
3635 ap
.Flags
|= AMIPRAGFLAG_PPC
;
3637 ap
.Flags
|= AMIPRAGFLAG_PPC0
;
3638 else if(abi
== ABI_PPC2
)
3639 ap
.Flags
|= AMIPRAGFLAG_PPC2
;
3643 DoError(ERR_EXPECTED_OPEN_BRACKET
, linenum
);
3645 ap2
= (struct AmiPragma
*)(AmiPragma
.Last
);
3648 if(ap2
->TagName
&& !(ap2
->Flags
& AMIPRAGFLAG_OWNTAGFUNC
))
3650 struct Pragma_AliasName
*p
;
3651 DoError(ERR_DOUBLE_VARARGS
, linenum
);
3653 if((p
= (struct Pragma_AliasName
*)
3654 AllocListMem(sizeof(struct Pragma_AliasName
))))
3656 p
->FunctionName
= ap2
->TagName
;
3657 p
->AliasName
= ap
.FuncName
;
3658 p
->Type
= FUNCFLAG_TAG
;
3659 AddAliasName(ap2
, p
, linenum
);
3664 printf("ScanFDFile: StormFD mode, tag func alias: %s\n", ap2
->TagName
);
3670 printf("ScanFDFile: StormFD mode, tag func: %s\n", ap2
->TagName
);
3672 ap2
->Flags
&= ~(AMIPRAGFLAG_OWNTAGFUNC
);
3673 ap2
->TagName
= ap
.FuncName
;
3676 if(ap
.NumArgs
!= ap2
->NumArgs
)
3677 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3678 else if(abi
== ABI_M68K
)
3682 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3684 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3686 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3692 /* handle them as alias instead seperate */
3693 else if(ap2
&& ap2
->Bias
== ap
.Bias
&& ap2
->NumArgs
== ap
.NumArgs
)
3695 struct Pragma_AliasName
*p
;
3697 if((p
= (struct Pragma_AliasName
*)
3698 AllocListMem(sizeof(struct Pragma_AliasName
))))
3700 p
->FunctionName
= ap2
->TagName
;
3701 p
->AliasName
= ap
.FuncName
;
3702 p
->Type
= FUNCFLAG_NORMAL
;
3703 AddAliasName(ap2
, p
, linenum
);
3709 for(i
= 0; i
< ap2
->NumArgs
; ++i
)
3711 if(ap2
->Args
[i
].ArgReg
!= ap
.Args
[i
].ArgReg
)
3713 DoError(ERR_VARARGS_ARGUMENTS_DIFFER
, linenum
);
3721 if(ap
.Flags
& AMIPRAGFLAG_VARARGS
)
3723 ap
.TagName
= ap
.FuncName
;
3726 else if((_public
|| (Flags
& FLAG_PRIVATE
)) &&
3727 !MakeTagFunction(&ap
))
3729 else /* check the alias names */
3733 while(Pragma_AliasNames
[i
].FunctionName
)
3735 if(!strcmp(ap
.FuncName
, Pragma_AliasNames
[i
].FunctionName
) ||
3736 (ap
.TagName
&& !strcmp(ap
.TagName
,
3737 Pragma_AliasNames
[i
].FunctionName
)))
3739 AddAliasName(&ap
, (struct Pragma_AliasName
*)
3740 &Pragma_AliasNames
[i
], linenum
);
3748 if(ap
.CallArgs
!= ap
.NumArgs
)
3749 ap
.Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3751 ap
.Flags
|= AMIPRAGFLAG_M68K
;
3753 if((Flags
& FLAG_NOFPU
) && (ap
.Flags
& AMIPRAGFLAG_FLOATARG
))
3754 DoError(ERR_FLOATARG_NOT_ALLOWED
, linenum
);
3755 else if(((ap
.Flags
& AMIPRAGFLAG_FLOATARG
) || !(Flags
& FLAG_FPUONLY
))
3756 && !(Flags
& FLAG_PPCONLY
))
3757 { /* skip all without FPU when FPUONLY and PPC when PPCONLY */
3758 struct AmiPragma
*d
;
3759 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3761 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3764 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3771 if(!(Flags
& FLAG_NOPPC
))
3773 struct AmiPragma
*d
;
3774 if(!(d
= (struct AmiPragma
*) NewItem(&AmiPragma
)))
3776 memcpy(d
, &ap
, sizeof(struct AmiPragma
));
3779 AddItem(&AmiPragma
, (struct ShortList
*) d
);
3790 in
.pos
= SkipBlanks(in
.pos
);
3792 DoError(ERR_EXTRA_CHARACTERS
, linenum
);
3793 ++in
.pos
; /* skip '\0' */
3797 DoError(ERR_MISSING_END
, 0);
3802 static int32
ScanTypes(strptr ptr
, uint32 size
)
3804 struct CPP_ExternNames
*a
= 0, *b
= 0;
3805 strptr endptr
= ptr
+size
;
3808 for(line
= 1; ptr
< endptr
; ++line
)
3810 struct CPP_ExternNames
*n
;
3812 if(*ptr
== '*') /* skip comments */
3814 while(ptr
< endptr
&& *(ptr
++) != '\n')
3817 else if((n
= (struct CPP_ExternNames
*)
3818 AllocListMem(sizeof(struct CPP_ExternNames
))))
3822 n
->Type
= ptr
; /* store start */
3824 while(ptr
< endptr
&& *ptr
!= ':' && *ptr
!= '\n' && *ptr
!= '\t'
3827 wptr
= SkipBlanks(ptr
);
3828 if(*(wptr
++) != ':')
3832 n
->NameType
.StructureName
= n
->Type
;
3833 n
->NameType
.StructureLength
= ptr
-n
->Type
; /* for struct ! types */
3835 if(!GetCPPType(&n
->NameType
, (ptr
= SkipBlanks(wptr
)), 0, 1))
3838 printf("'%20s', slen %2d, typelen %3d, pntd %d, type %c, sn '%.3s'\n",
3839 n
->Type
, n
->NameType
.StructureLength
, n
->NameType
.FullLength
,
3840 n
->NameType
.PointerDepth
, n
->NameType
.Type
? n
->NameType
.Type
: 's',
3841 n
->NameType
.StructureName
? n
->NameType
.StructureName
: "<e>");
3843 ptr
= SkipBlanks(n
->NameType
.TypeStart
+n
->NameType
.FullLength
);
3844 if(*(ptr
++) != '\n')
3847 printf("%.30s\n", ptr
);
3861 extnames
= b
; /* now store the list */
3865 static void FindHeader(void)
3867 strptr str
= HEADER
;
3882 else if(*str
== '/')
3885 else if(*str
== '*' || *str
== ';')
3887 else if(*str
== '{'/*}*/)
3891 else if(*str
== '('/*)*/ && *(++str
) == '*')
3897 while(*str
&& *(str
++) != '\n')
3903 while(*str
&& (*(str
-1) != '*' || *str
!= '/'))
3905 while(*str
&& *(str
++) != '\n')
3910 while(*str
&& *str
!= /*{*/'}')
3912 while(*str
&& *(str
++) != '\n')
3917 while(*str
&& (*(str
-1) != '*' || *str
!= /*(*/')'))
3919 while(*str
&& *(str
++) != '\n')
3924 headersize
= str
-HEADER
;
3927 HEADER
= 0; headersize
= 0;
3931 /* merge data register pairs for 64-bit argument types */
3932 static void FindRegPairs(struct AmiPragma
*ap
, struct ClibData
*cd
)
3936 for(i
= 0, j
= 0, k
= 0; i
< ap
->CallArgs
|| j
< ap
->NumArgs
; ++i
, ++j
)
3938 if(i
< ap
->CallArgs
&& (cd
->Args
[i
].Type
== CPP_TYPE_DOUBLE
||
3939 cd
->Args
[i
].Type
== CPP_TYPE_LONGLONG
)
3940 && j
< ap
->NumArgs
-1 && ap
->Args
[j
].ArgReg
< REG_D7
3941 && (ap
->Args
[j
].ArgReg
& 1) == 0
3942 && ap
->Args
[j
].ArgReg
+ 1 == ap
->Args
[j
+1].ArgReg
)
3944 ap
->Args
[k
++].ArgReg
= REG_D0D1
+ (ap
->Args
[j
].ArgReg
- REG_D0
) / 2;
3945 ++j
; /* skip next ArgReg */
3947 else if(j
< ap
->NumArgs
)
3948 ap
->Args
[k
++].ArgReg
= ap
->Args
[j
].ArgReg
;
3952 if (ap
->NumArgs
!= ap
->CallArgs
)
3953 ap
->Flags
|= AMIPRAGFLAG_ARGCOUNT
;
3955 ap
->Flags
&= ~AMIPRAGFLAG_ARGCOUNT
;
3958 /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
3959 static uint32
GetRegisterData(struct AmiPragma
*ap
)
3962 48E7 <lower word> MOVEM.L <registers>,-(A7) ; D0 is bit 15
3963 4CDF <upper word> MOVEM.L (A7)+,<registers> ; D0 is bit 0
3965 register uint32 i
, data
= 0, reg
;
3967 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3969 if((reg
= ap
->Args
[i
].ArgReg
) <= REG_FP0
)
3971 if(reg
>= 10 || (reg
>= 2 && reg
<= 7)) /* A2-A7 and D2-D7 */
3972 data
|= (1 << (reg
+ 16)) + (1 << (15 - reg
));
3975 if(data
) /* set A6 only when other register used */
3980 static uint16
GetFRegisterData(struct AmiPragma
*ap
)
3983 F227 <upper byte> FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
3984 F21F <lower byte> FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
3986 register uint32 i
, reg
;
3987 register uint16 data
= 0;
3989 for(i
= 0; i
< ap
->NumArgs
; ++i
)
3991 if((reg
= ap
->Args
[i
].ArgReg
) >= REG_FP2
)
3994 data
|= (1 << (reg
+ 8)) + (1 << (7 - reg
));
4000 static uint32
OutputXDEF(uint32 offset
, strptr format
, ...)
4006 va_start(a
, format
);
4007 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4011 EndPutM32(buf
+4+i
, offset
); /* the definition offset */
4013 EndPutM32(buf
, (EXT_DEF
<<24) + (i
>>2));
4015 return DoOutputDirect(buf
, i
+8);
4018 static uint32
OutputXREF(uint32 offset
, uint32 type
, strptr format
, ...)
4024 va_start(a
, format
);
4025 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4029 EndPutM32(buf
+4+i
, 1); /* 1 reference */
4030 EndPutM32(buf
+8+i
, offset
); /* the definition offset */
4032 EndPutM32(buf
, (type
<< 24) + (i
>>2));
4034 return DoOutputDirect(buf
, i
+12);
4037 static uint32
OutputXREF2(uint32 offset1
, uint32 offset2
, uint32 type
,
4044 va_start(a
, format
);
4045 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4049 EndPutM32(buf
+4+i
, 2); /* 2 references */
4050 EndPutM32(buf
+8+i
, offset1
); /* the definition offset */
4051 EndPutM32(buf
+12+i
, offset2
); /* the definition offset */
4053 EndPutM32(buf
, (type
<< 24) + (i
>>2));
4055 return DoOutputDirect(buf
, i
+16);
4058 static uint32
OutputSYMBOL(uint32 offset
, strptr format
, ...)
4064 va_start(a
, format
);
4065 i
= vsprintf((strptr
)(buf
+4), format
, a
);
4069 EndPutM32(buf
+4+i
, offset
);
4071 EndPutM32(buf
, (0 << 24) + (i
>>2));
4073 return DoOutputDirect(buf
, i
+8);
4076 static uint8
*AsmStackCopy(uint8
*data
, struct AmiPragma
*ap
, uint32 flags
,
4079 uint32 i
, j
, k
, l
, tofs
;
4081 if(Flags
& FLAG_PASCAL
)
4087 if(ap
->Args
[k
-1].ArgReg
>= REG_FP0
)
4089 struct ClibData
*cd
;
4091 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
4092 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
4094 if(cd
&& IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_DOUBLE
))
4096 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
4097 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
4102 if(!cd
|| !IsCPPType(&cd
->Args
[k
-1], CPP_TYPE_FLOAT
))
4103 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4104 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[--k
].ArgReg
-REG_FP0
)<<7));
4105 EndPutM16Inc(data
, (ofs
++) << 2);
4108 else if((k
>= 2) && (ap
->Args
[k
-1].ArgReg
< ap
->Args
[k
-2].ArgReg
)
4109 && ap
->Args
[k
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4114 j
= ap
->Args
[--k
].ArgReg
;
4118 } while(k
&& j
< ap
->Args
[k
-1].ArgReg
4119 && ap
->Args
[k
-1].ArgReg
< REG_FP0
);
4120 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4121 EndPutM16Inc(data
, l
);
4122 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
4126 l
= 0x202F; /* MOVE.L offs(A7),xxx */
4128 if((j
= ap
->Args
[--k
].ArgReg
) > 7)
4130 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
4132 /* set destination register and store */
4133 EndPutM16Inc(data
, l
| (j
<< 9));
4134 EndPutM16Inc(data
, (ofs
++) << 2);
4142 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4146 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4148 struct ClibData
*cd
;
4150 cd
= GetClibFunc(ap
->FuncName
, ap
, flags
);
4151 EndPutM16Inc(data
, 0xF22F); /* FMOVE.? offs(A7),FPx */
4153 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4155 EndPutM16Inc(data
, 0x5400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
4156 EndPutM16Inc(data
, ofs
<<2); /* one double needs two longs */
4161 if(!cd
|| !IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4162 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4163 EndPutM16Inc(data
, 0x4400 + ((ap
->Args
[i
++].ArgReg
-REG_FP0
)<<7));
4164 EndPutM16Inc(data
, (ofs
++) << 2);
4167 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
)
4168 && ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4173 j
= ap
->Args
[i
++].ArgReg
;
4177 } while(i
< k
&& j
< ap
->Args
[i
].ArgReg
4178 && ap
->Args
[i
].ArgReg
< REG_FP0
);
4179 EndPutM16Inc(data
, 0x4CEF); /* MOVEM.L offs(A7),xxx */
4180 EndPutM16Inc(data
, l
); /* Store MOVEM.L data */
4181 EndPutM16Inc(data
, tofs
<< 2); /* store start offset */
4185 l
= 0x202F; /* MOVE.L offs(A7),xxx */
4187 if((j
= ap
->Args
[i
++].ArgReg
) > 7)
4189 l
|= (1<<6); j
-= 8; /* set MOVEA bit */
4191 /* set destination register and store */
4192 EndPutM16Inc(data
, l
| (j
<< 9));
4193 EndPutM16Inc(data
, (ofs
++) << 2);
4199 if((j
= ap
->Args
[i
].ArgReg
) > 7)
4201 EndPutM16Inc(data
, 0x41EF | ((j
-8) << 9)); /* LEA xxx(A7),Ax */
4202 EndPutM16Inc(data
, ofs
<< 2);
4206 EndPutM16Inc(data
, 0x200F | (j
<< 9)); /* MOVE.L A7,Dx */
4207 EndPutM16Inc(data
, 0x5080 | j
); /* ADDQ.L #8,Dx */
4211 EndPutM16Inc(data
, 0x486F); /* PEA xxx(A7) */
4212 EndPutM16Inc(data
, ofs
<< 2);
4213 EndPutM16Inc(data
, 0x201F | j
<< 9); /* MOVE.L offs(A7),Dx */
4220 /* ------------------------------------------------------------------ */
4222 static void DoError(uint32 errnum
, uint32 line
, ...)
4224 uint32 err
= errnum
& 0xFFFF;
4227 if(Flags
& FLAG_DIDERROR
)
4230 if(!Errors
[err
].Type
)
4231 Flags
|= FLAG_DIDERROR
;
4234 printf((line
? "%s %ld in line %ld%s: " : "%s %ld : "),
4235 (Errors
[err
].Type
? "Warning" : "Error"), err
, line
,
4236 errnum
& ERROFFSET_CLIB
? " of clib file" : "");
4237 vprintf(Errors
[err
].Error
, a
);
4239 if(line
&& Errors
[err
].Skip
)
4247 static uint32
CheckError(struct AmiPragma
*ap
, uint32 errflags
)
4249 errflags
&= ap
->Flags
;
4251 if(errflags
& AMIPRAGFLAG_ARGCOUNT
)
4253 if(!(ap
->Flags
& AMIPRAGFLAG_DIDARGWARN
))
4255 DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER
, ap
->Line
);
4256 ap
->Flags
|= AMIPRAGFLAG_DIDARGWARN
;
4260 else if(errflags
& AMIPRAGFLAG_FLOATARG
)
4262 if(!(ap
->Flags
& AMIPRAGFLAG_DIDFLOATWARN
))
4264 DoError(ERR_FLOATARG_NOT_ALLOWED
, ap
->Line
);
4265 ap
->Flags
|= AMIPRAGFLAG_DIDFLOATWARN
;
4269 else if(errflags
& AMIPRAGFLAG_A6USE
)
4271 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
4274 else if(errflags
& AMIPRAGFLAG_A5USE
)
4276 DoError(ERR_A5_NOT_ALLOWED
, ap
->Line
);
4279 else if(errflags
& AMIPRAGFLAG_PPC
)
4281 if(!(Flags
& FLAG_DIDPPCWARN
))
4283 DoError(ERR_PPC_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4284 Flags
|= FLAG_DIDPPCWARN
;
4288 else if(errflags
& AMIPRAGFLAG_M68K
)
4290 if(!(Flags
& FLAG_DIDM68KWARN
))
4292 DoError(ERR_M68K_FUNCTION_NOT_SUPPORTED
, 0/*ap->Line*/);
4293 Flags
|= FLAG_DIDM68KWARN
;
4297 else if(errflags
& AMIPRAGFLAG_MOSBASESYSV
)
4299 DoError(ERR_MOSBASESYSV_NOT_SUPPORTED
, ap
->Line
);
4306 static uint32
DoOutput(strptr format
, ...)
4313 va_start(a
, format
);
4314 if(vfprintf(outfile
, format
, a
) < 0)
4318 return Output_Error
;
4321 static uint32
DoOutputDirect(void * data
, size_t size
)
4327 if(fwrite(data
, size
, 1, outfile
) != 1)
4330 return Output_Error
;
4333 /* ------------------------------------------------------------------ */
4335 static struct ShortList
*NewItem(struct ShortListRoot
*list
)
4337 struct ShortList
*item
;
4338 if(!list
|| !list
->Size
)
4340 if(!(item
= (struct ShortList
*) AllocListMem(list
->Size
)))
4345 static struct ShortList
*RemoveItem(struct ShortListRoot
*list
,
4346 struct ShortList
*item
)
4348 struct ShortList
*n
= list
->First
;
4351 list
->First
= item
->Next
;
4354 while(n
&& n
->Next
!= item
)
4358 if(!(n
->Next
= item
->Next
))
4365 static void AddItem(struct ShortListRoot
*list
, struct ShortList
*item
)
4368 list
->First
= list
->Last
= item
;
4371 list
->Last
->Next
= item
;
4376 /* ------------------------------------------------------------------ */
4378 uint32
FuncAMICALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4382 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4385 Flags
|= FLAG_DONE
; /* We did something */
4387 DoOutput("#pragma %s(%s,0x%03x,%s("/*))*/, flags
& FUNCFLAG_TAG
?
4388 "tagcall" : "amicall", BaseName
, ap
->Bias
, name
);
4390 for(i
= 0; i
< ap
->NumArgs
; ++i
)
4392 DoOutput(RegNames
[ap
->Args
[i
].ArgReg
]);
4393 if(i
+1 < ap
->NumArgs
)
4397 return DoOutput(/*((*/"))\n");
4400 uint32
FuncLIBCALL(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4404 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4407 Flags
|= FLAG_DONE
; /* We did something */
4409 if(ap
->Flags
& AMIPRAGFLAG_FLOATARG
)
4411 DoOutput("#pragma flibcall %s %-22s %03x ", BaseName
, name
, ap
->Bias
);
4412 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4413 DoOutput("%02x", ap
->Args
[i
].ArgReg
);
4415 return DoOutput("00%02x\n", ap
->NumArgs
);
4418 if((Flags
& FLAG_SYSCALL
) && !strcmp(BaseName
,"SysBase") &&
4419 (flags
& FUNCFLAG_NORMAL
))
4420 DoOutput("#pragma syscall %-22s %03x ", name
, ap
->Bias
);
4422 DoOutput("#pragma %s %s %-22s %03x ", (flags
& FUNCFLAG_TAG
) ?
4423 "tagcall" : "libcall", BaseName
, name
, ap
->Bias
);
4425 for(i
= ap
->NumArgs
-1; i
>= 0; --i
)
4426 DoOutput("%x", ap
->Args
[i
].ArgReg
);
4428 return DoOutput("0%x\n", ap
->NumArgs
);
4431 uint32
FuncAsmText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4438 struct ClibData
*cd
;
4440 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4443 Flags
|= FLAG_DONE
; /* We did something */
4445 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
4446 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
4448 if(Flags
& FLAG_SINGLEFILE
)
4450 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
4455 DoOutputDirect(HEADER
, headersize
);
4459 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
4461 DoOutput("\n\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
4462 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
4465 DoOutput("\n\tXDEF\t_%s\n_%s:\n",name
, name
);
4466 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4468 DoOutput("\tXDEF\t%s\n%s:\n",name
, name
);
4472 DoOutput("\tXDEF\t%s_\n%s_:\n",name
, name
);
4473 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4478 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
4480 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
4481 DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name
, txt
, name
, txt
);
4487 if((registers
= GetRegisterData(ap
) >> 16))
4489 if(Flags
& FLAG_NOMOVEM
)
4491 for(i
= 0; i
<= 15; ++i
)
4493 if(registers
& (1 << i
))
4496 DoOutput("\tMOVE.L\t%s,-(A7)\n", RegNamesUpper
[i
]);
4502 uint16 l
= registers
;
4504 DoOutput("\tMOVEM.L\t");
4506 for(i
= 0; i
<= 15; ++i
)
4512 DoOutput(RegNamesUpper
[i
]);
4517 DoOutput(",-(A7)\n");
4522 DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset
;
4525 if((fregs
= GetFRegisterData(ap
) >> 8))
4529 DoOutput("\tFMOVEM.X\t");
4531 for(i
= 0; i
<= 7; ++i
)
4537 DoOutput(RegNamesUpper
[REG_FP0
+ i
]);
4542 DoOutput(",-(A7)\n");
4545 if(Flags
& FLAG_SMALLDATA
)
4547 DoOutput(/*(*/"\tMOVEA.L\t%s_%s%sA4),A6\n", c1
, BaseName
, c2
);
4550 DoOutput("\tMOVEA.L\t_%s,A6\n", BaseName
);
4552 if(!(Flags
& FLAG_PASCAL
))
4556 k
= ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0);
4560 if(ap
->Args
[i
].ArgReg
>= REG_FP0
)
4563 struct ClibData
*cd
;
4565 cd
= GetClibFunc(name
, ap
, flags
);
4566 if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_DOUBLE
))
4567 t
= CPP_TYPE_DOUBLE
;
4568 else if(cd
&& IsCPPType(&cd
->Args
[i
], CPP_TYPE_FLOAT
))
4572 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4576 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
4577 ? 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4579 if(t
== CPP_TYPE_DOUBLE
)
4583 else if(((k
- i
) >= 2) && (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
) &&
4584 ap
->Args
[i
+1].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4586 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4587 RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4591 DoOutput("/%s", RegNamesUpper
[ap
->Args
[i
++].ArgReg
]);
4593 } while((i
< k
) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
].ArgReg
) &&
4594 ap
->Args
[i
].ArgReg
< REG_FP0
);
4599 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4600 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4601 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4608 if(ap
->Args
[i
].ArgReg
> 7)
4609 DoOutput(/*(*/"\tLEA\t%s%02ld%sA7),%s\n", c1
, offset
<<2, c2
,
4610 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4611 else if(offset
<= 2)
4612 DoOutput("\tMOVE.L\tA7,%s\n\tADDQ.L\t#%02ld,%s\n",
4613 RegNamesUpper
[ap
->Args
[i
].ArgReg
],offset
<<2,
4614 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4616 DoOutput(/*(*/"\tPEA\t%s%ld%sA7)\n\tMOVE.L\t(A7)+,%s\n",c1
,
4617 offset
<<2, c2
,RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4626 if(ap
->Args
[i
-1].ArgReg
>= REG_FP0
)
4629 struct ClibData
*cd
;
4631 cd
= GetClibFunc(name
, ap
, flags
);
4633 if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_DOUBLE
))
4634 t
= CPP_TYPE_DOUBLE
;
4635 else if(cd
&& IsCPPType(&cd
->Args
[i
-1], CPP_TYPE_FLOAT
))
4639 DoError(ERR_LONG_DOUBLE
, ap
->Line
);
4643 DoOutput(/*(*/"\tFMOVE.%c\t%s%02ld%sA7),%s\n", t
== CPP_TYPE_DOUBLE
?
4644 'D' : 'S', c1
, offset
<<2, c2
, RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4645 if(t
== CPP_TYPE_DOUBLE
)
4649 else if((i
>= 2) && (ap
->Args
[i
-1].ArgReg
< ap
->Args
[i
-2].ArgReg
) &&
4650 ap
->Args
[i
-2].ArgReg
< REG_FP0
&& !(Flags
& FLAG_NOMOVEM
))
4652 DoOutput(/*(*/"\tMOVEM.L\t%s%02ld%sA7),%s", c1
, (offset
++)<<2, c2
,
4653 RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4657 DoOutput("/%s", RegNamesUpper
[ap
->Args
[--i
].ArgReg
]);
4659 } while(i
&& (ap
->Args
[i
].ArgReg
< ap
->Args
[i
-1].ArgReg
) &&
4660 ap
->Args
[i
-1].ArgReg
< REG_FP0
);
4666 DoOutput(/*(*/"\tMOVE%s.L\t%s%02ld%sA7),%s\n",
4667 ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "", c1
, (offset
++)<<2, c2
,
4668 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
4673 DoOutput(/*(*/"\tJSR\t%s-%03d%sA6)\n", c1
, ap
->Bias
, c2
);
4677 DoOutput("\tFMOVEM.X\t(A7)+,");
4679 for(i
= 0; i
<= 7; ++i
)
4681 if(fregs
& (1 << i
))
4684 DoOutput(RegNamesUpper
[REG_FP0
+ i
]);
4694 if(Flags
& FLAG_NOMOVEM
)
4696 for(i
= 15; i
>= 0; --i
)
4698 if(registers
& (1 << i
))
4699 DoOutput("\tMOVE%s.L\t(A7)+,%s\n", i
>= REG_A0
? "A" : "",
4705 DoOutput("\tMOVEM.L\t(A7)+,");
4707 for(i
= 0; i
<= 15; ++i
)
4709 if(registers
& (1 << i
))
4711 registers
^= 1 << i
;
4712 DoOutput(RegNamesUpper
[i
]);
4721 DoOutput("\tMOVEA.L\t(A7)+,A6\n");
4723 return DoOutput("\tRTS\n");
4726 uint32
FuncAsmCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4728 uint32 registers
, offset
= 1, baseref
;
4733 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
4736 Flags
|= FLAG_DONE
; /* We did something */
4738 registers
= GetRegisterData(ap
);
4739 fregs
= GetFRegisterData(ap
);
4741 i
= strlen(name
) + 2;
4742 EndPutM32(tempbuf
, HUNK_UNIT
);
4743 EndPutM32(tempbuf
+4, (i
+3)>>2);
4744 DoOutputDirect(tempbuf
, 8);
4745 DoOutput("%s.o", name
);
4746 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4748 i
= strlen(hunkname
);
4749 EndPutM32(tempbuf
, HUNK_NAME
);
4750 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
4751 DoOutputDirect(tempbuf
, 8);
4752 DoOutputDirect(hunkname
, i
);
4753 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
4755 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
4759 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
4760 ++offset
; /* one long more on stack */
4764 if(Flags
& FLAG_NOMOVEM
)
4766 for(i
= 0; i
<= 15; ++i
)
4768 if(registers
& (1<< (16+i
)))
4770 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
4778 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
4779 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
4780 for(l
= (uint16
) registers
; l
; l
>>= 1)
4783 ++offset
; /* get offset addition */
4791 EndPutM16Inc(data
, 0xF227); /* FMOVEM.X xxx,-(A7) */
4792 EndPutM16Inc(data
, 0xE000 + ((fregs
>>8)&0xFF));
4793 for(l
= (uint8
) fregs
; l
; l
>>= 1)
4796 offset
+=3; /* get offset addition */
4800 baseref
= (data
-tempbuf
)-8+2; /* one word later (MOVE) - 2 header longs */
4801 if(Flags
& FLAG_SMALLDATA
)
4803 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
4804 EndPutM16Inc(data
, 0); /* place for base reference */
4808 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
4809 EndPutM32Inc(data
, 0); /* place for base reference */
4812 data
= AsmStackCopy(data
, ap
, flags
, offset
);
4814 /* here comes the base reference */
4815 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
4816 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
4820 EndPutM16Inc(data
, 0xF21F); /* FMOVEM.X (A7)+,xxx */
4821 EndPutM16Inc(data
, 0xD000 + (fregs
&0xFF));
4826 if(Flags
& FLAG_NOMOVEM
)
4829 for(i
= 15; i
>= 0; --i
)
4831 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
4832 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
4837 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
4838 EndPutM16Inc(data
, (registers
>> 16)); /* store MOVEM.L registers */
4842 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
4843 EndPutM16Inc(data
, 0x4E75); /* RTS */
4845 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
4847 EndPutM32(tempbuf
, HUNK_CODE
);
4848 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
4849 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
4851 EndPutM32(tempbuf
, HUNK_EXT
);
4852 DoOutputDirect(tempbuf
, 4);
4854 OutputXREF(baseref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
),
4856 /* here come the XDEF name references */
4857 OutputXDEF(0, "_%s", name
); /* C name */
4859 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4861 struct ClibData
*cd
;
4862 OutputXDEF(0, "%s", name
); /* ASM name */
4867 OutputXDEF(0, "%s_", name
); /* C++ name no parameters */
4868 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4870 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4872 if(CopyCPPType((strptr
)tempbuf
, i
, cd
, ap
->Args
))
4873 OutputXDEF(0, "%s__%s", name
, tempbuf
);
4879 EndPutM32(tempbuf
, 0);
4880 DoOutputDirect(tempbuf
, 4);
4881 if(!(Flags
& FLAG_NOSYMBOL
))
4883 EndPutM32(tempbuf
, HUNK_SYMBOL
);
4884 DoOutputDirect(tempbuf
, 4);
4885 OutputSYMBOL(0, "_%s", name
); /* C name */
4887 if(!(Flags
& (FLAG_PASCAL
|FLAG_ONLYCNAMES
)))
4889 struct ClibData
*cd
;
4890 OutputSYMBOL(0, "%s", name
); /* ASM name */
4895 OutputSYMBOL(0, "%s_", name
); /* C++ name no parameters */
4896 else if((cd
= GetClibFunc(name
, ap
, flags
)))
4898 for(i
= 0; i
< COPYCPP_PASSES
; ++i
) /* C++ name with parameters */
4900 if(CopyCPPType((strptr
) data
, i
, cd
, ap
->Args
))
4901 OutputSYMBOL(0, "%s__%s", name
, (strptr
) data
);
4907 EndPutM32(tempbuf
, 0);
4908 DoOutputDirect(tempbuf
, 4);
4911 EndPutM32(tempbuf
, HUNK_END
);
4912 return DoOutputDirect(tempbuf
, 4);
4915 /* Directly called by FuncInline and FuncInlineDirect also! */
4916 uint32
FuncCSTUBS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4918 struct ClibData
*f
, *t
;
4919 strptr ret
= "return ";
4922 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
4925 Flags
|= FLAG_DONE
; /* We did something */
4927 if(!(f
= GetClibFunc(ap
->FuncName
, ap
, 0)))
4929 t
= GetClibFunc(name
, ap
, flags
);
4931 if(flags
& FUNCFLAG_EXTENDMODE
)
4933 sprintf(tempbuf
, "___%s", name
);
4937 if(IsCPPType(&f
->ReturnType
, CPP_TYPE_VOID
))
4940 if(!OutClibType(&f
->ReturnType
, name
) || !DoOutput("("/*)*/))
4942 if(flags
& FUNCFLAG_EXTENDMODE
)
4944 DoOutput("%s %s, ", GetBaseType(), BaseName
);
4947 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4949 if(!OutClibType(&f
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4952 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4954 if(!OutClibType(&t
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
4957 else if(ap
->NumArgs
== 1 && !DoOutput("ULONG tag, "))
4960 if(!DoOutput(/*(*/"...)\n{\n %s%s("/*)*/, ret
, ap
->FuncName
))
4962 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
4964 if(!DoOutput("%s, ", ap
->Args
[i
].ArgName
))
4967 if(!DoOutput("("/*)*/) || !OutClibType(&f
->Args
[ap
->NumArgs
-1],0))
4970 if(t
&& t
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
4972 if(!DoOutput(/*((*/") &%s);\n}\n\n", ap
->Args
[ap
->NumArgs
-1].ArgName
))
4975 else if(ap
->NumArgs
== 1)
4977 if(!DoOutput(/*((*/") &tag);\n}\n\n"))
4980 else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
4981 ap
->Args
[ap
->NumArgs
-2].ArgName
) || !OutClibType(&f
->Args
[ap
->NumArgs
-2],0)
4982 || !DoOutput(/*(((*/")));\n}\n\n"))
4987 uint32
FuncLVOXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4989 Flags
|= FLAG_DONE
; /* We did something */
4990 return DoOutput("\t\tXDEF\t_LVO%s\n", name
);
4993 uint32
FuncLVO(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
4995 Flags
|= FLAG_DONE
; /* We did something */
4996 return DoOutput("\n_LVO%-24s\tEQU\t-%d", name
, ap
->Bias
);
4999 uint32
FuncLVOPPCXDEF(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5001 Flags
|= FLAG_DONE
; /* We did something */
5002 return DoOutput("\t.globl\t%sLVO%s\n", Flags
& FLAG_ABIV4
? "" : "_", name
);
5005 uint32
FuncLVOPPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5007 Flags
|= FLAG_DONE
; /* We did something */
5008 return DoOutput(".set\t%sLVO%s,-%d\n", Flags
& FLAG_ABIV4
? "" : "_", name
,
5012 uint32
FuncLVOPPCBias(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5014 Flags
|= FLAG_DONE
; /* We did something */
5016 EndPutM32Inc(elfbufpos
, symoffset
); /* st_name */
5017 symoffset
+= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1) + 1;
5018 EndPutM32Inc(elfbufpos
, -ap
->Bias
); /* st_value */
5019 EndPutM32Inc(elfbufpos
, 0); /* st_size */
5020 *(elfbufpos
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* st_info */
5021 *(elfbufpos
++) = 0; /* st_other */
5022 EndPutM16Inc(elfbufpos
, SHN_ABS
); /* st_shndx */
5027 uint32
FuncLVOPPCName(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5029 Flags
|= FLAG_DONE
; /* We did something */
5030 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5031 return DoOutputDirect("", 1);
5034 uint32
FuncLVOLib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5038 Flags
|= FLAG_DONE
; /* We did something */
5039 j
= strlen(name
) + 3 + (Flags
& FLAG_ABIV4
? 0 : 1);
5040 EndPutM32(tempbuf
, (EXT_ABS
<< 24) + ((j
+3)>>2));
5042 DoOutputDirect(tempbuf
, 4);
5043 DoOutput("%sLVO%s", Flags
& FLAG_ABIV4
? "" : "_", name
);
5044 DoOutputDirect("\0\0\0", ((j
+3)&(~3))-j
);
5045 EndPutM32(tempbuf
, -ap
->Bias
);
5046 return DoOutputDirect(tempbuf
, 4);
5049 uint32
FuncLocCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5051 strptr str2
= Flags
& FLAG_LOCALREG
? "rE" : "";
5054 struct ClibData
*cd
= 0;
5056 if(CheckError(ap
, AMIPRAGFLAG_PPC
))
5059 Flags
|= FLAG_DONE
; /* We did something */
5061 i
= strlen(name
) + 2;
5062 EndPutM32(tempbuf
, HUNK_UNIT
);
5063 EndPutM32(tempbuf
+4, (i
+3)>>2);
5064 DoOutputDirect(tempbuf
, 8);
5065 DoOutput("%s.o", name
);
5066 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5068 i
= strlen(hunkname
);
5069 EndPutM32(tempbuf
, HUNK_NAME
);
5070 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
5071 DoOutputDirect(tempbuf
, 8);
5072 DoOutputDirect(hunkname
, i
);
5073 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
5075 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
5077 if(Flags
& FLAG_LOCALREG
)
5079 if((flags
& FUNCFLAG_TAG
))
5081 i
= ap
->Args
[ap
->NumArgs
-1].ArgReg
;
5082 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE <ea>,-(A7) */
5086 EndPutM16Inc(data
, 0x41EF | ((i
-8) << 9)); /* LEA 8(A7),Ax */
5087 EndPutM16Inc(data
, 8);
5091 EndPutM16Inc(data
, 0x200F | (i
<< 9)); /* MOVE.L A7,Dx */
5092 EndPutM16Inc(data
, 0x5080 | i
); /* ADDQ.L #8,Dx */
5095 EndPutM16Inc(data
, 0x4EAE);
5096 EndPutM16Inc(data
, -ap
->Bias
); /* JSR instruction */
5098 /* MOVE (A7)+,<ea> */
5099 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5100 EndPutM16Inc(data
, 0x4E75); /* RTS */
5104 EndPutM16Inc(data
, 0x4EEE);
5105 EndPutM16Inc(data
, -ap
->Bias
); /* JMP instruction */
5110 uint32 registers
, offset
= 1;
5112 registers
= GetRegisterData(ap
);
5114 if(!registers
) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
5116 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
5117 ++offset
; /* one long more on stack */
5121 if(Flags
& FLAG_NOMOVEM
)
5123 for(i
= 0; i
<= 15; ++i
)
5125 if(registers
& (1<< (16+i
)))
5127 EndPutM16Inc(data
, 0x2F00 + i
); /* MOVE.L xxx,-(A7) */
5134 EndPutM16Inc(data
, 0x48E7); /* MOVEM.L xxx,-(A7) */
5135 EndPutM16Inc(data
, registers
); /* store MOVEM.L registers */
5136 for(i
= registers
&0xFFFF; i
; i
>>= 1)
5139 ++offset
; /* get offset addition */
5144 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
)) /* store library base in A6 */
5146 EndPutM16Inc(data
, 0x2C6F); /* MOVE.L ofs(A7),A6 */
5147 EndPutM16Inc(data
, (offset
++) << 2);
5150 data
= AsmStackCopy(data
, ap
, flags
, offset
);
5152 /* here comes the base reference */
5153 EndPutM16Inc(data
, 0x4EAE); /* JSR xxx(A6) */
5154 EndPutM16Inc(data
, -ap
->Bias
); /* JSR offset */
5157 if(Flags
& FLAG_NOMOVEM
)
5159 for(i
= 15; i
>= 0; --i
)
5161 if(registers
& (1<<(16+i
))) /* MOVE.L (A7)+,xxx */
5162 EndPutM16Inc(data
, 0x201F + ((i
&7)<<9) + ((i
>>3)<<6));
5167 EndPutM16Inc(data
, 0x4CDF); /* MOVEM.L (A7)+,xxx */
5168 EndPutM16Inc(data
, registers
>> 16); /* store MOVEM.L registers */
5172 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
5174 EndPutM16Inc(data
, 0x4E75); /* RTS */
5177 EndPutM16Inc(data
, 0); /* get longword assignment if not yet */
5179 EndPutM32(tempbuf
, HUNK_CODE
);
5180 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
5181 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
5183 EndPutM32(tempbuf
, HUNK_EXT
);
5184 DoOutputDirect(tempbuf
,4);
5186 /* here come the XDEF name references */
5188 if(!(Flags
& FLAG_ONLYCNAMES
))
5190 OutputXDEF(0, "%s", name
); /* ASM names */
5191 OutputXDEF(0, "LOC_%s", name
);
5194 OutputXDEF(0, "_%s", name
); /* C names */
5195 OutputXDEF(0, "_LOC_%s", name
);
5197 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5201 /* C++ names no parameters */
5202 OutputXDEF(0, "%s__%sP07Library", name
, str2
);
5203 OutputXDEF(0, "LOC_%s__%sP07Library", name
, str2
);
5205 else if((cd
= GetClibFunc(name
, ap
, flags
)))
5209 txt
= (strptr
) tempbuf
;
5211 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5213 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5214 { /* C++ names with parameters */
5215 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5217 OutputXDEF(0, "%s__%sP07Library%s", name
, str2
, txt
);
5218 OutputXDEF(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5222 OutputXDEF(0, "%s__%s", name
, txt
);
5223 OutputXDEF(0, "LOC_%s__%s", name
, txt
);
5230 EndPutM32(tempbuf
, 0);
5231 DoOutputDirect(tempbuf
,4);
5232 if(!(Flags
& FLAG_NOSYMBOL
))
5234 EndPutM32(tempbuf
, HUNK_SYMBOL
);
5235 DoOutputDirect(tempbuf
,4);
5236 if(!(Flags
& FLAG_ONLYCNAMES
))
5238 OutputSYMBOL(0, "%s", name
); /* ASM names */
5239 OutputSYMBOL(0, "LOC_%s", name
);
5242 OutputSYMBOL(0, "_%s", name
); /* C names */
5243 OutputSYMBOL(0, "_LOC_%s", name
);
5245 if(clibdata
&& !(Flags
& FLAG_ONLYCNAMES
))
5249 /* C++ names no parameters */
5250 OutputSYMBOL(0, "%s__%sP07Library", name
, str2
);
5251 OutputSYMBOL(0, "LOC_%s__%sP07Library", name
, str2
);
5257 txt
= (strptr
) tempbuf
;
5259 for(i
= 0; i
< COPYCPP_PASSES
; ++i
)
5261 if(CopyCPPType(txt
, i
, cd
, ap
->Args
))
5262 { /* C++ names with parameters */
5263 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5265 OutputSYMBOL(0, "%s__%sP07Library%s", name
, str2
, txt
);
5266 OutputSYMBOL(0, "LOC_%s__%sP07Library%s", name
, str2
, txt
);
5270 OutputSYMBOL(0, "%s__%s", name
, txt
);
5271 OutputSYMBOL(0, "LOC_%s__%s", name
, txt
);
5278 EndPutM32(tempbuf
, 0);
5279 DoOutputDirect(tempbuf
,4);
5281 EndPutM32(tempbuf
, HUNK_END
);
5282 return DoOutputDirect(tempbuf
,4);
5285 uint32
FuncLocText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5287 struct ClibData
*cd
;
5290 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5293 Flags
|= FLAG_DONE
; /* We did something */
5295 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
5298 OutClibType(&cd
->ReturnType
, 0);
5299 DoOutput(" LOC_%s("/*)*/, name
);
5300 if(!(ap
->Flags
& AMIPRAGFLAG_A6USE
))
5302 if(Flags
& FLAG_LOCALREG
)
5303 DoOutput("register __a6 ");
5304 DoOutput("%s libbase", GetBaseType());
5311 for(i
= 0; i
< ap
->NumArgs
-1; i
++)
5313 if(((Flags
& FLAG_LOCALREG
&&
5314 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5315 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) || !DoOutput(", "))
5319 if(flags
& FUNCFLAG_NORMAL
)
5321 if(((Flags
& FLAG_LOCALREG
&&
5322 !DoOutput("register __%s ", RegNames
[ap
->Args
[i
].ArgReg
]))) ||
5323 !OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
) ||
5324 !DoOutput(/*(*/");\n"))
5328 DoOutput("#define %s("/*)*/, name
);
5329 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5330 DoOutput("%c, ", 'a'+(char)i
);
5331 DoOutput(/*(*/"%c) LOC_%s(%s, "/*)*/,'a'+(char)i
, name
, BaseName
);
5332 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5333 DoOutput("%c, ",'a'+(char)i
);
5334 return DoOutput(/*(*/"%c)\n\n",'a'+(char)i
);
5338 return DoOutput(/*(*/"...);\n");
5341 return DoOutput(/*(*/");\n#define %s(a) LOC_%s(a)\n\n",
5344 return DoOutput(/*(*/");\n");
5348 uint32
FuncInlineDirect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5350 uint32 a4
= 0, a5
= 0;
5352 int32 i
, maxargs
, reg
=0;
5353 struct ClibData
*cd
;
5355 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
|AMIPRAGFLAG_VARARGS
))
5358 Flags
|= FLAG_DONE
; /* We did something */
5360 if(flags
& FUNCFLAG_ALIAS
)
5362 if(flags
& FUNCFLAG_TAG
)
5363 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
5366 DoOutput("#define %s("/*)*/, name
);
5367 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5368 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5369 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5370 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5371 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5372 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5375 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
5378 if(flags
& FUNCFLAG_TAG
)
5380 /* do not create some strange functions */
5381 if(IsNoCreateInlineFunc(name
))
5382 DoOutput("#if !defined(NO_INLINE_STDARG) "
5383 "&& defined(SPECIALMACRO_INLINE_STDARG)\n");
5385 DoOutput("#ifndef NO_INLINE_STDARG\n");
5386 DoOutput("static __inline__ ");
5387 FuncCSTUBS(ap
, flags
|FUNCFLAG_EXTENDMODE
, name
);
5389 DoOutput("#define %s("/*)*/, name
);
5390 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5392 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5396 DoOutput(/*(*/"...) ___%s(%s_BASE_NAME, "/*)*/, name
, ShortBaseNameUpper
);
5397 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5398 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->NumArgs
-2 ? ", " : "");
5401 DoOutput(/*(*/")\n");
5402 return DoOutput("#endif\n\n");
5405 DoOutput("#define %s("/*)*/, name
);
5408 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5409 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5410 DoOutput("%s", ap
->Args
[i
].ArgName
);
5412 DoOutput(/*(*/") ({ \\\n"/*})*/);
5414 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5416 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5418 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5419 DoOutput(" = (%s); \\\n", ap
->Args
[i
].ArgName
);
5422 if(Flags
& FLAG_INLINENEW
)
5425 DoOutput(" ({ \\\n"/*})*/);
5426 DoOutput(" register char * _%s__bn __asm(\"a6\") = (char *) ", name
);
5428 DoOutput("(%s_BASE_NAME);\\\n", ShortBaseNameUpper
);
5431 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
5433 if(i
== ap
->NumArgs
)
5435 DoOutput("(%s);\\\n", ap
->Args
[i
].ArgName
);
5438 DoOutput(" (("/*))*/);
5439 OutClibType(&cd
->ReturnType
, 0);
5440 DoOutput(" (*)("/*)*/);
5443 DoOutput("char * __asm(\"a6\")");
5447 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5449 OutClibType(&cd
->Args
[i
], 0);
5450 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
5451 if(i
< ap
->NumArgs
-1)
5454 DoOutput(/*((*/")) \\\n");
5455 DoOutput(/*(*/" (_%s__bn - %d))("/*)*/, name
, ap
->Bias
);
5458 DoOutput("_%s__bn", name
);
5462 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5464 if(ap
->Args
[i
].ArgReg
== REG_A6
)
5465 DoOutput("_%s__bn", name
);
5467 DoOutput("_%s_%s", name
, ap
->Args
[i
].ArgName
);
5468 if(i
< ap
->NumArgs
-1)
5471 DoOutput(/*(*/"); \\\n");
5473 DoOutput(/*({*/"});");
5477 /* do A5 first, as it is more important */
5478 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5480 a5
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5481 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5482 a5
|= 1<<ap
->Args
[i
].ArgReg
;
5486 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A5
]);
5491 for(i
= 0; (a5
& 1) && a5
; ++i
)
5493 a5
= i
; /* this is our A5 swap register */
5496 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5498 a4
= 0x303; /* D0-D1,A0-A1 are scratch and cannot be used */
5501 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5502 a4
|= 1<<ap
->Args
[i
].ArgReg
;
5506 DoError(ERR_INLINE_AX_SWAPREG
, ap
->Line
, RegNamesUpper
[REG_A4
]);
5511 for(i
= 0; (a4
& 1) && a4
; ++i
)
5513 a4
= i
; /* this is our A4 swap register */
5516 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5517 noret
= 1; /* this is a void function */
5519 if(ap
->NumArgs
|| !noret
)
5520 DoOutput(" %s{ \\\n", noret
? "" : "(" /*})*/);
5523 DoOutput(" register int _d0 __asm(\"d0\"); \\\n");
5525 " register int _d1 __asm(\"d1\"); \\\n"
5526 " register int _a0 __asm(\"a0\"); \\\n"
5527 " register int _a1 __asm(\"a1\"); \\\n");
5530 DoOutput(" register %s const __%s__bn __asm(\"a6\") = %s_BASE_NAME;\\\n",
5531 GetBaseType(), name
, ShortBaseNameUpper
);
5535 sprintf((strptr
)tempbuf
, "__%s__re", name
);
5536 DoOutput(" register ");
5537 OutClibType(&cd
->ReturnType
, (strptr
) tempbuf
);
5538 DoOutput(" __asm(\"d0\"); \\\n");
5540 if((maxargs
= ap
->NumArgs
) >= 9 && (Flags
& FLAG_STORMGCC
))
5542 for(i
= 0; i
< maxargs
; ++i
)
5544 reg
= ap
->Args
[i
].ArgReg
;
5545 if(a5
&& reg
== REG_A5
) reg
= a5
; /* we need to switch */
5546 if(a4
&& reg
== REG_A4
) reg
= a4
; /* we need to switch */
5548 sprintf((strptr
)tempbuf
, "__%s_%s", name
, ap
->Args
[i
].ArgName
);
5549 DoOutput(" register ");
5550 OutClibType(&cd
->Args
[i
], (strptr
) tempbuf
);
5551 DoOutput(" __asm(\"%s\") = (%s); \\\n", RegNames
[reg
],
5552 (strptr
) (tempbuf
+1));
5554 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5556 DoOutput(" const struct __%s__ArgsStr { \\\n"/*}*/, name
);
5557 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5559 DoOutput(" ULONG __%s_%s; \\\n", name
, ap
->Args
[i
].ArgName
);
5560 reg
= ap
->Args
[i
].ArgReg
;
5565 else if(reg
== REG_A5
)
5570 /* reg is now either the last register argument or its a4/a5 redirect */
5571 DoOutput(/*{*/" } __%s__Args = {"/*}*/, name
);
5572 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5574 sprintf((strptr
)tempbuf
, "_%s_%s", name
, ap
->Args
[i
].ArgName
);
5575 DoOutput("(ULONG)(%s)%s", (strptr
)tempbuf
, i
== ap
->NumArgs
-1 ?
5578 DoOutput(/*{*/"}; \\\n register const struct __%s__ArgsStr "
5579 "*__%s__ArgsPtr __asm(\"%s\") = &(__%s__Args); \\\n", name
, name
,
5580 RegNames
[reg
], name
);
5582 DoOutput(" __asm volatile (\""/*)*/);
5583 if(a5
) DoOutput("exg a5,%s\\n\\t", RegNames
[a5
]);
5584 if(a4
) DoOutput("exg a4,%s\\n\\t", RegNames
[a4
]);
5585 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5587 DoOutput("movem.l ");
5588 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5590 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5591 i
== ap
->NumArgs
-1 ? "" : "/");
5593 DoOutput(",-(a7)\\n\\t");
5594 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5597 DoOutput("move.l (%s),%s\\n\\t", RegNames
[reg
],
5598 RegNames
[ap
->Args
[i
].ArgReg
]);
5600 DoOutput("move.l %ld(%s),%s\\n\\t", (i
-maxargs
)*4, RegNames
[reg
],
5601 RegNames
[ap
->Args
[i
].ArgReg
]);
5604 DoOutput("jsr a6@(-%d:W)", ap
->Bias
);
5605 if(maxargs
!= ap
->NumArgs
) /* StormGCC mode */
5607 DoOutput("\\n\\tmovem.l (a7)+,");
5608 for(i
= maxargs
; i
< ap
->NumArgs
; ++i
)
5610 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
],
5611 i
== ap
->NumArgs
-1 ? "" : "/");
5614 if(a4
) DoOutput("\\n\\texg a4,%s", RegNames
[a4
]);
5615 if(a5
) DoOutput("\\n\\texg a5,%s", RegNames
[a5
]);
5616 DoOutput("\" \\\n");
5619 DoOutput(" : \"=r\" (_d0)");
5621 DoOutput(" : \"=r\"(__%s__re)", name
);
5622 DoOutput(", \"=r\" (_d1), \"=r\" (_a0), \"=r\" (_a1) \\\n :");
5624 DoOutput(" \"r\"(__%s__bn)%s", name
, ap
->NumArgs
? "," : "");
5625 for(i
= 0; i
< maxargs
; ++i
)
5627 DoOutput(" \"rf\"(__%s_%s)", name
, ap
->Args
[i
].ArgName
);
5628 if(i
< ap
->NumArgs
-1)
5631 if(i
!= ap
->NumArgs
) /* StormGCC mode */
5632 DoOutput(" \"r\"(__%s__ArgsPtr)", name
);
5633 DoOutput(/*(*/" \\\n : \"fp0\", \"fp1\", \"cc\", \"memory\"); \\\n");
5635 if(ap
->NumArgs
|| !noret
)
5636 DoOutput(/*({*/" }%s \\\n", noret
? "" : ");");
5639 return DoOutput(/*({*/"})\n\n");
5642 uint32
FuncInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
5644 uint32 noret
= 0, a45
= 0, j
;
5646 struct ClibData
*cd
;
5648 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
5651 if(!(Flags
& FLAG_INLINENEW
) && CheckError(ap
, AMIPRAGFLAG_MOSBASESYSV
))
5654 Flags
|= FLAG_DONE
; /* We did something */
5656 if(flags
& FUNCFLAG_ALIAS
)
5658 if(flags
& FUNCFLAG_TAG
)
5659 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
5660 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
5662 DoOutput("#define %s("/*)*/, name
);
5663 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5664 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5665 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
5666 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5667 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5668 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
5671 if(!(cd
= GetClibFunc(ap
->Flags
& AMIPRAGFLAG_VARARGS
?
5672 ap
->TagName
: ap
->FuncName
, ap
, flags
)))
5675 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5676 noret
= 1; /* this is a void function */
5678 if(ap
->Flags
& AMIPRAGFLAG_A5USE
)
5680 if(ap
->Flags
& AMIPRAGFLAG_A4USE
)
5684 DoError(ERR_INLINE_A4_AND_A5
, ap
->Line
);
5685 return 1; /* skip this entry */
5689 if(a45
&& (ap
->Flags
& AMIPRAGFLAG_D7USE
))
5691 DoError(ERR_INLINE_D7_AND_A45
, ap
->Line
);
5692 return 1; /* skip this entry */
5695 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
5697 if(Flags
& FLAG_INLINENEW
)
5699 DoOutput("#ifndef NO_%sINLINE_STDARG\n",
5700 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "");
5701 if(IsNoCreateInlineFunc(name
))
5703 DoOutput("__inline ");
5704 FuncCSTUBS(ap
, flags
, name
);
5705 /* call CSTUBS, as this equals the method used there */
5709 DoOutput("#define %s("/*)*/, name
);
5710 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5712 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5714 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
5716 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5717 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
5719 OutClibType(&cd
->Args
[i
], 0);
5720 DoOutput(/*({((*/") _tags);})\n");
5722 return DoOutput("#endif\n\n");
5724 else if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5725 == (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5727 int32 n
, d
, tagl
, local
;
5731 tagl
= 8 + (Flags2
& FLAG2_DIRECTVARARGS
? 0 : 64);
5732 local
= (n
* 4+d
+8+15) & ~15; /* size of the stack frame */
5735 * 0- 3: next frame ptr
5738 * 72-72+n*4+d+8-1: tag list start
5739 * ?-local-1: padding
5742 DoOutput("asm(\"\n"/*)*/
5745 "\t.type\t%s,@function\n"
5747 "\tstwu\t1,-%ld(1)\n" /* create stack frame */
5749 "\tstw\t0,%ld(1)\n",
5750 name
, name
, name
, local
, local
+4);
5752 /* If n is odd, one tag is split between regs and stack.
5753 * Copy its ti_Data together with the ti_Tag. */
5755 DoOutput("\tlwz\t0,%ld(1)\n", local
+8); /* read ti_Data */
5757 /* Save the registers */
5758 for(i
= ap
->NumArgs
; i
<= 8; ++i
)
5759 DoOutput("\tstw\t%ld,%ld(1)\n", i
+2, (i
-ap
->NumArgs
) * 4+tagl
);
5762 DoOutput("\tstw\t0,%ld(1)\n", tagl
+n
* 4); /* write ti_Data */
5765 DoOutput("\tli\t0,2\n"
5766 "\tstw\t0,%ld(1)\n" /* add TAG_MORE */
5768 "\tstw\t0,%ld(1)\n", /* ti_Data=&stack_params */
5769 tagl
+n
* 4+d
, local
+8+d
, tagl
+n
* 4+d
+4);
5771 if(Flags2
& FLAG2_DIRECTVARARGS
)
5773 DoOutput("\taddi\t%d,1,%ld\n" /* vararg_reg=&saved regs */
5774 "\tbl\t%s\n", ap
->NumArgs
+2, tagl
, name
);
5781 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
5784 /* Caos.Offset = -fD_GetOffset(obj) */
5785 DoOutput("\tli\t0,%d\n"
5786 "\tstw\t0,8(1)\n", -ap
->Bias
);
5788 /* Save the non-varargs registers in the Caos struct. */
5789 for(i
=0; i
< ap
->NumArgs
-1; ++i
)
5791 DoOutput("\tstw\t%ld,%d(1)\n", i
+3, 8+4+(ap
->Args
[i
].ArgReg
* 4));
5794 DoOutput("\taddi\t0,1,%ld\n"
5796 "\tstw\t0,%d(1)\n" /* Caos.reg_xx = taglist */
5797 "\tlwz\t12,%s@l(3)\n"
5799 "\tstw\t12,68(1)\n" /* Caos.reg_a6=libbase */
5802 "\tbctrl\n", /* EmulCallOS() */
5803 tagl
, BaseName
, 12+(4 * ap
->Args
[i
].ArgReg
), BaseName
);
5805 DoOutput("\tlwz\t0,%ld(1)\n" /* clear stack frame & return */
5809 /*(*/"\t.size\t%s,$-%s\n\");\n\n", local
+4, local
, name
, name
);
5813 DoOutput("%s%s__inline ", Flags
& FLAG_INLINESTUB
? "" : "extern ",
5814 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5815 return FuncCSTUBS(ap
, flags
, name
);
5816 /* call CSTUBS, as this equals the method used there */
5820 if(Flags
& FLAG_INLINENEW
) /* new style */
5822 strptr funcpar
= "";
5823 DoOutput("#define %s("/*)*/, name
);
5825 for(i
= 0; i
< cd
->NumArgs
; ++i
)
5827 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5833 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
5834 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
5835 DoOutput("%s", ap
->Args
[i
].ArgName
);
5837 DoOutput(/*(*/") \\\n\t");
5838 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
5840 DoOutput("((("/*)))*/);
5841 OutClibType(&cd
->ReturnType
, 0);
5842 DoOutput(" (*)("/*)*/);
5843 DoOutput("%s", GetBaseType());
5844 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5847 OutClibType(&cd
->Args
[i
], 0);
5849 DoOutput(/*(((*/"))*(void**)((long)(%s_BASE_NAME) -%d))"
5850 "(%s_BASE_NAME",/*)*/
5851 ShortBaseNameUpper
, ap
->Bias
-2, ShortBaseNameUpper
);
5853 for(i
= 0; i
< ap
->NumArgs
- ((flags
& FUNCFLAG_TAG
) ? 1 : 0); ++i
)
5854 DoOutput(", %s", ap
->Args
[i
].ArgName
);
5855 if(flags
& FUNCFLAG_TAG
)
5856 DoOutput(", __VA_ARGS__");
5857 return DoOutput(/*((*/"))\n\n");
5859 DoOutput("LP%d%s%s%s%s(0x%x, "/*)*/, ap
->NumArgs
,
5860 (noret
? "NR" : ""), (a45
? RegNamesUpper
[a45
] : (strptr
) ""),
5861 (BaseName
? "" : "UB"), funcpar
, ap
->Bias
);
5864 OutClibType(&cd
->ReturnType
, 0);
5867 DoOutput("%s, ", name
);
5869 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5871 j
= ap
->Args
[i
].ArgReg
;
5872 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
5874 if(cd
->Args
[i
].Flags
& CPP_FLAG_FUNCTION
)
5878 DoError(ERR_MULTIPLEFUNCTION
, ap
->Line
);
5883 DoOutput("__fpt"); fp
= i
;
5887 OutClibType(&cd
->Args
[i
], 0);
5889 DoOutput(", %s, %s%s", ap
->Args
[i
].ArgName
, RegNames
[j
],
5890 (i
== ap
->NumArgs
-1 && !BaseName
? "" : ", "));
5893 if(BaseName
) /* was "##base" used? */
5894 DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper
);
5899 OutClibType(&cd
->Args
[fp
], "__fpt");
5902 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
5903 DoOutput(", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
5905 return DoOutput(/*(*/")\n\n");
5908 /* old mode or stubs mode */
5910 if((Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
)) != (FLAG_INLINESTUB
|FLAG_MORPHOS
))
5911 DoOutput("%s%s__inline ", Flags
& (FLAG_INLINESTUB
|FLAG_MORPHOS
) ?
5912 "" : "extern ", Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "static " : "");
5913 OutClibType(&cd
->ReturnType
, 0);
5914 DoOutput("\n%s(%s"/*)*/, name
, (BaseName
?
5915 (ap
->NumArgs
? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
5917 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5919 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
5920 if(i
< ap
->NumArgs
-1)
5924 if(Flags
& FLAG_POWERUP
)
5926 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
5927 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
5928 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
5929 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
5930 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
5931 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
5932 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
5936 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5938 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
5939 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5943 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5946 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s_BASE_NAME;\n", ShortBaseNameUpper
);
5947 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5948 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
5951 DoOutput("\treturn(("/*))*/);
5952 OutClibType(&cd
->ReturnType
, 0);
5953 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
5955 return Output_Error
;
5957 else if(Flags
& FLAG_MORPHOS
)
5959 DoOutput(/*(*/")\n{\n\tstruct EmulCaos MyCaos;\n"/*}*/);
5963 for(i
= 0; i
< ap
->NumArgs
; ++i
)
5965 DoOutput("\tMyCaos.reg_%s\t\t= (ULONG) %s;\n",
5966 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
5970 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
5972 DoOutput("\tMyCaos.reg_a6\t\t= (ULONG) %s_BASE_NAME;\n",
5973 ShortBaseNameUpper
);
5975 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
5976 DoOutput(/*{*/"\t(*MyEmulHandle->EmulCallOS)(&MyCaos);\n}\n\n");
5979 DoOutput("\treturn(("/*))*/);
5980 OutClibType(&cd
->ReturnType
, 0);
5981 DoOutput(/*{((*/")(*MyEmulHandle->EmulCallOS)(&MyCaos));\n}\n\n");
5983 return Output_Error
;
5986 DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName
? " BASE_EXT_DECL\n" : ""));
5990 DoOutput(" register ");
5991 OutClibType(&cd
->ReturnType
, "res");
5992 DoOutput(" __asm(\"d0\");\n");
5996 DoOutput(" register %s a6 __asm(\"a6\") = %s_BASE_NAME;\n",
5997 GetBaseType(), ShortBaseNameUpper
);
5999 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6001 j
= ap
->Args
[i
].ArgReg
;
6002 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
6005 DoOutput(" register ");
6006 OutClibType(&cd
->Args
[i
], RegNames
[j
]);
6007 DoOutput(" __asm(\"%s\") = %s;\n", RegNames
[j
], ap
->Args
[i
].ArgName
);
6012 DoOutput(" __asm volatile (\"exg d7,%s\\n\\t"/*)*/
6013 "jsr a6@(-0x%x:W)\\n\\texg d7,%s\"\n", RegNames
[a45
],
6014 ap
->Bias
, RegNames
[a45
]);
6017 DoOutput(" __asm volatile (\"jsr a6@(-0x%x:W)\"\n"/*)*/, ap
->Bias
);
6019 DoOutput(noret
? " : /* No Output */\n" : " : \"=r\" (res)\n");
6023 DoOutput("\"r\" (a6)%s", (ap
->NumArgs
? ", ": ""));
6025 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6027 j
= ap
->Args
[i
].ArgReg
;
6028 if(a45
&& (j
== REG_A4
|| j
== REG_A5
))
6031 DoOutput("\"r\" (%s)%s", RegNames
[j
], (i
< ap
->NumArgs
-1 ? ", " : ""));
6034 DoOutput("\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
6037 return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
6039 return DoOutput(/*({*/", \"cc\", \"memory\");\n return res;\n}\n\n");
6043 /* new style inlines designed by Bernardo Innocenti */
6044 uint32
FuncInlineNS(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6047 struct ClibData
*cd
;
6049 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6052 Flags
|= FLAG_DONE
; /* We did something */
6054 if(flags
& FUNCFLAG_ALIAS
)
6056 if(flags
& FUNCFLAG_TAG
)
6057 return DoOutput("#ifndef NO_INLINE_STDARG\n#define %s %s\n#endif\n\n",
6060 DoOutput("#define %s("/*)*/, name
);
6061 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6062 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6063 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6064 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6065 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6066 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6069 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6072 if((flags
& FUNCFLAG_TAG
))
6074 if(!(Flags2
& FLAG2_INLINEMAC
))
6076 DoOutput("static __inline ");
6077 return FuncCSTUBS(ap
, flags
, name
);
6078 /* call CSTUBS, as this equals the method used there */
6082 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
6083 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
6084 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6085 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6086 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
6088 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6089 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6091 OutClibType(&cd
->Args
[i
], 0);
6092 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6096 if(Flags2
& FLAG2_INLINEMAC
)
6098 DoOutput("#define %s("/*)*/, name
);
6099 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6101 DoOutput("%s", ap
->Args
[i
].ArgName
);
6102 if(i
< ap
->NumArgs
-1)
6105 DoOutput(/*(*/") \\\n\t");
6109 DoOutput("static __inline ");
6110 OutClibType(&cd
->ReturnType
, 0);
6111 DoOutput(" %s("/*)*/, name
);
6112 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6114 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6115 if(i
< ap
->NumArgs
-1)
6118 DoOutput(/*(*/")\n{\n "/*}*/);
6119 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6120 DoOutput("return ");
6122 DoOutput("(("/*))*/);
6123 OutClibType(&cd
->ReturnType
, 0);
6124 DoOutput(" (*)("/*)*/);
6125 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6127 OutClibType(&cd
->Args
[i
], 0);
6128 DoOutput(" __asm(\"%s\")", RegNames
[ap
->Args
[i
].ArgReg
]);
6129 if(i
< ap
->NumArgs
-1)
6136 DoOutput("%s __asm(\"a6\")", GetBaseType());
6138 DoOutput(/*((*/"))");
6139 if(Flags2
& FLAG2_INLINEMAC
)
6142 DoOutput(/*(*/"\n (((char *) %s_BASE_NAME) - %d))("/*)*/,
6143 ShortBaseNameUpper
, ap
->Bias
);
6146 for(i
= 0; i
< ap
->NumArgs
&& ap
->Args
[i
].ArgReg
!= REG_A6
; ++i
)
6148 if(i
== ap
->NumArgs
)
6150 DoOutput(/*(*/"\n (((char *) %s) - %d))("/*)*/, ap
->Args
[i
].ArgName
,
6153 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6155 DoOutput("%s", ap
->Args
[i
].ArgName
);
6156 if(i
< ap
->NumArgs
-1)
6163 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
6166 if(Flags2
& FLAG2_INLINEMAC
)
6167 DoOutput(/*(*/")\n");
6169 DoOutput(/*{(*/");\n}\n");
6171 return DoOutput("\n");
6174 uint32
FuncPowerUP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6177 struct ClibData
*cd
;
6179 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6182 Flags
|= FLAG_DONE
; /* We did something */
6184 if(flags
& FUNCFLAG_ALIAS
)
6186 if(flags
& FUNCFLAG_TAG
)
6187 return DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s %s\n#endif\n\n",
6190 DoOutput("#define %s("/*)*/, name
);
6191 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6192 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6193 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6194 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6195 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6196 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
6199 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6202 if(flags
& FUNCFLAG_TAG
)
6204 DoOutput("#ifndef NO_PPCINLINE_STDARG\n#define %s("/*)*/, name
);
6205 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6206 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6207 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*)})*/,
6209 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6210 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6212 OutClibType(&cd
->Args
[i
], 0);
6213 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
6216 DoOutput("#define\t%s("/*)*/, name
);
6221 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6222 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6223 DoOutput(/*(*/"%s)\t_%s("/*)*/, ap
->Args
[i
].ArgName
, name
);
6226 DoOutput("%s_BASE_NAME, ", ShortBaseNameUpper
);
6228 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6229 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6230 DoOutput(/*(*/"%s)\n\n", ap
->Args
[i
].ArgName
);
6233 DoOutput(/*(*/")\t_%s(%s_BASE_NAME)\n\n", name
, ShortBaseNameUpper
);
6235 DoOutput(/*(*/")\t_%s()\n\n", name
);
6237 DoOutput("static __inline ");
6238 OutClibType(&cd
->ReturnType
, 0);
6240 DoOutput("\n_%s("/*)*/, name
);
6242 DoOutput("void * %s%s", BaseName
, ap
->NumArgs
? ", " : "");
6244 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6246 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6247 if(i
< ap
->NumArgs
-1)
6251 DoOutput(/*(*/")\n{\n\tstruct Caos MyCaos;\n"/*}*/
6252 "\tMyCaos.M68kCacheMode\t= IF_CACHEFLUSHALL;\n"
6253 "/*\tMyCaos.M68kStart\t= NULL;\t*/\n"
6254 "/*\tMyCaos.M68kSize\t\t= 0;\t*/\n"
6255 "\tMyCaos.PPCCacheMode\t= IF_CACHEFLUSHALL;\n"
6256 "/*\tMyCaos.PPCStart\t\t= NULL;\t*/\n"
6257 "/*\tMyCaos.PPCSize\t\t= 0;\t*/\n");
6261 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6263 DoOutput("\tMyCaos.%s\t\t= (ULONG) %s;\n",
6264 RegNames
[ap
->Args
[i
].ArgReg
], ap
->Args
[i
].ArgName
);
6268 DoOutput("\tMyCaos.caos_Un.Offset\t= %d;\n", -ap
->Bias
);
6271 DoOutput("\tMyCaos.a6\t\t= (ULONG) %s;\n", BaseName
);
6272 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6273 DoOutput(/*{*/"\tPPCCallOS(&MyCaos);\n}\n\n");
6276 DoOutput("\treturn(("/*))*/);
6277 OutClibType(&cd
->ReturnType
, 0);
6278 DoOutput(/*{((*/")PPCCallOS(&MyCaos));\n}\n\n");
6280 return Output_Error
;
6283 uint32
FuncFPCUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6286 struct ClibData
*cd
;
6288 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6290 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6293 if(!FuncFPCType(ap
, flags
, name
))
6296 DoOutput("BEGIN\n ASM\n\tMOVE.L\tA6,-(A7)\n");
6298 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6299 DoOutput("\tMOVE%s.L\t%s,%s\n", ap
->Args
[i
].ArgReg
>= REG_A0
? "A" : "",
6300 ap
->Args
[i
].ArgName
, RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
6303 DoOutput("\tMOVEA.L\t%s,A6\n", BaseName
);
6304 DoOutput("\tJSR\t-%03d(A6)\n\tMOVEA.L\t(A7)+,A6\n", ap
->Bias
);
6306 if(!IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6308 if(!cd
->ReturnType
.PointerDepth
&&
6309 cd
->ReturnType
.Flags
== CPP_FLAG_BOOLEAN
)
6310 DoOutput("\tTST.W\tD0\n\tBEQ.B\t@end\n\tMOVEQ\t#1,D0\n"
6311 " @end:\tMOVE.B\tD0,@RESULT\n");
6313 DoOutput("\tMOVE.L\tD0,@RESULT\n");
6315 return DoOutput(" END;\nEND;\n\n");
6318 uint32
FuncFPCType(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6322 struct ClibData
*cd
;
6324 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6326 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6329 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6331 ret
= 0; DoOutput("PROCEDURE %s", name
);
6334 DoOutput("FUNCTION %s", name
);
6339 for(i
= 0; i
< ap
->NumArgs
;)
6341 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6342 if(++i
!= ap
->NumArgs
)
6349 OutPASCALType(&cd
->ReturnType
, "", 1);
6351 Flags
|= FLAG_DONE
; /* We did something */
6353 return DoOutput(";\n");
6356 uint32
FuncFPCTypeTags(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6360 struct ClibData
*cd
;
6362 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6364 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6367 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6369 ret
= 0; DoOutput("PROCEDURE %s", name
);
6372 DoOutput("FUNCTION %s", name
);
6377 for(i
= 0; i
< ap
->NumArgs
-1;)
6379 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6380 if(++i
!= ap
->NumArgs
)
6383 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6388 OutPASCALType(&cd
->ReturnType
, "", 1);
6390 Flags
|= FLAG_DONE
; /* We did something */
6392 return DoOutput(";\n");
6395 uint32
FuncFPCTypeTagsUnit(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6399 struct ClibData
*cd
;
6401 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
6403 else if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
6406 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
6408 ret
= 0; DoOutput("PROCEDURE %s", name
);
6411 DoOutput("FUNCTION %s", name
);
6416 for(i
= 0; i
< ap
->NumArgs
-1;)
6418 OutPASCALType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
, 0);
6419 if(++i
!= ap
->NumArgs
)
6422 DoOutput("const %s : Array Of Const",ap
->Args
[i
].ArgName
);
6427 OutPASCALType(&cd
->ReturnType
, "", 1);
6429 DoOutput(";\nbegin\n");
6432 DoOutput(" %s := %s",name
, ap
->FuncName
);
6433 else DoOutput(" %s", ap
->FuncName
);
6438 for(i
= 0; i
< ap
->NumArgs
-1;)
6440 DoOutput("%s ", ap
->Args
[i
].ArgName
);
6441 if(++i
!= ap
->NumArgs
)
6444 DoOutput("readintags(%s)",ap
->Args
[i
].ArgName
);
6445 DoOutput(/*(*/");");
6450 Flags
|= FLAG_DONE
; /* We did something */
6452 return DoOutput(";\n\n");
6456 uint32
FuncBMAP(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6460 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_A5USE
6464 Flags
|= FLAG_DONE
; /* We did something */
6466 for(i
= 0; BMAPSpecial
[i
]; ++i
)
6468 if(!stricmp(name
, BMAPSpecial
[i
]))
6470 DoOutput("x"); break;
6475 reg
= 0; DoOutputDirect(®
, 1);
6476 reg
= (-ap
->Bias
)>>8; DoOutputDirect(®
, 1);
6477 reg
= -ap
->Bias
; DoOutputDirect(®
, 1);
6478 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6480 reg
= 1+ap
->Args
[i
].ArgReg
; DoOutputDirect(®
, 1);
6483 return DoOutputDirect(®
, 1);
6486 uint32
FuncVBCCInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6488 struct ClibData
*cd
;
6492 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6495 /* find register pairs for 64-bit types (long long, double) */
6496 FindRegPairs(ap
, cd
);
6498 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6501 c1
= Flags
& FLAG_NEWSYNTAX
? "(" : ""; /*)*/
6502 c2
= Flags
& FLAG_NEWSYNTAX
? "," : "("; /*)*/
6504 Flags
|= FLAG_DONE
; /* We did something */
6506 if(flags
& FUNCFLAG_TAG
)
6508 if(IsNoCreateInlineFunc(name
))
6509 return 1; /* do not create some strange functions */
6510 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6511 "(__STDC_VERSION__ >= 199901L)\n");
6514 if(flags
& FUNCFLAG_ALIAS
)
6516 DoOutput("#define %s("/*)*/, name
);
6517 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6518 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6519 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6520 if(Flags2
& FLAG2_OLDVBCC
)
6522 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6523 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6524 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6529 DoOutput("%s", BaseName
);
6530 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6531 DoOutput(", (%s)", ap
->Args
[i
].ArgName
);
6532 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
?
6537 OutClibType(&cd
->ReturnType
, 0);
6538 DoOutput(" __%s("/*)*/, name
);
6540 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6542 DoOutput("__reg(\"a6\") %s", GetBaseType());
6547 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6548 for(i
= 0; i
< k
; ++i
)
6550 DoOutput("__reg(\"%s\") ", RegNames
[ap
->Args
[i
].ArgReg
]);
6551 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6552 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6554 DoOutput("void * %s", ap
->Args
[i
].ArgName
);
6557 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6558 if(i
< ap
->NumArgs
-1)
6562 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6566 DoOutput("__reg(\"a6\") %s", GetBaseType());
6569 if(flags
& FUNCFLAG_TAG
)
6571 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6573 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6576 DoOutput(/*(*/"...)=\"\\tmove.l\\t%s,-(a7)\\n",
6577 RegNames
[ap
->Args
[k
].ArgReg
]);
6579 if(ap
->Args
[k
].ArgReg
> 7)
6580 DoOutput(/*(*/"\\tlea\\t%s4%sa7),%s\\n", c1
, c2
,
6581 RegNames
[ap
->Args
[k
].ArgReg
]);
6583 DoOutput("\\tmove.l\\ta7,%s\\n\\taddq.l\\t#4,%s\\n",
6584 RegNames
[ap
->Args
[k
].ArgReg
], RegNames
[ap
->Args
[k
].ArgReg
]);
6586 DoOutput(/*(*/"\\tjsr\\t%s-%d%sa6)\\n"
6587 "\\tmove%s.l\\t(a7)+,%s\";\n", c1
, ap
->Bias
, c2
,
6588 ap
->Args
[k
].ArgReg
>= REG_A0
? "a" : "", RegNames
[ap
->Args
[k
].ArgReg
]);
6591 DoOutput(/*((*/")=\"\\tjsr\\t%s-%d%sa6)\";\n", c1
, ap
->Bias
, c2
);
6593 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6594 DoOutput("#define %s("/*)*/, name
);
6595 for(i
= 0; i
< k
; ++i
)
6597 DoOutput("%s", ap
->Args
[i
].ArgName
);
6598 if(i
< ap
->NumArgs
-1)
6601 if(flags
& FUNCFLAG_TAG
)
6603 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6604 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6607 DoOutput(/*(*/") __%s("/*)*/, name
);
6608 if(!(Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6610 DoOutput("%s", BaseName
);
6614 for(i
= 0; i
< k
; ++i
)
6616 if(ap
->Args
[i
].ArgReg
>= REG_A0
&& ap
->Args
[i
].ArgReg
<= REG_A7
6617 && !(cd
->Args
[i
].Flags
& (CPP_FLAG_POINTER
|CPP_FLAG_FUNCTION
)))
6619 DoOutput("(void *)");
6621 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6622 if(i
< ap
->NumArgs
-1)
6625 if((Flags2
& FLAG2_OLDVBCC
) && BaseName
)
6629 DoOutput("%s", BaseName
);
6631 if(flags
& FUNCFLAG_TAG
)
6633 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6634 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6635 DoOutput("__VA_ARGS__");
6638 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6641 uint32
FuncVBCCWOSInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6643 struct ClibData
*cd
;
6646 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_M68K
))
6649 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6652 Flags
|= FLAG_DONE
; /* We did something */
6654 if(flags
& FUNCFLAG_TAG
)
6656 if(IsNoCreateInlineFunc(name
))
6657 return 1; /* do not create some strange functions */
6658 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6659 "(__STDC_VERSION__ >= 199901L)\n");
6662 if(flags
& FUNCFLAG_ALIAS
)
6664 DoOutput("#define %s("/*)*/, name
);
6665 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6666 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6667 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6668 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6669 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6670 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6674 OutClibType(&cd
->ReturnType
, 0);
6675 DoOutput(" __%s("/*)*/, name
);
6677 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6679 DoOutput("%s", GetBaseType());
6685 for(i
= 0; i
< k
; ++i
)
6687 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6691 if(flags
& FUNCFLAG_TAG
)
6692 DoOutput(", ..."); /* a standalone ... is not allowed in C */
6694 DoOutput(/*(*/")=\"");
6695 if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
6697 DoOutput("\\t.extern\\t_%s\\n", BaseName
);
6698 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6700 /* save tag1 and load taglist-pointer */
6701 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6702 "\\taddi\\t%s%d,%s1,%d\\n",
6703 PPCRegPrefix
, k
+2, 20+k
*4, PPCRegPrefix
, PPCRegPrefix
,
6704 k
+2, PPCRegPrefix
, 20+k
*4);
6706 DoOutput("\\tlwz\\t%s11,_%s(%s2)\\n"
6707 "\\tlwz\\t%s0,-%d(%s11)\\n"
6710 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
,
6711 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6713 else if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
6715 /* @@@ tagcall handling? */
6716 DoOutput("\\tstw\\t%s2,20(%s1)\\n"
6717 "\\t.extern\\t_%s\\n"
6718 "\\tlwz\\t%s2,_%s(%s2)\\n"
6719 "\\tlwz\\t%s0,-%d(%s2)\\n"
6722 "\\tlwz\\t%s2,20(%s1)",
6723 PPCRegPrefix
, PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
,
6724 PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
6725 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
6729 if ((flags
& FUNCFLAG_TAG
) && k
>0)
6731 /* save tag1 and load taglist-pointer */
6732 DoOutput("\\tstw\\t%s%d,%d(%s1)\\n"
6733 "\\taddi\\t%s%d,%s1,%d\\n",
6734 PPCRegPrefix
, k
+3, 24+k
*4, PPCRegPrefix
, PPCRegPrefix
,
6735 k
+3, PPCRegPrefix
, 24+k
*4);
6737 DoOutput("\\tlwz\\t%s0,-%d(%s3)\\n"
6740 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
6744 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6745 DoOutput("#define %s("/*)*/, name
);
6746 for(i
= 0; i
< k
; ++i
)
6748 DoOutput("%s", ap
->Args
[i
].ArgName
);
6749 if(i
< ap
->NumArgs
-1)
6752 if(flags
& FUNCFLAG_TAG
)
6754 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6755 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6758 DoOutput(/*(*/") __%s("/*)*/, name
);
6759 if(!(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)))
6761 DoOutput("%s", BaseName
);
6765 for(i
= 0; i
< k
; ++i
)
6767 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6768 if(i
< ap
->NumArgs
-1)
6771 if(flags
& FUNCFLAG_TAG
)
6773 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6774 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6775 DoOutput("__VA_ARGS__");
6778 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6781 uint32
FuncVBCCMorphInline(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6783 struct ClibData
*cd
;
6786 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
6789 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
6792 Flags
|= FLAG_DONE
; /* We did something */
6794 if(flags
& FUNCFLAG_TAG
)
6796 if(IsNoCreateInlineFunc(name
))
6797 return 1; /* do not create some strange functions */
6798 DoOutput("#if !defined(NO_INLINE_STDARG) && (__STDC__ == 1L) && "
6799 "(__STDC_VERSION__ >= 199901L)\n");
6802 if(flags
& FUNCFLAG_ALIAS
)
6804 DoOutput("#define %s("/*)*/, name
);
6805 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
6806 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
6807 DoOutput(/*(*/"%s) __%s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
6808 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6809 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
6810 return DoOutput(/*(*/"%s)\n%s\n", BaseName
, flags
& FUNCFLAG_TAG
?
6814 OutClibType(&cd
->ReturnType
, 0);
6815 if((flags
& FUNCFLAG_TAG
) && (Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6816 DoOutput(" __linearvarargs");
6818 DoOutput(" __%s("/*)*/, name
);
6820 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6822 DoOutput("%s", GetBaseType());
6827 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6829 if((flags
& FUNCFLAG_TAG
) &&
6830 !(ap
->Flags
& AMIPRAGFLAG_MOS_ALL
))
6832 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6837 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-1 : ap
->NumArgs
;
6838 for(i
= 0; i
< k
; ++i
)
6840 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
6841 if(i
< ap
->NumArgs
-1)
6845 if(flags
& FUNCFLAG_TAG
)
6847 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6849 if((ap
->Flags
& AMIPRAGFLAG_MOS_ALL
)
6850 && !(ap
->Flags
& AMIPRAGFLAG_VARARGS
))
6852 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6855 if(cd
->Args
[k
].Type
!= CPP_TYPE_VARARGS
)
6857 OutClibType(&cd
->Args
[k
], ap
->Args
[k
].ArgName
);
6865 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
6867 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s0,-%d(%s3)\\n\"\n",
6868 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6869 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6871 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6872 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6874 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6875 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6877 else if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
6881 DoOutput(/*(*/") =\n\t\"\\tlis\\t%s11,%s@ha\\n\"\n"
6882 "\t\"\\tlwz\\t%s12,%s@l(%s11)\\n\"\n"
6883 "\t\"\\tlwz\\t%s0,-%d(%s12)\\n\"\n",
6884 PPCRegPrefix
, BaseName
,
6885 PPCRegPrefix
, BaseName
, PPCRegPrefix
,
6886 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
);
6888 if((ap
->Flags
!= AMIPRAGFLAG_VARARGS
) && (flags
& FUNCFLAG_TAG
))
6890 DoOutput("\t\"\\taddi\\t%s%ld,%s1,8\\n\"\n",
6891 PPCRegPrefix
,3+k
+1,PPCRegPrefix
);
6893 DoOutput("\t\"\\tmtctr\\t%s0\\n\"\n"
6894 "\t\"\\tbctrl\";\n", PPCRegPrefix
);
6898 int ofs
= 4, fix
= 0;
6899 DoOutput(/*(*/") =\n\t\"\\tlwz\\t%s11,100(%s2)\\n\"\n",
6900 PPCRegPrefix
, PPCRegPrefix
);
6904 DoOutput("\t\"\\tstw\\t%s%ld,56(%s2)\\n\"\n", PPCRegPrefix
, k
++,
6907 if(Flags2
& FLAG2_SHORTPPCVBCCINLINE
)
6910 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6913 else if(flags
& FUNCFLAG_TAG
)
6915 if((i
= ap
->NumArgs
+(BaseName
?1:0)) <= 8)
6919 DoOutput("\t\"\\tmtctr\\t%s11\\n\"\n", PPCRegPrefix
);
6920 for(i
= 0; i
< ap
->NumArgs
; ++i
)
6922 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
6925 DoOutput("\t\"\\tstw\\t%s%ld,", PPCRegPrefix
, k
++);
6927 DoOutput("\t\"\\tlwz\\t%s11,%ld(%s1)\\n\"\n\t\"\\tstw\\t%s11,",
6928 PPCRegPrefix
, 8+(k
++-11)*4, PPCRegPrefix
, PPCRegPrefix
);
6932 DoOutput("\t\"\\taddi\\t%s%d,%s1,%ld\\n\"\n\t\"\\tstw\\t%s%d,",
6933 PPCRegPrefix
, ofs
, PPCRegPrefix
, (2+k
+fix
-11)*4, PPCRegPrefix
, ofs
);
6935 DoOutput("%d(%s2)\\n\"\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
6937 DoOutput("\t\"\\tli\\t%s3,-%d\\n\"\n\t\"\\tbctrl\";\n", PPCRegPrefix
,
6941 k
= (flags
& FUNCFLAG_TAG
) ? ap
->NumArgs
-2 : ap
->NumArgs
;
6942 DoOutput("#define %s("/*)*/, name
);
6943 for(i
= 0; i
< k
; ++i
)
6945 DoOutput("%s", ap
->Args
[i
].ArgName
);
6946 if(i
< ap
->NumArgs
-1)
6949 if(flags
& FUNCFLAG_TAG
)
6951 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6952 DoOutput("%s, ", ap
->Args
[k
].ArgName
);
6955 DoOutput(/*(*/") __%s("/*)*/, name
);
6956 if(BaseName
&& !(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
)))
6958 DoOutput("%s", BaseName
);
6962 if(!(Flags2
& FLAG2_SHORTPPCVBCCINLINE
))
6964 if(flags
& FUNCFLAG_TAG
&& !(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
))
6966 for(i
= ap
->NumArgs
+(BaseName
?1:0); i
<= 8; ++i
)
6970 for(i
= 0; i
< k
; ++i
)
6972 DoOutput("(%s)", ap
->Args
[i
].ArgName
);
6973 if(i
< ap
->NumArgs
-1)
6976 if(flags
& FUNCFLAG_TAG
)
6978 if(ap
->NumArgs
> 1 && cd
->Args
[ap
->NumArgs
-1].Type
!= CPP_TYPE_VARARGS
)
6979 DoOutput("(%s), ", ap
->Args
[k
].ArgName
);
6980 DoOutput("__VA_ARGS__");
6983 return DoOutput(/*(*/")\n%s\n", flags
& FUNCFLAG_TAG
? "#endif\n" : "");
6986 uint32
FuncVBCCWOSText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
6988 uint32 i
, k
, count
, ofs
;
6989 struct ClibData
*cd
= 0;
6991 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
6994 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
6995 !(cd
= GetClibFunc(name
, ap
, flags
)))
6998 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
6999 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
7000 !(Flags
& FLAG_WOSLIBBASE
)))
7002 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
7008 if(Flags
& FLAG_SINGLEFILE
)
7010 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7015 DoOutputDirect(HEADER
, headersize
);
7019 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7020 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7022 if(Flags
& FLAG_SINGLEFILE
)
7023 DoOutput("\t.file\t\"%s.o\"\n", name
);
7024 DoOutput("\t.align\t3\n");
7025 if(Flags
& FLAG_WOSLIBBASE
) /* PPCBase already in r3, LibBase in r4 */
7027 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
7028 DoOutput("\t.extern _%s\n", BaseName
);
7029 DoOutput("\t.global __%s\n__%s:\n", name
, name
);
7034 DoOutput("\t.extern _%s\n", BaseName
);
7035 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7036 DoOutput("\t.extern _PowerPCBase\n");
7037 DoOutput("\t.global _%s\n_%s:\n", name
, name
);
7040 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7042 DoOutput("\tstw\t%s2,20(%s1)\n"
7044 "\tstw\t%s0,16(%s1)\n"
7045 "\tlwz\t%s2,_%s(%s2)\n"
7046 "\tlwz\t%s0,-%d(%s2)\n"
7049 "\tlwz\t%s0,16(%s1)\n"
7050 "\tlwz\t%s2,20(%s1)\n"
7053 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7054 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2,
7055 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7056 PPCRegPrefix
, PPCRegPrefix
);
7058 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7060 DoOutput("\tmflr\t%s0\n", PPCRegPrefix
);
7061 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7063 DoOutput("\tstw\t%s%d,%d(%s1)\n" /* store first tag */
7064 "\taddi\t%s%d,%s1,%d\n", /* TagItem pointer */
7065 PPCRegPrefix
, (int)ap
->NumArgs
+2,
7066 20+(int)ap
->NumArgs
*4, PPCRegPrefix
, PPCRegPrefix
,
7067 (int)ap
->NumArgs
+2, PPCRegPrefix
, 20+(int)ap
->NumArgs
*4);
7069 DoOutput("\tstw\t%s0,8(%s1)\n" /* store LR */
7070 "\tstwu\t%s1,-32(%s1)\n" /* new stack frame */
7071 "\tlwz\t%s11,_%s(%s2)\n"
7072 "\tlwz\t%s0,-%d(%s11)\n"
7075 "\tlwz\t%s0,40(%s1)\n"
7076 "\taddi\t%s1,%s1,32\n"
7079 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7080 BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
,
7081 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7084 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7086 count
= ap
->NumArgs
;
7087 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7089 /* init stack frame */
7090 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7091 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7092 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7096 /* extra arguments must be passed on the stack */
7097 k
= 32-(count
-8); /* firstreg */
7099 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n\tlmw\t%s%ld,%ld(%s1)\n",
7100 PPCRegPrefix
, k
, 56+(count
-8)*4, PPCRegPrefix
, PPCRegPrefix
, k
,
7101 i
+56, PPCRegPrefix
);
7102 if(flags
& FUNCFLAG_TAG
)
7103 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7105 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7107 else if(flags
& FUNCFLAG_TAG
)
7109 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7110 PPCRegPrefix
, i
+20+count
*4);
7114 else /* Args must be shifted! */
7116 /* init stack frame */
7117 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7118 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-%ld(%s1)\n",
7119 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
);
7123 /* extra arguments must be passed on the stack */
7126 /* special case: move 8th argument into stack frame */
7127 if(flags
& FUNCFLAG_TAG
)
7128 DoOutput("\taddi\t%s10,%s1,%ld\n", PPCRegPrefix
, PPCRegPrefix
,
7130 DoOutput("\tstw\t%s10,56(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7134 k
= 32-(count
-7); /* firstreg */
7136 DoOutput("\tstmw\t%s%ld,%ld(%s1)\n"
7137 "\tmr\t%s%ld,%s10\n"
7138 "\tlmw\t%s%ld,%ld(%s1)\n",
7139 PPCRegPrefix
, k
, 56+(count
-7)*4, PPCRegPrefix
,
7140 PPCRegPrefix
, k
, PPCRegPrefix
, PPCRegPrefix
, k
+1,
7141 i
+56, PPCRegPrefix
);
7142 if(flags
& FUNCFLAG_TAG
)
7143 DoOutput("\taddi\t%s31,%s1,%ld\n", PPCRegPrefix
,
7144 PPCRegPrefix
, i
+20+count
*4);
7145 DoOutput("\tstmw\t%s%ld,56(%s1)\n", PPCRegPrefix
, k
, PPCRegPrefix
);
7148 else if(flags
& FUNCFLAG_TAG
)
7150 DoOutput("\taddi\t%s%ld,%s1,%ld\n", PPCRegPrefix
, count
+3,
7151 PPCRegPrefix
, i
+20+count
*4);
7155 /* shift all arguments into their following register */
7156 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7157 DoOutput("\tmr\t%s%ld,%s%ld\n", PPCRegPrefix
, 3+k
, PPCRegPrefix
, 2+k
);
7159 /* load library base and LVO, then call LVO via LR */
7160 DoOutput("\tlwz\t%s3,_%s(%s2)\n", PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7164 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtlr\t%s0\n\tblrl\n", PPCRegPrefix
,
7165 ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
7167 /* cleanup stack frame and return */
7170 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7171 DoOutput("\tlmw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, 32-(count
-k
),
7172 56+(count
-k
)*4, PPCRegPrefix
);
7175 DoOutput("\taddi\t%s1,%s1,%ld\n\tlwz\t%s0,8(%s1)\n\tmtlr\t%s0\n\tblr\n",
7176 PPCRegPrefix
, PPCRegPrefix
, i
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7180 DoOutput("\tmflr\t%s0\n\tstw\t%s0,8(%s1)\n\tstwu\t%s1,-0xB0(%s1)\n",
7181 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7183 /* clear PP_Flags, PP_Stack and PP_StackSize */
7184 DoOutput("\tli\t%s11,0\n\tstw\t%s11,0x28(%s1)\n\tstw\t%s11,0x2C(%s1)\n"
7185 "\tstw\t%s11,0x30(%s1)\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7186 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7188 if(Flags
& FLAG_WOSLIBBASE
)
7189 DoOutput("\tli\t%s11,-%d\n\tstw\t%s4,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n"
7190 "\tstw\t%s4,0x6C(%s1)\n", PPCRegPrefix
, ap
->Bias
, PPCRegPrefix
,
7191 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7193 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,0x24(%s1)\n", PPCRegPrefix
,
7194 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
);
7196 DoOutput("\tlwz\t%s0,_%s(%s2)\n\tli\t%s11,-%d\n"
7197 "\tstw\t%s0,0x20(%s1)\n\tstw\t%s11,0x24(%s1)\n\tstw\t%s0,0x6c(%s1)\n",
7198 PPCRegPrefix
, BaseName
, PPCRegPrefix
, PPCRegPrefix
, ap
->Bias
,
7199 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7202 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7203 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7204 for(i
= 0; i
< k
; ++i
)
7208 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7209 DoOutput("\tstw\t%s%ld,0x20(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7211 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3+ofs
);
7215 DoOutput("\tlwz\t%s11,%ld(%s1)\n", PPCRegPrefix
, (i
+1+ofs
)*4+196,
7217 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7218 DoOutput("\tstw\t%s11,0x20(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7219 DoOutput("\tstw\t%s11,", PPCRegPrefix
);
7221 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7223 if(flags
& FUNCFLAG_TAG
)
7225 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7226 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
+3+ofs
,
7227 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7228 DoOutput("\taddi\t%s11,%s1,%ld\n\tstw\t%s11,", PPCRegPrefix
,
7229 PPCRegPrefix
, 0xC4+(ap
->NumArgs
+ofs
)*4, PPCRegPrefix
);
7230 DoOutput("%d(%s1)\n", 0x34+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7233 if(!(Flags
& FLAG_WOSLIBBASE
))
7234 DoOutput("\tlwz\t%s3,_PowerPCBase(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
7236 DoOutput("\taddi\t%s4,%s1,0x20\n\tlwz\t%s0,-298(%s3)\n\tmtlr\t%s0\n"
7237 "\tblrl\n\tlwz\t%s3,0x34(%s1)\n\taddi\t%s1,%s1,0xB0\n\tlwz\t%s0,8(%s1)\n"
7238 "\tmtlr\t%s0\n\tblr\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7239 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7240 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7243 if(Flags
& FLAG_WOSLIBBASE
)
7244 return DoOutput("\t.type\t__%s,@function\n\t.size\t__%s,$-__%s\n\n",
7247 return DoOutput("\t.type\t_%s,@function\n\t.size\t_%s,$-_%s\n\n",
7251 uint32
FuncVBCCWOSCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7253 uint32 i
, j
, k
, ofs
, count
;
7254 uint8
*data
, *basepos
= 0, *pbasepos
= 0;
7255 struct ClibData
*cd
= 0;
7257 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
))
7260 if((flags
& FUNCFLAG_TAG
) && !(ap
->Flags
& AMIPRAGFLAG_PPC
) &&
7261 !(cd
= GetClibFunc(name
, ap
, flags
)))
7264 if((ap
->Flags
& AMIPRAGFLAG_PPC
) && !BaseName
&&
7265 ((ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
)) ||
7266 !(Flags
& FLAG_WOSLIBBASE
)))
7268 DoError(ERR_MISSING_BASENAME
, ap
->Line
);
7272 Flags
|= FLAG_DONE
; /* We did something */
7274 i
= strlen(name
) + 2;
7275 EndPutM32(tempbuf
, HUNK_UNIT
);
7276 EndPutM32(tempbuf
+4, (i
+3)>>2);
7277 DoOutputDirect(tempbuf
, 8);
7278 DoOutput("%s.o", name
);
7279 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7281 i
= strlen(hunkname
);
7282 EndPutM32(tempbuf
, HUNK_NAME
);
7283 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
7284 DoOutputDirect(tempbuf
, 8);
7285 DoOutputDirect(hunkname
, i
);
7286 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
7288 data
= tempbuf
+8; /* we need HUNK_PPC_CODE + size at start */
7290 if(ap
->Flags
& AMIPRAGFLAG_PPC2
)
7292 EndPutM32Inc(data
, 0x90410014); /* stw r2,20(r1) */
7293 /* mflr r0 = mfspr r0,8 = get link register */
7294 EndPutM32Inc(data
, 0x7C0802A6);
7295 EndPutM32Inc(data
, 0x90010010); /* stw r0,16(r1) */
7297 EndPutM32Inc(data
, 0x80420000); /* lwz r2,BaseName(r2) */
7298 EndPutM32Inc(data
, 0x80030000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r2) */
7299 /* mtlr r0 = mtspr 8,r0 = restore link register */
7300 EndPutM32Inc(data
, 0x7C0803A6);
7301 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7302 EndPutM32Inc(data
, 0x80010010); /* lwz r0,16(r1) */
7303 EndPutM32Inc(data
, 0x80410014); /* lwz r2,20(r1) */
7304 /* mtlr r0 = mtspr 8,r0 = restore link register */
7305 EndPutM32Inc(data
, 0x7C0803A6);
7306 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7308 else if(ap
->Flags
& AMIPRAGFLAG_PPC0
)
7311 /* mflr r0 = mfspr r0,8 = get link register */
7312 EndPutM32Inc(data
, 0x7C0802A6);
7313 if((flags
& FUNCFLAG_TAG
) && ap
->NumArgs
>0)
7315 EndPutM32Inc(data
, 0x90010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7316 (uint32
)(20+ap
->NumArgs
*4)); /* stw rN,d(r1) */
7317 EndPutM32Inc(data
, 0x38010000 + (((uint32
)ap
->NumArgs
+2) << 21) +
7318 (uint32
)(20+ap
->NumArgs
*4)); /* addi rN,r1,d */
7320 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7321 EndPutM32Inc(data
, 0x9421FFCE); /* stwu r1,-32(r1) */
7322 EndPutM32Inc(data
, 0x81620000); /* lwz r11,BaseName(r2) */
7323 EndPutM32Inc(data
, 0x800C0000-(ap
->Bias
-2));/* lwz r0,-ap->Bias-2(r11) */
7324 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7325 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7326 EndPutM32Inc(data
, 0x80010028); /* lwz r0,40(r1) */
7327 EndPutM32Inc(data
, 0x38210020); /* addi r1,r1,32 */
7328 /* mtlr r0 = mtspr 8,r0 = restore link register */
7329 EndPutM32Inc(data
, 0x7C0803A6);
7330 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7332 else if(ap
->Flags
& AMIPRAGFLAG_PPC
)
7334 count
= ap
->NumArgs
;
7335 if(Flags
& FLAG_WOSLIBBASE
) /* LibBase already in r3 */
7337 /* init stack frame */
7338 i
= (count
<= 8) ? 32 : ((56+(count
-8)*8+15)&~15); /* stksize */
7339 /* mflr r0 = mfspr r0,8 = get link register */
7340 EndPutM32Inc(data
, 0x7C0802A6);
7341 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7342 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7346 /* extra arguments must be passed on the stack */
7347 k
= 32-(count
-8); /* firstreg */
7349 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-8)*4));
7350 EndPutM32Inc(data
, 0xB8010000 + (k
<< 21) + (i
+56)); /* lmw rk,Y(r1) */
7351 if(flags
& FUNCFLAG_TAG
)
7352 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4)); /* addi r31,r1,X */
7353 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7355 else if(flags
& FUNCFLAG_TAG
)
7358 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7362 else /* Args must be shifted! */
7364 /* init stack frame */
7365 i
= (count
< 8) ? 32 : ((56+(count
-7)*8+15)&~15); /* stksize */
7366 /* mflr r0 = mfspr r0,8 = get link register */
7367 EndPutM32Inc(data
, 0x7C0802A6);
7368 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) */
7369 EndPutM32Inc(data
, 0x94220000 - i
); /* stwu r1,-i(r1) */
7373 /* extra arguments must be passed on the stack */
7376 /* special case: move 8th argument into stack frame */
7377 if(flags
& FUNCFLAG_TAG
)
7378 EndPutM32Inc(data
, 0x39410000 + (i
+20+count
*4)); /* addi r10,r1,X */
7379 EndPutM32Inc(data
, 0x91410038); /* stw r10,56(r1) */
7383 k
= 32-(count
-7); /* firstreg */
7386 EndPutM32Inc(data
, 0xBC010000 + (k
<< 21) + (56+(count
-7)*4));
7387 /* mr rk,r10 = or rk,r10,r10 */
7388 EndPutM32Inc(data
, 0x7D405378 + (k
<<16));
7390 EndPutM32Inc(data
, 0xB8010000 + ((k
+1) << 21) + (i
+56));
7391 if(flags
& FUNCFLAG_TAG
)
7394 EndPutM32Inc(data
, 0x3BE10000 + (i
+20+count
*4));
7396 EndPutM32Inc(data
, 0xBC010038 + (k
<< 21)); /* stmw rk,56(r1) */
7399 else if(flags
& FUNCFLAG_TAG
)
7402 EndPutM32Inc(data
, 0x38010000 + ((count
+3)<<21) + (i
+20+count
*4));
7406 /* shift all arguments into their following register */
7407 for(k
=(count
<8)?count
:7; k
> 0; --k
)
7408 EndPutM32Inc(data
, 0x7C000378 + ((3+k
)<<16) + ((2+k
)<<21) + ((2+k
)<<11)); /* mr rX,rY = or rX,rY,rY */
7410 /* load library base and LVO, then call LVO via LR */
7412 EndPutM32Inc(data
, 0x80620000); /* lwz r3,BaseName(r2) */
7415 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2)); /* lwz r0,-(ap->Bias-2)(r3) */
7416 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7417 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7420 /* cleanup stack frame and return */
7423 k
= Flags
& FLAG_WOSLIBBASE
? 8 : 7; /* restore saved regs */
7424 EndPutM32Inc(data
, 0xB8010000 + ((32-(count
-k
))<<21) + (56+(count
-k
)*4)); /* lmw rX,Y(r1) */
7426 EndPutM32Inc(data
, 0x38210000 + i
); /* addi r1,r1,i */
7427 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) */
7428 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7429 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump */
7433 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 = mfspr r0,8 = get link register */
7434 EndPutM32Inc(data
, 0x90010008); /* stw r0,8(r1) = save link register in 8(r1) */
7435 EndPutM32Inc(data
, 0x9421FF50); /* stwu r1,-0xB0(r1) = store word from r1 in -0xB0(r1) and update r1 */
7437 EndPutM32Inc(data
, 0x39600000); /* li r11,0 = addi r11,r0,0 = clear r11 */
7438 EndPutM32Inc(data
, 0x91610028); /* stwu r11,0x28(r1) = clear PP_Flags */
7439 EndPutM32Inc(data
, 0x9161002C); /* stwu r11,0x2C(r1) = clear PP_Stack */
7440 EndPutM32Inc(data
, 0x91610030); /* stwu r11,0x30(r1) = clear PP_StackSize */
7442 if(Flags
& FLAG_WOSLIBBASE
)
7444 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7445 EndPutM32Inc(data
, 0x90810020); /* stw r4,0x20(r1) = set PP_Code to Librarybase */
7446 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7447 EndPutM32Inc(data
, 0x9081006C); /* stw r4,0x6C(r1) = set A6 register */
7451 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7452 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7457 EndPutM32Inc(data
, 0x80020000); /* lwz r0,BaseName(r2) --> 16BIT RELOC! */
7458 EndPutM32Inc(data
, 0x39610000 -ap
->Bias
); /* li r11,ap->Bias */
7459 EndPutM32Inc(data
, 0x90010020); /* stw r0,0x20(r1) = set PP_Code to Librarybase */
7460 EndPutM32Inc(data
, 0x91610024); /* stw r11,0x24(r1) = set PP_Offset to Bias value */
7461 EndPutM32Inc(data
, 0x9001006C); /* stw r4,0x6C(r1) = set A6 register */
7464 ofs
= Flags
& FLAG_WOSLIBBASE
? 2 : 0;
7465 k
= ap
->NumArgs
- (flags
& FUNCFLAG_TAG
? 1 : 0);
7466 for(i
= 0; i
< k
; ++i
)
7468 j
= 0x34+4*ap
->Args
[i
].ArgReg
; /* PP_Regs offset */
7471 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7472 EndPutM32Inc(data
, 0x90010020 + ((i
+3+ofs
)<<21)); /* stw rX,0x20(r1) */
7473 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7477 EndPutM32Inc(data
, 0x81610000 + ((i
+1+ofs
)*4+0xC4)); /* lwz r11,X(r1) = get data from stack */
7478 if(ap
->Args
[i
].ArgReg
== REG_A6
)
7479 EndPutM32Inc(data
, 0x91610020); /* stw r11,0x20(r1) */
7480 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7483 if(flags
& FUNCFLAG_TAG
)
7485 j
= (ap
->NumArgs
+ofs
)*4+0xC4;
7487 if((i
+ofs
) <= 7 && cd
->Args
[i
].Type
!= CPP_TYPE_VARARGS
)
7488 EndPutM32Inc(data
, 0x90010000 + ((i
+3+ofs
)<<21) + j
); /* stw rX,j(r1) */
7489 EndPutM32Inc(data
, 0x39610000 + j
); /* addi r11,r1,j */
7490 EndPutM32Inc(data
, 0x91610000 + (0x34+4*ap
->Args
[i
].ArgReg
)); /* stw r11,X(r1) */
7493 if(!(Flags
& FLAG_WOSLIBBASE
))
7495 pbasepos
= data
; /* store 16BIT reloc offset */
7496 EndPutM32Inc(data
, 0x80620000); /* lwz r3,_PowerPCBase(r2) = get librarybase */
7498 EndPutM32Inc(data
, 0x38810020); /* addi r4,r1,0x20 = {r4 := 0x20(r1)} */
7499 EndPutM32Inc(data
, 0x8003FED6); /* lwz r0,-298(r3) = load jumpin base */
7500 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = store link register */
7501 EndPutM32Inc(data
, 0x4E800021); /* blrl = bclrl 20,0 = jump */
7502 EndPutM32Inc(data
, 0x80610034); /* lwz r3,0x34(r1) = get result D0 */
7503 EndPutM32Inc(data
, 0x382100B0); /* addi r1,r1,0xB0 = free PRCArgs structure */
7504 EndPutM32Inc(data
, 0x80010008); /* lwz r0,8(r1) = get old link register */
7505 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
7506 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 = jump back */
7509 EndPutM32(tempbuf
, HUNK_PPC_CODE
);
7510 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
7511 DoOutputDirect(tempbuf
, (data
-tempbuf
)&(~3));
7513 EndPutM32(tempbuf
, HUNK_EXT
);
7514 DoOutputDirect(tempbuf
,4);
7516 /* here come the XDEF name references */
7518 if(Flags
& FLAG_WOSLIBBASE
)
7520 if(ap
->Flags
& (AMIPRAGFLAG_PPC0
|AMIPRAGFLAG_PPC2
))
7521 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7522 OutputXDEF(0, "__%s", name
);
7527 OutputXREF((basepos
-tempbuf
-8)+2, EXT_DEXT16
, "_%s", BaseName
);
7528 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
7529 OutputXREF((pbasepos
-tempbuf
-8)+2, EXT_DEXT16
, "_PowerPCBase");
7530 OutputXDEF(0, "_%s", name
);
7532 EndPutM32(tempbuf
, 0);
7533 DoOutputDirect(tempbuf
,4);
7534 if(!(Flags
& FLAG_NOSYMBOL
))
7536 EndPutM32(tempbuf
, HUNK_SYMBOL
);
7537 DoOutputDirect(tempbuf
,4);
7538 if(Flags
& FLAG_WOSLIBBASE
)
7539 OutputSYMBOL(0, "__%s", name
);
7541 OutputSYMBOL(0, "_%s", name
);
7542 EndPutM32(tempbuf
, 0);
7543 DoOutputDirect(tempbuf
,4);
7545 EndPutM32(tempbuf
, HUNK_END
);
7547 return DoOutputDirect(tempbuf
,4);
7550 uint32
FuncVBCCPUPText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7554 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7559 if(Flags
& FLAG_SINGLEFILE
)
7561 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
7566 DoOutputDirect(HEADER
, headersize
);
7570 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
7571 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
7573 if(Flags
& FLAG_SINGLEFILE
)
7574 DoOutput("\t.file\t\"%s.o\"\n", name
);
7576 DoOutput("\t.global %s\n", BaseName
);
7577 DoOutput("\t.global PPCCallOS\n\t.global %s\n"
7578 "\t.align\t3\n%s:\n",name
, name
);
7580 if(flags
& FUNCFLAG_TAG
)
7582 /* Hack the stack-frame for varargs.
7583 Build stack-frame, but save LR in our own stack-frame,
7584 because we have to overwrite the lower 8 bytes of the
7586 DoOutput("\tstwu\t%s1,-128(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7587 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7589 /* Save the caller's saved SP in our own stack-frame. */
7590 DoOutput("\tlwz\t%s11,128(%s1)\n\tstw\t%s11,96(%s1)\n", PPCRegPrefix
,
7591 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7593 /* Store r3-r8 at the top of our stack-frame and r9-r10
7594 at the low 8 bytes of the caller's frame. This way all
7595 arguments will reside in one continuous area. */
7596 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7597 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
, 104+4*(i
-3),
7601 DoOutput("\tstwu\t%s1,-96(%s1)\n\tmflr\t%s11\n\tstw\t%s11,100(%s1)\n",
7602 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7604 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7606 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7609 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
7611 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
7612 100+(i
+1-8)*4, PPCRegPrefix
, PPCRegPrefix
);
7615 DoOutput("\taddi\t%s11,%s1,%d\n\tstw\t%s11,", PPCRegPrefix
,
7616 PPCRegPrefix
, 100+ap
->NumArgs
*4, PPCRegPrefix
);
7617 DoOutput("%d(%s1)\n", 36+4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
7620 /* Now place the real function call */
7621 /* store offset in Chaos->caos_Un.Offset */
7622 DoOutput("\tli\t%s11,-%d\n\tstw\t%s11,8(%s1)\n"
7623 "\tli\t%s11,1\n\tstw\t%s11,12(%s1)\n\tstw\t%s11,24(%s1)\n", PPCRegPrefix
,
7624 ap
->Bias
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7625 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7626 /* set M68kCacheMode and PPCCacheMode to IF_CACHEFLUSHALL */
7630 if(Flags
& FLAG_SMALLDATA
)
7631 DoOutput("\tlwz\t%s11,%s@sdarx(%s13)\n", PPCRegPrefix
, BaseName
,
7634 DoOutput("\tlis\t%s11,%s@ha\n\tlwz\t%s11,%s@l(%s11)\n", PPCRegPrefix
,
7635 BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
7636 /* store basepointer in A6 */
7637 DoOutput("\tstw\t%s11,92(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
7640 DoOutput("\taddi\t%s3,%s1,8\n\tbl\tPPCCallOS\n", PPCRegPrefix
, PPCRegPrefix
);
7641 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7642 DoOutput("\tlwz\t%s11,96(%s1)\n\tstw\t%s11,128(%s1)\n"
7643 "\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,128\n",
7644 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
7645 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7647 DoOutput("\tlwz\t%s11,100(%s1)\n\tmtlr\t%s11\n\taddi\t%s1,%s1,96\n",
7648 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
7650 return DoOutput("\tblr\n\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n", name
,
7654 uint32
FuncVBCCPUPCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7656 int32 i
, j
=0, k
, size
;
7657 uint8
*data
, *data2
, *data3
;
7658 struct ArHeader
*arh
;
7662 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
7667 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
7668 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
7669 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
7670 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
7671 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
7672 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
7673 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
7674 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7675 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7676 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
7677 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
7678 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
7679 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
7680 EndPutM32Inc(data
, 0); /* eeh->e_entry */
7681 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
7682 data2
= data
; data
+= 4;
7683 EndPutM32Inc(data
, 0); /* eeh->e_flags */
7684 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
7685 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
7686 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
7687 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
7688 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
7689 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
7692 if(flags
& FUNCFLAG_TAG
)
7694 /* Hack the stack-frame for varargs.
7695 Build stack-frame, but save LR in our own stack-frame,
7696 because we have to overwrite the lower 8 bytes of the
7698 EndPutM32Inc(data
, 0x9421FF80); /* stwu r1,-128(r1) */
7699 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7700 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7702 /* Save the caller's saved SP in our own stack-frame. */
7703 EndPutM32Inc(data
, 0x81610080); /* lwz r11,128(r1) */
7704 EndPutM32Inc(data
, 0x91610060); /* stw r11,96(r1) */
7706 /* Store r3-r8 at the top of our stack-frame and r9-r10
7707 at the low 8 bytes of the caller's frame. This way all
7708 arguments will reside in one continuous area. */
7709 for(i
=3+ap
->NumArgs
-1; i
<= 10; ++i
)
7710 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (104+4*(i
-3))); /* stw rX,Y(r1) */
7714 EndPutM32Inc(data
, 0x9421FFA0); /* stwu r1,-96(r1) */
7715 EndPutM32Inc(data
, 0x7D6802A6); /* mflr r11 = mfspr r11,8 = get link register */
7716 EndPutM32Inc(data
, 0x91610064); /* stw r11,100(r1) */
7719 for(i
= 0; i
< ap
->NumArgs
; ++i
)
7721 j
= 36+4*ap
->Args
[i
].ArgReg
;
7722 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
7726 EndPutM32Inc(data
, 0x90010000 + ((i
+3)<<21) + j
); /* stw rX,j(r1) */
7730 EndPutM32Inc(data
, 0x81610000 + (100+(i
+1-8)*4)); /* lwz r11,X(r1) = get data from stack */
7731 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,j(r1) */
7736 EndPutM32Inc(data
, 0x39610000 + (100+ap
->NumArgs
*4)); /* addi r11,r1,X */
7737 EndPutM32Inc(data
, 0x91610000 + j
); /* stw r11,X(r1) */
7741 /* Now place the real function call */
7742 EndPutM32Inc(data
, 0x39610000 - ap
->Bias
); /* li r11,-(ap->Bias) = addi r11,0,-ap->Bias */
7743 EndPutM32Inc(data
, 0x91610008); /* stw r11,8(r1) */
7744 EndPutM32Inc(data
, 0x39600001); /* li r11,1 = addi r11,0,1 = get IF_CACHEFLUSHALL */
7745 EndPutM32Inc(data
, 0x9161000C); /* stw r11,12(r1) = set M68kCacheMode */
7746 EndPutM32Inc(data
, 0x91610018); /* stw r11,24(r1) = set PPCCacheMode */
7750 if(Flags
& FLAG_SMALLDATA
)
7752 j
= (data
-data3
)+2; /* store reloc offset */
7753 EndPutM32Inc(data
, 0x816D0000); /* lwz r11,BaseName@sdarx(r13) */
7757 j
= (data
-data3
)+2; /* store reloc offset */
7758 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
7759 EndPutM32Inc(data
, 0x816B0000); /* lwz r11,BaseName@l(r11) */
7761 EndPutM32Inc(data
, 0x9161005C); /* stw r11,92(r1) */
7764 EndPutM32Inc(data
, 0x38610008); /* addi r3,r1,8 */
7765 k
= (data
-data3
); /* store reloc offset */
7766 EndPutM32Inc(data
, 0x48000001); /* bl PPCCallOS */
7767 if(flags
& FUNCFLAG_TAG
) /* Varargs. Rebuild the caller's stack-frame. */
7769 EndPutM32Inc(data
, 0x81610060); /* lwz r11,96(r1) */
7770 EndPutM32Inc(data
, 0x91610080); /* stw r11,128(r1) */
7771 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7772 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7773 EndPutM32Inc(data
, 0x38210080); /* addi r1,r1,128 */
7777 EndPutM32Inc(data
, 0x81610064); /* lwz r11,100(r1) */
7778 EndPutM32Inc(data
, 0x7D6803A6); /* mtlr r11 = mtspr 8,r11 = restore link register */
7779 EndPutM32Inc(data
, 0x38210060); /* addi r1,r1,96 */
7782 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
7784 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
7785 data
+= 44; /* 1 9 17 27 33 */
7787 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
7790 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
7791 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
7792 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7793 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7794 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
7795 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
7796 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7797 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7798 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
7799 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7802 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
7803 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
7804 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
7805 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
7806 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
7807 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
7808 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
7809 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
7810 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
7811 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
7814 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
7815 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
7816 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
7817 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
7818 data
+= 4; /* esh[2].sh_offset */
7819 data
+= 4; /* esh[2].sh_size */
7820 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
7821 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
7822 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
7823 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
7825 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
7826 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
7827 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
7828 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
7829 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
7830 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
7831 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
7832 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
7833 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
7834 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
7836 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
7837 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
7838 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
7839 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
7840 data
+= 4; /* esh[4].sh_offset */
7841 data
+= 4; /* esh[4].sh_size */
7842 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
7843 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
7844 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
7845 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
7847 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
7848 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
7849 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
7850 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
7851 data
+= 4; /* esh[0].sh_offset */
7852 data
+= 4; /* esh[0].sh_size */
7853 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
7854 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
7855 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
7856 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
7858 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
7859 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 6*16 : 5*16); /* esh[4].sh_size */
7862 data
+= BaseName
? 6*16 : 5*16;
7864 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
7867 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
7868 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
7869 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
7870 *(data2
++) = 0; /* esym[0].st_info */
7871 *(data2
++) = 0; /* esym[0].st_other */
7872 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
7876 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
7877 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
7878 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
7879 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
7880 *(data2
++) = 0; /* esym[1].st_other */
7881 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
7883 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
++]) ; /* get next store space */
7884 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
7885 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
7886 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
7887 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
7888 *(data2
++) = 0; /* esym[2].st_other */
7889 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
7891 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
7892 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
7893 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
7894 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
7895 *(data2
++) = 0; /* esym[3].st_other */
7896 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
7898 sprintf((strptr
)data
+i
, name
); while(data
[i
++]) ; /* get next store space */
7899 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
7900 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
7901 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
7902 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
7903 *(data2
++) = 0; /* esym[4].st_other */
7904 EndPutM16Inc(data2
, 0); /* esym[4].st_shndx */
7906 sprintf((strptr
)data
+i
, "PPCCallOS"); while(data
[i
++]) ; /* get next store space */
7909 EndPutM32Inc(data2
, i
); /* esym[5].st_name */
7910 EndPutM32Inc(data2
, 0); /* esym[5].st_value */
7911 EndPutM32Inc(data2
, 0); /* esym[5].st_size */
7912 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[5].st_info */
7913 *(data2
++) = 0; /* esym[5].st_other */
7914 EndPutM16
/*Inc*/(data2
, 0); /* esym[5].st_shndx */
7916 sprintf((strptr
)data
+i
, BaseName
); while(data
[i
++]) ; /* get next store space */
7918 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
7919 while(i
&3) /* long aligned */
7923 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
7927 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
7928 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_REL24
)); /* erel[0].r_info - entry 4, type 10 */
7929 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
7933 if(Flags
& FLAG_SMALLDATA
)
7935 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7936 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_SDAREL16
)); /* erel[1].r_info - entry 5, type 32 */
7937 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7941 EndPutM32Inc(data
, j
); /* erel[1].r_offset */
7942 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_HA
)); /* erel[1].r_info - entry 5, type 6 */
7943 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
7944 EndPutM32Inc(data
, j
+4); /* erel[2].r_offset */
7945 EndPutM32Inc(data
, ELF32_R_INFO(5,R_PPC_ADDR16_LO
)); /* erel[2].r_info - entry 5, type 4 */
7946 EndPutM32Inc(data
, 0); /* erel[2].r_addend */
7949 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
7951 /* make ar header and store all */
7952 arh
= (struct ArHeader
*) (data
+20);
7953 memset(arh
, ' ', sizeof(struct ArHeader
));
7955 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
7956 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
7957 arh
->ar_mode
[2] = '0';
7958 arh
->ar_mode
[0] = '6';
7959 arh
->ar_fmag
[0] = 96;
7960 arh
->ar_fmag
[1] = '\n';
7962 if((k
= strlen(name
) + 2) >= 16)
7964 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
7969 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
7972 j
= k
+ (data
-tempbuf
);
7973 for(i
= 9; j
; --i
) /* make decimal number */
7975 data
[i
] = (j
%10)+'0';
7978 for(j
= 0; i
< 9; ++j
)
7979 arh
->ar_size
[j
] = data
[++i
];
7981 DoOutputDirect(arh
, sizeof(struct ArHeader
));
7985 DoOutput("%s.o", name
);
7987 *(data
++) = 0x0A; /* alignment byte! */
7990 return DoOutputDirect(tempbuf
, data
-tempbuf
);
7993 uint32
FuncVBCCMorphText(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
7995 int32 i
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
7997 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
8002 if(Flags
& FLAG_SINGLEFILE
)
8004 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
8009 DoOutputDirect(HEADER
, headersize
);
8013 if(Flags
& (FLAG_ASMSECTION
|FLAG_SINGLEFILE
))
8014 DoOutput("\t.section %s,\"acrx4\"\n", hunkname
);
8016 if(Flags
& FLAG_SINGLEFILE
)
8017 DoOutput("\t.file\t\"%s.o\"\n", name
);
8019 DoOutput("\t.global %s\n", BaseName
);
8020 DoOutput("\t.global %s\n\t.align\t4\n%s:\n",name
, name
);
8022 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
8024 if(Flags
& FLAG_SMALLDATA
)
8025 DoOutput("\tlwz\t%s12,%s@sdarx(%s13)\n",
8026 PPCRegPrefix
, BaseName
, PPCRegPrefix
);
8028 DoOutput("\tlis\t%s11,%s@ha\n"
8029 "\tlwz\t%s12,%s@l(%s11)\n",
8030 PPCRegPrefix
, BaseName
, PPCRegPrefix
, BaseName
, PPCRegPrefix
);
8032 DoOutput("\tlwz\t%s0,-%d(%s12)\n\tmtctr\t%s0\n\tbctr\n",
8033 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8038 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8040 if(flags
& FUNCFLAG_TAG
)
8044 "\tlwz\t%s11,0(%s1)\n" /* backchain to next frame */
8045 "\tsub\t%s12,%s11,%s1\n" /* difference = size of frame to copy */
8046 "\tstw\t%s0,4(%s1)\n"
8047 "\tsub\t%s11,%s1,%s12\n"
8048 "\tsubi\t%s11,%s11,16\n" /* r11 Start of new frame, +16 size */
8049 "\tstw\t%s1,0(%s11)\n" /* Backchain to last frame */
8050 "\tsrwi\t%s12,%s12,2\n"
8051 "\tsubi\t%s0,%s12,2\n" /* size/4-2 = number of longwords to copy */
8052 "\taddi\t%s12,%s1,4\n"
8053 "\tmr\t%s1,%s11\n" /* new stack frame */
8054 "\taddi\t%s11,%s11,8\n"
8057 "\tlwzu\t%s0,4(%s12)\n" /* copy stack frame with offset 8 */
8058 "\tstwu\t%s0,4(%s11)\n"
8059 "\tbdnz\t.copyloop_%s\n"
8060 "\tstw\t%s10,8(%s1)\n", /* last register into stack */
8061 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8062 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8063 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8064 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8065 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8066 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8067 PPCRegPrefix
, PPCRegPrefix
, name
,
8068 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8069 name
, PPCRegPrefix
, PPCRegPrefix
);
8071 else if(ap
->NumArgs
>= 8)
8073 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8076 "\tstwu\t%s1,-%ld(%s1)\n"
8077 "\tstw\t%s0,%ld(%s1)\n",
8078 PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
,
8079 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8083 else if(flags
& FUNCFLAG_TAG
)
8085 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8086 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8088 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8089 || ap
->NumArgs
>= 8))
8091 DoOutput("\tstwu\t%s1,-%ld(%s1)\n"
8093 PPCRegPrefix
, stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
);
8098 /* Hack the stack-frame for varargs.
8099 Build stack-frame, but save LR in our own stack-frame,
8100 because we have to overwrite the lower 8 bytes of the
8102 /* Save the caller's saved SP in our own stack-frame. */
8103 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n", PPCRegPrefix
,
8104 stcksize
+nrcopyar
*4, PPCRegPrefix
, PPCRegPrefix
, stcksize
, PPCRegPrefix
);
8106 /* Store r3-r8 at the top of our stack-frame and r9-r10
8107 at the low 8 bytes of the caller's frame. This way all
8108 arguments will reside in one continuous area.
8109 Only copy the really relevant parts. */
8110 for(i
= 10; i
> 10-nrcopyar
; --i
)
8111 DoOutput("\tstw\t%s%ld,%ld(%s1)\n", PPCRegPrefix
, i
,
8112 stcksize
+4*(i
-1+nrcopyar
-8),PPCRegPrefix
);
8115 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8117 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8119 for(i
= ap
->NumArgs
-1; i
; --i
)
8123 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, 3+i
, PPCRegPrefix
,
8128 DoOutput("\tstw\t%s10,8(%s1)\n", PPCRegPrefix
, PPCRegPrefix
);
8132 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8133 PPCRegPrefix
, stcksize
+((i
-8)+3)*4, PPCRegPrefix
, PPCRegPrefix
,
8134 ((i
-8)+3)*4, PPCRegPrefix
);
8140 /* shift all the arguments one field */
8141 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8143 DoOutput("\tmr\t%s%ld,%s%ld\n",PPCRegPrefix
, i
, PPCRegPrefix
, i
-1);
8148 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8149 || ap
->NumArgs
>= 8))
8150 DoOutput("\tstw\t%s0,%ld(%s1)\n", PPCRegPrefix
, stcksize
+4, PPCRegPrefix
);
8154 if(Flags
& FLAG_SMALLDATA
)
8155 DoOutput("\tlwz\t%s%ld,%s@sdarx(%s13)\n", PPCRegPrefix
, basereg
,
8156 BaseName
, PPCRegPrefix
);
8158 DoOutput("\tlis\t%s%ld,%s@ha\n\tlwz\t%s%ld,%s@l(%s%ld)\n",
8159 PPCRegPrefix
, basereg
, BaseName
, PPCRegPrefix
, basereg
, BaseName
,
8160 PPCRegPrefix
, basereg
);
8163 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8165 DoOutput("\tlwz\t%s0,-%d(%s3)\n\tmtctr\t%s0\n\tbctrl\n",
8166 PPCRegPrefix
, ap
->Bias
-2, PPCRegPrefix
, PPCRegPrefix
);
8170 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8172 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8175 DoOutput("\tstw\t%s%ld,", PPCRegPrefix
, i
+3);
8177 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,", PPCRegPrefix
,
8178 stcksize
+(i
+2-8)*4, PPCRegPrefix
, PPCRegPrefix
);
8181 DoOutput("\taddi\t%s4,%s1,%ld\n\tstw\t%s4,", PPCRegPrefix
,
8182 PPCRegPrefix
, stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0),
8184 DoOutput("%d(%s2)\n", 4*ap
->Args
[i
].ArgReg
, PPCRegPrefix
);
8187 DoOutput("\tlwz\t%s11,100(%s2)\n", /* EmulCallDirectOS */
8188 PPCRegPrefix
, PPCRegPrefix
);
8190 /* store basepointer in A6 */
8192 DoOutput("\tstw\t%s12,56(%s2)\n", PPCRegPrefix
, PPCRegPrefix
);
8194 /* Now place the real function call */
8195 DoOutput("\tli\t%s3,-%d\n", /* store offset in EmulHandle */
8196 PPCRegPrefix
, ap
->Bias
);
8198 DoOutput("\tmtctr\t%s11\n\tbctrl\n", PPCRegPrefix
);
8201 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8203 DoOutput("\tlwz\t%s11,%ld(%s1)\n\tstw\t%s11,%ld(%s1)\n",
8204 PPCRegPrefix
, stcksize
, PPCRegPrefix
, PPCRegPrefix
,
8205 stcksize
+nrcopyar
*4,PPCRegPrefix
);
8208 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8209 || ap
->NumArgs
>= 8))
8211 if(ap
->NumArgs
>= 8)
8214 "\tlwz\t%s0,%ld(%s1)\n"
8215 "\taddi\t%s1,%s1,%ld\n"
8217 PPCRegPrefix
,stcksize
+4,PPCRegPrefix
,PPCRegPrefix
,PPCRegPrefix
,
8218 stcksize
,PPCRegPrefix
);
8223 "\tlwz\t%s1,0(%s1)\n" /* restore old stack frame */
8224 "\tlwz\t%s0,4(%s1)\n"
8225 "\tmtlr\t%s0\n", PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8226 PPCRegPrefix
, PPCRegPrefix
);
8231 DoOutput("\tlwz\t%s0,%ld(%s1)\n"
8232 "\taddi\t%s1,%s1,%ld\n"
8234 PPCRegPrefix
, stcksize
+4, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
8235 stcksize
+nrcopyar
*4, PPCRegPrefix
);
8238 DoOutput("\tblr\n");
8241 return DoOutput("\t.type\t%s,@function\n\t.size\t%s,$-%s\n\n",
8245 uint32
FuncVBCCMorphCode(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8247 int32 i
, j
, k
=0, size
, nrcopyar
= 0, stcksize
= 16, basereg
= 12;
8248 uint8
*data
, *data2
, *data3
;
8249 struct ArHeader
*arh
;
8253 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_PPC
))
8258 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
8259 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
8260 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
8261 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
8262 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
8263 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
8264 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
8265 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8266 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8267 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
8268 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
8269 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
8270 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
8271 EndPutM32Inc(data
, 0); /* eeh->e_entry */
8272 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
8273 data2
= data
; data
+= 4;
8274 EndPutM32Inc(data
, 0); /* eeh->e_flags */
8275 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
8276 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
8277 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
8278 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
8279 EndPutM16Inc(data
, 6); /* eeh->e_shnum */
8280 EndPutM16Inc(data
, 3); /* eeh->e_shstrndx - fourth table is string table */
8284 if(ap
->Flags
& (AMIPRAGFLAG_MOSSYSV
|AMIPRAGFLAG_MOSSYSVR12
))
8286 if(Flags
& FLAG_SMALLDATA
)
8288 k
= (data
-data3
)+2; /* store reloc offset */
8289 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8293 k
= (data
-data3
)+2; /* store reloc offset */
8294 EndPutM32Inc(data
, 0x3D600000); /* lis r11,BaseName@ha = addis r11,0,BaseName@ha */
8295 EndPutM32Inc(data
, 0x818B0000); /* lwz r12,BaseName@l(r11) */
8298 EndPutM32Inc(data
, 0x800c0000 - (ap
->Bias
-2));
8299 EndPutM32Inc(data
, 0x7c0903a6); /* mtctr r0 */
8300 EndPutM32Inc(data
, 0x4e800420); /* bctr */
8305 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8307 if(flags
& FUNCFLAG_TAG
)
8309 /* mflr r0 = mfspr r0,8 = get link register */
8310 EndPutM32Inc(data
, 0x7C0802A6);
8311 /* backchain to next frame: lwz r11,0(r1) */
8312 EndPutM32Inc(data
, 0x81610000);
8313 /* difference = size of frame to copy: sub r12,r11,r1 = subf r12,r1,r11 */
8314 EndPutM32Inc(data
, 0x7D815850);
8315 EndPutM32Inc(data
, 0x90010004); /* stw r0,4(r1) */
8316 EndPutM32Inc(data
, 0x7D6C0850); /* sub r11,r1,r12 */
8317 /* subi r11,r11,16 - r11 Start of new frame, +16 size */
8318 EndPutM32Inc(data
, 0x396BFFF0);
8319 EndPutM32Inc(data
, 0x902B0000); /* stw r1,0(r11) - Backchain to last frame */
8320 EndPutM32Inc(data
, 0x558CF0BE); /* srwi r12,r12,2 */
8321 /* subi r0,r12,2 - size/4-2 = number of longwords to copy */
8322 EndPutM32Inc(data
, 0x380CFFFE);
8323 EndPutM32Inc(data
, 0x39810004); /* addi r12,r1,4 */
8324 EndPutM32Inc(data
, 0x7D615B78); /* mr r1,r11 - new stack frame */
8325 EndPutM32Inc(data
, 0x396B0008); /* addi r11,r11,8 */
8326 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8327 /* .l: lwzu r0,4(r12) - copy stack frame with offset 8 */
8328 EndPutM32Inc(data
, 0x840C0004);
8329 EndPutM32Inc(data
, 0x940B0004); /* stwu r0,4(r11) */
8330 EndPutM32Inc(data
, 0x4200FFF8); /* bdnz .l */
8331 /* stw r10,8(r1) - last register into stack */
8332 EndPutM32Inc(data
, 0x91410008);
8334 else if(ap
->NumArgs
>= 8)
8336 stcksize
= ((8 + (ap
->NumArgs
-7)*4 + 15) & (~15));
8337 EndPutM32Inc(data
, 0x7C0802A6); /* mflr r0 */
8338 EndPutM32Inc(data
, 0x94220000 - stcksize
); /* stwu r1,-X(r1) */
8339 EndPutM32Inc(data
, 0x90010000 + stcksize
+ 4); /* stw r0,Y(r1) */
8343 else if(flags
& FUNCFLAG_TAG
)
8345 nrcopyar
= ap
->NumArgs
> 8 ? 0 : 8 + 1 - ap
->NumArgs
;
8346 stcksize
= (((nrcopyar
+ 2 + 3)&(~3))-nrcopyar
)*4;
8349 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8350 || ap
->NumArgs
>= 8))
8352 EndPutM32Inc(data
, 0x94210000+0x10000-(stcksize
+nrcopyar
*4)); /* stwu r1,-%d(r1) */
8353 /* mflr r0 = mfspr r0,8 = get link register */
8354 EndPutM32Inc(data
, 0x7C0802A6);
8359 /* Hack the stack-frame for varargs.
8360 Build stack-frame, but save LR in our own stack-frame,
8361 because we have to overwrite the lower 8 bytes of the
8363 /* Save the caller's saved SP in our own stack-frame. */
8364 EndPutM32Inc(data
, 0x81610000+stcksize
+nrcopyar
*4); /* lwz r11,%d(r1) */
8365 EndPutM32Inc(data
, 0x91610000+stcksize
); /* stw r11,%d(r1) */
8367 /* Store r3-r8 at the top of our stack-frame and r9-r10
8368 at the low 8 bytes of the caller's frame. This way all
8369 arguments will reside in one continuous area.
8370 Only copy the really relevant parts. */
8371 for(i
= 10; i
> 10-nrcopyar
; --i
)
8372 EndPutM32Inc(data
, 0x90010000 + (i
<<21) + (stcksize
+4*(i
-1+nrcopyar
-8))); /* stw rX,Y(r1) */
8375 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8377 if(flags
& FUNCFLAG_TAG
|| ap
->NumArgs
>= 8)
8379 for(i
= ap
->NumArgs
-1; i
; --i
)
8384 EndPutM32Inc(data
, 0x7C000378 + ((3+i
)<<21) + ((3+i
-1)<<16) + ((3+i
-1)<<11));
8389 EndPutM32Inc(data
, 0x91410008);
8394 EndPutM32Inc(data
, 0x81610000 + (stcksize
+((i
-8)+3)*4));
8395 EndPutM32Inc(data
, 0x91620000 + ((i
-8)+3)*4); /* stw r11,j(r1) */
8401 /* shift all the arguments one field */
8402 for(i
= ap
->NumArgs
+3; i
> 3; --i
)
8405 EndPutM32Inc(data
, 0x7C000378 + (i
<<21) + ((i
-1)<<16) + ((i
-1)<<11));
8410 if(!(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) || !((flags
& FUNCFLAG_TAG
)
8411 || ap
->NumArgs
>= 8))
8412 EndPutM32Inc(data
, 0x90010000+stcksize
+4); /* stw r0,%d(r1) */
8416 if(Flags
& FLAG_SMALLDATA
)
8418 k
= (data
-data3
)+2; /* store reloc offset */
8419 EndPutM32Inc(data
, 0x818D0000); /* lwz r12,BaseName@sdarx(r13) */
8423 k
= (data
-data3
)+2; /* store reloc offset */
8424 EndPutM32Inc(data
, 0x3D800000); /* lis r12,BaseName@ha = addis r12,0,BaseName@ha */
8425 EndPutM32Inc(data
, 0x818C0000); /* lwz r12,BaseName@l(r12) */
8429 if(ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
)
8432 EndPutM32Inc(data
, 0x80040000 - (ap
->Bias
-2));
8433 EndPutM32Inc(data
, 0x7C0903A6); /* mtctr r0 */
8434 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8438 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8440 j
= 4*ap
->Args
[i
].ArgReg
;
8441 if(!(flags
& FUNCFLAG_TAG
) || i
< ap
->NumArgs
-1)
8445 EndPutM32Inc(data
, 0x90020000 + ((i
+3)<<21) + j
); /* stw rX,j(r2) */
8449 EndPutM32Inc(data
, 0x81610000 + (stcksize
+(i
+2-8)*4)); /* lwz r11,X(r1) = get data from stack */
8450 EndPutM32Inc(data
, 0x91620000 + j
); /* stw r11,j(r1) */
8455 EndPutM32Inc(data
, 0x38810000 + (stcksize
+8+(ap
->NumArgs
> 8 ? (ap
->NumArgs
-8)*4 : 0))); /* addi r4,r1,X */
8456 EndPutM32Inc(data
, 0x90820000 + j
); /* stw r4,X(r2) */
8461 EndPutM32Inc(data
, 0x81620064); /* lwz r11,100(r2) */
8464 EndPutM32Inc(data
, 0x91820038); /* stw r12,56(r2) */
8466 /* Now place the real function call */
8467 EndPutM32Inc(data
, 0x38600000 + 0x10000 - ap
->Bias
); /* li r3,-(ap->Bias) = addi r3,0,-ap->Bias */
8469 EndPutM32Inc(data
, 0x7D6903A6); /* mtctr r11 */
8470 EndPutM32Inc(data
, 0x4E800421); /* bctrl */
8472 if(nrcopyar
) /* Varargs. Rebuild the caller's stack-frame. */
8474 EndPutM32Inc(data
, 0x81610000 + stcksize
); /* lwz r11,X(r1) */
8475 EndPutM32Inc(data
, 0x91610000 + (stcksize
+nrcopyar
*4)); /* stw r11,Y(r1) */
8478 if((ap
->Flags
& AMIPRAGFLAG_MOSBASESYSV
) && ((flags
& FUNCFLAG_TAG
)
8479 || ap
->NumArgs
>= 8))
8481 if(ap
->NumArgs
>= 8)
8483 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8484 EndPutM32Inc(data
, 0x38210000 + stcksize
); /* addi r1,r1,Y */
8485 /* mtlr r0 = mtspr 8,r0 = restore link register */
8486 EndPutM32Inc(data
, 0x7C0803A6);
8490 /* restore old stack frame: lwz r1,0(r1) */
8491 EndPutM32Inc(data
, 0x80210000);
8492 EndPutM32Inc(data
, 0x80010004); /* lwz r0,4(r1) */
8493 /* mtlr r0 = mtspr 8,r0 = restore link register */
8494 EndPutM32Inc(data
, 0x7C0803A6);
8499 EndPutM32Inc(data
, 0x80010000 + stcksize
+4); /* lwz r0,X(r1) */
8500 EndPutM32Inc(data
, 0x38210000 + (stcksize
+nrcopyar
*4)); /* addi r1,r1,Y */
8501 EndPutM32Inc(data
, 0x7C0803A6); /* mtlr r0 = mtspr 8,r0 = restore link register */
8504 EndPutM32Inc(data
, 0x4E800020); /* blr = bclr 20,0 */
8507 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0.text\0.rela.text\0", 44);
8508 data
+= 44; /* 1 9 17 27 33 */
8510 EndPutM32(data2
, data
-tempbuf
); /* eeh->e_shoff */
8513 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
8514 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
8515 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8516 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8517 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
8518 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
8519 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8520 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8521 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
8522 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8525 EndPutM32Inc(data
, 27); /* esh[1].sh_name = .text */
8526 EndPutM32Inc(data
, SHT_PROGBITS
); /* esh[1].sh_type */
8527 EndPutM32Inc(data
, SHF_ALLOC
|SHF_EXECINSTR
); /* esh[1].sh_flags */
8528 EndPutM32Inc(data
, 0); /* esh[1].sh_addr */
8529 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[1].sh_offset */
8530 EndPutM32Inc(data
, size
); /* esh[1].sh_size */
8531 EndPutM32Inc(data
, 0); /* esh[1].sh_link */
8532 EndPutM32Inc(data
, 0); /* esh[1].sh_info */
8533 EndPutM32Inc(data
, 16); /* esh[1].sh_addralign */
8534 EndPutM32Inc(data
, 0); /* esh[1].sh_entsize */
8537 EndPutM32Inc(data
, 33); /* esh[2].sh_name = .rela.text */
8538 EndPutM32Inc(data
, SHT_RELA
); /* esh[2].sh_type */
8539 EndPutM32Inc(data
, 0); /* esh[2].sh_flags */
8540 EndPutM32Inc(data
, 0); /* esh[2].sh_addr */
8541 data
+= 4; /* esh[2].sh_offset */
8542 data
+= 4; /* esh[2].sh_size */
8543 EndPutM32Inc(data
, 4); /* esh[2].sh_link - the fifth entry is symbol table */
8544 EndPutM32Inc(data
, 1); /* esh[2].sh_info - the second entry is programm data */
8545 EndPutM32Inc(data
, 4); /* esh[2].sh_addralign */
8546 EndPutM32Inc(data
, 12); /* esh[2].sh_entsize - sizeof(struct Elf32_Rela) */
8548 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
8549 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
8550 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
8551 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
8552 EndPutM32Inc(data
, data2
-tempbuf
); /* esh[3].sh_offset */
8553 EndPutM32Inc(data
, 44); /* esh[3].sh_size */
8554 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
8555 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
8556 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
8557 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
8559 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
8560 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
8561 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
8562 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
8563 data
+= 4; /* esh[4].sh_offset */
8564 data
+= 4; /* esh[4].sh_size */
8565 EndPutM32Inc(data
, 5); /* esh[4].sh_link - the sixth entry is our string table */
8566 EndPutM32Inc(data
, 3); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
8567 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
8568 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
8570 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
8571 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
8572 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
8573 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
8574 data
+= 4; /* esh[0].sh_offset */
8575 data
+= 4; /* esh[0].sh_size */
8576 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
8577 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
8578 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
8579 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
8581 EndPutM32(data3
+(2*40)+(4*4), data
-tempbuf
); /* esh[4].sh_offset */
8582 EndPutM32(data3
+(2*40)+(5*4), BaseName
? 5*16 : 4*16); /* esh[4].sh_size */
8585 data
+= BaseName
? 5*16 : 4*16;
8587 EndPutM32(data3
+(3*40)+(4*4), data
-tempbuf
); /* esh[5].sh_offset */
8590 EndPutM32Inc(data2
, i
); /* esym[0].st_name */
8591 EndPutM32Inc(data2
, 0); /* esym[0].st_value */
8592 EndPutM32Inc(data2
, 0); /* esym[0].st_size */
8593 *(data2
++) = 0; /* esym[0].st_info */
8594 *(data2
++) = 0; /* esym[0].st_other */
8595 EndPutM16Inc(data2
, 0); /* esym[0].st_shndx */
8599 EndPutM32Inc(data2
, i
); /* esym[1].st_name */
8600 EndPutM32Inc(data2
, 0); /* esym[1].st_value */
8601 EndPutM32Inc(data2
, 0); /* esym[1].st_size */
8602 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_FILE
); /* esym[1].st_info */
8603 *(data2
++) = 0; /* esym[1].st_other */
8604 EndPutM16Inc(data2
, SHN_ABS
); /* esym[1].st_shndx */
8606 sprintf((strptr
)data
+i
, "%s.o", name
); while(data
[i
++]) ; /* get next store space */
8607 EndPutM32Inc(data2
, 0); /* esym[2].st_name */
8608 EndPutM32Inc(data2
, 0); /* esym[2].st_value */
8609 EndPutM32Inc(data2
, 0); /* esym[2].st_size */
8610 *(data2
++) = ELF32_ST_INFO(STB_LOCAL
,STT_SECTION
); /* esym[2].st_info */
8611 *(data2
++) = 0; /* esym[2].st_other */
8612 EndPutM16Inc(data2
, 1); /* esym[2].st_shndx - the second entry is program section! */
8614 EndPutM32Inc(data2
, i
); /* esym[3].st_name */
8615 EndPutM32Inc(data2
, 0); /* esym[3].st_value */
8616 EndPutM32Inc(data2
, size
); /* esym[3].st_size */
8617 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_FUNC
); /* esym[3].st_info */
8618 *(data2
++) = 0; /* esym[3].st_other */
8619 EndPutM16Inc(data2
, 1); /* esym[3].st_shndx - the second entry is program section! */
8621 sprintf((strptr
)data
+i
, name
); while(data
[i
++]) ; /* get next store space */
8624 EndPutM32Inc(data2
, i
); /* esym[4].st_name */
8625 EndPutM32Inc(data2
, 0); /* esym[4].st_value */
8626 EndPutM32Inc(data2
, 0); /* esym[4].st_size */
8627 *(data2
++) = ELF32_ST_INFO(STB_GLOBAL
,STT_NOTYPE
); /* esym[4].st_info */
8628 *(data2
++) = 0; /* esym[4].st_other */
8629 EndPutM16
/*Inc*/(data2
, 0); /* esym[4].st_shndx */
8631 sprintf((strptr
)data
+i
, BaseName
); while(data
[i
++]) ; /* get next store space */
8633 EndPutM32(data3
+(3*40)+(5*4), i
); /* esh[5].sh_size */
8634 while(i
&3) /* long aligned */
8638 EndPutM32(data3
+(4*4), data
-tempbuf
); /* esh[2].sh_offset */
8644 if(Flags
& FLAG_SMALLDATA
)
8646 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8647 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_SDAREL16
)); /* erel[0].r_info - entry 4, type 32 */
8648 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8652 EndPutM32Inc(data
, k
); /* erel[0].r_offset */
8653 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_HA
)); /* erel[0].r_info - entry 4, type 6 */
8654 EndPutM32Inc(data
, 0); /* erel[0].r_addend */
8655 EndPutM32Inc(data
, k
+4); /* erel[1].r_offset */
8656 EndPutM32Inc(data
, ELF32_R_INFO(4,R_PPC_ADDR16_LO
)); /* erel[1].r_info - entry 4, type 4 */
8657 EndPutM32Inc(data
, 0); /* erel[1].r_addend */
8660 EndPutM32(data3
+(5*4), data
-data2
); /* esh[2].sh_size */
8662 /* make ar header and store all */
8663 arh
= (struct ArHeader
*) (data
+20);
8664 memset(arh
, ' ', sizeof(struct ArHeader
));
8666 arh
->ar_time
[sprintf(arh
->ar_time
, "%lu", (uint32
) time(0))] = ' ';
8667 arh
->ar_uid
[0] = arh
->ar_gid
[0] = arh
->ar_mode
[1] =
8668 arh
->ar_mode
[2] = '0';
8669 arh
->ar_mode
[0] = '6';
8670 arh
->ar_fmag
[0] = 96;
8671 arh
->ar_fmag
[1] = '\n';
8673 if((k
= strlen(name
) + 2) >= 16)
8675 arh
->ar_name
[sprintf(arh
->ar_name
, "#1/%ld", k
)] = ' ';
8680 arh
->ar_name
[sprintf(arh
->ar_name
, "%s.o", name
)] = ' ';
8683 j
= k
+ (data
-tempbuf
);
8684 for(i
= 9; j
; --i
) /* make decimal number */
8686 data
[i
] = (j
%10)+'0';
8689 for(j
= 0; i
< 9; ++j
)
8690 arh
->ar_size
[j
] = data
[++i
];
8692 DoOutputDirect(arh
, sizeof(struct ArHeader
));
8696 DoOutput("%s.o", name
);
8698 *(data
++) = 0x0A; /* alignment byte! */
8701 return DoOutputDirect(tempbuf
, data
-tempbuf
);
8704 uint32
FuncEModule(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8708 if(CheckError(ap
, AMIPRAGFLAG_FLOATARG
|AMIPRAGFLAG_A6USE
|AMIPRAGFLAG_PPC
) ||
8709 (flags
& FUNCFLAG_ALIAS
))
8712 if(LastBias
>= ap
->Bias
)
8713 DoError(ERR_ILLEGAL_FUNCTION_POSITION
, ap
->Line
, name
);
8716 Flags
|= FLAG_DONE
; /* We did something */
8718 for(LastBias
+= BIAS_OFFSET
; LastBias
< ap
->Bias
; LastBias
+= BIAS_OFFSET
)
8719 DoOutputDirect("Dum\x10", 4);
8721 DoOutput("%c", toupper(name
[0]));
8724 DoOutput("%c", tolower(name
[1]));
8726 DoOutput("%s", name
+2);
8729 DoOutputDirect("\x10", 1);
8732 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8734 r
= ap
->Args
[i
].ArgReg
;
8735 DoOutputDirect(&r
, 1);
8742 uint32
FuncFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8746 Flags
|= FLAG_DONE
; /* We did something */
8748 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8750 if(Flags
& FLAG_ISPRIVATE
)
8752 Flags
^= FLAG_ISPRIVATE
;
8753 DoOutput("##public\n");
8758 if(!(Flags
& FLAG_ISPRIVATE
))
8759 DoOutput("##private\n");
8760 Flags
|= FLAG_ISPRIVATE
;
8763 LastBias
+= BIAS_OFFSET
;
8764 if(LastBias
!= ap
->Bias
)
8766 DoOutput("##bias %d\n", ap
->Bias
);
8767 LastBias
= ap
->Bias
;
8770 if(ap
->Abi
!= CurrentABI
)
8774 case ABI_M68K
: DoOutput("##abi M68k\n"); break;
8775 case ABI_PPC0
: DoOutput("##abi PPC0\n"); break;
8776 case ABI_PPC2
: DoOutput("##abi PPC2\n"); break;
8777 case ABI_PPC
: DoOutput("##abi PPC\n"); break;
8779 CurrentABI
= ap
->Abi
;
8782 DoOutput("%s("/*)*/, name
);
8783 for(i
= 0; i
< ap
->CallArgs
; i
++)
8784 DoOutput("%s%s", ap
->Args
[i
].ArgName
, i
< ap
->CallArgs
-1 ? "," : "");
8785 DoOutput(/*(*/")("/*)*/);
8787 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8789 for(i
= 0; i
< ap
->CallArgs
; i
++)
8791 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], i
< ap
->CallArgs
-1 ?
8792 (ap
->Args
[i
].ArgReg
< ap
->Args
[i
+1].ArgReg
? "/" : ",") : "");
8795 return DoOutput(/*(*/")\n");
8798 /* called from FuncSFD directly */
8799 uint32
FuncClib(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8801 struct ClibData
*cd
;
8804 Flags
|= FLAG_DONE
; /* We did something */
8806 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8809 s
= MakeClibType(tempbuf
, &cd
->ReturnType
, 0);
8810 DoOutputDirect(tempbuf
, s
);
8811 DoOutput(" %s("/*)*/, name
);
8815 for(i
= 0; i
< cd
->NumArgs
; i
++)
8817 c
= MakeClibType(tempbuf
, &cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8820 DoOutput(i
? ",\n\t" : "\n\t"); s
= 8;
8824 DoOutput(", "); s
+= 2;
8826 DoOutputDirect(tempbuf
, c
);
8830 else if(Flags2
& FLAG2_CLIBOUT
)
8832 return DoOutput(/*(*/")%s", Flags2
& FLAG2_CLIBOUT
? ";\n" : "");
8835 uint32
FuncSFD(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8837 struct ClibData
*cd
;
8840 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8843 if(ap
->Flags
& AMIPRAGFLAG_PUBLIC
)
8845 if(Flags
& FLAG_ISPRIVATE
)
8847 Flags
^= FLAG_ISPRIVATE
;
8848 DoOutput("==public\n");
8853 if(!(Flags
& FLAG_ISPRIVATE
))
8854 DoOutput("==private\n");
8855 Flags
|= FLAG_ISPRIVATE
;
8858 if(ap
->Abi
!= CurrentABI
)
8862 case ABI_M68K
: DoOutput("==abi M68k\n"); break;
8863 case ABI_PPC0
: DoOutput("==abi PPC0\n"); break;
8864 case ABI_PPC2
: DoOutput("==abi PPC2\n"); break;
8865 case ABI_PPC
: DoOutput("==abi PPC\n"); break;
8867 CurrentABI
= ap
->Abi
;
8870 if(LastBias
+BIAS_OFFSET
< ap
->Bias
)
8872 DoOutput("==reserve %ld\n", ((ap
->Bias
-LastBias
)/BIAS_OFFSET
)-1);
8873 LastBias
= ap
->Bias
;
8875 else if(flags
& FUNCFLAG_TAG
)
8876 DoOutput("==varargs\n");
8877 else if((flags
& FUNCFLAG_ALIAS
) || LastBias
== ap
->Bias
)
8878 DoOutput("==alias\n");
8880 LastBias
+= BIAS_OFFSET
;
8882 if(!FuncClib(ap
, flags
, name
))
8885 DoOutput(" ("/*)*/);
8886 if(!(ap
->Flags
& AMIPRAGFLAG_PPC
))
8890 /* j runs in steps of two. If CPP_TYPE_DOUBLE is stored in data registers, it runs
8891 in step one, so the "-" can be placed at proper position. */
8892 for(j
= i
= 0; i
< ap
->NumArgs
; i
++)
8894 if(i
== ap
->NumArgs
-1)
8898 else if(IsCPPType(&cd
->Args
[j
>>1], CPP_TYPE_DOUBLE
) && ap
->Args
[i
].ArgReg
< REG_FP0
)
8900 s
= (j
&1) ? "," : "-"; ++j
;
8906 DoOutput("%s%s", RegNames
[ap
->Args
[i
].ArgReg
], s
);
8909 return DoOutput(/*(*/")\n");
8912 uint32
FuncOS4PPC(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
8914 struct ClibData
*cd
;
8915 int32 i
, noret
= 0, registers
;
8917 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
8920 Flags
|= FLAG_DONE
; /* We did something */
8922 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
8925 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
8926 noret
= 1; /* this is a void function */
8928 sprintf((strptr
)tempbuf
, "_%s_%s", GetIFXName(), name
);
8929 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
8931 DoOutput("( \n struct %sIFace *Self%s\n"/*)*/,GetIFXName(),
8932 ap
->NumArgs
? "," : "");
8933 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8936 if(i
== ap
->NumArgs
- 1 && (flags
& FUNCFLAG_TAG
))
8942 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
8943 if(i
< ap
->NumArgs
-1)
8947 if(flags
& FUNCFLAG_TAG
)
8949 struct ClibData
*cd2
;
8951 if(!(cd2
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
8954 DoOutput(/*(*/")\n{\n"/*}*/
8956 " va_startlinear(ap, colorMap);\n"
8959 DoOutput("return ");
8960 DoOutput("Self->%s(\n"/*)*/, ap
->FuncName
);
8961 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
8963 DoOutput(" %s,\n", ap
->Args
[i
].ArgName
);
8965 DoOutput(" va_getlinearva(ap, "/*)*/);
8966 OutClibType(&cd2
->Args
[i
], 0);
8967 DoOutput(/*((*/"));\n");
8971 DoOutput(/*(*/")\n{\n"/*}*/
8972 " struct Library *LibBase = Self->Data.LibBase;\n"
8973 " struct ExecIFace *IExec = (struct ExecIFace *)"
8974 "Self->Data.IExecPrivate;\n");
8979 OutClibType(&cd
->ReturnType
, "retval");
8984 " ULONG *regs = (ULONG *)(((struct ExecBase *)(IExec->Data.LibBase))"
8986 for(i
= 0; i
< ap
->NumArgs
; ++i
)
8989 registers
= GetRegisterData(ap
) | 0x40000002; /* set A6 everytime */
8990 for(i
= 0; i
<= 15; ++i
)
8992 if(registers
& (1<< (16+i
)))
8993 DoOutput(" ULONG save_%s = regs[%ld];\n", RegNames
[i
], i
);
8999 DoOutput("retval = ("/*)*/);
9000 OutClibType(&cd
->ReturnType
, 0);
9004 DoOutput("IExec->EmulateTags((APTR)LibBase,\n"
9005 " ET_Offset, -%d,\n"/*)*/,ap
->Bias
);
9006 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9008 DoOutput(" ET_Register%s, %s,\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
],
9009 ap
->Args
[i
].ArgName
);
9011 DoOutput(/*(*/" ET_RegisterA6, LibBase,\n TAG_DONE);\n\n");
9012 for(i
= 0; i
<= 15; ++i
)
9014 if(registers
& (1<< (16+i
)))
9015 DoOutput(" regs[%ld] = save_%s;\n", i
, RegNames
[i
]);
9019 DoOutput(" return retval;\n");
9021 return DoOutput(/*{*/"}\n\n");
9024 uint32
FuncOS4M68KCSTUB(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9026 struct ClibData
*cd
;
9029 if(ap
->NumArgs
<= 7)
9032 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9035 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9038 Flags
|= FLAG_DONE
; /* We did something */
9040 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9041 noret
= 1; /* this is a void function */
9043 sprintf((strptr
)tempbuf
, "Cstub_%s", name
);
9044 OutClibType(&cd
->ReturnType
, (strptr
)tempbuf
);
9046 DoOutput("(struct %sIFace *Interface)\n{\n"/*}*/
9047 " struct ExecIFace *IExec = (struct ExecIFace *)"
9048 "Interface->Data.IExecPrivate;\n"
9049 " struct ExecBase *SysBase = (struct ExecBase *)IExec->Data.LibBase;\n"
9050 " ULONG *regarray = (ULONG *)SysBase->EmuWS;\n ",GetIFXName());
9053 DoOutput("return ");
9055 DoOutput("Interface->%s(\n"/*)*/,(flags
& FUNCFLAG_TAG
) ? ap
->FuncName
9057 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9059 DoOutput(" ("/*)*/);
9060 OutClibType(&cd
->Args
[i
], 0);
9061 DoOutput(/*(*/") regarray[%d]", ap
->Args
[i
].ArgReg
);
9062 if(i
< ap
->NumArgs
-1)
9065 return DoOutput(/*{(*/");\n}\n\n");
9068 uint32
FuncOS4M68K(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9070 struct ClibData
*cd
;
9073 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9076 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9079 Flags
|= FLAG_DONE
; /* We did something */
9082 "\t.section .data\n"
9083 "\t.globl\tstub_%s\n"
9084 "\t.type\tstub_%s,@function\n"
9087 "\t.short\t0x4ef8\n"
9090 "\t.globl\tstub_%sPPC\n"
9091 "\t.long\tstub_%sPPC\n",name
, name
, name
, name
, name
);
9095 Flags2
|= FLAG2_OS4M68KCSTUB
;
9097 "\t.byte\t2\n" /* Rest of parameters in C */
9098 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9099 "\t.byte\t3,REG68K_A6\n"); /* r6<-A6 */
9104 "\t.byte\t%d\n" /* Rest of parameters in C */
9105 "\t.byte\t1,REG68K_A7\n" /* r1<-A7 */
9106 "\t.byte\t3,REG68K_A6\n", /* r6<-A6 */
9108 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9110 DoOutput("\t.byte\t%d,REG68K_%s\n",i
+4,
9111 RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9115 "\t.section .text\n"
9119 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
9120 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
9121 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
9122 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
9123 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
9124 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
9125 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
9126 "\tlwz\t%s3,ExtLib_MainIFace(%s3)\n", /* Get the real interface pointer */
9127 name
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9128 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9129 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
9130 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
9134 /* Since this function has 11 arguments, we need a C stub */
9136 "\t.globl\tCstub_%s\n"
9137 "\tlis\t%s4,Cstub_%s@h\n"
9138 "\tori\t%s4,%s4,Cstub_%s@l\n"
9141 name
, PPCRegPrefix
, name
, PPCRegPrefix
, PPCRegPrefix
, name
, PPCRegPrefix
);
9145 DoOutput("\tCallLib\tI%s_%s\n", GetIFXName(), name
);
9148 "\tlwz\t%s11,12(%s1)\n"
9150 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
9151 "\tblrl\n" /* Return to emulation */
9153 "\t.globl\tstub_%s68K\n"
9154 "\t.long\tstub_%s68K\n"
9155 "\t.byte\t0\n", /* Flags */
9156 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, name
,
9159 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9162 "\t.byte\t1\n" /* One register (a7 only) */
9163 "\t.byte\t1,REG68K_A7\n"); /* Map r1 to A7 */
9169 "\t.byte\t1,REG68K_A7\n"
9170 "\t.byte\t3,REG68K_D0\n");
9174 "\t.section .data\n"
9178 "\t.short\t0x4e75\n" /* RTS */
9182 uint32
FuncOS4M68KVect(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9184 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9187 while(LastBias
+ BIAS_OFFSET
< ap
->Bias
)
9189 DoOutput("\t.long\tstub_Reserved\n");
9190 LastBias
+= BIAS_OFFSET
;
9192 LastBias
= ap
->Bias
;
9194 return DoOutput("\t.long\tstub_%s\n", name
);
9197 uint32
FuncXML(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9199 struct ClibData
*cd
;
9202 if(CheckError(ap
, AMIPRAGFLAG_PPC
|AMIPRAGFLAG_MOS_ALL
))
9205 if(flags
& FUNCFLAG_ALIAS
)
9206 DoError(ERR_ALIASES_NOT_SUPPORTED
, ap
->Line
);
9208 Flags
|= FLAG_DONE
; /* We did something */
9210 if(!(cd
= GetClibFunc(name
, ap
, flags
)))
9213 while(LastBias
+BIAS_OFFSET
< ap
->Bias
)
9215 LastBias
+= BIAS_OFFSET
;
9216 DoOutput("\t\t<method name=\"Reserved%ld\" result=\"void\""
9217 " status=\"unimplemented\"/>\n", LastBias
);
9219 LastBias
= ap
->Bias
;
9221 DoOutput("\t\t<method name=\"%s\" result=\"", name
);
9222 OutClibType(&cd
->ReturnType
, 0);
9224 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9226 DoOutput("\t\t\t<%sarg name=\"%s\" type=\"",
9227 i
== ap
->NumArgs
-1 && (flags
& FUNCFLAG_TAG
) ? "var" : "",
9228 ap
->Args
[i
].ArgName
);
9229 OutClibType(&cd
->Args
[i
], 0);
9232 return DoOutput("\t\t</method>\n");
9235 uint32
FuncGateStubs(struct AmiPragma
*ap
, uint32 flags
, strptr name
)
9237 struct ClibData
*cd
;
9238 strptr ret
= "return ";
9241 if(CheckError(ap
, AMIPRAGFLAG_ARGCOUNT
|AMIPRAGFLAG_PPC
))
9244 if(!(cd
= GetClibFunc(ap
->FuncName
, ap
, flags
)))
9247 Flags
|= FLAG_DONE
; /* We did something */
9249 if(flags
& FUNCFLAG_ALIAS
)
9251 if(flags
& FUNCFLAG_TAG
)
9252 return DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s %s\n#endif\n\n",
9253 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
, ap
->TagName
);
9255 DoOutput("#define %s("/*)*/, name
);
9256 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9257 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9258 DoOutput(/*(*/"%s) %s("/*)*/, ap
->Args
[i
].ArgName
, ap
->FuncName
);
9259 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9260 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9261 return DoOutput(/*(*/"(%s))\n\n", ap
->Args
[i
].ArgName
);
9264 if((flags
& FUNCFLAG_TAG
))
9266 DoOutput("#ifndef NO_%sINLINE_STDARG\n#define %s("/*)*/,
9267 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", name
);
9268 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9270 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9272 DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/,
9274 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9275 DoOutput("(%s), ", ap
->Args
[i
].ArgName
);
9277 OutClibType(&cd
->Args
[i
], 0);
9278 return DoOutput(/*({((*/") _tags);})\n#endif\n\n");
9281 if(IsCPPType(&cd
->ReturnType
, CPP_TYPE_VOID
))
9284 if(!OutClibType(&cd
->ReturnType
, 0))
9287 DoOutput(" %s%s(void)\n{\n"/*}*/, prefix
, name
);
9289 for(i
= 0; i
< ap
->NumArgs
; ++i
)
9292 OutClibType(&cd
->Args
[i
], ap
->Args
[i
].ArgName
);
9293 DoOutput(" = ("/*)*/);
9294 OutClibType(&cd
->Args
[i
], 0);
9295 DoOutput(/*(*/") REG_%s;\n", RegNamesUpper
[ap
->Args
[i
].ArgReg
]);
9296 if((Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
)) && (Flags2
& FLAG2_REGLIB
))
9297 DoOutput(" %s ___RegBase = (%s) REG_A6;\n", GetBaseType(), GetBaseType());
9299 DoOutput(" %s%s%s("/*)*/, ret
, subprefix
, name
);
9302 if(Flags2
& FLAG2_PRELIB
)
9304 if(Flags2
& FLAG2_REGLIB
)
9305 DoOutput("___RegBase,");
9307 DoOutput("%s_BASE_NAME,", ShortBaseNameUpper
);
9310 for(i
= 0; i
< ap
->NumArgs
-1; ++i
)
9312 DoOutput("%s, ", ap
->Args
[i
].ArgName
);
9314 if(Flags2
& FLAG2_POSTLIB
)
9316 if(Flags2
& FLAG2_REGLIB
)
9317 DoOutput("%s, ___RegBase", ap
->Args
[i
].ArgName
);
9319 DoOutput("%s, %s_BASE_NAME", ap
->Args
[i
].ArgName
, ShortBaseNameUpper
);
9322 DoOutput("%s", ap
->Args
[i
].ArgName
);
9326 if(Flags2
& (FLAG2_PRELIB
|FLAG2_POSTLIB
))
9328 if(Flags2
& FLAG2_REGLIB
)
9329 DoOutput("___RegBase");
9331 DoOutput("%s_BASE_NAME", ShortBaseNameUpper
);
9334 return DoOutput(/*(({*/"));\n}\n");
9337 static uint32
DoCallFunc(struct AmiPragma
*ap
, uint32 flags
, strptr name
, FuncType Func
)
9341 if(Flags
& FLAG_SINGLEFILE
)
9343 sprintf(filename
, filenamefmt
, name
);
9344 if(!OpenDest(filename
))
9347 res
= Func(ap
, flags
, name
);
9348 if(Flags
& FLAG_SINGLEFILE
)
9350 CloseDest(filename
);
9355 static uint32
PrintComment(struct Comment
*com
, strptr comment
)
9357 if(com
->Private
&& !(Flags
& FLAG_PRIVATE
))
9359 else if((Flags2
& FLAG2_SFDOUT
) && com
->Version
)
9361 return DoOutput("==version %d\n", com
->Version
);
9363 else if((Flags2
& FLAG2_SFDOUT
) && com
->ReservedNum
)
9365 LastBias
+= BIAS_OFFSET
*com
->ReservedNum
;
9366 return DoOutput("==reserve %d\n", com
->ReservedNum
);
9368 else if(!(Flags
& FLAG_DOCOMMENT
) || !comment
)
9373 if(!DoOutput(comment
, com
->Data
))
9376 else if(com
->ReservedNum
)
9379 sprintf(temp
, "* --- (%u function slot%s reserved here) ---", com
->ReservedNum
,
9380 com
->ReservedNum
== 1 ? "" : "s");
9381 if(!DoOutput(comment
, temp
))
9384 else if(com
->Version
)
9387 if(com
->Version
>= FIRST_KNOWN_RELEASE
&& com
->Version
<= LAST_KNOWN_RELEASE
&&
9388 (Flags2
& FLAG2_SYSTEMRELEASE
))
9389 sprintf(temp
, "* --- functions in V%u or higher %s ---", com
->Version
,
9390 Release
[com
->Version
-FIRST_KNOWN_RELEASE
]);
9392 sprintf(temp
, "* --- functions in V%u or higher ---", com
->Version
);
9394 if(!DoOutput(comment
, temp
))
9400 static uint32
CallFunc(uint32 tagmode
, strptr comment
, FuncType Func
)
9402 struct Comment
*com
;
9404 struct AmiPragma
*ap
;
9406 com
= (struct Comment
*) Comment
.First
;
9408 for(ap
= (struct AmiPragma
*) AmiPragma
.First
; ap
;
9409 ap
= (struct AmiPragma
*) ap
->List
.Next
)
9411 if(BaseName
&& (ap
->Flags
& AMIPRAGFLAG_A6USE
))
9413 DoError(ERR_A6_NOT_ALLOWED
, ap
->Line
);
9415 else if((ap
->Flags
& AMIPRAGFLAG_PUBLIC
) || (Flags
& FLAG_PRIVATE
))
9417 while(com
&& com
->Bias
<= ap
->Bias
)
9419 if(!PrintComment(com
, comment
))
9421 com
= (struct Comment
*) com
->List
.Next
;
9422 } /* comment loop */
9425 printf("Processing %s - %s\n", ap
->FuncName
? ap
->FuncName
: "",
9426 ap
->TagName
? ap
->TagName
: "");
9429 if(tagmode
!= TAGMODE_TAGS
)
9431 if(ap
->FuncName
&& !DoCallFunc(ap
, FUNCFLAG_NORMAL
, ap
->FuncName
, Func
))
9434 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9436 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_NORMAL
)
9438 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9446 if(ap
->TagName
&& !DoCallFunc(ap
, FUNCFLAG_TAG
, ap
->TagName
, Func
))
9449 for(i
= 0; i
< ap
->NumAlias
; ++i
)
9451 if(ap
->AliasName
[i
]->Type
& FUNCFLAG_TAG
)
9453 if(!DoCallFunc(ap
, FUNCFLAG_ALIAS
|ap
->AliasName
[i
]->Type
, ap
->AliasName
[i
]->AliasName
, Func
))
9462 if(!PrintComment(com
, comment
))
9464 com
= (struct Comment
*) com
->List
.Next
;
9465 } /* comment loop */
9469 static uint32
PrintIncludes(void) /* copies the include lines */
9471 struct Include
*inc
;
9474 inc
= (struct Include
*) Includes
.First
;
9478 s2
= (strptr
) tempbuf
;
9479 for(s
= inc
->Include
; *s
; ++s
)
9483 case '<': *(s2
++) = ' '; break;
9485 case '.': *(s2
++) = '_'; break;
9487 default: *(s2
++) = toupper(*s
);
9491 DoOutput("#ifndef %s\n#include %s\n#endif\n", tempbuf
, inc
->Include
);
9492 inc
= (struct Include
*) inc
->List
.Next
;
9495 DoOutput("#include <exec/types.h>\n");
9496 return DoOutput("\n");
9499 /* ------------------------------------------------------------------ */
9501 static int32
AddClibEntry(strptr buffer
, strptr bufend
, uint32 linenum
)
9503 strptr buf
= buffer
;
9504 struct ClibData d
, *f
;
9506 memset(&d
, 0, sizeof(struct ClibData
));
9507 buf
= SkipBlanksRet(buf
);
9508 if(*buf
== '#') /* preprocessor lines */
9511 printf("Found non-function bracket in preprocessor line %ld\n", linenum
);
9513 while(buf
< bufend
&& *buf
!= '\n')
9517 if(!strnicmp(buf
, "ASM", 3))
9518 buf
= SkipBlanks(buf
+3);
9519 /* else if(!strnicmp(buf, "STACK", 5))
9520 buf = SkipBlanks(buf+5);
9522 else if(!strnicmp(buf
, "REGS", 4))
9523 buf
= SkipBlanks(buf
+4);
9525 if(!strnicmp(buf
, "extern", 6))
9527 buf
= SkipBlanksRet(buf
+6);
9528 if(!strnicmp(buf
, "\"C\"", 3)) /* CPP: extern "C" */
9530 buf
= SkipBlanksRet(buf
+3);
9533 buf
= SkipBlanksRet(buf
+1);
9538 if(!GetCPPType(&d
.ReturnType
, buf
, 1, 1))
9540 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE
, linenum
);
9543 else if(d
.ReturnType
.Unknown
)
9544 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_RETURNVALUE_TYPE_INT
, linenum
,
9545 d
.ReturnType
.Unknown
);
9547 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9549 strptr r
= d
.ReturnType
.TypeStart
;
9550 while(*r
!= '('/*)*/) ++r
;
9551 r
= SkipBlanks(++r
); /* the bracket */
9552 d
.FuncName
= SkipBlanks(++r
); /* the asterisk */
9555 d
.FuncName
= SkipBlanks(d
.ReturnType
.TypeStart
+d
.ReturnType
.FullLength
);
9557 while(*(buf
++) != '('/*)*/)
9559 *(SkipName(d
.FuncName
)) = 0;
9563 printf("Found non-function bracket in line %ld\n", linenum
);
9565 while(buf
< bufend
&& *buf
!= '\n')
9569 buf
= SkipBlanksRet(buf
);
9571 while(*buf
!= /*(*/')' && buf
< bufend
)
9573 if(d
.NumArgs
== MAXREGPPC
+1)
9575 DoError(ERROFFSET_CLIB
| ERR_TO_MUCH_ARGUMENTS
, linenum
);
9578 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 0, 1))
9580 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE
, linenum
, d
.NumArgs
);
9583 else if(d
.Args
[d
.NumArgs
-1].Unknown
)
9584 DoError(ERROFFSET_CLIB
| ERR_UNKNOWN_VARIABLE_TYPE_INT
, linenum
,
9585 d
.NumArgs
, d
.Args
[d
.NumArgs
-1].Unknown
);
9587 buf
= d
.Args
[d
.NumArgs
-1].TypeStart
+ d
.Args
[d
.NumArgs
-1].FullLength
;
9588 while(*buf
!= ',' && *buf
!= /*(*/')' && buf
< bufend
)
9591 printf("Added argument %d for %s (%d bytes)\n", d
.NumArgs
, d
.FuncName
,
9592 d
.Args
[d
.NumArgs
-1].FullLength
);
9595 buf
= SkipBlanksRet(++buf
);
9598 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9599 d
.NumArgs
= 0; /* void arguments are no arguments */
9601 if(!(f
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9604 memcpy(f
, &d
, sizeof(struct ClibData
));
9610 struct ClibData
*e
= clibdata
;
9615 if(d
.ReturnType
.Flags
& CPP_FLAG_FUNCTION
)
9617 int numclose
= 2, numopen
= 1;
9618 while(buf
< bufend
&& (numclose
|| numopen
> 0))
9620 if(*buf
== '('/*)*/) { ++numclose
; --numopen
; }
9621 else if(*buf
== /*(*/')') --numclose
;
9627 printf("Added prototype for %s (line %ld, %d bytes) with %d args\n",
9628 f
->FuncName
, linenum
, buf
-buffer
, f
->NumArgs
);
9633 static int32
ScanClibFile(strptr buf
, strptr bufend
)
9635 strptr linestart
= buf
;
9639 /* remove comments and other not so nice characters */
9642 if(*buf
== '\t' || *buf
== '\r' || *buf
== (string
)0xA0)
9644 else if(buf
[0] == '/' && buf
< bufend
-1)
9648 while(buf
< bufend
-1 && (buf
[0] != '*' || buf
[1] != '/'))
9657 else if(buf
[1] == '/')
9659 while(buf
< bufend
&& buf
[0] != '\n')
9666 else if(buf
[0] == '#' && strncmp("#include", buf
, 8))
9668 while(buf
< bufend
&& buf
[0] != '\n')
9677 printf("-----------\n%s-----------\n", linestart
);
9692 else if(!strncmp("#include", buf
, 8))
9696 if(!(d
= (struct Include
*) NewItem(&Includes
)))
9698 d
->Include
= buf
= SkipBlanks(buf
+8);
9699 AddItem(&Includes
, (struct ShortList
*) d
);
9700 while(*buf
&& *buf
!= '>' && *buf
!= '\n')
9708 printf("Added Include line %s\n", d
->Include
);
9712 else if(*buf
== '('/*)*/)
9716 if((i
= AddClibEntry(linestart
, bufend
, linenum
)) == -1) /* no memory */
9720 while(buf
< bufend
&& *buf
!= '\n')
9721 ++buf
; /* skip this line */
9726 while(buf
< bufend
&& i
-- > 0)
9728 if(*(buf
++) == '\n')
9732 } /* skip this function */
9743 static int32
IsCPPType(struct CPP_NameType
*data
, uint8 type
)
9745 if(!data
|| data
->Flags
|| data
->Type
!= type
|| data
->PointerDepth
)
9750 static uint32
CheckRegisterNum(strptr string
, struct CPP_NameType
*data
)
9754 for(i
= 0; i
< MAXREG
; ++i
)
9756 j
= strlen(RegNames
[i
]);
9757 if(!strnicmp(string
, RegNames
[i
], j
))
9760 if(*string
== ' ' || *string
== '\t' || *string
== '\n' || *string
== /*(*/')')
9763 data
->Flags
|= CPP_FLAG_REGISTER
;
9771 static uint32
ParseFuncPtrArgs(strptr buffer
, struct CPP_NameType
*data
)
9773 strptr buf
= buffer
;
9776 memset(&d
, 0, sizeof(struct ClibData
));
9777 while(*buf
!= /*(*/')')
9779 if(d
.NumArgs
== MAXREGPPC
+1)
9781 else if(!GetCPPType(&d
.Args
[d
.NumArgs
++], buf
, 1, 1))
9784 buf
+= d
.Args
[d
.NumArgs
-1].FullLength
;
9785 while(*buf
!= ',' && *buf
!= /*(*/')')
9788 buf
= SkipBlanksRet(++buf
);
9791 if(d
.NumArgs
== 1 && IsCPPType(&d
.Args
[0], CPP_TYPE_VOID
))
9792 d
.NumArgs
= 0; /* void arguments are no arguments */
9794 if(d
.NumArgs
) /* no need to allocate structure for nothing */
9796 if(!(data
->FuncPtr
= (struct ClibData
*) AllocListMem(sizeof(struct ClibData
))))
9799 memcpy(data
->FuncPtr
, &d
, sizeof(struct ClibData
));
9801 return (uint32
) (buf
+1-buffer
);
9804 /* rettype turns on usage of "extern" specifier */
9805 static int32
GetCPPType(struct CPP_NameType
*data
, strptr start
, uint32 rettype
, uint32 small
)
9812 data
->TypeStart
= start
= SkipBlanks(start
);
9814 if(!strncmp(start
, "REG", 3) && (start
[3] == ' ' || start
[3] == '\t' || start
[3] == '\n' || start
[3] == '('/*)*/))
9816 u
= SkipBlanksRet(start
+3);
9819 u
= SkipBlanks(u
+1);
9820 if((j
= CheckRegisterNum(u
, data
)))
9822 u
= SkipBlanks(u
+j
);
9824 start
= SkipBlanks(u
+1);
9828 data
->TypeStart
= start
;
9832 start
= SkipBlanks((u
= start
));
9833 if(!strncmp("...",start
,3))
9835 data
->Type
= CPP_TYPE_VARARGS
;
9836 data
->TypeLength
= start
+3 - (data
->TypeStart
);
9837 data
->FullLength
= data
->TypeLength
;
9840 if(CheckKeyword(start
, "const", 5) || CheckKeyword(start
, "CONST", 5))
9842 data
->Flags
|= CPP_FLAG_CONST
; start
+= 5;
9844 else if(rettype
&& CheckKeyword(start
, "extern", 6))
9846 start
+= 6; /* ignore it */
9848 else if(CheckKeyword(start
, "long", 4))
9850 if(data
->Flags
& CPP_FLAG_LONG
)
9851 data
->Type
= CPP_TYPE_LONGLONG
;
9853 data
->Flags
|= CPP_FLAG_LONG
;
9857 else if(CheckKeyword(start
, "signed", 6))
9859 else if(CheckKeyword(start
, "unsigned", 8))
9861 data
->Flags
|= CPP_FLAG_UNSIGNED
; start
+= 8;
9863 else if(CheckKeyword(start
, "register", 8))
9865 data
->Flags
|= CPP_FLAG_REGISTER
; start
+= 8;
9866 data
->Register
= UNDEFREGISTER
;
9868 else if(CheckKeyword(start
, "struct", 6))
9870 start
= SkipBlanks(start
+6);
9871 data
->Flags
|= CPP_FLAG_STRUCT
;
9872 if(*start
== '?') /* ? for external types */
9874 data
->StructureLength
= 0;
9875 data
->StructureName
= "";
9878 else if(*start
== '!') /* ! for typedef types */
9880 data
->Flags
|= CPP_FLAG_TYPEDEFNAME
;
9882 /* structure name and length already set */
9886 start
= SkipName((data
->StructureName
= start
));
9887 data
->StructureLength
= start
-data
->StructureName
;
9890 else if(CheckKeyword(start
, "union", 5))
9892 start
= SkipBlanks(start
+5);
9893 data
->Flags
|= CPP_FLAG_UNION
;
9894 if(*start
!= '?') /* ? for external types */
9896 start
= SkipName((data
->StructureName
= start
));
9897 data
->StructureLength
= start
-data
->StructureName
;
9901 data
->StructureLength
= 0;
9902 data
->StructureName
= "";
9906 else if(CheckKeyword(start
, "enum", 4))
9908 start
= SkipBlanks(start
+4);
9909 data
->Flags
|= CPP_FLAG_ENUM
;
9910 if(*start
!= '?') /* ? for external types */
9912 start
= SkipName((data
->StructureName
= start
));
9913 data
->StructureLength
= start
-data
->StructureName
;
9917 data
->StructureLength
= 0;
9918 data
->StructureName
= "";
9922 else if(*start
== '*')
9924 ++start
; ++data
->PointerDepth
;
9926 else if(*start
== '[')
9928 data
->Flags
|= CPP_FLAG_ARRAY
;
9929 while(*start
&& *start
!= ']')
9934 else if(start
[0] == '_' && start
[1] == '_' && (j
= CheckRegisterNum(start
+2, data
)))
9936 else if(!data
->Type
)
9940 for(i
= 0; CPP_Field
[i
].Text
; ++i
)
9942 if(!strncmp(start
, CPP_Field
[i
].Text
, CPP_Field
[i
].Length
) &&
9943 (start
[CPP_Field
[i
].Length
] == ' ' ||
9944 start
[CPP_Field
[i
].Length
] == '\t' ||
9945 start
[CPP_Field
[i
].Length
] == '\n' ||
9946 start
[CPP_Field
[i
].Length
] == ',' ||
9947 start
[CPP_Field
[i
].Length
] == /*(*/')' ||
9948 start
[CPP_Field
[i
].Length
] == '('/*)*/ ||
9949 start
[CPP_Field
[i
].Length
] == '*'))
9951 start
+= CPP_Field
[i
].Length
;
9952 data
->Type
= CPP_Field
[i
].Type
;
9953 data
->Flags
|= CPP_Field
[i
].Flags
;
9954 if(CPP_Field
[i
].Flags
& CPP_FLAG_POINTER
)
9955 ++data
->PointerDepth
;
9959 if(CPP_Field
[i
].Text
)
9963 struct CPP_ExternNames
*a
= extnames
;
9967 i
= strlen(a
->Type
);
9968 if(!strncmp(a
->Type
, start
, i
) && !isalnum(start
[i
]) &&
9972 data
->StructureName
= a
->NameType
.StructureName
;
9973 data
->FuncPtr
= a
->NameType
.FuncPtr
;
9974 data
->StructureLength
= a
->NameType
.StructureLength
;
9975 data
->PointerDepth
+= a
->NameType
.PointerDepth
;
9976 data
->Type
= a
->NameType
.Type
;
9977 data
->Flags
|= a
->NameType
.Flags
;
9978 data
->FuncArgs
= a
->NameType
.FuncArgs
;
9979 data
->ArgsLength
= a
->NameType
.ArgsLength
;
9983 /* check types here */
9988 else if((!data
->Type
) && (!data
->Flags
))
9991 struct CPP_Unknown
*u
;
9993 data
->Type
= CPP_TYPE_INT
;
9994 size
= SkipName(start
)-start
;
9995 for(u
= unknown
; u
&& strncmp(u
->Unknown
, start
, size
); u
= u
->Next
)
9999 data
->Unknown
= DupString(start
, size
);
10000 if((u
= (struct CPP_Unknown
*) AllocListMem(sizeof(struct CPP_Unknown
))))
10003 u
->Unknown
= data
->Unknown
;
10017 if(start
!= SkipBlanks(u
)) /* we broke the loop after increasing start */
10020 data
->TypeLength
= u
- (data
->TypeStart
);
10021 data
->FullLength
= data
->TypeLength
;
10028 u
= SkipBlanksRet(++u
);
10033 ++data
->FuncPointerDepth
; ++u
;
10035 u
= SkipBlanksRet(u
);
10036 if(CheckKeyword(u
, "const", 5) || CheckKeyword(u
, "CONST", 5))
10038 data
->Flags
|= CPP_FLAG_CONST
; u
+= 6;
10040 u
= SkipBlanksRet(u
);
10042 data
->FunctionName
= u
;
10043 u
= SkipBlanksRet(SkipName(u
));
10048 while(*u
&& numclose
)
10050 if(*u
== '('/*)*/) ++numclose
;
10051 else if(*u
== /*(*/')') --numclose
;
10057 u
= SkipBlanksRet(++u
);
10060 data
->Flags
|= CPP_FLAG_FUNCTION
;
10062 if((j
= ParseFuncPtrArgs(u
+1, data
)))
10064 data
->FuncArgs
= u
;
10065 data
->ArgsLength
= j
+1;
10066 data
->FullLength
= u
+data
->ArgsLength
- (data
->TypeStart
);
10072 if(data
->PointerDepth
)
10073 data
->Flags
|= CPP_FLAG_POINTER
;
10075 if(!(Flags2
& FLAG2_SMALLTYPES
) && !small
)
10077 if(!(data
->Flags
& (CPP_FLAG_STRPTR
|CPP_FLAG_POINTER
|CPP_FLAG_ENUM
10078 |CPP_FLAG_STRUCT
|CPP_FLAG_UNION
|CPP_FLAG_FUNCTION
|CPP_FLAG_REGISTER
)))
10080 if(data
->Type
== CPP_TYPE_BYTE
|| data
->Type
== CPP_TYPE_WORD
|| data
->Type
== CPP_TYPE_INT
)
10082 if(data
->Flags
& CPP_FLAG_UNSIGNED
)
10083 data
->Replace
= "const ULONG";
10085 data
->Replace
= "const LONG";
10086 data
->Type
= CPP_TYPE_LONG
;
10087 if(!(data
->Flags
& CPP_FLAG_CONST
))
10088 data
->Replace
+= 6;
10093 if(!data
->Type
&& (data
->Flags
& CPP_FLAG_LONG
))
10094 data
->Type
= CPP_TYPE_LONG
;
10096 if((!data
->Type
&& !data
->Flags
) || !ok
)
10101 static struct ClibData
*GetClibFunc(strptr name
, struct AmiPragma
*ap
, uint32 flags
)
10103 struct ClibData
*d
= clibdata
;
10107 DoError(ERR_ILLEGAL_INTERNAL_VALUE
, 0);
10111 while(d
&& strcmp(name
, d
->FuncName
))
10116 if(!(ap
->Flags
& AMIPRAGFLAG_NOCLIB
))
10118 DoError(ERR_PROTOTYPE_MISSING
, 0, name
);
10119 ap
->Flags
|= AMIPRAGFLAG_NOCLIB
;
10122 else if(ap
->CallArgs
!= d
->NumArgs
&& (!(flags
& FUNCFLAG_TAG
) ||
10123 ap
->CallArgs
+1 != d
->NumArgs
))
10125 if(!(ap
->Flags
& (AMIPRAGFLAG_CLIBARGCNT
|AMIPRAGFLAG_DIDARGWARN
)))
10127 DoError(ERR_CLIB_ARG_COUNT
, 0, name
, d
->NumArgs
, ap
->NumArgs
);
10128 ap
->Flags
|= AMIPRAGFLAG_CLIBARGCNT
;
10136 static int32
CheckKeyword(strptr string
, strptr keyword
, int32 size
)
10138 if(!strncmp(string
, keyword
, size
))
10141 if(*string
== ' ' || *string
== '\t' || *string
== '\n')
10147 /* return nonzero, when usable, zero, when string already emitted */
10148 static uint32
CopyCPPType(strptr buffer
, uint32 pass
, struct ClibData
*cd
,
10149 struct AmiArgs
*args
)
10151 uint32 ret
= 0, reg
;
10152 uint32 i
, j
, k
= 0;
10154 /* pass 0: signed strptr, MaxonC++ high args */
10155 /* pass 1: unsigned strptr, MaxonC++ high args */
10156 /* pass 2: signed strptr, StormC++ high args */
10157 /* pass 3: unsigned strptr, StormC++ high args */
10159 for(i
= 0; i
< cd
->NumArgs
; ++i
)
10161 struct CPP_NameType
*nt
;
10165 if(args
&& (Flags
& FLAG_LOCALREG
) && (nt
->Type
!= CPP_TYPE_VARARGS
))
10166 reg
= 1 + args
[k
].ArgReg
;
10167 else if((nt
->Flags
& CPP_FLAG_REGISTER
) && nt
->Register
!= UNDEFREGISTER
)
10168 reg
= 1 + nt
->Register
;
10172 if(reg
--) /* subtract the added 1 */
10174 *(buffer
++) = CPP_TYPE_REGISTER
;
10179 *(buffer
++) = reg
/10 + '0';
10180 *(buffer
++) = reg
%10 + '0';
10184 *(buffer
++) = reg
+ (reg
< 10 ? '0' : 'A'-10);
10187 *(buffer
++) = reg
+ '0';
10190 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10192 for(j
= 0; j
< nt
->FuncPointerDepth
; ++j
)
10193 *(buffer
++) = CPP_TYPE_POINTER
;
10194 *(buffer
++) = CPP_TYPE_FUNCTION
;
10196 for(j
= 0; j
< nt
->PointerDepth
; ++j
)
10197 *(buffer
++) = CPP_TYPE_POINTER
;
10198 if(nt
->Flags
& CPP_FLAG_CONST
)
10199 *(buffer
++) = CPP_TYPE_CONST
;
10200 if(nt
->Flags
& CPP_FLAG_UNSIGNED
)
10201 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10202 else if((nt
->Flags
& CPP_FLAG_STRPTR
) && (pass
& 1))
10204 *(buffer
++) = CPP_TYPE_UNSIGNED
;
10205 ret
|= 1; /* we really use this pass */
10207 if(nt
->Flags
& CPP_FLAG_ENUM
)
10208 *(buffer
++) = CPP_TYPE_ENUM
;
10210 *(buffer
++) = cd
->Args
[i
].Type
;
10214 sprintf(buffer
, "%02lu", (uint32
) nt
->StructureLength
); buffer
+= 2;
10215 for(i
= 0; i
< nt
->StructureLength
; ++i
)
10216 *(buffer
++) = nt
->StructureName
[i
];
10218 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10222 ret
|= CopyCPPType(buffer
, pass
, nt
->FuncPtr
, 0);
10224 ++buffer
; /* skip to the new end */
10226 *(buffer
++) = CPP_TYPE_FUNCEND
;
10229 if(IsCPPType(nt
, CPP_TYPE_DOUBLE
)) /* double needs 2 registers */
10240 return ret
; /* return nozero if this pass should be used */
10243 static uint32
OutClibType(struct CPP_NameType
*nt
, strptr txt
)
10246 DoOutput("%s", nt
->Replace
);
10248 DoOutputDirect(nt
->TypeStart
, nt
->TypeLength
);
10249 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10251 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10254 DoOutput(" ("/*)*/);
10255 for(i
= 0; i
< nt
->FuncPointerDepth
; ++i
)
10257 DoOutput(/*((*/txt
? "%s)" : ")", txt
);
10259 return DoOutputDirect(nt
->FuncArgs
, nt
->ArgsLength
);
10261 return DoOutput("()");
10264 return DoOutput(" %s", txt
);
10270 static uint32
MakeClibType(strptr dest
, struct CPP_NameType
*nt
, strptr txt
)
10278 i
= strlen(nt
->Replace
);
10279 memcpy(a
, nt
->Replace
, i
);
10284 memcpy(a
, nt
->TypeStart
, nt
->TypeLength
);
10285 a
+= nt
->TypeLength
;
10288 if(nt
->Type
!= CPP_TYPE_VARARGS
)
10290 if(nt
->Flags
& CPP_FLAG_FUNCTION
)
10292 a
+= sprintf(a
, (txt
? " (*%s)" : " (*)"), txt
);
10295 memcpy(a
, nt
->FuncArgs
, nt
->ArgsLength
);
10296 a
+= nt
->ArgsLength
;
10299 a
+= sprintf(a
, "()");
10302 a
+= sprintf(a
, " %s", txt
);
10304 return (uint32
)(a
-dest
);
10307 static uint32
OutPASCALType(struct CPP_NameType
*t
, strptr txt
, uint32 ret
)
10309 int32 i
= t
->PointerDepth
;
10311 if(t
->Flags
& CPP_FLAG_CONST
)
10312 DoOutput("CONST ");
10313 if(!ret
&& i
== 1 &&
10314 (t
->Type
== CPP_TYPE_LONG
|| t
->Type
== CPP_TYPE_WORD
))
10316 DoOutput("VAR "); --i
;
10319 DoOutput("%s : ", txt
);
10321 if(!i
&& t
->Flags
== CPP_FLAG_BOOLEAN
)
10322 return DoOutput("BOOLEAN");
10323 else if(i
&& t
->Type
== CPP_TYPE_VOID
)
10324 return DoOutput("POINTER");
10325 else if(t
->Flags
& CPP_FLAG_FUNCTION
)
10326 return DoOutput("tPROCEDURE");
10331 if((t
->Flags
& (CPP_FLAG_STRUCT
|CPP_FLAG_UNION
)) && t
->StructureLength
)
10333 if(!t
->PointerDepth
)
10335 return DoOutputDirect(t
->StructureName
, t
->StructureLength
);
10338 if(t
->Flags
& CPP_FLAG_UNSIGNED
)
10340 if(t
->Type
== CPP_TYPE_LONG
)
10341 return DoOutput("CARDINAL");
10342 if(t
->Type
== CPP_TYPE_WORD
)
10343 return DoOutput("int16");
10344 if(t
->Type
== CPP_TYPE_BYTE
)
10345 return DoOutput(t
->PointerDepth
== 1 ? "CHAR" : "int8");
10347 else if(t
->Type
== CPP_TYPE_WORD
)
10348 return DoOutput("INTEGER");
10349 else if(t
->Type
== CPP_TYPE_BYTE
)
10350 return DoOutput("SHORTINT");
10351 return DoOutput("int32INT");
10354 /* ------------------------------------------------------------------ */
10356 static uint32
CallPrag(uint32 tagmode
, strptr type
, FuncType Func
)
10359 if((*type
&& !DoOutput("#if%s\n", type
)) ||
10360 !(CallFunc(tagmode
, tagmode
? 0 : "/%s */\n", Func
)) ||
10361 (*type
&& !DoOutput("#endif\n")))
10366 static uint32
CreatePragmaFile(strptr amicall
, strptr libcall
, strptr amitags
,
10367 strptr libtags
, uint32 mode
)
10369 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10373 case PRAGMODE_PRAGLIB
: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n"
10374 "#define _INCLUDE_PRAGMA_%s_LIB_H\n", ShortBaseNameUpper
,
10375 ShortBaseNameUpper
); break;
10376 case PRAGMODE_PRAGSLIB
: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define "
10377 "PRAGMAS_%s_LIB_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10378 case PRAGMODE_PRAGSPRAGS
: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define "
10379 "PRAGMAS_%s_PRAGMAS_H\n", ShortBaseNameUpper
, ShortBaseNameUpper
); break;
10380 case PRAGMODE_NONE
: break;
10387 DoOutputDirect(HEADER
, headersize
);
10390 if(mode
!= PRAGMODE_NONE
&& !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10391 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10394 if((Flags
& FLAG_EXTERNC
) &&
10395 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10398 if(Flags
& FLAG_GNUPRAG
)
10400 DoOutput("#ifdef " TEXT_GNUC
"\n#ifdef NO_OBSOLETE\n"
10401 "#error \"Please include the proto file and not the compiler specific file!\"\n"
10402 "#endif\n#include <inline/%s.h>\n#endif\n\n", ShortBaseName
);
10403 Flags
|= FLAG_DONE
;
10407 !CallPrag(TAGMODE_NORMAL
, amicall
, FuncAMICALL
) ||
10408 !CallPrag(TAGMODE_NORMAL
, libcall
, FuncLIBCALL
))
10414 !CallPrag(TAGMODE_TAGS
, amitags
, FuncAMICALL
) ||
10415 !CallPrag(TAGMODE_TAGS
, libtags
, FuncLIBCALL
))
10419 if((Flags
& FLAG_EXTERNC
) &&
10420 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10425 case PRAGMODE_PRAGLIB
: DoOutput("\n#endif\t/* _INCLUDE_PRAGMA_%s_LIB_H */\n",
10426 ShortBaseNameUpper
); break;
10427 case PRAGMODE_PRAGSLIB
: DoOutput("\n#endif\t/* PRAGMAS_%s_LIB_H */\n",
10428 ShortBaseNameUpper
); break;
10429 case PRAGMODE_PRAGSPRAGS
: DoOutput("\n#endif\t/* PRAGMAS_%s_PRAGMA_H */\n",
10430 ShortBaseNameUpper
); break;
10431 case PRAGMODE_NONE
: break;
10434 return Output_Error
;
10437 static uint32
CreateCSTUBSFile(void)
10439 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10441 DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
10442 ShortBaseNameUpper
, ShortBaseNameUpper
);
10446 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10452 DoOutputDirect(HEADER
, headersize
);
10455 if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
10456 "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper
, ShortBaseName
))
10459 if(!CallFunc(TAGMODE_TAGS
, "/%s */\n", FuncCSTUBS
))
10462 return DoOutput("#endif\t/* _INCLUDE_%s_CSTUBS_H */\n",
10463 ShortBaseNameUpper
);
10466 static uint32
CreateLVOFile(uint32 mode
)
10468 strptr data
= "_LVO_I";
10470 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10472 if(mode
== 2 || mode
== 4)
10475 if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
10476 ShortBaseNameUpper
, data
, ShortBaseNameUpper
, data
) ||
10477 (HEADER
&& (!DoOutput("\n") || !DoOutputDirect(HEADER
, headersize
))) ||
10478 (mode
<= 2 && !CallFunc(TAGMODE_NORMAL
, 0, FuncLVOXDEF
)) ||
10479 !CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVO
) ||
10480 !DoOutput("\n\n\t\tENDC\n"))
10486 static uint32
CreateLVOFilePPC(uint32 mode
)
10488 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10490 if(!DoOutput("\t.ifndef LIBRARIES_%s_LIB_I\n.set\tLIBRARIES_%s_LIB_I,1\n\n",
10491 ShortBaseNameUpper
, ShortBaseNameUpper
))
10496 DoOutputDirect(HEADER
, headersize
);
10500 case 0: CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCXDEF
);
10501 case 1: CallFunc(TAGMODE_NORMAL
, "\n%s", FuncLVOPPC
);
10503 return DoOutput("\n\t.endif\n");
10506 static uint32
CreateAsmStubs(uint32 mode
, uint32 callmode
)
10508 if(mode
== 1 && (Flags2
& FLAG2_AUTOHEADER
)) DoOutput("* %s\n\n", AUTOHEADERTEXT
);
10510 /* 1 = Text, 2 = Code */
10517 DoOutputDirect(HEADER
, headersize
);
10520 if(!(Flags
& FLAG_ASMSECTION
))
10521 DoOutput("\tSECTION\t\"%s\",CODE\n\t%sREF\t_%s\n", hunkname
,
10522 Flags
& FLAG_SMALLDATA
? "N" : "X", BaseName
);
10523 if(!CallFunc(callmode
, "\n%s", FuncAsmText
))
10527 if(!CallFunc(callmode
, 0, FuncAsmCode
))
10535 static uint32
CreateProtoFile(uint32 Type
)
10537 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10539 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper
,
10540 ShortBaseNameUpper
);
10545 DoOutputDirect(HEADER
, headersize
);
10548 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
10550 DoOutput("#if !defined(CLIB_%s_PROTOS_H) && !defined(" TEXT_GNUC
")\n"
10551 "#include <clib/%s_protos.h>\n#endif\n",
10552 ShortBaseNameUpper
, ShortBaseName
);
10556 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10558 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10560 DoOutput("%s;\n#endif\n", BaseName
);
10567 DoOutput("\n#ifdef " TEXT_GNUC
"\n");
10569 DoOutput("#ifndef __cplusplus\n");
10570 DoOutput("#ifdef __AROS__\n");
10571 DoOutput("#include <defines/%s.h>\n", ShortBaseName
);
10572 DoOutput("#else\n");
10573 DoOutput("#include <inline/%s.h>\n", ShortBaseName
);
10574 DoOutput("#endif\n");
10576 DoOutput("#endif\n");
10580 DoOutput("#elif defined(" TEXT_VBCC
")\n"
10581 "#include <inline/%s_protos.h>\n#else", ShortBaseName
);
10583 DoOutput("#elif !defined(" TEXT_VBCC
")");
10587 DoOutput("\n#ifndef __PPC__");
10590 strptr str1
= "pragma", str2
= "lib";
10594 case 4: str1
= "pragmas"; /* no break; */
10595 case 2: str2
= "pragmas"; break;
10596 case 3: str1
= "pragmas"; break;
10597 case 5: str1
= "local"; str2
= "loc"; break;
10599 DoOutput("\n#include <%s/%s_%s.h>\n", str1
, ShortBaseName
, str2
);
10602 DoOutput("#endif\n");
10604 DoOutput("#endif\n");
10607 Flags
|= FLAG_DONE
;
10609 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10612 static uint32
CreateLocalData(strptr to
, uint32 callmode
)
10614 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10616 DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n"
10617 "#define _INCLUDE_PROTO_%s_LOC_H\n",
10618 ShortBaseNameUpper
, ShortBaseNameUpper
);
10623 DoOutputDirect(HEADER
, headersize
);
10629 if((Flags
& FLAG_EXTERNC
) &&
10630 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10633 if(!CallFunc(callmode
, "/%s */\n", FuncLocText
))
10636 if((Flags
& FLAG_EXTERNC
) &&
10637 !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
10640 DoOutput("#endif\t/* _INCLUDE_PROTO_%s_LOC_H */\n", ShortBaseNameUpper
);
10642 sprintf(filename
, "%s_loc.lib", ShortBaseName
);
10643 if(!CloseDest(to
) || !OpenDest(filename
))
10646 CallFunc(callmode
, 0, FuncLocCode
);
10648 return CloseDest(filename
);
10651 static uint32
CreateInline(uint32 mode
, uint32 callmode
)
10653 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10657 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10660 DoOutput("#ifndef _%sINLINE_%s_H\n#define _%sINLINE_%s_H\n",
10661 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
,
10662 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10667 DoOutputDirect(HEADER
, headersize
);
10672 /* prevent loading of clib-file after inline */
10673 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n#endif\n\n",
10674 ShortBaseNameUpper
, ShortBaseNameUpper
);
10678 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10679 DoOutput("#ifndef __PPCINLINE_MACROS_H\n"
10680 "#include <ppcinline/macros.h>\n#endif\n\n");
10682 DoOutput("#ifndef __INLINE_MACROS_H\n"
10683 "#include <inline/macros.h>\n#endif\n\n");
10684 Flags
|= FLAG_INLINENEW
;
10688 if(Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
))
10689 DoOutput("#ifndef __PPCINLINE_STUB_H\n"
10690 "#include <ppcinline/stubs.h>\n#endif\n\n");
10692 DoOutput("#ifndef __INLINE_STUB_H\n"
10693 "#include <inline/stubs.h>\n#endif\n\n");
10695 Flags
|= FLAG_INLINESTUB
;
10698 Flags2
|= FLAG2_INLINEMAC
;
10702 if((Flags
& FLAG_EXTERNC
) &&
10703 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
10708 if(mode
&& mode
<= 2)
10710 if(Flags
& FLAG_MORPHOS
)
10711 DoOutput("#include <emul/emulregs.h>\n");
10712 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10713 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10714 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10715 "#define BASE_PAR_DECL0 void\n#endif\n"
10716 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10717 "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10720 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10721 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10726 if(!CallFunc(callmode
, "/%s */\n", FuncInline
))
10732 Flags
|= FLAG_INLINENEW
;
10733 if(!CallFunc(callmode
, "/%s */\n", FuncInlineDirect
))
10738 if(!CallFunc(callmode
, "/%s */\n", FuncInlineNS
))
10742 if(mode
&& mode
<= 2 && BaseName
)
10743 DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
10744 "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef %s_BASE_NAME\n\n", ShortBaseNameUpper
);
10746 if((Flags
& FLAG_EXTERNC
) &&
10747 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
10750 return DoOutput("#endif /* _%sINLINE_%s_H */\n",
10751 Flags
& (FLAG_POWERUP
|FLAG_MORPHOS
) ? "PPC" : "", ShortBaseNameUpper
);
10754 static uint32
CreateGateStubs(uint32 callmode
)
10756 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10760 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10762 if(!prefix
[0] && !subprefix
[0])
10764 DoError(ERR_PREFIX
, 0); return 1;
10767 DoOutput("#ifndef _GATESTUBS_%s_H\n#define _GATESTUBS_%s_H\n",
10768 ShortBaseNameUpper
, ShortBaseNameUpper
);
10770 DoOutput("%s\n#include <clib/%s_protos.h>\n#include <emul/emulregs.h>\n",
10771 premacro
, ShortBaseName
);
10776 DoOutputDirect(HEADER
, headersize
);
10781 DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
10782 "#define BASE_EXT_DECL0 extern %s %s;\n#endif\n"
10783 "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
10784 "#define BASE_PAR_DECL0 void\n#endif\n"
10785 "#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n"
10786 "BASE_EXT_DECL0\n", GetBaseType(), BaseName
, ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10791 if(!CallFunc(callmode
, "/%s */\n", FuncGateStubs
))
10794 return DoOutput("#endif /* _GATESTUBS_%s_H */\n", ShortBaseNameUpper
);
10797 static uint32
CreateSASPowerUP(uint32 callmode
)
10799 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10801 DoOutput("#ifndef _PPCPRAGMA_%s_H\n#define _PPCPRAGMA_%s_H\n",
10802 ShortBaseNameUpper
, ShortBaseNameUpper
);
10807 DoOutputDirect(HEADER
, headersize
);
10810 DoOutput("\n#ifdef __GNUC__\n"
10811 "#ifndef _PPCINLINE__%s_H\n"
10812 "#include <ppcinline/%s.h>\n"
10815 "#ifndef POWERUP_PPCLIB_INTERFACE_H\n"
10816 "#include <ppclib/interface.h>\n"
10818 "#ifndef POWERUP_GCCLIB_PROTOS_H\n"
10819 "#include <gcclib/powerup_protos.h>\n"
10821 "#ifndef NO_PPCINLINE_STDARG\n"
10822 "#define NO_PPCINLINE_STDARG\n"
10823 "#endif /* SAS-C PPC inlines */\n\n",
10824 ShortBaseNameUpper
, ShortBaseName
);
10828 DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
10829 ShortBaseNameUpper
, ShortBaseNameUpper
, BaseName
);
10832 if(!CallFunc(callmode
, "/%s */\n", FuncPowerUP
))
10835 return DoOutput("#endif /* SAS-C PPC pragmas */\n"
10836 "#endif /* _PPCPRAGMA_%s_H */\n", ShortBaseNameUpper
);
10839 static uint32
CreateProtoPowerUP(void)
10841 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
10843 DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n",
10844 ShortBaseNameUpper
, ShortBaseNameUpper
);
10849 DoOutputDirect(HEADER
, headersize
);
10852 DoOutput("\n#include <clib/%s_protos.h>\n", ShortBaseName
);
10856 DoOutput("\n#ifndef __NOLIBBASE__\nextern %s", GetBaseType());
10857 DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
10858 "#endif\n%s;\n#endif\n", BaseName
);
10861 DoOutput("\n#ifdef " TEXT_GNUC
"\n"
10862 "#ifdef __PPC__\n#include <ppcinline/%s.h>\n"
10863 "#else\n#include <inline/%s.h>\n#endif\n"
10864 "#else /* SAS-C */\n"
10865 "#ifdef __PPC__\n#include <ppcpragmas/%s_pragmas.h>\n"
10866 "#else\n#include <pragmas/%s_pragmas.h>\n#endif\n#endif\n",
10867 ShortBaseName
, ShortBaseName
, ShortBaseName
, ShortBaseName
);
10869 Flags
|= FLAG_DONE
;
10871 return DoOutput("\n#endif\t/* _PROTO_%s_H */\n", ShortBaseNameUpper
);
10874 static uint32
CreateFPCUnit(void)
10877 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("(* %s *)\n\n", AUTOHEADERTEXT
);
10881 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
10885 DoOutput(" This is a unit for %s.library\n\n",ShortBaseName
);
10890 DoOutputDirect(HEADER
, headersize
);
10893 DoOutput("**********************************************************************}\n\n");
10894 DoOutput("\n{\n If there is no array of const in the unit\n remove this compilerswitch \n}\n");
10895 DoOutput("{$mode objfpc}\n");
10896 DoOutput("{$I useamigasmartlink.inc}\n");
10897 DoOutput("{$ifdef use_amiga_smartlink}\n");
10898 DoOutput(" {$smartlink on}\n");
10899 DoOutput("{$endif use_amiga_smartlink}\n\n");
10901 DoOutput("UNIT %s;\n", ShortBaseNameUpper
);
10903 DoOutput("\nINTERFACE\nUSES Exec;\n\nVAR %s : p%s;\n\n", BaseName
, GetBaseTypeLib());
10905 DoOutput("const\n %sNAME : PChar = '%s.library';\n\n",ShortBaseNameUpper
,ShortBaseName
);
10906 DoOutput("{\n Here we read const, types and records for %s\n}\n",ShortBaseName
);
10907 DoOutput("{$I %s.inc}\n\n",ShortBaseName
);
10909 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncFPCType
))
10912 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10913 if(!CallFunc(TAGMODE_TAGS
, 0, FuncFPCTypeTags
))
10916 DoOutput("\n{Here we read how to compile this unit}\n");
10917 DoOutput("{You can remove this include and use a define instead}\n");
10918 DoOutput("{$I useautoopenlib.inc}\n");
10919 DoOutput("{$ifdef use_init_openlib}\n");
10920 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10921 DoOutput("{$endif use_init_openlib}\n");
10922 DoOutput("\n{This is a variable that knows how the unit is compiled}\n");
10923 DoOutput("var\n %sIsCompiledHow : longint;\n",ShortBaseNameUpper
);
10924 DoOutput("\nIMPLEMENTATION\n\n");
10925 DoOutput("{\n If you don't use array of const then just remove tagsarray \n}\n");
10926 DoOutput("uses \n");
10927 DoOutput("{$ifndef dont_use_openlib}\n");
10928 DoOutput("msgbox, \n");
10929 DoOutput("{$endif dont_use_openlib}\n");
10930 DoOutput("tagsarray;\n\n");
10932 if(!CallFunc(TAGMODE_NORMAL
, "(%s *)\n", FuncFPCUnit
))
10935 DoOutput("{\n Functions and procedures with array of const go here\n}\n");
10936 if(!CallFunc(TAGMODE_TAGS
,"(%s *)\n", FuncFPCTypeTagsUnit
))
10939 DoOutput("const\n { Change VERSION and LIBVERSION to proper values }\n\n");
10940 DoOutput(" VERSION : string[2] = '0';\n");
10941 DoOutput(" LIBVERSION : Cardinal = 0;\n\n");
10943 DoOutput("{$ifdef use_init_openlib}\n");
10944 DoOutput(" {$Info Compiling initopening of %s.library}\n",ShortBaseName
);
10945 DoOutput(" {$Info don't forget to use Init%sLibrary in the beginning of your program}\n",ShortBaseNameUpper
);
10947 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10948 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10949 DoOutput("begin\n");
10950 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10951 DoOutput(" if %s <> nil then begin\n",BaseName
);
10952 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10953 DoOutput(" %s := nil;\n",BaseName
);
10954 DoOutput(" end;\n");
10955 DoOutput("end;\n\n");
10956 DoOutput("procedure Init%sLibrary;\n",ShortBaseNameUpper
);
10957 DoOutput("begin\n %s := nil;\n",BaseName
);
10958 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10959 DoOutput(" if %s <> nil then begin\n",BaseName
);
10960 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10961 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10962 DoOutput(" end else begin\n");
10963 DoOutput(" MessageBox('FPC Pascal Error',\n");
10964 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10965 DoOutput(" 'Deallocating resources and closing down',\n");
10966 DoOutput(" 'Oops');\n");
10967 DoOutput(" halt(20);\n");
10968 DoOutput(" end;\n");
10969 DoOutput("end;\n\n");
10970 DoOutput("begin\n");
10971 DoOutput(" %sIsCompiledHow := 2;\n",ShortBaseNameUpper
);
10972 DoOutput("{$endif use_init_openlib}\n\n");
10974 DoOutput("{$ifdef use_auto_openlib}\n");
10975 DoOutput(" {$Info Compiling autoopening of %s.library}\n",ShortBaseName
);
10977 DoOutput("\nvar\n %s_exit : Pointer;\n\n",ShortBaseName
);
10978 DoOutput("procedure Close%sLibrary;\n",ShortBaseName
);
10979 DoOutput("begin\n");
10980 DoOutput(" ExitProc := %s_exit;\n",ShortBaseName
);
10981 DoOutput(" if %s <> nil then begin\n",BaseName
);
10982 DoOutput(" CloseLibrary(%s);\n",BaseName
);
10983 DoOutput(" %s := nil;\n",BaseName
);
10984 DoOutput(" end;\n");
10985 DoOutput("end;\n\n");
10986 DoOutput("begin\n %s := nil;\n",BaseName
);
10987 DoOutput(" %s := OpenLibrary(%sNAME,LIBVERSION);\n",BaseName
, ShortBaseNameUpper
);
10988 DoOutput(" if %s <> nil then begin\n",BaseName
);
10989 DoOutput(" %s_exit := ExitProc;\n", ShortBaseName
);
10990 DoOutput(" ExitProc := @Close%sLibrary;\n", ShortBaseName
);
10991 DoOutput(" %sIsCompiledHow := 1;\n",ShortBaseNameUpper
);
10992 DoOutput(" end else begin\n");
10993 DoOutput(" MessageBox('FPC Pascal Error',\n");
10994 DoOutput(" 'Can''t open %s.library version ' + VERSION + #10 +\n",ShortBaseName
);
10995 DoOutput(" 'Deallocating resources and closing down',\n");
10996 DoOutput(" 'Oops');\n");
10997 DoOutput(" halt(20);\n");
10998 DoOutput(" end;\n\n");
10999 DoOutput("{$endif use_auto_openlib}\n\n");
11001 DoOutput("{$ifdef dont_use_openlib}\n");
11002 DoOutput("begin\n");
11003 DoOutput(" %sIsCompiledHow := 3;\n",ShortBaseNameUpper
);
11004 DoOutput(" {$Warning No autoopening of %s.library compiled}\n",ShortBaseName
);
11005 DoOutput(" {$Warning Make sure you open %s.library yourself}\n",ShortBaseName
);
11006 DoOutput("{$endif dont_use_openlib}\n\n");
11008 return DoOutput("END. (* UNIT %s *)\n", ShortBaseNameUpper
);
11011 static uint32
CreateBMAP(void)
11013 return CallFunc(TAGMODE_NORMAL
, 0, FuncBMAP
);
11016 static uint32
CreateLVOLib(void)
11020 i
= strlen(ShortBaseNameUpper
);
11021 EndPutM32(tempbuf
, HUNK_UNIT
);
11022 EndPutM32(tempbuf
+4, (i
+3)>>2);
11023 DoOutputDirect(tempbuf
, 8);
11024 DoOutputDirect(ShortBaseNameUpper
, i
);
11025 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11027 i
= strlen(hunkname
);
11028 EndPutM32(tempbuf
, HUNK_NAME
);
11029 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11030 DoOutputDirect(tempbuf
, 8);
11031 DoOutputDirect(hunkname
, i
);
11032 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11034 EndPutM32(tempbuf
, HUNK_CODE
);
11035 EndPutM32(tempbuf
+4, 0);
11036 EndPutM32(tempbuf
+8, HUNK_EXT
);
11037 DoOutputDirect(tempbuf
, 12);
11039 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOLib
))
11042 EndPutM32(tempbuf
, 0);
11043 EndPutM32(tempbuf
+4, HUNK_END
);
11044 return DoOutputDirect(tempbuf
, 8);
11047 static uint32
CreateLVOLibPPC(void)
11049 uint8
*data
= tempbuf
, *data2
, *data3
;
11051 *(data
++) = 0x7F; /* eeh->e_ident[EI_MAG0] */
11052 *(data
++) = 'E'; /* eeh->e_ident[EI_MAG1] */
11053 *(data
++) = 'L'; /* eeh->e_ident[EI_MAG2] */
11054 *(data
++) = 'F'; /* eeh->e_ident[EI_MAG3] */
11055 *(data
++) = ELFCLASS32
; /* eeh->e_ident[EI_CLASS] */
11056 *(data
++) = ELFDATA2MSB
; /* eeh->e_ident[EI_DATA] */
11057 *(data
++) = EV_CURRENT
; /* eeh->e_ident[EI_VERSION] */
11058 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11059 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11060 *(data
++) = 0; *(data
++) = 0; *(data
++) = 0;
11061 EndPutM16Inc(data
, ET_REL
); /* eeh->e_type */
11062 EndPutM16Inc(data
, EM_POWERPC
); /* eeh->e_machine */
11063 EndPutM32Inc(data
, EV_CURRENT
); /* eeh->e_version */
11064 EndPutM32Inc(data
, 0); /* eeh->e_entry */
11065 EndPutM32Inc(data
, 0); /* eeh->e_phoff */
11066 data2
= data
; data
+= 4;
11067 EndPutM32Inc(data
, 0); /* eeh->e_flags */
11068 EndPutM16Inc(data
, 52); /* eeh->e_ehsize */
11069 EndPutM16Inc(data
, 0); /* eeh->e_phentsize */
11070 EndPutM16Inc(data
, 0); /* eeh->e_phnum */
11071 EndPutM16Inc(data
, 40); /* eeh->e_shentsize */
11072 EndPutM16Inc(data
, 4); /* eeh->e_shnum */
11073 EndPutM16Inc(data
, 1); /* eeh->e_shstrndx - first table is string table */
11076 memcpy(data
, "\0.symtab\0.strtab\0.shstrtab\0\0", 28);
11077 data
+= 28; /* 1 9 17*/
11078 EndPutM32(data2
, data
-tempbuf
); /* store the entry */
11080 EndPutM32Inc(data
, 0); /* esh[0].sh_name */
11081 EndPutM32Inc(data
, 0); /* esh[0].sh_type */
11082 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11083 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11084 EndPutM32Inc(data
, 0); /* esh[0].sh_offset */
11085 EndPutM32Inc(data
, 0); /* esh[0].sh_size */
11086 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11087 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11088 EndPutM32Inc(data
, 0); /* esh[0].sh_addralign */
11089 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11091 EndPutM32Inc(data
, 17); /* esh[3].sh_name = .shstrtab */
11092 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[3].sh_type */
11093 EndPutM32Inc(data
, 0); /* esh[3].sh_flags */
11094 EndPutM32Inc(data
, 0); /* esh[3].sh_addr */
11095 EndPutM32Inc(data
, data3
-tempbuf
); /* esh[3].sh_offset */
11096 EndPutM32Inc(data
, 27); /* esh[3].sh_size */
11097 EndPutM32Inc(data
, 0); /* esh[3].sh_link */
11098 EndPutM32Inc(data
, 0); /* esh[3].sh_info */
11099 EndPutM32Inc(data
, 1); /* esh[3].sh_addralign */
11100 EndPutM32Inc(data
, 0); /* esh[3].sh_entsize */
11102 EndPutM32Inc(data
, 1); /* esh[4].sh_name = .symtab */
11103 EndPutM32Inc(data
, SHT_SYMTAB
); /* esh[4].sh_type */
11104 EndPutM32Inc(data
, 0); /* esh[4].sh_flags */
11105 EndPutM32Inc(data
, 0); /* esh[4].sh_addr */
11107 data
+= 4; /* esh[4].sh_offset */
11108 data
+= 4; /* esh[4].sh_size */
11109 EndPutM32Inc(data
, 3); /* esh[4].sh_link - the third entry is our string table */
11110 EndPutM32Inc(data
, 1); /* esh[4].sh_info - One greater than index of last LOCAL symbol*/
11111 EndPutM32Inc(data
, 4); /* esh[4].sh_addralign */
11112 EndPutM32Inc(data
, 16); /* esh[4].sh_entsize = sizeof(struct Elf32_Sym) */
11114 EndPutM32Inc(data
, 9); /* esh[0].sh_name = .strtab */
11115 EndPutM32Inc(data
, SHT_STRTAB
); /* esh[0].sh_type */
11116 EndPutM32Inc(data
, 0); /* esh[0].sh_flags */
11117 EndPutM32Inc(data
, 0); /* esh[0].sh_addr */
11119 data
+= 4; /* esh[0].sh_offset */
11120 data
+= 4; /* esh[0].sh_size */
11121 EndPutM32Inc(data
, 0); /* esh[0].sh_link */
11122 EndPutM32Inc(data
, 0); /* esh[0].sh_info */
11123 EndPutM32Inc(data
, 1); /* esh[0].sh_addralign */
11124 EndPutM32Inc(data
, 0); /* esh[0].sh_entsize */
11126 EndPutM32Inc(data2
, data
-tempbuf
);
11128 EndPutM32Inc(data
,0);
11129 EndPutM32Inc(data
,0); /* first entry is empty */
11130 EndPutM32Inc(data
,0);
11131 EndPutM32Inc(data
,0);
11133 symoffset
= 1; /* initial value */
11136 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCBias
))
11138 EndPutM32(data2
, elfbufpos
-data
+16);
11139 EndPutM32Inc(data3
, elfbufpos
-tempbuf
);
11140 EndPutM32(data3
, symoffset
);
11142 *(elfbufpos
++) = 0; /* first sym entry */
11143 if(!DoOutputDirect(tempbuf
, elfbufpos
-tempbuf
))
11146 if(!CallFunc(TAGMODE_NORMAL
, 0, FuncLVOPPCName
))
11149 while((symoffset
++)&3)
11151 if(!DoOutputDirect("", 1))
11158 static uint32
CreateVBCCInline(uint32 mode
, uint32 callmode
)
11160 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11164 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11167 DoOutput("#ifndef _VBCCINLINE_%s_H\n#define _VBCCINLINE_%s_H\n",
11168 ShortBaseNameUpper
, ShortBaseNameUpper
);
11170 DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
11173 /* always include emul/emulregs.h in MorphOS inlines,
11174 gcc-based sources might depend on it :| */
11175 DoOutput("#ifndef EMUL_EMULREGS_H\n#include <emul/emulregs.h>\n#endif\n");
11181 DoOutputDirect(HEADER
, headersize
);
11186 if(!CallFunc(callmode
, "/%s */\n", mode
? (mode
== 2 ? FuncVBCCMorphInline
11187 : FuncVBCCWOSInline
) : FuncVBCCInline
))
11190 return DoOutput("#endif /* _VBCCINLINE_%s_H */\n", ShortBaseNameUpper
);
11193 static uint32
CreateVBCC(uint32 mode
, uint32 callmode
)
11197 if(mode
!= 2 && mode
!= 3)
11199 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11204 DoOutputDirect(HEADER
, headersize
);
11210 case 4: res
= CallFunc(callmode
, 0, FuncVBCCPUPText
); break;
11212 case 3: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11213 case 2: res
= CallFunc(callmode
, 0, FuncVBCCWOSCode
); break;
11215 case 1: Flags
|= FLAG_WOSLIBBASE
; /* no break! */
11216 case 0: res
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
); break;
11221 static uint32
CreateVBCCPUPLib(uint32 callmode
)
11223 /* output header */
11224 DoOutput("!<arch>\n");
11226 return CallFunc(callmode
, 0, FuncVBCCPUPCode
);
11229 static uint32
CreateVBCCMorphCode(uint32 callmode
)
11231 /* output header */
11232 DoOutput("!<arch>\n");
11234 return CallFunc(callmode
, 0, FuncVBCCMorphCode
);
11237 static uint32
CreateEModule(uint32 sorted
)
11241 DoError(ERR_NO_SORTED
, 0);
11244 DoOutputDirect("EMOD\0\x06", 6);
11245 for(res
= 0; res
< 2; ++res
)
11247 for(i
= 0; BaseName
[i
]; ++i
)
11248 DoOutput("%c", tolower(BaseName
[i
]));
11249 DoOutputDirect("\x00",1);
11251 LastBias
= BIAS_START
-BIAS_OFFSET
;
11252 CallFunc(TAGMODE_NORMAL
, 0, FuncEModule
);
11253 res
= DoOutputDirect("\xFF",1);
11258 static uint32
CreateProtoRedirect(void)
11260 Flags
|= FLAG_DONE
;
11261 return DoOutput("#ifdef NO_OBSOLETE\n"
11262 "#error \"Please include the proto file and not the compiler specific file!\"\n"
11263 "#endif\n\n#include <proto/%s.h>\n", ShortBaseName
);
11266 static uint32
CreateSFD(uint32 callmode
)
11268 struct Include
*inc
;
11269 struct AmiPragma
*ap
;
11272 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11275 if((ap
= (struct AmiPragma
*) AmiPragma
.First
))
11276 LastBias
= ap
->Bias
-BIAS_OFFSET
;
11277 else /* only security, never used normally */
11279 CurrentABI
= ABI_M68K
;
11282 DoOutput("==id %s\n", IDstring
);
11289 tim
= localtime(&t
);
11291 DoOutput("==id %cId: %s,v 1.0 %04d/%02d/%02d %02d:%02d:%02d "
11292 "noname Exp $\n", '$', filename
, tim
->tm_year
+1900, tim
->tm_mon
+1,
11293 tim
->tm_mday
, tim
->tm_hour
, tim
->tm_min
, tim
->tm_sec
);
11297 DoOutput("* \"%s\"\n==base _%s\n==basetype %s\n==libname %s\n",
11298 GetLibraryName(), BaseName
, GetBaseType(), GetLibraryName());
11299 DoOutput("==bias %ld\n==public\n", LastBias
+BIAS_OFFSET
);
11301 for(inc
= (struct Include
*) Includes
.First
; inc
; inc
= (struct Include
*) inc
->List
.Next
)
11302 DoOutput("==include %s\n", inc
->Include
);
11303 if(!Includes
.First
)
11304 DoOutput("==include <exec/types.h>\n");
11306 CallFunc(callmode
, "%s\n", FuncSFD
);
11308 return DoOutput("==end\n");
11311 static uint32
CreateClib(uint32 callmode
)
11315 DoError(ERR_NOPROTOTYPES_FILE
, 0); return 1;
11318 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11320 DoOutput("#ifndef CLIB_%s_PROTOS_H\n#define CLIB_%s_PROTOS_H\n\n", ShortBaseNameUpper
,
11321 ShortBaseNameUpper
);
11326 DoOutputDirect(HEADER
, headersize
);
11335 tim
= localtime(&t
);
11339 s
= SkipBlanks(IDstring
+4);
11340 while(*s
&& *s
!= ' ')
11347 if(Flags2
& FLAG2_SYSTEMRELEASE
)
11349 DoOutput("\n/*\n**\t$Id: %s %s\n", filename
, s
);
11356 while(*t
&& *t
!= ' ')
11360 DoOutput("\n/*\n**\t$%s: %s %s (%02d.%02d.%04d)\n", "VER", filename
, s
,
11361 tim
->tm_mday
, tim
->tm_mon
+1, tim
->tm_year
+1900);
11363 DoOutput("**\n**\tC prototypes. For use with 32 bit integers only.\n**\n**\t");
11364 if(!Copyright
|| (Copyright
&& strncmp("Copyright ", Copyright
, 10)))
11365 DoOutput("Copyright © %d ", tim
->tm_year
+1900);
11366 DoOutput("%s\n", Copyright
? Copyright
: Flags2
& FLAG2_SYSTEMRELEASE
?
11367 "Amiga, Inc." : "");
11368 DoOutput("**\tAll Rights Reserved\n*/\n\n");
11373 if((Flags
& FLAG_EXTERNC
) &&
11374 !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
11377 CallFunc(callmode
, "\n/%s */\n\n", FuncClib
);
11379 if((Flags
& FLAG_EXTERNC
) &&
11380 !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
11383 return DoOutput("\n#endif\t/* CLIB_%s_PROTOS_H */\n", ShortBaseNameUpper
);
11386 static uint32
CreateFD(void)
11389 CurrentABI
= ABI_M68K
;
11392 DoOutput("##base _%s\n", BaseName
);
11393 DoOutput("##public\n");
11395 CallFunc(TAGMODE_NORMAL
, "%s\n", FuncFD
);
11397 return DoOutput("##end\n");
11400 static uint32
CreateGenAuto(strptr to
, uint32 type
)
11402 strptr name
, btype
;
11404 uint32 i
, verref
, exitfuncref
, sysref2
, exitref
, rel1
, rel2
, nameref
;
11405 if(!(name
= GetLibraryName()))
11407 btype
= GetBaseType();
11412 Flags
|= FLAG_DONE
;
11413 if(!(DoOutput("#include <exec/libraries.h>\n#include <proto/exec.h>\n\n"
11414 "%s %s = 0;\nextern unsigned long _%sVer;\n\n"
11415 "void _INIT_%ld_%s(void)\n{\n if(!(%s = %sOpenLibrary(\"%s\", _%sVer)))\n exit(20);\n}\n\n"
11416 "void _EXIT_%ld_%s(void)\n{\n if(%s)\n CloseLibrary(%s%s);\n}\n",
11417 btype
, BaseName
, BaseName
,
11418 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", name
, BaseName
,
11419 priority
, BaseName
, BaseName
, !strcmp("struct Library *", btype
) ? "" : "(struct Library *) ", BaseName
)))
11421 sprintf(filename
, "%s_autoopenver.c", ShortBaseName
);
11422 if(!CloseDest(to
) || !OpenDest(filename
))
11424 Flags
|= FLAG_DONE
;
11425 return DoOutput("unsigned long _%sVer = 0;\n", BaseName
);
11428 Flags
|= FLAG_DONE
;
11429 i
= strlen(filename
)-4; /* remove .lib extension */
11430 EndPutM32(tempbuf
, HUNK_UNIT
);
11431 EndPutM32(tempbuf
+4, (i
+3)>>2);
11432 DoOutputDirect(tempbuf
, 8);
11433 DoOutputDirect(filename
, i
);
11434 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11436 i
= strlen(hunkname
);
11437 EndPutM32(tempbuf
, HUNK_NAME
);
11438 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11439 DoOutputDirect(tempbuf
, 8);
11440 DoOutputDirect(hunkname
, i
);
11441 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11443 data
= tempbuf
+8; /* we need HUNK_CODE + size at start */
11444 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11446 if(Flags
& FLAG_SMALLDATA
)
11448 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11449 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11453 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11454 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11456 verref
= data
-tempbuf
-8+2;
11457 if(Flags
& FLAG_SMALLDATA
)
11459 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11460 EndPutM16Inc(data
, 0); /* place for basevers reference */
11464 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11465 EndPutM32Inc(data
, 0); /* place for basevers reference */
11467 EndPutM32Inc(data
, 0x43FA0030 + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2) + ((Flags
& FLAG_SMALLDATA
) ? 0 : 6));
11468 EndPutM32Inc(data
, 0x4EAEFDD8); /* JSR _LVOOpenLibrary(A6) */
11470 rel1
= data
-tempbuf
-8+2;
11471 if(Flags
& FLAG_SMALLDATA
)
11473 EndPutM16Inc(data
, 0x2940); /* MOVE.L D0,xxx(A4) */
11474 EndPutM16Inc(data
, 0);
11478 EndPutM16Inc(data
, 0x23C0); /* MOVE.L D0,xxx */
11479 EndPutM32Inc(data
, 0);
11481 EndPutM16Inc(data
, 0x660A + ((Flags2
& FLAG2_SMALLCODE
) ? 0 : 2)); /* BNE.B .lib */
11482 EndPutM32Inc(data
, 0x48780014); /* PEA 20 */
11484 exitfuncref
= data
-tempbuf
-8+2;
11485 if(Flags2
& FLAG2_SMALLCODE
)
11487 EndPutM16Inc(data
, 0x4EBA); /* JSR _exit(PC) */
11488 EndPutM16Inc(data
, 0); /* place for base reference */
11492 EndPutM16Inc(data
, 0x4EB9); /* JSR _exit */
11493 EndPutM32Inc(data
, 0); /* place for base reference */
11495 EndPutM16Inc(data
, 0x584F); /* ADDQ.W, #4,A7 */
11496 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11497 EndPutM16Inc(data
,0x4E75); /* RTS */
11498 exitref
= data
-tempbuf
-8;
11500 EndPutM16Inc(data
, 0x2F0E); /* MOVE.L A6,-(A7) */
11501 sysref2
= data
-tempbuf
-8+2;
11503 if(Flags
& FLAG_SMALLDATA
)
11505 EndPutM16Inc(data
, 0x2C6C); /* MOVEA.L base(A4),A6 */
11506 EndPutM16Inc(data
, 0); /* place for sysbase reference */
11510 EndPutM16Inc(data
, 0x2C79); /* MOVEA.L base,A6 */
11511 EndPutM32Inc(data
, 0); /* place for sysbase reference */
11513 rel2
= data
-tempbuf
-8+2;
11514 if(Flags
& FLAG_SMALLDATA
)
11516 EndPutM16Inc(data
, 0x202C); /* MOVE.L xxx(A4),D0 */
11517 EndPutM16Inc(data
, 0); /* place for base reference */
11521 EndPutM16Inc(data
, 0x2039); /* MOVE.L xxx,D0 */
11522 EndPutM32Inc(data
, 0); /* place for base reference */
11524 EndPutM16Inc(data
, 0x6606); /* BNE.B .nolib */
11525 EndPutM16Inc(data
, 0x2240); /* MOVEA.L D0,A1 */
11527 EndPutM32Inc(data
, 0x4EAEFE62); /* JSR _LVOCloseLibrary(A6) */
11528 EndPutM16Inc(data
, 0x2C5F); /* MOVE.L (A7)+,A6 */
11529 EndPutM16Inc(data
,0x4E75); /* RTS */
11530 nameref
= data
-tempbuf
-8;
11531 memcpy(data
, name
, strlen(name
));
11532 data
+= strlen(name
);
11533 do { *(data
++) = 0; } while((data
-tempbuf
)&3);
11535 EndPutM32(tempbuf
, HUNK_CODE
);
11536 EndPutM32(tempbuf
+4, (data
-tempbuf
-8)>>2)
11537 DoOutputDirect(tempbuf
, (size_t)(data
-tempbuf
)&(~3));
11539 if(Flags
& FLAG_SMALLDATA
)
11541 EndPutM32(tempbuf
, HUNK_DREL16
);
11545 EndPutM32(tempbuf
, HUNK_ABSRELOC32
);
11547 EndPutM32(tempbuf
+4, 2); /* 2 entries */
11548 EndPutM32(tempbuf
+8, 1); /* to hunk 1 */
11549 EndPutM32(tempbuf
+12, rel1
); /* address 0 */
11550 EndPutM32(tempbuf
+16, rel2
); /* address 0 */
11551 EndPutM32(tempbuf
+20, 0); /* end of reloc hunk */
11552 DoOutputDirect(tempbuf
, 24);
11554 /* extern references */
11555 EndPutM32(tempbuf
, HUNK_EXT
);
11556 DoOutputDirect(tempbuf
, 4);
11558 OutputXREF2(4, sysref2
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "_SysBase");
11559 OutputXREF(verref
, (Flags
& FLAG_SMALLDATA
? EXT_DEXT16
: EXT_REF32
), "__%sVer", BaseName
);
11560 OutputXREF(exitfuncref
, (Flags2
& FLAG2_SMALLCODE
? EXT_DEXT16
: EXT_REF32
), "_exit");
11561 OutputXDEF(0, "__INIT_%ld_%s", priority
, BaseName
);
11562 OutputXDEF(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11563 OutputXDEF(nameref
, "%sname", ShortBaseName
);
11564 EndPutM32(tempbuf
, 0); /* ext end */
11565 DoOutputDirect(tempbuf
, 4);
11567 if(!(Flags
& FLAG_NOSYMBOL
))
11569 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11570 DoOutputDirect(tempbuf
, 4);
11571 OutputSYMBOL(0, "__INIT_%ld_%s", priority
, BaseName
);
11572 OutputSYMBOL(exitref
, "__EXIT_%ld_%s", priority
, BaseName
);
11573 OutputSYMBOL(nameref
, "%sname", ShortBaseName
);
11574 EndPutM32(tempbuf
, 0);
11575 DoOutputDirect(tempbuf
, 4);
11578 EndPutM32(tempbuf
, HUNK_END
);
11579 DoOutputDirect(tempbuf
, 4);
11581 i
= strlen(datahunkname
);
11582 EndPutM32(tempbuf
, HUNK_NAME
);
11583 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11584 DoOutputDirect(tempbuf
, 8);
11585 DoOutputDirect(datahunkname
, i
);
11586 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11588 EndPutM32(tempbuf
, HUNK_BSS
);
11589 EndPutM32(tempbuf
+4, 1);
11590 DoOutputDirect(tempbuf
, 8);
11592 EndPutM32(tempbuf
, HUNK_EXT
);
11593 DoOutputDirect(tempbuf
, 4);
11594 OutputXDEF(0, "_%s", BaseName
);
11595 EndPutM32(tempbuf
, 0); /* ext end */
11596 DoOutputDirect(tempbuf
, 4);
11598 if(!(Flags
& FLAG_NOSYMBOL
))
11600 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11601 DoOutputDirect(tempbuf
, 4);
11602 OutputSYMBOL(0, "_%s", BaseName
);
11603 EndPutM32(tempbuf
, 0);
11604 DoOutputDirect(tempbuf
, 4);
11607 EndPutM32(tempbuf
, HUNK_END
);
11608 DoOutputDirect(tempbuf
, 4);
11610 sprintf(filename
, "%s_autoopenver", ShortBaseName
);
11611 i
= strlen(filename
);
11612 EndPutM32(tempbuf
, HUNK_UNIT
);
11613 EndPutM32(tempbuf
+4, (i
+3)>>2);
11614 DoOutputDirect(tempbuf
, 8);
11615 DoOutputDirect(filename
, i
);
11616 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11618 i
= strlen(datahunkname
);
11619 EndPutM32(tempbuf
, HUNK_NAME
);
11620 EndPutM32(tempbuf
+4, (i
+ 3)>>2);
11621 DoOutputDirect(tempbuf
, 8);
11622 DoOutputDirect(datahunkname
, i
);
11623 DoOutputDirect("\0\0\0", ((i
+3)&(~3))-i
);
11625 EndPutM32(tempbuf
, HUNK_BSS
);
11626 EndPutM32(tempbuf
+4, 1);
11627 DoOutputDirect(tempbuf
, 8);
11629 EndPutM32(tempbuf
, HUNK_EXT
);
11630 DoOutputDirect(tempbuf
, 4);
11631 OutputXDEF(0, "_%sVer", BaseName
);
11632 EndPutM32(tempbuf
, 0); /* ext end */
11633 DoOutputDirect(tempbuf
, 4);
11635 if(!(Flags
& FLAG_NOSYMBOL
))
11637 EndPutM32(tempbuf
, HUNK_SYMBOL
);
11638 DoOutputDirect(tempbuf
, 4);
11639 OutputSYMBOL(0, "_%sVer", BaseName
);
11640 EndPutM32(tempbuf
, 0);
11641 DoOutputDirect(tempbuf
, 4);
11644 EndPutM32(tempbuf
, HUNK_END
);
11645 return DoOutputDirect(tempbuf
, 4);
11652 static uint32
CreateXML(void)
11654 struct Include
*inc
;
11658 "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
11659 "<!DOCTYPE library SYSTEM \"library.dtd\">\n"
11660 "<library name=\"%s\" basename=\"%s\" openname=\"%s\"",
11661 ShortBaseName
, BaseName
, GetLibraryName());
11662 if(GetBaseTypeLib() != libstring
)
11663 DoOutput(" basetype=\"%s\"", GetBaseTypeLib());
11665 for(inc
= (struct Include
*) Includes
.First
; inc
;
11666 inc
= (struct Include
*) inc
->List
.Next
)
11667 DoOutput("\t<include>%.*s</include>\n", (int)(strlen(inc
->Include
)-2),
11669 if(!Includes
.First
)
11670 DoOutput("\t<include>exec/types.h</include>\n");
11672 DoOutput("\t<interface name=\"main\" version=\"1.0\" struct=\"%sIFace\""
11673 " prefix=\"_%s_\" asmprefix=\"I%s\" global=\"I%s\">\n",
11674 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName());
11676 "\t\t<method name=\"Obtain\" result=\"ULONG\"/>\n"
11677 "\t\t<method name=\"Release\" result=\"ULONG\"/>\n"
11678 "\t\t<method name=\"Expunge\" result=\"void\" status=\"unimplemented\"/>\n"
11679 "\t\t<method name=\"Clone\" result=\"struct Interface *\""
11680 " status=\"unimplemented\"/>\n");
11682 CallFunc(TAGMODE_BOTH
, 0, FuncXML
);
11684 return DoOutput("\t</interface>\n</library>\n");
11687 static uint32
CreateOS4PPC(uint32 callmode
)
11689 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11694 DoOutputDirect(HEADER
, headersize
);
11700 "#include <stdarg.h>\n"
11701 "#include <exec/types.h>\n"
11702 "#include <exec/interfaces.h>\n"
11703 "#include <exec/emulation.h>\n"
11704 "#include <interfaces/exec.h>\n");
11706 if(!stricmp("exec",ShortBaseName
))
11707 DoOutput("#include <interfaces/%s.h>\n", ShortBaseName
);
11709 DoOutput("#include \"%s_vectors.c\"\n\n", ShortBaseName
);
11711 CallFunc(callmode
, "\n/%s */\n\n", FuncOS4PPC
);
11714 "ULONG _%s_Obtain(struct %sIFace *Self)\n{\n"
11715 " return Self->Data.RefCount++;\n}\n\n"
11716 "ULONG _%s_Release(struct %sIFace *Self)\n{\n"
11717 " return Self->Data.RefCount--;\n}\n\n"
11718 "#define LIBNAME \"%s\"\n"
11719 "#define LIBVERSION 0\n"
11720 "#define IFACENAME \"%s.main\"\n\n",
11721 GetIFXName(), GetIFXName(), GetIFXName(), GetIFXName(),
11722 GetLibraryName(), GetLibraryName());
11724 /* following text is constant */
11726 "static void InitFunction(APTR dummy, ULONG SegList, "
11727 "struct ExecBase *ExecBase)\n{\n"
11728 " struct Library *LibBase;\n"
11729 " struct ExecIFace *IExec = (struct ExecIFace *)"
11730 "ExecBase->MainInterface;\n"
11731 " if((LibBase = IExec->OpenLibrary(LIBNAME, LIBVERSION)))\n"
11733 " struct Interface *NewInterface;\n"
11734 " if((NewInterface = IExec->MakeInterfaceTags(LibBase,\n"
11735 " MIT_VectorTable, main_vectors,\n"
11736 " MIT_Version, 1,\n"
11737 " MIT_Name, IFACENAME,\n"
11740 " NewInterface->Data.IExecPrivate = (APTR)IExec;\n"
11741 " IExec->AddInterface(LibBase, NewInterface);\n"
11745 "volatile static struct Resident MyResident =\n{\n"
11746 " RTC_MATCHWORD,\n"
11747 " (struct Resident *)&MyResident,\n"
11748 " (APTR)(&MyResident+1),\n"
11757 "void _start(void)\n"
11758 "{\n /* printf(\"This program cannot be run in DOS mode :-)\\n\"); */"
11762 static uint32
CreateOS4M68K(void)
11764 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11769 DoOutputDirect(HEADER
, headersize
);
11772 "#include \"exec/interfaces.i\"\n"
11773 "#include \"exec/libraries.i\"\n"
11774 "#include \"exec/emulation.i\"\n"
11775 "#include \"interfaces/%s.i\"\n\n",ShortBaseName
);
11778 "\t.section .data\n"
11779 "\t.globl\tstub_Open\n"
11780 "\t.type\tstub_Open,@function\n"
11783 "\t.short\t0x4ef8\n" /* JMP.w */
11784 "\t.short\t0\n" /* Indicate switch */
11785 "\t.short\t1\n" /* Trap type */
11786 "\t.globl\tstub_OpenPPC\n"
11787 "\t.long\tstub_OpenPPC\n"
11788 "\t.byte\t2\n" /* Register mapping */
11789 "\t.byte\t1,REG68K_A7\n"
11790 "\t.byte\t3,REG68K_A6\n"
11791 "\t.section .text\n"
11795 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11796 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11797 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11798 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11799 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11800 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11801 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11802 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11803 "\tCallLib\tlmi_Open\n"
11804 "\tlwz\t%s11,%s12(%s1)\n"
11806 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11807 "\tblrl\n" /* Return to emulation */
11809 "\t.globl\tstub_Open68K\n"
11810 "\t.long\tstub_Open68K\n"
11811 "\t.byte\t0\n" /* Flags */
11812 "\t.byte\t2\n" /* Two registers (a7 and d0) */
11813 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11814 "\t.byte\t3,REG68K_D0\n" /* Map r3 to D0 */
11815 "\t.section .data\n"
11819 "\t.short\t0x4e75\n" /* RTS */
11821 "\t.section .data\n"
11822 "\t.globl\tstub_Close\n"
11823 "\t.type\tstub_Close,@function\n"
11826 "\t.short\t0x4ef8\n" /* JMP.w */
11827 "\t.short\t0\n" /* Indicate switch */
11828 "\t.short\t1\n" /* Trap type */
11829 "\t.globl\tstub_ClosePPC\n"
11830 "\t.long\tstub_ClosePPC\n"
11831 "\t.byte\t2\n" /* Register mapping */
11832 "\t.byte\t1,REG68K_A7\n" /* map r1 to a7 */
11833 "\t.byte\t3,REG68K_A6\n"
11834 "\t.section .text\n"
11838 "\taddi\t%s12,%s1,-16\n" /* Calculate stackframe size */
11839 "\trlwinm\t%s12,%s12,0,0,27\n" /* Align it */
11840 "\tstw\t%s1,0(%s12)\n" /* Store backchain pointer */
11841 "\tmr\t%s1,%s12\n" /* Set real stack pointer */
11842 "\tstw\t%s11,12(%s1)\n" /* Store Enter68kQuick vector */
11843 "\tlhz\t%s12,LIB_POSSIZE(%s3)\n"
11844 "\tadd\t%s3,%s3,%s12\n" /* by addind posSize */
11845 "\tlwz\t%s3,ExtLib_ILibrary(%s3)\n" /* Get the real interface pointer */
11846 "\tCallLib\tlmi_Close\n"
11847 "\tlwz\t%s11,12(%s1)\n"
11849 "\tlwz\t%s1,0(%s1)\n" /* Cleanup stack frame */
11850 "\tblrl\n" /* Return to emulation */
11852 "\t.globl\tstub_Close68K\n"
11853 "\t.long\tstub_Close68K\n"
11854 "\t.byte\t0\n" /* Flags */
11855 "\t.byte\t1\n" /* One register (a7 only) */
11856 "\t.byte\t1,REG68K_A7\n" /* Map r1 to A7 */
11857 "\t.section .data\n"
11861 "\t.short\t0x4e75\n" /* RTS */
11863 "\t.section .data\n"
11864 "\t.globl\tstub_Expunge\n"
11865 "\t.type\tstub_Expunge,@function\n"
11868 "\t.short\t0x7000\n" /* moveq #0, d0 */
11869 "\t.short\t0x4e75\n" /* RTS */
11871 "\t.section .data\n"
11872 "\t.globl\tstub_Reserved\n"
11873 "\t.type\tstub_Reserved,@function\n"
11876 "\t.short\t0x7000\n" /* moveq #0, d0 */
11877 "\t.short\t0x4e75\n\n", /* RTS */
11878 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11879 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11880 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11881 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11882 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11883 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11884 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11885 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
,
11886 PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
, PPCRegPrefix
);
11888 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68K
);
11890 "\t.globl\tVector68K\n"
11891 "\t.globl\tVecTable68K\n"
11893 "\t.long\tVecTable68K\n"
11895 "\t.long\tstub_Open\n"
11896 "\t.long\tstub_Close\n"
11897 "\t.long\tstub_Expunge\n"
11898 "\t.long\tstub_Reserved\n");
11901 CallFunc(TAGMODE_NORMAL
, 0, FuncOS4M68KVect
);
11902 DoOutput("\t.long\t-1\n");
11904 CloseDest(filename
);
11906 if(Flags2
& FLAG2_OS4M68KCSTUB
)
11908 sprintf(filename
, "%s_68k.c", ShortBaseName
);
11909 if(!OpenDest(filename
))
11911 Flags
&= ~(FLAG_DONE
);
11912 if(Flags2
& FLAG2_AUTOHEADER
) DoOutput("/* %s */\n\n", AUTOHEADERTEXT
);
11917 DoOutputDirect(HEADER
, headersize
);
11921 "#ifdef __USE_INLINE__\n"
11922 "#undef __USE_INLINE__\n"
11924 "#ifndef __NOGLOBALIFACE__\n"
11925 "#define __NOGLOBALIFACE__\n"
11927 "#include <exec/interfaces.h>\n"
11928 "#include <exec/libraries.h>\n"
11929 "#include <exec/emulation.h>\n"
11930 "#include <interfaces/exec.h>\n"
11931 "#include <interfaces/%s.h>\n"
11932 "#include <proto/%s.h>\n\n", ShortBaseName
, ShortBaseName
);
11934 CallFunc(TAGMODE_NORMAL
, "\n/%s */\n\n", FuncOS4M68KCSTUB
);
11936 return Output_Error
;
11939 /* ------------------------------------------------------------------ */
11941 static uint32
GetName(struct NameList
*t
, struct ShortListRoot
*p
, uint32 args
)
11943 struct NameList
*p2
= (struct NameList
*) p
->First
;
11944 struct AmiPragma ap
;
11945 memset(&ap
, 0, sizeof(struct AmiPragma
));
11946 ap
.FuncName
= t
->NormName
;
11949 ap
.Args
[0].ArgName
= (args
? "args" : "tags");
11950 if(!MakeTagFunction(&ap
))
11956 while(p2
&& (!p2
->PragName
|| strcmp(p2
->PragName
, ap
.TagName
)))
11957 p2
= (struct NameList
*) p2
->List
.Next
;
11962 t
->Type
= (args
? NTP_ARGS
: NTP_TAGS
);
11963 t
->PragName
= ap
.TagName
;
11964 RemoveItem(p
, (struct ShortList
*) p2
);
11967 printf("GetName: name matches - %s _ %s\n", t
->NormName
, t
->PragName
);
11973 static void OptimizeFDData(struct PragData
*pd
)
11976 printf("OptimizeFDData\n");
11981 if(pd
->NumNames
> 1)
11983 struct ShortListRoot n
= {0,0,0}, p
= {0,0,0};
11984 struct NameList
*t
;
11985 while(pd
->Name
.First
) /* sorts in AmiCall and TagCall */
11987 t
= (struct NameList
*) pd
->Name
.First
;
11989 RemoveItem(&pd
->Name
, (struct ShortList
*) t
);
11990 AddItem(t
->PragName
? &p
: &n
, (struct ShortList
*) t
);
11995 t
= (struct NameList
*) n
.First
;
11996 while(p
.First
&& t
)
11998 if(!GetName(t
, &p
, 0))
12004 struct NameList
*t2
= (struct NameList
*) t
->List
.Next
;
12005 RemoveItem(&n
, (struct ShortList
*)t
);
12006 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12010 t
= (struct NameList
*) t
->List
.Next
;
12016 t
= (struct NameList
*) n
.First
;
12017 t
->PragName
= ((struct NameList
*)(p
.First
))->PragName
;
12018 RemoveItem(&n
, (struct ShortList
*) t
);
12020 printf("OptimizeFDData: names together - %s _ %s\n", t
->NormName
, t
->PragName
);
12022 t
->Type
= NTP_UNKNOWN
;
12028 t
= (struct NameList
*) p
.First
;
12029 i
= strlen(t
->PragName
);
12030 t
->NormName
= DupString(t
->PragName
, i
+1);
12031 t
->NormName
[i
++] = 'A';
12032 t
->NormName
[i
] = 0;
12033 t
->Type
= NTP_TAGS
;
12035 printf("OptimizeFDData: NormName created - %s _ %s\n", t
->NormName
, t
->PragName
);
12039 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12040 RemoveItem(&p
, p
.First
);
12044 AddItem(&pd
->Name
, n
.First
); /* add left NormNames */
12046 pd
= (struct PragData
*) pd
->List
.Next
;
12050 static uint32
MakeFD(struct PragList
*pl
)
12052 struct PragData
*pd
= (struct PragData
*) pl
->Data
.First
;
12056 printf("MakeFD\n");
12060 OptimizeFDData(pd
);
12062 printf("MakeFD: after Optimizing\n");
12064 DoOutput("##base _%s\n##bias %ld\n##public\n", pl
->Basename
, bias
);
12066 while(pd
&& Output_Error
)
12068 struct NameList
*n
= (struct NameList
*) pd
->Name
.First
;
12070 if(bias
!= pd
->Bias
)
12071 DoOutput("##bias %ld\n", (bias
= pd
->Bias
));
12075 strptr lastpar
= "last";
12078 if(n
->Type
== NTP_TAGS
)
12080 else if(n
->Type
== NTP_ARGS
)
12083 DoOutput("%s("/*)*/,n
->NormName
);
12085 DoOutput(/*(*/")()\n");
12088 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12089 DoOutput("par%ld,",i
+1);
12090 DoOutput(/*(*/"%s)("/*)*/, lastpar
);
12091 for(i
= 0; i
< pd
->NumArgs
-1; ++i
)
12092 DoOutput("%s,", RegNames
[pd
->ArgReg
[i
]]);
12093 DoOutput(/*(*/"%s)\n", RegNames
[pd
->ArgReg
[i
]]);
12095 if(n
->Type
== NTP_UNKNOWN
)
12098 for(i
= 0; n
->NormName
[i
] == n
->PragName
[i
]; ++i
)
12100 DoOutput("*tagcall");
12102 DoOutput("-%s", n
->NormName
+i
);
12104 DoOutput("+%s", n
->PragName
+i
);
12109 if((n
= (struct NameList
*) n
->List
.Next
))
12110 DoOutput("##bias %ld\n", pd
->Bias
);
12111 Flags
|= FLAG_DONE
;
12114 pd
= (struct PragData
*)pd
->List
.Next
; bias
+= BIAS_OFFSET
;
12117 DoOutput("##end\n");
12119 return Output_Error
;
12122 static uint32
AddFDData(struct ShortListRoot
*pls
, struct FDData
*fd
)
12124 struct NameList
*t
;
12125 struct PragList
*pl
= (struct PragList
*) pls
->First
;
12126 struct PragData
*pd
;
12128 while(pl
&& strcmp(pl
->Basename
, fd
->Basename
))
12129 pl
= (struct PragList
*) pl
->List
.Next
;
12134 printf("AddFDData: New PragList - %s\n", fd
->Basename
);
12136 if(!(pl
= (struct PragList
*) NewItem(pls
)))
12138 pl
->Basename
= fd
->Basename
;
12139 pl
->Data
.Size
= sizeof(struct PragData
);
12140 AddItem(pls
, (struct ShortList
*) pl
);
12143 if((pd
= (struct PragData
*) pl
->Data
.First
))
12145 while(pd
->List
.Next
&& ((struct PragData
*) pd
->List
.Next
)->Bias
12147 pd
= (struct PragData
*) pd
->List
.Next
;
12150 if(!pd
|| pd
->Bias
!= fd
->Bias
)
12152 struct PragData
*pd2
;
12154 printf("AddFDData: New PragData - %ld, %ld\n", fd
->Bias
, fd
->NumArgs
);
12156 if(!(pd2
= (struct PragData
*) NewItem(&pl
->Data
)))
12158 pd2
->Bias
= fd
->Bias
;
12159 memcpy(pd2
->ArgReg
, fd
->ArgReg
, MAXREG
);
12160 pd2
->NumArgs
= fd
->NumArgs
;
12161 pd2
->Name
.Size
= sizeof(struct NameList
);
12163 AddItem(&pl
->Data
, (struct ShortList
*) pd2
);
12164 else if(pd
->Bias
> fd
->Bias
) /* Insert at start */
12166 pd2
->List
.Next
= pl
->Data
.First
;
12167 pl
->Data
.First
= (struct ShortList
*) pd2
;
12169 else /* Insert the entry */
12171 pd2
->List
.Next
= pd
->List
.Next
;
12172 pd
->List
.Next
= (struct ShortList
*) pd2
;
12178 uint32 i
= fd
->NumArgs
;
12179 if(fd
->NumArgs
!= pd
->NumArgs
)
12182 printf("ArgNum %ld != %ld\n", fd
->NumArgs
, pd
->NumArgs
);
12184 return ERR_DIFFERENT_TO_PREVIOUS
;
12189 if(fd
->ArgReg
[i
] != pd
->ArgReg
[i
])
12192 printf("ArgReg %x != %x\n", fd
->ArgReg
[i
], pd
->ArgReg
[i
]);
12194 return ERR_DIFFERENT_TO_PREVIOUS
;
12199 t
= (struct NameList
*) pd
->Name
.First
; /* skips same names */
12200 while(t
&& (!(fd
->Mode
? t
->PragName
: t
->NormName
) ||
12201 strcmp(fd
->Name
, fd
->Mode
? t
->PragName
: t
->NormName
)))
12202 t
= (struct NameList
*) t
->List
.Next
;
12207 if(!(t
= (struct NameList
*) NewItem(&pd
->Name
)))
12210 t
->PragName
= fd
->Name
;
12212 t
->NormName
= fd
->Name
;
12213 AddItem(&pd
->Name
, (struct ShortList
*) t
);
12216 printf("AddFDData: New NameList - %s\n", fd
->Name
);
12221 static string
GetHexValue(string data
)
12224 return (string
) (data
- 'a' + 10);
12225 else if(data
>= 'A')
12226 return (string
) (data
- 'A' + 10);
12228 return (string
) (data
- '0');
12231 static string
GetDoubleHexValue(strptr data
)
12233 return (string
)((GetHexValue(*data
)<<4)+GetHexValue(data
[1]));
12236 static uint32
GetLibData(struct FDData
*fd
)
12239 fd
->Name
= SkipBlanks(in
.pos
);
12240 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12241 in
.pos
= SkipBlanks(in
.pos
);
12242 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12243 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
)));
12244 if((fd
->NumArgs
= GetHexValue(*(--in
.pos
))) > MAXREGNF
- 2)
12245 return ERR_TO_MUCH_ARGUMENTS
;
12246 --in
.pos
; /* skips return register */
12247 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12249 if((fd
->ArgReg
[i
] = GetHexValue(*(--in
.pos
))) > REG_A5
)
12250 return ERR_EXPECTED_REGISTER_NAME
;
12255 static uint32
GetFlibData(struct FDData
*fd
)
12258 fd
->Name
= SkipBlanks(in
.pos
);
12259 in
.pos
= SkipName(fd
->Name
); *(in
.pos
++) = 0;
12260 in
.pos
= SkipBlanks(in
.pos
);
12261 fd
->Bias
= strtoul(in
.pos
, 0, 16);
12262 in
.pos
= SkipName(SkipBlanks(SkipName(in
.pos
))) - 2;
12263 if((fd
->NumArgs
= GetDoubleHexValue(in
.pos
)) > MAXREG
-2)
12264 return ERR_TO_MUCH_ARGUMENTS
;
12265 in
.pos
-= 2; /* skips return register */
12266 for(i
= 0; i
< fd
->NumArgs
; ++i
)
12269 if((fd
->ArgReg
[i
] = GetDoubleHexValue(in
.pos
)) >= MAXREG
)
12270 return ERR_EXPECTED_REGISTER_NAME
;
12271 else if(fd
->ArgReg
[i
] >= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12272 return ERR_FLOATARG_NOT_ALLOWED
;
12277 static uint32
GetAmiData(struct FDData
*fd
)
12280 in
.pos
= SkipBlanks(in
.pos
);
12281 if(*in
.pos
!= '('/*)*/)
12282 return ERR_EXPECTED_OPEN_BRACKET
;
12283 fd
->Basename
= ++in
.pos
;
12284 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12286 return ERR_EXPECTED_COMMA
;
12288 in
.pos
= SkipBlanks(++in
.pos
);
12289 if(!strncmp(in
.pos
, "0x", 2))
12290 fd
->Bias
= strtoul(in
.pos
+2, 0, 16);
12292 fd
->Bias
= strtoul(in
.pos
, 0, 10);
12294 in
.pos
= SkipBlanks(SkipName(in
.pos
));
12296 return ERR_EXPECTED_COMMA
;
12297 fd
->Name
= in
.pos
= SkipBlanks(++in
.pos
);
12298 in
.pos
= SkipBlanks(endptr
= SkipName(in
.pos
));
12299 if(*in
.pos
!= '('/*)*/)
12300 return ERR_EXPECTED_OPEN_BRACKET
;
12302 in
.pos
= SkipBlanks(++in
.pos
);
12303 if(*in
.pos
== /*(*/')')
12306 while(*in
.pos
!= /*(*/')')
12309 in
.pos
= SkipBlanks(in
.pos
+1);
12311 for(i
= 0; i
< REG_FP0
; i
++)
12312 if(!strnicmp(RegNames
[i
], in
.pos
, 2))
12316 for(; i
< MAXREG
; i
++)
12317 if(!strnicmp(RegNames
[i
], in
.pos
, 3))
12322 return ERR_EXPECTED_REGISTER_NAME
;
12323 else if(i
>= REG_FP0
&& (Flags
& FLAG_NOFPU
))
12324 return ERR_FLOATARG_NOT_ALLOWED
;
12326 fd
->ArgReg
[fd
->NumArgs
] = i
; ++fd
->NumArgs
;
12328 if(fd
->NumArgs
> MAXREG
-2)
12329 return ERR_TO_MUCH_ARGUMENTS
;
12331 in
.pos
= SkipBlanks(in
.pos
+(i
>= REG_FP0
? 3 : 2));
12333 if(*in
.pos
!= ',' && *in
.pos
!= /*(*/')')
12334 return ERR_EXPECTED_CLOSE_BRACKET
;
12336 in
.pos
= SkipBlanks(in
.pos
+1);
12337 if(*in
.pos
!= /*(*/')')
12338 return ERR_EXPECTED_CLOSE_BRACKET
;
12342 static uint32
CreateFDFile(void)
12344 struct ShortListRoot pl
= {0, 0, sizeof(struct PragList
)};
12345 uint32 linenum
, err
= 0, skip
;
12348 ptr
= p2
= args
.infile
;
12351 if(*p2
== '/' || *p2
== ':' || *p2
== '\\')
12355 for(p2
= ptr
; *p2
&& *p2
!= '_' && *p2
!= '.'; ++p2
)
12359 ShortBaseName
= ptr
;
12363 for(linenum
= 1; in
.pos
< in
.buf
+ in
.size
; ++linenum
)
12365 in
.pos
= SkipBlanks(in
.pos
);
12366 if(!strncmp("#pragma", in
.pos
, 7))
12371 memset(&fd
, 0, sizeof(struct FDData
));
12373 in
.pos
= SkipBlanks(in
.pos
+7);
12374 if(!strncmp("tagcall", in
.pos
, 7))
12377 in
.pos
= SkipBlanks(in
.pos
+7);
12378 if(*in
.pos
== '(' /*)*/) /* Storm method */
12379 err
= GetAmiData(&fd
);
12380 else /* SAS method */
12382 fd
.Basename
= in
.pos
;
12383 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12384 err
= GetLibData(&fd
);
12387 else if(!strncmp("amicall", in
.pos
, 7)) /* Storm method */
12390 err
= GetAmiData(&fd
);
12392 else if(!strncmp("libcall", in
.pos
, 7)) /* SAS method */
12394 fd
.Basename
= SkipBlanks(in
.pos
+7);
12395 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12396 err
= GetLibData(&fd
);
12398 else if(!strncmp("flibcall", in
.pos
, 8)) /* SAS method */
12400 fd
.Basename
= SkipBlanks(in
.pos
+8);
12401 in
.pos
= SkipName(fd
.Basename
); *(in
.pos
++) = 0;
12402 err
= GetFlibData(&fd
);
12404 else if(!strncmp("syscall", in
.pos
, 7)) /* SAS method */
12406 fd
.Basename
= "SysBase";
12407 err
= GetLibData(&fd
);
12413 DoError(err
, linenum
);
12416 else if((err
= AddFDData(&pl
, &fd
)))
12419 DoError(err
, linenum
);
12423 while(*(in
.pos
++)) /* jumps to first char of next line */
12429 struct PragList
*p
= (struct PragList
*) pl
.First
;
12437 text
= ShortBaseName
; i
= strlen(text
);
12441 text
= p
->Basename
; i
= strlen(text
)-4;
12444 to
= DupString(text
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12445 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12460 i
= strlen(p
->Basename
) - 4;
12461 to
= DupString(p
->Basename
, i
+ sizeof(FDFILEEXTENSION
) - 1);
12462 memcpy(to
+i
, FDFILEEXTENSION
, sizeof(FDFILEEXTENSION
));
12469 p
= (struct PragList
*) p
->List
.Next
;
12477 #ifdef FD2PRAGMA_READARGS
12478 #include <proto/dos.h>
12480 /* undefine OS4 HUNKNAME macro */
12485 #define PARAM "FROM=INFILE/A,SPECIAL/N,MODE/N," \
12486 "TO/K,ABI/K,CLIB/K,COPYRIGHT/K,HEADER/K,HUNKNAME/K," \
12487 "BASENAME/K,LIBTYPE/K,LIBNAME/K,PRIORITY/N/K," \
12488 "PREFIX/K,SUBPREFIX/K,PREMACRO/K," \
12489 "AUTOHEADER/S,COMMENT/S,EXTERNC/S,FPUONLY/S," \
12491 "NOFPU/S,NOPPC/S,NOPPCREGNAME/S,NOSYMBOL/S," \
12492 "ONLYCNAMES/S,OPT040/S,PPCONLY/S," \
12493 "PRIVATE/S,SECTION/S,SMALLCODE/S,SMALLDATA/S," \
12494 "SMALLTYPES/S,SORTED/S,SYSTEMRELEASE/S,USESYSCALL/S," \
12522 uint32 NOPPCREGNAME
;
12533 uint32 SYSTEMRELEASE
;
12538 static const strptr helptext
=
12539 "INFILE: the input file which should be used\n"
12540 "SPECIAL: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12541 "\t 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12542 "\t 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12543 "\t 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12544 "\t 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12545 "\t 6 - pragma for all compilers [default]\n"
12546 "\t 7 - all compilers with pragma to inline redirect for GCC\n"
12547 "\t10 - stub-functions for C - C text\n"
12548 "\t11 - stub-functions for C - assembler text\n"
12549 "\t12 - stub-functions for C - link library\n"
12550 "\t13 - defines and link library for local library base (register call)\n"
12551 "\t14 - defines and link library for local library base (stack call)\n"
12552 "\t15 - stub-functions for Pascal - assembler text\n"
12553 "\t16 - stub-functions for Pascal - link library\n"
12554 "\t17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12555 "\t18 - module for AmigaE\n"
12556 "\t20 - assembler lvo _lvo.i file\n"
12557 "\t21 - assembler lvo _lib.i file\n"
12558 "\t22 - assembler lvo _lvo.i file no XDEF\n"
12559 "\t23 - assembler lvo _lib.i file no XDEF\n"
12560 "\t24 - assembler lvo link library\n"
12561 "\t30 - proto file with pragma/..._lib.h call\n"
12562 "\t31 - proto file with pragma/..._pragmas.h call\n"
12563 "\t32 - proto file with pragmas/..._lib.h call\n"
12564 "\t33 - proto file with pragmas/..._pragmas.h call\n"
12565 "\t34 - proto file with local/..._loc.h call\n"
12566 "\t35 - proto file for all compilers (VBCC stubs)\n"
12567 "\t36 - proto file for GNU-C compiler only\n"
12568 "\t37 - proto file without lib definitions\n"
12569 "\t38 - proto file for all compilers (VBCC inline)\n"
12570 "\t39 - proto file with special PPC related checks\n"
12571 "\t40 - GCC inline file (preprocessor based)\n"
12572 "\t41 - GCC inline file (old type - inline based)\n"
12573 "\t42 - GCC inline file (library stubs)\n"
12574 "\t43 - GCC inline file (new style - macro)\n"
12575 "\t44 - GCC inline file (new style - inline)\n"
12576 "\t45 - GCC inline file (new style - inline with include lines)\n"
12577 "\t46 - GCC inline file (preprocessor based, direct)\n"
12578 "\t47 - GCC inline file (new style, direct)\n"
12579 "\t48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12580 "\t50 - GCC inline files for PowerUP (preprocessor based)\n"
12581 "\t51 - GCC inline files for PowerUP (old type - inline based)\n"
12582 "\t52 - GCC inline files for PowerUP (library stubs)\n"
12583 "\t53 - SAS-C include file for PowerUP\n"
12584 "\t54 - Proto file for PowerUP\n"
12585 "\t60 - FPC pascal unit text\n"
12586 "\t70 - VBCC inline files\n"
12587 "\t71 - VBCC WOS stub-functions - assembler text\n"
12588 "\t72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12589 "\t73 - VBCC WOS stub-functions - link library\n"
12590 "\t74 - VBCC WOS stub-functions - link library (libbase)\n"
12591 "\t75 - VBCC PowerUP stub-functions - assembler text\n"
12592 "\t76 - VBCC PowerUP stub-functions - link library\n"
12593 "\t77 - VBCC WOS inline files\n"
12594 "\t78 - VBCC MorphOS stub-functions - link library\n"
12595 "\t79 - VBCC old inline files\n"
12596 "\t80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12597 "\t81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12598 "\t82 - pragma/proto redirect (xxx.h, GCC)\n"
12599 "\t83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12600 "\t90 - stub-functions for C - assembler text (multiple files)\n"
12601 "\t91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12602 "\t92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12603 "\t93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12604 " 100 - PPC assembler lvo file\n"
12605 " 101 - PPC assembler lvo file no XDEF\n"
12606 " 102 - PPC assembler lvo ELF link library\n"
12607 " 103 - PPC assembler lvo EHF link library\n"
12608 " 104 - PPC V.4-ABI assembler file\n"
12609 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12610 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12611 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12613 " 111 - CLIB file\n"
12614 " 112 - SFD file\n"
12615 " 120 - VBCC auto libopen files (C source)\n"
12616 " 121 - VBCC auto libopen files (m68k link library)\n"
12617 " 122 - VBCC MorphOS inline files\n"
12618 " 123 - VBCC new MorphOS inline files\n"
12619 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12620 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12621 " 132 - GCC inline files for MorphOS (library stubs)\n"
12622 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12623 " 134 - MorphOS gate stubs\n"
12624 " 135 - MorphOS gate stubs (prelib)\n"
12625 " 136 - MorphOS gate stubs (postlib)\n"
12626 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12627 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12628 " 140 - OS4 XML file\n"
12629 " 141 - OS4 PPC->M68K cross-call stubs\n"
12630 " 142 - OS4 M68K->PPC cross-call stubs\n"
12631 " 200 - FD file (source is a pragma file!)\n"
12632 "MODE: SPECIAL 1-7:\n"
12633 " 1: _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12634 " 2: _PRAGMAS_..._LIB_H definition method\n"
12635 " 3: _PRAGMAS_..._PRAGMAS_H definition method\n"
12636 " 4: no definition\n"
12637 " SPECIAL 11-14,40-45,50-53,70-76,78,90-91,111-112,122,\n"
12639 " 1: all functions, normal interface\n"
12640 " 2: only tag-functions, tagcall interface\n"
12641 " 3: all functions, normal and tagcall interface [default]\n"
12642 "TO: the destination directory (self creation of filename)\n"
12643 "ABI: set ABI type (m68k|ppc|ppc0|ppc2)\n"
12644 "CLIB: name of the prototypes file in clib directory\n"
12645 "COPYRIGHT: the copyright text for CLIB files\n"
12646 "HEADER: inserts given file into header of created file (\"\" is scan)\n"
12647 "HUNKNAME: use this name for HUNK_NAME instead of default 'text'\n"
12648 "BASENAME: name of library base without '_'\n"
12649 "LIBNAME: name of the library (.e.g. dos.library)\n"
12650 "LIBTYPE: type of base library structure\n"
12651 "PRIORITY: priority for auto open files\n"
12652 "PREFIX: MorphOS gate prefix\n"
12653 "SUBPREFIX: MorphOS gate sub prefix\n"
12654 "PREMACRO: MorphOS gate file start macro\n"
12656 "AUTOHEADER add the typical automatic generated header\n"
12657 "COMMENT: copy comments found in input file\n"
12658 "EXTERNC: add a #ifdef __cplusplus ... statement to pragma file\n"
12659 "FPUONLY: work only with functions using FPU register arguments\n"
12660 "NEWSYNTAX: uses new Motorola syntax for asm files\n"
12661 "NOFPU: disable usage of FPU register arguments\n"
12662 "NOPPC: disable usage of PPC-ABI functions\n"
12663 "NOPPCREGNAME: do not add 'r' to PPC register names\n"
12664 "NOSYMBOL: prevents creation of SYMBOL hunks for link libraries\n"
12665 "ONLYCNAMES: do not create C++ or ASM names\n"
12666 "OPT040: optimize for 68040, do not use MOVEM for stubs\n"
12667 "PPCONLY: only use PPC-ABI functions\n"
12668 "PRIVATE: includes private declared functions\n"
12669 "SECTION: add section statements to asm texts\n"
12670 "SMALLCODE: generate small code link libraries or assembler text\n"
12671 "SMALLDATA: generate small data link libraries or assembler text\n"
12672 "SMALLTYPES: allow 8 and 16 bit types in registers\n"
12673 "SORTED: sort generated files by name and not by bias value\n"
12674 "SYSTEMRELEASE: special handling of comments for system includes\n"
12675 "USESYSCALL: uses syscall pragma instead of libcall SysBase\n"
12676 "VOIDBASE: library bases are of type void *\n";
12678 /* print the help text */
12679 static void printhelp(void)
12681 printf("%s\n%s\n\n%s", version
+6, PARAM
, helptext
);
12685 /* initializes the arguments and starts argument parsing */
12686 static void GetArgs(int argc
, char **argv
)
12688 struct RDArgs
*rda
;
12689 struct AmiArg amiargs
;
12692 if((rda
= (struct RDArgs
*) AllocDosObject(DOS_RDARGS
, 0)))
12694 rda
->RDA_ExtHelp
= helptext
;
12695 memset(&amiargs
, 0, sizeof(struct AmiArg
));
12696 if(ReadArgs(PARAM
, (int32
*) &amiargs
, rda
))
12701 l
= strlen(amiargs
.TO
? amiargs
.TO
: "") + 1
12702 + strlen(amiargs
.CLIB
? amiargs
.CLIB
: "") + 1
12703 + strlen(amiargs
.HEADER
? amiargs
.HEADER
: "") + 1
12704 + strlen(amiargs
.ABI
? amiargs
.ABI
: "") + 1
12705 + strlen(amiargs
.HUNKNAME
? amiargs
.HUNKNAME
: "") + 1
12706 + strlen(amiargs
.BASENAME
? amiargs
.BASENAME
: "") + 1
12707 + strlen(amiargs
.LIBTYPE
? amiargs
.LIBTYPE
: "") + 1
12708 + strlen(amiargs
.LIBNAME
? amiargs
.LIBNAME
: "") + 1
12709 + strlen(amiargs
.COPYRIGHT
? amiargs
.COPYRIGHT
: "") + 1
12710 + strlen(amiargs
.PREFIX
? amiargs
.PREFIX
: "") + 1
12711 + strlen(amiargs
.SUBPREFIX
? amiargs
.SUBPREFIX
: "") + 1
12712 + strlen(amiargs
.PREMACRO
? amiargs
.PREMACRO
: "") + 1
12713 + strlen(amiargs
.INFILE
) + 1;
12714 if((d
= AllocListMem(l
)))
12718 s
= amiargs
.INFILE
;
12719 args
.infile
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12720 if((s
= amiargs
.TO
))
12722 args
.to
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12724 if((s
= amiargs
.HEADER
))
12726 args
.header
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12728 if((s
= amiargs
.CLIB
))
12730 args
.clib
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12732 if((s
= amiargs
.HUNKNAME
))
12734 hunkname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12736 if((s
= amiargs
.BASENAME
))
12738 Flags
|= FLAG_BASENAME
;
12739 BaseName
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12741 if((s
= amiargs
.LIBTYPE
))
12743 Flags2
|= FLAG2_LIBTYPE
;
12744 libtype
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12746 if((s
= amiargs
.LIBNAME
))
12748 Flags2
|= FLAG2_LIBNAME
;
12749 libname
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12751 if((s
= amiargs
.PREFIX
))
12753 prefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12755 if((s
= amiargs
.SUBPREFIX
))
12757 subprefix
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12759 if((s
= amiargs
.PREMACRO
))
12761 premacro
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12763 if((s
= amiargs
.COPYRIGHT
))
12765 Copyright
= d
; while(*s
) *(d
++) = *(s
++); *(d
++) = 0;
12767 if((s
= amiargs
.ABI
))
12769 defabi
= d
; while(*s
) *(d
++) = *(s
++); *d
= 0;
12771 if(amiargs
.EXTERNC
) Flags
^= FLAG_EXTERNC
;
12772 if(amiargs
.PRIVATE
) Flags
^= FLAG_PRIVATE
;
12773 if(amiargs
.NEWSYNTAX
) Flags
^= FLAG_NEWSYNTAX
;
12774 if(amiargs
.SMALLDATA
) Flags
^= FLAG_SMALLDATA
;
12775 if(amiargs
.SMALLCODE
) Flags2
^= FLAG2_SMALLCODE
;
12776 if(amiargs
.SMALLTYPES
) Flags2
^= FLAG2_SMALLTYPES
;
12777 if(amiargs
.USESYSCALL
) Flags
^= FLAG_SYSCALL
;
12778 if(amiargs
.OPT040
) Flags
^= FLAG_NOMOVEM
;
12779 if(amiargs
.NOFPU
) Flags
^= FLAG_NOFPU
;
12780 if(amiargs
.FPUONLY
) Flags
^= FLAG_FPUONLY
;
12781 if(amiargs
.NOPPC
) Flags
^= FLAG_NOPPC
;
12782 if(amiargs
.NOSYMBOL
) Flags
^= FLAG_NOSYMBOL
;
12783 if(amiargs
.PPCONLY
) Flags
^= FLAG_PPCONLY
;
12784 if(amiargs
.SECTION
) Flags
^= FLAG_ASMSECTION
;
12785 if(amiargs
.COMMENT
) Flags
^= FLAG_DOCOMMENT
;
12786 if(amiargs
.SORTED
) Flags
^= FLAG_SORTED
;
12787 if(amiargs
.ONLYCNAMES
) Flags
^= FLAG_ONLYCNAMES
;
12788 if(amiargs
.SYSTEMRELEASE
) Flags2
^= FLAG2_SYSTEMRELEASE
;
12789 if(amiargs
.VOIDBASE
) Flags2
^= FLAG2_VOIDBASE
;
12790 if(amiargs
.NOPPCREGNAME
) PPCRegPrefix
= "";
12791 if(amiargs
.AUTOHEADER
) Flags2
^= FLAG2_AUTOHEADER
;
12792 if(amiargs
.SPECIAL
)
12793 args
.special
= *amiargs
.SPECIAL
;
12795 args
.mode
= *amiargs
.MODE
;
12796 if(amiargs
.PRIORITY
)
12797 priority
= *amiargs
.PRIORITY
;
12802 PrintFault(IoErr(), 0);
12803 FreeDosObject(DOS_RDARGS
, rda
);
12812 static const strptr helptext
=
12814 " -i,--infile <input filename>\n"
12815 " -s,--special <number>\n"
12816 " -m,--mode <number>\n"
12817 " -t,--to <destination directory>\n"
12818 " -a,--abi <m68k|ppc|ppc0|ppc2>\n"
12819 " -c,--clib <clib prototypes filename>\n"
12820 " -d,--header <header file or \"\">\n"
12821 " -i,--libname <name of library>\n"
12822 " -n,--hunkname <name of HUNK_NAME, default is 'text'>\n"
12823 " -b,--basename <name of library base without '_'>\n"
12824 " -l,--libtype <name of base library type>\n"
12825 " -p,--priority <priority for auto open files>\n"
12826 " -r,--copyright<copyright text>\n"
12827 " --prefix <MorphOS gate prefix>\n"
12828 " --subprefix<MorphOS gate sub prefix>\n"
12829 " --premacro <MorphOS gate file start macro>\n"
12832 "--autoheader add the typical automatic generated header\n"
12833 "--comment copy comments found in input file\n"
12834 "--externc add a #ifdef __cplusplus ... statement to pragma file\n"
12835 "--fpuonly work only with functions using FPU register arguments\n"
12836 "--newsyntax uses new Motorola syntax for asm files\n"
12837 "--nofpu disable usage of FPU register arguments\n"
12838 "--noppc disable usage of PPC-ABI functions\n"
12839 "--noppcregname do not add 'r' to PPC register names\n"
12840 "--nosymbol prevents creation of SYMBOL hunks for link libraries\n"
12841 "--onlycnames do not create C++ or ASM names\n"
12842 "--opt040 optimize for 68040, do not use MOVEM for stubs\n"
12843 "--ppconly only use PPC-ABI functions\n"
12844 "--private includes private declared functions\n"
12845 "--section add section statements to asm texts\n"
12846 "--smallcode generate small code link libraries or assembler text\n"
12847 "--smalldata generate small data link libraries or assembler text\n"
12848 "--smalltypes allow 8 and 16 bit types in registers\n"
12849 "--sorted sort generated files by name and not by bias value\n"
12850 "--systemrelease special handling of comments for system includes\n"
12851 "--usesyscall uses syscall pragma instead of libcall SysBase\n"
12852 "--voidbase library bases are of type void *\n"
12854 "special: 1 - Aztec compiler (xxx_lib.h, MODE 2, AMICALL)\n"
12855 " 2 - DICE compiler (xxx_pragmas.h, MODE 3, LIBCALL)\n"
12856 " 3 - SAS compiler (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
12857 " 4 - MAXON compiler (xxx_lib.h, MODE 1, AMICALL)\n"
12858 " 5 - STORM compiler (xxx_lib.h, MODE 1, AMITAGS,AMICALL)\n"
12859 " 6 - pragma for all compilers [default]\n"
12860 " 7 - all compilers with pragma to inline redirect for GCC\n"
12861 " 10 - stub-functions for C - C text\n"
12862 " 11 - stub-functions for C - assembler text\n"
12863 " 12 - stub-functions for C - link library\n"
12864 " 13 - defines and link library for local library base (register call)\n"
12865 " 14 - defines and link library for local library base (stack call)\n"
12866 " 15 - stub-functions for Pascal - assembler text\n"
12867 " 16 - stub-functions for Pascal - link library\n"
12868 " 17 - BMAP file for AmigaBASIC and MaxonBASIC\n"
12869 " 18 - module for AmigaE\n"
12870 " 20 - assembler lvo _lvo.i file\n"
12871 " 21 - assembler lvo _lib.i file\n"
12872 " 22 - assembler lvo _lvo.i file no XDEF\n"
12873 " 23 - assembler lvo _lib.i file no XDEF\n"
12874 " 24 - assembler lvo link library\n"
12875 " 30 - proto file with pragma/..._lib.h call\n"
12876 " 31 - proto file with pragma/..._pragmas.h call\n"
12877 " 32 - proto file with pragmas/..._lib.h call\n"
12878 " 33 - proto file with pragmas/..._pragmas.h call\n"
12879 " 34 - proto file with local/..._loc.h call\n"
12880 " 35 - proto file for all compilers (VBCC stubs)\n"
12881 " 36 - proto file for GNU-C compiler only\n"
12882 " 37 - proto file without lib definitions\n"
12883 " 38 - proto file for all compilers (VBCC inline)\n"
12884 " 39 - proto file with special PPC related checks\n"
12885 " 40 - GCC inline file (preprocessor based)\n"
12886 " 41 - GCC inline file (old type - inline based)\n"
12887 " 42 - GCC inline file (library stubs)\n"
12888 " 43 - GCC inline file (new style - macro)\n"
12889 " 44 - GCC inline file (new style - inline)\n"
12890 " 45 - GCC inline file (new style - inline with include lines)\n"
12891 " 46 - GCC inline file (preprocessor based, direct)\n"
12892 " 47 - GCC inline file (new style, direct)\n"
12893 " 48 - GCC inline file (preprocessor based, direct, StormGCC)\n"
12894 " 50 - GCC inline files for PowerUP (preprocessor based)\n"
12895 " 51 - GCC inline files for PowerUP (old type - inline based)\n"
12896 " 52 - GCC inline files for PowerUP (library stubs)\n"
12897 " 53 - SAS-C include file for PowerUP\n"
12898 " 54 - Proto file for PowerUP\n"
12899 " 60 - FPC pascal unit text\n"
12900 " 70 - VBCC inline files\n"
12901 " 71 - VBCC WOS stub-functions - assembler text\n"
12902 " 72 - VBCC WOS stub-functions - assembler text (libbase)\n"
12903 " 73 - VBCC WOS stub-functions - link library\n"
12904 " 74 - VBCC WOS stub-functions - link library (libbase)\n"
12905 " 75 - VBCC PowerUP stub-functions - assembler text\n"
12906 " 76 - VBCC PowerUP stub-functions - link library\n"
12907 " 77 - VBCC WOS inline files\n"
12908 " 78 - VBCC MorphOS stub-functions - link library\n"
12909 " 79 - VBCC old inline files\n"
12910 " 80 - pragma/proto redirect (xxx_pragmas.h, SAS/Dice)\n"
12911 " 81 - pragma/proto redirect (xxx_lib.h, Aztec/Maxon/Storm)\n"
12912 " 82 - pragma/proto redirect (xxx.h, GCC)\n"
12913 " 83 - pragma/proto redirect (xxx_protos.h, VBCC)\n"
12914 " 90 - stub-functions for C - assembler text (multiple files)\n"
12915 " 91 - VBCC PowerUP stub-functions - assembler text (multiple files)\n"
12916 " 92 - VBCC WOS stub-functions - assembler text (multiple files)\n"
12917 " 93 - VBCC MorphOS stub-functions - assembler text (multiple files)\n"
12918 " 100 - PPC assembler lvo file\n"
12919 " 101 - PPC assembler lvo file no XDEF\n"
12920 " 102 - PPC assembler lvo ELF link library\n"
12921 " 103 - PPC assembler lvo EHF link library\n"
12922 " 104 - PPC V.4-ABI assembler file\n"
12923 " 105 - PPC V.4-ABI assembler file no XDEF\n"
12924 " 106 - PPC V.4-ABI assembler lvo ELF link library\n"
12925 " 107 - PPC V.4-ABI assembler lvo EHF link library\n"
12927 " 111 - CLIB file\n"
12928 " 112 - SFD file\n"
12929 " 120 - VBCC auto libopen files (C source)\n"
12930 " 121 - VBCC auto libopen files (m68k link library)\n"
12931 " 122 - VBCC MorphOS inline files\n"
12932 " 123 - VBCC new MorphOS inline files\n"
12933 " 130 - GCC inline files for MorphOS (preprocessor based)\n"
12934 " 131 - GCC inline files for MorphOS (old type - inline based)\n"
12935 " 132 - GCC inline files for MorphOS (library stubs)\n"
12936 " 133 - GCC inline files for MorphOS (library stubs, direct varargs)\n"
12937 " 134 - MorphOS gate stubs\n"
12938 " 135 - MorphOS gate stubs (prelib)\n"
12939 " 136 - MorphOS gate stubs (postlib)\n"
12940 " 137 - MorphOS gate stubs (reglib, prelib)\n"
12941 " 138 - MorphOS gate stubs (reglib, postlib)\n"
12942 " 140 - OS4 XML file\n"
12943 " 141 - OS4 PPC->M68K cross-call stubs\n"
12944 " 142 - OS4 M68K->PPC cross-call stubs\n"
12945 " 200 - FD file (source is a pragma file!)\n"
12946 "mode: special 1-7\n"
12947 " 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
12948 " 2 - _PRAGMAS_..._LIB_H definition method\n"
12949 " 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
12950 " 4 - no definition\n"
12951 " special 11-14,40-45,50-53,70-76,78,90-93,111-112,122,\n"
12953 " 1 - all functions, normal interface\n"
12954 " 2 - only tag-functions, tagcall interface\n"
12955 " 3 - all functions, normal and tagcall interface [default]\n";
12957 /* print the help text */
12958 static void printhelp(void)
12960 printf("%s\n%s", version
+6, helptext
);
12973 ARG_HELP
, ARG_INFILE
, ARG_SPECIAL
, ARG_MODE
, ARG_TO
, ARG_CLIB
, ARG_ABI
, ARG_COPYRIGHT
,
12974 ARG_HEADER
, ARG_HUNKNAME
, ARG_BASENAME
, ARG_LIBTYPE
,
12975 ARG_COMMENT
, ARG_EXTERNC
, ARG_FPUONLY
, ARG_NEWSYNTAX
, ARG_NOFPU
, ARG_NOPPC
,
12976 ARG_NOSYMBOL
, ARG_ONLYCNAMES
, ARG_OPT040
, ARG_PPCONLY
, ARG_PRIVATE
, ARG_SECTION
,
12977 ARG_SMALLDATA
, ARG_SORTED
, ARG_USESYSCALL
, ARG_NOPPCREGNAME
,
12978 ARG_SYSTEMRELEASE
, ARG_PRIORITY
, ARG_LIBNAME
, ARG_SMALLCODE
, ARG_VOIDBASE
,
12979 ARG_PREFIX
, ARG_SUBPREFIX
, ARG_PREMACRO
, ARG_SMALLTYPES
, ARG_AUTOHEADER
12982 /* argument definition array */
12983 static const struct ArgData argtexts
[] = {
12984 {"help", 'h', 4, ARG_HELP
},
12985 {"infile", 'i', 6, ARG_INFILE
},
12986 {"special", 's', 7, ARG_SPECIAL
},
12987 {"mode", 'm', 4, ARG_MODE
},
12988 {"to", 't', 2, ARG_TO
},
12989 {"clib", 'c', 4, ARG_CLIB
},
12990 {"abi", 'a', 3, ARG_ABI
},
12991 {"copyright", 'r', 9, ARG_COPYRIGHT
},
12992 {"header", 'd', 6, ARG_HEADER
},
12993 {"hunkname", 'n', 8, ARG_HUNKNAME
},
12994 {"basename", 'b', 8, ARG_BASENAME
},
12995 {"libtype", 'l', 7, ARG_LIBTYPE
},
12996 {"libname", 'i', 7, ARG_LIBNAME
},
12997 {"priority", 'p', 8, ARG_PRIORITY
},
12998 {"autoheader", 0, 10, ARG_AUTOHEADER
},
12999 {"comment", 0, 7, ARG_COMMENT
},
13000 {"externc", 0, 7, ARG_EXTERNC
},
13001 {"fpuonly", 0, 7, ARG_FPUONLY
},
13002 {"newsyntax", 0, 9, ARG_NEWSYNTAX
},
13003 {"nofpu", 0, 5, ARG_NOFPU
},
13004 {"noppc", 0, 5, ARG_NOPPC
},
13005 {"noppcregname", 0, 12, ARG_NOPPCREGNAME
},
13006 {"nosymbol", 0, 8, ARG_NOSYMBOL
},
13007 {"onlycnames", 0, 10, ARG_ONLYCNAMES
},
13008 {"opt040", 0, 6, ARG_OPT040
},
13009 {"ppconly", 0, 7, ARG_PPCONLY
},
13010 {"private", 0, 7, ARG_PRIVATE
},
13011 {"section", 0, 7, ARG_SECTION
},
13012 {"smalldata", 0, 9, ARG_SMALLDATA
},
13013 {"smalltypes", 0, 10, ARG_SMALLTYPES
},
13014 {"smallcode", 0, 9, ARG_SMALLCODE
},
13015 {"sorted", 0, 6, ARG_SORTED
},
13016 {"systemrelease", 0, 13, ARG_SYSTEMRELEASE
},
13017 {"usesyscall", 0, 10, ARG_USESYSCALL
},
13018 {"voidbase", 0, 8, ARG_VOIDBASE
},
13019 {"prefix", 0, 6, ARG_PREFIX
},
13020 {"subprefix", 0, 9, ARG_SUBPREFIX
},
13021 {"premacro", 0, 8, ARG_PREMACRO
},
13022 {0,0,0,0}, /* end marker */
13025 /* parse on argument entry, returns number of used entries, 0 for error, -1 for error without error printout */
13026 static uint32
ParseArgEntry(uint32 argc
, strptr
*argv
)
13028 uint32 numentries
= 1, l
;
13030 const struct ArgData
*ad
;
13032 if((*argv
)[0] != '-' || !(*argv
)[1])
13038 if((*argv
)[1] == ad
->ArgChar
|| ((*argv
)[1] == '-' && !strncmp(ad
->ArgName
, (*argv
)+2, ad
->ArgNameLen
)))
13046 case ARG_HELP
: printhelp(); break;
13047 case ARG_EXTERNC
: Flags
^= FLAG_EXTERNC
; break;
13048 case ARG_PRIVATE
: Flags
^= FLAG_PRIVATE
; break;
13049 case ARG_NEWSYNTAX
: Flags
^= FLAG_NEWSYNTAX
; break;
13050 case ARG_SMALLDATA
: Flags
^= FLAG_SMALLDATA
; break;
13051 case ARG_SMALLCODE
: Flags2
^= FLAG2_SMALLCODE
; break;
13052 case ARG_SMALLTYPES
: Flags2
^= FLAG2_SMALLTYPES
; break;
13053 case ARG_USESYSCALL
: Flags
^= FLAG_SYSCALL
; break;
13054 case ARG_OPT040
: Flags
^= FLAG_NOMOVEM
; break;
13055 case ARG_NOFPU
: Flags
^= FLAG_NOFPU
; break;
13056 case ARG_FPUONLY
: Flags
^= FLAG_FPUONLY
; break;
13057 case ARG_NOPPC
: Flags
^= FLAG_NOPPC
; break;
13058 case ARG_NOSYMBOL
: Flags
^= FLAG_NOSYMBOL
; break;
13059 case ARG_PPCONLY
: Flags
^= FLAG_PPCONLY
; break;
13060 case ARG_SECTION
: Flags
^= FLAG_ASMSECTION
; break;
13061 case ARG_COMMENT
: Flags
^= FLAG_DOCOMMENT
; break;
13062 case ARG_SORTED
: Flags
^= FLAG_SORTED
; break;
13063 case ARG_ONLYCNAMES
: Flags
^= FLAG_ONLYCNAMES
; break;
13064 case ARG_SYSTEMRELEASE
: Flags2
^= FLAG2_SYSTEMRELEASE
; break;
13065 case ARG_VOIDBASE
: Flags2
^= FLAG2_VOIDBASE
; break;
13066 case ARG_AUTOHEADER
: Flags2
^= FLAG2_AUTOHEADER
; break;
13067 case ARG_NOPPCREGNAME
: PPCRegPrefix
= "";
13069 a
= *argv
+((*argv
)[1] == '-' ? ad
->ArgNameLen
+2 : 2);
13072 if(argc
> 1) { a
= argv
[1]; numentries
= 2; }
13073 else { a
= 0; numentries
= 0;}
13083 a
[--l
] = 0; /* remove second " */
13087 case ARG_INFILE
: args
.infile
= a
; break;
13088 case ARG_COPYRIGHT
: Copyright
= a
; break;
13089 case ARG_TO
: args
.to
= a
; break;
13090 case ARG_ABI
: defabi
= a
; break;
13091 case ARG_CLIB
: args
.clib
= a
; break;
13092 case ARG_HEADER
: args
.header
= a
; break;
13093 case ARG_HUNKNAME
: hunkname
= a
; break;
13094 case ARG_PREFIX
: prefix
= a
; break;
13095 case ARG_SUBPREFIX
: subprefix
= a
; break;
13096 case ARG_PREMACRO
: premacro
= a
; break;
13097 case ARG_LIBTYPE
: libtype
= a
; Flags2
|= FLAG2_LIBTYPE
; break;
13098 case ARG_LIBNAME
: libname
= a
; Flags2
|= FLAG2_LIBNAME
; break;
13099 case ARG_BASENAME
: BaseName
= a
; Flags
|= FLAG_BASENAME
; break;
13101 args
.special
= strtoul(a
, &b
, 10);
13106 priority
= strtoul(a
, &b
, 10);
13111 args
.mode
= strtoul(a
, &b
, 10);
13112 if(*b
|| args
.mode
< 1 || args
.mode
> 3)
13121 /* initializes the arguments and starts argument parsing */
13122 static void GetArgs(int argc
, char **argv
)
13127 while(i
< argc
&& res
)
13129 if((j
= ParseArgEntry(argc
-i
, argv
+i
)) < 1)
13134 if(!res
|| !args
.infile
)
13140 static strptr
mygetfile(strptr name
, size_t *len
)
13145 if((infile
= fopen(name
, "rb")))
13147 if(!fseek(infile
, 0, SEEK_END
))
13149 *len
= ftell(infile
);
13150 if(!fseek(infile
, 0, SEEK_SET
))
13152 if((ptr
= AllocListMem(*len
+1)))
13156 printf("mygetfile: '%s' size %d\n", name
, *len
);
13158 if(fread(ptr
, *len
, 1, infile
) != 1)
13168 int main(int argc
, char **argv
)
13170 uint32 mode
= 0, pragmode
= PRAGMODE_PRAGLIB
, callmode
= TAGMODE_BOTH
;
13171 strptr amicall
= 0, libcall
= 0, amitags
= 0, libtags
= 0;
13173 size_t clibsize
= 0;
13175 GetArgs(argc
, argv
);
13177 if((tempbuf
= (uint8
*) AllocListMem(TEMPSIZE
)))
13179 if(!(in
.pos
= in
.buf
= mygetfile(args
.infile
, &in
.size
)))
13181 if(args
.special
== 200)
13183 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13188 sprintf((strptr
)tempbuf
, "%s" SFDFILEEXTENSION
, args
.infile
);
13189 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13191 sprintf((strptr
)tempbuf
, "%s" FDFILEEXTENSION
, args
.infile
);
13192 if(!(in
.pos
= in
.buf
= mygetfile((strptr
)tempbuf
, &in
.size
)))
13194 DoError(ERR_OPEN_FILE
, 0, args
.infile
);
13198 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13201 args
.infile
= DupString((strptr
) tempbuf
, strlen((strptr
) tempbuf
));
13204 printf("SourceFile: %s\n", args
.infile
);
13206 MakeLines(in
.pos
, in
.size
);
13208 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SORTED
)) /* is not possible to use both */
13210 DoError(ERR_SORTED_COMMENT
, 0);
13211 Flags
&= (~FLAG_SORTED
);
13214 if(args
.special
== 200)
13228 if(Flags2
& FLAG2_SFDMODE
)
13229 DoError(ERR_SFD_AND_CLIB
, 0);
13232 sprintf((strptr
)tempbuf
, "%s_protos.h", args
.clib
);
13233 if(!(clibbuf
= mygetfile(args
.clib
, &clibsize
)) && !(clibbuf
= mygetfile((strptr
)tempbuf
, &clibsize
)))
13235 DoError(ERR_OPEN_FILE
, 0, args
.clib
);
13238 ScanClibFile(clibbuf
, clibbuf
+clibsize
);
13242 if(!MakeShortBaseName())
13244 DoError(ERR_MISSING_SHORTBASENAME
, 0);
13248 /* WARN when requesting obsolete types! */
13249 switch(args
.special
)
13251 case 1: case 2: case 3: case 4: case 5: case 7:
13252 printf("You use obsolete data type %ld, better use type 6!\n", args
.special
);
13254 case 11: case 15: case 71: case 72: case 75:
13255 printf("You use obsolete assembler text type %ld, better use 90 to 99 or "
13256 "link libraries!\n", args
.special
);
13258 case 30: case 31: case 32: case 33: case 34: case 36: case 37: case 39:
13259 printf("You use obsolete proto type %ld, better us type 38 or 35!\n", args
.special
);
13262 printf("Obsolete inline file 79 used, better take type 70 instead!\n");
13266 if(args
.special
< 10) /* the pragma area is up to 9 */
13268 mode
= MODUS_PRAGMA
;
13269 sprintf(filename
, "%s_lib.h", ShortBaseName
);
13271 switch(args
.special
)
13274 case 1: pragmode
= PRAGMODE_PRAGSLIB
; amicall
= ""; break;
13275 case 2: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13276 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= ""; break;
13277 case 3: sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13278 pragmode
= PRAGMODE_PRAGSPRAGS
; libcall
= "";
13279 libtags
= "def " TEXT_SAS_60
; break;
13280 case 4: amicall
= ""; break;
13281 case 5: amicall
= amitags
= ""; break;
13282 case 7: Flags
|= FLAG_GNUPRAG
; /* no break ! */
13283 case 6: amicall
= " defined(" TEXT_AZTEC
") || defined("
13284 TEXT_MAXON
") || defined(" TEXT_STORM
")";
13285 libcall
= " defined(" TEXT_DICE
") || defined(" TEXT_SAS
")";
13286 libtags
= "def " TEXT_SAS_60
; amitags
="def " TEXT_STORM
; break;
13287 default: mode
= MODUS_ERROR
; break;
13290 if(args
.mode
> 0 && args
.mode
< 5)
13291 pragmode
= args
.mode
;
13293 else if(args
.special
< 20) /* the misc area is up to 19 */
13295 if(args
.mode
> 0 && args
.mode
< 4)
13296 callmode
= args
.mode
- 1;
13297 switch(args
.special
)
13299 case 10: mode
= MODUS_CSTUB
;
13300 sprintf(filename
, "%s_cstub.h", ShortBaseName
); break;
13301 case 11: mode
= MODUS_STUBTEXT
;
13302 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13303 case 12: mode
= MODUS_STUBCODE
;
13304 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13305 case 13: Flags
|= FLAG_LOCALREG
; /* no break ! */
13306 case 14: mode
= MODUS_LOCALDATA
;
13307 sprintf(filename
, "%s_loc.h", ShortBaseName
); break;
13308 case 15: mode
= MODUS_STUBTEXT
; callmode
= TAGMODE_NORMAL
;
13309 Flags
^= FLAG_PASCAL
;
13310 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13311 case 16: mode
= MODUS_STUBCODE
; callmode
= TAGMODE_NORMAL
;
13312 Flags
^= FLAG_PASCAL
;
13313 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13314 case 17: mode
= MODUS_BMAP
; callmode
= TAGMODE_NORMAL
;
13315 sprintf(filename
, "%s.bmap", ShortBaseName
); break;
13316 case 18: mode
= MODUS_EMODULE
;
13317 sprintf(filename
, "%s.m", ShortBaseName
); break;
13318 default: mode
= MODUS_ERROR
; break;
13321 else if(args
.special
< 30) /* the lvo area is up to 29 */
13323 switch(args
.special
)
13325 case 20: case 22: mode
= MODUS_LVO
+args
.special
-20;
13326 sprintf(filename
, "%s_lvo.i", ShortBaseName
); break;
13327 case 21: case 23: mode
= MODUS_LVO
+args
.special
-20;
13328 sprintf(filename
, "%s_lib.i", ShortBaseName
); break;
13329 case 24: mode
= MODUS_LVOLIB
;
13330 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13331 default: mode
= MODUS_ERROR
; break;
13334 else if(args
.special
< 40) /* the proto area is up to 39 */
13336 if(args
.special
< 40)
13338 mode
= MODUS_PROTO
+args
.special
-30;
13339 sprintf(filename
, "%s.h", ShortBaseName
);
13342 mode
= MODUS_ERROR
;
13344 else if(args
.special
< 50) /* the inline area is up to 49 */
13346 if(args
.mode
> 0 && args
.mode
< 4)
13347 callmode
= args
.mode
- 1;
13349 switch(args
.special
)
13351 case 40: case 41: case 42: case 43: case 44: case 45: case 46:
13353 mode
= MODUS_INLINE
+args
.special
-40;
13354 sprintf(filename
, "%s.h", ShortBaseName
); break;
13356 Flags
|= FLAG_STORMGCC
;
13357 /* the same mode as for 46, but additional flag */
13358 mode
= MODUS_INLINE
+args
.special
-40-2;
13359 sprintf(filename
, "%s.h", ShortBaseName
); break;
13360 default: mode
= MODUS_ERROR
; break;
13363 else if(args
.special
< 60) /* the PowerUP area is up to 59 */
13365 if(args
.mode
> 0 && args
.mode
< 4)
13366 callmode
= args
.mode
- 1;
13368 switch(args
.special
)
13370 case 50: case 51: case 52: mode
= MODUS_INLINE
+args
.special
-50;
13371 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_POWERUP
;
13374 sprintf(filename
, "%s_pragmas.h", ShortBaseName
);
13375 mode
= MODUS_SASPOWER
; break;
13377 sprintf(filename
, "%s.h", ShortBaseName
);
13378 mode
= MODUS_PROTOPOWER
; break;
13379 default: mode
= MODUS_ERROR
; break;
13382 else if(args
.special
< 70) /* the PASCAL stuff */
13384 if(args
.special
== 60)
13386 mode
= MODUS_PASCAL
;
13387 sprintf(filename
, "%s.pas", ShortBaseName
);
13390 mode
= MODUS_ERROR
;
13392 else if(args
.special
< 80) /* the VBCC stuff */
13394 if(args
.mode
> 0 && args
.mode
< 4)
13395 callmode
= args
.mode
- 1;
13397 switch(args
.special
)
13399 case 70: mode
= MODUS_VBCCINLINE
;
13400 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13401 case 71: case 72: case 75:
13402 mode
= MODUS_VBCC
+args
.special
-71;
13403 sprintf(filename
, "%s_stub.s", ShortBaseName
); break;
13405 mode
= MODUS_VBCC
+args
.special
-71;
13406 sprintf(filename
, "%s.lib", ShortBaseName
); break;
13408 mode
= MODUS_VBCCPUPLIB
;
13409 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13410 case 77: mode
= MODUS_VBCCWOSINLINE
;
13411 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13412 case 78: mode
= MODUS_VBCCMORPHCODE
;
13413 sprintf(filename
, "lib%s.a", ShortBaseName
); break;
13414 case 79: mode
= MODUS_VBCCINLINE
;
13415 Flags2
|= FLAG2_OLDVBCC
;
13416 callmode
= TAGMODE_NORMAL
;
13417 sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13418 default: mode
= MODUS_ERROR
; break;
13421 else if(args
.special
< 90) /* redirect stuff */
13423 mode
= MODUS_REDIRECT
;
13424 switch(args
.special
)
13426 case 80: sprintf(filename
, "%s_pragmas.h", ShortBaseName
); break;
13427 case 81: sprintf(filename
, "%s_lib.h", ShortBaseName
); break;
13428 case 82: sprintf(filename
, "%s.h", ShortBaseName
); break;
13429 case 83: sprintf(filename
, "%s_protos.h", ShortBaseName
); break;
13430 default: mode
= MODUS_ERROR
; break;
13433 else if(args
.special
< 100) /* multifile stuff */
13435 Flags
|= FLAG_SINGLEFILE
;
13436 switch(args
.special
)
13439 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13440 mode
= MODUS_ASMTEXTSF
; filenamefmt
= "%s.s";
13443 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13444 mode
= MODUS_VBCCPUPTEXTSF
; filenamefmt
= "%s.s";
13447 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13448 mode
= MODUS_VBCCWOSTEXTSF
; filenamefmt
= "%s.s";
13451 if(args
.mode
> 0 && args
.mode
< 4) callmode
= args
.mode
- 1;
13452 mode
= MODUS_VBCCMORPHTEXTSF
; filenamefmt
= "%s.s";
13454 default: mode
= MODUS_ERROR
; break;
13457 else if(args
.special
< 110) /* PPC lvo's */
13459 switch(args
.special
)
13461 case 100: case 101: mode
= MODUS_LVOPPC
+args
.special
-100;
13462 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13464 case 104: case 105: mode
= MODUS_LVOPPC
+args
.special
-104;
13465 Flags
|= FLAG_ABIV4
;
13466 sprintf(filename
, "%s_lib.i", ShortBaseName
);
13468 case 103: mode
= MODUS_LVOLIB
;
13469 sprintf(filename
, "%slvo.o", ShortBaseName
);
13471 case 107: mode
= MODUS_LVOLIB
;
13472 Flags
|= FLAG_ABIV4
;
13473 sprintf(filename
, "%slvo.o", ShortBaseName
);
13475 case 102: mode
= MODUS_LVOLIBPPC
;
13476 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13477 case 106: mode
= MODUS_LVOLIBPPC
;
13478 Flags
|= FLAG_ABIV4
;
13479 sprintf(filename
, "%slvo.o", ShortBaseName
); break;
13480 default: mode
= MODUS_ERROR
; break;
13483 else if(args
.special
< 120) /* different files */
13485 if(args
.mode
> 0 && args
.mode
< 4)
13486 callmode
= args
.mode
- 1;
13488 switch(args
.special
)
13490 case 110: mode
= MODUS_FD
;
13491 sprintf(filename
, "%s_lib.fd", ShortBaseName
);
13492 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13494 DoError(ERR_SORTED_SFD_FD
, 0);
13495 Flags
&= (~FLAG_SORTED
);
13498 case 111: mode
= MODUS_CLIB
; Flags2
|= FLAG2_CLIBOUT
;
13499 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13501 case 112: mode
= MODUS_SFD
; Flags2
|= FLAG2_SFDOUT
;
13502 sprintf(filename
, "%s_lib.sfd", ShortBaseName
);
13506 DoError(ERR_ONLYTAGMODE_NOTALLOWED
, 0);
13509 if(Flags
& FLAG_SORTED
) /* is not possible to use here */
13511 DoError(ERR_SORTED_SFD_FD
, 0);
13512 Flags
&= (~FLAG_SORTED
);
13515 default: mode
= MODUS_ERROR
; break;
13518 else if(args
.special
< 130) /* auto libopen files */
13520 if(args
.mode
> 0 && args
.mode
< 4) /* for 122 */
13521 callmode
= args
.mode
- 1;
13523 switch(args
.special
)
13525 case 120: mode
= MODUS_GENAUTO
;
13526 sprintf(filename
, "%s_autoopenlib.c", ShortBaseName
);
13528 case 121: mode
= MODUS_GENAUTO
+(args
.special
-120);
13529 sprintf(filename
, "%s_autoopenlib.lib", ShortBaseName
);
13531 case 123: Flags2
|= FLAG2_SHORTPPCVBCCINLINE
; /* no break */
13532 case 122: mode
= MODUS_VBCCMORPHINLINE
;
13533 PPCRegPrefix
= ""; /* no "r" allowed */
13534 sprintf(filename
, "%s_protos.h", ShortBaseName
);
13536 default: mode
= MODUS_ERROR
; break;
13539 else if(args
.special
< 140) /* the MorphOS area is up to 139 */
13541 if(args
.mode
> 0 && args
.mode
< 4)
13542 callmode
= args
.mode
- 1;
13544 switch(args
.special
)
13546 case 130: case 131: case 132: mode
= MODUS_INLINE
+args
.special
-130;
13547 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13549 case 133: mode
= MODUS_INLINE
+2;
13550 sprintf(filename
, "%s.h", ShortBaseName
); Flags
|= FLAG_MORPHOS
;
13551 Flags2
|= FLAG2_DIRECTVARARGS
;
13553 case 134: mode
= MODUS_GATESTUBS
;
13554 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13556 case 135: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
;
13557 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13559 case 136: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
;
13560 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13562 case 137: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_PRELIB
|FLAG2_REGLIB
;
13563 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13565 case 138: mode
= MODUS_GATESTUBS
; Flags2
|= FLAG2_POSTLIB
|FLAG2_REGLIB
;
13566 sprintf(filename
, "%s_gates.h", ShortBaseName
);
13568 default: mode
= MODUS_ERROR
; break;
13571 else if(args
.special
< 150) /* the OS4 area is up to 139 */
13573 if(args
.mode
> 0 && args
.mode
< 4)
13574 callmode
= args
.mode
- 1;
13576 switch(args
.special
)
13580 sprintf(filename
, "%s.xml", ShortBaseName
);
13582 case 141: /* OS4 PPC->M68K cross-call stubs */
13583 mode
= MODUS_OS4_PPCSTUBS
;
13584 sprintf(filename
, "%s.c", ShortBaseName
);
13586 case 142: /* OS4 M68K->PPC cross-call stubs */
13587 mode
= MODUS_OS4_68KSTUBS
;
13588 sprintf(filename
, "%s_68k.s", ShortBaseName
);
13590 default: mode
= MODUS_ERROR
; break;
13593 if(Flags
& FLAG_SORTED
)
13596 if((Flags
& FLAG_DOCOMMENT
) && (Flags
& FLAG_SINGLEFILE
)) /* is not possible to use both */
13598 DoError(ERR_COMMENT_SINGLEFILE
, 0);
13599 Flags
&= (~FLAG_DOCOMMENT
);
13602 if(!mode
|| mode
== MODUS_ERROR
)
13605 /* These modes need BaseName always. */
13606 if(!BaseName
&& (mode
== MODUS_PRAGMA
|| mode
== MODUS_STUBTEXT
||
13607 mode
== MODUS_STUBCODE
|| mode
== MODUS_EMODULE
|| (mode
>= MODUS_GENAUTO
&&
13608 mode
<= MODUS_GENAUTO
+9)))
13610 DoError(ERR_MISSING_BASENAME
, 0);
13614 if(args
.header
&& args
.header
[0] && (args
.header
[0] != '@' || args
.header
[1]))
13616 HEADER
= mygetfile(args
.header
, &headersize
);
13620 if(!(Flags
& FLAG_SINGLEFILE
))
13622 if(!OpenDest(filename
))
13626 /* from here mode is used as return result */
13627 if(mode
>= MODUS_GENAUTO
)
13628 mode
= CreateGenAuto(filename
, mode
-MODUS_GENAUTO
);
13629 else if(mode
>= MODUS_LVOPPC
)
13630 mode
= CreateLVOFilePPC(mode
-MODUS_LVOPPC
);
13631 else if(mode
>= MODUS_VBCC
)
13632 mode
= CreateVBCC(mode
-MODUS_VBCC
, callmode
);
13633 else if(mode
>= MODUS_INLINE
)
13634 mode
= CreateInline(mode
-MODUS_INLINE
, callmode
);
13635 else if(mode
>= MODUS_PROTO
)
13636 mode
= CreateProtoFile(mode
-MODUS_PROTO
+1);
13637 else if(mode
>= MODUS_LVO
)
13638 mode
= CreateLVOFile(mode
-MODUS_LVO
+1);
13639 else if(mode
== MODUS_VBCCMORPHINLINE
)
13640 mode
= CreateVBCCInline(2, callmode
);
13641 else if(mode
== MODUS_XML
)
13642 mode
= CreateXML();
13643 else if(mode
== MODUS_OS4_PPCSTUBS
)
13644 mode
= CreateOS4PPC(callmode
);
13645 else if(mode
== MODUS_OS4_68KSTUBS
)
13646 mode
= CreateOS4M68K();
13647 else if(mode
== MODUS_GATESTUBS
)
13648 mode
= CreateGateStubs(callmode
);
13649 else if(mode
== MODUS_SFD
)
13650 mode
= CreateSFD(callmode
);
13651 else if(mode
== MODUS_CLIB
)
13652 mode
= CreateClib(callmode
);
13653 else if(mode
== MODUS_FD
)
13655 else if(mode
== MODUS_LVOLIBPPC
)
13656 mode
= CreateLVOLibPPC();
13657 else if(mode
== MODUS_VBCCMORPHCODE
)
13658 mode
= CreateVBCCMorphCode(callmode
);
13659 else if(mode
== MODUS_VBCCMORPHTEXTSF
) /* single files */
13660 mode
= CallFunc(callmode
, "\n%s", FuncVBCCMorphText
);
13661 else if(mode
== MODUS_VBCCWOSINLINE
)
13662 mode
= CreateVBCCInline(1, callmode
);
13663 else if(mode
== MODUS_VBCCWOSTEXTSF
) /* single files */
13664 mode
= CallFunc(callmode
, "\n%s", FuncVBCCWOSText
);
13665 else if(mode
== MODUS_VBCCPUPTEXTSF
) /* single files */
13666 mode
= CallFunc(callmode
, "\n%s", FuncVBCCPUPText
);
13667 else if(mode
== MODUS_ASMTEXTSF
) /* single files */
13668 mode
= CallFunc(callmode
, "\n%s", FuncAsmText
);
13669 else if(mode
== MODUS_REDIRECT
)
13670 mode
= CreateProtoRedirect();
13671 else if(mode
== MODUS_EMODULE
)
13672 mode
= CreateEModule(Flags
& FLAG_SORTED
);
13673 else if(mode
== MODUS_LVOLIB
)
13674 mode
= CreateLVOLib();
13675 else if(mode
== MODUS_VBCCPUPLIB
)
13676 mode
= CreateVBCCPUPLib(callmode
);
13677 else if(mode
== MODUS_VBCCINLINE
)
13678 mode
= CreateVBCCInline(0, callmode
);
13679 else if(mode
== MODUS_PASCAL
)
13680 mode
= CreateFPCUnit();
13681 else if(mode
== MODUS_BMAP
)
13682 mode
= CreateBMAP();
13683 else if(mode
== MODUS_PROTOPOWER
)
13684 mode
= CreateProtoPowerUP();
13685 else if(mode
== MODUS_SASPOWER
)
13686 mode
= CreateSASPowerUP(callmode
);
13687 else if(mode
== MODUS_CSTUB
)
13688 mode
= CreateCSTUBSFile();
13689 else if(mode
== MODUS_PRAGMA
)
13690 mode
= CreatePragmaFile(amicall
, libcall
, amitags
, libtags
, pragmode
);
13691 else if(mode
== MODUS_LOCALDATA
)
13692 mode
= CreateLocalData(filename
, callmode
);
13693 else if(mode
) /* MODUS_STUBTEXT starts with 1 */
13694 mode
= CreateAsmStubs(mode
, callmode
);
13696 CloseDest(filename
);
13700 DoError(Output_Error
? ERR_UNKNOWN_ERROR
: ERR_WRITING_FILE
, 0);