added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / tools / fd2inline / fd2inline.c
blobc99776824c560f38f53d7ced62d51bb7fc8b6635
1 /******************************************************************************
3 * fd2inline
5 * Should be able to parse CBM fd files and generate vanilla inline calls
6 * for gcc. Works as a filter.
8 * by Wolfgang Baron, all rights reserved.
10 * improved, updated, simply made workable by Rainer F. Trunz 1/95
12 * Completely reworked Version, cleaned up and removed a whole lot of bugs
13 * found by Kamil Iskra.
15 * Expect miracles now (hopefully...). Ok, I am just kidding :)
17 * Version 0.99a by Rainer F. Trunz 6/95
19 * Version 0.99b and later by Kamil Iskra.
21 * Version 1.3x by Martin Blom
22 * See fd2inline.guide/fd2inline.info for details.
24 *****************************************************************************/
26 #include <ctype.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
32 /******************************************************************************
33 * The program has a few sort of class definitions, which are the result of
34 * object oriented thinking, to be imlemented in plain C. I just haven't
35 * had the time to learn C++ or install the compiler. The design does however
36 * improve robustness, which allows the source to be used over and over again.
37 * if you use this code, please leave a little origin note.
38 ******************************************************************************/
40 const static char version_str[]="$VER: fd2inline " VERSION " (24.2.2002)";
42 /******************************************************************************
43 * These are general definitions including types for defining registers etc.
44 ******************************************************************************/
46 #ifdef DEBUG
47 #define DBP(a) a
48 #else /* !DEBUG */
49 #define DBP(a)
50 #endif /* !DEBUG */
52 #if (defined(__GNUC__) || defined(__SASC)) && 0
53 #define INLINE __inline /* Gives 20% *larger* executable with GCC?! */
54 #else
55 #define INLINE
56 #endif
58 #define REGS 16 /* d0=0,...,a7=15 */
59 #define FDS 1000
61 typedef enum
63 d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
64 } regs;
66 typedef unsigned char shortcard;
68 typedef enum { false, nodef, real_error } Error;
70 enum { NEW, OLD, STUBS, PROTO, GATESTUBS, GATEPROTO } output_mode=NEW;
71 enum { IX86BE_AMITHLON, AROS, M68K_AMIGAOS, M68K_POS, PPC_POWERUP, PPC_MORPHOS } target = M68K_AMIGAOS;
73 int Quiet = 0;
74 int DirectVarargsCalls = 0;
75 int RegLibFlag = 0;
76 int PreLibFlag = 0;
77 int PostLibFlag = 0;
78 char *gateprefix = "";
79 char *libprefix = "";
81 char BaseName[64], BaseNamU[64], BaseNamL[64], BaseNamC[64];
82 char Buffer[512];
84 const static char *LibExcTable[]=
86 "BattClockBase", "Node",
87 "BattMemBase", "Node",
88 "ConsoleDevice", "Device",
89 "DiskBase", "DiskResource",
90 "DOSBase", "DosLibrary",
91 "SysBase", "ExecBase",
92 "ExpansionBase", "ExpansionBase",
93 "GfxBase", "GfxBase",
94 "InputBase", "Device",
95 "IntuitionBase", "IntuitionBase",
96 "LocaleBase", "LocaleBase",
97 "MathIeeeDoubBasBase", "MathIEEEBase",
98 "MathIeeeDoubTransBase","MathIEEEBase",
99 "MathIeeeSingBasBase", "MathIEEEBase",
100 "MathIeeeSingTransBase","MathIEEEBase",
101 "MiscBase", "Node",
102 "PotgoBase", "Node",
103 "RamdriveDevice", "Device",
104 "RealTimeBase", "RealTimeBase",
105 "RexxSysBase", "RxsLib",
106 "TimerBase", "Device",
107 "UtilityBase", "UtilityBase"
109 const char *StdLib; /* global lib-name ptr */
111 /*******************************************
112 * just some support functions, no checking
113 *******************************************/
115 char*
116 NewString(char** new, const char* old)
118 const char *high;
119 unsigned long len;
121 while (*old && (*old==' ' || *old=='\t'))
122 old++;
123 len=strlen(old);
124 for (high=old+len-1; high>=old && (*high==' ' || *high=='\t'); high--);
125 high++;
126 len=high-old;
127 *new=malloc(1+len);
128 if (*new)
130 strncpy(*new, old, len);
131 (*new)[len]='\0';
133 else
134 fprintf(stderr, "No mem for string\n");
135 return *new;
138 static INLINE void
139 illparams(const char* funcname)
141 fprintf(stderr, "%s: illegal Parameters\n", funcname);
144 static INLINE const char*
145 RegStr(regs reg)
147 const static char *aosregs[]=
149 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
150 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal"
152 *posregs[]=
154 "__INLINE_REG_D0",
155 "__INLINE_REG_D1",
156 "__INLINE_REG_D2",
157 "__INLINE_REG_D3",
158 "__INLINE_REG_D4",
159 "__INLINE_REG_D5",
160 "__INLINE_REG_D6",
161 "__INLINE_REG_D7",
162 "__INLINE_REG_A0",
163 "__INLINE_REG_A1",
164 "__INLINE_REG_A2",
165 "__INLINE_REG_A3",
166 "__INLINE_REG_A4",
167 "__INLINE_REG_A5",
168 "__INLINE_REG_A6",
169 "__INLINE_REG_A7",
170 "illegal"
173 if (reg>illegal)
174 reg=illegal;
175 if (reg<d0)
176 reg=d0;
177 return (target!=M68K_POS ? aosregs[reg] : posregs[reg]);
180 static INLINE const char*
181 RegStrU(regs reg)
183 const static char *aosregs[]=
185 "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
186 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "illegal"
189 if (reg>illegal)
190 reg=illegal;
191 if (reg<d0)
192 reg=d0;
193 return (target!=M68K_POS ? aosregs[reg] : RegStr(reg));
196 static INLINE
198 /******************************************************************************
199 * StrNRBrk
201 * searches string in from position at downwards, as long as in does not
202 * contain any character in not.
204 ******************************************************************************/
206 const char*
207 StrNRBrk(const char* in, const char* not, const char* at)
209 const char *chcheck;
210 Error ready;
212 chcheck=""; /* if at<in, the result will be NULL */
213 for (ready=false; ready==false && at>=in;)
215 for (chcheck=not; *chcheck && *chcheck != *at; chcheck++);
216 if (*chcheck)
217 ready=real_error;
218 else
219 at--;
221 DBP(fprintf(stderr, "{%c}", *chcheck));
222 return *chcheck ? at : NULL;
226 Our own "strupr", since it is a non-standard function.
228 void
229 StrUpr(char* str)
231 while (*str)
233 *str=toupper(*str);
234 str++;
239 MatchGlob( char* glob, char* str )
241 while( *glob )
243 char c = *glob++;
245 switch( c )
247 case '?':
248 if( *str == 0 )
250 return 0;
252 break;
254 case '\\':
255 c = *glob++;
256 if( c == 0 || *str != c )
258 return 0;
260 break;
262 case '*':
263 if( *glob == 0 )
265 return 1;
268 while( *str )
270 if( MatchGlob( glob, str ) )
272 return 1;
274 ++str;
276 return 0;
278 default:
279 if( *str != c )
281 return 0;
283 break;
286 ++str;
289 return *str == 0;
293 /******************************************************************************
294 * CLASS fdFile
296 * stores a file with a temporary buffer (static length, sorry), a line number,
297 * an offset (used for library offsets and an error field.
298 * When there's no error, line will contain line #lineno and offset will be
299 * the last offset set by the interpretation of the last line. If there's been
300 * no ##bias line, this field assumes a bias of 30, which is the standard bias.
301 * It is assumed offsets are always negative.
302 ******************************************************************************/
304 #define fF_BUFSIZE 1024
306 /* all you need to know about an fdFile you parse */
308 typedef enum {FD_PRIVATE=1, FD_SHADOW=2} fdflags;
310 typedef struct
312 FILE* file; /* the file we're reading from */
313 char line[fF_BUFSIZE]; /* the current line */
314 unsigned long lineno; /* current line number */
315 long offset; /* current fd offset (-bias) */
316 Error error; /* is everything o.k. */
317 fdflags flags; /* for ##private, ##shadow (p.OS) */
318 } fdFile;
320 fdFile*
321 fF_ctor (const char* fname);
322 static void
323 fF_dtor (fdFile* obj);
324 static void
325 fF_SetError (fdFile* obj, Error error);
326 static void
327 fF_SetOffset (fdFile* obj, long at);
328 Error
329 fF_readln (fdFile* obj);
330 static Error
331 fF_GetError (const fdFile* obj);
332 static long
333 fF_GetOffset (const fdFile* obj);
334 char*
335 fF_FuncName (fdFile* obj); /* return name or null */
336 static void
337 fF_SetFlags (fdFile* obj, fdflags flags);
338 static fdflags
339 fF_GetFlags (const fdFile* obj);
341 static INLINE void
342 fF_dtor(fdFile* obj)
344 fclose(obj->file);
345 free(obj);
348 static INLINE void
349 fF_SetError(fdFile* obj, Error error)
351 if (obj)
352 obj->error=error;
353 else
354 illparams("fF_SetError");
357 #define FUNCTION_GAP (target!=M68K_POS ? 6 : 12)
359 static INLINE void
360 fF_SetOffset(fdFile* obj, long at)
362 if (obj)
363 obj->offset= at;
364 else
365 illparams("fFSetOffset");
368 static INLINE void
369 fF_SetFlags(fdFile* obj, fdflags flags)
371 if (obj)
372 obj->flags=flags;
373 else
374 illparams("fF_SetFlags");
377 fdFile*
378 fF_ctor(const char* fname)
380 fdFile *result;
382 if (fname)
384 result=malloc(sizeof(fdFile));
385 if (result)
387 result->file=fopen(fname, "r");
388 if (result->file)
390 result->lineno=0;
391 fF_SetOffset(result, -30);
392 fF_SetError(result, false);
393 fF_SetFlags(result, 0);
394 result->line[0]='\0';
396 else
398 free(result);
399 result=NULL;
403 else
405 result=NULL;
406 illparams("fF_ctor");
408 return result;
411 Error
412 fF_readln(fdFile* obj)
414 char *low, *bpoint;
415 long glen, /* the length we read until now */
416 len; /* the length of the last segment */
418 if (obj)
420 low=obj->line;
421 glen=0;
423 for (;;)
425 obj->lineno++;
426 if (!fgets(low, fF_BUFSIZE-1-glen, obj->file))
428 fF_SetError(obj, real_error);
429 obj->line[0]='\0';
430 return real_error;
432 if (low==strpbrk(low, "*#/"))
434 DBP(fprintf(stderr, "in# %s\n", obj->line));
435 return false;
437 len=strlen(low);
438 bpoint=low+len-1;
439 while (len && isspace(*bpoint))
441 bpoint--;
442 len--;
444 if (*bpoint==';' || *bpoint==')')
446 DBP(fprintf(stderr, "\nin: %s\n", obj->line));
447 return false;
449 glen+=len;
450 low+=len;
451 if (glen>=fF_BUFSIZE-10) /* somewhat pessimistic? */
453 fF_SetError(obj, real_error);
454 fprintf(stderr, "Line %lu too long.\n", obj->lineno);
455 return real_error;
457 DBP(fprintf(stderr, "+"));
460 illparams("fF_readln");
461 return real_error;
464 static INLINE Error
465 fF_GetError(const fdFile* obj)
467 if (obj)
468 return obj->error;
469 illparams("fF_GetError");
470 return real_error;
473 static INLINE long
474 fF_GetOffset(const fdFile* obj)
476 if (obj)
477 return obj->offset;
478 illparams("fF_GetOffset");
479 return -1;
482 /******************************************************************************
483 * fF_FuncName
485 * checks if it can find a function-name and return it's address, or NULL
486 * if the current line does not seem to contain one. The return value will
487 * be a pointer into a malloced buffer, thus the caller will have to free().
488 ******************************************************************************/
490 char*
491 fF_FuncName(fdFile* obj)
493 const char *lower;
494 const char *upper;
495 char *buf;
496 long obraces; /* count of open braces */
497 Error ready; /* ready with searching */
499 if (!obj || fF_GetError(obj)==real_error)
501 illparams("fF_FuncName");
502 return NULL;
505 lower=obj->line;
506 while (*lower && (*lower==' ' || *lower=='\t'))
507 lower++;
509 if (!*lower || (!isalpha(*lower) && *lower!='_'))
511 fF_SetError(obj, nodef);
512 return NULL;
515 while (*lower)
517 if (!isalnum(*lower) && !isspace(*lower) && *lower!='*' && *lower!=','
518 && *lower!='.' && *lower!=';' && *lower!='(' && *lower!=')' &&
519 *lower!='[' && *lower!=']' && *lower!='_' && *lower!='\\')
521 fF_SetError(obj, nodef);
522 return NULL;
524 lower++;
527 lower=NULL;
528 buf=NULL;
530 if (obj && fF_GetError(obj)==false)
532 if ((upper=strrchr(obj->line, ')'))!=0)
534 DBP(fprintf(stderr, "end:%s:", upper));
536 for (obraces=1, ready=false; ready==false; upper=lower)
538 lower=StrNRBrk(obj->line, "()", --upper);
539 if (lower)
541 switch (*lower)
543 case ')':
544 obraces++;
545 DBP(fprintf(stderr, " )%ld%s", obraces, lower));
546 break;
547 case '(':
548 obraces--;
549 DBP(fprintf(stderr, " (%ld%s", obraces, lower));
550 if (!obraces)
551 ready=nodef;
552 break;
553 default:
554 fprintf(stderr, "Faulty StrNRBrk\n");
557 else
559 fprintf(stderr, "'(' or ')' expected in line %lu.\n",
560 obj->lineno);
561 ready=real_error;
564 if (ready==nodef) /* we found the matching '(' */
566 long newlen;
567 const char* name;
569 upper--;
571 while (upper>=obj->line && (*upper==' ' || *upper=='\t'))
572 upper--;
574 lower=StrNRBrk(obj->line, " \t*)", upper);
576 if (!lower)
577 lower=obj->line;
578 else
579 lower++;
581 for (name=lower; name<=upper; name++)
582 if (!isalnum(*name) && *name!='_')
584 fF_SetError(obj, nodef);
585 return NULL;
588 newlen=upper-lower+1;
589 buf=malloc(newlen+1);
591 if (buf)
593 strncpy(buf, lower, newlen);
594 buf[newlen]='\0';
596 else
597 fprintf(stderr, "No mem for fF_FuncName");
601 else
602 illparams("fF_FuncName");
603 return buf;
606 static INLINE fdflags
607 fF_GetFlags(const fdFile* obj)
609 if (obj)
610 return obj->flags;
611 illparams("fF_GetFlags");
612 return 0;
615 /*********************
616 * CLASS fdDef *
617 *********************/
619 typedef struct
621 char* name;
622 char* type;
623 long offset;
624 regs reg[REGS];
625 char* param[REGS];
626 char* proto[REGS];
627 regs funcpar; /* number of argument that has type "pointer to function" */
628 } fdDef;
630 fdDef*
631 fD_ctor (void);
632 void
633 fD_dtor (fdDef* obj);
634 static void
635 fD_NewName (fdDef* obj, const char* newname);
636 void
637 fD_NewParam (fdDef* obj, shortcard at, const char* newstr);
639 fD_NewProto (fdDef* obj, shortcard at, char* newstr);
640 static void
641 fD_NewReg (fdDef* obj, shortcard at, regs reg);
642 static void
643 fD_NewType (fdDef* obj, const char* newstr);
644 static void
645 fD_SetOffset (fdDef* obj, long off);
646 Error
647 fD_parsefd (fdDef* obj, fdFile* infile);
648 Error
649 fD_parsepr (fdDef* obj, fdFile* infile);
650 static const char*
651 fD_GetName (const fdDef* obj);
652 static long
653 fD_GetOffset (const fdDef* obj);
654 static const char*
655 fD_GetParam (const fdDef* obj, shortcard at);
656 static regs
657 fD_GetReg (const fdDef* obj, shortcard at);
658 static const char*
659 fD_GetRegStr (const fdDef* obj, shortcard at);
660 static const char*
661 fD_GetRegStrU (const fdDef* obj, shortcard at);
662 static const char*
663 fD_GetType (const fdDef* obj);
664 static shortcard
665 fD_ParamNum (const fdDef* obj);
666 static shortcard
667 fD_ProtoNum (const fdDef* obj);
668 static shortcard
669 fD_RegNum (const fdDef* obj);
671 fD_cmpName (const void* big, const void* small);
672 void
673 fD_write (FILE* outfile, const fdDef* obj);
674 static shortcard
675 fD_GetFuncParNum (const fdDef* obj);
676 static void
677 fD_SetFuncParNum (fdDef* obj, shortcard at);
678 static void
679 fD_adjustargnames(fdDef *obj);
681 fdDef **arrdefs;
682 long fds;
684 char *fD_nostring="";
686 fdDef*
687 fD_ctor(void)
689 fdDef *result;
690 regs count;
692 result=malloc(sizeof(fdDef));
694 if (result)
696 result->name=fD_nostring;
697 result->type=fD_nostring;
698 result->funcpar=illegal;
700 for (count=d0; count<illegal; count++ )
702 result->reg[count]=illegal;
703 result->param[count]=fD_nostring; /* if (!strlen) dont't free() */
704 result->proto[count]=fD_nostring;
707 return result;
710 /* free all resources and make the object as illegal as possible */
712 void
713 fD_dtor(fdDef* obj)
715 regs count;
717 if (obj)
719 if (!obj->name)
720 fprintf(stderr, "fD_dtor: null name");
721 else
722 if (obj->name!=fD_nostring)
723 free(obj->name);
725 if (!obj->type)
726 fprintf(stderr, "fD_dtor: null type");
727 else
728 if (obj->type!=fD_nostring)
729 free(obj->type);
731 obj->name=obj->type=NULL;
733 for (count=d0; count<illegal; count++)
735 obj->reg[count]=illegal;
737 if (!obj->param[count])
738 fprintf(stderr, "fD_dtor: null param");
739 else
740 if (obj->param[count]!=fD_nostring)
741 free(obj->param[count]);
743 if (!obj->proto[count])
744 fprintf(stderr, "fD_dtor: null proto");
745 else
746 if (obj->proto[count]!=fD_nostring)
747 free(obj->proto[count]);
749 obj->param[count]=obj->proto[count]=NULL;
752 free(obj);
754 else
755 fprintf(stderr, "fd_dtor(NULL)\n");
758 static INLINE void
759 fD_NewName(fdDef* obj, const char* newname)
761 if (obj && newname)
763 if (obj->name && obj->name!=fD_nostring)
764 free(obj->name);
765 if (!NewString(&obj->name, newname))
766 obj->name=fD_nostring;
768 else
769 illparams("fD_NewName");
772 void
773 fD_NewParam(fdDef* obj, shortcard at, const char* newstr)
775 char *pa;
777 if (newstr && obj && at<illegal)
779 pa=obj->param[at];
781 if (pa && pa!=fD_nostring)
782 free(pa);
784 while (*newstr==' ' || *newstr=='\t')
785 newstr++;
787 if (NewString(&pa, newstr))
789 char* prefix_pa;
791 prefix_pa = malloc( strlen( pa ) + 4 );
793 if( prefix_pa == NULL )
795 fprintf(stderr, "No mem for string\n");
797 else
799 sprintf( prefix_pa, "___%s", pa );
800 obj->param[at]=prefix_pa;
801 free( pa );
804 else
805 obj->param[at]=fD_nostring;
807 else
808 illparams("fD_NewParam");
811 /* get first free *reg or illegal */
813 static INLINE shortcard
814 fD_RegNum(const fdDef* obj)
816 shortcard count;
818 if (obj)
820 for (count=d0; count<illegal && obj->reg[count]!=illegal; count++);
821 return count;
823 else
825 illparams("fD_RegNum");
826 return illegal;
830 static INLINE void
831 fD_NewReg(fdDef* obj, shortcard at, regs reg)
833 if (obj && at<illegal && reg>=d0 && reg<=illegal)
834 obj->reg[at]=reg;
835 else
836 illparams("fD_NewReg");
839 static INLINE regs
840 fD_GetReg(const fdDef* obj, shortcard at)
842 if (obj && at<illegal)
843 return obj->reg[at];
844 else
846 illparams("fD_GetReg");
847 return illegal;
851 static INLINE shortcard
852 fD_GetFuncParNum(const fdDef* obj)
854 if (obj)
855 return (shortcard)obj->funcpar;
856 else
858 illparams("fD_GetFuncParNum");
859 return illegal;
863 static INLINE void
864 fD_SetFuncParNum(fdDef* obj, shortcard at)
866 if (obj && at<illegal)
867 obj->funcpar=at;
868 else
869 illparams("fD_SetFuncParNum");
873 fD_NewProto(fdDef* obj, shortcard at, char* newstr)
875 char *pr;
877 if (newstr && obj && at<illegal)
879 char *t, arr[200]; /* I hope 200 will be enough... */
880 int numwords=1;
881 pr=obj->proto[at];
883 if (pr && pr!=fD_nostring)
884 free(pr);
886 while (*newstr==' ' || *newstr=='\t')
887 newstr++; /* Skip leading spaces */
889 t=arr;
890 while ((*t++=*newstr)!=0)
892 /* Copy the rest, counting number of words */
893 if ((*newstr==' ' || *newstr=='\t') && newstr[1] && newstr[1]!=' ' &&
894 newstr[1]!='\t')
895 numwords++;
896 newstr++;
899 t=arr+strlen(arr)-1;
900 while (*t==' ' || *t=='\t')
901 t--;
902 t[1]='\0'; /* Get rid of tailing spaces */
904 if (at!=fD_GetFuncParNum(obj))
906 if (numwords>1) /* One word - must be type */
907 if (*t!='*')
909 /* '*' on the end - no parameter name used */
910 while (*t!=' ' && *t!='\t' && *t!='*')
911 t--;
912 t++;
913 if (strcmp(t, "char") && strcmp(t, "short") && strcmp(t, "int")
914 && strcmp(t, "long") && strcmp(t, "APTR"))
916 /* Not one of applicable keywords - must be parameter name.
917 Get rid of it. */
918 t--;
919 while (*t==' ' || *t=='\t')
920 t--;
921 t[1]='\0';
925 else
927 /* Parameter of type "pointer to function". */
928 char *end;
929 t=strchr(arr, '(');
930 t++;
931 while (*t==' ' || *t=='\t')
932 t++;
933 if (*t!='*')
934 return 1;
935 t++;
936 end=strchr(t, ')');
937 if (target!=M68K_POS)
939 memmove(t+2, end, strlen(end)+1);
940 *t='%';
941 t[1]='s';
943 else
944 memmove(t, end, strlen(end)+1);
947 if (NewString(&pr, arr))
949 obj->proto[at]=pr;
950 while (*pr==' ' || *pr=='\t')
951 pr++;
952 if (!strcasecmp(pr, "double"))
954 /* "double" needs two data registers */
955 int count, regs=fD_RegNum(obj);
956 for (count=at+1; count<regs; count++)
957 fD_NewReg(obj, count, fD_GetReg(obj, count+1));
960 else
961 obj->proto[at]=fD_nostring;
963 else
964 illparams("fD_NewProto");
966 return 0;
969 static INLINE void
970 fD_NewType(fdDef* obj, const char* newtype)
972 if (obj && newtype)
974 if (obj->type && obj->type!=fD_nostring)
975 free(obj->type);
976 if (!NewString(&obj->type, newtype))
977 obj->type=fD_nostring;
979 else
980 illparams("fD_NewType");
983 static INLINE void
984 fD_SetOffset(fdDef* obj, long off)
986 if (obj)
987 obj->offset=off;
988 else
989 illparams("fD_SetOffset");
992 static INLINE const char*
993 fD_GetName(const fdDef* obj)
995 if (obj && obj->name)
996 return obj->name;
997 else
999 illparams("fD_GetName");
1000 return fD_nostring;
1004 static INLINE long
1005 fD_GetOffset(const fdDef* obj)
1007 if (obj)
1008 return obj->offset;
1009 else
1011 illparams("fD_GetOffset");
1012 return 0;
1016 static INLINE const char*
1017 fD_GetProto(const fdDef* obj, shortcard at)
1019 if (obj && at<illegal && obj->proto[at])
1020 return obj->proto[at];
1021 else
1023 illparams("fD_GetProto");
1024 return fD_nostring;
1028 static INLINE const char*
1029 fD_GetParam(const fdDef* obj, shortcard at)
1031 if (obj && at<illegal && obj->param[at])
1032 return obj->param[at];
1033 else
1035 illparams("fD_GetParam");
1036 return fD_nostring;
1040 static INLINE const char*
1041 fD_GetRegStr(const fdDef* obj, shortcard at)
1043 if (obj && at<illegal)
1044 return RegStr(obj->reg[at]);
1045 else
1047 illparams("fD_GetReg");
1048 return RegStr(illegal);
1052 static INLINE const char*
1053 fD_GetRegStrU(const fdDef* obj, shortcard at)
1055 if (obj && at<illegal)
1056 return RegStrU(obj->reg[at]);
1057 else
1059 illparams("fD_GetReg");
1060 return RegStrU(illegal);
1064 static INLINE const char*
1065 fD_GetType(const fdDef* obj)
1067 if (obj && obj->type)
1068 return obj->type;
1069 else
1071 illparams("fD_GetType");
1072 return fD_nostring;
1076 /* get first free param or illegal */
1078 static INLINE shortcard
1079 fD_ParamNum(const fdDef* obj)
1081 shortcard count;
1083 if (obj)
1085 for (count=d0; count<illegal && obj->param[count]!=fD_nostring;
1086 count++);
1087 return count;
1089 else
1091 illparams("fD_ParamNum");
1092 return illegal;
1096 static INLINE shortcard
1097 fD_ProtoNum(const fdDef* obj)
1099 shortcard count;
1101 if (obj)
1103 for (count=d0; count<illegal && obj->proto[count]!=fD_nostring;
1104 count++);
1105 return count;
1107 else
1109 illparams("fD_ProtoNum");
1110 return illegal;
1114 /******************************************************************************
1115 * fD_parsefd
1117 * parse the current line. Needs to copy input, in order to insert \0's
1118 * RETURN
1119 * fF_GetError(infile):
1120 * false = read a definition.
1121 * nodef = not a definition on line (so try again)
1122 * error = real error
1123 ******************************************************************************/
1125 Error
1126 fD_parsefd(fdDef* obj, fdFile* infile)
1128 enum parse_info { name, params, regs, ready } parsing;
1129 char *buf, *bpoint, *bnext;
1130 unsigned long index;
1132 if (obj && infile && fF_GetError(infile)==false)
1134 parsing=name;
1136 if (!NewString(&buf, infile->line))
1138 fprintf(stderr, "No mem for line %lu\n", infile->lineno);
1139 fF_SetError(infile, real_error);
1141 bpoint=buf; /* so -Wall keeps quiet */
1143 /* try to parse the line until there's an error or we are done */
1145 while (parsing!=ready && fF_GetError(infile)==false)
1147 switch (parsing)
1149 case name:
1150 switch (buf[0])
1152 case '#':
1153 if (strncmp("##base", buf, 6)==0)
1155 bnext=buf+6;
1156 while (*bnext==' ' || *bnext=='\t' || *bnext=='_')
1157 bnext++;
1158 strcpy(BaseName, bnext);
1159 BaseName[strlen(BaseName)-1]='\0';
1161 else
1162 if (strncmp("##bias", buf, 6)==0)
1164 if (!sscanf(buf+6, "%ld", &infile->offset))
1166 fprintf(stderr, "Illegal ##bias in line %lu: %s\n",
1167 infile->lineno, infile->line);
1168 fF_SetError(infile, real_error);
1169 break; /* avoid nodef */
1171 else
1173 if (fF_GetOffset(infile)>0)
1174 fF_SetOffset(infile, -fF_GetOffset(infile));
1175 DBP(fprintf(stderr, "set offset to %ld\n",
1176 fF_GetOffset(infile)));
1179 else
1181 if (strncmp("##private", buf, 9)==0)
1182 fF_SetFlags(infile, fF_GetFlags(infile) |
1183 FD_PRIVATE);
1184 else if (strncmp("##public", buf, 8)==0)
1185 fF_SetFlags(infile, fF_GetFlags(infile) &
1186 ~FD_PRIVATE);
1187 else if (strncmp("##shadow", buf, 8)==0)
1188 fF_SetFlags(infile, fF_GetFlags(infile) |
1189 FD_SHADOW);
1191 /* drop through for error comment */
1193 case '*':
1194 /* try again somewhere else */
1195 fF_SetError(infile, nodef);
1196 break;
1198 default:
1199 /* assume a regular line here */
1200 if (fF_GetFlags(infile) & (FD_PRIVATE | FD_SHADOW))
1202 /* don't store names of privates */
1203 fF_SetError(infile, nodef);
1204 if (!(fF_GetFlags(infile) & FD_SHADOW))
1205 fF_SetOffset(infile,
1206 fF_GetOffset(infile)-FUNCTION_GAP);
1207 else
1208 /* Shadow is valid for one line only. */
1209 fF_SetFlags(infile, fF_GetFlags(infile) &
1210 ~FD_SHADOW);
1211 break;
1213 parsing=name; /* switch (parsing) */
1214 for (index=0; buf[index] && buf[index]!='('; index++);
1216 if (!buf[index])
1218 /* oops, no fd ? */
1219 fprintf(stderr, "Not an fd, line %lu: %s\n",
1220 infile->lineno, buf /* infile->line */);
1221 fF_SetError(infile, nodef);
1222 } /* maybe next time */
1223 else
1225 buf[index]=0;
1227 fD_NewName(obj, buf);
1228 fD_SetOffset(obj, fF_GetOffset(infile));
1230 bpoint=buf+index+1;
1231 parsing=params; /* continue the loop */
1234 break;
1236 case params:
1238 char *bptmp; /* needed for fD_NewParam */
1240 /* look for parameters now */
1242 for (bnext = bpoint; *bnext && *bnext!=',' && *bnext!=')';
1243 bnext++);
1245 if (*bnext)
1247 bptmp=bpoint;
1249 if (*bnext == ')')
1251 if (bnext[1] != '(')
1253 fprintf(stderr, "Registers expected in line %lu: %s\n",
1254 infile->lineno, infile->line);
1255 fF_SetError(infile, nodef);
1257 else
1259 parsing=regs;
1260 bpoint=bnext+2;
1263 else
1264 bpoint = bnext+1;
1266 /* terminate string and advance to next item */
1268 *bnext='\0';
1269 fD_NewParam(obj, fD_ParamNum(obj), bptmp);
1271 else
1273 fF_SetError(infile, nodef);
1274 fprintf(stderr, "Param expected in line %lu: %s\n",
1275 infile->lineno, infile->line);
1277 break; /* switch parsing */
1280 case regs:
1281 /* look for parameters now */
1283 for (bnext=bpoint; *bnext && *bnext!='/' && *bnext!=',' &&
1284 *bnext!=')'; bnext++);
1286 if (*bnext)
1288 if (')'==*bnext)
1290 /* wow, we've finished */
1291 fF_SetOffset(infile, fF_GetOffset(infile)-FUNCTION_GAP);
1292 parsing=ready;
1294 *bnext = '\0';
1296 bpoint[0]=tolower(bpoint[0]);
1298 if ((bpoint[0]=='d' || bpoint[0]=='a') && bpoint[1]>='0' &&
1299 bpoint[1]<='8' && bnext==bpoint+2)
1300 fD_NewReg(obj, fD_RegNum(obj),
1301 bpoint[1]-'0'+(bpoint[0]=='a'? 8 : 0));
1302 else
1303 if (bnext!=bpoint)
1305 /* it is when our function is void */
1306 fprintf(stderr, "Illegal register %s in line %ld\n",
1307 bpoint, infile->lineno);
1308 fF_SetError(infile, nodef);
1310 bpoint = bnext+1;
1312 else
1314 fF_SetError(infile, nodef);
1315 fprintf(stderr, "Reg expected in line %lu\n",
1316 infile->lineno);
1318 break; /* switch parsing */
1320 case ready:
1321 fprintf(stderr, "Internal error, use another compiler.\n");
1322 break;
1326 free(buf);
1327 return fF_GetError(infile);
1329 else
1331 illparams("fD_parsefd");
1332 return real_error;
1336 static void
1337 fD_adjustargnames(fdDef *obj)
1339 int parnum;
1341 if (output_mode!=NEW)
1342 return;
1344 /* For #define-base output mode, we have to check if argument names are not
1345 the same as some words in type names. We check from the first argument
1346 to the last, resolving conflicts by changing argument names, if
1347 necessary. */
1349 for (parnum=0; parnum<fD_ParamNum(obj); parnum++)
1351 const char *parname=fD_GetParam(obj, parnum);
1352 int finished;
1355 int num;
1356 const char *type=fD_GetType(obj);
1357 char *str;
1359 finished=1;
1361 if ((str=strstr(type, parname))!=0 && (str==type ||
1362 (!isalnum(str[-1]) && str[-1]!='_')) &&
1363 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_')))
1365 char buf[300]; /* Hope will be enough... */
1366 strcpy(buf, parname);
1367 strcat(buf, "_");
1368 fD_NewParam(obj, parnum, buf);
1369 parname=fD_GetParam(obj, parnum);
1370 finished=0;
1372 else
1373 for (num=0; num<fD_ParamNum(obj); num++)
1375 const char *name=fD_GetParam(obj, num);
1376 const char *proto=fD_GetProto(obj, num);
1377 if ((num<parnum && strcmp(name, parname)==0) ||
1378 ((str=strstr(proto, parname))!=0 && (str==proto ||
1379 (!isalnum(str[-1]) && str[-1]!='_')) &&
1380 (!*(str+=strlen(parname)) || (!isalnum(*str) && *str!='_'))))
1382 char buf[300]; /* Hope will be enough... */
1383 strcpy(buf, parname);
1384 strcat(buf, "_");
1385 fD_NewParam(obj, parnum, buf);
1386 parname=fD_GetParam(obj, parnum);
1387 // lcs finished=0;
1388 break;
1391 } while (!finished);
1395 Error
1396 fD_parsepr(fdDef* obj, fdFile* infile)
1398 char *buf; /* a copy of infile->line */
1399 char *bpoint, /* cursor in buf */
1400 *bnext, /* looking for the end */
1401 *lowarg; /* beginning of this argument */
1402 long obraces; /* count of open braces */
1403 regs count, /* count parameter number */
1404 args; /* the number of arguments for this function */
1406 if (!(obj && infile && fF_GetError(infile)==false))
1408 illparams("fD_parsepr");
1409 fF_SetError(infile, real_error);
1410 return real_error;
1412 if (!NewString(&buf, infile->line))
1414 fprintf(stderr, "No mem for fD_parsepr\n");
1415 fF_SetError(infile, real_error);
1416 return real_error;
1418 fF_SetError(infile, false);
1420 bpoint=strchr(buf, '(');
1421 while (--bpoint>=buf && strstr(bpoint, fD_GetName(obj))!=bpoint);
1422 if (bpoint>=buf)
1424 while (--bpoint >= buf && (*bpoint==' ' || *bpoint=='\t'));
1425 *++bpoint='\0';
1427 fD_NewType(obj, buf);
1429 while (bpoint && *bpoint++!='('); /* one beyond '(' */
1431 lowarg=bpoint;
1432 obraces=0;
1434 for (count=0, args=fD_RegNum(obj); count<args; bpoint=bnext+1)
1436 while (*bpoint && (*bpoint==' ' || *bpoint=='\t')) /* ignore spaces */
1437 bpoint++;
1439 if (!obraces && target==M68K_POS && strncmp(bpoint, "_R_", 3)==0 &&
1440 isalnum(bpoint[3]) && isalnum(bpoint[4]) && isspace(bpoint[5]))
1441 lowarg=bpoint+5;
1443 bnext=strpbrk(bpoint, "(),");
1445 if (bnext)
1447 switch (*bnext)
1449 case '(':
1450 if (!obraces)
1452 if (target==M68K_AMIGAOS || target==M68K_POS)
1454 if (fD_GetFuncParNum(obj)!=illegal &&
1455 fD_GetFuncParNum(obj)!=count &&
1456 !Quiet)
1457 fprintf(stderr, "Warning: two parameters of type "
1458 "pointer to function are used.\n"
1459 "This is not supported!\n");
1462 fD_SetFuncParNum(obj, count);
1464 obraces++;
1465 DBP(fprintf(stderr, "< (%ld%s >", obraces, bnext));
1466 break;
1468 case ')':
1469 if (obraces)
1471 DBP(fprintf(stderr, "< )%ld%s >", obraces, bnext));
1472 obraces--;
1474 else
1476 *bnext='\0';
1477 DBP(fprintf(stderr, "< )0> [LAST PROTO=%s]", lowarg));
1478 if (fD_NewProto(obj, count, lowarg))
1479 fprintf(stderr, "Parser confused in line %ld\n",
1480 infile->lineno);
1481 lowarg=bnext+1;
1483 if (count!=args-1)
1485 DBP(fprintf(stderr, "%s needs %u arguments and got %u.\n",
1486 fD_GetName(obj), args, count+1));
1487 fF_SetError(infile, nodef);
1489 count++;
1491 break;
1493 case ',':
1494 if (!obraces)
1496 *bnext='\0';
1497 DBP(fprintf(stderr, " [PROTO=%s] ", lowarg));
1498 if (fD_NewProto(obj, count, lowarg))
1499 fprintf(stderr, "Parser confused in line %ld\n",
1500 infile->lineno);
1501 lowarg=bnext+1;
1502 count++;
1504 break;
1506 default:
1507 fprintf(stderr, "Faulty strpbrk in line %lu.\n",
1508 infile->lineno);
1511 else
1513 DBP(fprintf(stderr, "Faulty argument %u in line %lu.\n", count+1,
1514 infile->lineno));
1515 count=args; /* this will effectively quit the for loop */
1516 fF_SetError(infile, nodef);
1519 if (fD_ProtoNum(obj)!=fD_RegNum(obj))
1520 fF_SetError(infile, nodef);
1522 else
1524 fprintf(stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno);
1525 fprintf(stderr, "function , definition %s.\n",
1526 /* fD_GetName(obj),*/ infile->line);
1527 fF_SetError(infile, nodef);
1530 free(buf);
1532 fD_adjustargnames(obj);
1534 return fF_GetError(infile);
1538 fD_cmpName(const void* big, const void* small) /* for qsort and bsearch */
1540 return strcmp(fD_GetName(*(fdDef**)big), fD_GetName(*(fdDef**)small));
1543 const static char *TagExcTable[]=
1545 "BuildEasyRequestArgs", "BuildEasyRequest",
1546 "DoDTMethodA", "DoDTMethod",
1547 "DoGadgetMethodA", "DoGadgetMethod",
1548 "EasyRequestArgs", "EasyRequest",
1549 "MUI_MakeObjectA", "MUI_MakeObject",
1550 "MUI_RequestA", "MUI_Request",
1551 "PrintDTObjectA", "PrintDTObject",
1552 "RefreshDTObjectA", "RefreshDTObjects",
1553 "UMSVLog", "UMSLog",
1554 "VFWritef", "FWritef",
1555 "VFPrintf", "FPrintf",
1556 "VPrintf", "Printf",
1559 const char*
1560 getvarargsfunction(const fdDef * obj)
1562 unsigned int count;
1563 const char *name = fD_GetName(obj);
1565 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1567 if (strcmp(name, TagExcTable[count])==0)
1569 return TagExcTable[count+1];
1572 return(NULL);
1575 const char*
1576 taggedfunction(const fdDef* obj)
1578 shortcard numregs=fD_RegNum(obj);
1579 unsigned int count;
1580 int aos_tagitem;
1581 const char *name=fD_GetName(obj);
1582 static char newname[200]; /* Hope will be enough... static because used
1583 out of the function. */
1584 const char *lastarg;
1585 const static char *TagExcTable2[]=
1587 "ApplyTagChanges",
1588 "CloneTagItems",
1589 "FindTagItem",
1590 "FreeTagItems",
1591 "GetTagData",
1592 "PackBoolTags",
1593 "PackStructureTags",
1594 "RefreshTagItemClones",
1595 "UnpackStructureTags",
1598 if (!numregs)
1599 return NULL;
1601 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0]; count+=2)
1602 if (strcmp(name, TagExcTable[count])==0)
1603 return NULL;
1604 // lcs return TagExcTable[count+1];
1606 for (count=0; count<sizeof TagExcTable2/sizeof TagExcTable2[0]; count++)
1607 if (strcmp(name, TagExcTable2[count])==0)
1608 return NULL;
1610 lastarg=fD_GetProto(obj, numregs-1);
1611 if (strncmp(lastarg, "const", 5)==0 || strncmp(lastarg, "CONST", 5)==0)
1612 lastarg+=5;
1613 while (*lastarg==' ' || *lastarg=='\t')
1614 lastarg++;
1615 if (strncmp(lastarg, "struct", 6))
1616 return NULL;
1617 lastarg+=6;
1618 while (*lastarg==' ' || *lastarg=='\t')
1619 lastarg++;
1620 aos_tagitem=1;
1621 if (strncmp(lastarg, "TagItem", 7) &&
1622 (target!=M68K_POS || ((aos_tagitem=strncmp(lastarg, "pOS_TagItem", 11))!=0)))
1623 return NULL;
1624 lastarg+=(aos_tagitem ? 7 : 11);
1625 while (*lastarg==' ' || *lastarg=='\t')
1626 lastarg++;
1627 if (strcmp(lastarg, "*"))
1628 return NULL;
1630 strcpy(newname, name);
1631 if (newname[strlen(newname)-1]=='A')
1632 newname[strlen(newname)-1]='\0';
1633 else
1634 if (strlen(newname)>7 && !strcmp(newname+strlen(newname)-7, "TagList"))
1635 strcpy(newname+strlen(newname)-4, "s");
1636 else
1637 strcat(newname, "Tags");
1638 return newname;
1641 const char*
1642 aliasfunction(const char* name)
1644 const static char *AliasTable[]=
1646 "AllocDosObject", "AllocDosObjectTagList",
1647 "CreateNewProc", "CreateNewProcTagList",
1648 "NewLoadSeg", "NewLoadSegTagList",
1649 "System", "SystemTagList",
1651 unsigned int count;
1652 for (count=0; count<sizeof AliasTable/sizeof AliasTable[0]; count++)
1653 if (strcmp(name, AliasTable[count])==0)
1654 return AliasTable[count+(count%2 ? -1 : 1)];
1655 return NULL;
1658 void
1659 fD_write(FILE* outfile, const fdDef* obj)
1661 shortcard count, numregs;
1662 const char *chtmp, *tagname, *varname, *name, *rettype;
1663 int vd=0, a45=0, d7=0;
1665 DBP(fprintf(stderr, "func %s\n", fD_GetName(obj)));
1667 numregs=fD_RegNum(obj);
1669 if ((rettype=fD_GetType(obj))==fD_nostring)
1671 fprintf(stderr, "%s has no prototype.\n", fD_GetName(obj));
1672 return;
1674 if (!strcasecmp(rettype, "void"))
1675 vd = 1; /* set flag */
1676 for (count=d0; count<numregs; count++)
1678 const char *reg=fD_GetRegStr(obj, count);
1679 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1681 if (strcmp(reg, "a4")==0 || strcmp(reg, "a5")==0)
1683 if (!a45)
1684 a45=(strcmp(reg, "a4") ? 5 : 4); /* set flag */
1685 else /* Security check */
1686 if (!Quiet)
1687 fprintf(stderr, "Warning: both a4 and a5 are used. "
1688 "This is not supported!\n");
1691 if (strcmp(reg, "d7")==0) /* Used only when a45!=0 */
1692 d7=1;
1695 if (!((output_mode == NEW) && (target == PPC_POWERUP)))
1697 if (a45 && d7) /* Security check */
1698 if (!Quiet)
1699 fprintf(stderr, "Warning: d7 and a4 or a5 are used. This is not "
1700 "supported!\n");
1703 name=fD_GetName(obj);
1705 if (fD_ProtoNum(obj)!=numregs)
1707 fprintf(stderr, "%s gets %d fd args and %d proto%s.\n", name, numregs,
1708 fD_ProtoNum(obj), fD_ProtoNum(obj)!= 1 ? "s" : "");
1709 return;
1712 if (output_mode==NEW)
1714 fprintf(outfile, "#define %s(", name);
1716 if (numregs>0)
1718 for (count=d0; count<numregs-1; count++)
1719 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
1720 fprintf(outfile, "%s", fD_GetParam(obj, count));
1723 if (target==M68K_AMIGAOS)
1725 fprintf(outfile, ") \\\n\tLP%d%s%s%s%s(0x%lx, ", numregs,
1726 (vd ? "NR" : ""), (a45 ? (a45==4 ? "A4" : "A5") : ""),
1727 (BaseName[0] ? "" : "UB"),
1728 (fD_GetFuncParNum(obj)==illegal ? "" : "FP"), -fD_GetOffset(obj));
1729 if (!vd)
1730 fprintf(outfile, "%s, ", rettype);
1731 fprintf(outfile, "%s, ", name);
1733 for (count=d0; count<numregs; count++)
1735 chtmp=fD_GetRegStr(obj, count);
1736 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1737 chtmp="d7";
1738 fprintf(outfile, "%s, %s, %s%s", (fD_GetFuncParNum(obj)==count ?
1739 "__fpt" : fD_GetProto(obj, count)),
1740 fD_GetParam(obj, count),
1741 chtmp, (count==numregs-1 && !BaseName[0] ? "" : ", "));
1744 if (BaseName[0]) /* was "##base" used? */
1745 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1746 if (fD_GetFuncParNum(obj)!=illegal)
1748 fprintf(outfile, ", ");
1749 fprintf(outfile, fD_GetProto(obj, fD_GetFuncParNum(obj)), "__fpt");
1751 fprintf(outfile, ")\n\n");
1753 else if(target==M68K_POS)
1755 fprintf(outfile, ") \\\n\t__INLINE_FUN_%d(", numregs);
1756 fprintf(outfile, "__%s_BASE_NAME, __%s_LIB_NAME, 0x%lx, %s, %s%s",
1757 BaseNamU, BaseNamU, -fD_GetOffset(obj), rettype, name,
1758 (numregs ? ", \\\n\t" : ""));
1760 for (count=d0; count<numregs; count++)
1761 fprintf(outfile, "%s, %s, %s%s", fD_GetProto(obj, count),
1762 fD_GetParam(obj, count), fD_GetRegStr(obj, count),
1763 (count==numregs-1 ? "" : ", "));
1764 fprintf(outfile, ")\n\n");
1766 else if (target==PPC_POWERUP || target==PPC_MORPHOS)
1768 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1769 numregs,
1770 (vd ? "NR" : ""),
1771 (BaseName[0] ? "" : "UB"),
1772 -fD_GetOffset(obj));
1774 if (!vd)
1775 fprintf(outfile, "%s, ", rettype);
1776 fprintf(outfile, "%s, ", name);
1778 for (count=d0; count<numregs; count++)
1780 chtmp=fD_GetRegStr(obj, count);
1782 if (strchr(fD_GetProto(obj, count),'%'))
1784 sprintf(Buffer,
1785 fD_GetProto(obj, count),
1786 "");
1788 fprintf(outfile, "%s, %s, %s%s",
1789 Buffer,
1790 fD_GetParam(obj, count),
1791 chtmp,
1792 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1794 else
1796 fprintf(outfile, "%s, %s, %s%s",
1797 fD_GetProto(obj, count),//(fD_GetFuncParNum(obj) == count ? "__fpt" : fD_GetProt\o(obj, count)),
1798 fD_GetParam(obj, count),
1799 chtmp,
1800 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1804 if (BaseName[0])
1805 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1808 * Here it would make sense to create a database file to
1809 * integrate optimizations automaticly into every new
1810 * build. Not every function needs a complete flush. For
1811 * example functions with no parameter wouldn`t need a
1812 * PPC flush normally. Or Read(File,Addr,Size); would
1813 * only need a flush for Addr with the Size
1816 fprintf(outfile, ", IF_CACHEFLUSHALL, NULL, 0, IF_CACHEFLUSHALL, NULL, 0");
1817 fprintf(outfile, ")\n\n");
1819 else if (target==IX86BE_AMITHLON)
1821 fprintf(outfile, ") \\\n\tLP%d%s%s(0x%lx, ",
1822 numregs,
1823 (vd ? "NR" : ""),
1824 (BaseName[0] ? "" : "UB"),
1825 -fD_GetOffset(obj));
1827 if (!vd)
1828 fprintf(outfile, "%s, ", rettype);
1829 fprintf(outfile, "%s, ", name);
1831 for (count=d0; count<numregs; count++)
1833 chtmp=fD_GetRegStr(obj, count);
1835 if (strchr(fD_GetProto(obj, count),'%'))
1837 sprintf(Buffer,
1838 fD_GetProto(obj, count),
1839 "");
1841 fprintf(outfile, "%s, %s, %s%s",
1842 Buffer,
1843 fD_GetParam(obj, count),
1844 chtmp,
1845 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1847 else
1849 fprintf(outfile, "%s, %s, %s%s",
1850 fD_GetProto(obj, count),
1851 fD_GetParam(obj, count),
1852 chtmp,
1853 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
1857 if (BaseName[0])
1858 fprintf(outfile, "\\\n\t, %s_BASE_NAME", BaseNamU);
1860 fprintf(outfile, ")\n\n");
1862 else if (target==AROS)
1864 fprintf(outfile, ") \\\n\tAROS_LC%d%s(%s, %s, \\\n",
1865 numregs,
1866 (BaseName[0] ? "" : "I"),
1867 (vd ? "void" : rettype),
1868 name);
1870 for (count=d0; count<numregs; count++)
1872 chtmp=fD_GetRegStrU(obj, count);
1873 fprintf(outfile, "\tAROS_LCA(%s, (%s), %s), \\\n",
1874 fD_GetProto(obj, count),
1875 fD_GetParam(obj, count),
1876 chtmp);
1879 if (BaseName[0]) /* was "##base" used? */
1881 fprintf(outfile, "\tstruct %s *, %s_BASE_NAME, ", StdLib, BaseNamU);
1883 else
1885 fprintf(outfile, "\t/* bt */, /* bn */, ");
1887 fprintf(outfile,
1888 "%ld, /* s */)\n\n",
1889 -fD_GetOffset(obj) / 6);
1891 else
1893 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
1894 return;
1897 else if (output_mode==OLD || output_mode==STUBS)
1899 fprintf(outfile, "%s__inline %s\n%s(%s",
1900 (output_mode==STUBS ? "" : "extern "), rettype, name,
1901 (BaseName[0] ? (numregs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
1903 if (target==M68K_AMIGAOS)
1905 for (count=d0; count<numregs; count++)
1907 chtmp=fD_GetProto(obj, count);
1908 if (fD_GetFuncParNum(obj)==count)
1909 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1910 else
1911 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp+strlen(chtmp)-1)=='*' ?
1912 "" : " "), fD_GetParam(obj, count));
1913 if (count<numregs-1)
1914 fprintf(outfile, ", ");
1917 fprintf(outfile, ")\n{\n%s", (BaseName[0] ? " BASE_EXT_DECL\n" : ""));
1918 if (!vd)
1919 fprintf(outfile, " register %s%sres __asm(\"d0\");\n", rettype,
1920 (*(rettype+strlen(rettype)-1)=='*' ? "" : " "));
1922 if (BaseName[0])
1923 fprintf(outfile, " register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
1924 StdLib);
1926 for (count=d0; count<numregs; count++)
1928 chtmp=fD_GetRegStr(obj, count);
1929 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1930 chtmp="d7";
1931 if (fD_GetFuncParNum(obj)==count)
1933 fprintf(outfile, " register ");
1934 fprintf(outfile, fD_GetProto(obj, count), chtmp);
1935 fprintf(outfile, " __asm(\"%s\") = %s;\n", chtmp, fD_GetParam(obj,
1936 count));
1938 else
1940 const char *proto=fD_GetProto(obj, count);
1941 fprintf(outfile, " register %s%s%s __asm(\"%s\") = %s;\n",
1942 proto, (*(proto+strlen(proto)-1)=='*' ? "" : " "), chtmp,
1943 chtmp, fD_GetParam(obj, count));
1946 if (a45)
1947 fprintf(outfile, " __asm volatile (\"exg d7,%s\\n\\t"
1948 "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", (a45==4 ? "a4" : "a5"),
1949 -fD_GetOffset(obj), (a45==4 ? "a4" : "a5"));
1950 else
1951 fprintf(outfile, " __asm volatile (\"jsr a6@(-0x%lx:W)\"\n",
1952 -fD_GetOffset(obj));
1954 fprintf(outfile, (vd ? " : /* No Output */\n" : " : \"=r\" (res)\n"));
1956 fprintf(outfile, " : ");
1957 if (BaseName[0])
1958 fprintf(outfile, "\"r\" (a6)%s", (numregs ? ", ": ""));
1960 for (count=d0; count<numregs; count++)
1962 chtmp=fD_GetRegStr(obj, count);
1963 if (a45 && (strcmp(chtmp, "a4")==0 || strcmp(chtmp, "a5")==0))
1964 chtmp="d7";
1965 fprintf(outfile, "\"r\" (%s)%s", chtmp, (count<numregs-1 ? ", " : ""));
1967 fprintf(outfile, "\n : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
1969 if (vd)
1970 fprintf(outfile, ", \"cc\", \"memory\");\n}\n\n"); /* { */
1971 else
1972 fprintf(outfile, ", \"cc\", \"memory\");\n return res;\n}\n\n");
1975 else if (target==PPC_POWERUP)
1977 for (count = d0; count < numregs; count++)
1979 chtmp = fD_GetProto(obj, count);
1980 if (fD_GetFuncParNum(obj) == count)
1981 fprintf(outfile, chtmp, fD_GetParam(obj, count));
1982 else
1983 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
1984 "" : " "), fD_GetParam(obj, count));
1985 if (count < numregs - 1)
1986 fprintf(outfile, ", ");
1989 fprintf(outfile, ")\t\n");
1990 fprintf(outfile, "{\t\n");
1991 fprintf(outfile, "struct Caos\tMyCaos;\n");
1992 fprintf(outfile, "\tMyCaos.M68kCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1993 fprintf(outfile, "//\tMyCaos.M68kStart\t=\tNULL;\t\n");
1994 fprintf(outfile, "//\tMyCaos.M68kSize\t\t=\t0;\t\n");
1995 fprintf(outfile, "\tMyCaos.PPCCacheMode\t=\tIF_CACHEFLUSHALL;\t\n");
1996 fprintf(outfile, "//\tMyCaos.PPCStart\t\t=\tNULL;\t\n");
1997 fprintf(outfile, "//\tMyCaos.PPCSize\t\t=\t0;\t\n");
1999 if (numregs > 0)
2001 for (count = d0; count < numregs; count++)
2003 fprintf(outfile, "\tMyCaos.%s\t\t=(ULONG) %s;\t\n",
2004 fD_GetRegStr(obj, count),
2005 fD_GetParam(obj, count));
2009 fprintf(outfile, "\tMyCaos.caos_Un.Offset\t=\t(%ld);\t\n", fD_GetOffset(obj));
2010 if (BaseName[0]) /*
2011 * was "##base" used?
2014 fprintf(outfile, "\tMyCaos.a6\t\t=\t(ULONG) BASE_NAME;\t\n");
2016 if (vd)
2018 fprintf(outfile, "\tPPCCallOS(&MyCaos);\t\n}\n\n");
2020 else
2022 fprintf(outfile, "\treturn((%s)PPCCallOS(&MyCaos));\n}\n\n",
2023 rettype);
2026 else if (target==PPC_MORPHOS)
2028 for (count = d0; count < numregs; count++)
2030 chtmp = fD_GetProto(obj, count);
2031 if (fD_GetFuncParNum(obj) == count)
2032 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2033 else
2034 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2035 "" : " "), fD_GetParam(obj, count));
2036 if (count < numregs - 1)
2037 fprintf(outfile, ", ");
2040 fprintf(outfile, ")\t\n{\t\n");
2042 if (numregs > 0)
2044 for (count = d0; count < numregs; count++)
2046 fprintf(outfile, "\tREG_%s\t\t=\t(ULONG) %s;\n",
2047 fD_GetRegStrU(obj, count), fD_GetParam(obj, count));
2051 if (BaseName[0]) /*
2052 * was "##base" used?
2055 fprintf(outfile, "\tREG_A6\t\t=\t(ULONG) BASE_NAME;\n");
2057 if (vd)
2059 fprintf(outfile, "\t(*MyEmulHandle->EmulCallDirectOS)(%ld);\n}\n\n", fD_GetOffset(obj));
2061 else
2063 fprintf(outfile, "\treturn((%s)(*MyEmulHandle->EmulCallDirectOS)(%ld));\n}\n\n",
2064 rettype, fD_GetOffset(obj));
2067 else if (target==IX86BE_AMITHLON)
2069 #if 0
2070 for (count = d0; count < numregs; count++)
2072 chtmp = fD_GetProto(obj, count);
2073 if (fD_GetFuncParNum(obj) == count)
2074 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2075 else
2076 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2077 "" : " "), fD_GetParam(obj, count));
2078 if (count < numregs - 1)
2079 fprintf(outfile, ", ");
2082 fprintf(outfile, ")\n{\n");
2083 fprintf(outfile, "\tstruct _Regs _regs;\n");
2085 if (numregs > 0)
2087 for (count = d0; count < numregs; count++)
2089 fprintf(outfile, "\t_regs.reg_%s = (ULONG) (%s);\n",
2090 fD_GetRegStr(obj, count),
2091 fD_GetParam(obj, count));
2095 if (BaseName[0])
2097 fprintf(outfile, "\t_regs.reg_a6 = (ULONG) (BASE_NAME);\n");
2100 if (vd)
2102 fprintf(outfile, "\t_CallOS68k(%ld,&_regs);\n}\n\n",
2103 -fD_GetOffset(obj));
2105 else
2107 fprintf(outfile, "\treturn (%s) _CallOS68k(%ld,&_regs);\n}\n\n",
2108 rettype,-fD_GetOffset(obj));
2110 #else
2111 for (count = d0; count < numregs; count++)
2113 chtmp = fD_GetProto(obj, count);
2114 if (fD_GetFuncParNum(obj) == count)
2115 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2116 else
2117 fprintf(outfile, "%s%s%s", chtmp, (*(chtmp + strlen(chtmp) - 1) == '*' ?
2118 "" : " "), fD_GetParam(obj, count));
2119 if (count < numregs - 1)
2120 fprintf(outfile, ", ");
2123 fprintf(outfile, ")\n{\n");
2124 fprintf(outfile, "\t%s LP%d%s%s(0x%lx, ",
2125 (vd ? "" : "return "),
2126 numregs,
2127 (vd ? "NR" : ""),
2128 (BaseName[0] ? "" : "UB"),
2129 -fD_GetOffset(obj));
2131 if (!vd)
2132 fprintf(outfile, "%s, ", rettype);
2133 fprintf(outfile, "%s, ", name);
2135 for (count=d0; count<numregs; count++)
2137 chtmp=fD_GetRegStr(obj, count);
2139 if (strchr(fD_GetProto(obj, count),'%'))
2141 sprintf(Buffer,
2142 fD_GetProto(obj, count),
2143 "");
2145 fprintf(outfile, "%s, %s, %s%s",
2146 Buffer,
2147 fD_GetParam(obj, count),
2148 chtmp,
2149 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2151 else
2153 fprintf(outfile, "%s, %s, %s%s",
2154 fD_GetProto(obj, count),
2155 fD_GetParam(obj, count),
2156 chtmp,
2157 (count == numregs - 1 && !BaseName[0] ? "" : ", "));
2161 if (BaseName[0])
2162 fprintf(outfile, "\\\n\t, BASE_NAME");
2164 fprintf(outfile, ");\n}\n\n");
2165 #endif
2167 else
2169 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2170 return;
2173 else if (output_mode==GATESTUBS || output_mode==GATEPROTO)
2175 int has_base = (BaseName[0] && fD_GetOffset(obj) != 0);
2177 //lcs
2178 if (target==AROS)
2180 for (count=d0; count<numregs; count++)
2182 if (fD_GetFuncParNum(obj) == count)
2184 char funcproto[200]; /* Hope will be enough... */
2185 sprintf(funcproto, "%s_%s_funcproto_%d",
2186 BaseNamC, name, count );
2187 fprintf(outfile, "typedef ");
2188 fprintf(outfile, fD_GetProto(obj, count), funcproto);
2189 fprintf(outfile, ";\n");
2194 if (output_mode==GATESTUBS)
2196 fprintf(outfile, "%s %s%s(",
2197 rettype,
2198 libprefix,
2199 name);
2201 for (count=d0; count<numregs; count++)
2203 chtmp = fD_GetProto(obj, count);
2205 fprintf(outfile, chtmp, "");
2206 fprintf(outfile, "%s",
2207 (count == numregs - 1 && !has_base ? ");\n" : ", "));
2210 if (has_base)
2211 fprintf(outfile, "struct %s *);\n", StdLib);
2214 if (target==M68K_AMIGAOS)
2216 fprintf(outfile, "%s %s%s(\n",
2217 rettype,
2218 gateprefix,
2219 name);
2221 for (count=d0; count<numregs; count++)
2223 chtmp = fD_GetProto(obj, count);
2225 if (fD_GetFuncParNum(obj) == count)
2227 fprintf(outfile, "\t");
2228 fprintf(outfile, chtmp,
2229 fD_GetParam(obj, count));
2230 fprintf(outfile, " __asm(\"%s\")%s",
2231 fD_GetRegStr(obj, count),
2232 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2234 else
2236 fprintf(outfile, "\t%s %s __asm(\"%s\")%s",
2237 chtmp,
2238 fD_GetParam(obj, count),
2239 fD_GetRegStr(obj, count),
2240 (count == numregs - 1 && !has_base ? ")\n" : ",\n"));
2244 if (has_base)
2245 fprintf(outfile, "\tstruct %s * BASE_NAME __asm(\"a6\") )\n", StdLib);
2247 if (output_mode==GATESTUBS)
2248 fprintf(outfile, "{\n");
2250 else if (target==AROS)
2252 fprintf(outfile, "AROS_LH%d%s(%s, %s%s,\n",
2253 numregs,
2254 has_base ? "" : "I",
2255 rettype,
2256 gateprefix,
2257 name);
2259 for (count=d0; count<numregs; count++)
2261 char funcproto[200]; /* Hope will be enough... */
2263 if (fD_GetFuncParNum(obj) == count)
2265 sprintf(funcproto, "%s_%s_funcproto_%d",
2266 BaseNamC, name, count );
2269 fprintf(outfile, "\tAROS_LHA(%s, %s, %s),\n",
2270 fD_GetFuncParNum(obj) == count ? funcproto : fD_GetProto(obj, count),
2271 fD_GetParam(obj, count),
2272 fD_GetRegStrU(obj, count));
2275 fprintf(outfile, "\tstruct %s *, BASE_NAME, %ld, %s)\n",
2276 StdLib,
2277 -fD_GetOffset(obj) / 6,
2278 BaseNamC);
2280 if (output_mode==GATESTUBS)
2281 fprintf(outfile, "{\n");
2283 else if (target==PPC_MORPHOS)
2285 fprintf(outfile, "%s %s%s(void)\n",
2286 rettype,
2287 gateprefix,
2288 name);
2290 if (output_mode==GATESTUBS)
2292 fprintf(outfile, "{\n");
2294 for (count=d0; count<numregs; count++)
2296 chtmp = fD_GetProto(obj, count);
2298 if (fD_GetFuncParNum(obj) == count)
2300 fprintf(outfile, "\t");
2301 fprintf(outfile, chtmp,
2302 fD_GetParam(obj, count));
2303 fprintf(outfile, " = (");
2304 fprintf(outfile, chtmp, "");
2305 fprintf(outfile, ") REG_%s;\n",
2306 fD_GetRegStrU(obj, count));
2308 else
2310 fprintf(outfile, "\t%s %s = (%s) REG_%s;\n",
2311 fD_GetProto(obj, count),
2312 fD_GetParam(obj, count),
2313 fD_GetProto(obj, count),
2314 fD_GetRegStrU(obj, count));
2318 if (has_base)
2319 fprintf(outfile,
2320 "\tstruct %s * BASE_NAME = (struct %s *) REG_A6;\n",
2321 StdLib, StdLib);
2323 fprintf(outfile, "\n");
2326 else if (target==IX86BE_AMITHLON)
2328 fprintf(outfile, "%s %s%s( struct _Regs _regs )\n",
2329 rettype,
2330 gateprefix,
2331 name);
2333 if (output_mode==GATESTUBS)
2335 fprintf(outfile, "{\n");
2337 for (count=d0; count<numregs; count++)
2339 chtmp = fD_GetProto(obj, count);
2341 if (fD_GetFuncParNum(obj) == count)
2343 fprintf(outfile, "\t");
2344 fprintf(outfile, chtmp,
2345 fD_GetParam(obj, count));
2346 fprintf(outfile, " = (");
2347 fprintf(outfile, chtmp, "");
2348 fprintf(outfile, ") _regs.%s;\n",
2349 fD_GetRegStr(obj, count));
2351 else
2353 fprintf(outfile, "\t%s %s = (%s) _regs.%s;\n",
2354 fD_GetProto(obj, count),
2355 fD_GetParam(obj, count),
2356 fD_GetProto(obj, count),
2357 fD_GetRegStr(obj, count));
2361 if (has_base)
2362 fprintf(outfile,
2363 "\tstruct %s * BASE_NAME = (struct %s *) _regs.a6;\n",
2364 StdLib, StdLib);
2366 fprintf(outfile, "\n");
2369 else
2371 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2372 return;
2375 if (output_mode==GATESTUBS)
2377 fprintf(outfile,"\treturn %s%s(",
2378 libprefix,
2379 name);
2381 for (count=d0; count<numregs; count++)
2383 fprintf(outfile, "%s%s",
2384 fD_GetParam(obj, count),
2385 (count == numregs - 1 && !has_base ? ");" : ", "));
2388 if (has_base)
2389 fprintf(outfile, "BASE_NAME);");
2391 fprintf(outfile,"\n}\n\n");
2393 else
2395 fprintf(outfile,";\n");
2397 if (target==AROS)
2399 fprintf(outfile, "#define %s%s AROS_SLIB_ENTRY(%s%s,%s)\n",
2400 gateprefix, name,
2401 gateprefix, name,
2402 BaseNamC);
2405 fprintf(outfile,"\n");
2408 else
2410 fprintf(stderr, "Internal error: Unknown output mode in fD_write().\n");
2411 return;
2414 if ((tagname=aliasfunction(fD_GetName(obj)))!=0 &&
2415 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2417 fprintf(outfile, "#define %s(", tagname);
2418 for (count=d0; count<numregs-1; count++)
2419 fprintf(outfile, "a%d, ", count);
2420 fprintf(outfile, "a%d) %s (", count, name);
2421 for (count=d0; count<numregs-1; count++)
2422 fprintf(outfile, "(a%d), ", count);
2423 fprintf(outfile, "(a%d))\n\n", count);
2426 if ((tagname=taggedfunction(obj))!=0 &&
2427 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2429 if (output_mode!=STUBS)
2431 fprintf( outfile,
2432 "#ifndef %sNO_INLINE_STDARG\n"
2433 "#define %s(",
2434 (target==M68K_POS ? "__" : ""),
2435 tagname);
2437 for (count=d0; count<numregs-1; count++)
2438 fprintf(outfile, "a%d, ", count);
2440 fprintf(outfile, "...) \\\n\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2441 name);
2443 for (count=d0; count<numregs-1; count++)
2444 fprintf(outfile, "(a%d), ", count);
2446 fprintf(outfile, "(%s)_tags);})\n#endif /* !%sNO_INLINE_STDARG */\n\n",
2447 fD_GetProto(obj, fD_RegNum(obj)-1),
2448 (target==M68K_POS ? "__" : ""));
2451 else
2453 if (target==M68K_AMIGAOS || target==IX86BE_AMITHLON)
2455 fprintf(outfile, "__inline %s\n%s(", rettype, tagname);
2457 for (count=d0; count<numregs-1; count++)
2459 chtmp=fD_GetProto(obj, count);
2460 if (count==fD_GetFuncParNum(obj))
2461 fprintf(outfile, chtmp, fD_GetParam(obj, count));
2462 else
2463 fprintf(outfile, "%s%s%s", chtmp,
2464 (*(chtmp+strlen(chtmp)-1)=='*' ? "" : " "),
2465 fD_GetParam(obj, count));
2466 fprintf(outfile, ", ");
2469 fprintf(outfile, "int tag, ...)\n{\n ");
2470 if (!vd)
2471 fprintf(outfile, "return ");
2473 fprintf(outfile, "%s(", name);
2474 for (count=d0; count<numregs-1; count++)
2475 fprintf(outfile, "%s, ", fD_GetParam(obj, count));
2477 fprintf(outfile, "(%s)&tag);\n}\n\n", fD_GetProto(obj, fD_RegNum(obj)-1));
2479 else if (target==PPC_MORPHOS)
2481 int n = 9 - numregs; /* number of regs that contain varargs */
2482 int d = n & 1 ? 4 : 0; /* add 4 bytes if that's an odd number, to avoid splitting a tag */
2483 int taglist = 8; /* offset of the start of the taglist */
2484 int local = (taglist + n * 4 + d + 8 + 15) & ~15; /* size of the stack frame */
2487 * Stack frame:
2489 * 0 - 3: next frame ptr
2490 * 4 - 7: save lr
2491 * 8 - 8+n*4+d+8-1: tag list start
2492 * ? - local-1: padding
2495 fprintf(outfile,
2496 "asm(\"\n"
2497 " .align 2 \n"
2498 " .globl %s \n"
2499 " .type %s,@function\n"
2500 "%s: \n"
2501 " stwu 1,-%d(1) \n" /* create stack frame */
2502 " mflr 0 \n"
2503 " stw 0,%d(1) \n",
2504 tagname, tagname, tagname, local, local + 4);
2507 * If n is odd, one tag is split between regs and stack.
2508 * Copy its ti_Data together with the ti_Tag.
2510 if (d)
2511 fprintf(outfile, " lwz 0,%d(1)\n", local + 8); /* read ti_Data */
2513 * Save the registers
2515 for (count = numregs; count <= 8; count++)
2516 fprintf(outfile, " stw %d,%d(1)\n", count + 2, (count - numregs) * 4 + taglist);
2518 if (d)
2519 fprintf(outfile, " stw 0,%d(1)\n", taglist + n * 4); /* write ti_Data */
2522 * Add TAG_MORE
2524 fprintf(outfile, " li 11,2 \n"
2525 " addi 0,1,%d \n"
2526 " stw 11,%d(1) \n" /* add TAG_MORE */
2527 " stw 0,%d(1) \n", /* ti_Data = &stack_params */
2528 local + 8 + d,
2529 taglist + n * 4 + d,
2530 taglist + n * 4 + d + 4);
2533 if (DirectVarargsCalls)
2535 fprintf(outfile,
2536 " addi %d,1,%d \n" /* vararg_reg = &saved regs */
2537 " bl %s \n",
2538 numregs + 2, taglist, name);
2540 else
2543 * Save the non-varargs registers in the EmulHandle struct.
2545 for (count = 0; count < numregs - 1; count++)
2547 int r = fD_GetReg(obj, count);
2549 fprintf(outfile, " stw %d,%d(2)\n", count + 3, r * 4);
2552 fprintf(outfile,
2553 " lis 12,%s@ha \n"
2554 " addi 0,1,%d \n"
2555 " lwz 11,0x64(2)\n" /* r11 = EmulCallDirectOS */
2556 " stw 0,%d(2) \n" /* REG_?? = taglist */
2557 " mtctr 11 \n"
2558 " lwz 12,%s@l(12)\n"
2559 " li 3,%ld \n" /* r3 = lvo */
2560 " stw 12,56(2) \n" /* REG_A6 = libbase */
2561 " bctrl \n",/* EmulCallOS() */
2562 BaseName, taglist, 4 * fD_GetReg(obj, numregs - 1), BaseName,
2563 fD_GetOffset(obj));
2566 fprintf(outfile," lwz 0,%d(1) \n" /* clear stack frame & return */
2567 " mtlr 0 \n"
2568 " addi 1,1,%d \n"
2569 " blr \n"
2570 ".L%se1: \n"
2571 " .size\t%s,.L%se1-%s\n"
2572 "\");\n\n",
2573 local + 4, local,
2574 tagname, tagname, tagname, tagname);
2576 else
2578 fprintf(stderr, "Internal error: Unknown target in fD_write().\n");
2579 return;
2583 else if ((varname = getvarargsfunction(obj)) != 0 &&
2584 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2586 if (output_mode != STUBS)
2588 fprintf(outfile,
2589 "#ifndef NO_INLINE_VARARGS\n"
2590 "#define %s(", varname);
2592 for (count = d0; count < numregs - 1; count++)
2593 fprintf(outfile, "a%d, ", count);
2595 fprintf(outfile,
2596 "...) \\\n"
2597 "\t({ULONG _tags[] = { __VA_ARGS__ }; %s(",
2598 name);
2600 for (count = d0; count < numregs - 1; count++)
2601 fprintf(outfile, "(a%d), ", count);
2603 fprintf(outfile,
2604 "(%s)_tags);})\n"
2605 "#endif /* !NO_INLINE_VARARGS */\n\n",
2606 fD_GetProto(obj, fD_RegNum(obj) - 1));
2608 else
2610 fprintf(stderr, "can`t create a varargs stub function for %s\n",
2611 varname);
2615 if (strcmp(name, "DoPkt")==0 &&
2616 output_mode!=GATESTUBS && output_mode!=GATEPROTO)
2618 fdDef *objnc=(fdDef*)obj;
2619 char newname[7]="DoPkt0";
2620 objnc->name=newname;
2621 for (count=2; count<7; count++)
2623 regs reg=objnc->reg[count];
2624 char *proto=objnc->proto[count];
2625 objnc->reg[count]=illegal;
2626 objnc->proto[count]=fD_nostring;
2627 fD_write(outfile, objnc);
2628 objnc->reg[count]=reg;
2629 objnc->proto[count]=proto;
2630 newname[5]++;
2632 objnc->name=(char*)name;
2637 varargsfunction(const char* proto, const char* funcname)
2639 const char *end=proto+strlen(proto)-1;
2640 while (isspace(*end))
2641 end--;
2642 if (*end--==';')
2644 while (isspace(*end))
2645 end--;
2646 if (*end--==')')
2648 while (isspace(*end))
2649 end--;
2650 if (!strncmp(end-2, "...", 3))
2652 /* Seems to be a varargs function. Check if it will be recognized
2653 as "tagged". */
2654 unsigned int count;
2655 char fixedname[200]; /* Hope will be enough... */
2656 fdDef *tmpdef;
2658 for (count=0; count<sizeof TagExcTable/sizeof TagExcTable[0];
2659 count+=2)
2660 if (strcmp(funcname, TagExcTable[count+1])==0)
2661 return 1;
2663 if (!(tmpdef=fD_ctor()))
2665 fprintf(stderr, "No mem for FDs\n");
2666 exit(EXIT_FAILURE);
2669 strcpy(fixedname, funcname);
2670 if (strlen(funcname)>4 &&
2671 !strcmp(funcname+strlen(funcname)-4, "Tags"))
2673 /* Might be either nothing or "TagList". */
2674 fixedname[strlen(fixedname)-4]='\0';
2675 fD_NewName(tmpdef, fixedname);
2676 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2677 fD_cmpName))
2678 return 1;
2680 strcat(fixedname, "TagList");
2681 fD_NewName(tmpdef, fixedname);
2682 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2683 fD_cmpName))
2684 return 1;
2686 else
2688 strcat(fixedname, "A");
2689 fD_NewName(tmpdef, fixedname);
2690 if (bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
2691 fD_cmpName))
2692 return 1;
2697 return 0;
2701 ishandleddifferently(const char* proto, const char* funcname)
2703 /* First check if this is a vararg call? */
2704 if (varargsfunction(proto, funcname))
2705 return 1;
2707 /* It might be a dos.library "alias" name. */
2708 if (aliasfunction(funcname))
2709 return 1;
2711 /* It might be one from dos.library/DoPkt() family. */
2712 if (strlen(funcname)==6 && !strncmp(funcname, "DoPkt", 5) &&
2713 funcname[5]>='0' && funcname[6]<='4')
2714 return 1;
2716 /* Finally, it can be intuition.library/ReportMouse1(). */
2717 return !strcmp(funcname, "ReportMouse1");
2720 void
2721 printusage(const char* exename)
2723 fprintf(stderr,
2724 "Usage: %s [options] fd-file clib-file [[-o] output-file]\n"
2725 "Options:\n"
2727 "--mode=MODE\t\tMODE is one of the following:\n"
2728 "\tnew\t\t\tPreprocessor based (default)\n"
2729 "\told\t\t\tInline based\n"
2730 "\tstubs\t\t\tLibrary stubs\n"
2731 "\tgatestubs\t\tLibrary gate stubs\n"
2732 "\tgateproto\t\tLibrary gate prototypes\n"
2733 "\tproto\t\t\tBuild proto files (no clib-file required)\n"
2735 "--target=OS\t\tOS is one of the following: \n"
2736 "\t*-aros\t\t\tAROS (any CPU)\n"
2737 "\ti?86be*-amithlon\tAmithlon (Intel x86)\n"
2738 "\tm68k*-amigaos\t\tAmigaOS (Motorola 68000)\n"
2739 "\tm68k*-pos\t\tPOS (Motorola 68000)\n"
2740 "\tpowerpc*-powerup\tPowerUp (PowerPC)\n"
2741 "\tpowerpc*-morphos\tMorphOS (PowerPC)\n"
2743 "--direct-varargs-calls\tUse direct varargs call for MorphOS stubs\n"
2744 "--gateprefix=PREFIX\tLibrary gate function name prefix\n"
2745 "--libprefix=PREFIX\tLocal function name prefix\n"
2746 "--local\t\t\tUse local includes\n"
2747 "--quiet\t\t\tDon't display warnings\n"
2748 "--version\t\tPrint version number and exit\n\n"
2749 "Compatibility options:\n"
2750 "--new\t\t\tSame as --mode=new\n"
2751 "--old\t\t\tSame as --mode=old\n"
2752 "--stubs\t\t\tSame as --mode=stubs\n"
2753 "--gatestubs\t\tSame as --mode=gatestubs\n"
2754 "--proto\t\t\tSame as --mode=prot\n"
2755 "--pos\t\t\tSame as --target=m68k-pos\n"
2756 "--morphos\t\tSame as --target=powerpc-morphos\n"
2757 "--powerup\t\tSame as --target=powerpc-powerup\n"
2758 , exename);
2761 void output_proto(FILE* outfile)
2763 fprintf(outfile,
2764 "/* Automatically generated header! Do not edit! */\n\n"
2765 "#ifndef PROTO_%s_H\n"
2766 "#define PROTO_%s_H\n\n"
2767 "#include <clib/%s_protos.h>\n\n"
2768 "#ifndef _NO_INLINE\n"
2769 "#ifdef __GNUC__\n"
2770 "#include <inline/%s.h>\n"
2771 "#endif /* __GNUC__ */\n"
2772 "#endif /* !_NO_INLINE */\n\n",
2773 BaseNamU, BaseNamU, BaseNamL, BaseNamL);
2775 if (BaseName[0])
2776 fprintf(outfile,
2777 "#ifndef __NOLIBBASE__\n"
2778 "extern struct %s *\n"
2779 "#ifdef __CONSTLIBBASEDECL__\n"
2780 "__CONSTLIBBASEDECL__\n"
2781 "#endif /* __CONSTLIBBASEDECL__ */\n"
2782 "%s;\n"
2783 "#endif /* !__NOLIBBASE__ */\n\n",
2784 StdLib, BaseName);
2786 fprintf(outfile,
2787 "#endif /* !PROTO_%s_H */\n", BaseNamU);
2790 /******************************************************************************/
2793 main(int argc, char** argv)
2795 fdDef *tmpdef, /* a dummy to contain the name to look for */
2796 *founddef; /* the fdDef for which we found a prototype */
2797 fdFile *myfile;
2798 char *tmpstr;
2799 FILE *outfile;
2800 int closeoutfile=0;
2801 char *fdfilename=0, *clibfilename=0, *outfilename=0;
2803 int count;
2804 Error lerror;
2806 for (count=1; count<argc; count++)
2808 char *option=argv[count];
2809 if (*option=='-')
2811 option++;
2812 if (strcmp(option, "o")==0)
2814 if (count==argc-1 || outfilename)
2816 printusage(argv[0]);
2817 return EXIT_FAILURE;
2819 if (strcmp(argv[++count], "-"))
2820 outfilename=argv[count];
2822 else
2824 if (*option=='-') /* Accept GNU-style '--' options */
2825 option++;
2826 if (strncmp(option, "mode=", 5)==0)
2828 if (strcmp(option+5, "new")==0)
2829 output_mode=NEW;
2830 else if (strcmp(option+5, "old")==0)
2831 output_mode=OLD;
2832 else if (strcmp(option+5, "stubs")==0)
2833 output_mode=STUBS;
2834 else if (strcmp(option+5, "gatestubs")==0)
2835 output_mode=GATESTUBS;
2836 else if (strcmp(option+5, "gateproto")==0)
2837 output_mode=GATEPROTO;
2838 else if (strcmp(option+5, "proto")==0)
2839 output_mode=PROTO;
2841 else if (strncmp(option, "target=", 7)==0)
2843 if (MatchGlob("*-aros",option+7))
2844 target=AROS;
2845 else if (MatchGlob("i?86be*-amithlon",option+7))
2846 target=IX86BE_AMITHLON;
2847 else if (MatchGlob("m68k*-amigaos",option+7))
2848 target=M68K_AMIGAOS;
2849 else if (MatchGlob("m68k*-pos",option+7))
2850 target=M68K_POS;
2851 else if (MatchGlob("powerpc*-powerup",option+7))
2852 target=PPC_POWERUP;
2853 else if (MatchGlob("powerpc*-morphos",option+7))
2854 target=PPC_MORPHOS;
2855 else
2857 printusage(argv[0]);
2858 return EXIT_FAILURE;
2861 else if (strcmp(option, "direct-varargs-calls") == 0)
2862 DirectVarargsCalls = 1;
2863 else if (strncmp(option, "gateprefix=", 11)==0)
2864 gateprefix = option+11;
2865 else if (strncmp(option, "libprefix=", 10)==0)
2866 libprefix = option+10;
2867 else if (strcmp(option, "quiet") == 0)
2868 Quiet = 1;
2869 else if (strcmp(option, "version")==0)
2871 fprintf(stderr, "fd2inline version " VERSION "\n");
2872 return EXIT_SUCCESS;
2874 /* Compatibility options */
2875 else if (strcmp(option, "new")==0)
2876 output_mode=NEW;
2877 else if (strcmp(option, "old")==0)
2878 output_mode=OLD;
2879 else if (strcmp(option, "stubs")==0)
2880 output_mode=STUBS;
2881 else if (strcmp(option, "gatestubs")==0)
2882 output_mode=GATESTUBS;
2883 else if (strcmp(option, "proto")==0)
2884 output_mode=PROTO;
2885 else if (strcmp(option, "pos")==0)
2886 target=M68K_POS;
2887 else if (strcmp(option, "powerup")==0)
2888 target=PPC_POWERUP;
2889 else if (strcmp(option, "morphos")==0)
2890 target=PPC_MORPHOS;
2891 /* Unknown option */
2892 else
2894 printusage(argv[0]);
2895 return EXIT_FAILURE;
2899 else
2901 /* One of the filenames */
2902 if (!fdfilename)
2903 fdfilename=option;
2904 else if (!clibfilename)
2905 clibfilename=option;
2906 else if (!outfilename)
2907 outfilename=option;
2908 else
2910 printusage(argv[0]);
2911 return EXIT_FAILURE;
2916 if (!fdfilename || (!clibfilename && output_mode!=PROTO))
2918 printusage(argv[0]);
2919 return EXIT_FAILURE;
2922 if (target==M68K_POS && output_mode!=NEW)
2924 fprintf(stderr, "Target is not compatible with the mode.\n");
2925 return EXIT_FAILURE;
2928 if (!(arrdefs=malloc(FDS*sizeof(fdDef*))))
2930 fprintf(stderr, "No mem for FDs\n");
2931 return EXIT_FAILURE;
2933 for (count=0; count<FDS; count++)
2934 arrdefs[count]=NULL;
2936 if (!(myfile=fF_ctor(fdfilename)))
2938 fprintf(stderr, "Couldn't open file '%s'.\n", fdfilename);
2939 return EXIT_FAILURE;
2942 lerror=false;
2944 for (count=0; count<FDS && lerror==false; count++)
2946 if (!(arrdefs[count]=fD_ctor()))
2948 fprintf(stderr, "No mem for FDs\n" );
2949 return EXIT_FAILURE;
2953 if ((lerror=fF_readln(myfile))==false)
2955 fF_SetError(myfile, false);
2956 lerror=fD_parsefd(arrdefs[count], myfile);
2959 while (lerror==nodef);
2961 if (count<FDS)
2963 count--;
2964 fD_dtor(arrdefs[count]);
2965 arrdefs[count]=NULL;
2967 fds=count;
2969 qsort(arrdefs, count, sizeof arrdefs[0], fD_cmpName);
2971 if (output_mode!=NEW || target==AROS)
2973 unsigned int count2;
2974 StdLib="Library";
2976 for (count2=0; count2<sizeof LibExcTable/sizeof LibExcTable[0]; count2+=2)
2977 if (strcmp(BaseName, LibExcTable[count2])==0)
2979 StdLib=LibExcTable[count2+1];
2980 break;
2984 fF_dtor(myfile);
2986 if (output_mode!=PROTO)
2988 if (!(myfile=fF_ctor(clibfilename)))
2990 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
2991 return EXIT_FAILURE;
2994 if (!(tmpdef=fD_ctor()))
2996 fprintf(stderr, "No mem for FDs\n");
2997 return EXIT_FAILURE;
3000 for (lerror=false; lerror==false || lerror==nodef;)
3001 if ((lerror=fF_readln(myfile))==false)
3003 fF_SetError(myfile, false); /* continue even on errors */
3004 tmpstr=fF_FuncName(myfile);
3006 if (tmpstr)
3008 fdDef **res;
3009 fD_NewName(tmpdef, tmpstr);
3010 res=(fdDef**)bsearch(&tmpdef, arrdefs, fds, sizeof arrdefs[0],
3011 fD_cmpName);
3013 if (res)
3015 founddef=*res;
3016 DBP(fprintf(stderr, "found (%s).\n", fD_GetName(founddef)));
3017 fF_SetError(myfile, false);
3018 lerror=fD_parsepr(founddef, myfile);
3020 else
3021 if (!ishandleddifferently(myfile->line, tmpstr))
3022 if (!Quiet)
3023 fprintf(stderr, "Don't know what to do with <%s> in line %lu.\n",
3024 tmpstr, myfile->lineno);
3025 free(tmpstr);
3029 fD_dtor(tmpdef);
3031 fF_dtor(myfile);
3034 if (strlen(fdfilename)>7 &&
3035 !strcmp(fdfilename+strlen(fdfilename)-7, "_lib.fd"))
3037 char *str=fdfilename+strlen(fdfilename)-8;
3038 while (str!=fdfilename && str[-1]!='/' && str[-1]!=':')
3039 str--;
3040 //lcs strncpy(BaseNamL, str, strlen(str)-7);
3041 strncpy(BaseNamU, str, strlen(str)-7);
3042 BaseNamU[strlen(str)-7]='\0';
3043 strcpy(BaseNamL, BaseNamU);
3044 strcpy(BaseNamC, BaseNamU);
3046 else
3048 strcpy(BaseNamU, BaseName);
3049 if (strlen(BaseNamU)>4 && strcmp(BaseNamU+strlen(BaseNamU)-4, "Base")==0)
3050 BaseNamU[strlen(BaseNamU)-4]='\0';
3051 if (target==M68K_POS && strncmp(BaseNamU, "gb_", 3)==0)
3052 memmove(BaseNamU, &BaseNamU[3], strlen(&BaseNamU[3])+1);
3053 strcpy(BaseNamL, BaseNamU);
3054 strcpy(BaseNamC, BaseNamU);
3056 StrUpr(BaseNamU);
3057 BaseNamC[0]=toupper(BaseNamC[0]);
3059 if (outfilename)
3061 if (!(outfile=fopen(outfilename, "w")))
3063 fprintf(stderr, "Couldn't open output file.\n");
3064 return EXIT_FAILURE;
3066 else
3068 closeoutfile=1;
3071 else
3072 outfile=stdout;
3074 if (output_mode==PROTO)
3075 output_proto(outfile);
3076 else
3078 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS ||
3079 output_mode==GATESTUBS || output_mode==GATEPROTO)
3081 if (output_mode==GATESTUBS || output_mode==GATEPROTO)
3083 fprintf(outfile,
3084 "/* Automatically generated stubs! Do not edit! */\n\n");
3086 else
3088 fprintf(outfile,
3089 "/* Automatically generated header! Do not edit! */\n\n"
3090 "#ifndef %sINLINE_%s_H\n"
3091 "#define %sINLINE_%s_H\n\n",
3092 (target==M68K_POS ? "__INC_POS_P" : "_"),
3093 BaseNamU,
3094 (target==M68K_POS ? "__INC_POS_P" : "_"),
3095 BaseNamU );
3098 if (output_mode==NEW)
3100 if(target==M68K_POS)
3102 fprintf(outfile,
3103 "#ifndef __INC_POS_PINLINE_MACROS_H\n"
3104 "#include <pInline/macros.h>\n"
3105 "#endif /* !__INC_POS_PINLINE_MACROS_H */\n\n" );
3107 else if(target==AROS)
3109 fprintf(outfile,
3110 "#ifndef AROS_LIBCALL_H\n"
3111 "#include <aros/libcall.h>\n"
3112 "#endif /* !AROS_LIBCALL_H */\n\n");
3114 else
3116 fprintf(outfile,
3117 "#ifndef __INLINE_MACROS_H\n"
3118 "#include <inline/macros.h>\n"
3119 "#endif /* !__INLINE_MACROS_H */\n\n");
3122 else
3124 FILE* clib;
3126 fprintf(outfile,
3127 "#ifndef __INLINE_STUB_H\n"
3128 "#include <inline/stubs.h>\n"
3129 "#endif /* !__INLINE_STUB_H */\n\n");
3131 fprintf(outfile, "#ifdef __CLIB_TYPES__\n" );
3133 clib = fopen( clibfilename, "r" );
3135 if( clib == NULL )
3137 fprintf(stderr, "Couldn't open file '%s'.\n", clibfilename);
3139 else
3141 char* buffer = malloc( 1024 );
3143 if( buffer == NULL )
3145 fprintf(stderr, "No memory for line buffer.\n " );
3147 else
3149 while( fgets( buffer, 1023, clib ) != NULL )
3151 if( buffer[ 0 ] == '#' /* Pre-processor instruction */ ||
3152 strncmp( buffer, "typedef", 7 ) == 0 )
3154 fprintf(outfile, buffer );
3158 free( buffer );
3161 fclose( clib );
3164 fprintf(outfile, "#endif /* __CLIB_TYPES__ */\n\n" );
3166 if(target==AROS)
3168 fprintf(outfile,
3169 "#include <aros/libcall.h>\n\n" );
3171 else if(target==IX86BE_AMITHLON)
3173 fprintf(outfile,
3174 "#ifndef __INLINE_MACROS_H\n"
3175 "#include <inline/macros.h>\n"
3176 "#endif /* __INLINE_MACROS_H */\n\n");
3178 else if (target == PPC_MORPHOS)
3180 fprintf(outfile,
3181 "#include <emul/emulregs.h>\n\n" );
3185 else
3187 fprintf(stderr, "Internal error: Unknown output mode in main().\n");
3189 if (closeoutfile)
3191 fclose(outfile);
3194 return EXIT_FAILURE;
3197 if (BaseName[0])
3199 if (output_mode==NEW)
3201 fprintf(outfile,
3202 "#ifndef %s%s_BASE_NAME\n"
3203 "#define %s%s_BASE_NAME %s\n"
3204 "#endif /* !%s%s_BASE_NAME */\n\n",
3205 (target==M68K_POS ? "__" : ""), BaseNamU,
3206 (target==M68K_POS ? "__" : ""), BaseNamU, BaseName,
3207 (target==M68K_POS ? "__" : ""), BaseNamU);
3208 if (target==M68K_POS)
3209 fprintf(outfile,
3210 "#ifndef __%s_LIB_NAME\n"
3211 "#define __%s_LIB_NAME %s\n"
3212 "#endif /* !__%s_LIB_NAME */\n\n",
3213 BaseNamU, BaseNamU,
3214 (strcmp(BaseName, "gb_ExecBase") ? BaseName : "gb_ExecLib"),
3215 BaseNamU);
3217 else
3218 fprintf(outfile,
3219 "#ifndef BASE_EXT_DECL\n"
3220 "#define BASE_EXT_DECL\n"
3221 "#define BASE_EXT_DECL0 extern struct %s *%s;\n"
3222 "#endif /* !BASE_EXT_DECL */\n"
3223 "#ifndef BASE_PAR_DECL\n"
3224 "#define BASE_PAR_DECL\n"
3225 "#define BASE_PAR_DECL0 void\n"
3226 "#endif /* !BASE_PAR_DECL */\n"
3227 "#ifndef BASE_NAME\n"
3228 "#define BASE_NAME %s\n"
3229 "#endif /* !BASE_NAME */\n\n"
3230 "BASE_EXT_DECL0\n\n", StdLib, BaseName, BaseName);
3233 for (count=0; count<FDS && arrdefs[count]; count++)
3235 DBP(fprintf(stderr, "outputting %ld...\n", count));
3237 fD_write(outfile, arrdefs[count]);
3238 fD_dtor(arrdefs[count]);
3239 arrdefs[count]=NULL;
3242 if (output_mode!=NEW)
3243 if (BaseName[0])
3244 fprintf(outfile,
3245 "#undef BASE_EXT_DECL\n"
3246 "#undef BASE_EXT_DECL0\n"
3247 "#undef BASE_PAR_DECL\n"
3248 "#undef BASE_PAR_DECL0\n"
3249 "#undef BASE_NAME\n\n");
3251 if (output_mode==NEW || output_mode==OLD || output_mode==STUBS)
3253 fprintf(outfile, "#endif /* !%sINLINE_%s_H */\n",
3254 (target==M68K_POS ? "__INC_POS_P" : "_"), BaseNamU);
3258 free(arrdefs);
3260 if (closeoutfile)
3262 fclose(outfile);
3265 return EXIT_SUCCESS;