OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [software/] [AS64/] [source/] [main.cpp] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2016-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// AS64 - Assembler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
 
28
#define MAX_PASS  6
29
 
30
int gCpu = 888;
31
int verbose = 1;
32
int debug = 1;
33
int listing = 1;
34
int binary_out = 1;
35
int verilog_out = 1;
36
int elf_out = 1;
37
int rel_out = 0;
38
int coe_out = 0;
39
int code_bits = 32;
40
int data_bits = 32;
41
int pass;
42
int lineno;
43
char *inptr;
44
char *stptr;
45
char *pif1, *pif2;
46
int token;
47
int phasing_errors;
48
int pe1, pe2, pe3;
49
int bGen = 0;
50
bool bGenListing = false;
51
char fSeg = 0;
52
int segment;
53
int segprefix = -1;
54
int segmodel = 0;
55
int64_t program_address;
56
int64_t code_address;
57
int64_t data_address;
58
int64_t bss_address;
59
int64_t start_address;
60
FILE *ofp, *vfp;
61
int regno;
62
char first_org = 1;
63
char current_label[500];
64
 
65
char buf[10000];
66
char masterFile[10000000];
67
char segmentFile[10000000];
68
int NumSections = 12;
69
clsElf64Section sections[12];
70
NameTable nmTable;
71
char codebuf[10000000];
72
char rodatabuf[10000000];
73
char databuf[10000000];
74
char bssbuf[10000000];
75
char tlsbuf[10000000];
76
uint8_t binfile[10000000];
77
uint64_t binfilex36[10000000];
78
int binndx;
79
int64_t binstart;
80
int mfndx;
81
int codendx;
82
int datandx;
83
int rodatandx;
84
int tlsndx;
85
int bssndx;
86
SYM *lastsym;
87
int isInitializationData;
88
float num_bytes;
89
int num_insns;
90
int num_cinsns;
91
HTBLE hTable[100000];
92
int htblmax;
93
int processOpt;
94
int gCanCompress = 1;
95
int expandedBlock;
96
int expand_flag;
97
int compress_flag;
98
int vebits = 128;
99
void emitCode(int cd);
100
void emitAlignedCode(int cd);
101
void process_shifti(int oc,int fn);
102
void processFile(char *fname, int searchincl);
103
void bump_address();
104
extern void Table888_bump_address();
105
extern void searchenv(char *filename, char *envname, char **pathname);
106
extern void Table888mmu_processMaster();
107
extern void Friscv_processMaster();
108
extern void FISA64_processMaster();
109
extern void Thor_processMaster();
110
extern void dsd6_processMaster();
111
extern void dsd7_processMaster();
112
extern void dsd9_processMaster();
113
extern void FT64_processMaster();
114
extern void FT64x36_processMaster();
115
extern void SymbolInit();
116
extern void dsd9_VerilogOut(FILE *fp);
117
 
118
// ---------------------------------------------------------------------------
119
// ---------------------------------------------------------------------------
120
 
121
void displayHelp()
122
{
123
     printf("a64 [options] file\r\n");
124
     printf("    +v      = verbose output\r\n");
125
     printf("    +r      = relocatable output\r\n");
126
     printf("    -s      = non-segmented\r\n");
127
     printf("    +g[n]   = cpu version 8=Table888, 9=Table888mmu V=RISCV 6=FISA64 T=Thor\r\n");
128
     printf("                          D=DSD6 7=DSD7 A=DSD9 F=FT64 G=FT64x36\r\n");
129
     printf("    -o[bvlc] = suppress output file b=binary, v=verilog, l=listing, c=coe\r\n");
130
}
131
 
132
int hcmp(const void *a1, const void *b1)
133
{
134
    HTBLE *a = (HTBLE *)a1;
135
    HTBLE *b = (HTBLE *)b1;
136
    return (a->count < b->count) ? 1 : (a->count==b->count) ? 0 : -1;
137
}
138
 
139
// ----------------------------------------------------------------------------
140
// ----------------------------------------------------------------------------
141
 
142
void DumphTable()
143
{
144
    int nn;
145
    HTBLE *pt;
146
 
147
   pt = (HTBLE *)hTable;
148
 
149
   // Sort the table (already sorted)
150
//   qsort(pt, htblmax, sizeof(HTBLE), hcmp);
151
 
152
   if (gCpu=='F') {
153
    fprintf(ofp, "%d compressable instructions\n", htblmax);
154
    fprintf(ofp, "The top 256 are:\n", htblmax);
155
    fprintf(ofp, "Comp  Opcode  Count\n");
156
    for (nn = 0; nn < htblmax && nn < 256; nn++) {
157
        fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
158
    }
159
        return;
160
   }
161
    fprintf(ofp, "%d compressable instructions\n", htblmax);
162
    fprintf(ofp, "The top 1024 are:\n", htblmax);
163
    fprintf(ofp, "Comp  Opcode  Count\n");
164
    for (nn = 0; nn < htblmax && nn < 1024; nn++) {
165
        fprintf(ofp, " %03X %08X %d\n", nn, hTable[nn].opcode, hTable[nn].count);
166
    }
167
}
168
 
169
// ---------------------------------------------------------------------------
170
// ---------------------------------------------------------------------------
171
 
172
int processOptions(int argc, char **argv)
173
{
174
    int nn, mm;
175
 
176
    segmodel = 0;
177
    nn = 1;
178
    do {
179
        if (nn >= argc-1)
180
           break;
181
        if (argv[nn][0]=='-') {
182
           if (argv[nn][1]=='o') {
183
               mm = 2;
184
               while(argv[nn][mm] && !isspace(argv[nn][mm])) {
185
                   if (argv[nn][mm]=='b')
186
                       binary_out = 0;
187
                   else if (argv[nn][mm]=='l')
188
                       listing = 0;
189
                   else if (argv[nn][mm]=='v')
190
                       verilog_out = 0;
191
                   else if (argv[nn][mm]=='e')
192
                       elf_out = 0;
193
               }
194
           }
195
           if (argv[nn][1]=='s')
196
               fSeg = 0;
197
           nn++;
198
        }
199
        else if (argv[nn][0]=='+') {
200
           mm = 2;
201
           if (argv[nn][1]=='r') {
202
               rel_out = 1;
203
           }
204
           if (argv[nn][1]=='s')
205
               fSeg = 1;
206
           if (argv[nn][1]=='g') {
207
              if (argv[nn][2]=='9') {
208
                 gCpu=889;
209
                 fSeg = 1;
210
              }
211
              if (argv[nn][2]=='V') {
212
                 gCpu = 5;
213
              }
214
              if (argv[nn][2]=='6') {
215
                 gCpu = 64;
216
              }
217
              if (argv[nn][2]=='7') {
218
                 gCpu = 7;
219
                                 if (argv[nn][3]=='c')
220
                                         gCanCompress = 1;
221
                                 else
222
                                         gCanCompress = 0;
223
              }
224
              if (argv[nn][2]=='T') {
225
                 gCpu = 4;
226
                 if (argv[nn][3]=='2') {
227
                   segmodel = 2;
228
                 }
229
              }
230
              if (argv[nn][2]=='D') {
231
                 gCpu = 14;
232
              }
233
              if (argv[nn][2]=='A') {
234
                 gCpu = 'A';
235
                                 if (argv[nn][3]=='c')
236
                                         gCanCompress = 1;
237
                                 else
238
                                         gCanCompress = 0;
239
              }
240
              if (argv[nn][2]=='F') {
241
                 gCpu = 'F';
242
                                 mm = 3;
243
                                 gCanCompress = 0;
244
                                 while(argv[nn][mm]) {
245
                                         if (argv[nn][mm]=='3')
246
                                                 gCpu = 'H';
247
                                         else if (argv[nn][mm]=='c')
248
                                                 gCanCompress = 1;
249
                                         else if (argv[nn][mm]=='n')
250
                                                 vebits = 64;
251
                                         mm++;
252
                                 }
253
              }
254
              if (argv[nn][2]=='G') {
255
                 gCpu = 'G';
256
                                 if (argv[nn][3]=='n')
257
                                         vebits = 64;
258
                                 else if (argv[nn][3]=='c')
259
                                         gCanCompress = 1;
260
                                 else
261
                                         gCanCompress = 0;
262
              }
263
           }
264
           nn++;
265
        }
266
        else break;
267
    } while (1);
268
    return nn;
269
}
270
 
271
// ---------------------------------------------------------------------------
272
// Emit a byte, for DSD7 a byte is 16 bits.
273
// ---------------------------------------------------------------------------
274
 
275
void emitByte(int64_t cd)
276
{
277
     if (segment < 5) {
278
                 if (gCpu==7)
279
                        sections[segment].AddChar(cd);
280
                 else
281
                        sections[segment].AddByte(cd);
282
         }
283
    if (segment == codeseg || segment == rodataseg) {
284
                if (gCpu==7) {
285
                        binfile[binndx] = cd & 255LL;
286
                        binndx++;
287
                        binfile[binndx] = (cd >> 8) & 255LL;
288
                        binndx++;
289
                }
290
                else {
291
                        binfile[binndx] = cd & 255LL;
292
                        binndx++;
293
                }
294
    }
295
    if (segment==bssseg) {
296
       bss_address++;
297
    }
298
    else if (segment==dataseg)
299
         data_address++;
300
    else
301
        code_address++;
302
}
303
 
304
// ---------------------------------------------------------------------------
305
// ---------------------------------------------------------------------------
306
 
307
void emitNybble(int64_t cd)
308
{
309
        static int64_t ln;
310
        static bool evn = false;
311
        static int byt = 0;
312
 
313
        if (cd > 15)
314
                evn = cd >> 4;
315
        if (!evn) {
316
                emitByte((cd << 4) | ln);
317
        }
318
        else
319
                ln = cd;
320
        evn = !evn;
321
}
322
 
323
// ---------------------------------------------------------------------------
324
// ---------------------------------------------------------------------------
325
 
326
void emitChar(int64_t cd)
327
{
328
     emitByte(cd & 255LL);
329
     emitByte((cd >> 8) & 255LL);
330
}
331
 
332
// ---------------------------------------------------------------------------
333
// ---------------------------------------------------------------------------
334
 
335
void emitHalf(int64_t cd)
336
{
337
        if (gCpu==7) {
338
                emitByte(cd & 65535LL);
339
                //emitByte((cd >> 16) & 65535LL);
340
        }
341
  else if (gCpu==5) {
342
     emitByte(cd & 255LL);
343
     emitByte((cd >> 8) & 255LL);
344
  }
345
  else {
346
     emitChar(cd & 65535LL);
347
     emitChar((cd >> 16) & 65535LL);
348
  }
349
}
350
 
351
// ---------------------------------------------------------------------------
352
// ---------------------------------------------------------------------------
353
 
354
void emitWord(int64_t cd)
355
{
356
  if (gCpu==5 || gCpu==7) {
357
     emitHalf(cd & 0xFFFFLL);
358
     emitHalf((cd >> 16) & 0xFFFFLL);
359
  }
360
  else {
361
     emitHalf(cd & 0xFFFFFFFFLL);
362
     emitHalf((cd >> 32) & 0xFFFFFFFFLL);
363
  }
364
}
365
 
366
void emitDecibyte(Int128 cd)
367
{
368
        emitWord(cd.low);
369
        emitChar(cd.high & 0xFFFFLL);
370
}
371
 
372
// ---------------------------------------------------------------------------
373
// ---------------------------------------------------------------------------
374
 
375
void emitCode(int cd)
376
{
377
     emitByte(cd);
378
}
379
 
380
// ----------------------------------------------------------------------------
381
// Process a public declaration.
382
//     public code myfn
383
// ----------------------------------------------------------------------------
384
 
385
void process_public()
386
{
387
    SYM *sym;
388
    int64_t ca;
389
        int div = 1;
390
 
391
        if (gCpu==7)
392
                div = 2;
393
 
394
    NextToken();
395
    if (token==tk_code) {
396
        segment = codeseg;
397
    }
398
    else if (token==tk_rodata) {
399
         segment = rodataseg;
400
    }
401
    else if (token==tk_data) {
402
         if (isInitializationData)
403
             segment = rodataseg;
404
         else
405
             segment = dataseg;
406
    }
407
    else if (token==tk_bss) {
408
         segment = bssseg;
409
    }
410
    else
411
        prevToken();
412
    bump_address();
413
//    if (segment==bssseg)
414
//        ca = bss_address;
415
//    else
416
//        ca = code_address;
417
    switch(segment) {
418
    case codeseg:
419
         ca = code_address/div;
420
         ca = sections[0].address/div;
421
         break;
422
    case rodataseg:
423
         ca = sections[1].address/div;
424
         break;
425
    case dataseg:
426
         ca = sections[2].address/div;
427
         break;
428
    case bssseg:
429
         ca = sections[3].address/div;
430
         break;
431
    case tlsseg:
432
         ca = sections[4].address/div;
433
         break;
434
    }
435
    NextToken();
436
    if (token != tk_id) {
437
        printf("Identifier expected. Token %d\r\n", token);
438
        printf("Line:%.60s", stptr);
439
    }
440
    else {
441
         if (isInitializationData) {
442
             ScanToEOL();
443
             inptr++;
444
             return;
445
         }
446
        sym = find_symbol(lastid);
447
        if (pass == 4) {
448
            if (sym) {
449
                if (sym->defined)
450
                    printf("Symbol (%s) already defined.\r\n", lastid);
451
            }
452
            else {
453
                sym = new_symbol(lastid);
454
            }
455
            if (sym) {
456
                sym->defined = 1;
457
                                if (gCpu=='G')
458
                                        sym->value.low = ca & -4LL;
459
                                else
460
                                        sym->value.low = ca;
461
                                sym->value.high = 0;
462
                sym->segment = segment;
463
                sym->scope = 'P';
464
            }
465
        }
466
        else if (pass > 4) {
467
                        if (!sym)
468
                            printf("Symbol (%s) not defined.\r\n", lastid);
469
                        else {
470
                    if (sym->value.low != ca) {
471
                        phasing_errors++;
472
                        sym->phaserr = '*';
473
                         //if (bGen) printf("%s=%06I64x ca=%06I64x\r\n", nmTable.GetName(sym->name),  sym->value, code_address);
474
                    }
475
                    else
476
                         sym->phaserr = ' ';
477
                                if (gCpu=='G')
478
                                        sym->value.low = ca & -4LL;
479
                                else
480
                                        sym->value.low = ca;
481
                                sym->value.high = 0;
482
                }
483
        }
484
        strcpy_s(current_label, sizeof(current_label), lastid);
485
    }
486
    ScanToEOL();
487
    inptr++;
488
}
489
 
490
// ----------------------------------------------------------------------------
491
// extern somefn
492
// ----------------------------------------------------------------------------
493
 
494
void process_extern()
495
{
496
    SYM *sym;
497
 
498
//    printf("<process_extern>");
499
    NextToken();
500
    if (token != tk_id)
501
        printf("Expecting an identifier.\r\n");
502
    else {
503
        sym = find_symbol(lastid);
504
        if (pass == 4) {
505
            if (sym) {
506
 
507
            }
508
            else {
509
                sym = new_symbol(lastid);
510
            }
511
            if (sym) {
512
                sym->defined = 0;
513
                sym->value.low = 0;
514
                                sym->value.high = 0;
515
                sym->segment = segment;
516
                sym->scope = 'P';
517
                sym->isExtern = 1;
518
            }
519
        }
520
        else if (pass > 4) {
521
        }
522
        NextToken();
523
        if (token==':') {
524
           NextToken();
525
           if (sym)
526
               sym->bits = (int)expr();
527
        }
528
        else {
529
//    printf("J:sym=%p lastid=%s", sym, lastid);
530
           prevToken();
531
            if (sym)
532
               sym->bits = 32;
533
        }
534
    }
535
    ScanToEOL();
536
    inptr++;
537
//    printf("</process_extern>\r\n");
538
}
539
 
540
// ----------------------------------------------------------------------------
541
// .org $23E200
542
// .org is ignored for relocatable files.
543
// ----------------------------------------------------------------------------
544
 
545
void process_org()
546
{
547
    int64_t new_address;
548
        int mul = 1;
549
 
550
        if (gCpu==7)
551
                mul = 2;
552
    NextToken();
553
    new_address = expr();
554
    if (!rel_out) {
555
        if (segment==dataseg) {
556
            data_address = new_address*mul;
557
            sections[segment].address = new_address*mul;
558
        }
559
        else if (segment==bssseg || segment==tlsseg) {
560
            bss_address = new_address*mul;
561
            sections[segment].address = new_address*mul;
562
        }
563
        else {
564
            if (first_org && segment==codeseg) {
565
                                program_address = new_address;
566
               code_address = new_address;
567
               start_address = new_address*mul;
568
               sections[0].address = new_address*mul;
569
               first_org = 0;
570
            }
571
            else {
572
                 // Ignore the org directive in initialized data area of rodata
573
                 if (!isInitializationData)
574
                while(sections[0].address < new_address*mul)
575
                    emitByte(0x00);
576
            }
577
        }
578
    }
579
    ScanToEOL();
580
}
581
 
582
// ----------------------------------------------------------------------------
583
// ----------------------------------------------------------------------------
584
 
585
void process_align()
586
{
587
        int64_t v;
588
 
589
        NextToken();
590
        if (token == tk_code && gCpu=='F')
591
                v = 5;
592
        else
593
                v = expr();
594
        if (v == 0) {
595
                printf("Bad align directive. (%d)\r\n", lineno);
596
                return;
597
        }
598
    if (segment == codeseg || segment == rodataseg || segment == dataseg || segment==bssseg || segment==tlsseg) {
599
        while (sections[segment].address % v)
600
            emitByte(0x00);
601
    }
602
//    if (segment==bssseg) {
603
//        while (bss_address % v)
604
//            emitByte(0x00);
605
//    }
606
//    else {
607
//        while (code_address % v)
608
//            emitByte(0x00);
609
//    }
610
}
611
 
612
// ----------------------------------------------------------------------------
613
//      hint #1
614
//
615
// Process a compiler hint. Normally these instructions don't make it through
616
// the compile stage, but in case one does... It is just ignored.
617
// ----------------------------------------------------------------------------
618
 
619
void process_hint()
620
{
621
    int64_t v;
622
 
623
    NextToken();
624
    v = expr();
625
}
626
 
627
// ----------------------------------------------------------------------------
628
// code 0x8000 to 0xFFFF
629
// code 24 bits
630
// code
631
// ----------------------------------------------------------------------------
632
 
633
void process_code()
634
{
635
    int64_t st, nd;
636
 
637
    segment = codeseg;
638
    NextToken();
639
    if (token==tk_eol) {
640
        prevToken();
641
        return;
642
    }
643
    st = expr();
644
    if (token==tk_bits) {
645
        code_bits = (int)st;
646
        return;
647
    }
648
    if (token==tk_to) {
649
        NextToken();
650
        nd = expr();
651
        code_bits = (int)log((double)nd+1)/log(2.0);    // +1 to round up a little bit
652
    }
653
}
654
 
655
// ----------------------------------------------------------------------------
656
// data 0x8000 to 0xFFFF
657
// data 24 bits
658
// data
659
// ----------------------------------------------------------------------------
660
 
661
void process_data(int seg)
662
{
663
    int64_t st, nd;
664
 
665
    segment = seg;
666
    NextToken();
667
    if (token==tk_eol) {
668
        prevToken();
669
        return;
670
    }
671
    st = expr();
672
    if (token==tk_bits) {
673
        data_bits = (int)st;
674
        return;
675
    }
676
    if (token==tk_to) {
677
        NextToken();
678
        nd = expr();
679
        data_bits = (int)log((double)nd+1)/log((double)2.0);    // +1 to round up a little bit
680
    }
681
}
682
 
683
// ----------------------------------------------------------------------------
684
// ----------------------------------------------------------------------------
685
 
686
void process_db()
687
{
688
    int64_t val;
689
 
690
    SkipSpaces();
691
    //NextToken();
692
    while(token!=tk_eol) {
693
        SkipSpaces();
694
        if (*inptr=='\n') break;
695
        if (*inptr=='"') {
696
            inptr++;
697
            while (*inptr!='"') {
698
                if (*inptr=='\\') {
699
                    inptr++;
700
                    switch(*inptr) {
701
                    case '\\': emitByte('\\'); inptr++; break;
702
                    case 'r': emitByte(0x0D); inptr++; break;
703
                    case 'n': emitByte(0x0A); inptr++; break;
704
                    case 'b': emitByte('\b'); inptr++; break;
705
                    case '"': emitByte('"'); inptr++; break;
706
                    default: inptr++; break;
707
                    }
708
                }
709
                else {
710
                    emitByte(*inptr);
711
                    inptr++;
712
                }
713
            }
714
            inptr++;
715
        }
716
/*
717
        else if (*inptr=='\'') {
718
            inptr++;
719
            emitByte(*inptr);
720
            inptr++;
721
            if (*inptr!='\'') {
722
                printf("Missing ' in character constant.\r\n");
723
            }
724
        }
725
*/
726
        else {
727
            NextToken();
728
            val = expr();
729
            emitByte(val & 255);
730
            prevToken();
731
        }
732
        SkipSpaces();
733
        if (*inptr!=',')
734
            break;
735
        inptr++;
736
    }
737
    ScanToEOL();
738
}
739
 
740
// ----------------------------------------------------------------------------
741
// ----------------------------------------------------------------------------
742
 
743
void process_dc()
744
{
745
    int64_t val;
746
 
747
    SkipSpaces();
748
    while(token!=tk_eol) {
749
        SkipSpaces();
750
        if (*inptr=='"') {
751
            inptr++;
752
            while (*inptr!='"') {
753
                if (*inptr=='\\') {
754
                    inptr++;
755
                    switch(*inptr) {
756
                    case '\\': emitChar('\\'); inptr++; break;
757
                    case 'r': emitChar(0x0D); inptr++; break;
758
                    case 'n': emitChar(0x0A); inptr++; break;
759
                    case 'b': emitChar('\b'); inptr++; break;
760
                    case '"': emitChar('"'); inptr++; break;
761
                    default: inptr++; break;
762
                    }
763
                }
764
                else {
765
                    emitChar(*inptr);
766
                    inptr++;
767
                }
768
            }
769
            inptr++;
770
        }
771
        else if (*inptr=='\'') {
772
            inptr++;
773
            emitChar(*inptr);
774
            inptr++;
775
            if (*inptr!='\'') {
776
                printf("Missing ' in character constant.\r\n");
777
            }
778
        }
779
        else {
780
             NextToken();
781
            val = expr();
782
            emitChar(val);
783
            prevToken();
784
        }
785
        SkipSpaces();
786
        if (*inptr!=',')
787
            break;
788
        inptr++;
789
    }
790
    ScanToEOL();
791
}
792
 
793
// ----------------------------------------------------------------------------
794
// ----------------------------------------------------------------------------
795
 
796
void process_dh()
797
{
798
    int64_t val;
799
 
800
    SkipSpaces();
801
    while(token!=tk_eol) {
802
        SkipSpaces();
803
        if (*inptr=='"') {
804
            inptr++;
805
            while (*inptr!='"') {
806
                if (*inptr=='\\') {
807
                    inptr++;
808
                    switch(*inptr) {
809
                    case '\\': emitHalf('\\'); inptr++; break;
810
                    case 'r': emitHalf(0x0D); inptr++; break;
811
                    case 'n': emitHalf(0x0A); inptr++; break;
812
                    case 'b': emitHalf('\b'); inptr++; break;
813
                    case '"': emitHalf('"'); inptr++; break;
814
                    default: inptr++; break;
815
                    }
816
                }
817
                else {
818
                    emitHalf(*inptr);
819
                    inptr++;
820
                }
821
            }
822
            inptr++;
823
        }
824
        else if (*inptr=='\'') {
825
            inptr++;
826
            emitHalf(*inptr);
827
            inptr++;
828
            if (*inptr!='\'') {
829
                printf("Missing ' in character constant.\r\n");
830
            }
831
        }
832
        else {
833
             NextToken();
834
            val = expr();
835
            emitHalf(val);
836
            prevToken();
837
        }
838
        SkipSpaces();
839
        if (*inptr!=',')
840
            break;
841
        inptr++;
842
    }
843
    ScanToEOL();
844
}
845
 
846
// ----------------------------------------------------------------------------
847
// ----------------------------------------------------------------------------
848
 
849
void process_dh_htbl()
850
{
851
        int nn;
852
 
853
        if (gCpu=='F') {
854
                emitHalf(htblmax > 1024 ? 1024 : htblmax);
855
                for (nn = 0; nn < htblmax && nn < 1024; nn++) {
856
                        emitHalf(hTable[nn].opcode);
857
                }
858
                return;
859
        }
860
        else if (gCpu==7)
861
                emitByte(htblmax > 1024 ? 1024 : htblmax);
862
        else
863
                emitHalf(htblmax > 1024 ? 1024 : htblmax);
864
        for (nn = 0; nn < htblmax && nn < 1024; nn++) {
865
                emitWord(hTable[nn].opcode);
866
        }
867
}
868
 
869
// ----------------------------------------------------------------------------
870
// ----------------------------------------------------------------------------
871
 
872
void process_dw()
873
{
874
    int64_t val;
875
 
876
    SkipSpaces();
877
    while(token!=tk_eol) {
878
        SkipSpaces();
879
        if (*inptr=='"') {
880
            inptr++;
881
            while (*inptr!='"') {
882
                if (*inptr=='\\') {
883
                    inptr++;
884
                    switch(*inptr) {
885
                    case '\\': emitWord('\\'); inptr++; break;
886
                    case 'r': emitWord(0x0D); inptr++; break;
887
                    case 'n': emitWord(0x0A); inptr++; break;
888
                    case 'b': emitWord('\b'); inptr++; break;
889
                    case '"': emitWord('"'); inptr++; break;
890
                    default: inptr++; break;
891
                    }
892
                }
893
                else {
894
                    emitWord(*inptr);
895
                    inptr++;
896
                }
897
            }
898
            inptr++;
899
        }
900
        else if (*inptr=='\'') {
901
            inptr++;
902
            emitWord(*inptr);
903
            inptr++;
904
            if (*inptr!='\'') {
905
                printf("Missing ' in character constant.\r\n");
906
            }
907
        }
908
        else {
909
             NextToken();
910
            val = expr();
911
    // A pointer to an object might be emitted as a data word.
912
    if (bGen && lastsym)
913
    if( lastsym->segment < 5)
914
    sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
915
            emitWord(val);
916
            prevToken();
917
        }
918
        SkipSpaces();
919
        if (*inptr!=',')
920
            break;
921
        inptr++;
922
    }
923
    ScanToEOL();
924
}
925
 
926
// ----------------------------------------------------------------------------
927
// ----------------------------------------------------------------------------
928
 
929
void process_dd()
930
{
931
    Int128 val;
932
 
933
    SkipSpaces();
934
    while(token!=tk_eol) {
935
        SkipSpaces();
936
        if (*inptr=='"') {
937
            inptr++;
938
            while (*inptr!='"') {
939
                if (*inptr=='\\') {
940
                    inptr++;
941
                    switch(*inptr) {
942
                    case '\\': emitWord('\\'); emitChar(0); inptr++; break;
943
                    case 'r': emitWord(0x0D); emitChar(0); inptr++; break;
944
                    case 'n': emitWord(0x0A); emitChar(0); inptr++; break;
945
                    case 'b': emitWord('\b'); emitChar(0); inptr++; break;
946
                    case '"': emitWord('"'); emitChar(0); inptr++; break;
947
                    default: inptr++; break;
948
                    }
949
                }
950
                else {
951
                    emitWord(*inptr);
952
                                        emitChar(0);
953
                    inptr++;
954
                }
955
            }
956
            inptr++;
957
        }
958
        else if (*inptr=='\'') {
959
            inptr++;
960
            emitWord(*inptr);
961
                        emitChar(0);
962
            inptr++;
963
            if (*inptr!='\'') {
964
                printf("Missing ' in character constant.\r\n");
965
            }
966
        }
967
        else {
968
             NextToken();
969
            val = expr128();
970
    // A pointer to an object might be emitted as a data word.
971
    if (bGen && lastsym)
972
    if( lastsym->segment < 5)
973
    sections[segment+7].AddRel(sections[segment].index,((int64_t)(lastsym->ord+1) << 32) | 6 | (lastsym->isExtern ? 128 : 0));
974
            emitDecibyte(val);
975
            prevToken();
976
        }
977
        SkipSpaces();
978
        if (*inptr!=',')
979
            break;
980
        inptr++;
981
    }
982
    ScanToEOL();
983
}
984
 
985
// ----------------------------------------------------------------------------
986
// fill.b 252,0x00
987
// ----------------------------------------------------------------------------
988
 
989
void process_fill()
990
{
991
    char sz = 'b';
992
    int64_t count;
993
    int64_t val;
994
    int64_t nn;
995
 
996
    if (*inptr=='.') {
997
        inptr++;
998
        if (strchr("bchwBCHW",*inptr)) {
999
            sz = tolower(*inptr);
1000
            inptr++;
1001
        }
1002
        else
1003
            printf("Illegal fill size.\r\n");
1004
    }
1005
    SkipSpaces();
1006
    NextToken();
1007
    count = expr();
1008
    prevToken();
1009
    need(',');
1010
    NextToken();
1011
    val = expr();
1012
    prevToken();
1013
    for (nn = 0; nn < count; nn++)
1014
        switch(sz) {
1015
        case 'b': emitByte(val); break;
1016
        case 'c': emitChar(val); break;
1017
        case 'h': emitHalf(val); break;
1018
        case 'w': emitWord(val); break;
1019
        }
1020
}
1021
 
1022
// ----------------------------------------------------------------------------
1023
// Bump up the address to the next aligned code address.
1024
// ----------------------------------------------------------------------------
1025
 
1026
void bump_address()
1027
{
1028
     if (gCpu==888 || gCpu==889)
1029
        Table888_bump_address();
1030
}
1031
 
1032
// ---------------------------------------------------------------------------
1033
// ---------------------------------------------------------------------------
1034
void process_message()
1035
{
1036
    char buf[200];
1037
    int nn;
1038
 
1039
    while(*inptr != '"' && *inptr != '\n') inptr++;
1040
    if (*inptr=='\n') { NextToken(); return; }
1041
    nn = 0;
1042
    inptr++;
1043
    while (*inptr != '"' && *inptr != '\n' && nn < 197) {
1044
        buf[nn] = *inptr;
1045
        inptr++;
1046
        nn++;
1047
    }
1048
    buf[nn] = '\0';
1049
    strcat_s(buf, sizeof(buf), "\r\n");
1050
    printf(buf);
1051
    ScanToEOL();
1052
}
1053
 
1054
// ----------------------------------------------------------------------------
1055
// label:
1056
// ----------------------------------------------------------------------------
1057
 
1058
void process_label()
1059
{
1060
    SYM *sym;
1061
    static char nm[500];
1062
    int64_t ca;
1063
    Int128 val;
1064
    int isEquate;
1065
    int shft = 0;
1066
 
1067
        val.low = 0;
1068
        val.high = 0;
1069
        if (gCpu==7)
1070
                shft = 1;
1071
 
1072
//    printf("<process_label>");
1073
    isEquate = 0;
1074
    // Bump up the address to align it with a valid code address if needed.
1075
    bump_address();
1076
    switch(segment) {
1077
    case codeseg:
1078
         ca = code_address >> shft;
1079
         ca = sections[0].address >> shft;
1080
         break;
1081
    case rodataseg:
1082
         ca = sections[1].address >> shft;
1083
         break;
1084
    case dataseg:
1085
         ca = sections[2].address >> shft;
1086
         break;
1087
    case bssseg:
1088
         ca = sections[3].address >> shft;
1089
         break;
1090
    case tlsseg:
1091
         ca = sections[4].address >> shft;
1092
         break;
1093
        default:
1094
                 ca = code_address >> shft;
1095
                 ca = sections[0].address >> shft;
1096
                 break;
1097
        }
1098
//    if (segment==bssseg)
1099
//       ca = bss_address;
1100
//    else
1101
//        ca = code_address;
1102
    if (lastid[0]=='.') {
1103
        sprintf_s(nm, sizeof(nm), "%s%s", current_label, lastid);
1104
    }
1105
    else {
1106
        strcpy_s(current_label, sizeof(current_label), lastid);
1107
        strcpy_s(nm, sizeof(nm), lastid);
1108
    }
1109
    if (strcmp("end_init_data", nm)==0)
1110
       isInitializationData = 0;
1111
    NextToken();
1112
//    SkipSpaces();
1113
    if (token==tk_equ || token==tk_eq) {
1114
        NextToken();
1115
        val = expr128();
1116
        isEquate = 1;
1117
    }
1118
    else {
1119
                prevToken();
1120
                val.low = ca;
1121
                val.high = 0;
1122
        }
1123
//    if (token==tk_eol)
1124
//       prevToken();
1125
    //else if (token==':') inptr++;
1126
    // ignore the labels in initialization data
1127
    if (isInitializationData)
1128
       return;
1129
    sym = find_symbol(nm);
1130
    if (pass==4 || pass==3) {
1131
        if (sym) {
1132
            if (sym->defined) {
1133
                //if (!Int128::IsEqual(&sym->value, &val)) {
1134
                //    printf("Label %s already defined %ld vs %ld.\r\n", nm, sym->value.low, val.low);
1135
                //    printf("Line %d: %.60s\r\n", lineno, stptr);
1136
                //}
1137
            }
1138
            sym->defined = 1;
1139
            if (isEquate) {
1140
                sym->value = val;
1141
                sym->segment = constseg;
1142
                sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
1143
            }
1144
            else {
1145
                                if (gCpu=='G')
1146
                                        sym->value.low = ca & -4LL;
1147
                                else
1148
                                        sym->value.low = ca;
1149
                                sym->value.high = 0;
1150
                sym->segment = segment;
1151
                if (segment==codeseg)
1152
                   sym->bits = code_bits;
1153
                else
1154
                    sym->bits = data_bits;
1155
            }
1156
        }
1157
        else {
1158
            sym = new_symbol(nm);
1159
            sym->defined = 1;
1160
            if (isEquate) {
1161
                sym->value = val;
1162
                sym->segment = constseg;
1163
                sym->bits = (int)ceil(log(fabs((double)val.low)+1) / log(2.0))+1;
1164
            }
1165
            else {
1166
                                if (gCpu=='G')
1167
                                        sym->value.low = ca & -4LL;
1168
                                else
1169
                                        sym->value.low = ca;
1170
                                sym->value.high = 0;
1171
                                sym->segment = segment;
1172
                if (segment==codeseg)
1173
                   sym->bits = code_bits;
1174
                else
1175
                    sym->bits = data_bits;
1176
            }
1177
        }
1178
    }
1179
    else if (pass>4) {
1180
         if (!sym) {
1181
            printf("Internal error: SYM is NULL.\r\n");
1182
            printf("Couldn't find <%s>\r\n", nm);
1183
         }
1184
         else {
1185
             if (isEquate) {
1186
                 sym->value = val;
1187
             }
1188
             else {
1189
                                 if ((sym->value.low != ca && gCpu!='G') || (sym->value.low != (ca & -4LL) && gCpu=='G')) {
1190
                     phasing_errors++;
1191
                     sym->phaserr = '*';
1192
                     //if (bGen) printf("%s=%06llx ca=%06llx\r\n", nmTable.GetName(sym->name),  sym->value, code_address);
1193
                 }
1194
                 else
1195
                     sym->phaserr = ' ';
1196
                                        if (gCpu=='G')
1197
                                                sym->value.low = ca & -4LL;
1198
                                        else
1199
                                                sym->value.low = ca;
1200
                                 sym->value.high = 0;
1201
                         }
1202
         }
1203
    }
1204
    if (strcmp("begin_init_data", nm)==0)
1205
       isInitializationData = 1;
1206
//    printf("</process_ label>\r\n");
1207
}
1208
 
1209
// ----------------------------------------------------------------------------
1210
// Group and reorder the segments in the master file.
1211
//     code          placed first
1212
//     rodata        followed by
1213
//     data
1214
//     tls
1215
// ----------------------------------------------------------------------------
1216
 
1217
void processSegments()
1218
{
1219
    char *pinptr;
1220
    int segment = codeseg;
1221
    int inComment;
1222
 
1223
    if (verbose)
1224
       printf("Processing segments.\r\n");
1225
    inptr = &masterFile[0];
1226
    pinptr = inptr;
1227
    codendx = 0;
1228
    datandx = 0;
1229
    rodatandx = 0;
1230
    tlsndx = 0;
1231
    bssndx = 0;
1232
    memset(codebuf,0,sizeof(codebuf));
1233
    memset(databuf,0,sizeof(databuf));
1234
    memset(rodatabuf,0,sizeof(rodatabuf));
1235
    memset(tlsbuf,0,sizeof(tlsbuf));
1236
    memset(bssbuf,0,sizeof(bssbuf));
1237
    inComment = 0;
1238
 
1239
    while (*inptr) {
1240
        SkipSpaces();
1241
        if (*inptr==';')
1242
                goto j1;
1243
        if (inptr[0]=='/' && inptr[1]=='/')
1244
                goto j1;
1245
//        if (inptr[0]=='/' && inptr[1]=='*') {
1246
//              inComment = 1;
1247
//              goto j1;
1248
//              }
1249
//              if (inComment && inptr[0]=='*' && inptr[1]=='/')
1250
//                      inComment = 0;
1251
//              if (inComment)
1252
//                      goto j1;
1253
        if (*inptr=='.') inptr++;
1254
        if ((_strnicmp(inptr,"code",4)==0) && !isIdentChar(inptr[4])) {
1255
            segment = codeseg;
1256
        }
1257
        else if ((_strnicmp(inptr,"data",4)==0) && !isIdentChar(inptr[4])) {
1258
            segment = dataseg;
1259
        }
1260
        else if ((_strnicmp(inptr,"rodata",6)==0) && !isIdentChar(inptr[6])) {
1261
            segment = rodataseg;
1262
        }
1263
        else if ((_strnicmp(inptr,"tls",3)==0) && !isIdentChar(inptr[3])) {
1264
            segment = tlsseg;
1265
        }
1266
        else if ((_strnicmp(inptr,"bss",3)==0) && !isIdentChar(inptr[3])) {
1267
            segment = bssseg;
1268
        }
1269
j1:
1270
        ScanToEOL();
1271
        inptr++;
1272
        switch(segment) {
1273
        case codeseg:
1274
             strncpy(&codebuf[codendx], pinptr, inptr-pinptr);
1275
             codendx += inptr-pinptr;
1276
             break;
1277
        case dataseg:
1278
             strncpy(&databuf[datandx], pinptr, inptr-pinptr);
1279
             datandx += inptr-pinptr;
1280
             break;
1281
        case rodataseg:
1282
             strncpy(&rodatabuf[rodatandx], pinptr, inptr-pinptr);
1283
             rodatandx += inptr-pinptr;
1284
             break;
1285
        case tlsseg:
1286
             strncpy(&tlsbuf[tlsndx], pinptr, inptr-pinptr);
1287
             tlsndx += inptr-pinptr;
1288
             break;
1289
        case bssseg:
1290
             strncpy(&bssbuf[bssndx], pinptr, inptr-pinptr);
1291
             bssndx += inptr-pinptr;
1292
             break;
1293
        }
1294
        pinptr = inptr;
1295
    }
1296
    memset(masterFile,0,sizeof(masterFile));
1297
    strcat(masterFile, codebuf);
1298
    strcat(masterFile, rodatabuf);
1299
    strcat(masterFile, "\r\n\trodata\r\n");
1300
    strcat(masterFile, "\talign 8\r\n");
1301
    strcat(masterFile, "begin_init_data:\r\n");
1302
    strcat(masterFile, databuf);
1303
    strcat(masterFile, "\r\n\trodata\r\n");
1304
    strcat(masterFile, "\talign 8\r\n");
1305
    strcat(masterFile, "end_init_data:\r\n");
1306
    strcat(masterFile, databuf);
1307
    strcat(masterFile, bssbuf);
1308
    strcat(masterFile, tlsbuf);
1309
    if (debug) {
1310
        FILE *fp;
1311
        fp = fopen("a64-segments.asm", "w");
1312
        if (fp) {
1313
                fwrite(masterFile, 1, strlen(masterFile), fp);
1314
                fclose(fp);
1315
        }
1316
    }
1317
}
1318
 
1319
void skipif(int64_t val)
1320
{
1321
        int iflevel = 1;
1322
        char *p1, *p2, *p3;
1323
        bool codecut = false;
1324
 
1325
        // Cut out the if statement
1326
        p1 = pif1;
1327
        memmove(pif1,pif2,sizeof(masterFile)-(pif2-masterFile));
1328
 
1329
        p1 = inptr = pif1;
1330
        while(*inptr) {
1331
                SkipSpaces();
1332
                p2 = inptr;
1333
                NextToken();
1334
                p3 = inptr;
1335
                if (token==tk_if || token==tk_ifdef || token==tk_ifndef)
1336
                        iflevel++;
1337
                else if (token==tk_endif) {
1338
                        iflevel--;
1339
                        if (iflevel==0) {
1340
                                // If the if was false cut out the code between
1341
                                // if and endif
1342
                                if (val==0 && !codecut) {
1343
                                        memmove(pif1,p3,sizeof(masterFile)-(p3-masterFile));
1344
                                        inptr = pif1;
1345
                                        return;
1346
                                }
1347
                                else {
1348
                                        // remove endif but leave remaining text
1349
                                        memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
1350
                                        inptr = p2;
1351
                                }
1352
                        }
1353
                }
1354
                else if (token==tk_else) {
1355
                        if (iflevel==0) {
1356
                                // cut out code between if and else
1357
                                // and keep going until endif
1358
                                if (val==0) {
1359
                                        memmove(pif1,p2+4,sizeof(masterFile)-(p2+4-masterFile));
1360
                                        inptr = pif1;
1361
                                        codecut = true;
1362
                                }
1363
                                else {
1364
                                        // remove the else from text
1365
                                        // and keep going until endif
1366
                                        memmove(p2,inptr,sizeof(masterFile)-(inptr-masterFile));
1367
                                        inptr = p2;
1368
                                }
1369
                        }
1370
                }
1371
                else
1372
                        ScanToEOL();
1373
                if (*inptr=='\n')
1374
                        inptr++;
1375
        }
1376
}
1377
 
1378
void doif()
1379
{
1380
        int64_t val;
1381
 
1382
        NextToken();
1383
        val = expr();
1384
        pif2 = inptr;
1385
        ScanToEOL();
1386
        skipif(val);
1387
}
1388
 
1389
void doifdef()
1390
{
1391
        int64_t val;
1392
 
1393
        if (getIdentifier()==0)
1394
                printf("Expecting an identifier %d.\n", lineno);
1395
    val = (find_symbol(lastid)!=nullptr);
1396
        ScanToEOL();
1397
        pif2 = inptr;
1398
        skipif(val);
1399
}
1400
 
1401
void doifndef()
1402
{
1403
        int64_t val;
1404
 
1405
        if (getIdentifier()==0)
1406
                printf("Expecting an identifier %d.\n", lineno);
1407
    val = (find_symbol(lastid)==nullptr);
1408
        ScanToEOL();
1409
        pif2 = inptr;
1410
        skipif(val);
1411
}
1412
 
1413
// ----------------------------------------------------------------------------
1414
// Look for .include directives and include the files.
1415
// ----------------------------------------------------------------------------
1416
 
1417
void processLine(char *line)
1418
{
1419
    char *p;
1420
    int quoteType;
1421
    static char fnm[300];
1422
    char *fname;
1423
    int nn;
1424
    int lb;
1425
 
1426
    p = line;
1427
    while(isspace(*p)) p++;
1428
    if (!*p) goto addToMaster;
1429
    // see if the first thing on the line is an include directive
1430
    if (*p=='.') p++;
1431
    if (strnicmp(p, "include", 7)==0 && !isIdentChar(p[7]))
1432
    {
1433
        p += 7;
1434
        // Capture the file name
1435
        while(isspace(*p)) p++;
1436
        if (*p=='"') { quoteType = '"'; p++; }
1437
        else if (*p=='<') { quoteType = '>'; p++; }
1438
        else quoteType = ' ';
1439
        nn = 0;
1440
        do {
1441
           fnm[nn] = *p;
1442
           p++; nn++;
1443
           if (quoteType==' ' && isspace(*p)) break;
1444
           else if (*p == quoteType) break;
1445
           else if (*p=='\n') break;
1446
        } while(nn < sizeof(fnm)/sizeof(char));
1447
        fnm[nn] = '\0';
1448
        fname = strdup(fnm);
1449
        lb = lineno;
1450
        lineno = 1;
1451
        processFile(fname,1);
1452
        lineno = lb;
1453
        free(fname);
1454
        return;
1455
    }
1456
    // Not an include directive, then just copy the line to the master buffer.
1457
addToMaster:
1458
    strcpy(&masterFile[mfndx], line);
1459
    mfndx += strlen(line);
1460
}
1461
 
1462
// ----------------------------------------------------------------------------
1463
// Build a aggregate of all the included files into a single master buffer.
1464
// ----------------------------------------------------------------------------
1465
 
1466
void processFile(char *fname, int searchincl)
1467
{
1468
     FILE *fp;
1469
     char *pathname;
1470
 
1471
     if (verbose)
1472
        printf("Processing file:%s\r\n", fname);
1473
     pathname = (char *)NULL;
1474
     fp = fopen(fname, "r");
1475
     if (!fp) {
1476
         if (searchincl) {
1477
             searchenv(fname, "INCLUDE", &pathname);
1478
             if (strlen(pathname)) {
1479
                 fp = fopen(pathname, "r");
1480
                 if (fp) goto j1;
1481
             }
1482
         }
1483
         printf("Can't open file <%s>\r\n", fname);
1484
         goto j2;
1485
     }
1486
j1:
1487
     while (!feof(fp)) {
1488
         fgets(buf, sizeof(buf)/sizeof(char), fp);
1489
         processLine(buf);
1490
                 ZeroMemory(buf,sizeof(buf));
1491
     }
1492
     fclose(fp);
1493
j2:
1494
     if (pathname)
1495
         free(pathname);
1496
}
1497
 
1498
// ----------------------------------------------------------------------------
1499
// ----------------------------------------------------------------------------
1500
 
1501
int checksum(int32_t *val)
1502
{
1503
    int nn;
1504
    int cs;
1505
 
1506
    cs = 0;
1507
    for (nn = 0; nn < 32; nn++)
1508
        cs ^= (*val & (1 << nn))!=0;
1509
    return cs;
1510
}
1511
 
1512
 
1513
int checksum64(int64_t *val)
1514
{
1515
    int nn;
1516
    int cs;
1517
 
1518
    cs = 0;
1519
    for (nn = 0; nn < 64; nn++)
1520
        cs ^= (*val & (1LL << nn))!=0;
1521
    return cs;
1522
}
1523
 
1524
 
1525
// ----------------------------------------------------------------------------
1526
// ----------------------------------------------------------------------------
1527
 
1528
void processMaster()
1529
{
1530
    expandedBlock = 0;
1531
        switch(gCpu) {
1532
        case 888:       Table888_processMaster();       break;
1533
        case 889:       Table888mmu_processMaster();    break;
1534
        case 64:        FISA64_processMaster(); break;
1535
        case 5:         Friscv_processMaster(); break;
1536
        case 4:         Thor_processMaster();   break;
1537
        case 14:        dsd6_processMaster();   break;
1538
        case 7:         dsd7_processMaster();   break;
1539
        case 'A':       dsd9_processMaster();   break;
1540
        case 'F':       FT64_processMaster();   break;
1541
        case 'G':       FT64x36_processMaster();        break;
1542
        default:        FT64_processMaster();
1543
        }
1544
}
1545
 
1546
// ----------------------------------------------------------------------------
1547
// ----------------------------------------------------------------------------
1548
 
1549
int64_t Round512(int64_t n)
1550
{
1551
    return (n + 511LL) & 0xFFFFFFFFFFFFFE00LL;
1552
}
1553
 
1554
int64_t Round4096(int64_t n)
1555
{
1556
    return (n + 4095LL) & 0xFFFFFFFFFFFFF000LL;
1557
}
1558
 
1559
// ----------------------------------------------------------------------------
1560
// ----------------------------------------------------------------------------
1561
 
1562
void WriteELFFile(FILE *fp)
1563
{
1564
    int nn;
1565
    Elf64Symbol elfsym;
1566
    clsElf64File elf;
1567
    SYM *sym,*syms;
1568
    int64_t start;
1569
 
1570
    sections[0].hdr.sh_name = nmTable.AddName(".text");
1571
    sections[0].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
1572
    sections[0].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_EXECINSTR;
1573
    sections[0].hdr.sh_addr = rel_out ? 0 : sections[0].start;
1574
    sections[0].hdr.sh_offset = 512;  // offset in file
1575
    sections[0].hdr.sh_size = sections[0].index;
1576
    sections[0].hdr.sh_link = 0;
1577
    sections[0].hdr.sh_info = 0;
1578
    sections[0].hdr.sh_addralign = 16;
1579
    sections[0].hdr.sh_entsize = 0;
1580
 
1581
    sections[1].hdr.sh_name = nmTable.AddName(".rodata");
1582
    sections[1].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
1583
    sections[1].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC;
1584
    sections[1].hdr.sh_addr = sections[0].hdr.sh_addr + sections[0].index;
1585
    sections[1].hdr.sh_offset = sections[0].hdr.sh_offset + sections[0].index; // offset in file
1586
    sections[1].hdr.sh_size = sections[1].index;
1587
    sections[1].hdr.sh_link = 0;
1588
    sections[1].hdr.sh_info = 0;
1589
    sections[1].hdr.sh_addralign = 8;
1590
    sections[1].hdr.sh_entsize = 0;
1591
 
1592
    sections[2].hdr.sh_name = nmTable.AddName(".data");
1593
    sections[2].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
1594
    sections[2].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
1595
    sections[2].hdr.sh_addr = sections[1].hdr.sh_addr + sections[1].index;
1596
    sections[2].hdr.sh_offset = sections[1].hdr.sh_offset + sections[1].index; // offset in file
1597
    sections[2].hdr.sh_size = sections[2].index;
1598
    sections[2].hdr.sh_link = 0;
1599
    sections[2].hdr.sh_info = 0;
1600
    sections[2].hdr.sh_addralign = 8;
1601
    sections[2].hdr.sh_entsize = 0;
1602
 
1603
    sections[3].hdr.sh_name = nmTable.AddName(".bss");
1604
    sections[3].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
1605
    sections[3].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
1606
    sections[3].hdr.sh_addr = sections[2].hdr.sh_addr + sections[2].index;
1607
    sections[3].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
1608
    sections[3].hdr.sh_size = 0;
1609
    sections[3].hdr.sh_link = 0;
1610
    sections[3].hdr.sh_info = 0;
1611
    sections[3].hdr.sh_addralign = 8;
1612
    sections[3].hdr.sh_entsize = 0;
1613
 
1614
    sections[4].hdr.sh_name = nmTable.AddName(".tls");
1615
    sections[4].hdr.sh_type = clsElf64Shdr::SHT_PROGBITS;
1616
    sections[4].hdr.sh_flags = clsElf64Shdr::SHF_ALLOC | clsElf64Shdr::SHF_WRITE;
1617
    sections[4].hdr.sh_addr = sections[3].hdr.sh_addr + sections[3].index;;
1618
    sections[4].hdr.sh_offset = sections[2].hdr.sh_offset + sections[2].index; // offset in file
1619
    sections[4].hdr.sh_size = 0;
1620
    sections[4].hdr.sh_link = 0;
1621
    sections[4].hdr.sh_info = 0;
1622
    sections[4].hdr.sh_addralign = 8;
1623
    sections[4].hdr.sh_entsize = 0;
1624
 
1625
    sections[5].hdr.sh_name = nmTable.AddName(".strtab");
1626
    // The following line must be before the name table is copied to the section.
1627
    sections[6].hdr.sh_name = nmTable.AddName(".symtab");
1628
    sections[7].hdr.sh_name = nmTable.AddName(".reltext");
1629
    sections[8].hdr.sh_name = nmTable.AddName(".relrodata");
1630
    sections[9].hdr.sh_name = nmTable.AddName(".reldata");
1631
    sections[10].hdr.sh_name = nmTable.AddName(".relbss");
1632
    sections[11].hdr.sh_name = nmTable.AddName(".reltls");
1633
    sections[5].hdr.sh_type = clsElf64Shdr::SHT_STRTAB;
1634
    sections[5].hdr.sh_flags = 0;
1635
    sections[5].hdr.sh_addr = 0;
1636
    sections[5].hdr.sh_offset = 512 + sections[0].index + sections[1].index + sections[2].index; // offset in file
1637
    sections[5].hdr.sh_size = nmTable.length;
1638
    sections[5].hdr.sh_link = 0;
1639
    sections[5].hdr.sh_info = 0;
1640
    sections[5].hdr.sh_addralign = 1;
1641
    sections[5].hdr.sh_entsize = 0;
1642
    memcpy(sections[5].bytes, nmTable.text, nmTable.length);
1643
 
1644
    sections[6].hdr.sh_type = clsElf64Shdr::SHT_SYMTAB;
1645
    sections[6].hdr.sh_flags = 0;
1646
    sections[6].hdr.sh_addr = 0;
1647
    sections[6].hdr.sh_offset = Round512(512 + sections[0].index + sections[1].index + sections[2].index) + nmTable.length; // offset in file
1648
    sections[6].hdr.sh_size = (numsym + 1) * 24;
1649
    sections[6].hdr.sh_link = 5;
1650
    sections[6].hdr.sh_info = 0;
1651
    sections[6].hdr.sh_addralign = 1;
1652
    sections[6].hdr.sh_entsize = 24;
1653
 
1654
    for(nn = 7; nn < 12; nn++) {
1655
        sections[nn].hdr.sh_type = clsElf64Shdr::SHT_REL;
1656
        sections[nn].hdr.sh_flags = 0;
1657
        sections[nn].hdr.sh_addr = 0;
1658
        sections[nn].hdr.sh_offset = sections[nn-1].hdr.sh_offset + sections[nn-1].hdr.sh_size; // offset in file
1659
        sections[nn].hdr.sh_size = sections[nn].index;
1660
        sections[nn].hdr.sh_link = 6;
1661
        sections[nn].hdr.sh_info = 0;
1662
        sections[nn].hdr.sh_addralign = 1;
1663
        sections[nn].hdr.sh_entsize = 16;
1664
    }
1665
 
1666
    nn = 1;
1667
    // The first entry is an NULL symbol
1668
    elfsym.st_name = 0;
1669
    elfsym.st_info = 0;
1670
    elfsym.st_other = 0;
1671
    elfsym.st_shndx = 0;
1672
    elfsym.st_value = 0;
1673
    elfsym.st_size = 0;
1674
    sections[6].Add(&elfsym);
1675
    syms = (SYM*)HashInfo.table;
1676
    for (nn = 0; nn < HashInfo.size; nn++) {
1677
        // Don't output the constants
1678
//        if (syms[nn].segment < 5) {
1679
          if (syms[nn].name) {
1680
            elfsym.st_name = syms[nn].name;
1681
            elfsym.st_info = syms[nn].scope == 'P' ? STB_GLOBAL << 4 : 0;
1682
            elfsym.st_other = 0;
1683
            elfsym.st_shndx = syms[nn].segment;
1684
            elfsym.st_value = syms[nn].value.low;
1685
            elfsym.st_size = 8;
1686
            sections[6].Add(&elfsym);
1687
//        }
1688
        }
1689
    }
1690
 
1691
    elf.hdr.e_ident[0] = 127;
1692
    elf.hdr.e_ident[1] = 'E';
1693
    elf.hdr.e_ident[2] = 'L';
1694
    elf.hdr.e_ident[3] = 'F';
1695
    elf.hdr.e_ident[4] = clsElf64Header::ELFCLASS64;   // 64 bit file format
1696
    elf.hdr.e_ident[5] = clsElf64Header::ELFDATA2LSB;  // little endian
1697
    elf.hdr.e_ident[6] = 1;        // header version always 1
1698
    elf.hdr.e_ident[7] = 255;      // OS/ABI indentification, 255 = standalone
1699
    elf.hdr.e_ident[8] = 255;      // ABI version
1700
    elf.hdr.e_ident[9] = 0;
1701
    elf.hdr.e_ident[10] = 0;
1702
    elf.hdr.e_ident[11] = 0;
1703
    elf.hdr.e_ident[12] = 0;
1704
    elf.hdr.e_ident[13] = 0;
1705
    elf.hdr.e_ident[14] = 0;
1706
    elf.hdr.e_ident[15] = 0;
1707
    elf.hdr.e_type = rel_out ? 1 : 2;
1708
    elf.hdr.e_machine = 888;         // machine architecture
1709
    elf.hdr.e_version = 1;
1710
    sym = find_symbol("start");
1711
    if (sym)
1712
        start = sym->value.low;
1713
    else
1714
        start = 0xC00200;
1715
    elf.hdr.e_entry = start;
1716
    elf.hdr.e_phoff = 0;
1717
    elf.hdr.e_shoff = sections[11].hdr.sh_offset + sections[11].index;
1718
    elf.hdr.e_flags = 0;
1719
    elf.hdr.e_ehsize = Elf64HdrSz;
1720
    elf.hdr.e_phentsize = 0;
1721
    elf.hdr.e_phnum = 0;
1722
    elf.hdr.e_shentsize = Elf64ShdrSz;
1723
    elf.hdr.e_shnum = 0;              // This will be incremented by AddSection()
1724
    elf.hdr.e_shstrndx = 5;           // index into section table of string table header
1725
 
1726
    for (nn = 0; nn < 12; nn++)
1727
        elf.AddSection(&sections[nn]);
1728
    elf.Write(fp);
1729
 
1730
}
1731
 
1732
int IHChecksum(char *ibuf, int payloadCount)
1733
{
1734
    char buf[20];
1735
    int nn;
1736
    int ii;
1737
    int sum;
1738
 
1739
    sum = 0;
1740
    for (nn = 0; nn < payloadCount +4; nn++) {
1741
        buf[0] = ibuf[nn*2+1];
1742
        buf[1] = ibuf[nn*2+2];
1743
        buf[2] = '\0';
1744
        ii = strtoul(buf,NULL,16);
1745
        sum = sum + ii;
1746
    }
1747
    sum = -sum;
1748
    sprintf(&ibuf[(payloadCount+4) * 2+1],"%02X\n", sum & 0xFF);
1749
        return sum;
1750
}
1751
 
1752
// ----------------------------------------------------------------------------
1753
// ----------------------------------------------------------------------------
1754
 
1755
int64_t getbit(int n, int bit)
1756
{
1757
        return (n >> bit) & 1;
1758
}
1759
 
1760
// ----------------------------------------------------------------------------
1761
// Compute 38 bit ECC (32+6 bits EDC).
1762
// ----------------------------------------------------------------------------
1763
 
1764
int checkbits(unsigned int i)
1765
{
1766
/*
1767
        unsigned int p0,p1,p2,p3,p4,p5,p;
1768
        unsigned int t1,t2,t3;
1769
 
1770
        p0 = u ^ (u >> 2);
1771
        p0 = p0 ^ (p0 >> 4);
1772
        p0 = p0 ^ (p0 >> 8);
1773
        p0 = p0 ^ (p0 >> 16);
1774
 
1775
        t1 = u ^ (u >> 1);
1776
        p1 = t1 ^ (t1 >> 4);
1777
        p1 = p1 ^ (p1 >> 8);
1778
        p1 = p1 ^ (p1 >> 16);
1779
 
1780
        t2 = t1 ^ (t1 >> 2);
1781
        p2 = t2 ^ (t2 >> 8);
1782
        p2 = p2 ^ (p2 >> 16);
1783
 
1784
        t3 = t2 ^ (t2 >> 4);
1785
        p3 = t3 ^ (t3 >> 16);
1786
 
1787
        p4 = t3 ^ (t3 >> 8);
1788
 
1789
        p5 = p4 ^ (p4 >> 16);
1790
 
1791
        p = ((p0 >> 1)&1) | ((p1 >> 1)&2) | ((p2>>2)&4) |
1792
                ((p3 >> 5)&8) | ((p4 >> 12)&16) | ((p5 & 1)<<5);
1793
 
1794
        p = p ^ (-(u & 1)&0x3f);        // now account for u[0]
1795
        return p;
1796
*/
1797
 
1798
        static int8_t g1[18] = {0,1,3,4,6,8,10,11,13,15,17,19,21,23,25,26,28,30};
1799
        static int8_t g2[18] = {0,2,3,5,6,9,10,12,13,16,17,20,21,24,25,27,28,31};
1800
        static int8_t g4[18] = {1,2,3,7,8,9,10,14,15,16,17,22,23,24,25,29,30,31};
1801
        static int8_t g8[15] = {4,5,6,7,8,9,10,18,19,20,21,22,23,24,25};
1802
        static int8_t g16[15] = {11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
1803
        static int8_t g32[6] = {26,27,28,29,30,31};
1804
        unsigned int p1,p2,p4,p8,p16,p32,pg,b,o;
1805
        int nn;
1806
 
1807
        p1 = 0;
1808
        for (nn = 0; nn < 18; nn++) {
1809
                b = getbit(i,g1[nn]);
1810
                p1 = p1 ^ b;
1811
        }
1812
        p2 = 0;
1813
        for (nn = 0; nn < 18; nn++) {
1814
                b = getbit(i,g2[nn]);
1815
                p2 = p2 ^ b;
1816
        }
1817
        p4 = 0;
1818
        for (nn = 0; nn < 18; nn++) {
1819
                b = getbit(i,g4[nn]);
1820
                p4 = p4 ^ b;
1821
        }
1822
        p8 = 0;
1823
        for (nn = 0; nn < 15; nn++) {
1824
                b = getbit(i,g8[nn]);
1825
                p8 = p8 ^ b;
1826
        }
1827
        p16 = 0;
1828
        for (nn = 0; nn < 15; nn++) {
1829
                b = getbit(i,g16[nn]);
1830
                p16 = p16 ^ b;
1831
        }
1832
        p32 = 0;
1833
        for (nn = 0; nn < 6; nn++) {
1834
                b = getbit(i,g32[nn]);
1835
                p32 = p32 ^ b;
1836
        }
1837
/*
1838
        o = p1|(p2<<1)|(getbit(i,0)<<2)|(p4<<3);
1839
        o = o | (getbit(i,1)<<4)| (getbit(i,2)<<5)| (getbit(i,3)<<6)|(p8<<7);
1840
        for (nn = 4; nn <= 10; nn++)
1841
                o = o | (getbit(i,nn)<<(nn+4));
1842
        o = o | (p16 << 15);
1843
        for (nn = 11; nn <= 25; nn++)
1844
                o = o | (getbit(i,nn)<<(nn+5));
1845
        o = o | (p32 << 31);
1846
        for (nn = 26; nn <= 31; nn++)
1847
                o = o | (getbit(i,nn)<<(nn+6));
1848
*/
1849
        pg = checksum((int32_t*)&i)^p1^p2^p4^p8^p16^p32;
1850
//      o = i | (p32<<37)|(p16<<36)|(p8<<35)|(p4<<34)|(p2<<33)|(p1<<32) | (pg << 38);
1851
        o = (p32<<5)|(p16<<4)|(p8<<3)|(p4<<2)|(p2<<1)|p1|(pg<<6);
1852
        return o;
1853
}
1854
 
1855
/*
1856
int PreProcessFile(char *nm)
1857
{
1858
        static char outname[1000];
1859
        static char sysbuf[500];
1860
 
1861
        strcpy_s(outname, sizeof(outname), nm);
1862
        strcat_s(outname,sizeof(outname),".app.asm");
1863
        sprintf_s(sysbuf, sizeof(sysbuf), "app -V %s %s", nm, outname);
1864
        return system(sysbuf);
1865
}
1866
*/
1867
// ----------------------------------------------------------------------------
1868
// ----------------------------------------------------------------------------
1869
 
1870
int main(int argc, char *argv[])
1871
{
1872
    int nn,qq,kk;
1873
    static char fname[500];
1874
    static char hexbuf[500];
1875
    char *p;
1876
    uint64_t lsa;      // last start address
1877
    double bpi;
1878
    int64_t i64;
1879
    uint32_t u32;
1880
        float nc2;
1881
 
1882
    processOpt = 1;
1883
        sections[bssseg].storebyte = 0;
1884
    ofp = stdout;
1885
    nn = processOptions(argc, argv);
1886
    if (nn > argc-1) {
1887
       displayHelp();
1888
       return 0;
1889
    }
1890
    SymbolInit();
1891
    strcpy_s(fname, sizeof(fname), argv[nn]);
1892
    mfndx = 0;
1893
    start_address = 0;
1894
    code_address = 0;
1895
    bss_address = 0;
1896
    data_address = 0;
1897
    isInitializationData = 0;
1898
    for (qq = 0; qq < 12; qq++)
1899
        sections[qq].Clear();
1900
    nmTable.Clear();
1901
    memset(masterFile,0,sizeof(masterFile));
1902
    if (verbose) printf("Pass 1 - collect all input files.\r\n");
1903
        //PreProcessFile(fname);
1904
        //strcat_s(fname,sizeof(fname),".app.asm");
1905
    processFile(fname,0);   // Pass 1, collect all include files
1906
    if (debug) {
1907
        FILE *fp;
1908
        fopen_s(&fp, "a64-master.asm", "w");
1909
        if (fp) {
1910
                fwrite(masterFile, 1, strlen(masterFile), fp);
1911
                fclose(fp);
1912
        }
1913
    }
1914
 
1915
    if (verbose) printf("Pass 2 - group and reorder segments\r\n");
1916
    first_org = 1;
1917
    processSegments();     // Pass 2, group and order segments
1918
 
1919
    pass = 3;
1920
    processMaster();       // Pass 3 collect up opcodes
1921
    printf("Qsorting\r\n");
1922
    qsort((HTBLE*)hTable, htblmax, sizeof(HTBLE), hcmp);
1923
 
1924
    pass = 4;
1925
    if (verbose) printf("Pass 4 - get all symbols, set initial values.\r\n");
1926
    first_org = 1;
1927
    processMaster();
1928
    pass = 5;
1929
    phasing_errors = 0;
1930
    if (verbose) printf("Pass 5 - assemble code.\r\n");
1931
    first_org = 1;
1932
    processMaster();
1933
    if (verbose) printf("Pass 6: phase errors: %d\r\n", phasing_errors);
1934
    pass = 6;
1935
        pe3 = pe2 = pe1 = 0;
1936
    while (phasing_errors && pass < 40) {
1937
        phasing_errors = 0;
1938
        num_bytes = 0;
1939
        num_insns = 0;
1940
                num_cinsns = 0;
1941
            first_org = 1;
1942
        processMaster();
1943
        if (verbose) printf("Pass %d: phase errors: %d\r\n", pass, phasing_errors);
1944
        pass++;
1945
                pe3 = pe2;
1946
                pe2 = pe1;
1947
                pe1 = phasing_errors;
1948
                if (pe1==pe2 && pe2==pe3 && pe1==pe3) {
1949
                        if (verbose)
1950
                                printf("Non converging phase errors\r\n");
1951
                        break;
1952
                }
1953
    }
1954
    //processMaster();
1955
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1956
    // Output listing file.
1957
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1958
    ofp = (FILE *)NULL;
1959
    if (listing) {
1960
        if (verbose) printf("Generating listing file %s.\r\n", argv[nn]);
1961
        strcpy_s(fname, sizeof(fname), argv[nn]);
1962
        p = strrchr(fname,'.');
1963
        if (p) {
1964
            *p = '\0';
1965
        }
1966
        strcat_s(fname, sizeof(fname), ".lst");
1967
        fopen_s(&ofp, fname,"w");
1968
        if (!ofp)
1969
           printf("Can't open output file <%s>\r\n", fname);
1970
        bGen = 1;
1971
    }
1972
    processOpt = 2;
1973
        bGenListing = true;
1974
    processMaster();
1975
        bGenListing = false;
1976
    DumpSymbols();
1977
    DumphTable();
1978
    fprintf(ofp, "\nnumber of bytes: %f\n", num_bytes);
1979
    fprintf(ofp, "number of instructions: %d\n", num_insns);
1980
        fprintf(ofp, "number of compressed instructions: %d\n", num_cinsns);
1981
        bpi = (double)num_bytes/(double)num_insns;
1982
    fprintf(ofp, "%0.6f bytes (%d bits) per instruction\n", bpi, (int)(bpi*8));
1983
        nc2 = (float)num_cinsns * 2.0;
1984
        fprintf(ofp, "Compression ratio: %f%%", (nc2 / (num_bytes + nc2)) * 100.0);
1985
 
1986
/*
1987
    chksum = 0;
1988
    for (nn = 0; nn < binndx; nn+=4) {
1989
        chksum += binfile[nn] +
1990
                  (binfile[nn+1] << 8) +
1991
                  (binfile[nn+2] << 16) +
1992
                  (binfile[nn+3] << 24)
1993
                  ;
1994
    }
1995
 
1996
    fprintf(ofp, "\r\nChecksum: %08X\r\n", chksum);
1997
*/
1998
    if (listing)
1999
        fclose(ofp);
2000
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2001
    // Output binary file.
2002
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2003
    if (binary_out) {
2004
        if (verbose) printf("Generating binary file.\r\n");
2005
        strcpy_s(fname, sizeof(fname), argv[nn]);
2006
        p = strrchr(fname,'.');
2007
        if (p) {
2008
            *p = '\0';
2009
        }
2010
        strcat_s(fname, sizeof(fname), ".bin");
2011
        fopen_s(&ofp, fname,"wb");
2012
        if (ofp) {
2013
            fwrite((void*)sections[0].bytes,sections[0].index,1,ofp);
2014
            fwrite((void*)sections[1].bytes,sections[1].index,1,ofp);
2015
            //fwrite((void*)sections[2].bytes,sections[2].index,1,ofp);
2016
            //fwrite(binfile,binndx,1,ofp);
2017
            fclose(ofp);
2018
        }
2019
        else
2020
            printf("Can't create .bin file.\r\n");
2021
    }
2022
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2023
    // Output ELF file.
2024
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2025
    if (elf_out) {
2026
        if (verbose) printf("Generating ELF file.\r\n");
2027
        strcpy_s(fname, sizeof(fname), argv[nn]);
2028
        p = strrchr(fname,'.');
2029
        if (p) {
2030
            *p = '\0';
2031
        }
2032
        if (rel_out)
2033
            strcat_s(fname, sizeof(fname), ".rel");
2034
        else
2035
            strcat_s(fname, sizeof(fname), ".elf");
2036
        fopen_s(&ofp, fname,"wb");
2037
        if (ofp) {
2038
            WriteELFFile(ofp);
2039
            fclose(ofp);
2040
        }
2041
        else
2042
            printf("Can't create .elf file.\r\n");
2043
    }
2044
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2045
    // Output coe file
2046
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2047
    if (coe_out) {
2048
            if (verbose) printf("Generating COE file.\r\n");
2049
            strcpy_s(fname, sizeof(fname), argv[nn]);
2050
            p = strrchr(fname,'.');
2051
            if (p) {
2052
                *p = '\0';
2053
            }
2054
            strcat_s(fname, sizeof(fname), ".coe");
2055
            fopen_s(&vfp, fname, "w");
2056
            if (vfp) {
2057
                fprintf(vfp, "memory_initialization_radix=16;\r\n");
2058
                fprintf(vfp, "memory_initialization_vector=\r\n");
2059
                for (kk = 0;kk < binndx; kk+=4) {
2060
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
2061
                    i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
2062
                    fprintf(vfp, "%010I64X,\r\n", i64);
2063
                }
2064
                fprintf(vfp,"000000;\r\n");
2065
                fclose(vfp);
2066
                }
2067
        }
2068
 
2069
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2070
    // Output Verilog memory declaration
2071
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2072
    if (verilog_out) {
2073
        if (verbose) printf("Generating Verilog file.\r\n");
2074
        strcpy_s(fname, sizeof(fname), argv[nn]);
2075
        p = strrchr(fname,'.');
2076
        if (p) {
2077
            *p = '\0';
2078
        }
2079
        strcat_s(fname, sizeof(fname), ".ve0");
2080
        fopen_s(&vfp, fname, "w");
2081
        if (vfp) {
2082
                        /*
2083
                        if (gCpu=='A') {
2084
                                dsd9_VerilogOut(vfp);
2085
                        }
2086
            else
2087
                        */
2088
                        if (gCpu=='F' || gCpu=='G') {
2089
                                if (vebits==128) {
2090
                                        for (kk = 0; kk < binndx; kk+=16) {
2091
                                                fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2092
                                                        ((((unsigned int)start_address+kk)/16)%16384), //checksum64((int64_t *)&binfile[kk]),
2093
                                                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
2094
                                                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
2095
                                                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
2096
                                                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2097
                                        }
2098
                                }
2099
                                else if (vebits==64) {
2100
                                        for (kk = 0; kk < binndx; kk+=8) {
2101
                                                fprintf(vfp, "\trommem[%d] = 64'h%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2102
                                                        ((((unsigned int)start_address+kk)/8)%16384), //checksum64((int64_t *)&binfile[kk]),
2103
                                                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
2104
                                                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2105
                                        }
2106
                                }
2107
            }
2108
                        /*
2109
                        else if (gCpu=='G') {
2110
                for (kk = 0; kk < binndx; kk+=32) {
2111
                    fprintf(vfp, "\trommem[%d] = 256'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
2112
                                                "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2113
                        ((((unsigned int)start_address+kk)/32)%16384), //checksum64((int64_t *)&binfile[kk]),
2114
                        binfile[kk+31], binfile[kk+30], binfile[kk+29], binfile[kk+28],
2115
                        binfile[kk+27], binfile[kk+26], binfile[kk+25], binfile[kk+24],
2116
                        binfile[kk+23], binfile[kk+22], binfile[kk+21], binfile[kk+20],
2117
                        binfile[kk+19], binfile[kk+18], binfile[kk+17], binfile[kk+16],
2118
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
2119
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
2120
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
2121
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2122
                }
2123
            }
2124
                        */
2125
                        else if (gCpu==64) {
2126
                for (kk = 0; kk < binndx; kk+=8) {
2127
                    fprintf(vfp, "\trommem0[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2128
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
2129
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
2130
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2131
                }
2132
            }
2133
            else if (gCpu==5) {
2134
                for (kk = 0;kk < binndx; kk+=4) {
2135
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
2136
                    i64 = (uint64_t)u32;
2137
                    fprintf(vfp, "\trommem[%d] = 32'h%08I64X;\n",
2138
                        (int)(((start_address+kk)/4)%32768), i64);
2139
                }
2140
            }
2141
                        else if (gCpu=='A') {
2142
                for (kk = 0; kk < binndx; kk+=16) {
2143
                    fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2144
                        (((0+kk)/16)%16384),
2145
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
2146
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
2147
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
2148
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2149
                }
2150
                                if (kk != binndx)
2151
                    fprintf(vfp, "\trommem[%d] = 128'h%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2152
                        (((0+kk)/16)%16384),
2153
                        binfile[kk+15], binfile[kk+14], binfile[kk+13], binfile[kk+12],
2154
                        binfile[kk+11], binfile[kk+10], binfile[kk+9], binfile[kk+8],
2155
                        binfile[kk+7], binfile[kk+6], binfile[kk+5], binfile[kk+4],
2156
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2157
            }
2158
            else {
2159
                for (kk = 0;kk < binndx; kk+=4) {
2160
                        u32 = (binfile[kk+3]<<24)|(binfile[kk+2]<<16)|(binfile[kk+1]<<8)|binfile[kk];
2161
                    i64 = ((uint64_t)checkbits(u32) << 32)|(uint64_t)u32;
2162
                    fprintf(vfp, "\trommem0[%d] = 39'h%010I64X;\n",
2163
                        (int)(((0+kk)/4)%32768), i64);
2164
                }
2165
            }
2166
            fclose(vfp);
2167
        }
2168
        else
2169
            printf("Can't create .ver file.\r\n");
2170
        strcpy_s(fname, sizeof(fname), argv[nn]);
2171
        p = strrchr(fname,'.');
2172
        if (p) {
2173
            *p = '\0';
2174
        }
2175
        strcat_s(fname, sizeof(fname), ".ve1");
2176
        fopen_s(&vfp, fname, "w");
2177
        if (vfp) {
2178
            if (gCpu==64) {
2179
                for (kk = 0; kk < binndx; kk+=8) {
2180
                    fprintf(vfp, "\trommem1[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2181
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
2182
                        binfile[kk+7]^0xAA, binfile[kk+6], binfile[kk+5], binfile[kk+4],
2183
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2184
                }
2185
            }
2186
            else {
2187
                for (kk = 0;kk < binndx; kk+=4) {
2188
                    fprintf(vfp, "\trommem1[%d] = 32'h%02X%02X%02X%02X;\n",
2189
                        (((start_address+kk)/4)%32768), binfile[kk+3]^0xAA, binfile[kk+2]^0xAA, binfile[kk+1]^0xAA, binfile[kk]^0xAA);
2190
                }
2191
            }
2192
            fclose(vfp);
2193
        }
2194
        else
2195
            printf("Can't create .ver file.\r\n");
2196
        strcpy_s(fname, sizeof(fname), argv[nn]);
2197
        p = strrchr(fname,'.');
2198
        if (p) {
2199
            *p = '\0';
2200
        }
2201
        strcat_s(fname, sizeof(fname), ".ve2");
2202
        fopen_s(&vfp, fname, "w");
2203
        if (vfp) {
2204
            if (gCpu==64) {
2205
                for (kk = 0; kk < binndx; kk+=8) {
2206
                    fprintf(vfp, "\trommem2[%d] = 65'h%01d%02X%02X%02X%02X%02X%02X%02X%02X;\n",
2207
                        (((0+kk)/8)%16384), checksum64((int64_t *)&binfile[kk]),
2208
                        binfile[kk+7]^0x55, binfile[kk+6], binfile[kk+5], binfile[kk+4],
2209
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2210
                }
2211
            }
2212
            else {
2213
                for (kk = 0;kk < binndx; kk+=4) {
2214
                    fprintf(vfp, "\trommem2[%d] = 32'h%02X%02X%02X%02X;\n",
2215
                        (((start_address+kk)/4)%32768), binfile[kk+3]^0x55, binfile[kk+2]^0x55, binfile[kk+1]^0x55, binfile[kk]^0x55);
2216
                }
2217
            }
2218
            fclose(vfp);
2219
        }
2220
        else
2221
            printf("Can't create .ver file.\r\n");
2222
    }
2223
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2224
    // Output Verilog memory declaration
2225
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2226
        if (verbose) printf("Generating Text file.\r\n");
2227
        strcpy_s(fname, sizeof(fname), argv[nn]);
2228
        p = strrchr(fname,'.');
2229
        if (p) {
2230
            *p = '\0';
2231
        }
2232
        strcat_s(fname, sizeof(fname), ".txt");
2233
        printf("fname:%s\r\n", fname);
2234
        fopen_s(&vfp, fname, "w");
2235
        if (vfp) {
2236
            if (gCpu==64) {
2237
                for (kk = 0; kk < binndx; kk+=4) {
2238
                    fprintf(vfp, "%06X,%02X%02X%02X%02X\n",
2239
                        (((start_address+kk))),
2240
                        binfile[kk+3], binfile[kk+2], binfile[kk+1], binfile[kk]);
2241
                }
2242
            }
2243
            fclose(vfp);
2244
        }
2245
        else
2246
            printf("Can't create .txt file.\r\n");
2247
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2248
    // Output Intel hex file
2249
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2250
        if (verbose) printf("Generating Hex file.\r\n");
2251
        strcpy_s(fname, sizeof(fname), argv[nn]);
2252
        p = strrchr(fname,'.');
2253
        if (p) {
2254
            *p = '\0';
2255
        }
2256
        lsa = 0;
2257
        strcat_s(fname, sizeof(fname), ".hex");
2258
        printf("fname:%s\r\n", fname);
2259
        fopen_s(&vfp, fname, "w");
2260
        if (vfp) {
2261
            if (gCpu==64||gCpu=='F'||gCpu=='G') {
2262
                for (kk = 0; kk < binndx; kk+=4) {
2263
                    if (lsa != (start_address + kk) >> 16) {
2264
                        sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
2265
                        IHChecksum(hexbuf, 2);
2266
                        fprintf(vfp, hexbuf);
2267
                        lsa = (start_address+kk) >> 16;
2268
                    }
2269
                    sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X\n",
2270
                        4, (int)(start_address + kk) & 0xFFFF,
2271
                        binfile[kk], binfile[kk+1], binfile[kk+2], binfile[kk+3]
2272
                    );
2273
                    IHChecksum(hexbuf, 4);
2274
                    fprintf(vfp, hexbuf);
2275
                }
2276
            }
2277
            else if (gCpu==4) {
2278
                for (kk = 0; kk < binndx; kk+=8) {
2279
                    if (lsa != (start_address + kk) >> 16) {
2280
                        sprintf_s(hexbuf, sizeof(hexbuf), ":02000004%04X00\n", (int)((start_address+kk) >> 16));
2281
                        IHChecksum(hexbuf, 2);
2282
                        fprintf(vfp, hexbuf);
2283
                        lsa = (start_address+kk) >> 16;
2284
                    }
2285
                    sprintf_s(hexbuf, sizeof(hexbuf), ":%02X%04X00%02X%02X%02X%02X%02X%02X%02X%02X\n",
2286
                        8, (start_address + kk) & 0xFFFF,
2287
                        binfile[kk], binfile[kk+1], binfile[kk+2],binfile[kk+3],
2288
                        binfile[kk+4],binfile[kk+5],binfile[kk+6],binfile[kk+7]
2289
                    );
2290
                    IHChecksum(hexbuf, 8);
2291
                    fprintf(vfp, hexbuf);
2292
                }
2293
            }
2294
            fprintf(vfp, ":00000001FF\n%c",26);        // end of file record
2295
            fclose(vfp);
2296
        }
2297
        else
2298
            printf("Can't create .hex file.\r\n");
2299
    return 0;
2300
}
2301
 
2302
bool IsNBit(int64_t val, int64_t n)
2303
{
2304
        int64_t low, high;
2305
 
2306
        low = -(1LL << (n - 1LL));
2307
        high = (1LL << (n - 1LL));
2308
        return (val >= low && val < high);
2309
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.