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

Subversion Repositories thor

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2016  Robert Finch, Stratford
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// A64 - 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
static void emitAlignedCode(int cd);
29
static void process_shifti(int oc, int funct3, int funct7);
30
static void ProcessEOL(int opt);
31
 
32
extern int first_rodata;
33
extern int first_data;
34
extern int first_bss;
35
extern int htable[100000];
36
extern int htblcnt[100000];
37
extern int htblmax;
38
extern int pass;
39
 
40
static int64_t ca;
41
 
42
extern int use_gp;
43
 
44
#define OPT64     0
45
#define OPTX32    1
46
#define OPTLUI0   0
47
 
48
// ----------------------------------------------------------------------------
49
// Return the register number or -1 if not a register.
50
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
51
// ----------------------------------------------------------------------------
52
 
53
static int getRegisterX()
54
{
55
    int reg;
56
 
57
    while(isspace(*inptr)) inptr++;
58
    switch(*inptr) {
59
    case 'x': case 'X':
60
         if (isdigit(inptr[1])) {
61
             reg = inptr[1]-'0';
62
             if (isdigit(inptr[2])) {
63
                 reg = 10 * reg + (inptr[2]-'0');
64
                 if (isdigit(inptr[3])) {
65
                     reg = 10 * reg + (inptr[3]-'0');
66
                     if (isIdentChar(inptr[4]))
67
                         return -1;
68
                     inptr += 4;
69
                     NextToken();
70
                     return reg;
71
                 }
72
                 else if (isIdentChar(inptr[3]))
73
                     return -1;
74
                 else {
75
                     inptr += 3;
76
                     NextToken();
77
                     return reg;
78
                 }
79
             }
80
             else if (isIdentChar(inptr[2]))
81
                 return -1;
82
             else {
83
                 inptr += 2;
84
                 NextToken();
85
                 return reg;
86
             }
87
         }
88
         else return -1;
89
    case 'a': case 'A':
90
         if (isdigit(inptr[1])) {
91
             reg = inptr[1]-'0' + 18;
92
             if (isIdentChar(inptr[2]))
93
                 return -1;
94
             else {
95
                 inptr += 2;
96
                 NextToken();
97
                 return reg;
98
             }
99
         }
100
         else return -1;
101
    case 'f': case 'F':
102
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
103
            inptr += 2;
104
            NextToken();
105
            return 2;
106
        }
107
        break;
108
    case 'g': case 'G':
109
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
110
            inptr += 2;
111
            NextToken();
112
            return 26;
113
        }
114
        break;
115
    case 's': case 'S':
116
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
117
            inptr += 2;
118
            NextToken();
119
            return 14;
120
        }
121
        break;
122
    case 't': case 'T':
123
         if (isdigit(inptr[1])) {
124
             reg = inptr[1]-'0' + 26;
125
             if (isIdentChar(inptr[2]))
126
                 return -1;
127
             else {
128
                 inptr += 2;
129
                 NextToken();
130
                 return reg;
131
             }
132
         }
133
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
134
            inptr += 2;
135
            NextToken();
136
            return 15;
137
        }
138
        /*
139
        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
140
            inptr += 2;
141
            NextToken();
142
            return 24;
143
        }
144
        */
145
        break;
146
    case 'p': case 'P':
147
        if ((inptr[1]=='c' || inptr[1]=='C') && !isIdentChar(inptr[2])) {
148
            inptr += 2;
149
            NextToken();
150
            return 29;
151
        }
152
        break;
153
    case 'l': case 'L':
154
        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
155
            inptr += 2;
156
            NextToken();
157
            return 31;
158
        }
159
        break;
160
    case 'r': case 'R':
161
        if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
162
            inptr += 2;
163
            NextToken();
164
            return 1;
165
        }
166
        break;
167
    case 'v': case 'V':
168
         if (inptr[1]=='0' || inptr[1]=='1') {
169
             reg = inptr[1]-'0' + 16;
170
             if (isIdentChar(inptr[2]))
171
                 return -1;
172
             else {
173
                 inptr += 2;
174
                 NextToken();
175
                 return reg;
176
             }
177
         }
178
    default:
179
        return -1;
180
    }
181
    return -1;
182
}
183
 
184
static int isdelim(char ch)
185
{
186
    return ch==',' || ch=='[' || ch=='(' || ch==']' || ch==')' || ch=='.';
187
}
188
 
189
// ----------------------------------------------------------------------------
190
// ----------------------------------------------------------------------------
191
 
192
static int getCodeareg()
193
{
194
    int pr;
195
 
196
    SkipSpaces();
197
    if (inptr[0]=='c' || inptr[0]=='C') {
198
         if (isdigit(inptr[1]) && (inptr[2]==',' || isdelim(inptr[2]) || isspace(inptr[2]))) {
199
              pr = (inptr[1]-'0');
200
              inptr += 2;
201
         }
202
         else if (isdigit(inptr[1]) && isdigit(inptr[2]) && (inptr[3]==',' || isdelim(inptr[3]) || isspace(inptr[3]))) {
203
              pr = ((inptr[1]-'0') * 10) + (inptr[2]-'0');
204
              inptr += 3;
205
         }
206
         else
207
             return -1;
208
    }
209
    else
210
        return -1;
211
     NextToken();
212
     return pr;
213
}
214
 
215
 
216
// ----------------------------------------------------------------------------
217
// Get the friendly name of a special purpose register.
218
// ----------------------------------------------------------------------------
219
 
220
static int DSD6_getSprRegister()
221
{
222
    int reg;
223
    int pr;
224
 
225
    while(isspace(*inptr)) inptr++;
226
    reg = getCodeareg();
227
    if (reg >= 0) {
228
       reg |= 0x10;
229
       return reg;
230
    }
231
    if (inptr[0]=='p' || inptr[0]=='P') {
232
         if (isdigit(inptr[1]) && isdigit(inptr[2])) {
233
              pr = ((inptr[1]-'0' * 10) + (inptr[2]-'0'));
234
              if (!isIdentChar(inptr[3])) {
235
                  inptr += 3;
236
                  NextToken();
237
                  return pr | 0x40;
238
              }
239
         }
240
         else if (isdigit(inptr[1])) {
241
              pr = (inptr[1]-'0');
242
              if (!isIdentChar(inptr[2])) {
243
                  inptr += 2;
244
                  NextToken();
245
                  return pr | 0x40;
246
              }
247
         }
248
     }
249
 
250
    while(isspace(*inptr)) inptr++;
251
    switch(*inptr) {
252
 
253
    case '0':
254
    case '1':
255
    case '2':
256
    case '3':
257
    case '4':
258
    case '5':
259
    case '6':
260
    case '7':
261
    case '8':
262
    case '9':
263
         NextToken();
264
         NextToken();
265
         return ival.low;
266
 
267
    // arg1
268
    case 'a': case 'A':
269
         if ((inptr[1]=='r' || inptr[1]=='R') &&
270
             (inptr[2]=='g' || inptr[2]=='G') &&
271
             (inptr[3]=='1' || inptr[3]=='1') &&
272
             !isIdentChar(inptr[4])) {
273
             inptr += 4;
274
             NextToken();
275
             return 58;
276
         }
277
         break;
278
    // bear
279
    case 'b': case 'B':
280
         if ((inptr[1]=='e' || inptr[1]=='E') &&
281
             (inptr[2]=='a' || inptr[2]=='A') &&
282
             (inptr[3]=='r' || inptr[3]=='R') &&
283
             !isIdentChar(inptr[4])) {
284
             inptr += 4;
285
             NextToken();
286
             return 11;
287
         }
288
         break;
289
    // cas clk cr0 cr3 cs CPL
290
    case 'c': case 'C':
291
         if ((inptr[1]=='a' || inptr[1]=='A') &&
292
             (inptr[2]=='s' || inptr[2]=='S') &&
293
             !isIdentChar(inptr[3])) {
294
             inptr += 3;
295
             NextToken();
296
             return 44;
297
         }
298
         if ((inptr[1]=='l' || inptr[1]=='L') &&
299
             (inptr[2]=='k' || inptr[2]=='K') &&
300
             !isIdentChar(inptr[3])) {
301
             inptr += 3;
302
             NextToken();
303
             return 0x06;
304
         }
305
         if ((inptr[1]=='r' || inptr[1]=='R') &&
306
             (inptr[2]=='0') &&
307
             !isIdentChar(inptr[3])) {
308
             inptr += 3;
309
             NextToken();
310
             return 0x00;
311
         }
312
         if ((inptr[1]=='r' || inptr[1]=='R') &&
313
             (inptr[2]=='3') &&
314
             !isIdentChar(inptr[3])) {
315
             inptr += 3;
316
             NextToken();
317
             return 0x03;
318
         }
319
        if ((inptr[1]=='s' || inptr[1]=='S') &&
320
            !isIdentChar(inptr[2])) {
321
            if (inptr[2]=='.') {
322
               if ((inptr[3]=='l' || inptr[3]=='L') &&
323
                   (inptr[4]=='m' || inptr[4]=='M') &&
324
                   (inptr[5]=='t' || inptr[5]=='T') &&
325
                   !isIdentChar(inptr[6])) {
326
                       inptr += 6;
327
                       NextToken();
328
                       return 0x2F;
329
               }
330
            }
331
            inptr += 2;
332
            NextToken();
333
            return 0x27;
334
        }
335
         if ((inptr[1]=='p' || inptr[1]=='P') &&
336
             (inptr[2]=='l' || inptr[2]=='L') &&
337
             !isIdentChar(inptr[3])) {
338
             inptr += 3;
339
             NextToken();
340
             return 42;
341
         }
342
         break;
343
 
344
    // dbad0 dbad1 dbctrl dpc dsp ds
345
    case 'd': case 'D':
346
         if ((inptr[1]=='b' || inptr[1]=='B') &&
347
             (inptr[2]=='a' || inptr[2]=='A') &&
348
             (inptr[3]=='d' || inptr[3]=='D') &&
349
             (inptr[4]=='0' || inptr[4]=='0') &&
350
             !isIdentChar(inptr[5])) {
351
             inptr += 5;
352
             NextToken();
353
             return 50;
354
         }
355
         if ((inptr[1]=='b' || inptr[1]=='B') &&
356
             (inptr[2]=='a' || inptr[2]=='A') &&
357
             (inptr[3]=='d' || inptr[3]=='D') &&
358
             (inptr[4]=='1' || inptr[4]=='1') &&
359
             !isIdentChar(inptr[5])) {
360
             inptr += 5;
361
             NextToken();
362
             return 51;
363
         }
364
         if ((inptr[1]=='b' || inptr[1]=='B') &&
365
             (inptr[2]=='a' || inptr[2]=='A') &&
366
             (inptr[3]=='d' || inptr[3]=='D') &&
367
             (inptr[4]=='2' || inptr[4]=='2') &&
368
             !isIdentChar(inptr[5])) {
369
             inptr += 5;
370
             NextToken();
371
             return 52;
372
         }
373
         if ((inptr[1]=='b' || inptr[1]=='B') &&
374
             (inptr[2]=='a' || inptr[2]=='A') &&
375
             (inptr[3]=='d' || inptr[3]=='D') &&
376
             (inptr[4]=='3' || inptr[4]=='3') &&
377
             !isIdentChar(inptr[5])) {
378
             inptr += 5;
379
             NextToken();
380
             return 53;
381
         }
382
         if ((inptr[1]=='b' || inptr[1]=='B') &&
383
             (inptr[2]=='c' || inptr[2]=='C') &&
384
             (inptr[3]=='t' || inptr[3]=='T') &&
385
             (inptr[4]=='r' || inptr[4]=='R') &&
386
             (inptr[5]=='l' || inptr[5]=='L') &&
387
             !isIdentChar(inptr[6])) {
388
             inptr += 6;
389
             NextToken();
390
             return 54;
391
         }
392
         if ((inptr[1]=='p' || inptr[1]=='P') &&
393
             (inptr[2]=='c' || inptr[2]=='C') &&
394
             !isIdentChar(inptr[3])) {
395
             inptr += 3;
396
             NextToken();
397
             return 7;
398
         }
399
         if (
400
             (inptr[1]=='b' || inptr[1]=='B') &&
401
             (inptr[2]=='p' || inptr[2]=='P') &&
402
             (inptr[3]=='c' || inptr[3]=='C') &&
403
             !isIdentChar(inptr[4])) {
404
             inptr += 4;
405
             NextToken();
406
             return 7;
407
         }
408
         if ((inptr[1]=='s' || inptr[1]=='S') &&
409
             (inptr[2]=='p' || inptr[2]=='P') &&
410
             !isIdentChar(inptr[3])) {
411
             inptr += 3;
412
             NextToken();
413
             return 16;
414
         }
415
        if ((inptr[1]=='s' || inptr[1]=='S') &&
416
            !isIdentChar(inptr[2])) {
417
            if (inptr[2]=='.') {
418
               if ((inptr[3]=='l' || inptr[3]=='L') &&
419
                   (inptr[4]=='m' || inptr[4]=='M') &&
420
                   (inptr[5]=='t' || inptr[5]=='T') &&
421
                   !isIdentChar(inptr[6])) {
422
                       inptr += 6;
423
                       NextToken();
424
                       return 0x29;
425
               }
426
            }
427
            inptr += 2;
428
            NextToken();
429
            return 0x21;
430
        }
431
         break;
432
 
433
    // ea epc esp es
434
    case 'e': case 'E':
435
         if ((inptr[1]=='a' || inptr[1]=='A') &&
436
             !isIdentChar(inptr[2])) {
437
             inptr += 2;
438
             NextToken();
439
             return 40;
440
         }
441
         if ((inptr[1]=='p' || inptr[1]=='P') &&
442
             (inptr[2]=='c' || inptr[2]=='C') &&
443
             !isIdentChar(inptr[3])) {
444
             inptr += 3;
445
             NextToken();
446
             return 9;
447
         }
448
         if ((inptr[1]=='s' || inptr[1]=='S') &&
449
             (inptr[2]=='p' || inptr[2]=='P') &&
450
             !isIdentChar(inptr[3])) {
451
             inptr += 3;
452
             NextToken();
453
             return 17;
454
         }
455
        if ((inptr[1]=='s' || inptr[1]=='S') &&
456
            !isIdentChar(inptr[2])) {
457
            if (inptr[2]=='.') {
458
               if ((inptr[3]=='l' || inptr[3]=='L') &&
459
                   (inptr[4]=='m' || inptr[4]=='M') &&
460
                   (inptr[5]=='t' || inptr[5]=='T') &&
461
                   !isIdentChar(inptr[6])) {
462
                       inptr += 6;
463
                       NextToken();
464
                       return 0x2A;
465
               }
466
            }
467
            inptr += 2;
468
            NextToken();
469
            return 0x22;
470
        }
471
         break;
472
 
473
    // fault_pc fs
474
    case 'f': case 'F':
475
         if ((inptr[1]=='a' || inptr[1]=='A') &&
476
             (inptr[2]=='u' || inptr[2]=='U') &&
477
             (inptr[3]=='l' || inptr[3]=='L') &&
478
             (inptr[4]=='t' || inptr[4]=='T') &&
479
             (inptr[5]=='_' || inptr[5]=='_') &&
480
             (inptr[6]=='p' || inptr[6]=='P') &&
481
             (inptr[7]=='c' || inptr[7]=='C') &&
482
             !isIdentChar(inptr[8])) {
483
             inptr += 8;
484
             NextToken();
485
             return 0x08;
486
         }
487
        if ((inptr[1]=='s' || inptr[1]=='S') &&
488
            !isIdentChar(inptr[2])) {
489
            if (inptr[2]=='.') {
490
               if ((inptr[3]=='l' || inptr[3]=='L') &&
491
                   (inptr[4]=='m' || inptr[4]=='M') &&
492
                   (inptr[5]=='t' || inptr[5]=='T') &&
493
                   !isIdentChar(inptr[6])) {
494
                       inptr += 6;
495
                       NextToken();
496
                       return 0x2B;
497
               }
498
            }
499
            inptr += 2;
500
            NextToken();
501
            return 0x23;
502
        }
503
         break;
504
 
505
    // gs GDT
506
    case 'g': case 'G':
507
        if ((inptr[1]=='s' || inptr[1]=='S') &&
508
            !isIdentChar(inptr[2])) {
509
            if (inptr[2]=='.') {
510
               if ((inptr[3]=='l' || inptr[3]=='L') &&
511
                   (inptr[4]=='m' || inptr[4]=='M') &&
512
                   (inptr[5]=='t' || inptr[5]=='T') &&
513
                   !isIdentChar(inptr[6])) {
514
                       inptr += 6;
515
                       NextToken();
516
                       return 0x2C;
517
               }
518
            }
519
            inptr += 2;
520
            NextToken();
521
            return 0x24;
522
        }
523
        if ((inptr[1]=='d' || inptr[1]=='D') &&
524
           (inptr[2]=='t' || inptr[2]=='T') &&
525
            !isIdentChar(inptr[3])) {
526
            inptr += 3;
527
            NextToken();
528
            return 41;
529
        }
530
        break;
531
 
532
    // history
533
    case 'h': case 'H':
534
         if ((inptr[1]=='i' || inptr[1]=='I') &&
535
             (inptr[2]=='s' || inptr[2]=='S') &&
536
             (inptr[3]=='t' || inptr[3]=='T') &&
537
             (inptr[4]=='o' || inptr[4]=='O') &&
538
             (inptr[5]=='r' || inptr[5]=='R') &&
539
             (inptr[6]=='y' || inptr[6]=='Y') &&
540
             !isIdentChar(inptr[7])) {
541
             inptr += 7;
542
             NextToken();
543
             return 0x0D;
544
         }
545
        if ((inptr[1]=='s' || inptr[1]=='S') &&
546
            !isIdentChar(inptr[2])) {
547
            if (inptr[2]=='.') {
548
               if ((inptr[3]=='l' || inptr[3]=='L') &&
549
                   (inptr[4]=='m' || inptr[4]=='M') &&
550
                   (inptr[5]=='t' || inptr[5]=='T') &&
551
                   !isIdentChar(inptr[6])) {
552
                       inptr += 6;
553
                       NextToken();
554
                       return 0x2D;
555
               }
556
            }
557
            inptr += 2;
558
            NextToken();
559
            return 0x25;
560
        }
561
         break;
562
 
563
    // ipc isp ivno
564
    case 'i': case 'I':
565
         if ((inptr[1]=='p' || inptr[1]=='P') &&
566
             (inptr[2]=='c' || inptr[2]=='C') &&
567
             !isIdentChar(inptr[3])) {
568
             inptr += 3;
569
             NextToken();
570
             return 8;
571
         }
572
         if ((inptr[1]=='s' || inptr[1]=='S') &&
573
             (inptr[2]=='p' || inptr[2]=='P') &&
574
             !isIdentChar(inptr[3])) {
575
             inptr += 3;
576
             NextToken();
577
             return 15;
578
         }
579
         if ((inptr[1]=='v' || inptr[1]=='V') &&
580
             (inptr[2]=='n' || inptr[2]=='N') &&
581
             (inptr[3]=='o' || inptr[3]=='O') &&
582
             !isIdentChar(inptr[4])) {
583
             inptr += 4;
584
             NextToken();
585
             return 0x0C;
586
         }
587
         break;
588
 
589
 
590
    // LC LDT
591
    case 'l': case 'L':
592
         if ((inptr[1]=='c' || inptr[1]=='C') &&
593
             !isIdentChar(inptr[2])) {
594
             inptr += 2;
595
             NextToken();
596
             return 0x33;
597
         }
598
         if ((inptr[1]=='d' || inptr[1]=='D') &&
599
            (inptr[2]=='t' || inptr[2]=='T') &&
600
             !isIdentChar(inptr[3])) {
601
             inptr += 3;
602
             NextToken();
603
             return 40;
604
         }
605
         break;
606
 
607
    // pregs
608
    case 'p': case 'P':
609
         if ((inptr[1]=='r' || inptr[1]=='R') &&
610
             (inptr[2]=='e' || inptr[2]=='E') &&
611
             (inptr[3]=='g' || inptr[3]=='G') &&
612
             (inptr[4]=='s' || inptr[4]=='S') &&
613
             !isIdentChar(inptr[5])) {
614
             inptr += 5;
615
             NextToken();
616
             return 52;
617
         }
618
         break;
619
 
620
    // rand
621
    case 'r': case 'R':
622
         if ((inptr[1]=='a' || inptr[1]=='A') &&
623
             (inptr[2]=='n' || inptr[2]=='N') &&
624
             (inptr[3]=='d' || inptr[3]=='D') &&
625
             !isIdentChar(inptr[4])) {
626
             inptr += 4;
627
             NextToken();
628
             return 0x12;
629
         }
630
         break;
631
    // ss_ll srand1 srand2 ss segsw segbase seglmt segacr
632
    case 's': case 'S':
633
         if ((inptr[1]=='s' || inptr[1]=='S') &&
634
             (inptr[2]=='_' || inptr[2]=='_') &&
635
             (inptr[3]=='l' || inptr[3]=='L') &&
636
             (inptr[4]=='l' || inptr[4]=='L') &&
637
             !isIdentChar(inptr[5])) {
638
             inptr += 5;
639
             NextToken();
640
             return 0x1A;
641
         }
642
         if ((inptr[1]=='r' || inptr[1]=='R') &&
643
             (inptr[2]=='a' || inptr[2]=='A') &&
644
             (inptr[3]=='n' || inptr[3]=='N') &&
645
             (inptr[4]=='d' || inptr[4]=='D') &&
646
             (inptr[5]=='1') &&
647
             !isIdentChar(inptr[6])) {
648
             inptr += 6;
649
             NextToken();
650
             return 0x10;
651
         }
652
         if ((inptr[1]=='r' || inptr[1]=='R') &&
653
             (inptr[2]=='a' || inptr[2]=='A') &&
654
             (inptr[3]=='n' || inptr[3]=='N') &&
655
             (inptr[4]=='d' || inptr[4]=='D') &&
656
             (inptr[5]=='2') &&
657
             !isIdentChar(inptr[6])) {
658
             inptr += 6;
659
             NextToken();
660
             return 0x11;
661
         }
662
         if ((inptr[1]=='p' || inptr[1]=='P') &&
663
             (inptr[2]=='r' || inptr[2]=='R') &&
664
             isdigit(inptr[3]) && isdigit(inptr[4]) &&
665
             !isIdentChar(inptr[5])) {
666
             inptr += 5;
667
             NextToken();
668
             return (inptr[3]-'0')*10 + (inptr[4]-'0');
669
         }
670
        if ((inptr[1]=='s' || inptr[1]=='S') &&
671
            !isIdentChar(inptr[2])) {
672
            if (inptr[2]=='.') {
673
               if ((inptr[3]=='l' || inptr[3]=='L') &&
674
                   (inptr[4]=='m' || inptr[4]=='M') &&
675
                   (inptr[5]=='t' || inptr[5]=='T') &&
676
                   !isIdentChar(inptr[6])) {
677
                       inptr += 6;
678
                       NextToken();
679
                       return 0x2E;
680
               }
681
            }
682
            inptr += 2;
683
            NextToken();
684
            return 0x26;
685
         }
686
         // segxxx
687
         if ((inptr[1]=='e' || inptr[1]=='E') &&
688
             (inptr[2]=='g' || inptr[2]=='G')) {
689
             // segsw
690
             if ((inptr[3]=='s' || inptr[3]=='S') &&
691
                  (inptr[4]=='w' || inptr[4]=='W') &&
692
                  !isIdentChar(inptr[5])) {
693
               inptr += 5;
694
               NextToken();
695
               return 43;
696
             }
697
             // segbase
698
             if ((inptr[3]=='b' || inptr[3]=='B') &&
699
                  (inptr[4]=='a' || inptr[4]=='A') &&
700
                  (inptr[5]=='s' || inptr[5]=='S') &&
701
                  (inptr[6]=='e' || inptr[6]=='E') &&
702
                  !isIdentChar(inptr[7])) {
703
               inptr += 7;
704
               NextToken();
705
               return 44;
706
             }
707
             // seglmt
708
             if ((inptr[3]=='l' || inptr[3]=='L') &&
709
                  (inptr[4]=='m' || inptr[4]=='M') &&
710
                  (inptr[5]=='t' || inptr[5]=='T') &&
711
                  !isIdentChar(inptr[6])) {
712
               inptr += 6;
713
               NextToken();
714
               return 45;
715
             }
716
             // segacr
717
             if ((inptr[3]=='a' || inptr[3]=='A') &&
718
                  (inptr[4]=='c' || inptr[4]=='C') &&
719
                  (inptr[5]=='r' || inptr[5]=='R') &&
720
                  !isIdentChar(inptr[6])) {
721
               inptr += 6;
722
               NextToken();
723
               return 47;
724
             }
725
         }
726
         break;
727
 
728
    // tag tick 
729
    case 't': case 'T':
730
         if ((inptr[1]=='i' || inptr[1]=='I') &&
731
             (inptr[2]=='c' || inptr[2]=='C') &&
732
             (inptr[3]=='k' || inptr[3]=='K') &&
733
             !isIdentChar(inptr[4])) {
734
             inptr += 4;
735
             NextToken();
736
             return 0x32;
737
         }
738
         if ((inptr[1]=='a' || inptr[1]=='A') &&
739
             (inptr[2]=='g' || inptr[2]=='G') &&
740
             !isIdentChar(inptr[3])) {
741
             inptr += 3;
742
             NextToken();
743
             return 41;
744
         }
745
         break;
746
 
747
    // vbr
748
    case 'v': case 'V':
749
         if ((inptr[1]=='b' || inptr[1]=='B') &&
750
             (inptr[2]=='r' || inptr[2]=='R') &&
751
             !isIdentChar(inptr[3])) {
752
             inptr += 3;
753
             NextToken();
754
             return 10;
755
         }
756
         break;
757
    case 'z': case 'Z':
758
        if ((inptr[1]=='s' || inptr[1]=='S') &&
759
            !isIdentChar(inptr[2])) {
760
            if (inptr[2]=='.') {
761
               if ((inptr[3]=='l' || inptr[3]=='L') &&
762
                   (inptr[4]=='m' || inptr[4]=='M') &&
763
                   (inptr[5]=='t' || inptr[5]=='T') &&
764
                   !isIdentChar(inptr[6])) {
765
                       inptr += 6;
766
                       NextToken();
767
                       return 0x28;
768
               }
769
            }
770
            inptr += 2;
771
            NextToken();
772
            return 0x20;
773
        }
774
        break;
775
    }
776
    return -1;
777
}
778
 
779
// ---------------------------------------------------------------------------
780
// ---------------------------------------------------------------------------
781
 
782
static void emit_insn(int oc, int can_compress)
783
{
784
    int ndx;
785
 
786
    if (pass==3 && can_compress) {
787
       for (ndx = 0; ndx < htblmax; ndx++) {
788
         if (oc == hTable[ndx].opcode) {
789
           hTable[ndx].count++;
790
           return;
791
         }
792
       }
793
       if (htblmax < 100000) {
794
          hTable[htblmax].opcode = oc;
795
          hTable[htblmax].count = 1;
796
          htblmax++;
797
          return;
798
       }
799
       printf("Too many instructions.\r\n");
800
       return;
801
    }
802
    if (pass > 3) {
803
     if (can_compress) {
804
       for (ndx = 0; ndx < htblmax; ndx++) {
805
         if (oc == hTable[ndx].opcode) {
806
           emitAlignedCode(((ndx & 8) << 4)|0x50|(ndx & 0x7));
807
           emitCode(ndx >> 4);
808
           return;
809
         }
810
       }
811
     }
812
     emitAlignedCode(oc & 255);
813
     emitCode((oc >> 8) & 255);
814
     emitCode((oc >> 16) & 255);
815
     emitCode((oc >> 24) & 255);
816
    }
817
    /*
818
    if (processOpt==2) {
819
       for (ndx = 0; ndx < htblmax; ndx++) {
820
         if (oc == hTable[ndx].opcode) {
821
           printf("found opcode\n");
822
           emitAlignedCode(((ndx & 8) << 4)|0x50|(ndx & 0x7));
823
           emitCode(ndx >> 4);
824
           return;
825
         }
826
       }
827
     emitAlignedCode(oc & 255);
828
     emitCode((oc >> 8) & 255);
829
     emitCode((oc >> 16) & 255);
830
     emitCode((oc >> 24) & 255);
831
    }
832
    else {
833
     emitAlignedCode(oc & 255);
834
     emitCode((oc >> 8) & 255);
835
     emitCode((oc >> 16) & 255);
836
     emitCode((oc >> 24) & 255);
837
    }
838
    */
839
}
840
 
841
// ---------------------------------------------------------------------------
842
// ---------------------------------------------------------------------------
843
 
844
static void emit_insn2(int64_t oc)
845
{
846
     emitCode(oc & 255);
847
     emitCode((oc >> 8) & 255);
848
     emitCode((oc >> 16) & 255);
849
     emitCode((oc >> 24) & 255);
850
}
851
 
852
 
853
// ---------------------------------------------------------------------------
854
// Emit code aligned to a code address.
855
// ---------------------------------------------------------------------------
856
 
857
static void emitAlignedCode(int cd)
858
{
859
     int64_t ad;
860
 
861
     ad = code_address & 15;
862
//     while (ad != 0 && ad != 4 && ad != 8 && ad != 12) {
863
       while (ad & 1) {
864
         emitByte(0x00);
865
         ad = code_address & 15;
866
     }
867
     emitByte(cd);
868
}
869
 
870
 
871
// ---------------------------------------------------------------------------
872
// Emit constant extension for memory operands.
873
// ---------------------------------------------------------------------------
874
 
875
static void emitImm0(int64_t v, int force)
876
{
877
     if (v != 0 || force) {
878
          emitAlignedCode(0xfd);
879
          emitCode(v & 255);
880
          emitCode((v >> 8) & 255);
881
          emitCode((v >> 16) & 255);
882
          emitCode((v >> 24) & 255);
883
     }
884
     if (((v < 0) && ((v >> 32) != -1L)) || ((v > 0) && ((v >> 32) != 0L)) || (force && data_bits > 32)) {
885
          emitAlignedCode(0xfe);
886
          emitCode((v >> 32) & 255);
887
          emitCode((v >> 40) & 255);
888
          emitCode((v >> 48) & 255);
889
          emitCode((v >> 56) & 255);
890
     }
891
}
892
 
893
// ---------------------------------------------------------------------------
894
// Emit constant extension for memory operands.
895
// ---------------------------------------------------------------------------
896
 
897
static void emitImm2(int64_t v, int force)
898
{
899
     if (v < 0L || v > 3L || force) {
900
          emitAlignedCode(0xfd);
901
          emitCode((v >> 2) & 255);
902
          emitCode((v >> 10) & 255);
903
          emitCode((v >> 18) & 255);
904
          emitCode((v >> 26) & 255);
905
     }
906
     if (((v < 0) && ((v >> 34) != -1L)) || ((v > 0) && ((v >> 34) != 0L)) || (force && data_bits > 34)) {
907
          emitAlignedCode(0xfe);
908
          emitCode((v >> 34) & 255);
909
          emitCode((v >> 42) & 255);
910
          emitCode((v >> 50) & 255);
911
          emitCode((v >> 58) & 255);
912
     }
913
}
914
 
915
// ---------------------------------------------------------------------------
916
// Emit constant extension for memory operands.
917
// ---------------------------------------------------------------------------
918
 
919
static void emitImm12(int64_t v, int force)
920
{
921
     if (v < -2048L || v > 2047L || force) {
922
          emitAlignedCode(0xfd);
923
          emitCode((v >> 12) & 255);
924
          emitCode((v >> 20) & 255);
925
          emitCode((v >> 28) & 255);
926
          emitCode((v >> 36) & 255);
927
     }
928
     if (((v < 0) && ((v >> 44) != -1L)) || ((v > 0) && ((v >> 44) != 0L)) || (force && data_bits > 44)) {
929
          emitAlignedCode(0xfe);
930
          emitCode((v >> 44) & 255);
931
          emitCode((v >> 52) & 255);
932
          emitCode((v >> 60) & 255);
933
          emitCode(0x00);
934
     }
935
}
936
 
937
// ---------------------------------------------------------------------------
938
// Emit constant extension for 16-bit operands.
939
// ---------------------------------------------------------------------------
940
 
941
static void emitImm16(int64_t v, int force)
942
{
943
     if (v < -32768L || v > 32767L || force) {
944
          emitAlignedCode(0xfd);
945
          emitCode((v >> 16) & 255);
946
          emitCode((v >> 24) & 255);
947
          emitCode((v >> 32) & 255);
948
          emitCode((v >> 40) & 255);
949
     }
950
     if (((v < 0) && ((v >> 48) != -1L)) || ((v > 0) && ((v >> 48) != 0L)) || (force && (code_bits > 48 || data_bits > 48))) {
951
          emitAlignedCode(0xfe);
952
          emitCode((v >> 48) & 255);
953
          emitCode((v >> 56) & 255);
954
          emitCode(0x00);
955
          emitCode(0x00);
956
     }
957
}
958
 
959
// ---------------------------------------------------------------------------
960
// Emit constant extension for 24-bit operands.
961
// ---------------------------------------------------------------------------
962
 
963
static void emitImm20(int64_t v, int force)
964
{
965
     if (v < -524288L || v > 524287L || force) {
966
          emitAlignedCode(0xfd);
967
          emitCode((v >> 20) & 255);
968
          emitCode((v >> 28) & 255);
969
          emitCode((v >> 36) & 255);
970
          emitCode((v >> 44) & 255);
971
     }
972
     if (((v < 0) && ((v >> 52) != -1L)) || ((v > 0) && ((v >> 52) != 0L)) || (force && (code_bits > 52 || data_bits > 52))) {
973
          emitAlignedCode(0xfe);
974
          emitCode((v >> 52) & 255);
975
          emitCode((v >> 60) & 255);
976
          emitCode(0x00);
977
          emitCode(0x00);
978
     }
979
}
980
 
981
// ---------------------------------------------------------------------------
982
// Emit constant extension for 24-bit operands.
983
// ---------------------------------------------------------------------------
984
 
985
static void emitImm24(int64_t v, int force)
986
{
987
     if (v < -8388608L || v > 8388607L || force) {
988
          emitAlignedCode(0xfd);
989
          emitCode((v >> 24) & 255);
990
          emitCode((v >> 32) & 255);
991
          emitCode((v >> 40) & 255);
992
          emitCode((v >> 48) & 255);
993
     }
994
     if (((v < 0) && ((v >> 56) != -1L)) || ((v > 0) && ((v >> 56) != 0L)) || (force && (code_bits > 56 || data_bits > 56))) {
995
          emitAlignedCode(0xfe);
996
          emitCode((v >> 56) & 255);
997
          emitCode(0x00);
998
          emitCode(0x00);
999
          emitCode(0x00);
1000
     }
1001
}
1002
 
1003
// ---------------------------------------------------------------------------
1004
// Emit constant extension for 32-bit operands.
1005
// ---------------------------------------------------------------------------
1006
 
1007
static void emitImm32(int64_t v, int force)
1008
{
1009
     if (v < -2147483648LL || v > 2147483647LL || force) {
1010
          emitAlignedCode(0xfd);
1011
          emitCode((v >> 32) & 255);
1012
          emitCode((v >> 40) & 255);
1013
          emitCode((v >> 48) & 255);
1014
          emitCode((v >> 56) & 255);
1015
     }
1016
}
1017
 
1018
// ---------------------------------------------------------------------------
1019
// addi r1,r2,#1234
1020
// ---------------------------------------------------------------------------
1021
 
1022
static void process_riop(int opcode7)
1023
{
1024
    int Ra;
1025
    int Rt;
1026
    char *p;
1027
    int64_t val;
1028
 
1029
    p = inptr;
1030
    Rt = getRegisterX();
1031
    need(',');
1032
    Ra = getRegisterX();
1033
    need(',');
1034
    NextToken();
1035
    val = expr();
1036
    if (val < -2147483648LL || val > 2147483647LL) {
1037
        emit_insn((0x4080 << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1038
        emit_insn(val,0);
1039
        emit_insn(val>>32,0);
1040
    }
1041
    else if ((val < -16000LL || val > 16383LL)) {
1042
      {
1043
        emit_insn((0x4000 << 17)|(Rt << 12)|(Ra << 7)|opcode7,1);
1044
        emit_insn(val,0);
1045
      }
1046
    }
1047
    else
1048
      emit_insn(((val & 0x7FFF) << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1049
}
1050
 
1051
// ---------------------------------------------------------------------------
1052
// ---------------------------------------------------------------------------
1053
 
1054
static void process_rrop(int funct7)
1055
{
1056
    int Ra,Rb,Rt;
1057
    char *p;
1058
 
1059
    p = inptr;
1060
    Rt = getRegisterX();
1061
    need(',');
1062
    Ra = getRegisterX();
1063
    need(',');
1064
    NextToken();
1065
    if (token=='#') {
1066
        inptr = p;
1067
        process_riop(funct7);
1068
        return;
1069
    }
1070
    prevToken();
1071
    Rb = getRegisterX();
1072
    //prevToken();
1073
    emit_insn((funct7<<25)|(Rt<<17)|(Rb<<12)|(Ra<<7)|0x02,1);
1074
}
1075
 
1076
// ---------------------------------------------------------------------------
1077
// jmp main
1078
// jsr [r19]
1079
// jmp (tbl,r2)
1080
// jsr [gp+r20]
1081
// ---------------------------------------------------------------------------
1082
 
1083
static void process_jal()
1084
{
1085
    int64_t addr;
1086
    int Ra, Rb;
1087
    int Rt;
1088
 
1089
    Rt = 0;
1090
    NextToken();
1091
    if (token=='(' || token=='[') {
1092
j1:
1093
       Ra = getRegisterX();
1094
       if (Ra==-1) {
1095
           printf("Expecting a register\r\n");
1096
           return;
1097
       }
1098
       // Simple jmp [Rn]
1099
       else {
1100
            if (token != ')' && token!=']')
1101
                printf("Missing close bracket\r\n");
1102
            emit_insn((Ra << 15)|(Rt<<7)|0x67,1);
1103
            return;
1104
       }
1105
    }
1106
    prevToken();
1107
    Rt = getRegisterX();
1108
    printf("Rt=%d ", Rt);
1109
    if (Rt >= 0) {
1110
        need(',');
1111
        NextToken();
1112
        // jal Rt,[Ra]
1113
        if (token=='(' || token=='[')
1114
           goto j1;
1115
    }
1116
    else
1117
        Rt = 0;
1118
    addr = expr() - code_address;
1119
    printf("Addr=%ld ", addr);
1120
    prevToken();
1121
    // d(Rn)? 
1122
    if (token=='(' || token=='[') {
1123
        printf("a ");
1124
        NextToken();
1125
        Ra = getRegisterX();
1126
        if (Ra==-1) {
1127
            printf("Illegal jump address mode.\r\n");
1128
            Ra = 0;
1129
        }
1130
j2:
1131
        if (addr < -2048 || addr > 2047)
1132
            emit_insn((addr & 0xFFFFF000)|0x37,1);
1133
        emit_insn(((addr & 0xFFF) << 20)|(Ra<<15)|(Rt << 7)|0x67,1);
1134
        return;
1135
    }
1136
    printf("b ");
1137
    if (addr > 524287 || addr < -524288) {
1138
        Ra = 0;
1139
        goto j2;
1140
    }
1141
    printf("emit_insn \r\n");
1142
    emit_insn(
1143
        (((addr & 0x100000)>>20)<< 31) |
1144
        (((addr & 0x7FE)>>1) << 21) |
1145
        (((addr & 0x800)>>11) << 20) |
1146
        (((addr & 0xFF000)>>12) << 12) |
1147
        (Rt << 7) |
1148
        0x6F, 0
1149
    );
1150
}
1151
 
1152
// ---------------------------------------------------------------------------
1153
// subui r1,r2,#1234
1154
// ---------------------------------------------------------------------------
1155
/*
1156
static void process_riop(int oc)
1157
{
1158
    int Ra;
1159
    int Rt;
1160
    char *p;
1161
    int64_t val;
1162
 
1163
    p = inptr;
1164
    Rt = getRegisterX();
1165
    need(',');
1166
    Ra = getRegisterX();
1167
    need(',');
1168
    NextToken();
1169
    val = expr();
1170
 
1171
   if (lastsym != (SYM *)NULL)
1172
       emitImm16(val,!lastsym->defined);
1173
   else
1174
       emitImm16(val,0);
1175
 
1176
    emitImm16(val,lastsym!=(SYM*)NULL);
1177
    emitAlignedCode(oc);
1178
    if (bGen)
1179
    if (lastsym && !use_gp) {
1180
        if( lastsym->segment < 5)
1181
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
1182
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
1183
    }
1184
    emitCode(Ra);
1185
    emitCode(Rt);
1186
    emitCode(val & 255);
1187
    emitCode((val >> 8) & 255);
1188
}
1189
*/
1190
// ---------------------------------------------------------------------------
1191
// fabs.d fp1,fp2[,rm]
1192
// ---------------------------------------------------------------------------
1193
 
1194
static void process_fprop(int oc)
1195
{
1196
    int Ra;
1197
    int Rt;
1198
    char *p;
1199
    int  sz;
1200
    int fmt;
1201
    int rm;
1202
 
1203
    rm = 0;
1204
    sz = 'd';
1205
    if (*inptr=='.') {
1206
        inptr++;
1207
        if (strchr("sdtqSDTQ",*inptr)) {
1208
            sz = tolower(*inptr);
1209
            inptr++;
1210
        }
1211
        else
1212
            printf("Illegal float size.\r\n");
1213
    }
1214
    p = inptr;
1215
    if (oc==0xF6)        // fcmp
1216
        Rt = getRegisterX();
1217
    else
1218
        Rt = getFPRegister();
1219
    need(',');
1220
    Ra = getFPRegister();
1221
    if (token==',')
1222
       rm = getFPRoundMode();
1223
    prevToken();
1224
    emitAlignedCode(0x01);
1225
    emitCode(Ra);
1226
    emitCode(Rt);
1227
    switch(sz) {
1228
    case 's': fmt = 0; break;
1229
    case 'd': fmt = 1; break;
1230
    case 't': fmt = 2; break;
1231
    case 'q': fmt = 3; break;
1232
    }
1233
    emitCode((fmt << 3)|rm);
1234
    emitCode(oc);
1235
}
1236
 
1237
// ---------------------------------------------------------------------------
1238
// fadd.d fp1,fp2,fp12[,rm]
1239
// fcmp.d r1,fp3,fp10[,rm]
1240
// ---------------------------------------------------------------------------
1241
 
1242
static void process_fprrop(int oc)
1243
{
1244
    int Ra;
1245
    int Rb;
1246
    int Rt;
1247
    char *p;
1248
    int  sz;
1249
    int fmt;
1250
    int rm;
1251
 
1252
    rm = 0;
1253
    sz = 'd';
1254
    if (*inptr=='.') {
1255
        inptr++;
1256
        if (strchr("sdtqSDTQ",*inptr)) {
1257
            sz = tolower(*inptr);
1258
            inptr++;
1259
        }
1260
        else
1261
            printf("Illegal float size.\r\n");
1262
    }
1263
    p = inptr;
1264
    if (oc==0xF6)        // fcmp
1265
        Rt = getRegisterX();
1266
    else
1267
        Rt = getFPRegister();
1268
    need(',');
1269
    Ra = getFPRegister();
1270
    need(',');
1271
    Rb = getFPRegister();
1272
    if (token==',')
1273
       rm = getFPRoundMode();
1274
    prevToken();
1275
    emitAlignedCode(oc);
1276
    emitCode(Ra);
1277
    emitCode(Rb);
1278
    emitCode(Rt);
1279
    switch(sz) {
1280
    case 's': fmt = 0; break;
1281
    case 'd': fmt = 1; break;
1282
    case 't': fmt = 2; break;
1283
    case 'q': fmt = 3; break;
1284
    }
1285
    emitCode((fmt << 3)|rm);
1286
}
1287
 
1288
// ---------------------------------------------------------------------------
1289
// fcx r0,#2
1290
// fdx r1,#0
1291
// ---------------------------------------------------------------------------
1292
 
1293
static void process_fpstat(int oc)
1294
{
1295
    int Ra;
1296
    int64_t bits;
1297
    char *p;
1298
 
1299
    p = inptr;
1300
    bits = 0;
1301
    Ra = getRegisterX();
1302
    if (token==',') {
1303
       NextToken();
1304
       bits = expr();
1305
    }
1306
    prevToken();
1307
    emitAlignedCode(0x01);
1308
    emitCode(Ra);
1309
    emitCode(bits & 0xff);
1310
    emitCode(0x00);
1311
    emitCode(oc);
1312
}
1313
 
1314
// ---------------------------------------------------------------------------
1315
// not r3,r3
1316
// ---------------------------------------------------------------------------
1317
 
1318
static void process_rop(int oc)
1319
{
1320
    int Ra;
1321
    int Rt;
1322
 
1323
    Rt = getRegisterX();
1324
    need(',');
1325
    Ra = getRegisterX();
1326
//    prevToken();
1327
    emitAlignedCode(1);
1328
    emitCode(Ra);
1329
    emitCode(Rt);
1330
    emitCode(0x00);
1331
    emitCode(oc);
1332
}
1333
 
1334
// ---------------------------------------------------------------------------
1335
// brnz r1,label
1336
// ---------------------------------------------------------------------------
1337
 
1338
static void process_bcc(int opcode4)
1339
{
1340
    int Ra, Rb;
1341
    int64_t val;
1342
    int64_t disp;
1343
 
1344
    Ra = getRegisterX();
1345
    need(',');
1346
    Rb = getRegisterX();
1347
    need(',');
1348
    NextToken();
1349
    val = expr();
1350
    disp = val - code_address;
1351
    printf("exmit branch\r\n");
1352
    emit_insn((disp & 0x7FFF) << 17 |
1353
        (Rb << 12) |
1354
        (Ra << 7) |
1355
        0x10 |
1356
        opcode4,0
1357
    );
1358
}
1359
 
1360
// ---------------------------------------------------------------------------
1361
// bra label
1362
// ---------------------------------------------------------------------------
1363
 
1364
static void process_bra(int oc)
1365
{
1366
    int64_t val;
1367
    int64_t disp;
1368
    int64_t ad;
1369
 
1370
    NextToken();
1371
    val = expr();
1372
    ad = code_address + 5;
1373
    if ((ad & 15)==15)
1374
       ad++;
1375
    disp = ((val & 0xFFFFFFFFFFFFF000L) - (ad & 0xFFFFFFFFFFFFF000L)) >> 12;
1376
    emitAlignedCode(oc);
1377
    emitCode(0x00);
1378
    emitCode(val & 255);
1379
    emitCode(((disp & 15) << 4)|((val >> 8) & 15));
1380
    if (oc==0x56)   // BSR
1381
        emitCode((disp >> 4) & 255);
1382
    else
1383
        emitCode((disp >> 4) & 31);
1384
}
1385
 
1386
// ---------------------------------------------------------------------------
1387
// expr
1388
// expr[Reg]
1389
// expr[Reg+Reg*sc]
1390
// [Reg]
1391
// [Reg+Reg*sc]
1392
// ---------------------------------------------------------------------------
1393
 
1394
static void mem_operand(int64_t *disp, int *regA)
1395
{
1396
     int64_t val;
1397
 
1398
     // chech params
1399
     if (disp == (int64_t *)NULL)
1400
         return;
1401
     if (regA == (int *)NULL)
1402
         return;
1403
 
1404
     *disp = 0;
1405
     *regA = -1;
1406
     if (token!='[') {;
1407
          val = expr();
1408
          *disp = val;
1409
     }
1410
     if (token=='[') {
1411
         *regA = getRegisterX();
1412
         if (*regA == -1) {
1413
             printf("expecting a register\r\n");
1414
         }
1415
         need(']');
1416
     }
1417
}
1418
 
1419
// ---------------------------------------------------------------------------
1420
// sw disp[r1],r2
1421
// sw [r1+r2],r3
1422
// ----------------------------------------------------------------------------
1423
 
1424
static void process_store(int opcode7)
1425
{
1426
    int Ra;
1427
    int Rs;
1428
    int64_t disp,val;
1429
 
1430
    Rs = getRegisterX();
1431
    if (Rs < 0) {
1432
        printf("Expecting a source register.\r\n");
1433
        ScanToEOL();
1434
        return;
1435
    }
1436
    expect(',');
1437
    mem_operand(&disp, &Ra);
1438
    if (Ra < 0) Ra = 0;
1439
    if ((disp < -2048 || disp > 2047) && OPTLUI0) {
1440
        emit_insn((disp & 0xFFFFF000)|(0 << 7)|0x37,1); // LUI
1441
    }
1442
    val = disp;
1443
    if (val < -2147483648LL || val > 2147483647LL) {
1444
        emit_insn((0x4080 << 17)|(Rs << 12)|(Ra << 7)|opcode7,!expand_flag);
1445
        emit_insn(val,0);
1446
        emit_insn(val>>32,0);
1447
    }
1448
    else if ((val < -16000LL || val > 16383LL)) {
1449
      {
1450
        emit_insn((0x4000 << 17)|(Rs << 12)|(Ra << 7)|opcode7,1);
1451
        emit_insn(val,0);
1452
      }
1453
    }
1454
    else
1455
      emit_insn(((val & 0x7FFF) << 17)|(Rs << 12)|(Ra << 7)|opcode7,!expand_flag);
1456
    ScanToEOL();
1457
}
1458
 
1459
// ----------------------------------------------------------------------------
1460
// ----------------------------------------------------------------------------
1461
 
1462
static void process_ldi()
1463
{
1464
       int Ra = 0;
1465
    int Rt;
1466
    int64_t val;
1467
    int opcode7 = 0x09;  // ORI
1468
 
1469
    Rt = getRegisterX();
1470
    expect(',');
1471
    val = expr();
1472
    if (val < -2147483648LL || val > 2147483647LL) {
1473
        emit_insn((0x4080 << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1474
        emit_insn(val,0);
1475
        emit_insn(val>>32,0);
1476
        printf("64 bit constant");
1477
    }
1478
    else if ((val < -16000LL || val > 16383LL)) {
1479
      {
1480
        emit_insn((0x4000 << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1481
        emit_insn(val,0);
1482
      }
1483
    }
1484
    else
1485
      emit_insn(((val & 0x7FFF) << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1486
}
1487
 
1488
// ----------------------------------------------------------------------------
1489
// lw r1,disp[r2]
1490
// lw r1,[r2+r3]
1491
// ----------------------------------------------------------------------------
1492
 
1493
static void process_load(int opcode7)
1494
{
1495
    int Ra;
1496
    int Rt;
1497
    char *p;
1498
    int64_t disp;
1499
    int64_t val;
1500
    int fixup = 5;
1501
 
1502
    p = inptr;
1503
    Rt = getRegisterX();
1504
    if (Rt < 0) {
1505
        printf("Expecting a target register.\r\n");
1506
//        printf("Line:%.60s\r\n",p);
1507
        ScanToEOL();
1508
        inptr-=2;
1509
        return;
1510
    }
1511
    expect(',');
1512
    mem_operand(&disp, &Ra);
1513
    if (Ra < 0) Ra = 0;
1514
    val = disp;
1515
    if (val < -2147483648LL || val > 2147483647LL) {
1516
        emit_insn((0x4080 << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1517
        emit_insn(val,0);
1518
        emit_insn(val>>32,0);
1519
        printf("64 bit constant");
1520
    }
1521
    else if ((val < -16000LL || val > 16383LL)) {
1522
      {
1523
        emit_insn((0x4000 << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1524
        emit_insn(val,0);
1525
      }
1526
    }
1527
    else
1528
      emit_insn(((val & 0x7FFF) << 17)|(Rt << 12)|(Ra << 7)|opcode7,!expand_flag);
1529
    ScanToEOL();
1530
}
1531
 
1532
// ----------------------------------------------------------------------------
1533
// mov r1,r2
1534
// ----------------------------------------------------------------------------
1535
 
1536
static void process_mov(int oc)
1537
{
1538
     int Ra;
1539
     int Rt;
1540
 
1541
     Rt = getRegisterX();
1542
     need(',');
1543
     Ra = getRegisterX();
1544
     emitAlignedCode(0x01);
1545
     emitCode(Ra);
1546
     emitCode(Rt);
1547
     emitCode(0x00);
1548
     emitCode(oc);
1549
//     prevToken();
1550
}
1551
 
1552
// ----------------------------------------------------------------------------
1553
// rts
1554
// rts #24
1555
// ----------------------------------------------------------------------------
1556
 
1557
static void process_rts(int oc)
1558
{
1559
     int64_t val;
1560
 
1561
     val = 0;
1562
     NextToken();
1563
     if (token=='#') {
1564
        val = expr();
1565
     }
1566
     emitAlignedCode(oc);
1567
     emitCode(0x00);
1568
     emitCode(val & 255);
1569
     emitCode((val >> 8) & 255);
1570
     emitCode(0x00);
1571
}
1572
 
1573
// ----------------------------------------------------------------------------
1574
// srli r1,r2,#5
1575
// ----------------------------------------------------------------------------
1576
 
1577
static void process_shifti(int funct7)
1578
{
1579
     int Ra;
1580
     int Rt;
1581
     int64_t val;
1582
 
1583
     Rt = getRegisterX();
1584
     need(',');
1585
     Ra = getRegisterX();
1586
     need(',');
1587
     NextToken();
1588
     val = expr();
1589
     emit_insn((funct7 << 25) | ((val & 0x20) << 22) | (Rt << 17)| ((val & 0x1F) << 12) | (Ra << 7) | 0x02,1);  // ORI
1590
}
1591
 
1592
// ----------------------------------------------------------------------------
1593
// gran r1
1594
// ----------------------------------------------------------------------------
1595
 
1596
static void process_gran(int oc)
1597
{
1598
    int Rt;
1599
 
1600
    Rt = getRegisterX();
1601
    emitAlignedCode(0x01);
1602
    emitCode(0x00);
1603
    emitCode(Rt);
1604
    emitCode(0x00);
1605
    emitCode(oc);
1606
    prevToken();
1607
}
1608
 
1609
// ----------------------------------------------------------------------------
1610
// ----------------------------------------------------------------------------
1611
 
1612
static void process_mtspr(int oc)
1613
{
1614
    int spr;
1615
    int Ra;
1616
 
1617
    spr = DSD6_getSprRegister();
1618
    need(',');
1619
    Ra = getRegisterX();
1620
    emitAlignedCode(0x01);
1621
    emitCode(Ra);
1622
    emitCode(spr);
1623
    emitCode(0x00);
1624
    emitCode(oc);
1625
    if (Ra >= 0)
1626
    prevToken();
1627
}
1628
 
1629
// ----------------------------------------------------------------------------
1630
// ----------------------------------------------------------------------------
1631
 
1632
static void process_mtfp(int oc)
1633
{
1634
    int fpr;
1635
    int Ra;
1636
 
1637
    fpr = getFPRegister();
1638
    need(',');
1639
    Ra = getRegisterX();
1640
    emitAlignedCode(0x01);
1641
    emitCode(Ra);
1642
    emitCode(fpr);
1643
    emitCode(0x00);
1644
    emitCode(oc);
1645
    if (Ra >= 0)
1646
    prevToken();
1647
}
1648
 
1649
// ----------------------------------------------------------------------------
1650
// ----------------------------------------------------------------------------
1651
 
1652
static void process_mfspr(int oc)
1653
{
1654
    int spr;
1655
    int Rt;
1656
 
1657
    Rt = getRegisterX();
1658
    need(',');
1659
    spr = DSD6_getSprRegister();
1660
    emitAlignedCode(0x01);
1661
    emitCode(spr);
1662
    emitCode(Rt);
1663
    emitCode(0x00);
1664
    emitCode(oc);
1665
    if (spr >= 0)
1666
    prevToken();
1667
}
1668
 
1669
// ----------------------------------------------------------------------------
1670
// ----------------------------------------------------------------------------
1671
 
1672
static void process_mffp(int oc)
1673
{
1674
    int fpr;
1675
    int Rt;
1676
 
1677
    Rt = getRegisterX();
1678
    need(',');
1679
    fpr = getFPRegister();
1680
    emitAlignedCode(0x01);
1681
    emitCode(fpr);
1682
    emitCode(Rt);
1683
    emitCode(0x00);
1684
    emitCode(oc);
1685
    if (fpr >= 0)
1686
    prevToken();
1687
}
1688
 
1689
// ----------------------------------------------------------------------------
1690
// ----------------------------------------------------------------------------
1691
 
1692
static void process_fprdstat(int oc)
1693
{
1694
    int Rt;
1695
 
1696
    Rt = getRegisterX();
1697
    emitAlignedCode(0x01);
1698
    emitCode(0x00);
1699
    emitCode(Rt);
1700
    emitCode(0x00);
1701
    emitCode(oc);
1702
}
1703
 
1704
static void process_csrrw()
1705
{
1706
  int Rd;
1707
  int Rs;
1708
  int64_t val;
1709
 
1710
  Rd = getRegisterX();
1711
  need(',');
1712
  NextToken();
1713
  val = expr();
1714
  Rs = getRegisterX();
1715
  need(',');
1716
  emit_insn((val << 20) | (Rs << 15) | (1 << 12) | (Rd << 7) | 0x73,!expand_flag);
1717
}
1718
 
1719
static void process_sync(int oc)
1720
{
1721
    emit_insn(oc,!expand_flag);
1722
}
1723
 
1724
 
1725
// ----------------------------------------------------------------------------
1726
// ----------------------------------------------------------------------------
1727
 
1728
static void ProcessEOL(int opt)
1729
{
1730
    int nn,mm;
1731
    int first;
1732
    int cc;
1733
 
1734
     //printf("Line: %d\r", lineno);
1735
     expand_flag = 0;
1736
     compress_flag = 0;
1737
     segprefix = -1;
1738
     if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
1739
    nn = binstart;
1740
    cc = 8;
1741
    if (segment==codeseg) {
1742
       cc = 4;
1743
/*
1744
        if (sections[segment].bytes[binstart]==0x61) {
1745
            fprintf(ofp, "%06LLX ", ca);
1746
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
1747
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
1748
            }
1749
            fprintf(ofp, "   ; imm\n");
1750
             if (((ca+5) & 15)==15) {
1751
                 ca+=6;
1752
                 binstart+=6;
1753
                 nn++;
1754
             }
1755
             else {
1756
                  ca += 5;
1757
                  binstart += 5;
1758
             }
1759
        }
1760
*/
1761
/*
1762
        if (sections[segment].bytes[binstart]==0xfd) {
1763
            fprintf(ofp, "%06LLX ", ca);
1764
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
1765
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
1766
            }
1767
            fprintf(ofp, "   ; imm\n");
1768
             if (((ca+5) & 15)==15) {
1769
                 ca+=6;
1770
                 binstart+=6;
1771
                 nn++;
1772
             }
1773
             else {
1774
                  ca += 5;
1775
                  binstart += 5;
1776
             }
1777
        }
1778
         if (sections[segment].bytes[binstart]==0xfe) {
1779
            fprintf(ofp, "%06LLX ", ca);
1780
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
1781
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
1782
            }
1783
            fprintf(ofp, "   ; imm\n");
1784
             if (((ca+5) & 15)==15) {
1785
                 ca+=6;
1786
                 nn++;
1787
             }
1788
             else {
1789
                  ca += 5;
1790
             }
1791
        }
1792
*/
1793
    }
1794
 
1795
    first = 1;
1796
    while (nn < sections[segment].index) {
1797
        fprintf(ofp, "%06LLX ", ca);
1798
        for (mm = nn; nn < mm + cc && nn < sections[segment].index; nn++) {
1799
            fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
1800
        }
1801
        for (; nn < mm + cc; nn++)
1802
            fprintf(ofp, "   ");
1803
        if (first & opt) {
1804
            fprintf(ofp, "\t%.*s\n", inptr-stptr-1, stptr);
1805
            first = 0;
1806
        }
1807
        else
1808
            fprintf(ofp, opt ? "\n" : "; NOP Ramp\n");
1809
        ca += cc;
1810
    }
1811
    // empty (codeless) line
1812
    if (binstart==sections[segment].index) {
1813
        fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
1814
    }
1815
    } // bGen
1816
    if (opt) {
1817
       stptr = inptr;
1818
       lineno++;
1819
    }
1820
    binstart = sections[segment].index;
1821
    ca = sections[segment].address;
1822
}
1823
 
1824
// ----------------------------------------------------------------------------
1825
// ----------------------------------------------------------------------------
1826
 
1827
void dsd6_processMaster()
1828
{
1829
    int nn,mm;
1830
    int64_t bs1, bs2;
1831
 
1832
    lineno = 1;
1833
    binndx = 0;
1834
    binstart = 0;
1835
    bs1 = 0;
1836
    bs2 = 0;
1837
    inptr = &masterFile[0];
1838
    stptr = inptr;
1839
    code_address = 0;
1840
    bss_address = 0;
1841
    start_address = 0;
1842
    first_org = 1;
1843
    first_rodata = 1;
1844
    first_data = 1;
1845
    first_bss = 1;
1846
    if (pass<3) {
1847
    htblmax = 0;
1848
    for (nn = 0; nn < 100000; nn++) {
1849
      hTable[nn].count = 0;
1850
      hTable[nn].opcode = 0;
1851
    }
1852
    }
1853
    for (nn = 0; nn < 12; nn++) {
1854
        sections[nn].index = 0;
1855
        if (nn == 0)
1856
        sections[nn].address = 0;
1857
        else
1858
        sections[nn].address = 0;
1859
        sections[nn].start = 0;
1860
        sections[nn].end = 0;
1861
    }
1862
    ca = code_address;
1863
    segment = codeseg;
1864
    memset(current_label,0,sizeof(current_label));
1865
    NextToken();
1866
    while (token != tk_eof) {
1867
//        printf("\t%.*s\n", inptr-stptr-1, stptr);
1868
//        printf("token=%d\r", token);
1869
        switch(token) {
1870
        case tk_eol: ProcessEOL(1); break;
1871
//        case tk_add:  process_add(); break;
1872
        case tk_add:  process_rrop(0x04); break;
1873
        case tk_addi: process_riop(0x04); break;
1874
        case tk_align: process_align(); continue; break;
1875
        case tk_and:  process_rrop(0x08); break;
1876
        case tk_andi:  process_riop(0x08); break;
1877
        case tk_beq: process_bcc(0); break;
1878
        case tk_bge: process_bcc(3); break;
1879
        case tk_bgeu: process_bcc(7); break;
1880
        case tk_bgt: process_bcc(5); break;
1881
        case tk_bgtu: process_bcc(9); break;
1882
        case tk_ble: process_bcc(4); break;
1883
        case tk_bleu: process_bcc(8); break;
1884
        case tk_blt: process_bcc(2); break;
1885
        case tk_bltu: process_bcc(6); break;
1886
        case tk_bne: process_bcc(1); break;
1887
        case tk_bra: process_bra(0x46); break;
1888
        case tk_bsr: process_bra(0x56); break;
1889
        case tk_bss:
1890
            if (first_bss) {
1891
                while(sections[segment].address & 4095)
1892
                    emitByte(0x00);
1893
                sections[3].address = sections[segment].address;
1894
                first_bss = 0;
1895
                binstart = sections[3].index;
1896
                ca = sections[3].address;
1897
            }
1898
            segment = bssseg;
1899
            break;
1900
        case tk_cli: emit_insn(0x3100000001,1); break;
1901
        case tk_code: process_code(); break;
1902
        case tk_com: process_rop(0x06); break;
1903
        case tk_cs:  segprefix = 15; break;
1904
        case tk_csrrw: process_csrrw(); break;
1905
        case tk_data:
1906
            if (first_data) {
1907
                while(sections[segment].address & 4095)
1908
                    emitByte(0x00);
1909
                sections[2].address = sections[segment].address;   // set starting address
1910
                first_data = 0;
1911
                binstart = sections[2].index;
1912
                ca = sections[2].address;
1913
            }
1914
            process_data(dataseg);
1915
            break;
1916
        case tk_db:  process_db(); break;
1917
        case tk_dc:  process_dc(); break;
1918
        case tk_dh:  process_dh(); break;
1919
//        case tk_div: process_rrop(0x08); break;
1920
//        case tk_divu: process_rrop(0x18); break;
1921
        case tk_dw:  process_dw(); break;
1922
        case tk_end: goto j1;
1923
        case tk_endpublic: break;
1924
        case tk_eor: process_rrop(0x0A); break;
1925
        case tk_eori: process_riop(0x0A); break;
1926
        case tk_extern: process_extern(); break;
1927
        case tk_fabs: process_fprop(0x88); break;
1928
        case tk_fadd: process_fprrop(0xF4); break;
1929
        case tk_fcmp: process_fprrop(0xF6); break;
1930
        case tk_fdiv: process_fprrop(0xF8); break;
1931
        case tk_fill: process_fill(); break;
1932
        case tk_fix2flt: process_fprop(0x84); break;
1933
        case tk_flt2fix: process_fprop(0x85); break;
1934
        case tk_fmov: process_fprop(0x87); break;
1935
        case tk_fmul: process_fprrop(0xF7); break;
1936
        case tk_fnabs: process_fprop(0x89); break;
1937
        case tk_fneg: process_fprop(0x8A); break;
1938
        case tk_frm: process_fpstat(0x78); break;
1939
        case tk_fstat: process_fprdstat(0x86); break;
1940
        case tk_fsub: process_fprrop(0xF5); break;
1941
        case tk_ftx: process_fpstat(0x75); break;
1942
        case tk_gran: process_gran(0x14); break;
1943
        case tk_jal: process_jal(); break;
1944
        case tk_jmp: process_jal(); break;
1945
        case tk_lb:  process_load(0x40); break;
1946
        case tk_lbu: process_load(0x41); break;
1947
        case tk_lc:  process_load(0x42); break;
1948
        case tk_lcu: process_load(0x43); break;
1949
        case tk_ldi: process_ldi(); break;
1950
        case tk_lh:  process_load(0x44); break;
1951
        case tk_lhu: process_load(0x45); break;
1952
//        case tk_lui: process_lui(); break;
1953
        case tk_lw:  process_load(0x46); break;
1954
        case tk_lwar:  process_load(0x47); break;
1955
        case tk_mfspr: process_mfspr(0x49); break;
1956
        case tk_mov: process_mov(0x04); break;
1957
        case tk_mtspr: process_mtspr(0x48); break;
1958
        case tk_mul: process_rrop(0x60); break;
1959
        case tk_neg: process_rop(0x05); break;
1960
        case tk_nop: emit_insn(0xEAEAEAEAEA,1); break;
1961
        case tk_not: process_rop(0x07); break;
1962
        case tk_or:  process_rrop(0x09); break;
1963
        case tk_ori: process_riop(0x09); break;
1964
        case tk_org: process_org(); break;
1965
        case tk_php: emit_insn(0x3200000001,1); break;
1966
        case tk_plp: emit_insn(0x3300000001,1); break;
1967
        case tk_plus: expand_flag = 1; break;
1968
        case tk_public: process_public(); break;
1969
        case tk_rodata:
1970
            if (first_rodata) {
1971
                while(sections[segment].address & 4095)
1972
                    emitByte(0x00);
1973
                sections[1].address = sections[segment].address;
1974
                first_rodata = 0;
1975
                binstart = sections[1].index;
1976
                ca = sections[1].address;
1977
            }
1978
            segment = rodataseg;
1979
            break;
1980
        case tk_rti: emit_insn(0x4000000001,1); break;
1981
        case tk_rts: process_rts(0x60); break;
1982
        case tk_sb:  process_store(0x48); break;
1983
        case tk_sc:  process_store(0x49); break;
1984
        case tk_sei: emit_insn(0x3000000001,1); break;
1985
        //case tk_slt:  process_rrop(0x33,0x02,0x00); break;
1986
        //case tk_sltu:  process_rrop(0x33,0x03,0x00); break;
1987
        //case tk_slti:  process_riop(0x13,0x02); break;
1988
        //case tk_sltui:  process_riop(0x13,0x03); break;
1989
        case tk_sh:  process_store(0x4A); break;
1990
        case tk_slli: process_shifti(0x18); break;
1991
        case tk_srai: process_shifti(0x1A); break;
1992
        case tk_srli: process_shifti(0x19); break;
1993
        case tk_sub:  process_rrop(0x07); break;
1994
//        case tk_sub:  process_sub(); break;
1995
        case tk_sxb: process_rop(0x08); break;
1996
        case tk_sxc: process_rop(0x09); break;
1997
        case tk_sxh: process_rop(0x0A); break;
1998
        case tk_sw:  process_store(0x4B); break;
1999
        case tk_swap: process_rop(0x03); break;
2000
        case tk_sync: process_sync(0x77); break;
2001
        case tk_xor: process_rrop(0x0A); break;
2002
        case tk_xori: process_riop(0x0A); break;
2003
        case tk_id:  process_label(); break;
2004
        case '-': compress_flag = 1; break;
2005
        }
2006
        NextToken();
2007
    }
2008
j1:
2009
    ;
2010
}
2011
 

powered by: WebSVN 2.1.0

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