]> Shamusworld >> Repos - rmac/blob - rmac.c
More correct calculation of ^^ABSCOUNT. Also updated VS project. Now at version 2...
[rmac] / rmac.c
1 //
2 // RMAC - Reboot's Macro Assembler for all Atari computers
3 // RMAC.C - Main Application Code
4 // Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends
5 // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
6 // Source utilised with the kind permission of Landon Dyer
7 //
8
9 #include "rmac.h"
10 #include "6502.h"
11 #include "debug.h"
12 #include "direct.h"
13 #include "dsp56k.h"
14 #include "error.h"
15 #include "expr.h"
16 #include "listing.h"
17 #include "mark.h"
18 #include "macro.h"
19 #include "object.h"
20 #include "procln.h"
21 #include "riscasm.h"
22 #include "sect.h"
23 #include "symbol.h"
24 #include "token.h"
25 #include "version.h"
26
27 int perm_verb_flag;                             // Permanently verbose, interactive mode
28 int list_flag;                                  // "-l" listing flag on command line
29 int list_pag = 1;                               // Enable listing pagination by default
30 int verb_flag;                                  // Be verbose about what's going on
31 int m6502;                                              // 1, assembling 6502 code
32 int as68_flag;                                  // as68 kludge mode
33 int glob_flag;                                  // Assume undefined symbols are global
34 int lsym_flag;                                  // Include local symbols in object file
35 int sbra_flag;                                  // Warn about possible short branches
36 int prg_flag;                                   // !=0, produce .PRG executable (2=symbols)
37 int prg_extend;                                 // !=0, output extended .PRG symbols
38 int legacy_flag;                                // Do stuff like insert code in RISC assembler
39 int obj_format;                                 // Object format flag
40 int debug;                                              // [1..9] Enable debugging levels
41 int err_flag;                                   // '-e' specified
42 int err_fd;                                             // File to write error messages to
43 int rgpu, rdsp;                                 // Assembling Jaguar GPU or DSP code
44 int robjproc;                                   // Assembling Jaguar Object Processor code
45 int dsp56001;                                   // Assembling DSP 56001 code
46 int list_fd;                                    // File to write listing to
47 int regbank;                                    // RISC register bank
48 int segpadsize;                                 // Segment padding size
49 int endian;                                             // Host processor endianess (0 = LE, 1 = BE)
50 char * objfname;                                // Object filename pointer
51 char * firstfname;                              // First source filename
52 char * cmdlnexec;                               // Executable name, pointer to ARGV[0]
53 char * searchpath;                              // Search path for include files
54 char defname[] = "noname.o";    // Default output filename
55 int optim_flags[OPT_COUNT];             // Specific optimisations on/off matrix
56 int activecpu = CPU_68000;              // Active 68k CPU (68000 by default)
57 int activefpu = FPU_NONE;               // Active FPU (none by default)
58
59
60 //
61 // Convert a string to uppercase
62 //
63 void strtoupper(char * s)
64 {
65         while (*s)
66                 *s++ &= 0xDF;
67 }
68
69
70 //
71 // Manipulate file extension.
72 //
73 // 'name' must be large enough to hold any possible filename. If 'stripp' is
74 // nonzero, any old extension is removed. If the file does not already have an
75 // extension, 'extension' is appended to the filename.
76 //
77 char * fext(char * name, char * extension, int stripp)
78 {
79         char * s;
80
81         // Find beginning of "real" name (strip off path)
82         char * beg = strrchr(name, SLASHCHAR);
83
84         if (beg == NULL)
85                 beg = name;
86
87         // Clobber any old extension, if requested
88         if (stripp)
89         {
90                 for(s=beg; *s && *s!='.'; ++s)
91                         ;
92
93                 *s = '\0';
94         }
95
96         if (strrchr(beg, '.') == NULL)
97                 strcat(beg, extension);
98
99         return name;
100 }
101
102
103 //
104 // Return 'item'nth element of semicolon-seperated pathnames specified in the
105 // enviroment string 's'. Copy the pathname to 'buf'.  Return 0 if the 'item'
106 // nth path doesn't exist.
107 //
108 // ['item' ranges from 0 to N-1, where N = #elements in search path]
109 //
110 int nthpath(char * env_var, int itemno, char * buf)
111 {
112         char * s = searchpath;
113
114         if (s == NULL)
115                 s = getenv(env_var);
116
117         if (s == NULL)
118                 return 0;
119
120         while (itemno--)
121                 while (*s != EOS && *s++ != ';')
122                         ;
123
124         if (*s == EOS)
125                 return 0;
126
127         while (*s != EOS && *s != ';')
128                 *buf++ = *s++;
129
130         *buf++ = EOS;
131
132         return 1;
133 }
134
135
136 //
137 // Display command line help
138 //
139 void DisplayHelp(void)
140 {
141         printf("Usage:\n"
142                 "    %s [options] srcfile\n"
143                 "\n"
144                 "Options:\n"
145                 "  -? or -h          Display usage information\n"
146                 "  -dsymbol[=value]  Define symbol (with optional value, default=0)\n"
147                 "  -e[errorfile]     Send error messages to file, not stdout\n"
148                 "  -f[format]        Output object file format\n"
149                 "                    a: ALCYON (use this for ST)\n"
150                 "                    b: BSD (use this for Jaguar)\n"
151                 "                    e: ELF\n"
152                 "                    p: P56 (use this for DSP56001 only)\n"
153                 "                    l: LOD (use this for DSP56001 only)\n"
154                 "                    x: com/exe/xex (Atari 800)\n"
155                 "  -i[path]          Directory to search for include files\n"
156                 "  -l[filename]      Create an output listing file\n"
157                 "  -l*[filename]     Create an output listing file without pagination\n"
158                 "  -m[cpu]           Select default CPU. Available options:\n"
159                 "                    68000\n"
160                 "                    68020\n"
161                 "                    68030\n"
162                 "                    68040\n"
163                 "                    68060\n"
164                 "                    6502\n"
165                 "                    tom\n"
166                 "                    jerry\n"
167                 "                    56001\n"
168                 "  -n                Don't do things behind your back in RISC assembler\n"
169                 "  -o file           Output file name\n"
170                 "  +o[value]         Turn a specific optimisation on\n"
171                 "                    Available optimisation values and default settings:\n"
172                 "                    o0: Absolute long adddresses to word        (on)\n"
173                 "                    o1: move.l #x,dn/an to moveq                (on)\n"
174                 "                    o2: Word branches to short                  (on)\n"
175                 "                    o3: Outer displacement 0(an) to (an)        (off)\n"
176                 "                    o4: lea size(An),An to addq #size,An        (off)\n"
177                 "                    o5: Absolute long base displacement to word (off)\n"
178                 "                    o6: Null branches to NOP                    (off)\n"
179                 "                    o7: clr.l Dx to moveq #0,Dx                 (off)\n"
180                 "                    o8: adda.w/l #x,Dy to addq.w/l #x,Dy        (off)\n"
181                 "                    o9: adda.w/l #x,Dy to lea x(Dy),Dy          (off)\n"
182                 "  ~o[value]         Turn a specific optimisation off\n"
183                 "  +oall             Turn all optimisations on\n"
184                 "  ~oall             Turn all optimisations off\n"
185                 "  -p                Create an ST .prg (without symbols)\n"
186                 "  -ps               Create an ST .prg (with symbols)\n"
187                 "  -px               Create an ST .prg (with exsymbols)\n"
188                 "                    Forces -fa\n"
189                 "  -r[size]          Pad segments to boundary size specified\n"
190                 "                    w: word (2 bytes, default alignment)\n"
191                 "                    l: long (4 bytes)\n"
192                 "                    p: phrase (8 bytes)\n"
193                 "                    d: double phrase (16 bytes)\n"
194                 "                    q: quad phrase (32 bytes)\n"
195                 "  -s                Warn about possible short branches\n"
196                 "                    and applied optimisations\n"
197                 "  -u                Force referenced and undefined symbols global\n"
198                 "  -v                Set verbose mode\n"
199                 "  -x                Turn on debugging mode\n"
200                 "  -y[pagelen]       Set page line length (default: 61)\n"
201                 "\n", cmdlnexec);
202 }
203
204
205 //
206 // Display version information
207 //
208 void DisplayVersion(void)
209 {
210         printf("\n"
211                 " _ __ _ __ ___   __ _  ___ \n"
212                 "| '__| '_ ` _ \\ / _` |/ __|\n"
213                 "| |  | | | | | | (_| | (__ \n"
214                 "|_|  |_| |_| |_|\\__,_|\\___|\n"
215                 "\nReboot's Macro Assembler\n"
216                 "Copyright (C) 199x Landon Dyer, 2011-2019 Reboot\n"
217                 "V%01i.%01i.%01i %s (%s)\n\n", MAJOR, MINOR, PATCH, __DATE__, PLATFORM);
218 }
219
220
221 //
222 // Parse optimisation options
223 //
224 int ParseOptimization(char * optstring)
225 {
226         int onoff = 0;
227
228         if (*optstring == '+')
229                 onoff = 1;
230         else if (*optstring != '~')
231                 return ERROR;
232
233         if ((optstring[2] == 'a' || optstring[2] == 'A')
234                 && (optstring[3] == 'l' || optstring[3] == 'L')
235                 && (optstring[4] == 'l' || optstring[4] == 'L'))
236         {
237                 memset(optim_flags, onoff, OPT_COUNT * sizeof(int));
238                 return OK;
239         }
240         else if (optstring[1] == 'o' || optstring[1] == 'O') // Turn on specific optimisation
241         {
242                 int opt_no = atoi(&optstring[2]);
243
244                 if ((opt_no >= 0) && (opt_no < OPT_COUNT))
245                 {
246                         optim_flags[opt_no] = onoff;
247                         return OK;
248                 }
249                 else
250                         return ERROR;
251         }
252         else
253         {
254                 return ERROR;
255         }
256 }
257
258
259 //
260 // Process command line arguments and do an assembly
261 //
262 int Process(int argc, char ** argv)
263 {
264         int argno;                                              // Argument number
265         SYM * sy;                                               // Pointer to a symbol record
266         char * s;                                               // String pointer
267         int fd;                                                 // File descriptor
268         char fnbuf[FNSIZ];                              // Filename buffer
269         int i;                                                  // Iterator
270
271         errcnt = 0;                                             // Initialize error count
272         listing = 0;                                    // Initialize listing level
273         list_flag = 0;                                  // Initialize listing flag
274         verb_flag = perm_verb_flag;             // Initialize verbose flag
275         as68_flag = 0;                                  // Initialize as68 kludge mode
276         glob_flag = 0;                                  // Initialize .globl flag
277         sbra_flag = 0;                                  // Initialize short branch flag
278         debug = 0;                                              // Initialize debug flag
279         searchpath = NULL;                              // Initialize search path
280         objfname = NULL;                                // Initialize object filename
281         list_fname = NULL;                              // Initialize listing filename
282         err_fname = NULL;                               // Initialize error filename
283         obj_format = BSD;                               // Initialize object format
284         firstfname = NULL;                              // Initialize first filename
285         err_fd = ERROUT;                                // Initialize error file descriptor
286         err_flag = 0;                                   // Initialize error flag
287         rgpu = 0;                                               // Initialize GPU assembly flag
288         rdsp = 0;                                               // Initialize DSP assembly flag
289         robjproc = 0;                                   // Initialize OP assembly flag
290         lsym_flag = 1;                                  // Include local symbols in object file
291         regbank = BANK_N;                               // No RISC register bank specified
292         orgactive = 0;                                  // Not in RISC org section
293         orgwarning = 0;                                 // No ORG warning issued
294         segpadsize = 2;                                 // Initialize segment padding size
295     dsp_orgmap[0].start = 0;            // Initialize 56001 org initial address
296     dsp_orgmap[0].memtype = ORG_P;      // Initialize 56001 org start segment
297         m6502 = 0;                                              // 6502 mode off by default
298
299         // Initialize modules
300         InitSymbolTable();                              // Symbol table
301         InitTokenizer();                                // Tokenizer
302         InitLineProcessor();                    // Line processor
303         InitExpression();                               // Expression analyzer
304         InitSection();                                  // Section manager / code generator
305         InitMark();                                             // Mark tape-recorder
306         InitMacro();                                    // Macro processor
307         InitListing();                                  // Listing generator
308         Init6502();                                             // 6502 assembler
309
310         // Process command line arguments and assemble source files
311         for(argno=0; argno<argc; argno++)
312         {
313                 if (*argv[argno] == '-')
314                 {
315                         switch (argv[argno][1])
316                         {
317                         case 'd':                               // Define symbol
318                         case 'D':
319                                 for(s=argv[argno]+2; *s!=EOS;)
320                                 {
321                                         if (*s++ == '=')
322                                         {
323                                                 s[-1] = EOS;
324                                                 break;
325                                         }
326                                 }
327
328                                 if (argv[argno][2] == EOS)
329                                 {
330                                         printf("-d: empty symbol\n");
331                                         errcnt++;
332                                         return errcnt;
333                                 }
334
335                                 sy = lookup(argv[argno] + 2, 0, 0);
336
337                                 if (sy == NULL)
338                                 {
339                                         sy = NewSymbol(argv[argno] + 2, LABEL, 0);
340                                         sy->svalue = 0;
341                                 }
342
343                                 sy->sattr = DEFINED | EQUATED | ABS;
344                                 sy->svalue = (*s ? (uint64_t)atoi(s) : 0);
345                                 break;
346                         case 'e':                               // Redirect error message output
347                         case 'E':
348                                 err_fname = argv[argno] + 2;
349                                 break;
350                         case 'f':                               // -f<format>
351                         case 'F':
352                                 switch (argv[argno][2])
353                                 {
354                                 case EOS:
355                                 case 'a':                       // -fa = Alcyon [the default]
356                                 case 'A':
357                                         obj_format = ALCYON;
358                                         break;
359                                 case 'b':                       // -fb = BSD (Jaguar Recommended: 3 out 4 jaguars recommend it!)
360                                 case 'B':
361                                         obj_format = BSD;
362                                         break;
363                                 case 'e':                       // -fe = ELF
364                                 case 'E':
365                                         obj_format = ELF;
366                                         break;
367                 case 'l':           // -fl = LOD
368                 case 'L':
369                     obj_format = LOD;
370                     break;
371                 case 'p':           // -fp = P56
372                 case 'P':
373                     obj_format = P56;
374                                         break;
375                                 case 'x':                       // -fx = COM/EXE/XEX
376                                 case 'X':
377                                         obj_format = XEX;
378                                         break;
379                                 default:
380                                         printf("-f: unknown object format specified\n");
381                                         errcnt++;
382                                         return errcnt;
383                                 }
384                                 break;
385                         case 'g':                               // Debugging flag
386                         case 'G':
387                                 printf("Debugging flag (-g) not yet implemented\n");
388                                 break;
389                         case 'i':                               // Set directory search path
390                         case 'I':
391                                 searchpath = argv[argno] + 2;
392                                 break;
393                         case 'l':                               // Produce listing file
394                         case 'L':
395                                 if (*(argv[argno] + 2) == '*')
396                                 {
397                                         list_fname = argv[argno] + 3;
398                                         list_pag = 0;    // Special case - turn off pagination
399                                 }
400                                 else
401                                 {
402                                         list_fname = argv[argno] + 2;
403                                 }
404
405                                 listing = 1;
406                                 list_flag = 1;
407                                 lnsave++;
408                                 break;
409                         case 'm':
410                         case 'M':
411                                 if (strcmp(argv[argno] + 2, "68000") == 0)
412                                         d_68000();
413                                 else if (strcmp(argv[argno] + 2, "68020") == 0)
414                                         d_68020();
415                                 else if (strcmp(argv[argno] + 2, "68030") == 0)
416                                         d_68030();
417                                 else if (strcmp(argv[argno] + 2, "68040") == 0)
418                                         d_68040();
419                                 else if (strcmp(argv[argno] + 2, "68060") == 0)
420                                         d_68060();
421                                 else if (strcmp(argv[argno] + 2, "68881") == 0)
422                                         d_68881();
423                                 else if (strcmp(argv[argno] + 2, "68882") == 0)
424                                         d_68882();
425                                 else if (strcmp(argv[argno] + 2, "56001") == 0)
426                                         d_56001();
427                                 else if (strcmp(argv[argno] + 2, "6502") == 0)
428                                         d_6502();
429                                 else if (strcmp(argv[argno] + 2, "tom") == 0)
430                                         d_gpu();
431                                 else if (strcmp(argv[argno] + 2, "jerry") == 0)
432                                         d_dsp();
433                                 else
434                                 {
435                                         printf("Unrecognized CPU '%s'\n", argv[argno] + 2);
436                                         errcnt++;
437                                         return errcnt;
438                                 }
439                                 break;
440                         case 'o':                               // Direct object file output
441                         case 'O':
442                                 if (argv[argno][2] != EOS)
443                                         objfname = argv[argno] + 2;
444                                 else
445                                 {
446                                         if (++argno >= argc)
447                                         {
448                                                 printf("Missing argument to -o");
449                                                 errcnt++;
450                                                 return errcnt;
451                                         }
452
453                                         objfname = argv[argno];
454                                 }
455
456                                 break;
457                         case 'p':               /* -p: generate ".PRG" executable output */
458                         case 'P':
459                                 /*
460                                  * -p           .PRG generation w/o symbols
461                                  * -ps          .PRG generation with symbols
462                                  * -px          .PRG generation with extended symbols
463                                  */
464                                 switch (argv[argno][2])
465                                 {
466                                         case EOS:
467                                                 prg_flag = 1;
468                                                 break;
469
470                                         case 's':
471                                         case 'S':
472                                                 prg_flag = 2;
473                                                 break;
474
475                                         case 'x':
476                                         case 'X':
477                                                 prg_flag = 3;
478                                                 break;
479
480                                         default:
481                                                 printf("-p: syntax error\n");
482                                                 errcnt++;
483                                                 return errcnt;
484                                 }
485
486                                 // Enforce Alcyon object format - kind of silly
487                                 // to ask for .prg output without it!
488                                 obj_format = ALCYON;
489                                 break;
490                         case 'r':                               // Pad seg to requested boundary size
491                         case 'R':
492                                 switch(argv[argno][2])
493                                 {
494                                 case 'w': case 'W': segpadsize = 2;  break;
495                                 case 'l': case 'L': segpadsize = 4;  break;
496                                 case 'p': case 'P': segpadsize = 8;  break;
497                                 case 'd': case 'D': segpadsize = 16; break;
498                                 case 'q': case 'Q': segpadsize = 32; break;
499                                 default: segpadsize = 2; break; // Effective autoeven();
500                                 }
501                                 break;
502                         case 's':                               // Warn about possible short branches
503                         case 'S':
504                                 sbra_flag = 1;
505                                 break;
506                         case 'u':                               // Make undefined symbols .globl
507                         case 'U':
508                                 glob_flag = 1;
509                                 break;
510                         case 'v':                               // Verbose flag
511                         case 'V':
512                                 verb_flag++;
513
514                                 if (verb_flag > 1)
515                                         DisplayVersion();
516
517                                 break;
518                         case 'x':                               // Turn on debugging
519                         case 'X':
520                                 debug = 1;
521                                 printf("~ Debugging ON\n");
522                                 break;
523                         case 'y':                               // -y<pagelen>
524                         case 'Y':
525                                 pagelen = atoi(argv[argno] + 2);
526
527                                 if (pagelen < 10)
528                                 {
529                                         printf("-y: bad page length\n");
530                                         errcnt++;
531                                         return errcnt;
532                                 }
533
534                                 break;
535                         case EOS:                               // Input is stdin
536                                 if (firstfname == NULL) // Kludge first filename
537                                         firstfname = defname;
538
539                                 include(0, "(stdin)");
540                                 Assemble();
541                                 break;
542                         case 'h':                               // Display command line usage
543                         case 'H':
544                         case '?':
545                                 DisplayVersion();
546                                 DisplayHelp();
547                                 errcnt++;
548                                 break;
549                         case 'n':                               // Turn off legacy mode
550                         case 'N':
551                                 legacy_flag = 0;
552                                 printf("Legacy mode OFF\n");
553                                 break;
554                         default:
555                                 DisplayVersion();
556                                 printf("Unknown switch: %s\n\n", argv[argno]);
557                                 DisplayHelp();
558                                 errcnt++;
559                                 break;
560                         }
561                 }
562                 else if (*argv[argno] == '+' || *argv[argno] == '~')
563                 {
564                         if (ParseOptimization(argv[argno]) != OK)
565                         {
566                                 DisplayVersion();
567                                 printf("Unknown switch: %s\n\n", argv[argno]);
568                                 DisplayHelp();
569                                 errcnt++;
570                                 break;
571                         }
572                 }
573                 else
574                 {
575                         // Record first filename.
576                         if (firstfname == NULL)
577                                 firstfname = argv[argno];
578
579                         strcpy(fnbuf, argv[argno]);
580                         fext(fnbuf, ".s", 0);
581                         fd = open(fnbuf, 0);
582
583                         if (fd < 0)
584                         {
585                                 printf("Cannot open: %s\n", fnbuf);
586                                 errcnt++;
587                                 continue;
588                         }
589
590                         include(fd, fnbuf);
591                         Assemble();
592                 }
593         }
594
595         // Wind-up processing;
596         // o  save current section (no more code generation)
597         // o  do auto-even of all sections (or boundary alignment as requested
598         //    through '-r')
599     // o  save the last pc value for 6502 (if we used 6502 at all) and
600     //    detemine if the last section contains anything
601         // o  determine name of object file:
602         //    -  "foo.o" for linkable output;
603         //    -  "foo.prg" for GEMDOS executable (-p flag).
604         SaveSection();
605         int temp_section = cursect;
606
607         for(i=TEXT; i<=BSS; i<<=1)
608         {
609                 SwitchSection(i);
610
611                 switch(segpadsize)
612                 {
613                 case 2:  d_even();    break;
614                 case 4:  d_long();    break;
615                 case 8:  d_phrase();  break;
616                 case 16: d_dphrase(); break;
617                 case 32: d_qphrase(); break;
618                 }
619
620                 SaveSection();
621         }
622
623         SwitchSection(M6502);
624
625         if (sloc != currentorg[0])
626         {
627                 currentorg[1] = sloc;
628                 currentorg += 2;
629         }
630
631         // This looks like an awful kludge...  !!! FIX !!!
632         if (temp_section & (M56001P | M56001X | M56001Y))
633         {
634                 SwitchSection(temp_section);
635
636                 if (chptr != dsp_currentorg->start)
637                 {
638                         dsp_currentorg->end = chptr;
639                         dsp_currentorg++;
640                 }
641         }
642
643         SwitchSection(TEXT);
644
645         if (objfname == NULL)
646         {
647                 if (firstfname == NULL)
648                         firstfname = defname;
649
650                 strcpy(fnbuf, firstfname);
651                 fext(fnbuf, (prg_flag ? ".prg" : ".o"), 1);
652                 objfname = fnbuf;
653         }
654
655         // With one pass finished, go back and:
656         // (1)   run through all the fixups and resolve forward references;
657         // (1.5) ensure that remaining fixups can be handled by the linker
658         //       (`lo68' format, extended (postfix) format....)
659         // (2)   generate the output file image and symbol table;
660         // (3)   generate relocation information from left-over fixups.
661         ResolveAllFixups();                                             // Do all fixups
662         StopMark();                                                             // Stop mark tape-recorder
663
664         if (errcnt == 0)
665         {
666                 if ((fd = open(objfname, _OPEN_FLAGS, _PERM_MODE)) < 0)
667                         CantCreateFile(objfname);
668
669                 if (verb_flag)
670                 {
671                         s = (prg_flag ? "executable" : "object");
672                         printf("[Writing %s file: %s]\n", s, objfname);
673                 }
674
675                 WriteObject(fd);
676                 close(fd);
677
678                 if (errcnt != 0)
679                         unlink(objfname);
680         }
681
682         if (list_flag)
683         {
684                 if (verb_flag)
685                         printf("[Wrapping-up listing file]\n");
686
687                 listing = 1;
688                 symtable();
689                 close(list_fd);
690         }
691
692         if (err_flag)
693                 close(err_fd);
694
695         DEBUG dump_everything();
696
697         return errcnt;
698 }
699
700
701 //
702 // Determine processor endianess
703 //
704 int GetEndianess(void)
705 {
706         int i = 1;
707         char * p = (char *)&i;
708
709         if (p[0] == 1)
710                 return 0;
711
712         return 1;
713 }
714
715
716 //
717 // Application entry point
718 //
719 int main(int argc, char ** argv)
720 {
721         perm_verb_flag = 0;                             // Clobber "permanent" verbose flag
722         legacy_flag = 1;                                // Default is legacy mode on (:-P)
723
724         // Set legacy optimisation flags to on and everything else to off
725         memset(optim_flags, 0, OPT_COUNT * sizeof(int));
726         optim_flags[OPT_ABS_SHORT] =
727                 optim_flags[OPT_MOVEL_MOVEQ] =
728                 optim_flags[OPT_BSR_BCC_S] = 1;
729
730         cmdlnexec = argv[0];                    // Obtain executable name
731         endian = GetEndianess();                // Get processor endianess
732
733         // If commands were passed in, process them
734         if (argc > 1)
735                 return Process(argc - 1, argv + 1);
736
737         DisplayVersion();
738         DisplayHelp();
739
740         return 0;
741 }
742