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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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