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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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