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

Subversion Repositories thor

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

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

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-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
static void ProcessEOL(int opt);
29
extern void process_message();
30
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc);
31
 
32
extern char *pif1;
33
extern int first_rodata;
34
extern int first_data;
35
extern int first_bss;
36
extern int htable[100000];
37
extern int htblcnt[100000];
38
extern int htblmax;
39
extern int pass;
40
extern int num_cinsns;
41
 
42
static int64_t ca;
43
 
44
extern int use_gp;
45
 
46
static int regSP = 31;
47
static int regFP = 30;
48
static int regLR = 29;
49
static int regXL = 28;
50
static int regGP = 27;
51
static int regTP = 26;
52
static int regCB = 23;
53
static int regCnst;
54
 
55
#define OPT64     0
56
#define OPTX32    1
57
#define OPTLUI0   0
58
#define LB16    -31653LL
59
 
60
// ----------------------------------------------------------------------------
61
// Return the register number or -1 if not a register.
62
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
63
// ----------------------------------------------------------------------------
64
 
65
//static int getRegisterX()
66
//{
67
//    int reg;
68
//
69
//    while(isspace(*inptr)) inptr++;
70
//      if (*inptr == '$')
71
//              inptr++;
72
//    switch(*inptr) {
73
//    case 'r': case 'R':
74
//        if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
75
//            inptr += 2;
76
//            NextToken();
77
//            return 29;
78
//        }
79
//         if (isdigit(inptr[1])) {
80
//             reg = inptr[1]-'0';
81
//             if (isdigit(inptr[2])) {
82
//                 reg = 10 * reg + (inptr[2]-'0');
83
//                 if (isdigit(inptr[3])) {
84
//                     reg = 10 * reg + (inptr[3]-'0');
85
//                     if (isIdentChar(inptr[4]))
86
//                         return -1;
87
//                     inptr += 4;
88
//                     NextToken();
89
//                     return reg;
90
//                 }
91
//                 else if (isIdentChar(inptr[3]))
92
//                     return -1;
93
//                 else {
94
//                     inptr += 3;
95
//                     NextToken();
96
//                     return reg;
97
//                 }
98
//             }
99
//             else if (isIdentChar(inptr[2]))
100
//                 return -1;
101
//             else {
102
//                 inptr += 2;
103
//                 NextToken();
104
//                 return reg;
105
//             }
106
//         }
107
//         else return -1;
108
//    case 'a': case 'A':
109
//         if (isdigit(inptr[1])) {
110
//             reg = inptr[1]-'0' + 18;
111
//             if (isIdentChar(inptr[2]))
112
//                 return -1;
113
//             else {
114
//                 inptr += 2;
115
//                 NextToken();
116
//                 return reg;
117
//             }
118
//         }
119
//         else return -1;
120
//    case 'b': case 'B':
121
//        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
122
//            inptr += 2;
123
//            NextToken();
124
//            return 30;
125
//        }
126
//        break;
127
//    case 'f': case 'F':
128
//        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
129
//            inptr += 2;
130
//            NextToken();
131
//            return 2;
132
//        }
133
//        break;
134
//    case 'g': case 'G':
135
//        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
136
//            inptr += 2;
137
//            NextToken();
138
//            return 26;
139
//        }
140
//        break;
141
//    case 'p': case 'P':
142
//        if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
143
//            inptr += 2;
144
//            NextToken();
145
//            return 31;
146
//        }
147
//        break;
148
//    case 's': case 'S':
149
//        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
150
//            inptr += 2;
151
//            NextToken();
152
//            return 31;
153
//        }
154
//        break;
155
//    case 't': case 'T':
156
//         if (isdigit(inptr[1])) {
157
//             reg = inptr[1]-'0' + 26;
158
//             if (isIdentChar(inptr[2]))
159
//                 return -1;
160
//             else {
161
//                 inptr += 2;
162
//                 NextToken();
163
//                 return reg;
164
//             }
165
//         }
166
//        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
167
//            inptr += 2;
168
//            NextToken();
169
//            return 15;
170
//        }
171
//        /*
172
//        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
173
//            inptr += 2;
174
//            NextToken();
175
//            return 24;
176
//        }
177
//        */
178
//        break;
179
//      // lr
180
//    case 'l': case 'L':
181
//        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
182
//            inptr += 2;
183
//            NextToken();
184
//            return 29;
185
//        }
186
//        break;
187
//      // xlr
188
//    case 'x': case 'X':
189
//        if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') && 
190
//                      !isIdentChar(inptr[3])) {
191
//            inptr += 3;
192
//            NextToken();
193
//            return 28;
194
//        }
195
//        break;
196
//    default:
197
//        return -1;
198
//    }
199
//    return -1;
200
//}
201
static int getRegisterX()
202
{
203
    int reg;
204
 
205
    while(isspace(*inptr)) inptr++;
206
        if (*inptr == '$')
207
                inptr++;
208
    switch(*inptr) {
209
    case 'r': case 'R':
210
        if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
211
            inptr += 2;
212
            NextToken();
213
            return regLR;
214
        }
215
         if (isdigit(inptr[1])) {
216
             reg = inptr[1]-'0';
217
             if (isdigit(inptr[2])) {
218
                 reg = 10 * reg + (inptr[2]-'0');
219
                 if (isdigit(inptr[3])) {
220
                     reg = 10 * reg + (inptr[3]-'0');
221
                     if (isIdentChar(inptr[4]))
222
                         return -1;
223
                     inptr += 4;
224
                     NextToken();
225
                     return reg;
226
                 }
227
                 else if (isIdentChar(inptr[3]))
228
                     return -1;
229
                 else {
230
                     inptr += 3;
231
                     NextToken();
232
                     return reg;
233
                 }
234
             }
235
             else if (isIdentChar(inptr[2]))
236
                 return -1;
237
             else {
238
                 inptr += 2;
239
                 NextToken();
240
                 return reg;
241
             }
242
         }
243
         else return -1;
244
    case 'a': case 'A':
245
         if (isdigit(inptr[1])) {
246
             reg = inptr[1]-'0' + 18;
247
             if (isIdentChar(inptr[2]))
248
                 return -1;
249
             else {
250
                 inptr += 2;
251
                 NextToken();
252
                 return reg;
253
             }
254
         }
255
         else return -1;
256
    case 'f': case 'F':
257
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
258
            inptr += 2;
259
            NextToken();
260
            return regFP;
261
        }
262
        break;
263
    case 'g': case 'G':
264
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
265
            inptr += 2;
266
            NextToken();
267
            return regGP;
268
        }
269
        break;
270
    case 'p': case 'P':
271
        if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
272
            inptr += 2;
273
            NextToken();
274
            return 31;
275
        }
276
        break;
277
    case 's': case 'S':
278
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
279
            inptr += 2;
280
            NextToken();
281
            return (regSP);
282
        }
283
        break;
284
    case 't': case 'T':
285
         if (isdigit(inptr[1])) {
286
             reg = inptr[1]-'0' + 5;
287
             if (isdigit(inptr[2])) {
288
                 reg = 10 * reg + (inptr[2]-'0');
289
                 if (isdigit(inptr[3])) {
290
                     reg = 10 * reg + (inptr[3]-'0');
291
                     if (isIdentChar(inptr[4]))
292
                         return -1;
293
                     inptr += 4;
294
                     NextToken();
295
                     return reg;
296
                 }
297
                 else if (isIdentChar(inptr[3]))
298
                     return -1;
299
                 else {
300
                     inptr += 3;
301
                     NextToken();
302
                     return reg;
303
                 }
304
             }
305
             if (isIdentChar(inptr[2]))
306
                 return -1;
307
             else {
308
                 inptr += 2;
309
                 NextToken();
310
                 return (reg);
311
             }
312
         }
313
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
314
            inptr += 2;
315
            NextToken();
316
            return (regTP);
317
        }
318
        /*
319
        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
320
            inptr += 2;
321
            NextToken();
322
            return 24;
323
        }
324
        */
325
        break;
326
        // lr
327
    case 'l': case 'L':
328
        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
329
            inptr += 2;
330
            NextToken();
331
            return (regLR);
332
        }
333
        break;
334
        // xlr
335
    case 'x': case 'X':
336
        if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') &&
337
                        !isIdentChar(inptr[3])) {
338
            inptr += 3;
339
            NextToken();
340
            return (regXL);
341
        }
342
        break;
343
        case 'v': case 'V':
344
         if (isdigit(inptr[1])) {
345
             reg = inptr[1]-'0' + 1;
346
             if (isIdentChar(inptr[2]))
347
                 return -1;
348
             else {
349
                 inptr += 2;
350
                 NextToken();
351
                 return (reg);
352
             }
353
         }
354
                 break;
355
    default:
356
        return -1;
357
    }
358
    return -1;
359
}
360
static int isdelim(char ch)
361
{
362
    return ch==',' || ch=='[' || ch=='(' || ch==']' || ch==')' || ch=='.';
363
}
364
 
365
// ----------------------------------------------------------------------------
366
// Return the register number or -1 if not a register.
367
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
368
// ----------------------------------------------------------------------------
369
 
370
static int getVecRegister()
371
{
372
    int reg;
373
 
374
    while(isspace(*inptr)) inptr++;
375
        if (*inptr=='$')
376
                inptr++;
377
    switch(*inptr) {
378
    case 'v': case 'V':
379
         if (isdigit(inptr[1])) {
380
             reg = inptr[1]-'0';
381
             if (isdigit(inptr[2])) {
382
                 reg = 10 * reg + (inptr[2]-'0');
383
                 if (isdigit(inptr[3])) {
384
                     reg = 10 * reg + (inptr[3]-'0');
385
                     if (isIdentChar(inptr[4]))
386
                         return -1;
387
                     inptr += 4;
388
                     NextToken();
389
                     return reg;
390
                 }
391
                 else if (isIdentChar(inptr[3]))
392
                     return -1;
393
                 else {
394
                     inptr += 3;
395
                     NextToken();
396
                     return reg;
397
                 }
398
             }
399
             else if (isIdentChar(inptr[2]))
400
                 return -1;
401
             else {
402
                 inptr += 2;
403
                 NextToken();
404
                 return reg;
405
             }
406
         }
407
                 else if (inptr[1]=='l' || inptr[1]=='L') {
408
                         if (!isIdentChar(inptr[2])) {
409
                                 inptr += 2;
410
                                 NextToken();
411
                                 return 0x2F;
412
                         }
413
                 }
414
         else if (inptr[1]=='m' || inptr[1]=='M') {
415
                         if (isdigit(inptr[2])) {
416
                                 if (inptr[2] >= '0' && inptr[2] <= '7') {
417
                                         if (!isIdentChar(inptr[3])) {
418
                                                 reg = 0x20 | (inptr[2]-'0');
419
                                                 inptr += 3;
420
                                                 NextToken();
421
                                                 return (reg);
422
                                         }
423
                                 }
424
                         }
425
                 }
426
                 return -1;
427
        }
428
    return -1;
429
}
430
 
431
// ----------------------------------------------------------------------------
432
// Get the friendly name of a special purpose register.
433
// ----------------------------------------------------------------------------
434
 
435
static int DSD7_getSprRegister()
436
{
437
    int reg = -1;
438
    int pr;
439
 
440
    while(isspace(*inptr)) inptr++;
441
//    reg = getCodeareg();
442
    if (reg >= 0) {
443
       reg |= 0x10;
444
       return reg;
445
    }
446
    if (inptr[0]=='p' || inptr[0]=='P') {
447
         if (isdigit(inptr[1]) && isdigit(inptr[2])) {
448
              pr = ((inptr[1]-'0' * 10) + (inptr[2]-'0'));
449
              if (!isIdentChar(inptr[3])) {
450
                  inptr += 3;
451
                  NextToken();
452
                  return pr | 0x40;
453
              }
454
         }
455
         else if (isdigit(inptr[1])) {
456
              pr = (inptr[1]-'0');
457
              if (!isIdentChar(inptr[2])) {
458
                  inptr += 2;
459
                  NextToken();
460
                  return pr | 0x40;
461
              }
462
         }
463
     }
464
 
465
    while(isspace(*inptr)) inptr++;
466
    switch(*inptr) {
467
 
468
    case '0':
469
    case '1':
470
    case '2':
471
    case '3':
472
    case '4':
473
    case '5':
474
    case '6':
475
    case '7':
476
    case '8':
477
    case '9':
478
         NextToken();
479
         NextToken();
480
         return (int)ival.low & 0xFFF;
481
 
482
    // arg1
483
    case 'a': case 'A':
484
         if ((inptr[1]=='r' || inptr[1]=='R') &&
485
             (inptr[2]=='g' || inptr[2]=='G') &&
486
             (inptr[3]=='1' || inptr[3]=='1') &&
487
             !isIdentChar(inptr[4])) {
488
             inptr += 4;
489
             NextToken();
490
             return 58;
491
         }
492
         break;
493
    // bear
494
    case 'b': case 'B':
495
         if ((inptr[1]=='e' || inptr[1]=='E') &&
496
             (inptr[2]=='a' || inptr[2]=='A') &&
497
             (inptr[3]=='r' || inptr[3]=='R') &&
498
             !isIdentChar(inptr[4])) {
499
             inptr += 4;
500
             NextToken();
501
             return 11;
502
         }
503
         break;
504
    // cas clk cr0 cr3 cs CPL
505
    case 'c': case 'C':
506
         if ((inptr[1]=='a' || inptr[1]=='A') &&
507
             (inptr[2]=='s' || inptr[2]=='S') &&
508
             !isIdentChar(inptr[3])) {
509
             inptr += 3;
510
             NextToken();
511
             return 44;
512
         }
513
         if ((inptr[1]=='l' || inptr[1]=='L') &&
514
             (inptr[2]=='k' || inptr[2]=='K') &&
515
             !isIdentChar(inptr[3])) {
516
             inptr += 3;
517
             NextToken();
518
             return 0x06;
519
         }
520
         if ((inptr[1]=='r' || inptr[1]=='R') &&
521
             (inptr[2]=='0') &&
522
             !isIdentChar(inptr[3])) {
523
             inptr += 3;
524
             NextToken();
525
             return 0x00;
526
         }
527
         if ((inptr[1]=='r' || inptr[1]=='R') &&
528
             (inptr[2]=='3') &&
529
             !isIdentChar(inptr[3])) {
530
             inptr += 3;
531
             NextToken();
532
             return 0x03;
533
         }
534
        if ((inptr[1]=='s' || inptr[1]=='S') &&
535
            !isIdentChar(inptr[2])) {
536
            if (inptr[2]=='.') {
537
               if ((inptr[3]=='l' || inptr[3]=='L') &&
538
                   (inptr[4]=='m' || inptr[4]=='M') &&
539
                   (inptr[5]=='t' || inptr[5]=='T') &&
540
                   !isIdentChar(inptr[6])) {
541
                       inptr += 6;
542
                       NextToken();
543
                       return 0x2F;
544
               }
545
            }
546
            inptr += 2;
547
            NextToken();
548
            return 0x27;
549
        }
550
         if ((inptr[1]=='p' || inptr[1]=='P') &&
551
             (inptr[2]=='l' || inptr[2]=='L') &&
552
             !isIdentChar(inptr[3])) {
553
             inptr += 3;
554
             NextToken();
555
             return 42;
556
         }
557
         break;
558
 
559
    // dbad0 dbad1 dbctrl dpc dsp ds
560
    case 'd': case 'D':
561
         if ((inptr[1]=='b' || inptr[1]=='B') &&
562
             (inptr[2]=='a' || inptr[2]=='A') &&
563
             (inptr[3]=='d' || inptr[3]=='D') &&
564
             (inptr[4]=='0' || inptr[4]=='0') &&
565
             !isIdentChar(inptr[5])) {
566
             inptr += 5;
567
             NextToken();
568
             return 50;
569
         }
570
         if ((inptr[1]=='b' || inptr[1]=='B') &&
571
             (inptr[2]=='a' || inptr[2]=='A') &&
572
             (inptr[3]=='d' || inptr[3]=='D') &&
573
             (inptr[4]=='1' || inptr[4]=='1') &&
574
             !isIdentChar(inptr[5])) {
575
             inptr += 5;
576
             NextToken();
577
             return 51;
578
         }
579
         if ((inptr[1]=='b' || inptr[1]=='B') &&
580
             (inptr[2]=='a' || inptr[2]=='A') &&
581
             (inptr[3]=='d' || inptr[3]=='D') &&
582
             (inptr[4]=='2' || inptr[4]=='2') &&
583
             !isIdentChar(inptr[5])) {
584
             inptr += 5;
585
             NextToken();
586
             return 52;
587
         }
588
         if ((inptr[1]=='b' || inptr[1]=='B') &&
589
             (inptr[2]=='a' || inptr[2]=='A') &&
590
             (inptr[3]=='d' || inptr[3]=='D') &&
591
             (inptr[4]=='3' || inptr[4]=='3') &&
592
             !isIdentChar(inptr[5])) {
593
             inptr += 5;
594
             NextToken();
595
             return 53;
596
         }
597
         if ((inptr[1]=='b' || inptr[1]=='B') &&
598
             (inptr[2]=='c' || inptr[2]=='C') &&
599
             (inptr[3]=='t' || inptr[3]=='T') &&
600
             (inptr[4]=='r' || inptr[4]=='R') &&
601
             (inptr[5]=='l' || inptr[5]=='L') &&
602
             !isIdentChar(inptr[6])) {
603
             inptr += 6;
604
             NextToken();
605
             return 54;
606
         }
607
         if ((inptr[1]=='p' || inptr[1]=='P') &&
608
             (inptr[2]=='c' || inptr[2]=='C') &&
609
             !isIdentChar(inptr[3])) {
610
             inptr += 3;
611
             NextToken();
612
             return 7;
613
         }
614
         if (
615
             (inptr[1]=='b' || inptr[1]=='B') &&
616
             (inptr[2]=='p' || inptr[2]=='P') &&
617
             (inptr[3]=='c' || inptr[3]=='C') &&
618
             !isIdentChar(inptr[4])) {
619
             inptr += 4;
620
             NextToken();
621
             return 7;
622
         }
623
         if ((inptr[1]=='s' || inptr[1]=='S') &&
624
             (inptr[2]=='p' || inptr[2]=='P') &&
625
             !isIdentChar(inptr[3])) {
626
             inptr += 3;
627
             NextToken();
628
             return 16;
629
         }
630
        if ((inptr[1]=='s' || inptr[1]=='S') &&
631
            !isIdentChar(inptr[2])) {
632
            if (inptr[2]=='.') {
633
               if ((inptr[3]=='l' || inptr[3]=='L') &&
634
                   (inptr[4]=='m' || inptr[4]=='M') &&
635
                   (inptr[5]=='t' || inptr[5]=='T') &&
636
                   !isIdentChar(inptr[6])) {
637
                       inptr += 6;
638
                       NextToken();
639
                       return 0x29;
640
               }
641
            }
642
            inptr += 2;
643
            NextToken();
644
            return 0x21;
645
        }
646
         break;
647
 
648
    // ea epc esp es
649
    case 'e': case 'E':
650
         if ((inptr[1]=='a' || inptr[1]=='A') &&
651
             !isIdentChar(inptr[2])) {
652
             inptr += 2;
653
             NextToken();
654
             return 40;
655
         }
656
         if ((inptr[1]=='p' || inptr[1]=='P') &&
657
             (inptr[2]=='c' || inptr[2]=='C') &&
658
             !isIdentChar(inptr[3])) {
659
             inptr += 3;
660
             NextToken();
661
             return 9;
662
         }
663
         if ((inptr[1]=='s' || inptr[1]=='S') &&
664
             (inptr[2]=='p' || inptr[2]=='P') &&
665
             !isIdentChar(inptr[3])) {
666
             inptr += 3;
667
             NextToken();
668
             return 17;
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 0x2A;
680
               }
681
            }
682
            inptr += 2;
683
            NextToken();
684
            return 0x22;
685
        }
686
         break;
687
 
688
    // fault_pc fs
689
    case 'f': case 'F':
690
         if ((inptr[1]=='a' || inptr[1]=='A') &&
691
             (inptr[2]=='u' || inptr[2]=='U') &&
692
             (inptr[3]=='l' || inptr[3]=='L') &&
693
             (inptr[4]=='t' || inptr[4]=='T') &&
694
             (inptr[5]=='_' || inptr[5]=='_') &&
695
             (inptr[6]=='p' || inptr[6]=='P') &&
696
             (inptr[7]=='c' || inptr[7]=='C') &&
697
             !isIdentChar(inptr[8])) {
698
             inptr += 8;
699
             NextToken();
700
             return 0x08;
701
         }
702
        if ((inptr[1]=='s' || inptr[1]=='S') &&
703
            !isIdentChar(inptr[2])) {
704
            if (inptr[2]=='.') {
705
               if ((inptr[3]=='l' || inptr[3]=='L') &&
706
                   (inptr[4]=='m' || inptr[4]=='M') &&
707
                   (inptr[5]=='t' || inptr[5]=='T') &&
708
                   !isIdentChar(inptr[6])) {
709
                       inptr += 6;
710
                       NextToken();
711
                       return 0x2B;
712
               }
713
            }
714
            inptr += 2;
715
            NextToken();
716
            return 0x23;
717
        }
718
         break;
719
 
720
    // gs GDT
721
    case 'g': case 'G':
722
        if ((inptr[1]=='s' || inptr[1]=='S') &&
723
            !isIdentChar(inptr[2])) {
724
            if (inptr[2]=='.') {
725
               if ((inptr[3]=='l' || inptr[3]=='L') &&
726
                   (inptr[4]=='m' || inptr[4]=='M') &&
727
                   (inptr[5]=='t' || inptr[5]=='T') &&
728
                   !isIdentChar(inptr[6])) {
729
                       inptr += 6;
730
                       NextToken();
731
                       return 0x2C;
732
               }
733
            }
734
            inptr += 2;
735
            NextToken();
736
            return 0x24;
737
        }
738
        if ((inptr[1]=='d' || inptr[1]=='D') &&
739
           (inptr[2]=='t' || inptr[2]=='T') &&
740
            !isIdentChar(inptr[3])) {
741
            inptr += 3;
742
            NextToken();
743
            return 41;
744
        }
745
        break;
746
 
747
    // history
748
    case 'h': case 'H':
749
         if ((inptr[1]=='i' || inptr[1]=='I') &&
750
             (inptr[2]=='s' || inptr[2]=='S') &&
751
             (inptr[3]=='t' || inptr[3]=='T') &&
752
             (inptr[4]=='o' || inptr[4]=='O') &&
753
             (inptr[5]=='r' || inptr[5]=='R') &&
754
             (inptr[6]=='y' || inptr[6]=='Y') &&
755
             !isIdentChar(inptr[7])) {
756
             inptr += 7;
757
             NextToken();
758
             return 0x0D;
759
         }
760
        if ((inptr[1]=='s' || inptr[1]=='S') &&
761
            !isIdentChar(inptr[2])) {
762
            if (inptr[2]=='.') {
763
               if ((inptr[3]=='l' || inptr[3]=='L') &&
764
                   (inptr[4]=='m' || inptr[4]=='M') &&
765
                   (inptr[5]=='t' || inptr[5]=='T') &&
766
                   !isIdentChar(inptr[6])) {
767
                       inptr += 6;
768
                       NextToken();
769
                       return 0x2D;
770
               }
771
            }
772
            inptr += 2;
773
            NextToken();
774
            return 0x25;
775
        }
776
         break;
777
 
778
    // ipc isp ivno
779
    case 'i': case 'I':
780
         if ((inptr[1]=='p' || inptr[1]=='P') &&
781
             (inptr[2]=='c' || inptr[2]=='C') &&
782
             !isIdentChar(inptr[3])) {
783
             inptr += 3;
784
             NextToken();
785
             return 8;
786
         }
787
         if ((inptr[1]=='s' || inptr[1]=='S') &&
788
             (inptr[2]=='p' || inptr[2]=='P') &&
789
             !isIdentChar(inptr[3])) {
790
             inptr += 3;
791
             NextToken();
792
             return 15;
793
         }
794
         if ((inptr[1]=='v' || inptr[1]=='V') &&
795
             (inptr[2]=='n' || inptr[2]=='N') &&
796
             (inptr[3]=='o' || inptr[3]=='O') &&
797
             !isIdentChar(inptr[4])) {
798
             inptr += 4;
799
             NextToken();
800
             return 0x0C;
801
         }
802
         break;
803
 
804
 
805
    // LC LDT
806
    case 'l': case 'L':
807
         if ((inptr[1]=='c' || inptr[1]=='C') &&
808
             !isIdentChar(inptr[2])) {
809
             inptr += 2;
810
             NextToken();
811
             return 0x33;
812
         }
813
         if ((inptr[1]=='d' || inptr[1]=='D') &&
814
            (inptr[2]=='t' || inptr[2]=='T') &&
815
             !isIdentChar(inptr[3])) {
816
             inptr += 3;
817
             NextToken();
818
             return 40;
819
         }
820
         break;
821
 
822
    // pregs
823
    case 'p': case 'P':
824
         if ((inptr[1]=='r' || inptr[1]=='R') &&
825
             (inptr[2]=='e' || inptr[2]=='E') &&
826
             (inptr[3]=='g' || inptr[3]=='G') &&
827
             (inptr[4]=='s' || inptr[4]=='S') &&
828
             !isIdentChar(inptr[5])) {
829
             inptr += 5;
830
             NextToken();
831
             return 52;
832
         }
833
         break;
834
 
835
    // rand
836
    case 'r': case 'R':
837
         if ((inptr[1]=='a' || inptr[1]=='A') &&
838
             (inptr[2]=='n' || inptr[2]=='N') &&
839
             (inptr[3]=='d' || inptr[3]=='D') &&
840
             !isIdentChar(inptr[4])) {
841
             inptr += 4;
842
             NextToken();
843
             return 0x12;
844
         }
845
         break;
846
    // ss_ll srand1 srand2 ss segsw segbase seglmt segacr
847
    case 's': case 'S':
848
         if ((inptr[1]=='s' || inptr[1]=='S') &&
849
             (inptr[2]=='_' || inptr[2]=='_') &&
850
             (inptr[3]=='l' || inptr[3]=='L') &&
851
             (inptr[4]=='l' || inptr[4]=='L') &&
852
             !isIdentChar(inptr[5])) {
853
             inptr += 5;
854
             NextToken();
855
             return 0x1A;
856
         }
857
         if ((inptr[1]=='r' || inptr[1]=='R') &&
858
             (inptr[2]=='a' || inptr[2]=='A') &&
859
             (inptr[3]=='n' || inptr[3]=='N') &&
860
             (inptr[4]=='d' || inptr[4]=='D') &&
861
             (inptr[5]=='1') &&
862
             !isIdentChar(inptr[6])) {
863
             inptr += 6;
864
             NextToken();
865
             return 0x10;
866
         }
867
         if ((inptr[1]=='r' || inptr[1]=='R') &&
868
             (inptr[2]=='a' || inptr[2]=='A') &&
869
             (inptr[3]=='n' || inptr[3]=='N') &&
870
             (inptr[4]=='d' || inptr[4]=='D') &&
871
             (inptr[5]=='2') &&
872
             !isIdentChar(inptr[6])) {
873
             inptr += 6;
874
             NextToken();
875
             return 0x11;
876
         }
877
         if ((inptr[1]=='p' || inptr[1]=='P') &&
878
             (inptr[2]=='r' || inptr[2]=='R') &&
879
             isdigit(inptr[3]) && isdigit(inptr[4]) &&
880
             !isIdentChar(inptr[5])) {
881
             inptr += 5;
882
             NextToken();
883
             return (inptr[3]-'0')*10 + (inptr[4]-'0');
884
         }
885
        if ((inptr[1]=='s' || inptr[1]=='S') &&
886
            !isIdentChar(inptr[2])) {
887
            if (inptr[2]=='.') {
888
               if ((inptr[3]=='l' || inptr[3]=='L') &&
889
                   (inptr[4]=='m' || inptr[4]=='M') &&
890
                   (inptr[5]=='t' || inptr[5]=='T') &&
891
                   !isIdentChar(inptr[6])) {
892
                       inptr += 6;
893
                       NextToken();
894
                       return 0x2E;
895
               }
896
            }
897
            inptr += 2;
898
            NextToken();
899
            return 0x26;
900
         }
901
         // segxxx
902
         if ((inptr[1]=='e' || inptr[1]=='E') &&
903
             (inptr[2]=='g' || inptr[2]=='G')) {
904
             // segsw
905
             if ((inptr[3]=='s' || inptr[3]=='S') &&
906
                  (inptr[4]=='w' || inptr[4]=='W') &&
907
                  !isIdentChar(inptr[5])) {
908
               inptr += 5;
909
               NextToken();
910
               return 43;
911
             }
912
             // segbase
913
             if ((inptr[3]=='b' || inptr[3]=='B') &&
914
                  (inptr[4]=='a' || inptr[4]=='A') &&
915
                  (inptr[5]=='s' || inptr[5]=='S') &&
916
                  (inptr[6]=='e' || inptr[6]=='E') &&
917
                  !isIdentChar(inptr[7])) {
918
               inptr += 7;
919
               NextToken();
920
               return 44;
921
             }
922
             // seglmt
923
             if ((inptr[3]=='l' || inptr[3]=='L') &&
924
                  (inptr[4]=='m' || inptr[4]=='M') &&
925
                  (inptr[5]=='t' || inptr[5]=='T') &&
926
                  !isIdentChar(inptr[6])) {
927
               inptr += 6;
928
               NextToken();
929
               return 45;
930
             }
931
             // segacr
932
             if ((inptr[3]=='a' || inptr[3]=='A') &&
933
                  (inptr[4]=='c' || inptr[4]=='C') &&
934
                  (inptr[5]=='r' || inptr[5]=='R') &&
935
                  !isIdentChar(inptr[6])) {
936
               inptr += 6;
937
               NextToken();
938
               return 47;
939
             }
940
         }
941
         break;
942
 
943
    // tag tick 
944
    case 't': case 'T':
945
         if ((inptr[1]=='i' || inptr[1]=='I') &&
946
             (inptr[2]=='c' || inptr[2]=='C') &&
947
             (inptr[3]=='k' || inptr[3]=='K') &&
948
             !isIdentChar(inptr[4])) {
949
             inptr += 4;
950
             NextToken();
951
             return 0x32;
952
         }
953
         if ((inptr[1]=='a' || inptr[1]=='A') &&
954
             (inptr[2]=='g' || inptr[2]=='G') &&
955
             !isIdentChar(inptr[3])) {
956
             inptr += 3;
957
             NextToken();
958
             return 41;
959
         }
960
         break;
961
 
962
    // vbr
963
    case 'v': case 'V':
964
         if ((inptr[1]=='b' || inptr[1]=='B') &&
965
             (inptr[2]=='r' || inptr[2]=='R') &&
966
             !isIdentChar(inptr[3])) {
967
             inptr += 3;
968
             NextToken();
969
             return 10;
970
         }
971
         break;
972
    case 'z': case 'Z':
973
        if ((inptr[1]=='s' || inptr[1]=='S') &&
974
            !isIdentChar(inptr[2])) {
975
            if (inptr[2]=='.') {
976
               if ((inptr[3]=='l' || inptr[3]=='L') &&
977
                   (inptr[4]=='m' || inptr[4]=='M') &&
978
                   (inptr[5]=='t' || inptr[5]=='T') &&
979
                   !isIdentChar(inptr[6])) {
980
                       inptr += 6;
981
                       NextToken();
982
                       return 0x28;
983
               }
984
            }
985
            inptr += 2;
986
            NextToken();
987
            return 0x20;
988
        }
989
        break;
990
    }
991
    return -1;
992
}
993
 
994
// Detect if a register can be part of a compressed instruction
995
int CmpReg(int reg)
996
{
997
        switch(reg) {
998
        case 1: return(0);
999
        case 3: return(1);
1000
        case 4: return(2);
1001
        case 11: return(3);
1002
        case 12: return(4);
1003
        case 18: return(5);
1004
        case 19: return(6);
1005
        case 20: return(7);
1006
        default:
1007
                return(-1);
1008
        }
1009
}
1010
// ---------------------------------------------------------------------------
1011
// Process the size specifier for a FP instruction.
1012
// h: half (16 bit)
1013
// s: single (32 bit)
1014
// d: double (64 bit)
1015
// t: triple (96 bit)
1016
// q: quad (128 bit)
1017
// ---------------------------------------------------------------------------
1018
 
1019
static int GetFPSize()
1020
{
1021
        int sz;
1022
 
1023
    sz = 'd';
1024
    if (*inptr=='.') {
1025
        inptr++;
1026
        if (strchr("hsdtqHSDTQ",*inptr)) {
1027
            sz = tolower(*inptr);
1028
            inptr++;
1029
        }
1030
        else
1031
            printf("Illegal float size.\r\n");
1032
    }
1033
        switch(sz) {
1034
        case 'h':       sz = 0; break;
1035
        case 's':       sz = 1; break;
1036
        case 'd':       sz = 2; break;
1037
        case 't':       sz = 3; break;
1038
        case 'q':       sz = 4; break;
1039
        default:        sz = 3; break;
1040
        }
1041
        return (sz);
1042
}
1043
 
1044
 
1045
// ---------------------------------------------------------------------------
1046
// ---------------------------------------------------------------------------
1047
 
1048
static void emit_insn(int64_t oc, int can_compress, int sz)
1049
{
1050
    int ndx;
1051
 
1052
    if (pass==3 && can_compress && gCanCompress) {
1053
       for (ndx = 0; ndx < htblmax; ndx++) {
1054
         if ((int)oc == hTable[ndx].opcode) {
1055
           hTable[ndx].count++;
1056
           return;
1057
         }
1058
       }
1059
       if (htblmax < 100000) {
1060
          hTable[htblmax].opcode = (int)oc;
1061
          hTable[htblmax].count = 1;
1062
          htblmax++;
1063
          return;
1064
       }
1065
       printf("Too many instructions.\r\n");
1066
       return;
1067
    }
1068
    if (pass > 3) {
1069
     if (can_compress && gCanCompress) {
1070
       for (ndx = 0; ndx < min(128,htblmax); ndx++) {
1071
         if ((int)oc == hTable[ndx].opcode) {
1072
           emitCode(((ndx << 6)|0x3F) & 0xff);
1073
           emitCode(((ndx << 6)|0x3F) >> 8);
1074
                   num_bytes += 2;
1075
                   num_insns += 1;
1076
           return;
1077
         }
1078
       }
1079
     }
1080
         if (sz==2) {
1081
             emitCode(oc & 255);
1082
                 emitCode((oc >> 8) & 255);
1083
             num_bytes += 2;
1084
             num_insns += 1;
1085
                 num_cinsns += 1;
1086
                 return;
1087
         }
1088
         if (sz == 4) {
1089
                 emitCode(oc & 255);
1090
                 emitCode((oc >> 8) & 255);
1091
                 emitCode((oc >> 16) & 255);
1092
                 emitCode((oc >> 24) & 255);
1093
                 num_bytes += 4;
1094
                 num_insns += 1;
1095
                 return;
1096
         }
1097
         emitCode(oc & 255);
1098
         emitCode((oc >> 8) & 255);
1099
         emitCode((oc >> 16) & 255);
1100
         emitCode((oc >> 24) & 255);
1101
         emitCode((oc >> 32LL) & 255);
1102
         emitCode((oc >> 40LL) & 255);
1103
         num_bytes += 6;
1104
        //if (sz==3) {
1105
        //      emitCode((int)(oc >> 16));
1106
 //         num_bytes += 2;
1107
        //      emitCode(oc >> 32);
1108
 //         num_bytes += 2;
1109
        //}
1110
        num_insns += 1;
1111
    /*
1112
    if (processOpt==2) {
1113
       for (ndx = 0; ndx < htblmax; ndx++) {
1114
         if (oc == hTable[ndx].opcode) {
1115
           printf("found opcode\n");
1116
           emitAlignedCode(((ndx & 8) << 4)|0x50|(ndx & 0x7));
1117
           emitCode(ndx >> 4);
1118
           return;
1119
         }
1120
       }
1121
     emitAlignedCode(oc & 255);
1122
     emitCode((oc >> 8) & 255);
1123
     emitCode((oc >> 16) & 255);
1124
     emitCode((oc >> 24) & 255);
1125
    }
1126
    else {
1127
     emitAlignedCode(oc & 255);
1128
     emitCode((oc >> 8) & 255);
1129
     emitCode((oc >> 16) & 255);
1130
     emitCode((oc >> 24) & 255);
1131
    */
1132
    }
1133
}
1134
 
1135
void LoadConstant(int64_t val, int rg)
1136
{
1137
        if (IsNBit(val, 14)) {
1138
                emit_insn(
1139
                        (val << 18LL) |
1140
                        (rg << 13) |
1141
                        0x09, !expand_flag, 4); // ORI
1142
                return;
1143
        }
1144
        if (IsNBit(val, 30)) {
1145
                emit_insn(
1146
                        (val << 18LL) |
1147
                        (rg << 13) |
1148
                        (1 << 6) |
1149
                        0x09, !expand_flag, 6);
1150
                return;
1151
        }
1152
        if (IsNBit(val, 49)) {
1153
                emit_insn(
1154
                        ((val >> 30) << 13LL) |
1155
                        (rg << 8) |
1156
                        0x27, !expand_flag, 4); // LUI
1157
                if (((val >> 20) & 0xfffffLL) != 0)
1158
                        emit_insn(
1159
                        (val << 18LL) |
1160
                        (rg << 13) |
1161
                        (1 << 6) |
1162
                        0x09, !expand_flag, 6);
1163
                return;
1164
        }
1165
        // Won't fit into 49 bits, assume 64 bit constant
1166
        emit_insn(
1167
                ((val >> 30) << 13LL) |
1168
                (rg << 8) |
1169
                0x27, !expand_flag, 6); // LUI
1170
        if (((val >> 20) & 0xfffffLL) != 0)
1171
                emit_insn(
1172
                (val << 18LL) |
1173
                        (rg << 13) |
1174
                        (1 << 6) |
1175
                        0x09, !expand_flag, 6); // ORI
1176
        return;
1177
}
1178
 
1179
static void Lui34(int64_t val, int rg)
1180
{
1181
        if (IsNBit(val, 49)) {
1182
                emit_insn(
1183
                        ((val >> 30LL) << 13LL) |
1184
                        (rg << 8) |
1185
                        (0 << 6) |
1186
                        0x27, !expand_flag, 4
1187
                );
1188
                return;
1189
        }
1190
        emit_insn(
1191
                ((val >> 30LL) << 13LL) |
1192
                (rg << 8) |
1193
                (1 << 6) |
1194
                0x27, !expand_flag, 6
1195
        );
1196
}
1197
 
1198
void LoadConstant12(int64_t val, int rg)
1199
{
1200
        if (val & 0x800) {
1201
                emit_insn(
1202
                        (0 << 16) |
1203
                        (rg << 11) |
1204
                        (0 << 6) |
1205
                        0x09,!expand_flag,4);   // ORI
1206
                emit_insn(
1207
                        (val << 16) |
1208
                        (rg << 11) |
1209
                        (0 << 6) |
1210
                        (0 << 6) |
1211
                        0x1A,!expand_flag,4);   // ORQ0
1212
        }
1213
        else {
1214
                emit_insn(
1215
                        (val << 16) |
1216
                        (rg << 11) |
1217
                        (0 << 6) |
1218
                        0x09,!expand_flag,4);   // ORI
1219
        }
1220
        val >>= 16;
1221
        emit_insn(
1222
                (val << 16) |
1223
                (rg << 11) |
1224
                (0 << 6) |
1225
                (1 << 6) |
1226
                0x1A,!expand_flag,4);   // ORQ1
1227
        val >>= 16;
1228
        if (val != 0) {
1229
                emit_insn(
1230
                        (val << 16) |
1231
                        (rg << 11) |
1232
                        (0 << 6) |
1233
                        (2 << 6) |
1234
                        0x1A,!expand_flag,4);   // ORQ2
1235
        }
1236
        val >>= 16;
1237
        if (val != 0) {
1238
                emit_insn(
1239
                        (val << 16) |
1240
                        (rg << 11) |
1241
                        (0 << 6) |
1242
                        (3 << 6) |
1243
                        0x1A,!expand_flag,4);   // ORQ3
1244
        }
1245
}
1246
 
1247
// ----------------------------------------------------------------------------
1248
// ----------------------------------------------------------------------------
1249
static void getSz(int *sz)
1250
{
1251
        if (*inptr=='.')
1252
                inptr++;
1253
    *sz = inptr[0];
1254
    switch(*sz) {
1255
    case 'b': case 'B':
1256
                if (inptr[1] == 'p' || inptr[1] == 'P') {
1257
                        inptr++;
1258
                        *sz = 4;
1259
                }
1260
                else
1261
                        *sz = 0;
1262
                break;
1263
        case 'c': case 'C':
1264
                if (inptr[1] == 'p' || inptr[1] == 'P') {
1265
                        inptr++;
1266
                        *sz = 5;
1267
                }
1268
                else
1269
                        *sz = 1;
1270
                break;
1271
    case 'h': case 'H':
1272
                if (inptr[1] == 'p' || inptr[1] == 'P') {
1273
                        inptr++;
1274
                        *sz = 6;
1275
                }
1276
                else
1277
                        *sz = 2;
1278
                break;
1279
    case 'w': case 'W':
1280
                if (inptr[1] == 'p' || inptr[1] == 'P') {
1281
                        inptr++;
1282
                        *sz = 7;
1283
                }
1284
                else
1285
                        *sz = 3;
1286
                break;
1287
        case 'd': case 'D': *sz = 0x83; break;
1288
        case 'i': case 'I': *sz = 0x43; break;
1289
    default:
1290
             printf("%d bad size.\r\n", lineno);
1291
             *sz = 3;
1292
    }
1293
    inptr += 1;
1294
}
1295
 
1296
// ---------------------------------------------------------------------------
1297
// Get memory aquire and release bits.
1298
// ---------------------------------------------------------------------------
1299
 
1300
static void GetArBits(int64_t *aq, int64_t *rl)
1301
{
1302
        *aq = *rl = 0;
1303
        while (*inptr == '.') {
1304
                inptr++;
1305
                if (inptr[0] != 'a' && inptr[0] != 'A' && inptr[0] != 'r' && inptr[0] != 'R')
1306
                        break;
1307
                if ((inptr[0] == 'a' || inptr[0] == 'A') && (inptr[1] == 'q' || inptr[1] == 'Q')) {
1308
                        inptr += 2;
1309
                        *aq = 1;
1310
                }
1311
                if ((inptr[0] == 'r' || inptr[0] == 'R') && (inptr[1] == 'l' || inptr[1] == 'L')) {
1312
                        inptr += 2;
1313
                        *rl = 1;
1314
                }
1315
        }
1316
}
1317
 
1318
// ---------------------------------------------------------------------------
1319
// addi r1,r2,#1234
1320
//
1321
// A value that is too large has to be loaded into a register then the
1322
// instruction converted to a registered form.
1323
// So
1324
//              addi    r1,r2,#$12345678
1325
// Becomes:
1326
//              ldiq1   r52,#$00123
1327
//              oriq0   r52,#$45678
1328
//              addi    r1,r2,r52
1329
// ---------------------------------------------------------------------------
1330
 
1331
static void process_riop(int64_t opcode6)
1332
{
1333
    int Ra;
1334
    int Rt, Rtp;
1335
    char *p;
1336
    int64_t val;
1337
        int sz = 3;
1338
 
1339
    p = inptr;
1340
        if (*p == '.')
1341
                getSz(&sz);
1342
        Rt = getRegisterX();
1343
    need(',');
1344
    Ra = getRegisterX();
1345
    need(',');
1346
    NextToken();
1347
    val = expr();
1348
        if (opcode6==0x05LL)    { // subi
1349
                val = -val;
1350
                opcode6 = 0x04LL;       // change to addi
1351
        }
1352
        // ADDI
1353
        if (opcode6 == 0x04) {
1354
                if (Ra == Rt) {
1355
                        if (Rt == regSP) {
1356
                                if (val >= -128 && val < 128 && ((val & 7) == 0)) {
1357
                                        emit_insn(
1358
                                                (0 << 12) |
1359
                                                (((val >> 4) & 0x0F) << 8) |
1360
                                                (2 << 6) |
1361
                                                (((val >> 3) & 0x1) << 5) |
1362
                                                regSP, 0, 2);
1363
                                        return;
1364
                                }
1365
                        }
1366
                        else {
1367
                                if (val >= -16 && val < 16) {
1368
                                        emit_insn(
1369
                                                (0 << 12) |
1370
                                                (((val >> 1) & 0x0F) << 8) |
1371
                                                (2 << 6) |
1372
                                                ((val & 0x1) << 5) |
1373
                                                Ra, 0, 2);
1374
                                        return;
1375
                                }
1376
                        }
1377
                }
1378
        }
1379
        // Compress ANDI ?
1380
        if (opcode6 == 0x08 && Ra == Rt && Ra != 0) {
1381
                if (val > -16 && val < 16) {
1382
                        emit_insn(
1383
                                (2 << 12) |
1384
                                (((val >> 4) & 0x0F) << 8) |
1385
                                (2 << 6) |
1386
                                (((val >> 3) & 0x1) << 5) |
1387
                                Rt, 0, 2
1388
                        );
1389
                        return;
1390
                }
1391
        }
1392
        // Compress ORI ?
1393
        if (opcode6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Ra)) >= 0) {
1394
                if (val > -16 && val < 16) {
1395
                        emit_insn(
1396
                                (4 << 12) |
1397
                                (((val >> 1) & 0x0f) << 8) |
1398
                                (2 << 6) |
1399
                                (2 << 4) |
1400
                                ((val & 1) << 3) |
1401
                                Rtp, 0, 2
1402
                        );
1403
                }
1404
                return;
1405
        }
1406
        if (!IsNBit(val, 14)) {
1407
                if (!IsNBit(val, 30)) {
1408
                        Lui34(val, 23);
1409
                        emit_insn(
1410
                                (val << 18) |
1411
                                (23 << 13) |
1412
                                (23 << 8) |
1413
                                (1 << 6) |
1414
                                0x09, !expand_flag, 6   // ORI
1415
                        );
1416
                        emit_insn(
1417
                                (opcode6 << 26LL) |
1418
                                (sz << 23) |            // set size to word size op
1419
                                (Rt << 18) |
1420
                                (23 << 13) |
1421
                                (Ra << 8) |
1422
                                0x02, !expand_flag, 4);
1423
                        return;
1424
                }
1425
                emit_insn(
1426
                        (val << 18LL) |
1427
                        (Rt << 13) |
1428
                        (Ra << 8) |
1429
                        (1 << 6) |
1430
                        opcode6, !expand_flag, 6);
1431
                return;
1432
        }
1433
        emit_insn(
1434
                (val << 18)|(Rt << 13)|(Ra << 8)|opcode6,!expand_flag,4);
1435
}
1436
 
1437
// ---------------------------------------------------------------------------
1438
// slti r1,r2,#1234
1439
//
1440
// A value that is too large has to be loaded into a register then the
1441
// instruction converted to a registered form.
1442
// ---------------------------------------------------------------------------
1443
 
1444
static void process_setiop(int64_t opcode6)
1445
{
1446
    int Ra;
1447
    int Rt;
1448
    char *p;
1449
    int64_t val;
1450
 
1451
    p = inptr;
1452
    Rt = getRegisterX();
1453
    need(',');
1454
    Ra = getRegisterX();
1455
    need(',');
1456
    NextToken();
1457
    val = expr();
1458
        if (!IsNBit(val, 30)) {
1459
                LoadConstant(val, 23);
1460
                switch (opcode6)
1461
                {
1462
                case 0x06:
1463
                case 0x07:
1464
                        emit_insn(
1465
                                (opcode6 << 26) |       // SLT / SLTU
1466
                                (3 << 23) |
1467
                                (Rt << 18) |
1468
                                (23 << 13) |
1469
                                (Ra << 8) |
1470
                                (0 << 6) |
1471
                                0x02, !expand_flag, 4);
1472
                        return;
1473
                case 0x2C:      // SGTI
1474
                        emit_insn(
1475
                                (0x28 << 26) |  // SLE
1476
                                (3 << 23) |
1477
                                (Rt << 18) |
1478
                                (23 << 13) |
1479
                                (Ra << 8) |
1480
                                (0 << 6) |
1481
                                0x02,!expand_flag,4)
1482
                                ;
1483
                        emit_insn(
1484
                                (0x01 << 26) |
1485
                                (3 << 23) |
1486
                                (3 << 18) |             // COM
1487
                                (Rt << 13) |
1488
                                (Ra << 8) |
1489
                                (0 << 6) |
1490
                                0x02,!expand_flag,4
1491
                        );
1492
                        return;
1493
                case 0x1C:      // SGTUI
1494
                        emit_insn(
1495
                                (0x29 << 26) |  // SLEU
1496
                                (3 << 23) |
1497
                                (Rt << 18) |
1498
                                (23 << 13) |
1499
                                (Ra << 8) |
1500
                                (0 << 6) |
1501
                                0x02, !expand_flag, 4)
1502
                                ;
1503
                        emit_insn(
1504
                                (0x01 << 26) |
1505
                                (3 << 23) |
1506
                                (3 << 18) |             // COM
1507
                                (Rt << 13) |
1508
                                (Ra << 8) |
1509
                                (0 << 6) |
1510
                                0x02, !expand_flag, 4
1511
                        );
1512
                        return;
1513
                }
1514
                printf("Illegal set immediate instruction %d.", lineno);
1515
                return;
1516
        }
1517
        if (!IsNBit(val, 14)) {
1518
                emit_insn(
1519
                        (val << 18) |
1520
                        (Rt << 13) | (Ra << 8) |
1521
                        (1 << 6) |
1522
                        opcode6, !expand_flag,6);
1523
                return;
1524
        }
1525
        emit_insn(
1526
                (val << 18)|
1527
                (Rt << 13)|
1528
                (Ra << 8)|
1529
                opcode6,!expand_flag,4);
1530
}
1531
 
1532
static void process_setop(int64_t opcode6)
1533
{
1534
        int Ra, Rb, Rt;
1535
        char *p;
1536
        int sz = 3;
1537
 
1538
        p = inptr;
1539
        if (*p == '.')
1540
                getSz(&sz);
1541
        sz &= 7;
1542
        Rt = getRegisterX();
1543
        need(',');
1544
        Ra = getRegisterX();
1545
        need(',');
1546
        NextToken();
1547
        Rb = getRegisterX();
1548
        if (Rb == -1) {
1549
                inptr = p;
1550
                process_setiop(opcode6);
1551
                return;
1552
        }
1553
        switch (opcode6)
1554
        {
1555
        case -6:        // SGE = !SLT
1556
        case -7:        // SGEU = !SLTU
1557
                emit_insn(
1558
                        (-opcode6 << 26) |
1559
                        (sz << 23) |
1560
                        (Rt << 18) |
1561
                        (Rb << 13) |
1562
                        (Ra << 8) |
1563
                        (0 << 6) |
1564
                        0x02, !expand_flag, 4
1565
                );
1566
                emit_insn(
1567
                        (1 << 26) |
1568
                        (sz << 23) |
1569
                        (3 << 18) |     // COM
1570
                        (Rt << 13) |
1571
                        (Ra << 8) |
1572
                        (0 << 6) |
1573
                        0x02, !expand_flag, 4
1574
                );
1575
                return;
1576
        case -0x2C:     // SGT = !SLE
1577
                emit_insn(
1578
                        (0x28 << 26) |
1579
                        (sz << 23) |
1580
                        (Rt << 18) |
1581
                        (Rb << 13) |
1582
                        (Ra << 8) |
1583
                        (0 << 6) |
1584
                        0x02, !expand_flag, 4
1585
                );
1586
                emit_insn(
1587
                        (1 << 26) |
1588
                        (sz << 23) |
1589
                        (3 << 18) |     // COM
1590
                        (Rt << 13) |
1591
                        (Ra << 8) |
1592
                        (0 << 6) |
1593
                        0x02, !expand_flag, 4
1594
                );
1595
                return;
1596
        case -0x1C:     // SGTU = !SLEU
1597
                emit_insn(
1598
                        (0x29 << 26) |
1599
                        (sz << 23) |
1600
                        (Rt << 18) |
1601
                        (Rb << 13) |
1602
                        (Ra << 8) |
1603
                        (0 << 6) |
1604
                        0x02, !expand_flag, 4
1605
                );
1606
                emit_insn(
1607
                        (1 << 26) |
1608
                        (sz << 23) |
1609
                        (3 << 18) |     // COM
1610
                        (Rt << 13) |
1611
                        (Ra << 8) |
1612
                        (0 << 6) |
1613
                        0x02, !expand_flag, 4
1614
                );
1615
                return;
1616
        }
1617
        emit_insn(
1618
                (opcode6 << 26) |
1619
                (sz << 23) |
1620
                (Rt << 18) |
1621
                (Rb << 13) |
1622
                (Ra << 8) |
1623
                (0 << 6) |
1624
                0x02, !expand_flag, 4
1625
        );
1626
}
1627
 
1628
// ---------------------------------------------------------------------------
1629
// add r1,r2,r3
1630
// ---------------------------------------------------------------------------
1631
 
1632
static void process_rrop(int64_t funct6)
1633
{
1634
    int Ra,Rb,Rt,Rbp,Rtp;
1635
    char *p;
1636
        int sz = 3;
1637
 
1638
    p = inptr;
1639
        if (*p=='.')
1640
                getSz(&sz);
1641
    Rt = getRegisterX();
1642
    need(',');
1643
    Ra = getRegisterX();
1644
    need(',');
1645
    NextToken();
1646
    if (token=='#') {
1647
        inptr = p;
1648
        process_riop(funct6);
1649
        return;
1650
    }
1651
    prevToken();
1652
    Rb = getRegisterX();
1653
        // Compress ADD
1654
        if (funct6 == 0x04 && Ra == Rt) {
1655
                emit_insn(
1656
                        (1 << 12) |
1657
                        (((Ra >> 1) & 0xF) << 8) |
1658
                        (3 << 6) |
1659
                        ((Ra & 1) << 5) |
1660
                        (Rt),
1661
                        0,2
1662
                );
1663
                return;
1664
        }
1665
        // Compress SUB
1666
        if (funct6 == 0x05 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1667
                emit_insn(
1668
                        (4 << 12) |
1669
                        (0 << 10) |
1670
                        (((Rbp >> 1) & 0x3) << 8) |
1671
                        (2 << 6) |
1672
                        (3 << 4) |
1673
                        ((Rbp & 1) << 3) |
1674
                        (Rtp),
1675
                        0, 2
1676
                );
1677
                return;
1678
        }
1679
        // Compress AND
1680
        if (funct6 == 0x08 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1681
                emit_insn(
1682
                        (4 << 12) |
1683
                        (1 << 10) |
1684
                        (((Rbp >> 1) & 0x3) << 8) |
1685
                        (2 << 6) |
1686
                        (3 << 4) |
1687
                        ((Rbp & 1) << 3) |
1688
                        (Rtp),
1689
                        0, 2
1690
                );
1691
                return;
1692
        }
1693
        // Compress OR
1694
        if (funct6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1695
                emit_insn(
1696
                        (4 << 12) |
1697
                        (2 << 10) |
1698
                        (((Rbp >> 1) & 0x3) << 8) |
1699
                        (2 << 6) |
1700
                        (3 << 4) |
1701
                        ((Rbp & 1) << 3) |
1702
                        (Rtp),
1703
                        0, 2
1704
                );
1705
                return;
1706
        }
1707
        // Compress XOR
1708
        if (funct6 == 0x0A && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1709
                emit_insn(
1710
                        (4 << 12) |
1711
                        (3 << 10) |
1712
                        (((Rbp >> 1) & 0x3) << 8) |
1713
                        (2 << 6) |
1714
                        (3 << 4) |
1715
                        ((Rbp & 1) << 3) |
1716
                        (Rtp),
1717
                        0, 2
1718
                );
1719
                return;
1720
        }
1721
        //prevToken();
1722
        if (funct6==0x2E || funct6==0x2C || funct6==0x2D) {
1723
                funct6 += 0x10; // change to divmod
1724
            emit_insn((funct6<<26LL)||(1<<23)||(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
1725
                return;
1726
        }
1727
        else if (funct6==0x3C || funct6==0x3D || funct6==0x3E) {
1728
            emit_insn((funct6<<26LL)||(0<<23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
1729
                return;
1730
        }
1731
    emit_insn((funct6<<26LL)|(sz << 23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
1732
}
1733
 
1734
// ---------------------------------------------------------------------------
1735
// or r1,r2,r3,r4
1736
// ---------------------------------------------------------------------------
1737
 
1738
static void process_rrrop(int64_t funct6)
1739
{
1740
        int Ra, Rb, Rc = 0, Rt;
1741
        char *p;
1742
        int sz = 3;
1743
 
1744
        p = inptr;
1745
        if (*p == '.')
1746
                getSz(&sz);
1747
        Rt = getRegisterX();
1748
        need(',');
1749
        Ra = getRegisterX();
1750
        need(',');
1751
        NextToken();
1752
        if (token == '#') {
1753
                inptr = p;
1754
                process_riop(funct6);
1755
                return;
1756
        }
1757
        prevToken();
1758
        Rb = getRegisterX();
1759
        if (token == ',') {
1760
                NextToken();
1761
                Rc = getRegisterX();
1762
        }
1763
        else {
1764
                switch (funct6) {
1765
                case 0x08:      Rc = Rb; break; // and
1766
                case 0x09:      Rc = 0; break;   // or
1767
                case 0x0A:      Rc = 0; break;   // xor
1768
                }
1769
        }
1770
        emit_insn((funct6 << 34LL) | (sz << 24) | (Rt << 27) | (Rc << 18) | (Rb << 12) | (Ra << 6) | 0x42, !expand_flag, 5);
1771
}
1772
 
1773
static void process_cmove(int64_t funct6)
1774
{
1775
        int Ra, Rb, Rc = 0, Rt;
1776
        char *p;
1777
        int sz = 3;
1778
        int64_t val;
1779
 
1780
        p = inptr;
1781
        Rt = getRegisterX();
1782
        need(',');
1783
        Ra = getRegisterX();
1784
        need(',');
1785
        Rb = getRegisterX();
1786
        need(',');
1787
        NextToken();
1788
        if (token == '#') {
1789
                val = expr();
1790
                emit_insn(
1791
                        (funct6 << 42LL) |
1792
                        (1LL << 41LL) |
1793
                        (((val >> 5) & 0x7ff) << 28) |
1794
                        (Rt << 23) |
1795
                        ((val & 0x1f) << 18) |
1796
                        (Rb << 13) |
1797
                        (Ra << 8) |
1798
                        0x02, !expand_flag, 6);
1799
                return;
1800
        }
1801
        prevToken();
1802
        Rc = getRegisterX();
1803
        emit_insn((funct6 << 42LL) | (Rt << 23) | (Rc << 18) | (Rb << 13) | (Ra << 8) | 0x02, !expand_flag, 6);
1804
}
1805
 
1806
// ---------------------------------------------------------------------------
1807
// jmp main
1808
// jal [r19]
1809
// ---------------------------------------------------------------------------
1810
 
1811
static void process_jal(int64_t oc)
1812
{
1813
    int64_t addr, val;
1814
    int Ra;
1815
    int Rt;
1816
        bool noRt;
1817
        char *p;
1818
 
1819
        noRt = false;
1820
        Ra = 0;
1821
    Rt = 0;
1822
        p = inptr;
1823
    NextToken();
1824
        if (token == '(' || token == '[') {
1825
        j1:
1826
                Ra = getRegisterX();
1827
                if (Ra == -1) {
1828
                        printf("Expecting a register\r\n");
1829
                        return;
1830
                }
1831
                // Simple jmp [Rn]
1832
                else {
1833
                        if (token != ')' && token != ']')
1834
                                printf("Missing close bracket\r\n");
1835
                        emit_insn((Ra << 8) | (Rt << 13) | 0x18, 0, 4);
1836
                        return;
1837
                }
1838
        }
1839
        else
1840
                inptr = p;
1841
    Rt = getRegisterX();
1842
    if (Rt >= 0) {
1843
        need(',');
1844
        NextToken();
1845
        // jal Rt,[Ra]
1846
        if (token=='(' || token=='[')
1847
           goto j1;
1848
    }
1849
    else {
1850
        Rt = 0;
1851
                noRt = true;
1852
        }
1853
        addr = expr();
1854
    // d(Rn)? 
1855
    //NextToken();
1856
    if (token=='(' || token=='[') {
1857
        Ra = getRegisterX();
1858
        if (Ra==-1) {
1859
            printf("Illegal jump address mode.\r\n");
1860
            Ra = 0;
1861
        }
1862
                if (Ra==regSP)  // program counter relative ?
1863
                        addr -= code_address;
1864
        }
1865
        val = addr;
1866
        if (IsNBit(val, 14)) {
1867
                emit_insn(
1868
                        (val << 18) |
1869
                        (Rt << 13) |
1870
                        (Ra << 8) |
1871
                        0x18, !expand_flag, 4);
1872
                return;
1873
        }
1874
        if (IsNBit(val, 30)) {
1875
                emit_insn(
1876
                        (val << 18) |
1877
                        (Rt << 13) |
1878
                        (Ra << 8) |
1879
                        (1 << 6) |
1880
                        0x18, !expand_flag, 6);
1881
                return;
1882
        }
1883
 
1884
        {
1885
                LoadConstant(val, 23);
1886
                if (Ra != 0) {
1887
                        // add r23,r23,Ra
1888
                        emit_insn(
1889
                                (0x04LL << 26LL) |
1890
                                (3 << 23) |
1891
                                (23 << 18) |
1892
                                (23 << 13) |
1893
                                (Ra << 8) |
1894
                                0x02, 0, 4
1895
                        );
1896
                        // jal Rt,r23
1897
                        emit_insn(
1898
                                (0 << 18) |
1899
                                (Rt << 12) |
1900
                                (23 << 8) | 0x18, !expand_flag, 4);
1901
                        return;
1902
                }
1903
                emit_insn(
1904
                        (Rt << 12) |
1905
                        (23 << 8) | 0x18, !expand_flag, 4);
1906
                return;
1907
        }
1908
}
1909
 
1910
// ---------------------------------------------------------------------------
1911
// subui r1,r2,#1234
1912
// ---------------------------------------------------------------------------
1913
/*
1914
static void process_riop(int oc)
1915
{
1916
    int Ra;
1917
    int Rt;
1918
    char *p;
1919
    int64_t val;
1920
 
1921
    p = inptr;
1922
    Rt = getRegisterX();
1923
    need(',');
1924
    Ra = getRegisterX();
1925
    need(',');
1926
    NextToken();
1927
    val = expr();
1928
 
1929
   if (lastsym != (SYM *)NULL)
1930
       emitImm16(val,!lastsym->defined);
1931
   else
1932
       emitImm16(val,0);
1933
 
1934
    emitImm16(val,lastsym!=(SYM*)NULL);
1935
    emitAlignedCode(oc);
1936
    if (bGen)
1937
    if (lastsym && !use_gp) {
1938
        if( lastsym->segment < 5)
1939
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
1940
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
1941
    }
1942
    emitCode(Ra);
1943
    emitCode(Rt);
1944
    emitCode(val & 255);
1945
    emitCode((val >> 8) & 255);
1946
}
1947
*/
1948
// ---------------------------------------------------------------------------
1949
// fabs.d r1,r2[,rm]
1950
// ---------------------------------------------------------------------------
1951
 
1952
static void process_fprop(int64_t oc)
1953
{
1954
    int Ra;
1955
    int Rt;
1956
    char *p;
1957
    int fmt;
1958
    int64_t rm;
1959
 
1960
    rm = 0;
1961
    fmt = GetFPSize();
1962
    p = inptr;
1963
    Rt = getFPRegister();
1964
    need(',');
1965
    Ra = getFPRegister();
1966
    if (token==',')
1967
       rm = getFPRoundMode();
1968
//    prevToken();
1969
        if (fmt != 2) {
1970
                emit_insn(
1971
                        (oc << 42LL) |
1972
                        ((int64_t)fmt << 31LL) |
1973
                        (rm << 28) |
1974
                        (Rt << 23) |
1975
                        (0 << 13) |
1976
                        (Ra << 8) |
1977
                        0x0F, !expand_flag, 6
1978
                );
1979
                return;
1980
        }
1981
    emit_insn(
1982
                        (oc << 26LL) |
1983
                        (rm << 23) |
1984
                        (Rt << 18)|
1985
                        (0 << 13)|
1986
                        (Ra << 8) |
1987
                        0x0F,!expand_flag,4
1988
                        );
1989
}
1990
 
1991
// ---------------------------------------------------------------------------
1992
// fabs.d r1,r2[,rm]
1993
// ---------------------------------------------------------------------------
1994
 
1995
static void process_itof(int64_t oc)
1996
{
1997
    int Ra;
1998
    int Rt;
1999
    char *p;
2000
    int fmt;
2001
    int64_t rm;
2002
 
2003
    rm = 0;
2004
    fmt = GetFPSize();
2005
    p = inptr;
2006
    Rt = getFPRegister();
2007
    need(',');
2008
    Ra = getRegisterX();
2009
    if (token==',')
2010
       rm = getFPRoundMode();
2011
//    prevToken();
2012
        if (fmt != 2) {
2013
                emit_insn(
2014
                        (oc << 42LL) |
2015
                        (fmt << 31LL) |
2016
                        (rm << 28LL) |
2017
                        (Rt << 23) |
2018
                        (0 << 13) |
2019
                        (Ra << 8) |
2020
                        0x0F, !expand_flag, 6
2021
                );
2022
                return;
2023
        }
2024
    emit_insn(
2025
                        (oc << 26LL) |
2026
                        (rm << 23LL)|
2027
                        (Rt << 18)|
2028
                        (0 << 13)|
2029
                        (Ra << 8) |
2030
                        0x0F,!expand_flag,4
2031
                        );
2032
}
2033
 
2034
static void process_ftoi(int64_t oc)
2035
{
2036
        int Ra;
2037
        int Rt;
2038
        char *p;
2039
        int fmt;
2040
        int64_t rm;
2041
 
2042
        rm = 0;
2043
        fmt = GetFPSize();
2044
        p = inptr;
2045
        Rt = getRegisterX();
2046
        need(',');
2047
        Ra = getFPRegister();
2048
        if (token == ',')
2049
                rm = getFPRoundMode();
2050
        //    prevToken();
2051
        if (fmt != 2) {
2052
                emit_insn(
2053
                        (oc << 42LL) |
2054
                        (fmt << 31LL) |
2055
                        (rm << 28LL) |
2056
                        (Rt << 23) |
2057
                        (0 << 13) |
2058
                        (Ra << 8) |
2059
                        0x0F, !expand_flag, 6
2060
                );
2061
                return;
2062
        }
2063
        emit_insn(
2064
                (oc << 26LL) |
2065
                (rm << 23LL) |
2066
                (Rt << 18) |
2067
                (0 << 13) |
2068
                (Ra << 8) |
2069
                0x0F, !expand_flag, 4
2070
        );
2071
}
2072
 
2073
// ---------------------------------------------------------------------------
2074
// fadd.d r1,r2,r12[,rm]
2075
// fcmp.d r1,r3,r10[,rm]
2076
// ---------------------------------------------------------------------------
2077
 
2078
static void process_fprrop(int64_t oc)
2079
{
2080
    int Ra;
2081
    int Rb;
2082
    int Rt;
2083
    char *p;
2084
    int fmt;
2085
    int64_t rm;
2086
 
2087
    rm = 0;
2088
    fmt = GetFPSize();
2089
    p = inptr;
2090
    if (oc==0x01)        // fcmp
2091
        Rt = getRegisterX();
2092
    else
2093
        Rt = getFPRegister();
2094
    need(',');
2095
    Ra = getFPRegister();
2096
    need(',');
2097
    Rb = getFPRegister();
2098
    if (token==',')
2099
       rm = getFPRoundMode();
2100
//    prevToken();
2101
        if (fmt != 2) {
2102
                emit_insn(
2103
                        (oc << 42LL) |
2104
                        ((int64_t)fmt << 31LL) |
2105
                        (rm << 28LL) |
2106
                        (Rt << 23) |
2107
                        (Rb << 13) |
2108
                        (Ra << 8) |
2109
                        (1 << 6) |
2110
                        0x0F, !expand_flag, 6
2111
                );
2112
                return;
2113
        }
2114
 
2115
    emit_insn(
2116
                        (oc << 26LL)|
2117
                        (rm << 23LL)|
2118
                        (Rt << 18)|
2119
                        (Rb << 13)|
2120
                        (Ra << 8) |
2121
                        0x0F,!expand_flag,4
2122
                        );
2123
}
2124
 
2125
// ---------------------------------------------------------------------------
2126
// fcx r0,#2
2127
// fdx r1,#0
2128
// ---------------------------------------------------------------------------
2129
 
2130
static void process_fpstat(int oc)
2131
{
2132
    int Ra;
2133
    int64_t bits;
2134
    char *p;
2135
 
2136
    p = inptr;
2137
    bits = 0;
2138
    Ra = getRegisterX();
2139
    if (token==',') {
2140
       NextToken();
2141
       bits = expr();
2142
    }
2143
    prevToken();
2144
        emit_insn(
2145
                ((bits & 0x3F) << 18) |
2146
                (oc << 12) |
2147
                (Ra << 6) |
2148
                0x36,!expand_flag,5
2149
                );
2150
}
2151
 
2152
// ---------------------------------------------------------------------------
2153
// not r3,r3
2154
// ---------------------------------------------------------------------------
2155
 
2156
static void process_rop(int oc)
2157
{
2158
    int Ra;
2159
    int Rt;
2160
        int sz = 3;
2161
        char *p;
2162
 
2163
        p = inptr;
2164
        if (*p == '.')
2165
                getSz(&sz);
2166
        Rt = getRegisterX();
2167
    need(',');
2168
    Ra = getRegisterX();
2169
        emit_insn(
2170
                (1LL << 26LL) |
2171
                (sz << 23) |
2172
                (oc << 18) |
2173
                (Rt << 13) |
2174
                (Ra << 8) |
2175
                0x02,!expand_flag,4
2176
                );
2177
        prevToken();
2178
}
2179
 
2180
// ---------------------------------------------------------------------------
2181
// beqi r2,#123,label
2182
// ---------------------------------------------------------------------------
2183
 
2184
static void process_beqi(int64_t opcode6, int64_t opcode3)
2185
{
2186
    int Ra, pred = 0;
2187
    int64_t val, imm;
2188
    int64_t disp;
2189
        int sz = 3;
2190
        char *p;
2191
        bool isn48 = false;
2192
 
2193
        p = inptr;
2194
        if (*p == '.')
2195
                getSz(&sz);
2196
 
2197
    Ra = getRegisterX();
2198
    need(',');
2199
    NextToken();
2200
    imm = expr();
2201
        need(',');
2202
        NextToken();
2203
        val = expr();
2204
        disp = val - (code_address + 4LL);
2205
        if (!IsNBit(disp, 11)) {
2206
                disp = val - (code_address + 6LL);
2207
                isn48 = true;
2208
        }
2209
        disp >>= 1;
2210
        if (!IsNBit(imm,8)) {
2211
                //printf("Branch immediate too large: %d %I64d", lineno, imm);
2212
                isn48 = false;
2213
                LoadConstant(imm, 23);
2214
                disp = val - (code_address + 4LL);
2215
                if (!IsNBit(disp, 11)) {
2216
                        disp = val - (code_address + 6LL);
2217
                        isn48 = true;
2218
                }
2219
                disp >>= 1;
2220
                emit_insn(
2221
                        (disp << 21LL) |
2222
                        (0x00 << 18) |          // BEQ
2223
                        (23 << 13) |
2224
                        (Ra << 8) |
2225
                        0x30, !expand_flag, isn48 ? 6 : 4
2226
                );
2227
                return;
2228
        }
2229
        emit_insn((disp << 21LL) |
2230
                ((imm & 0xFF) << 13) |
2231
                (Ra << 8) |
2232
                opcode6,!expand_flag,isn48 ? 6 : 4
2233
        );
2234
    return;
2235
}
2236
 
2237
 
2238
// ---------------------------------------------------------------------------
2239
// beq r1,r2,label
2240
// bne r2,r3,r4
2241
//
2242
// When opcode4 is negative it indicates to swap the a and b registers. This
2243
// allows source code to use alternate forms of branch conditions.
2244
// ---------------------------------------------------------------------------
2245
 
2246
static void process_bcc(int opcode6, int opcode4)
2247
{
2248
    int Ra, Rb, pred;
2249
        int fmt;
2250
    int64_t val;
2251
    int64_t disp;
2252
        char *p1;
2253
        bool ins48 = false;
2254
 
2255
    fmt = GetFPSize();
2256
        pred = 0;
2257
        p1 = inptr;
2258
    Ra = getRegisterX();
2259
    need(',');
2260
    Rb = getRegisterX();
2261
    need(',');
2262
        NextToken();
2263
        if (token=='#' && opcode4==0) {
2264
                inptr = p1;
2265
                process_beqi(0x32,0);
2266
                return;
2267
        }
2268
        val = expr();
2269
        disp = val - (code_address + 4);
2270
        if (!IsNBit(disp, 12)) {
2271
                disp = val - (code_address + 6);
2272
                ins48 = true;
2273
        }
2274
        disp >>= 1;
2275
        // Check for compressed bnez
2276
        if (opcode4 == 1 && Rb == 0 && IsNBit(disp+1,7)) {       // disp+1 to account for 2 byte instruction
2277
                disp++;
2278
                emit_insn(
2279
                        (3 << 14) |
2280
                        (((disp >> 1) & 0x3f) << 8) |
2281
                        (2 << 6) |
2282
                        ((disp & 1) << 5) |
2283
                        Ra,0,2
2284
                );
2285
                return;
2286
        }
2287
        // compressed beqz
2288
        if (opcode4 == 0 && Rb == 0 && IsNBit(disp+1, 7)) {
2289
                disp++;
2290
                emit_insn(
2291
                        (2 << 14) |
2292
                        (((disp >> 1) & 0x3f) << 8) |
2293
                        (2 << 6) |
2294
                        ((disp & 1) << 5) |
2295
                        Ra, 0, 2
2296
                );
2297
                return;
2298
        }
2299
        if (opcode4 < 0) {
2300
                opcode4 = -opcode4;
2301
                emit_insn((disp << 21LL) |
2302
                        (opcode4 << 18) |
2303
                        (Ra << 13) |
2304
                        (Rb << 8) |
2305
                        (ins48 << 6) |
2306
                        opcode6,!expand_flag,ins48 ? 6 : 4
2307
                );
2308
                return;
2309
        }
2310
        emit_insn((disp << 21LL) |
2311
                (opcode4 << 18) |
2312
                (Rb << 13) |
2313
                (Ra << 8) |
2314
                (ins48 << 6) |
2315
                opcode6, !expand_flag, ins48 ? 6 : 4
2316
        );
2317
        return;
2318
}
2319
 
2320
// ---------------------------------------------------------------------------
2321
// dbnz r1,label
2322
//
2323
// ---------------------------------------------------------------------------
2324
 
2325
static void process_dbnz(int opcode6, int opcode3)
2326
{
2327
    int Ra, Rc, pred;
2328
    int64_t val;
2329
    int64_t disp;
2330
        char *p1;
2331
        int sz = 3;
2332
        char *p;
2333
 
2334
        p = inptr;
2335
        if (*p == '.')
2336
                getSz(&sz);
2337
 
2338
        pred = 3;               // default: statically predict as always taken
2339
        p1 = inptr;
2340
    Ra = getRegisterX();
2341
    need(',');
2342
        p = inptr;
2343
        Rc = getRegisterX();
2344
        if (Rc==-1) {
2345
                inptr = p;
2346
            NextToken();
2347
                val = expr();
2348
                disp = val - (code_address + 4LL);
2349
                disp >>= 1;
2350
                emit_insn(
2351
                        (disp << 21LL) |
2352
                        ((opcode3 & 3) << 19) |
2353
                        (0 << 13) |
2354
                        (Ra << 8) |
2355
                        opcode6,!expand_flag,4
2356
                );
2357
                return;
2358
        }
2359
        printf("dbnz: target must be a label %d.\n", lineno);
2360
        emit_insn(
2361
                (opcode3 << 19) |
2362
                (0 << 13) |
2363
                (Ra << 8) |
2364
                opcode6,!expand_flag,4
2365
        );
2366
}
2367
 
2368
// ---------------------------------------------------------------------------
2369
// ibne r1,r2,label
2370
//
2371
// ---------------------------------------------------------------------------
2372
 
2373
static void process_ibne(int opcode6, int opcode3)
2374
{
2375
    int Ra, Rb, Rc, pred;
2376
    int64_t val;
2377
    int64_t disp;
2378
        char *p1;
2379
        int sz = 3;
2380
        char *p;
2381
        bool isn48 = false;
2382
 
2383
        p = inptr;
2384
        if (*p == '.')
2385
                getSz(&sz);
2386
 
2387
        pred = 3;               // default: statically predict as always taken
2388
        p1 = inptr;
2389
    Ra = getRegisterX();
2390
    need(',');
2391
    Rb = getRegisterX();
2392
    need(',');
2393
        p = inptr;
2394
        Rc = getRegisterX();
2395
        if (Rc==-1) {
2396
                inptr = p;
2397
            NextToken();
2398
                val = expr();
2399
                disp = val - (code_address + 4LL);
2400
                disp >>= 1;
2401
                if (!IsNBit(disp, 11)) {
2402
                        isn48 = true;
2403
                        disp = val - (code_address + 6LL);
2404
                        disp >>= 1;
2405
                }
2406
            emit_insn((disp << 21LL) |
2407
                        ((opcode3 & 3) << 19) |
2408
                        (Rb << 13) |
2409
                        (Ra << 8) |
2410
                        opcode6,!expand_flag,isn48 ? 6 : 4
2411
                );
2412
                return;
2413
        }
2414
        printf("ibne: target must be a label %d.\n", lineno);
2415
        emit_insn(
2416
                (opcode3 << 19) |
2417
                (Rb << 13) |
2418
                (Ra << 8) |
2419
                0x03,!expand_flag,4
2420
        );
2421
}
2422
 
2423
// ---------------------------------------------------------------------------
2424
// bfextu r1,r2,#1,#63
2425
// ---------------------------------------------------------------------------
2426
 
2427
static void process_bitfield(int64_t oc)
2428
{
2429
    int Ra;
2430
    int Rt;
2431
    int64_t mb;
2432
    int64_t me;
2433
        int64_t val;
2434
        int sz = 3;
2435
        char *p;
2436
 
2437
        p = inptr;
2438
        if (*p == '.')
2439
                getSz(&sz);
2440
 
2441
    Rt = getRegisterX();
2442
    need(',');
2443
        if (oc==4) {
2444
                NextToken();
2445
                val = expr();
2446
                Ra = 0;
2447
        }
2448
        else {
2449
                val = 0LL;
2450
                Ra = getRegisterX();
2451
        }
2452
    need(',');
2453
    NextToken();
2454
    mb = expr();
2455
    need(',');
2456
    NextToken();
2457
    me = expr();
2458
        emit_insn(
2459
                (oc << 34LL) |
2460
                (me << 27LL) |
2461
                (sz << 24) |
2462
                (mb << 18) |
2463
                (Rt << 12) |
2464
                ((Ra|(val & 0x3f)) << 6) |
2465
                0x22,!expand_flag,5
2466
        );
2467
}
2468
 
2469
 
2470
// ---------------------------------------------------------------------------
2471
// bra label
2472
// ---------------------------------------------------------------------------
2473
 
2474
static void process_bra(int oc)
2475
{
2476
    int Ra = 0, Rb = 0;
2477
    int64_t val;
2478
    int64_t disp;
2479
        bool ins48 = false;
2480
 
2481
    NextToken();
2482
    val = expr();
2483
    disp = val - (code_address + 4LL);
2484
        if (!IsNBit(disp, 12)) {
2485
                disp = val - (code_address + 6LL);
2486
                ins48 = true;
2487
        }
2488
        disp >>= 1;
2489
        if (disp+1 > -512 && disp+1 < 512) {    // disp+1 accounts for instruction size of 2 not 4
2490
                disp++;
2491
                emit_insn(
2492
                        (7 << 12) |
2493
                        (((disp >> 6) & 0xf) << 8) |
2494
                        (2 << 6) |
2495
                        (disp & 0x3f), 0, 2
2496
                );
2497
                return;
2498
        }
2499
        emit_insn((disp << 21) |
2500
                (0 << 18) |      // BEQ
2501
        (0 << 13) |
2502
        (0 << 8) |
2503
        0x30,!expand_flag,4
2504
    );
2505
}
2506
 
2507
// ----------------------------------------------------------------------------
2508
// chk r1,r2,r3,label
2509
// ----------------------------------------------------------------------------
2510
 
2511
static void process_chk(int opcode6)
2512
{
2513
        int Ra;
2514
        int Rb;
2515
        int Rc;
2516
        int64_t val, disp;
2517
 
2518
        Ra = getRegisterX();
2519
        need(',');
2520
        Rb = getRegisterX();
2521
        need(',');
2522
        Rc = getRegisterX();
2523
        need(',');
2524
        NextToken();
2525
        val = expr();
2526
    disp = val - code_address;
2527
        emit_insn(((disp >> 3) & 0x3FF) << 22 |
2528
                (Rc << 16) |
2529
                (Rb << 11) |
2530
                (Ra << 6) |
2531
                ((disp >> 2) & 1) |
2532
                opcode6,!expand_flag,4
2533
        );
2534
}
2535
 
2536
 
2537
static void process_chki(int opcode6)
2538
{
2539
        int Ra;
2540
        int Rb;
2541
        int64_t val, disp;
2542
 
2543
        Ra = getRegisterX();
2544
        need(',');
2545
        Rb = getRegisterX();
2546
        need(',');
2547
        NextToken();
2548
        val = expr();
2549
    disp = val - code_address;
2550
        if (val < LB16 || val > 32767LL) {
2551
                emit_insn((0x8000 << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
2552
                emit_insn(val,!expand_flag,2);
2553
                return;
2554
        }
2555
        emit_insn(((val & 0xFFFF) << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
2556
}
2557
 
2558
 
2559
// ---------------------------------------------------------------------------
2560
// fbeq.q fp1,fp0,label
2561
// ---------------------------------------------------------------------------
2562
 
2563
static void process_fbcc(int64_t opcode3)
2564
{
2565
    int Ra, Rb;
2566
    int64_t val;
2567
    int64_t disp;
2568
        int sz;
2569
        bool ins48 = false;
2570
 
2571
    sz = GetFPSize();
2572
    Ra = getFPRegister();
2573
    need(',');
2574
    Rb = getFPRegister();
2575
    need(',');
2576
    NextToken();
2577
 
2578
    val = expr();
2579
        disp = val - (code_address + 4);
2580
        if (!IsNBit(disp, 12)) {
2581
                disp = val - (code_address + 6);
2582
                ins48 = true;
2583
        }
2584
        disp >>= 1;
2585
        emit_insn(
2586
                (disp << 21LL) |
2587
                (opcode3 << 18) |
2588
                (Rb << 13) |
2589
                (Ra << 8) |
2590
                ((ins48 ? 1 : 0) << 6) |
2591
                0x05, !expand_flag, ins48 ? 6 : 4
2592
    );
2593
}
2594
 
2595
// ---------------------------------------------------------------------------
2596
// ---------------------------------------------------------------------------
2597
 
2598
static void process_call(int opcode)
2599
{
2600
        int64_t val;
2601
        int Ra = 0;
2602
 
2603
    NextToken();
2604
        if (token == '[')
2605
                val = 0;
2606
        else
2607
                val = expr();
2608
        if (token=='[') {
2609
                Ra = getRegisterX();
2610
                need(']');
2611
                if (Ra==31) {
2612
                        val -= code_address;
2613
                }
2614
        }
2615
        if (val==0) {
2616
                if (opcode==0x28)       // JMP [Ra]
2617
                        // jal r0,[Ra]
2618
                        emit_insn(
2619
                                (Ra << 6) |
2620
                                0x18,!expand_flag,4
2621
                        );
2622
                else
2623
                        // jal lr,[Ra]  - call [Ra]
2624
                        //emit_insn(
2625
                        //      (29 << 13) |
2626
                        //      (Ra << 8) |
2627
                        //      0x18,!expand_flag,4
2628
                        //);
2629
                        emit_insn(
2630
                                (2 << 12) |
2631
                                (((29 >> 1) & 0xf) << 8) |
2632
                                (3 << 6) |
2633
                                ((29 & 1) << 5) |
2634
                                Ra,0,2
2635
                        );
2636
                return;
2637
        }
2638
        if (code_bits > 27 && !IsNBit(val,40)) {
2639
                LoadConstant(val,23);
2640
                if (Ra!=0) {
2641
                        // add r23,r23,Ra
2642
                        emit_insn(
2643
                                (0x04 << 26) |
2644
                                (23 << 18) |
2645
                                (23 << 13) |
2646
                                (Ra << 8) |
2647
                                0x02,!expand_flag,4
2648
                                );
2649
                }
2650
                if (opcode==0x28)       // JMP
2651
                        // jal r0,[r23]
2652
                        emit_insn(
2653
                                (23 << 8) |
2654
                                0x18,!expand_flag,4
2655
                                );
2656
                else
2657
                        // jal lr,[r23] - call [r23]
2658
                        emit_insn(
2659
                                (29 << 13) |
2660
                                (23 << 8) |
2661
                                0x18,!expand_flag,4
2662
                                );
2663
                return;
2664
        }
2665
        if (!IsNBit(val, 24)) {
2666
                emit_insn(
2667
                        ((((val >> 1) & 0xFFFFFFFFFFLL)) << 8) |
2668
                        (1 << 6) |
2669
                        opcode, !expand_flag, 4
2670
                );
2671
                return;
2672
        }
2673
        emit_insn(
2674
                ((((val >> 1) & 0xFFFFFFLL)) << 8) |
2675
                opcode,!expand_flag,4
2676
                );
2677
}
2678
 
2679
static void process_iret(int op)
2680
{
2681
        int64_t val = 0;
2682
 
2683
    NextToken();
2684
        if (token=='#') {
2685
                val = expr();
2686
        }
2687
        emit_insn(
2688
                ((val & 0x3F) << 18) |
2689
                (0 << 12) |
2690
                (0 << 6) |
2691
                op,!expand_flag,5
2692
        );
2693
}
2694
 
2695
static void process_ret()
2696
{
2697
        int64_t val = 0;
2698
        bool ins48 = false;
2699
 
2700
    NextToken();
2701
        if (token=='#') {
2702
                val = expr();
2703
        }
2704
        // Compress ?
2705
        if (val >= 0 && val < 256) {
2706
                emit_insn(
2707
                        (2 << 12) |
2708
                        (((val >> 4) & 0x0F) << 8) |
2709
                        (2 << 7) |
2710
                        (((val >> 3) & 1) << 5),
2711
                        0, 2
2712
                );
2713
                return;
2714
        }
2715
        // If too large a constant, do the SP adjusment directly.
2716
        if (!IsNBit(val,30)) {
2717
                LoadConstant(val,23);
2718
                // add.w r63,r63,r23
2719
                emit_insn(
2720
                        (0x04LL << 26LL) |
2721
                        (3 << 23) |
2722
                        (regSP << 18) |
2723
                        (23 << 13) |
2724
                        (regSP << 8) |
2725
                        0x02,!expand_flag,4
2726
                        );
2727
                val = 0;
2728
        }
2729
        ins48 = !IsNBit(val, 14);
2730
        emit_insn(
2731
                (val << 18LL) |
2732
                (regLR << 13) |
2733
                (regSP << 8) |
2734
                (ins48 << 6) |
2735
                0x29,!expand_flag, ins48 ? 6 : 4
2736
        );
2737
}
2738
 
2739
// ----------------------------------------------------------------------------
2740
// inc -8[bp],#1
2741
// ----------------------------------------------------------------------------
2742
 
2743
static void process_inc(int64_t oc)
2744
{
2745
    int Ra;
2746
    int Rb;
2747
        int Sc;
2748
    int64_t incamt;
2749
    int64_t disp;
2750
    char *p;
2751
    int fixup = 5;
2752
    int neg = 0;
2753
 
2754
        if (oc == 0x25) neg = 1;
2755
        NextToken();
2756
    p = inptr;
2757
    mem_operand(&disp, &Ra, &Rb, &Sc);
2758
    incamt = 1;
2759
        if (token==']')
2760
       NextToken();
2761
    if (token==',') {
2762
        NextToken();
2763
        incamt = expr();
2764
        prevToken();
2765
    }
2766
        if (neg) incamt = -incamt;
2767
        if (Rb >= 0) {
2768
       if (disp != 0)
2769
           printf("displacement not allowed with indexed addressing.\r\n");
2770
       oc = 0x1A;  // INCX
2771
           // ToDo: fix this
2772
       emit_insn(
2773
                   (oc << 26LL) |
2774
                   (0 << 23) |           // Sc = 0
2775
                   (incamt << 18) |
2776
                   (23 << 13) |
2777
                   (Ra << 8) |
2778
                   0x16, !expand_flag, 4
2779
           );
2780
       return;
2781
    }
2782
    oc = 0x1A;        // INC
2783
    if (Ra < 0) Ra = 0;
2784
        incamt &= 31;
2785
        if (!IsNBit(disp, 30)) {
2786
                LoadConstant(disp, 23);
2787
                // Change to indexed addressing
2788
                emit_insn(
2789
                        (oc << 26LL) |
2790
                        (0 << 23) |              // Sc = 0
2791
                        (incamt << 18) |
2792
                        (23 << 13) |
2793
                        (Ra << 8) |
2794
                        0x16, !expand_flag, 4);
2795
                ScanToEOL();
2796
                return;
2797
        }
2798
        if (!IsNBit(disp, 14)) {
2799
                emit_insn(
2800
                        (disp << 18LL) |
2801
                        (incamt << 13) |
2802
                        (Ra << 8) |
2803
                        (1 << 6) |
2804
                        oc, !expand_flag, 6);
2805
                ScanToEOL();
2806
                return;
2807
        }
2808
        emit_insn(
2809
                (disp << 18LL) |
2810
                (incamt << 13) |
2811
                (Ra << 8) |
2812
                oc, !expand_flag, 4);
2813
        ScanToEOL();
2814
}
2815
 
2816
// ---------------------------------------------------------------------------
2817
// ---------------------------------------------------------------------------
2818
 
2819
static void process_brk()
2820
{
2821
        int64_t val;
2822
        int inc = 1;
2823
        int Ra = -1;
2824
 
2825
        Ra = getRegisterX();
2826
        if (Ra == -1) {
2827
                NextToken();
2828
                val = expr();
2829
                NextToken();
2830
                if (token == ',') {
2831
                        inc = (int)expr();
2832
                }
2833
                else
2834
                        prevToken();
2835
                emit_insn(
2836
                        ((inc & 0x1f) << 19) |
2837
                        ((val & 0x1FFLL) << 6) |
2838
                        0x00, !expand_flag, 5
2839
                );
2840
                return;
2841
        }
2842
        NextToken();
2843
        if (token == ',') {
2844
                inc = (int)expr();
2845
        }
2846
        else
2847
                prevToken();
2848
        emit_insn(
2849
                ((inc & 0x1f) << 19) |
2850
                (1 << 15) |
2851
                ((Ra & 0x3FLL) << 6) |
2852
                0x00, !expand_flag, 5
2853
        );
2854
}
2855
 
2856
// ---------------------------------------------------------------------------
2857
// ---------------------------------------------------------------------------
2858
 
2859
static void GetIndexScale(int *sc)
2860
{
2861
      int64_t val;
2862
 
2863
      NextToken();
2864
      val = expr();
2865
      prevToken();
2866
      switch(val) {
2867
      case 0: *sc = 0; break;
2868
      case 1: *sc = 0; break;
2869
      case 2: *sc = 1; break;
2870
      case 4: *sc = 2; break;
2871
      case 8: *sc = 3; break;
2872
      default: printf("Illegal scaling factor.\r\n");
2873
      }
2874
}
2875
 
2876
 
2877
// ---------------------------------------------------------------------------
2878
// expr
2879
// expr[Reg]
2880
// [Reg]
2881
// [Reg+Reg]
2882
// ---------------------------------------------------------------------------
2883
 
2884
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc)
2885
{
2886
     int64_t val;
2887
 
2888
     // chech params
2889
     if (disp == (int64_t *)NULL)
2890
         return;
2891
     if (regA == (int *)NULL)
2892
         return;
2893
         if (regB == (int *)NULL)
2894
                 return;
2895
         if (Sc == (int *)NULL)
2896
                 return;
2897
 
2898
     *disp = 0;
2899
     *regA = -1;
2900
         *regB = -1;
2901
         *Sc = 0;
2902
     if (token!='[') {;
2903
          val = expr();
2904
          *disp = val;
2905
     }
2906
     if (token=='[') {
2907
         *regA = getRegisterX();
2908
         if (*regA == -1) {
2909
             printf("expecting a register\r\n");
2910
         }
2911
                 if (token=='+') {
2912
                         *regB = getRegisterX();
2913
                         if (*regB == -1) {
2914
                                 printf("expecting a register\r\n");
2915
                         }
2916
              if (token=='*') {
2917
                  GetIndexScale(Sc);
2918
              }
2919
                 }
2920
         need(']');
2921
     }
2922
}
2923
 
2924
static void mem_voperand(int64_t *disp, int *regA, int *regB)
2925
{
2926
     int64_t val;
2927
 
2928
     // chech params
2929
     if (disp == (int64_t *)NULL)
2930
         return;
2931
     if (regA == (int *)NULL)
2932
         return;
2933
 
2934
     *disp = 0;
2935
     *regA = -1;
2936
         *regB = -1;
2937
     if (token!='[') {;
2938
          val = expr();
2939
          *disp = val;
2940
     }
2941
     if (token=='[') {
2942
         *regA = getRegisterX();
2943
         if (*regA == -1) {
2944
             printf("expecting a register\r\n");
2945
         }
2946
                 if (token=='+') {
2947
                         *regB = getVecRegister();
2948
                         if (*regB == -1) {
2949
                                 printf("expecting a vector register: %d\r\n", lineno);
2950
                         }
2951
                 }
2952
         need(']');
2953
     }
2954
}
2955
 
2956
// ---------------------------------------------------------------------------
2957
// If the displacement is too large the instruction is converted to an
2958
// indexed form and the displacement loaded into a second register.
2959
//
2960
// So
2961
//      sw   r2,$12345678[r2]
2962
// Becomes:
2963
//              ori  r23,r0,#$5678
2964
//      orq1 r23,#$1234
2965
//      sw   r2,[r2+r23]
2966
//
2967
// sw disp[r1],r2
2968
// sw [r1+r2],r3
2969
// ----------------------------------------------------------------------------
2970
 
2971
static void process_store(int64_t opcode6, int sz)
2972
{
2973
    int Ra,Rb;
2974
    int Rs;
2975
        int Sc;
2976
    int64_t disp,val;
2977
        int64_t aq = 0, rl = 0;
2978
        int ar;
2979
 
2980
        GetArBits(&aq, &rl);
2981
        ar = (int)((aq << 1LL) | rl);
2982
        Rs = getRegisterX();
2983
    if (Rs < 0) {
2984
        printf("Expecting a source register (%d).\r\n", lineno);
2985
        printf("Line:%.60s\r\n",inptr);
2986
        ScanToEOL();
2987
        return;
2988
    }
2989
    expect(',');
2990
    mem_operand(&disp, &Ra, &Rb, &Sc);
2991
        if (Ra > 0 && Rb > 0) {
2992
                switch (sz) {
2993
                case 1: opcode6 = 0x24; break;  // SCX
2994
                case 2: opcode6 = 0x14; break;  // SHX
2995
                case 4: opcode6 = 0x16; break;  // SWX
2996
                default:;
2997
                }
2998
                emit_insn(
2999
                        (opcode6 << 26LL) |
3000
                        (Sc << 23) |
3001
                        (Rs << 18) |
3002
                        (Rb << 13) |
3003
                        (Ra << 8) |
3004
                        0x16,!expand_flag,4);
3005
                return;
3006
        }
3007
    if (Ra < 0) Ra = 0;
3008
    val = disp;
3009
        if (Ra == 55)
3010
                val -= program_address;
3011
        if (sz == 4 && Ra == regSP) {
3012
                if ((val & 7) == 0) {
3013
                        if (val >= -128 && val < 128) {
3014
                                emit_insn(
3015
                                        (((val >> 4) & 0x0F) << 8) |
3016
                                        (9 << 12) |
3017
                                        (3 << 6) |
3018
                                        (((val >> 3) & 0x1) << 5) |
3019
                                        Rs, 0, 2
3020
                                );
3021
                                ScanToEOL();
3022
                                return;
3023
                        }
3024
                }
3025
        }
3026
        if (sz == 4 && Ra == regFP) {
3027
                if ((val & 7) == 0) {
3028
                        if (val >= -128 && val < 128) {
3029
                                emit_insn(
3030
                                        (((val >> 4) & 0x0F) << 8) |
3031
                                        (11 << 12) |
3032
                                        (3 << 6) |
3033
                                        (((val >> 3) & 0x1) << 5) |
3034
                                        Rs, 0, 2
3035
                                );
3036
                                ScanToEOL();
3037
                                return;
3038
                        }
3039
                }
3040
        }
3041
        if (!IsNBit(val,30)) {
3042
                LoadConstant(val,23);
3043
                // Change to indexed addressing
3044
                switch (sz) {
3045
                case 1: opcode6 = 0x24; break;
3046
                case 2: opcode6 = 0x14; break;
3047
                case 4: opcode6 = 0x16; break;
3048
                default: opcode6 = 0x15;
3049
                }
3050
                emit_insn(
3051
                        (opcode6 << 26LL) |
3052
                        (0 << 23) |              // Sc
3053
                        (Rs << 18) |
3054
                        (23 << 13) |
3055
                        (Ra << 8) |
3056
                        0x02,!expand_flag,4);
3057
                ScanToEOL();
3058
                return;
3059
        }
3060
        if (!IsNBit(val, 14)) {
3061
                emit_insn(
3062
                        ((val|sz) << 18) |
3063
                        (Rs << 13) |
3064
                        (Ra << 8) |
3065
                        (1 << 6) |
3066
                        opcode6, !expand_flag, 6);
3067
                ScanToEOL();
3068
                return;
3069
        }
3070
        emit_insn(
3071
                ((val|sz) << 18) |
3072
                (Rs << 13) |
3073
                (Ra << 8) |
3074
                opcode6,!expand_flag,4);
3075
    ScanToEOL();
3076
}
3077
/*
3078
static void process_storepair(int64_t opcode6)
3079
{
3080
        int Ra, Rb;
3081
        int Rs, Rs2;
3082
        int Sc;
3083
        int64_t disp, val;
3084
        int64_t aq = 0, rl = 0;
3085
        int ar;
3086
 
3087
        GetArBits(&aq, &rl);
3088
        ar = (int)((aq << 1LL) | rl);
3089
        Rs = getRegisterX();
3090
        if (Rs < 0) {
3091
                printf("Expecting a source register (%d).\r\n", lineno);
3092
                printf("Line:%.60s\r\n", inptr);
3093
                ScanToEOL();
3094
                return;
3095
        }
3096
        expect(',');
3097
        Rs2 = getRegisterX();
3098
        expect(',');
3099
        mem_operand(&disp, &Ra, &Rb, &Sc);
3100
        if (Ra > 0 && Rb > 0) {
3101
                emit_insn(
3102
                        (opcode6 << 34LL) |
3103
                        (ar << 26) |
3104
                        (Sc << 24) |
3105
                        (Rs << 18) |
3106
                        (Rb << 12) |
3107
                        (Ra << 6) |
3108
                        0x02, !expand_flag, 5);
3109
                return;
3110
        }
3111
        if (Ra < 0) Ra = 0;
3112
        val = disp;
3113
        if (Ra == 55)
3114
                val -= program_address;
3115
        if (!IsNBit(val, 14)) {
3116
                LoadConstant(val, 52);
3117
                // Change to indexed addressing
3118
                emit_insn(
3119
                        (opcode6 << 34LL) |
3120
                        (ar << 26) |
3121
                        (0 << 24) |             // Sc
3122
                        (Rs << 18) |
3123
                        (52 << 12) |
3124
                        (Ra << 6) |
3125
                        0x02, !expand_flag, 5);
3126
                ScanToEOL();
3127
                return;
3128
        }
3129
        emit_insn(
3130
                (val << 26LL) |
3131
                (ar << 24) |
3132
                (Rs2 << 18) |
3133
                (Rs << 12) |
3134
                (Ra << 6) |
3135
                opcode6, !expand_flag, 5, true);
3136
        ScanToEOL();
3137
}
3138
*/
3139
static void process_sv(int64_t opcode6)
3140
{
3141
    int Ra,Vb;
3142
    int Vs;
3143
    int64_t disp,val;
3144
        int64_t aq = 0, rl = 0;
3145
        int ar = 0;
3146
 
3147
        GetArBits(&aq, &rl);
3148
        ar = (int)((aq << 1LL) | rl);
3149
        Vs = getVecRegister();
3150
    if (Vs < 0 || Vs > 63) {
3151
        printf("Expecting a vector source register (%d).\r\n", lineno);
3152
        printf("Line:%.60s\r\n",inptr);
3153
        ScanToEOL();
3154
        return;
3155
    }
3156
    expect(',');
3157
    mem_voperand(&disp, &Ra, &Vb);
3158
        if (Ra > 0 && Vb > 0) {
3159
                emit_insn(
3160
                        (opcode6 << 34LL) |
3161
                        (ar << 26) |
3162
                        (Vs << 18) |
3163
                        (Vb << 12) |
3164
                        (Ra << 6) |
3165
                        0x02,!expand_flag,5);
3166
                return;
3167
        }
3168
    if (Ra < 0) Ra = 0;
3169
    val = disp;
3170
        //if (val < -32768 || val > 32767)
3171
        //      printf("SV displacement too large: %d\r\n", lineno);
3172
        if (!IsNBit(val, 20)) {
3173
                LoadConstant(val, 52);
3174
                // ToDo: store with indexed addressing
3175
                return;
3176
        }
3177
        emit_insn(
3178
                (val << 20) |
3179
                (ar << 18) |
3180
                (Vs << 12) |
3181
                (Ra << 6) |
3182
                opcode6,!expand_flag,5);
3183
    ScanToEOL();
3184
}
3185
 
3186
// ----------------------------------------------------------------------------
3187
// ----------------------------------------------------------------------------
3188
 
3189
static void process_ldi()
3190
{
3191
    int Ra = 0;
3192
    int Rt;
3193
    int64_t val;
3194
        char *p;
3195
        int sz = 3;
3196
 
3197
    p = inptr;
3198
        if (*p=='.')
3199
                getSz(&sz);
3200
        sz &= 3;
3201
    Rt = getRegisterX();
3202
    expect(',');
3203
    val = expr();
3204
        if (IsNBit(val, 5) && Rt != 0) {
3205
                emit_insn(
3206
                        (1 << 12) |
3207
                        (((val >> 1) & 0x0f) << 8)|
3208
                        (2 << 6) |
3209
                        ((val & 1) << 5) |
3210
                        Rt,
3211
                        !expand_flag,2
3212
                );
3213
                return;
3214
        }
3215
        if (IsNBit(val, 14)) {
3216
                emit_insn(
3217
                        (val << 18LL) |
3218
                        (Rt << 13) |
3219
                        (0 << 8) |               // ADDI
3220
                        0x04, !expand_flag, 4);
3221
                return;
3222
        }
3223
        if (IsNBit(val, 30)) {
3224
                emit_insn(
3225
                        (val << 18LL) |
3226
                        (Rt << 13) |
3227
                        (0 << 8) |               // ADDI
3228
                        (1 << 6) |
3229
                        0x04, !expand_flag, 6);
3230
                return;
3231
        }
3232
        if (IsNBit(val, 49)) {
3233
                emit_insn(
3234
                        ((val >> 30LL) << 13LL) |
3235
                        (Rt << 8) |
3236
                        (0 << 6) |
3237
                        0x27, !expand_flag, 4
3238
                );
3239
                emit_insn(
3240
                        (val << 18LL) |
3241
                        (Rt << 13) |
3242
                        (0 << 8) |               // ORI
3243
                        (1 << 6) |
3244
                        0x09, !expand_flag, 6);
3245
                return;
3246
        }
3247
        // 64 bit constant
3248
        emit_insn(
3249
                ((val >> 30LL) << 13LL) |
3250
                (Rt << 8) |
3251
                (1 << 6) |
3252
                0x27, !expand_flag, 6
3253
        );
3254
        emit_insn(
3255
                (val << 18LL) |
3256
                (Rt << 13) |
3257
                (0 << 8) |               // ORI
3258
                (1 << 6) |
3259
                0x09, !expand_flag, 6);
3260
        return;
3261
}
3262
 
3263
// ----------------------------------------------------------------------------
3264
// link #-40
3265
// ----------------------------------------------------------------------------
3266
 
3267
// ----------------------------------------------------------------------------
3268
// lw r1,disp[r2]
3269
// lw r1,[r2+r3]
3270
// ----------------------------------------------------------------------------
3271
 
3272
static void process_load(int64_t opcode6, int sz)
3273
{
3274
    int Ra,Rb;
3275
    int Rt;
3276
        int Sc;
3277
    char *p;
3278
    int64_t disp;
3279
    int64_t val;
3280
        int64_t aq = 0, rl = 0;
3281
        int ar;
3282
    int fixup = 5;
3283
 
3284
        GetArBits(&aq, &rl);
3285
        ar = (int)((aq << 1LL) | rl);
3286
        p = inptr;
3287
        if (opcode6==0x26)
3288
                Rt = getVecRegister();
3289
        else
3290
                Rt = getRegisterX();
3291
    if (Rt < 0) {
3292
        printf("Expecting a target register (%d).\r\n", lineno);
3293
        printf("Line:%.60s\r\n",p);
3294
        ScanToEOL();
3295
        inptr-=2;
3296
        return;
3297
    }
3298
    expect(',');
3299
    mem_operand(&disp, &Ra, &Rb, &Sc);
3300
        if (Ra > 0 && Rb > 0) {
3301
                // Trap LEA, convert to LEAX opcode
3302
                if (opcode6==0x04) // ADD is really LEA
3303
                        opcode6 = 0x18;
3304
                else {
3305
                        switch (sz) {
3306
                        case -1: opcode6 = 0x21; break; // LCUX
3307
                        case 1: opcode6 = 0x20; break;          // LCX
3308
                        case -2: opcode6 = 0x11; break; // LHUX
3309
                        case 2: opcode6 = 0x10; break;  // LHX
3310
                        case 4: opcode6 = 0x12; break;          // LWX
3311
                        }
3312
                }
3313
                emit_insn(
3314
                        (opcode6 << 26LL) |
3315
                        (Sc << 23) |
3316
                        (Rt << 18) |
3317
                        (Rb << 13) |
3318
                        (Ra << 8) |
3319
                        0x16,!expand_flag,4);
3320
                return;
3321
        }
3322
    if (Ra < 0) Ra = 0;
3323
    val = disp;
3324
        if (Ra == 55)
3325
                val -= program_address;
3326
        if (sz == 4 && Ra == regSP) {
3327
                if ((val & 7) == 0) {
3328
                        if (val >= -128 && val < 128) {
3329
                                emit_insn(
3330
                                        (((val >> 4) & 0x0F) << 8) |
3331
                                        (5 << 12) |
3332
                                        (3 << 6) |
3333
                                        (((val >> 3) & 0x1) << 5) |
3334
                                        Rt, 0, 2
3335
                                );
3336
                                ScanToEOL();
3337
                                return;
3338
                        }
3339
                }
3340
        }
3341
        if (sz == 4 && Ra == regFP) {
3342
                if ((val & 7) == 0) {
3343
                        if (val >= -128 && val < 128) {
3344
                                emit_insn(
3345
                                        (((val >> 4) & 0x0F) << 8) |
3346
                                        (7 << 12) |
3347
                                        (3 << 6) |
3348
                                        (((val >> 3) & 0x1) << 5) |
3349
                                        Rt, 0, 2
3350
                                );
3351
                                ScanToEOL();
3352
                                return;
3353
                        }
3354
                }
3355
        }
3356
        if (!IsNBit(val, 30)) {
3357
                LoadConstant(val, 23);
3358
                // Change to indexed addressing
3359
                switch (sz) {
3360
                case -1: opcode6 = 0x21;        // LCUX
3361
                case 1: opcode6 = 0x20;         // LCX
3362
                case -2: opcode6 = 0x11;        // LHUX
3363
                case 2: opcode6 = 0x10;         // LHX
3364
                case 4: opcode6 = 0x12;         // LWX
3365
                }
3366
                emit_insn(
3367
                        (opcode6 << 26LL) |
3368
                        (0 << 23) |              // Sc = 0
3369
                        (Rt << 18) |
3370
                        (23 << 13) |
3371
                        (Ra << 8) |
3372
                        0x02,!expand_flag,4);
3373
                ScanToEOL();
3374
                return;
3375
        }
3376
        if (!IsNBit(val, 14)) {
3377
                emit_insn(
3378
                        ((val|abs(sz)) << 18LL) |
3379
                        (Rt << 13) |
3380
                        (Ra << 8) |
3381
                        (1 << 6) |
3382
                        opcode6, !expand_flag, 6);
3383
                ScanToEOL();
3384
                return;
3385
        }
3386
        emit_insn(
3387
                ((val|abs(sz)) << 18LL) |
3388
                (Rt << 13) |
3389
                (Ra << 8) |
3390
                opcode6,!expand_flag,4);
3391
    ScanToEOL();
3392
}
3393
 
3394
static void process_cache(int opcode6)
3395
{
3396
    int Ra,Rb;
3397
        int Sc;
3398
    char *p;
3399
    int64_t disp;
3400
    int64_t val;
3401
    int fixup = 5;
3402
        int cmd;
3403
 
3404
    p = inptr;
3405
        NextToken();
3406
        cmd = (int)expr() & 0x1f;
3407
    expect(',');
3408
    mem_operand(&disp, &Ra, &Rb, &Sc);
3409
        if (Ra > 0 && Rb > 0) {
3410
                emit_insn(
3411
                        (opcode6 << 26) |
3412
                        (Sc << 21) |
3413
                        (cmd << 16) |
3414
                        (Rb << 11) |
3415
                        (Ra << 6) |
3416
                        0x16,!expand_flag,4);
3417
                return;
3418
        }
3419
    if (Ra < 0) Ra = 0;
3420
    val = disp;
3421
        if (!IsNBit(val,30)) {
3422
                LoadConstant(val,23);
3423
                // Change to indexed addressing
3424
                emit_insn(
3425
                        (opcode6 << 26) |
3426
                        (cmd << 18) |
3427
                        (23 << 13) |
3428
                        (Ra << 8) |
3429
                        0x16,!expand_flag,4);
3430
                ScanToEOL();
3431
                return;
3432
        }
3433
        if (!IsNBit(val, 14)) {
3434
                emit_insn(
3435
                        (val << 18LL) |
3436
                        (cmd << 13) |
3437
                        (Ra << 8) |
3438
                        (1 << 6) |
3439
                        opcode6, !expand_flag, 6);
3440
                return;
3441
        }
3442
        emit_insn(
3443
                (val << 18) |
3444
                (cmd << 13) |
3445
                (Ra << 8) |
3446
                opcode6,!expand_flag,4);
3447
    ScanToEOL();
3448
}
3449
 
3450
// ----------------------------------------------------------------------------
3451
// lw r1,disp[r2]
3452
// lw r1,[r2+r3]
3453
// ----------------------------------------------------------------------------
3454
 
3455
static void ProcessLoadVolatile(int opcode3)
3456
{
3457
    int Ra,Rb;
3458
    int Rt;
3459
        int Sc;
3460
    char *p;
3461
    int64_t disp;
3462
    int64_t val;
3463
    int fixup = 5;
3464
 
3465
    p = inptr;
3466
        Rt = getRegisterX();
3467
    if (Rt < 0) {
3468
        printf("Expecting a target register (%d).\r\n", lineno);
3469
        printf("Line:%.60s\r\n",p);
3470
        ScanToEOL();
3471
        inptr-=2;
3472
        return;
3473
    }
3474
    expect(',');
3475
    mem_operand(&disp, &Ra, &Rb, &Sc);
3476
        if (Ra > 0 && Rb > 0) {
3477
                emit_insn(
3478
                        (0x3B << 26) |
3479
                        (opcode3 << 23) |
3480
                        (Sc << 21) |
3481
                        (Rt << 16) |
3482
                        (Rb << 11) |
3483
                        (Ra << 6) |
3484
                        0x02,!expand_flag,4);
3485
                return;
3486
        }
3487
    if (Ra < 0) Ra = 0;
3488
    val = disp;
3489
        if (val < -2048 || val > 2047) {
3490
                LoadConstant12(val,23);
3491
                // Change to indexed addressing
3492
                emit_insn(
3493
                        (0x3B << 26) |
3494
                        (opcode3 << 23) |
3495
                        (Rt << 16) |
3496
                        (23 << 11) |
3497
                        (Ra << 6) |
3498
                        0x02,!expand_flag,4);
3499
                ScanToEOL();
3500
                return;
3501
        }
3502
        emit_insn(
3503
                (opcode3 << 28) |
3504
                ((val & 0xFFF) << 16) |
3505
                (Rt << 11) |
3506
                (Ra << 6) |
3507
                0x3B,!expand_flag,4);
3508
    ScanToEOL();
3509
}
3510
 
3511
static void process_lv(int opcode6)
3512
{
3513
    int Ra,Vb;
3514
    int Vt;
3515
    char *p;
3516
    int64_t disp;
3517
    int64_t val;
3518
    int fixup = 5;
3519
 
3520
    p = inptr;
3521
        Vt = getVecRegister();
3522
    if (Vt < 0) {
3523
        printf("Expecting a vector target register (%d).\r\n", lineno);
3524
        printf("Line:%.60s\r\n",p);
3525
        ScanToEOL();
3526
        inptr-=2;
3527
        return;
3528
    }
3529
    expect(',');
3530
    mem_voperand(&disp, &Ra, &Vb);
3531
        if (Ra > 0 && Vb > 0) {
3532
                emit_insn(
3533
                        (opcode6 << 26) |
3534
                        (Vt << 16) |
3535
                        (Vb << 11) |
3536
                        (Ra << 6) |
3537
                        0x02,!expand_flag,4);
3538
                return;
3539
        }
3540
    if (Ra < 0) Ra = 0;
3541
    val = disp;
3542
        //if (val < -32768 || val > 32767)
3543
        //      printf("LV displacement too large: %d\r\n", lineno);
3544
        if (val >= -32768 && val < 32768) {
3545
                emit_insn(
3546
                        (val << 16) |
3547
                        (Vt << 11) |
3548
                        (Ra << 6) |
3549
                        opcode6,!expand_flag,4);
3550
                ScanToEOL();
3551
                return;
3552
        }
3553
        LoadConstant(val,23);
3554
        // add r23,r23,ra
3555
        if (Ra != 0)
3556
                emit_insn(
3557
                        (0x04 << 26) |
3558
                        (3 << 21) |
3559
                        (23 << 16) |
3560
                        (23 << 11) |
3561
                        (Ra << 6) |
3562
                        0x02,!expand_flag,4
3563
                );
3564
        emit_insn(
3565
                (Vt << 11) |
3566
                (23 << 6) |
3567
                opcode6,!expand_flag,4);
3568
        ScanToEOL();
3569
}
3570
 
3571
static void process_lsfloat(int64_t opcode6, int64_t opcode3)
3572
{
3573
    int Ra,Rb;
3574
    int Rt;
3575
        int Sc;
3576
    char *p;
3577
    int64_t disp;
3578
    int64_t val;
3579
    int fixup = 5;
3580
 
3581
    int  sz;
3582
    int rm;
3583
 
3584
    rm = 0;
3585
    sz = GetFPSize();
3586
    p = inptr;
3587
    Rt = getFPRegister();
3588
    if (Rt < 0) {
3589
        printf("Expecting a target register (1:%d).\r\n", lineno);
3590
        printf("Line:%.60s\r\n",p);
3591
        ScanToEOL();
3592
        inptr-=2;
3593
        return;
3594
    }
3595
    expect(',');
3596
    mem_operand(&disp, &Ra, &Rb, &Sc);
3597
        if (Ra > 0 && Rb > 0) {
3598
                emit_insn(
3599
                        ((opcode6+sz) << 26) |
3600
                        (Sc << 23) |
3601
                        (Rt << 18) |
3602
                        (Rb << 13) |
3603
                        (Ra << 8) |
3604
                        0x16,!expand_flag,4);
3605
                return;
3606
        }
3607
    if (Ra < 0) Ra = 0;
3608
    val = disp;
3609
        if (!IsNBit(val, 30)) {
3610
                LoadConstant(val, 23);
3611
                // Change to indexed addressing
3612
                emit_insn(
3613
                        ((opcode6+sz) << 26LL) |
3614
                        (0 << 23) |              // Sc = 0
3615
                        (Rt << 18) |
3616
                        (23 << 13) |
3617
                        (Ra << 8) |
3618
                        0x02, !expand_flag, 4);
3619
                ScanToEOL();
3620
                return;
3621
        }
3622
        switch (sz) {
3623
        case 0:  val &= 0xfffffffffffffffeLL; val |= 1; break;
3624
        case 1: val &= 0xfffffffffffffffcLL; val |= 2; break;
3625
        case 2: val &= 0xfffffffffffffff8LL; val |= 4; break;
3626
        case 4: val &= 0xfffffffffffffff0LL; val |= 8; break;
3627
        }
3628
        if (!IsNBit(val, 14)) {
3629
                emit_insn(
3630
                        (val << 18LL) |
3631
                        (Rt << 13) |
3632
                        (Ra << 8) |
3633
                        (1 << 6) |
3634
                        opcode6, !expand_flag, 6);
3635
                ScanToEOL();
3636
                return;
3637
        }
3638
        emit_insn(
3639
                (val << 18LL) |
3640
                (Rt << 13) |
3641
                (Ra << 8) |
3642
                opcode6, !expand_flag, 4);
3643
        ScanToEOL();
3644
 
3645
}
3646
 
3647
static void process_ld()
3648
{
3649
        int Rt;
3650
        char *p;
3651
 
3652
        p = inptr;
3653
        Rt = getRegisterX();
3654
        expect(',');
3655
//      NextToken();
3656
        if (token == '#') {
3657
                inptr = p;
3658
                process_ldi();
3659
                return;
3660
        }
3661
        // Else: do a word load
3662
        inptr = p;
3663
        process_load(0x20,4);
3664
}
3665
 
3666
// ----------------------------------------------------------------------------
3667
// ----------------------------------------------------------------------------
3668
 
3669
static void process_ltcb(int oc)
3670
{
3671
        int Rn;
3672
 
3673
        Rn = getRegisterX();
3674
        emit_insn(
3675
                (oc << 11) |
3676
                (Rn << 6) |
3677
                0x19,0,1
3678
                );
3679
        prevToken();
3680
}
3681
 
3682
// ----------------------------------------------------------------------------
3683
// mov r1,r2 -> translated to or Rt,Ra,#0
3684
// ----------------------------------------------------------------------------
3685
 
3686
static void process_mov(int64_t oc, int64_t fn)
3687
{
3688
     int Ra;
3689
     int Rt;
3690
     char *p;
3691
         int vec = 0;
3692
         int fp = 0;
3693
         int d3;
3694
         int rgs = 8;
3695
         int sz = 3;
3696
 
3697
         p = inptr;
3698
         if (*p == '.')
3699
                 getSz(&sz);
3700
 
3701
         d3 = 7;        // current to current
3702
         p = inptr;
3703
     Rt = getRegisterX();
3704
         if (Rt==-1) {
3705
                 inptr = p;
3706
                 Rt = getFPRegister();
3707
                 if (Rt == -1) {
3708
                         d3 = 4;
3709
                         inptr = p;
3710
                         vec = 1;
3711
                         Rt = getVecRegister();
3712
                 }
3713
                 else {
3714
                         d3 = 4;
3715
                         fp = 1;
3716
                 }
3717
         }
3718
         Rt &= 31;
3719
        if (inptr[-1]==':') {
3720
                if (*inptr=='x' || *inptr=='X') {
3721
                        d3 = 2;
3722
                        inptr++;
3723
                        NextToken();
3724
                }
3725
                else {
3726
                        rgs = (int)expr();
3727
                        d3 = 0;
3728
                }
3729
        }
3730
     need(',');
3731
         p = inptr;
3732
     Ra = getRegisterX();
3733
         if (Ra==-1) {
3734
                 inptr = p;
3735
                 Ra = getFPRegister();
3736
                 if (Ra == -1) {
3737
                         inptr = p;
3738
                         Ra = getVecRegister();
3739
                         vec |= 2;
3740
                 }
3741
                 else {
3742
                         if (fp == 1)
3743
                                 d3 = 6;
3744
                         else
3745
                                 d3 = 5;
3746
                         fp |= 2;
3747
                 }
3748
         }
3749
         Ra &= 31;
3750
        if (inptr[-1]==':') {
3751
                if (*inptr=='x' || *inptr=='X') {
3752
                        inptr++;
3753
                        d3 = 3;
3754
                        NextToken();
3755
                }
3756
                else {
3757
                        rgs = (int)expr();
3758
                        d3 = 1;
3759
                }
3760
        }
3761
         if (vec==1) {
3762
                 emit_insn(
3763
                         (0x33LL << 34LL) |
3764
                         (0x00LL << 28LL) |
3765
                         (Rt << 12) |
3766
                         (Ra << 6) |
3767
                         0x01,!expand_flag,5
3768
                 );
3769
                 return;
3770
         }
3771
         else if (vec==2) {
3772
                 emit_insn(
3773
                         (0x33LL << 34LL) |
3774
                         (0x01LL << 28LL) |
3775
                         (Rt << 12) |
3776
                         (Ra << 6) |
3777
                         0x01,!expand_flag,5
3778
                 );
3779
                 return;
3780
         }
3781
         else if (vec==3)
3782
                 printf("Unsupported mov operation. %d\n", lineno);
3783
         if (rgs < 0 || rgs > 63)
3784
                 printf("Illegal register set spec: %d\n", lineno);
3785
         rgs &= 0x31;
3786
         if (d3 == 7) {
3787
                 emit_insn(
3788
                         (0 << 12) |
3789
                         (3 << 6) |
3790
                         ((Rt >> 1) << 8) |
3791
                         ((Rt & 1) << 5) |
3792
                         (Ra),
3793
                 0,2);
3794
                 prevToken();
3795
                 return;
3796
         }
3797
         emit_insn(
3798
                 (fn << 26LL) |
3799
                 (d3 << 23LL) |
3800
                 (rgs << 18) |
3801
                 (Rt << 13) |
3802
                 (Ra << 8) |
3803
                 oc,!expand_flag,4
3804
                 );
3805
        prevToken();
3806
}
3807
 
3808
static void process_vmov(int opcode, int func)
3809
{
3810
        int Vt, Va;
3811
        int Rt, Ra;
3812
 
3813
        Vt = getVecRegister();
3814
        if (Vt < 0x20) {
3815
                Rt = getRegisterX();
3816
                if (Rt < 0) {
3817
                        printf("Illegal register in vmov (%d)\n", lineno);
3818
                        ScanToEOL();
3819
                        return;
3820
                }
3821
                Va = getVecRegister();
3822
                if (Va < 0x20) {
3823
                        printf("Illegal register in vmov (%d)\n", lineno);
3824
                        ScanToEOL();
3825
                        return;
3826
                }
3827
                emit_insn(
3828
                        (func << 26) |
3829
                        (1 << 21) |
3830
                        ((Rt & 0x1f) << 11) |
3831
                        ((Va & 0x1F) << 6) |
3832
                        opcode,!expand_flag,4
3833
                        );
3834
                return;
3835
        }
3836
        need(',');
3837
        Ra = getRegisterX();
3838
        if (Ra < 0) {
3839
                printf("Illegal register in vmov (%d)\n", lineno);
3840
                ScanToEOL();
3841
                return;
3842
        }
3843
        emit_insn(
3844
                (func << 26) |
3845
                ((Vt & 0x1f) << 11) |
3846
                (Ra << 6) |
3847
                opcode,!expand_flag,4
3848
                );
3849
}
3850
 
3851
 
3852
// ----------------------------------------------------------------------------
3853
// shr r1,r2,#5
3854
// ----------------------------------------------------------------------------
3855
 
3856
static void process_shifti(int64_t op4)
3857
{
3858
     int Ra;
3859
     int Rt;
3860
         int sz = 3;
3861
         int64_t func6 = 0x0F;
3862
     int64_t val;
3863
         char *p = inptr;
3864
 
3865
         if (p[0]=='.')
3866
                 getSz(&sz);
3867
     Rt = getRegisterX();
3868
     need(',');
3869
     Ra = getRegisterX();
3870
     need(',');
3871
     NextToken();
3872
     val = expr();
3873
         val &= 63;
3874
         if (val < 32 && op4 == 0 && Rt==Ra) {
3875
                 emit_insn(
3876
                         (3 << 12) |
3877
                         (((val >> 1) & 0x0f) << 8) |
3878
                         (2 << 6) |
3879
                         ((val & 1) << 5) |
3880
                         Rt,0,2
3881
                 );
3882
                 return;
3883
         }
3884
         if (val > 31)
3885
                 func6 += 0x10;
3886
        emit_insn(
3887
                (func6 << 26LL) |
3888
                (op4 << 23LL) |
3889
                ((val & 0x1f) << 18) |
3890
                (Rt << 13) |
3891
                (Ra << 8) |
3892
                0x02,!expand_flag,4);
3893
}
3894
 
3895
// ----------------------------------------------------------------------------
3896
// SEI R1
3897
// SEI #5
3898
// ----------------------------------------------------------------------------
3899
 
3900
static void process_sei()
3901
{
3902
        int64_t val = 7;
3903
        int Ra = -1;
3904
    char *p;
3905
 
3906
        p = inptr;
3907
        NextToken();
3908
        if (token=='#')
3909
                val = expr();
3910
        else {
3911
                inptr = p;
3912
            Ra = getRegisterX();
3913
        }
3914
        if (Ra==-1) {
3915
                emit_insn(
3916
                        0xC0000002LL |
3917
                        ((val & 7) << 18) |
3918
                        (0 << 8),
3919
                        !expand_flag,4);
3920
        }
3921
        else {
3922
                emit_insn(
3923
                        0xC0000002LL |
3924
                        (0 << 18) |
3925
                        (Ra << 8),
3926
                        !expand_flag,4);
3927
        }
3928
}
3929
 
3930
// ----------------------------------------------------------------------------
3931
// REX r0,6,6,1
3932
// ----------------------------------------------------------------------------
3933
 
3934
static void process_rex()
3935
{
3936
        int64_t val = 7;
3937
        int Ra = -1;
3938
        int tgtol;
3939
        int pl;
3940
        int im;
3941
    char *p;
3942
 
3943
        p = inptr;
3944
    Ra = getRegisterX();
3945
        need(',');
3946
        NextToken();
3947
        tgtol = (int)expr() & 7;
3948
        if (tgtol==0)
3949
                printf("REX: Illegal redirect to user level %d.\n", lineno);
3950
        need(',');
3951
        NextToken();
3952
        pl = (int)expr() & 7;
3953
        need(',');
3954
        NextToken();
3955
        im = (int)expr() & 7;
3956
        emit_insn(
3957
                (im << 24) |
3958
                (pl << 16) |
3959
                (tgtol << 11) |
3960
                (Ra << 6) |
3961
                0x0D,!expand_flag,4
3962
        );
3963
}
3964
 
3965
// ----------------------------------------------------------------------------
3966
// shl r1,r2,r3
3967
// ----------------------------------------------------------------------------
3968
 
3969
static void process_shift(int op4)
3970
{
3971
     int Ra, Rb;
3972
     int Rt;
3973
     char *p;
3974
         int sz = 3;
3975
         int func6 = 0x2f;
3976
 
3977
         p = inptr;
3978
         if (p[0]=='.')
3979
                 getSz(&sz);
3980
     Rt = getRegisterX();
3981
     need(',');
3982
     Ra = getRegisterX();
3983
     need(',');
3984
     NextToken();
3985
         if (token=='#') {
3986
                 inptr = p;
3987
                 process_shifti(op4);
3988
         }
3989
         else {
3990
                prevToken();
3991
                Rb = getRegisterX();
3992
                emit_insn((func6 << 26) | (op4 << 23) | (Rt << 18)| (Rb << 12) | (Ra << 8) | 0x02,!expand_flag,4);
3993
         }
3994
}
3995
 
3996
// ----------------------------------------------------------------------------
3997
// gran r1
3998
// ----------------------------------------------------------------------------
3999
 
4000
static void process_gran(int oc)
4001
{
4002
    int Rt;
4003
 
4004
    Rt = getRegisterX();
4005
//    emitAlignedCode(0x01);
4006
    emitCode(0x00);
4007
    emitCode(Rt);
4008
    emitCode(0x00);
4009
    emitCode(oc);
4010
    prevToken();
4011
}
4012
 
4013
 
4014
// ----------------------------------------------------------------------------
4015
// ----------------------------------------------------------------------------
4016
 
4017
static void process_mffp(int oc)
4018
{
4019
    int fpr;
4020
    int Rt;
4021
 
4022
    Rt = getRegisterX();
4023
    need(',');
4024
    fpr = getFPRegister();
4025
    //emitAlignedCode(0x01);
4026
    emitCode(fpr);
4027
    emitCode(Rt);
4028
    emitCode(0x00);
4029
    emitCode(oc);
4030
    if (fpr >= 0)
4031
    prevToken();
4032
}
4033
 
4034
// ----------------------------------------------------------------------------
4035
// ----------------------------------------------------------------------------
4036
 
4037
static void process_fprdstat(int oc)
4038
{
4039
    int Rt;
4040
 
4041
    Rt = getRegisterX();
4042
    //emitAlignedCode(0x01);
4043
    emitCode(0x00);
4044
    emitCode(Rt);
4045
    emitCode(0x00);
4046
    emitCode(oc);
4047
}
4048
 
4049
 
4050
// ----------------------------------------------------------------------------
4051
// Four cases, two with extendable immediate constants
4052
//
4053
// csrrw        r2,#21,r3
4054
// csrrw        r4,#34,#1234
4055
// csrrw        r5,r4,#1234
4056
// csrrw        r6,r4,r5
4057
// ----------------------------------------------------------------------------
4058
 
4059
static void process_csrrw(int64_t op)
4060
{
4061
        int Rd;
4062
        int Rs;
4063
        int Rc;
4064
        int64_t val,val2;
4065
        char *p;
4066
        int sz = 3;
4067
 
4068
        p = inptr;
4069
        if (p[0] == '.')
4070
                getSz(&sz);
4071
        Rd = getRegisterX();
4072
        need(',');
4073
        p = inptr;
4074
        NextToken();
4075
        if (token=='#') {
4076
                val = expr();
4077
                need(',');
4078
                NextToken();
4079
                if (token=='#') {
4080
                        printf("Illegal CSR instruction.\r\n");
4081
                        return;
4082
                        val2 = expr();
4083
                        if (val2 < -15LL || val2 > 15LL) {
4084
                                emit_insn((val << 18) | (op << 16) | (0x10 << 6) | (Rd << 11) | 0x05,0,2);
4085
                                emit_insn(val2,0,2);
4086
                                return;
4087
                        }
4088
                        emit_insn((val << 18) | (op << 16) | ((val2 & 0x1f) << 6) | (Rd << 11) | 0x05,!expand_flag,2);
4089
                        return;
4090
                }
4091
                prevToken();
4092
                Rs = getRegisterX();
4093
                emit_insn(((val & 0x3FF) << 18) | (op << 30LL) | (Rs << 8) | (Rd << 13) | 0x05,!expand_flag,4);
4094
                prevToken();
4095
                return;
4096
                }
4097
        printf("Illegal CSR instruction.\r\n");
4098
        return;
4099
        inptr = p;
4100
        Rc = getRegisterX();
4101
        need(',');
4102
        NextToken();
4103
        if (token=='#') {
4104
                val2 = expr();
4105
                if (val2 < -15LL || val2 > 15LL) {
4106
                        emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | (0x10 << 6) | (Rc << 11) | 0x0C,0,2);
4107
                        emit_insn(val2,0,2);
4108
                        return;
4109
                }
4110
                emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | ((val2 & 0x1f) << 6) | (Rc << 11) | 0x0C,!expand_flag,2);
4111
                return;
4112
        }
4113
        prevToken();
4114
        Rs = getRegisterX();
4115
        emit_insn((0x3F << 26) | (op << 21) | (Rd << 16) | (Rc << 11) | (Rs << 6) | 0x0C,!expand_flag,2);
4116
        prevToken();
4117
        return;
4118
}
4119
 
4120
// ---------------------------------------------------------------------------
4121
// com r3,r3
4122
// - alternate mnemonic for xor Rn,Rn,#-1
4123
// ---------------------------------------------------------------------------
4124
 
4125
static void process_com()
4126
{
4127
    int Ra;
4128
    int Rt;
4129
        char *p;
4130
        int sz = 3;
4131
 
4132
        p = inptr;
4133
        if (p[0] == '.')
4134
                getSz(&sz);
4135
 
4136
    Rt = getRegisterX();
4137
    need(',');
4138
    Ra = getRegisterX();
4139
        emit_insn(
4140
                (0xFFFFFLL << 20) |
4141
                (sz << 18) |
4142
                (Rt << 12) |
4143
                (Ra << 6) |
4144
                0x0A,!expand_flag,5
4145
                );
4146
        prevToken();
4147
}
4148
 
4149
// ---------------------------------------------------------------------------
4150
// neg r3,r3
4151
// - alternate mnemonic for sub Rn,R0,Rn
4152
// ---------------------------------------------------------------------------
4153
 
4154
static void process_neg()
4155
{
4156
    int Ra;
4157
    int Rt;
4158
        char *p;
4159
        int sz = 3;
4160
 
4161
        p = inptr;
4162
        if (p[0] == '.')
4163
                getSz(&sz);
4164
 
4165
    Rt = getRegisterX();
4166
    need(',');
4167
    Ra = getRegisterX();
4168
        emit_insn(
4169
                (0x05LL << 34LL) |
4170
                (sz << 24) |
4171
                (Rt << 18) |
4172
                (Ra << 12) |
4173
                (0 << 6) |
4174
                0x02,!expand_flag,5
4175
                );
4176
        prevToken();
4177
}
4178
 
4179
static void process_sync(int oc)
4180
{
4181
//    emit_insn(oc,!expand_flag);
4182
}
4183
 
4184
 
4185
// ---------------------------------------------------------------------------
4186
// ---------------------------------------------------------------------------
4187
 
4188
static void process_vrrop(int funct6)
4189
{
4190
    int Va,Vb,Vt,Vm;
4191
    char *p;
4192
        int sz = 0x43;
4193
 
4194
    p = inptr;
4195
        if (*p=='.')
4196
                getSz(&sz);
4197
        if (sz==0x43)
4198
                sz = 0;
4199
        else if (sz==0x83)
4200
                sz = 1;
4201
    Vt = getVecRegister();
4202
    need(',');
4203
    Va = getVecRegister();
4204
    need(',');
4205
    Vb = getVecRegister();
4206
    need(',');
4207
    Vm = getVecRegister();
4208
        if (Vm < 0x20 || Vm > 0x23)
4209
                printf("Illegal vector mask register: %d\r\n", lineno);
4210
        Vm &= 0x7;
4211
    //prevToken();
4212
    emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Vb<<11)|(Va<<6)|0x01,!expand_flag,4);
4213
}
4214
 
4215
// ---------------------------------------------------------------------------
4216
// ---------------------------------------------------------------------------
4217
 
4218
static void process_vsrrop(int funct6)
4219
{
4220
    int Va,Rb,Vt,Vm;
4221
    char *p;
4222
        int sz = 0x43;
4223
 
4224
    p = inptr;
4225
        if (*p=='.')
4226
                getSz(&sz);
4227
        if (sz==0x43)
4228
                sz = 0;
4229
        else if (sz==0x83)
4230
                sz = 1;
4231
    Vt = getVecRegister();
4232
    need(',');
4233
    Va = getVecRegister();
4234
    need(',');
4235
    Rb = getRegisterX();
4236
    need(',');
4237
    Vm = getVecRegister();
4238
        if (Vm < 0x20 || Vm > 0x23)
4239
                printf("Illegal vector mask register: %d\r\n", lineno);
4240
        Vm &= 0x3;
4241
    //prevToken();
4242
    emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Rb<<11)|(Va<<6)|0x01,!expand_flag,4);
4243
}
4244
 
4245
// ----------------------------------------------------------------------------
4246
// ----------------------------------------------------------------------------
4247
 
4248
static void ProcessEOL(int opt)
4249
{
4250
    int64_t nn,mm,cai,caia;
4251
    int first;
4252
    int cc,jj;
4253
 
4254
     //printf("Line: %d\r", lineno);
4255
     expand_flag = 0;
4256
     compress_flag = 0;
4257
     segprefix = -1;
4258
     if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
4259
    nn = binstart;
4260
    cc = 2;
4261
    if (segment==codeseg) {
4262
       cc = 4;
4263
/*
4264
        if (sections[segment].bytes[binstart]==0x61) {
4265
            fprintf(ofp, "%06LLX ", ca);
4266
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
4267
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
4268
            }
4269
            fprintf(ofp, "   ; imm\n");
4270
             if (((ca+5) & 15)==15) {
4271
                 ca+=6;
4272
                 binstart+=6;
4273
                 nn++;
4274
             }
4275
             else {
4276
                  ca += 5;
4277
                  binstart += 5;
4278
             }
4279
        }
4280
*/
4281
/*
4282
        if (sections[segment].bytes[binstart]==0xfd) {
4283
            fprintf(ofp, "%06LLX ", ca);
4284
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
4285
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
4286
            }
4287
            fprintf(ofp, "   ; imm\n");
4288
             if (((ca+5) & 15)==15) {
4289
                 ca+=6;
4290
                 binstart+=6;
4291
                 nn++;
4292
             }
4293
             else {
4294
                  ca += 5;
4295
                  binstart += 5;
4296
             }
4297
        }
4298
         if (sections[segment].bytes[binstart]==0xfe) {
4299
            fprintf(ofp, "%06LLX ", ca);
4300
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
4301
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
4302
            }
4303
            fprintf(ofp, "   ; imm\n");
4304
             if (((ca+5) & 15)==15) {
4305
                 ca+=6;
4306
                 nn++;
4307
             }
4308
             else {
4309
                  ca += 5;
4310
             }
4311
        }
4312
*/
4313
    }
4314
 
4315
    first = 1;
4316
    while (nn < sections[segment].index) {
4317
        fprintf(ofp, "%06I64X ", ca);
4318
                caia = 0;
4319
        for (mm = nn; nn < mm + cc && nn < sections[segment].index; ) {
4320
                        cai = sections[segment].index - nn;
4321
                        // Output for instructions with multiple words
4322
                        if ((cai % 4) == 0 && cai < 20 && segment==codeseg)
4323
                                cai = 4;
4324
                        // Otherwise a big stream of information was output, likely data
4325
                        if (cai > 8) cai = 8;
4326
//                      for (jj = (int)cai-1; jj >= 0; jj--)
4327
//                              fprintf(ofp, "%02X", sections[segment].bytes[nn+jj]);
4328
                        for (jj = 0; jj < (int) cai; jj++)
4329
                                fprintf(ofp, "%02X ", sections[segment].bytes[nn + jj]);
4330
                        fprintf(ofp, " ");
4331
                        nn += cai;
4332
                        caia += cai;
4333
        }
4334
                for (jj = 8 - (int)caia; jj >= 0; jj--)
4335
                        fprintf(ofp, "   ");
4336
//        for (; nn < mm + caia; nn++)
4337
//            fprintf(ofp, "  ");
4338
        if (first & opt) {
4339
                        fprintf(ofp, "\t%.*s\n", inptr - stptr - 1, stptr);
4340
                        first = 0;
4341
        }
4342
        else
4343
            fprintf(ofp, opt ? "\n" : "; NOP Ramp\n");
4344
        ca += caia;
4345
    }
4346
    // empty (codeless) line
4347
    if (binstart==sections[segment].index) {
4348
        fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
4349
    }
4350
    } // bGen
4351
    if (opt) {
4352
       stptr = inptr;
4353
       lineno++;
4354
    }
4355
    binstart = sections[segment].index;
4356
    ca = sections[segment].address;
4357
}
4358
 
4359
// ----------------------------------------------------------------------------
4360
// ----------------------------------------------------------------------------
4361
 
4362
void FT64_processMaster()
4363
{
4364
    int nn;
4365
    int64_t bs1, bs2;
4366
 
4367
    lineno = 1;
4368
    binndx = 0;
4369
    binstart = 0;
4370
    bs1 = 0;
4371
    bs2 = 0;
4372
    inptr = &masterFile[0];
4373
    stptr = inptr;
4374
    code_address = 0;
4375
    bss_address = 0;
4376
    start_address = 0;
4377
    first_org = 1;
4378
    first_rodata = 1;
4379
    first_data = 1;
4380
    first_bss = 1;
4381
        expandedBlock = 0;
4382
    if (pass<3) {
4383
    htblmax = 0;
4384
    for (nn = 0; nn < 100000; nn++) {
4385
      hTable[nn].count = 0;
4386
      hTable[nn].opcode = 0;
4387
    }
4388
    }
4389
    for (nn = 0; nn < 12; nn++) {
4390
        sections[nn].index = 0;
4391
        if (nn == 0)
4392
        sections[nn].address = 0;
4393
        else
4394
        sections[nn].address = 0;
4395
        sections[nn].start = 0;
4396
        sections[nn].end = 0;
4397
    }
4398
    ca = code_address;
4399
    segment = codeseg;
4400
    memset(current_label,0,sizeof(current_label));
4401
    NextToken();
4402
    while (token != tk_eof) {
4403
//        printf("\t%.*s\n", inptr-stptr-1, stptr);
4404
//        printf("token=%d\r", token);
4405
          if (expandedBlock)
4406
             expand_flag = 1;
4407
        switch(token) {
4408
        case tk_eol: ProcessEOL(1); break;
4409
//        case tk_add:  process_add(); break;
4410
//              case tk_abs:  process_rop(0x04); break;
4411
                case tk_abs: process_rop(0x01); break;
4412
        case tk_add:  process_rrop(0x04); break;
4413
        case tk_addi: process_riop(0x04); break;
4414
        case tk_align: process_align(); continue; break;
4415
        case tk_and:  process_rrop(0x08); break;
4416
        case tk_andi:  process_riop(0x08); break;
4417
        case tk_asl: process_shift(0x2); break;
4418
        case tk_asr: process_shift(0x3); break;
4419
        case tk_bbc: process_beqi(0x26,1); break;
4420
        case tk_bbs: process_beqi(0x26,0); break;
4421
        case tk_begin_expand: expandedBlock = 1; break;
4422
        case tk_beq: process_bcc(0x30,0); break;
4423
        case tk_beqi: process_beqi(0x32,0); break;
4424
                case tk_bfchg: process_bitfield(2); break;
4425
                case tk_bfclr: process_bitfield(1); break;
4426
        case tk_bfext: process_bitfield(5); break;
4427
        case tk_bfextu: process_bitfield(6); break;
4428
                case tk_bfins: process_bitfield(3); break;
4429
                case tk_bfinsi: process_bitfield(4); break;
4430
                case tk_bfset: process_bitfield(0); break;
4431
        case tk_bge: process_bcc(0x30,3); break;
4432
        case tk_bgeu: process_bcc(0x30,5); break;
4433
        case tk_bgt: process_bcc(0x30,-2); break;
4434
        case tk_bgtu: process_bcc(0x30,-4); break;
4435
        case tk_ble: process_bcc(0x30,-3); break;
4436
        case tk_bleu: process_bcc(0x30,-5); break;
4437
        case tk_blt: process_bcc(0x30,2); break;
4438
        case tk_bltu: process_bcc(0x30,4); break;
4439
        case tk_bne: process_bcc(0x30,1); break;
4440
        case tk_bra: process_bra(0x01); break;
4441
                case tk_brk: process_brk(); break;
4442
        //case tk_bsr: process_bra(0x56); break;
4443
        case tk_bss:
4444
            if (first_bss) {
4445
                while(sections[segment].address & 4095)
4446
                    emitByte(0x00);
4447
                sections[3].address = sections[segment].address;
4448
                first_bss = 0;
4449
                binstart = sections[3].index;
4450
                ca = sections[3].address;
4451
            }
4452
            segment = bssseg;
4453
            break;
4454
                case tk_cache: process_cache(0x1E); break;
4455
                case tk_call:  process_call(0x19); break;
4456
        case tk_cli: emit_insn(0xC0000002,0,4); break;
4457
                case tk_chk:  process_chk(0x34); break;
4458
                case tk_cmovenz: process_cmove(0x29); break;
4459
                case tk_cmp:  process_rrop(0x06); break;
4460
                case tk_cmpi:  process_riop(0x06); break;
4461
                case tk_cmpu:  process_rrop(0x07); break;
4462
                case tk_cmpui:  process_riop(0x07); break;
4463
        case tk_code: process_code(); break;
4464
        case tk_com: process_com(); break;
4465
        case tk_csrrc: process_csrrw(0x3); break;
4466
        case tk_csrrs: process_csrrw(0x2); break;
4467
        case tk_csrrw: process_csrrw(0x1); break;
4468
        case tk_csrrd: process_csrrw(0x0); break;
4469
        case tk_data:
4470
            if (first_data) {
4471
                while(sections[segment].address & 4095)
4472
                    emitByte(0x00);
4473
                sections[2].address = sections[segment].address;   // set starting address
4474
                first_data = 0;
4475
                binstart = sections[2].index;
4476
                ca = sections[2].address;
4477
            }
4478
            process_data(dataseg);
4479
            break;
4480
        case tk_db:  process_db(); break;
4481
                case tk_dbnz: process_dbnz(0x26,3); break;
4482
        case tk_dc:  process_dc(); break;
4483
                case tk_dec:    process_inc(0x25); break;
4484
                case tk_dh:  process_dh(); break;
4485
        case tk_dh_htbl:  process_dh_htbl(); break;
4486
                case tk_div: process_riop(0x3E); break;
4487
        case tk_dw:  process_dw(); break;
4488
        case tk_end: goto j1;
4489
        case tk_end_expand: expandedBlock = 0; break;
4490
        case tk_endpublic: break;
4491
        case tk_eor: process_rrrop(0x0A); break;
4492
        case tk_eori: process_riop(0x0A); break;
4493
        case tk_extern: process_extern(); break;
4494
                case tk_ftoi:   process_ftoi(0x12); break;
4495
                case tk_fadd:   process_fprrop(0x04); break;
4496
        case tk_fbeq:   process_fbcc(0); break;
4497
        case tk_fbge:   process_fbcc(3); break;
4498
        case tk_fblt:   process_fbcc(2); break;
4499
        case tk_fbne:   process_fbcc(1); break;
4500
                case tk_fdiv:   process_fprrop(0x09); break;
4501
        case tk_fill: process_fill(); break;
4502
                case tk_fmov:   process_fprop(0x10); break;
4503
                case tk_fmul:   process_fprrop(0x08); break;
4504
                case tk_fneg:   process_fprop(0x14); break;
4505
                case tk_fsub:   process_fprrop(0x05); break;
4506
                case tk_hint:   process_hint(); break;
4507
                case tk_ibne: process_ibne(0x26,2); break;
4508
                case tk_inc:    process_inc(0x1A); break;
4509
                case tk_if:             pif1 = inptr-2; doif(); break;
4510
                case tk_itof: process_itof(0x15); break;
4511
                case tk_iret:   process_iret(0xC8000002); break;
4512
                case tk_isnull:  process_rop(0x0C); break;
4513
                case tk_isptr:  process_rop(0x0D); break;
4514
        case tk_jal: process_jal(0x18); break;
4515
                case tk_jmp: process_call(0x28); break;
4516
        case tk_lb:  process_load(0x13,0); break;
4517
        case tk_lbu:  process_load(0x23,0); break;
4518
        case tk_lc:  process_load(0x20,1); break;
4519
        case tk_lcu:  process_load(0x20,-1); break;
4520
                case tk_ld:     process_ld(); break;
4521
        case tk_ldi: process_ldi(); break;
4522
        case tk_lea: process_load(0x04,0); break;
4523
                case tk_lf:      process_lsfloat(0x1b,0x00); break;
4524
        case tk_lh:  process_load(0x20,2); break;
4525
        case tk_lhu: process_load(0x20,-2); break;
4526
                //case tk_lui: process_lui(0x27); break;
4527
        case tk_lv:  process_lv(0x36); break;
4528
                case tk_lvb: ProcessLoadVolatile(0); break;
4529
                case tk_lvc: ProcessLoadVolatile(2); break;
4530
                case tk_lvh: ProcessLoadVolatile(4); break;
4531
                case tk_lvw: ProcessLoadVolatile(6); break;
4532
        case tk_lw:  process_load(0x20,4); break;
4533
        case tk_lwr:  process_load(0x1D,0); break;
4534
                case tk_memdb: emit_insn(0x40100002,0,4); break;
4535
                case tk_memsb: emit_insn(0x40110002,0,4); break;
4536
                case tk_message: process_message(); break;
4537
                case tk_mod: process_riop(0x2E); break;
4538
                case tk_modu: process_riop(0x2C); break;
4539
        case tk_mov: process_mov(0x02, 0x22); break;
4540
                case tk_mul: process_riop(0x3A); break;
4541
                case tk_mulu: process_riop(0x38); break;
4542
        case tk_neg: process_neg(); break;
4543
        case tk_nop: emit_insn(0x1C,0,4); break;
4544
                case tk_not: process_rop(0x05); break;
4545
//        case tk_not: process_rop(0x07); break;
4546
        case tk_or:  process_rrop(0x09); break;
4547
        case tk_ori: process_riop(0x09); break;
4548
        case tk_org: process_org(); break;
4549
        case tk_plus: expand_flag = 1; break;
4550
        case tk_public: process_public(); break;
4551
        case tk_rodata:
4552
            if (first_rodata) {
4553
                while(sections[segment].address & 4095)
4554
                    emitByte(0x00);
4555
                sections[1].address = sections[segment].address;
4556
                first_rodata = 0;
4557
                binstart = sections[1].index;
4558
                ca = sections[1].address;
4559
            }
4560
            segment = rodataseg;
4561
            break;
4562
                case tk_redor: process_rop(0x06); break;
4563
                case tk_ret: process_ret(); break;
4564
                case tk_rex: process_rex(); break;
4565
                case tk_rol: process_shift(0x4); break;
4566
                case tk_roli: process_shift(0xC); break;
4567
                case tk_ror: process_shift(0x5); break;
4568
                case tk_rori: process_shift(0xD); break;
4569
                case tk_rti: process_iret(0xC8000002); break;
4570
        case tk_sb:  process_store(0x15,0); break;
4571
        case tk_sc:  process_store(0x24,1); break;
4572
        case tk_sei: process_sei(); break;
4573
                //case tk_seq:  process_riop(0x1B,2); break;
4574
                case tk_sf:             process_lsfloat(0x2B,0x00); break;
4575
                case tk_sge:    process_setop(-6); break;
4576
                case tk_sgeu:   process_setiop(-7); break;
4577
                case tk_sgt:    process_setiop(-0x2C); break;
4578
                case tk_sgtu:   process_setiop(-0x1C); break;
4579
        //case tk_slt:  process_rrop(0x33,0x02,0x00); break;
4580
        //case tk_sltu:  process_rrop(0x33,0x03,0x00); break;
4581
        //case tk_slti:  process_riop(0x13,0x02); break;
4582
        //case tk_sltui:  process_riop(0x13,0x03); break;
4583
        case tk_sh:  process_store(0x24,2); break;
4584
        case tk_shl: process_shift(0x0); break;
4585
        case tk_shli: process_shifti(0x8); break;
4586
                case tk_shr: process_shift(0x1); break;
4587
        case tk_shri: process_shifti(0x9); break;
4588
                case tk_shru: process_shift(0x1); break;
4589
                case tk_shrui: process_shifti(0x9); break;
4590
                case tk_sle:    process_setop(0x28); break;
4591
                case tk_sleu:   process_setop(0x29); break;
4592
                case tk_slt:    process_setop(0x06); break;
4593
                case tk_sltu:   process_setop(0x07); break;
4594
                //case tk_sne:  process_setiop(0x1B,3); break;
4595
        case tk_slli: process_shifti(0x8); break;
4596
                case tk_srai: process_shifti(0xB); break;
4597
        case tk_srli: process_shifti(0x9); break;
4598
        case tk_sub:  process_rrop(0x05); break;
4599
        case tk_subi:  process_riop(0x05); break;
4600
        case tk_sv:  process_sv(0x37); break;
4601
        case tk_sw:  process_store(0x24,4); break;
4602
        case tk_swc:  process_store(0x17,0); break;
4603
        case tk_swap: process_rop(0x03); break;
4604
                //case tk_swp:  process_storepair(0x27); break;
4605
                case tk_sxb: process_rop(0x1A); break;
4606
                case tk_sxc: process_rop(0x19); break;
4607
                case tk_sxh: process_rop(0x18); break;
4608
                case tk_sync: emit_insn(0x04120002,0,4); break;
4609
                //case tk_unlink: emit_insn((0x1B << 26) | (0x1F << 16) | (30 << 11) | (0x1F << 6) | 0x02,0,4); break;
4610
                case tk_vadd: process_vrrop(0x04); break;
4611
                case tk_vadds: process_vsrrop(0x14); break;
4612
                case tk_vand: process_vrrop(0x08); break;
4613
                case tk_vands: process_vsrrop(0x18); break;
4614
                case tk_vdiv: process_vrrop(0x3E); break;
4615
                case tk_vdivs: process_vsrrop(0x2E); break;
4616
                case tk_vmov: process_vmov(0x02,0x33); break;
4617
                case tk_vmul: process_vrrop(0x3A); break;
4618
                case tk_vmuls: process_vsrrop(0x2A); break;
4619
                case tk_vor: process_vrrop(0x09); break;
4620
                case tk_vors: process_vsrrop(0x19); break;
4621
                case tk_vsub: process_vrrop(0x05); break;
4622
                case tk_vsubs: process_vsrrop(0x15); break;
4623
                case tk_vxor: process_vrrop(0x0A); break;
4624
                case tk_vxors: process_vsrrop(0x1A); break;
4625
                case tk_xnor: process_rrop(0x0E); break;
4626
                case tk_xor: process_rrop(0x0A); break;
4627
        case tk_xori: process_riop(0x0A); break;
4628
                case tk_zxb: process_rop(0x0A); break;
4629
                case tk_zxc: process_rop(0x09); break;
4630
                case tk_zxh: process_rop(0x08); break;
4631
                case tk_id:  process_label(); break;
4632
        case '-': compress_flag = 1; expand_flag = 0; break;
4633
        }
4634
        NextToken();
4635
    }
4636
j1:
4637
    ;
4638
}
4639
 

powered by: WebSVN 2.1.0

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