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

Subversion Repositories thor

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

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

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// AS64 - Assembler
9
//  - 64 bit CPU
10
//
11
// This source file is free software: you can redistribute it and/or modify 
12
// it under the terms of the GNU Lesser General Public License as published 
13
// by the Free Software Foundation, either version 3 of the License, or     
14
// (at your option) any later version.                                      
15
//                                                                          
16
// This source file is distributed in the hope that it will be useful,      
17
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
18
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
19
// GNU General Public License for more details.                             
20
//                                                                          
21
// You should have received a copy of the GNU General Public License        
22
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
23
//                                                                          
24
// ============================================================================
25
//
26
#include "stdafx.h"
27
 
28
static void ProcessEOL(int opt);
29
extern void process_message();
30
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc);
31
 
32
extern char *pif1;
33
extern int first_rodata;
34
extern int first_data;
35
extern int first_bss;
36
extern int 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
//              ldiq1   r52,#$00123
1316
//              oriq0   r52,#$45678
1317
//              addi    r1,r2,r52
1318
// ---------------------------------------------------------------------------
1319
 
1320
static void process_riop(int64_t opcode6)
1321
{
1322 54 robfinch
  int Ra;
1323
  int Rt, Rtp;
1324
  char *p;
1325
  int64_t val;
1326 48 robfinch
        int sz = 3;
1327
 
1328 54 robfinch
  p = inptr;
1329 48 robfinch
        if (*p == '.')
1330
                getSz(&sz);
1331
        Rt = getRegisterX();
1332 54 robfinch
  need(',');
1333
  Ra = getRegisterX();
1334
  need(',');
1335
  NextToken();
1336
  val = expr();
1337 50 robfinch
        if (opcode6==-4LL)      { // subi
1338 48 robfinch
                val = -val;
1339
                opcode6 = 0x04LL;       // change to addi
1340
        }
1341
        // ADDI
1342
        if (opcode6 == 0x04) {
1343
                if (Ra == Rt) {
1344
                        if (Rt == regSP) {
1345
                                if (val >= -128 && val < 128 && ((val & 7) == 0)) {
1346
                                        emit_insn(
1347
                                                (0 << 12) |
1348
                                                (((val >> 4) & 0x0F) << 8) |
1349
                                                (2 << 6) |
1350
                                                (((val >> 3) & 0x1) << 5) |
1351
                                                regSP, 0, 2);
1352 54 robfinch
                                        goto xit;
1353 48 robfinch
                                }
1354
                        }
1355
                        else {
1356
                                if (val >= -16 && val < 16) {
1357
                                        emit_insn(
1358
                                                (0 << 12) |
1359
                                                (((val >> 1) & 0x0F) << 8) |
1360
                                                (2 << 6) |
1361
                                                ((val & 0x1) << 5) |
1362
                                                Ra, 0, 2);
1363 54 robfinch
                                        goto xit;
1364 48 robfinch
                                }
1365
                        }
1366
                }
1367
        }
1368
        // Compress ANDI ?
1369
        if (opcode6 == 0x08 && Ra == Rt && Ra != 0) {
1370
                if (val > -16 && val < 16) {
1371
                        emit_insn(
1372
                                (2 << 12) |
1373
                                (((val >> 4) & 0x0F) << 8) |
1374
                                (2 << 6) |
1375
                                (((val >> 3) & 0x1) << 5) |
1376
                                Rt, 0, 2
1377
                        );
1378 54 robfinch
                        goto xit;
1379 48 robfinch
                }
1380
        }
1381
        // Compress ORI ?
1382
        if (opcode6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Ra)) >= 0) {
1383
                if (val > -16 && val < 16) {
1384
                        emit_insn(
1385
                                (4 << 12) |
1386
                                (((val >> 1) & 0x0f) << 8) |
1387
                                (2 << 6) |
1388
                                (2 << 4) |
1389
                                ((val & 1) << 3) |
1390
                                Rtp, 0, 2
1391
                        );
1392
                }
1393 54 robfinch
                goto xit;
1394 48 robfinch
        }
1395
        if (!IsNBit(val, 14)) {
1396
                if (!IsNBit(val, 30)) {
1397
                        Lui34(val, 23);
1398
                        emit_insn(
1399
                                (val << 18) |
1400
                                (23 << 13) |
1401
                                (23 << 8) |
1402
                                (1 << 6) |
1403
                                0x09, !expand_flag, 6   // ORI
1404
                        );
1405
                        emit_insn(
1406
                                (opcode6 << 26LL) |
1407
                                (sz << 23) |            // set size to word size op
1408
                                (Rt << 18) |
1409
                                (23 << 13) |
1410
                                (Ra << 8) |
1411
                                0x02, !expand_flag, 4);
1412 54 robfinch
                        goto xit;
1413 48 robfinch
                }
1414
                emit_insn(
1415
                        (val << 18LL) |
1416
                        (Rt << 13) |
1417
                        (Ra << 8) |
1418
                        (1 << 6) |
1419
                        opcode6, !expand_flag, 6);
1420 54 robfinch
                goto xit;
1421 48 robfinch
        }
1422
        emit_insn(
1423
                (val << 18)|(Rt << 13)|(Ra << 8)|opcode6,!expand_flag,4);
1424 54 robfinch
xit:
1425
        ScanToEOL();
1426 48 robfinch
}
1427
 
1428
// ---------------------------------------------------------------------------
1429
// slti r1,r2,#1234
1430
//
1431
// A value that is too large has to be loaded into a register then the
1432
// instruction converted to a registered form.
1433
// ---------------------------------------------------------------------------
1434
 
1435
static void process_setiop(int64_t opcode6)
1436
{
1437
    int Ra;
1438
    int Rt;
1439
    char *p;
1440
    int64_t val;
1441
 
1442
    p = inptr;
1443
    Rt = getRegisterX();
1444
    need(',');
1445
    Ra = getRegisterX();
1446
    need(',');
1447
    NextToken();
1448
    val = expr();
1449
        if (!IsNBit(val, 30)) {
1450
                LoadConstant(val, 23);
1451
                switch (opcode6)
1452
                {
1453
                case 0x06:
1454
                case 0x07:
1455
                        emit_insn(
1456
                                (opcode6 << 26) |       // SLT / SLTU
1457
                                (3 << 23) |
1458
                                (Rt << 18) |
1459
                                (23 << 13) |
1460
                                (Ra << 8) |
1461
                                (0 << 6) |
1462
                                0x02, !expand_flag, 4);
1463
                        return;
1464
                case 0x2C:      // SGTI
1465
                        emit_insn(
1466
                                (0x28 << 26) |  // SLE
1467
                                (3 << 23) |
1468
                                (Rt << 18) |
1469
                                (23 << 13) |
1470
                                (Ra << 8) |
1471
                                (0 << 6) |
1472
                                0x02,!expand_flag,4)
1473
                                ;
1474
                        emit_insn(
1475
                                (0x01 << 26) |
1476
                                (3 << 23) |
1477
                                (3 << 18) |             // COM
1478
                                (Rt << 13) |
1479
                                (Ra << 8) |
1480
                                (0 << 6) |
1481
                                0x02,!expand_flag,4
1482
                        );
1483
                        return;
1484
                case 0x1C:      // SGTUI
1485
                        emit_insn(
1486
                                (0x29 << 26) |  // SLEU
1487
                                (3 << 23) |
1488
                                (Rt << 18) |
1489
                                (23 << 13) |
1490
                                (Ra << 8) |
1491
                                (0 << 6) |
1492
                                0x02, !expand_flag, 4)
1493
                                ;
1494
                        emit_insn(
1495
                                (0x01 << 26) |
1496
                                (3 << 23) |
1497
                                (3 << 18) |             // COM
1498
                                (Rt << 13) |
1499
                                (Ra << 8) |
1500
                                (0 << 6) |
1501
                                0x02, !expand_flag, 4
1502
                        );
1503
                        return;
1504
                }
1505 54 robfinch
                error("Illegal set immediate instruction");
1506 48 robfinch
                return;
1507
        }
1508
        if (!IsNBit(val, 14)) {
1509
                emit_insn(
1510
                        (val << 18) |
1511
                        (Rt << 13) | (Ra << 8) |
1512
                        (1 << 6) |
1513
                        opcode6, !expand_flag,6);
1514
                return;
1515
        }
1516
        emit_insn(
1517
                (val << 18)|
1518
                (Rt << 13)|
1519
                (Ra << 8)|
1520
                opcode6,!expand_flag,4);
1521
}
1522
 
1523
static void process_setop(int64_t opcode6)
1524
{
1525
        int Ra, Rb, Rt;
1526
        char *p;
1527
        int sz = 3;
1528
 
1529
        p = inptr;
1530
        if (*p == '.')
1531
                getSz(&sz);
1532
        sz &= 7;
1533
        Rt = getRegisterX();
1534
        need(',');
1535
        Ra = getRegisterX();
1536
        need(',');
1537
        NextToken();
1538
        Rb = getRegisterX();
1539
        if (Rb == -1) {
1540
                inptr = p;
1541
                process_setiop(opcode6);
1542
                return;
1543
        }
1544
        switch (opcode6)
1545
        {
1546
        case -6:        // SGE = !SLT
1547
        case -7:        // SGEU = !SLTU
1548
                emit_insn(
1549
                        (-opcode6 << 26) |
1550
                        (sz << 23) |
1551
                        (Rt << 18) |
1552
                        (Rb << 13) |
1553
                        (Ra << 8) |
1554
                        (0 << 6) |
1555
                        0x02, !expand_flag, 4
1556
                );
1557
                emit_insn(
1558
                        (1 << 26) |
1559
                        (sz << 23) |
1560
                        (3 << 18) |     // COM
1561
                        (Rt << 13) |
1562
                        (Ra << 8) |
1563
                        (0 << 6) |
1564
                        0x02, !expand_flag, 4
1565
                );
1566
                return;
1567
        case -0x2C:     // SGT = !SLE
1568
                emit_insn(
1569
                        (0x28 << 26) |
1570
                        (sz << 23) |
1571
                        (Rt << 18) |
1572
                        (Rb << 13) |
1573
                        (Ra << 8) |
1574
                        (0 << 6) |
1575
                        0x02, !expand_flag, 4
1576
                );
1577
                emit_insn(
1578
                        (1 << 26) |
1579
                        (sz << 23) |
1580
                        (3 << 18) |     // COM
1581
                        (Rt << 13) |
1582
                        (Ra << 8) |
1583
                        (0 << 6) |
1584
                        0x02, !expand_flag, 4
1585
                );
1586
                return;
1587
        case -0x1C:     // SGTU = !SLEU
1588
                emit_insn(
1589
                        (0x29 << 26) |
1590
                        (sz << 23) |
1591
                        (Rt << 18) |
1592
                        (Rb << 13) |
1593
                        (Ra << 8) |
1594
                        (0 << 6) |
1595
                        0x02, !expand_flag, 4
1596
                );
1597
                emit_insn(
1598
                        (1 << 26) |
1599
                        (sz << 23) |
1600
                        (3 << 18) |     // COM
1601
                        (Rt << 13) |
1602
                        (Ra << 8) |
1603
                        (0 << 6) |
1604
                        0x02, !expand_flag, 4
1605
                );
1606
                return;
1607
        }
1608
        emit_insn(
1609
                (opcode6 << 26) |
1610
                (sz << 23) |
1611
                (Rt << 18) |
1612
                (Rb << 13) |
1613
                (Ra << 8) |
1614
                (0 << 6) |
1615
                0x02, !expand_flag, 4
1616
        );
1617
}
1618
 
1619
// ---------------------------------------------------------------------------
1620
// add r1,r2,r3
1621
// ---------------------------------------------------------------------------
1622
 
1623 50 robfinch
static void process_rrop(int64_t funct6, int64_t iop)
1624 48 robfinch
{
1625
    int Ra,Rb,Rt,Rbp,Rtp;
1626
    char *p;
1627
        int sz = 3;
1628
 
1629
    p = inptr;
1630
        if (*p=='.')
1631
                getSz(&sz);
1632
    Rt = getRegisterX();
1633
    need(',');
1634
    Ra = getRegisterX();
1635
    need(',');
1636
    NextToken();
1637
    if (token=='#') {
1638 50 robfinch
                if (iop < 0 && iop!=-4)
1639 54 robfinch
                        error("Immediate mode not supported");
1640
      inptr = p;
1641
      process_riop(iop);
1642
      return;
1643 48 robfinch
    }
1644
    prevToken();
1645
    Rb = getRegisterX();
1646
        // Compress ADD
1647
        if (funct6 == 0x04 && Ra == Rt) {
1648
                emit_insn(
1649
                        (1 << 12) |
1650
                        (((Ra >> 1) & 0xF) << 8) |
1651
                        (3 << 6) |
1652
                        ((Ra & 1) << 5) |
1653
                        (Rt),
1654
                        0,2
1655
                );
1656 54 robfinch
                goto xit;
1657 48 robfinch
        }
1658
        // Compress SUB
1659
        if (funct6 == 0x05 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1660
                emit_insn(
1661
                        (4 << 12) |
1662
                        (0 << 10) |
1663
                        (((Rbp >> 1) & 0x3) << 8) |
1664
                        (2 << 6) |
1665
                        (3 << 4) |
1666
                        ((Rbp & 1) << 3) |
1667
                        (Rtp),
1668
                        0, 2
1669
                );
1670 54 robfinch
                goto xit;
1671 48 robfinch
        }
1672
        // Compress AND
1673
        if (funct6 == 0x08 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1674
                emit_insn(
1675
                        (4 << 12) |
1676
                        (1 << 10) |
1677
                        (((Rbp >> 1) & 0x3) << 8) |
1678
                        (2 << 6) |
1679
                        (3 << 4) |
1680
                        ((Rbp & 1) << 3) |
1681
                        (Rtp),
1682
                        0, 2
1683
                );
1684 54 robfinch
                goto xit;
1685 48 robfinch
        }
1686
        // Compress OR
1687
        if (funct6 == 0x09 && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1688
                emit_insn(
1689
                        (4 << 12) |
1690
                        (2 << 10) |
1691
                        (((Rbp >> 1) & 0x3) << 8) |
1692
                        (2 << 6) |
1693
                        (3 << 4) |
1694
                        ((Rbp & 1) << 3) |
1695
                        (Rtp),
1696
                        0, 2
1697
                );
1698 54 robfinch
                goto xit;
1699 48 robfinch
        }
1700
        // Compress XOR
1701
        if (funct6 == 0x0A && Ra == Rt && (Rtp = CmpReg(Rt)) >= 0 && (Rbp = CmpReg(Rb)) >= 0) {
1702
                emit_insn(
1703
                        (4 << 12) |
1704
                        (3 << 10) |
1705
                        (((Rbp >> 1) & 0x3) << 8) |
1706
                        (2 << 6) |
1707
                        (3 << 4) |
1708
                        ((Rbp & 1) << 3) |
1709
                        (Rtp),
1710
                        0, 2
1711
                );
1712 54 robfinch
                goto xit;
1713 48 robfinch
        }
1714
        //prevToken();
1715
        if (funct6==0x2E || funct6==0x2C || funct6==0x2D) {
1716
                funct6 += 0x10; // change to divmod
1717
            emit_insn((funct6<<26LL)||(1<<23)||(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
1718 54 robfinch
                goto xit;
1719 48 robfinch
        }
1720
        else if (funct6==0x3C || funct6==0x3D || funct6==0x3E) {
1721
            emit_insn((funct6<<26LL)||(0<<23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
1722 54 robfinch
                        goto xit;
1723 48 robfinch
        }
1724
    emit_insn((funct6<<26LL)|(sz << 23)|(Rt<<18)|(Rb<<13)|(Ra<<8)|0x02,!expand_flag,4);
1725 54 robfinch
xit:
1726
                ScanToEOL();
1727 48 robfinch
}
1728
 
1729
// ---------------------------------------------------------------------------
1730
// or r1,r2,r3,r4
1731
// ---------------------------------------------------------------------------
1732
 
1733
static void process_rrrop(int64_t funct6)
1734
{
1735
        int Ra, Rb, Rc = 0, Rt;
1736
        char *p;
1737
        int sz = 3;
1738
 
1739
        p = inptr;
1740
        if (*p == '.')
1741
                getSz(&sz);
1742
        Rt = getRegisterX();
1743
        need(',');
1744
        Ra = getRegisterX();
1745
        need(',');
1746
        NextToken();
1747
        if (token == '#') {
1748
                inptr = p;
1749
                process_riop(funct6);
1750
                return;
1751
        }
1752
        prevToken();
1753
        Rb = getRegisterX();
1754
        if (token == ',') {
1755
                NextToken();
1756
                Rc = getRegisterX();
1757
        }
1758
        else {
1759
                switch (funct6) {
1760
                case 0x08:      Rc = Rb; break; // and
1761
                case 0x09:      Rc = 0; break;   // or
1762
                case 0x0A:      Rc = 0; break;   // xor
1763
                }
1764
        }
1765
        emit_insn((funct6 << 34LL) | (sz << 24) | (Rt << 27) | (Rc << 18) | (Rb << 12) | (Ra << 6) | 0x42, !expand_flag, 5);
1766
}
1767
 
1768
static void process_cmove(int64_t funct6)
1769
{
1770
        int Ra, Rb, Rc = 0, Rt;
1771
        char *p;
1772
        int sz = 3;
1773
        int64_t val;
1774
 
1775
        p = inptr;
1776
        Rt = getRegisterX();
1777
        need(',');
1778
        Ra = getRegisterX();
1779
        need(',');
1780
        Rb = getRegisterX();
1781
        need(',');
1782
        NextToken();
1783
        if (token == '#') {
1784
                val = expr();
1785
                emit_insn(
1786
                        (funct6 << 42LL) |
1787
                        (1LL << 41LL) |
1788
                        (((val >> 5) & 0x7ff) << 28) |
1789
                        (Rt << 23) |
1790
                        ((val & 0x1f) << 18) |
1791
                        (Rb << 13) |
1792
                        (Ra << 8) |
1793
                        0x02, !expand_flag, 6);
1794
                return;
1795
        }
1796
        prevToken();
1797
        Rc = getRegisterX();
1798
        emit_insn((funct6 << 42LL) | (Rt << 23) | (Rc << 18) | (Rb << 13) | (Ra << 8) | 0x02, !expand_flag, 6);
1799
}
1800
 
1801
// ---------------------------------------------------------------------------
1802
// jmp main
1803
// jal [r19]
1804
// ---------------------------------------------------------------------------
1805
 
1806
static void process_jal(int64_t oc)
1807
{
1808 54 robfinch
  int64_t addr, val;
1809
  int Ra;
1810
  int Rt;
1811 48 robfinch
        bool noRt;
1812
        char *p;
1813
 
1814
        noRt = false;
1815
        Ra = 0;
1816 54 robfinch
  Rt = 0;
1817 48 robfinch
        p = inptr;
1818 54 robfinch
  NextToken();
1819 48 robfinch
        if (token == '(' || token == '[') {
1820
        j1:
1821
                Ra = getRegisterX();
1822
                if (Ra == -1) {
1823
                        printf("Expecting a register\r\n");
1824 54 robfinch
                        goto xit;
1825 48 robfinch
                }
1826
                // Simple jmp [Rn]
1827 54 robfinch
                if (token != ')' && token != ']')
1828
                        printf("Missing close bracket %d\n", lineno);
1829
                emit_insn((Ra << 8) | (Rt << 13) | 0x18, 0, 4);
1830
                goto xit;
1831 48 robfinch
        }
1832
        else
1833
                inptr = p;
1834
    Rt = getRegisterX();
1835
    if (Rt >= 0) {
1836
        need(',');
1837
        NextToken();
1838
        // jal Rt,[Ra]
1839
        if (token=='(' || token=='[')
1840
           goto j1;
1841
    }
1842
    else {
1843 54 robfinch
      Rt = 0;
1844
                        noRt = true;
1845
                }
1846
                addr = expr();
1847 48 robfinch
    // d(Rn)? 
1848
    //NextToken();
1849
    if (token=='(' || token=='[') {
1850
        Ra = getRegisterX();
1851
        if (Ra==-1) {
1852
            printf("Illegal jump address mode.\r\n");
1853
            Ra = 0;
1854
        }
1855
                if (Ra==regSP)  // program counter relative ?
1856
                        addr -= code_address;
1857
        }
1858
        val = addr;
1859
        if (IsNBit(val, 14)) {
1860
                emit_insn(
1861
                        (val << 18) |
1862
                        (Rt << 13) |
1863
                        (Ra << 8) |
1864
                        0x18, !expand_flag, 4);
1865 54 robfinch
                goto xit;
1866 48 robfinch
        }
1867
        if (IsNBit(val, 30)) {
1868
                emit_insn(
1869
                        (val << 18) |
1870
                        (Rt << 13) |
1871
                        (Ra << 8) |
1872
                        (1 << 6) |
1873
                        0x18, !expand_flag, 6);
1874 54 robfinch
                goto xit;
1875 48 robfinch
        }
1876
 
1877
        {
1878
                LoadConstant(val, 23);
1879
                if (Ra != 0) {
1880
                        // add r23,r23,Ra
1881
                        emit_insn(
1882
                                (0x04LL << 26LL) |
1883
                                (3 << 23) |
1884
                                (23 << 18) |
1885
                                (23 << 13) |
1886
                                (Ra << 8) |
1887
                                0x02, 0, 4
1888
                        );
1889
                        // jal Rt,r23
1890
                        emit_insn(
1891
                                (0 << 18) |
1892
                                (Rt << 12) |
1893
                                (23 << 8) | 0x18, !expand_flag, 4);
1894 54 robfinch
                        goto xit;
1895 48 robfinch
                }
1896
                emit_insn(
1897
                        (Rt << 12) |
1898
                        (23 << 8) | 0x18, !expand_flag, 4);
1899 54 robfinch
                goto xit;
1900 48 robfinch
        }
1901 54 robfinch
xit:
1902
        ScanToEOL();
1903 48 robfinch
}
1904
 
1905
// ---------------------------------------------------------------------------
1906
// subui r1,r2,#1234
1907
// ---------------------------------------------------------------------------
1908
/*
1909
static void process_riop(int oc)
1910
{
1911
    int Ra;
1912
    int Rt;
1913
    char *p;
1914
    int64_t val;
1915
 
1916
    p = inptr;
1917
    Rt = getRegisterX();
1918
    need(',');
1919
    Ra = getRegisterX();
1920
    need(',');
1921
    NextToken();
1922
    val = expr();
1923
 
1924
   if (lastsym != (SYM *)NULL)
1925
       emitImm16(val,!lastsym->defined);
1926
   else
1927
       emitImm16(val,0);
1928
 
1929
    emitImm16(val,lastsym!=(SYM*)NULL);
1930
    emitAlignedCode(oc);
1931
    if (bGen)
1932
    if (lastsym && !use_gp) {
1933
        if( lastsym->segment < 5)
1934
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
1935
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
1936
    }
1937
    emitCode(Ra);
1938
    emitCode(Rt);
1939
    emitCode(val & 255);
1940
    emitCode((val >> 8) & 255);
1941
}
1942
*/
1943
// ---------------------------------------------------------------------------
1944
// fabs.d r1,r2[,rm]
1945
// ---------------------------------------------------------------------------
1946
 
1947
static void process_fprop(int64_t oc)
1948
{
1949
    int Ra;
1950
    int Rt;
1951
    char *p;
1952
    int fmt;
1953
    int64_t rm;
1954
 
1955
    rm = 0;
1956
    fmt = GetFPSize();
1957
    p = inptr;
1958
    Rt = getFPRegister();
1959
    need(',');
1960
    Ra = getFPRegister();
1961
    if (token==',')
1962
       rm = getFPRoundMode();
1963
//    prevToken();
1964
        if (fmt != 2) {
1965
                emit_insn(
1966
                        (oc << 42LL) |
1967
                        ((int64_t)fmt << 31LL) |
1968
                        (rm << 28) |
1969
                        (Rt << 23) |
1970
                        (0 << 13) |
1971
                        (Ra << 8) |
1972
                        0x0F, !expand_flag, 6
1973
                );
1974
                return;
1975
        }
1976
    emit_insn(
1977
                        (oc << 26LL) |
1978
                        (rm << 23) |
1979
                        (Rt << 18)|
1980
                        (0 << 13)|
1981
                        (Ra << 8) |
1982
                        0x0F,!expand_flag,4
1983
                        );
1984
}
1985
 
1986
// ---------------------------------------------------------------------------
1987
// fabs.d r1,r2[,rm]
1988
// ---------------------------------------------------------------------------
1989
 
1990
static void process_itof(int64_t oc)
1991
{
1992
    int Ra;
1993
    int Rt;
1994
    char *p;
1995
    int fmt;
1996
    int64_t rm;
1997
 
1998
    rm = 0;
1999
    fmt = GetFPSize();
2000
    p = inptr;
2001
    Rt = getFPRegister();
2002
    need(',');
2003
    Ra = getRegisterX();
2004
    if (token==',')
2005
       rm = getFPRoundMode();
2006
//    prevToken();
2007
        if (fmt != 2) {
2008
                emit_insn(
2009
                        (oc << 42LL) |
2010
                        (fmt << 31LL) |
2011
                        (rm << 28LL) |
2012
                        (Rt << 23) |
2013
                        (0 << 13) |
2014
                        (Ra << 8) |
2015
                        0x0F, !expand_flag, 6
2016
                );
2017
                return;
2018
        }
2019
    emit_insn(
2020
                        (oc << 26LL) |
2021
                        (rm << 23LL)|
2022
                        (Rt << 18)|
2023
                        (0 << 13)|
2024
                        (Ra << 8) |
2025
                        0x0F,!expand_flag,4
2026
                        );
2027
}
2028
 
2029
static void process_ftoi(int64_t oc)
2030
{
2031
        int Ra;
2032
        int Rt;
2033
        char *p;
2034
        int fmt;
2035
        int64_t rm;
2036
 
2037
        rm = 0;
2038
        fmt = GetFPSize();
2039
        p = inptr;
2040
        Rt = getRegisterX();
2041
        need(',');
2042
        Ra = getFPRegister();
2043
        if (token == ',')
2044
                rm = getFPRoundMode();
2045
        //    prevToken();
2046
        if (fmt != 2) {
2047
                emit_insn(
2048
                        (oc << 42LL) |
2049
                        (fmt << 31LL) |
2050
                        (rm << 28LL) |
2051
                        (Rt << 23) |
2052
                        (0 << 13) |
2053
                        (Ra << 8) |
2054
                        0x0F, !expand_flag, 6
2055
                );
2056
                return;
2057
        }
2058
        emit_insn(
2059
                (oc << 26LL) |
2060
                (rm << 23LL) |
2061
                (Rt << 18) |
2062
                (0 << 13) |
2063
                (Ra << 8) |
2064
                0x0F, !expand_flag, 4
2065
        );
2066
}
2067
 
2068
// ---------------------------------------------------------------------------
2069
// fadd.d r1,r2,r12[,rm]
2070
// fcmp.d r1,r3,r10[,rm]
2071
// ---------------------------------------------------------------------------
2072
 
2073
static void process_fprrop(int64_t oc)
2074
{
2075
    int Ra;
2076
    int Rb;
2077
    int Rt;
2078
    char *p;
2079
    int fmt;
2080
    int64_t rm;
2081
 
2082
    rm = 0;
2083
    fmt = GetFPSize();
2084
    p = inptr;
2085
    if (oc==0x01)        // fcmp
2086
        Rt = getRegisterX();
2087
    else
2088
        Rt = getFPRegister();
2089
    need(',');
2090
    Ra = getFPRegister();
2091
    need(',');
2092
    Rb = getFPRegister();
2093
    if (token==',')
2094
       rm = getFPRoundMode();
2095
//    prevToken();
2096
        if (fmt != 2) {
2097
                emit_insn(
2098
                        (oc << 42LL) |
2099
                        ((int64_t)fmt << 31LL) |
2100
                        (rm << 28LL) |
2101
                        (Rt << 23) |
2102
                        (Rb << 13) |
2103
                        (Ra << 8) |
2104
                        (1 << 6) |
2105
                        0x0F, !expand_flag, 6
2106
                );
2107
                return;
2108
        }
2109
 
2110
    emit_insn(
2111
                        (oc << 26LL)|
2112
                        (rm << 23LL)|
2113
                        (Rt << 18)|
2114
                        (Rb << 13)|
2115
                        (Ra << 8) |
2116
                        0x0F,!expand_flag,4
2117
                        );
2118
}
2119
 
2120
// ---------------------------------------------------------------------------
2121
// fcx r0,#2
2122
// fdx r1,#0
2123
// ---------------------------------------------------------------------------
2124
 
2125
static void process_fpstat(int oc)
2126
{
2127
    int Ra;
2128
    int64_t bits;
2129
    char *p;
2130
 
2131
    p = inptr;
2132
    bits = 0;
2133
    Ra = getRegisterX();
2134
    if (token==',') {
2135
       NextToken();
2136
       bits = expr();
2137
    }
2138
    prevToken();
2139
        emit_insn(
2140
                ((bits & 0x3F) << 18) |
2141
                (oc << 12) |
2142
                (Ra << 6) |
2143
                0x36,!expand_flag,5
2144
                );
2145
}
2146
 
2147
// ---------------------------------------------------------------------------
2148
// not r3,r3
2149
// ---------------------------------------------------------------------------
2150
 
2151
static void process_rop(int oc)
2152
{
2153
    int Ra;
2154
    int Rt;
2155
        int sz = 3;
2156
        char *p;
2157
 
2158
        p = inptr;
2159
        if (*p == '.')
2160
                getSz(&sz);
2161
        Rt = getRegisterX();
2162
    need(',');
2163
    Ra = getRegisterX();
2164
        emit_insn(
2165
                (1LL << 26LL) |
2166
                (sz << 23) |
2167
                (oc << 18) |
2168
                (Rt << 13) |
2169
                (Ra << 8) |
2170
                0x02,!expand_flag,4
2171
                );
2172
        prevToken();
2173
}
2174
 
2175
// ---------------------------------------------------------------------------
2176
// beqi r2,#123,label
2177
// ---------------------------------------------------------------------------
2178
 
2179
static void process_beqi(int64_t opcode6, int64_t opcode3)
2180
{
2181
    int Ra, pred = 0;
2182
    int64_t val, imm;
2183
    int64_t disp;
2184
        int sz = 3;
2185
        char *p;
2186
        bool isn48 = false;
2187
 
2188
        p = inptr;
2189
        if (*p == '.')
2190
                getSz(&sz);
2191
 
2192
    Ra = getRegisterX();
2193
    need(',');
2194
    NextToken();
2195
    imm = expr();
2196
        need(',');
2197
        NextToken();
2198
        val = expr();
2199
        disp = val - (code_address + 4LL);
2200
        if (!IsNBit(disp, 11)) {
2201
                disp = val - (code_address + 6LL);
2202
                isn48 = true;
2203
        }
2204
        disp >>= 1;
2205
        if (!IsNBit(imm,8)) {
2206
                //printf("Branch immediate too large: %d %I64d", lineno, imm);
2207
                isn48 = false;
2208
                LoadConstant(imm, 23);
2209
                disp = val - (code_address + 4LL);
2210
                if (!IsNBit(disp, 11)) {
2211
                        disp = val - (code_address + 6LL);
2212
                        isn48 = true;
2213
                }
2214
                disp >>= 1;
2215
                emit_insn(
2216
                        (disp << 21LL) |
2217
                        (0x00 << 18) |          // BEQ
2218
                        (23 << 13) |
2219
                        (Ra << 8) |
2220
                        0x30, !expand_flag, isn48 ? 6 : 4
2221
                );
2222
                return;
2223
        }
2224
        emit_insn((disp << 21LL) |
2225
                ((imm & 0xFF) << 13) |
2226
                (Ra << 8) |
2227
                opcode6,!expand_flag,isn48 ? 6 : 4
2228
        );
2229
    return;
2230
}
2231
 
2232
 
2233
// ---------------------------------------------------------------------------
2234
// beq r1,r2,label
2235
// bne r2,r3,r4
2236
//
2237
// When opcode4 is negative it indicates to swap the a and b registers. This
2238
// allows source code to use alternate forms of branch conditions.
2239
// ---------------------------------------------------------------------------
2240
 
2241
static void process_bcc(int opcode6, int opcode4)
2242
{
2243 54 robfinch
  int Ra, Rb, pred;
2244 48 robfinch
        int fmt;
2245 54 robfinch
  int64_t val;
2246
  int64_t disp, cdisp;
2247 48 robfinch
        char *p1;
2248
        bool ins48 = false;
2249
 
2250 54 robfinch
  fmt = GetFPSize();
2251 48 robfinch
        pred = 0;
2252
        p1 = inptr;
2253 54 robfinch
  Ra = getRegisterX();
2254
  need(',');
2255
  Rb = getRegisterX();
2256
  need(',');
2257 48 robfinch
        NextToken();
2258
        if (token=='#' && opcode4==0) {
2259
                inptr = p1;
2260
                process_beqi(0x32,0);
2261
                return;
2262
        }
2263
        val = expr();
2264
        disp = val - (code_address + 4);
2265 54 robfinch
        cdisp = val - (code_address + 2);
2266 48 robfinch
        if (!IsNBit(disp, 12)) {
2267 54 robfinch
                error("Branch displacement too large");
2268 48 robfinch
                disp = val - (code_address + 6);
2269
                ins48 = true;
2270
        }
2271
        disp >>= 1;
2272 54 robfinch
        cdisp >>= 1;
2273 48 robfinch
        // Check for compressed bnez
2274 54 robfinch
        if (opcode4 == 1 && Rb == 0 && IsNBit(cdisp,7)) {
2275 48 robfinch
                emit_insn(
2276
                        (3 << 14) |
2277 54 robfinch
                        (((cdisp >> 1) & 0x3f) << 8) |
2278 48 robfinch
                        (2 << 6) |
2279 54 robfinch
                        ((cdisp & 1) << 5) |
2280 48 robfinch
                        Ra,0,2
2281
                );
2282
                return;
2283
        }
2284
        // compressed beqz
2285 54 robfinch
        if (opcode4 == 0 && Rb == 0 && IsNBit(cdisp, 7)) {
2286 48 robfinch
                emit_insn(
2287
                        (2 << 14) |
2288 54 robfinch
                        (((cdisp >> 1) & 0x3f) << 8) |
2289 48 robfinch
                        (2 << 6) |
2290 54 robfinch
                        ((cdisp & 1) << 5) |
2291 48 robfinch
                        Ra, 0, 2
2292
                );
2293
                return;
2294
        }
2295
        if (opcode4 < 0) {
2296
                opcode4 = -opcode4;
2297
                emit_insn((disp << 21LL) |
2298
                        (opcode4 << 18) |
2299
                        (Ra << 13) |
2300
                        (Rb << 8) |
2301
                        (ins48 << 6) |
2302
                        opcode6,!expand_flag,ins48 ? 6 : 4
2303
                );
2304
                return;
2305
        }
2306
        emit_insn((disp << 21LL) |
2307
                (opcode4 << 18) |
2308
                (Rb << 13) |
2309
                (Ra << 8) |
2310
                (ins48 << 6) |
2311
                opcode6, !expand_flag, ins48 ? 6 : 4
2312
        );
2313
        return;
2314
}
2315
 
2316
// ---------------------------------------------------------------------------
2317
// dbnz r1,label
2318
//
2319
// ---------------------------------------------------------------------------
2320
 
2321
static void process_dbnz(int opcode6, int opcode3)
2322
{
2323
    int Ra, Rc, pred;
2324
    int64_t val;
2325
    int64_t disp;
2326
        char *p1;
2327
        int sz = 3;
2328
        char *p;
2329
 
2330
        p = inptr;
2331
        if (*p == '.')
2332
                getSz(&sz);
2333
 
2334
        pred = 3;               // default: statically predict as always taken
2335
        p1 = inptr;
2336
    Ra = getRegisterX();
2337
    need(',');
2338
        p = inptr;
2339
        Rc = getRegisterX();
2340
        if (Rc==-1) {
2341
                inptr = p;
2342
            NextToken();
2343
                val = expr();
2344
                disp = val - (code_address + 4LL);
2345 54 robfinch
                disp >>= 1LL;
2346 48 robfinch
                emit_insn(
2347
                        (disp << 21LL) |
2348
                        ((opcode3 & 3) << 19) |
2349
                        (0 << 13) |
2350
                        (Ra << 8) |
2351
                        opcode6,!expand_flag,4
2352
                );
2353
                return;
2354
        }
2355 54 robfinch
        error("dbnz: target must be a label");
2356 48 robfinch
        emit_insn(
2357
                (opcode3 << 19) |
2358
                (0 << 13) |
2359
                (Ra << 8) |
2360
                opcode6,!expand_flag,4
2361
        );
2362
}
2363
 
2364
// ---------------------------------------------------------------------------
2365
// ibne r1,r2,label
2366
//
2367
// ---------------------------------------------------------------------------
2368
 
2369
static void process_ibne(int opcode6, int opcode3)
2370
{
2371
    int Ra, Rb, Rc, pred;
2372
    int64_t val;
2373
    int64_t disp;
2374
        char *p1;
2375
        int sz = 3;
2376
        char *p;
2377
        bool isn48 = false;
2378
 
2379
        p = inptr;
2380
        if (*p == '.')
2381
                getSz(&sz);
2382
 
2383
        pred = 3;               // default: statically predict as always taken
2384
        p1 = inptr;
2385
    Ra = getRegisterX();
2386
    need(',');
2387
    Rb = getRegisterX();
2388
    need(',');
2389
        p = inptr;
2390
        Rc = getRegisterX();
2391
        if (Rc==-1) {
2392
                inptr = p;
2393
            NextToken();
2394
                val = expr();
2395
                disp = val - (code_address + 4LL);
2396
                disp >>= 1;
2397
                if (!IsNBit(disp, 11)) {
2398
                        isn48 = true;
2399
                        disp = val - (code_address + 6LL);
2400
                        disp >>= 1;
2401
                }
2402
            emit_insn((disp << 21LL) |
2403
                        ((opcode3 & 3) << 19) |
2404
                        (Rb << 13) |
2405
                        (Ra << 8) |
2406
                        opcode6,!expand_flag,isn48 ? 6 : 4
2407
                );
2408
                return;
2409
        }
2410 54 robfinch
        error("ibne: target must be a label");
2411 48 robfinch
        emit_insn(
2412
                (opcode3 << 19) |
2413
                (Rb << 13) |
2414
                (Ra << 8) |
2415
                0x03,!expand_flag,4
2416
        );
2417
}
2418
 
2419
// ---------------------------------------------------------------------------
2420 54 robfinch
// bfextu r1,#1,#63,r2
2421 48 robfinch
// ---------------------------------------------------------------------------
2422
 
2423
static void process_bitfield(int64_t oc)
2424
{
2425 54 robfinch
        int Ra, Rb, Rc;
2426
        int Rt;
2427
        int64_t mb;
2428
        int64_t me;
2429 48 robfinch
        int64_t val;
2430 54 robfinch
        int64_t op;
2431 48 robfinch
        int sz = 3;
2432
        char *p;
2433 54 robfinch
        bool gmb, gme, gval;
2434 48 robfinch
 
2435 54 robfinch
        gmb = gme = gval = false;
2436 48 robfinch
        p = inptr;
2437
        if (*p == '.')
2438
                getSz(&sz);
2439
 
2440 54 robfinch
        Rt = getRegisterX();
2441
        need(',');
2442
        p = inptr;
2443
        Ra = getRegisterX();
2444
        if (Ra == -1) {
2445
                inptr = p;
2446 48 robfinch
                NextToken();
2447 54 robfinch
                mb = expr();
2448
                gmb = true;
2449
        }
2450
        need(',');
2451
        p = inptr;
2452
        Rb = getRegisterX();
2453
        if (Rb == -1) {
2454
                inptr = p;
2455
                NextToken();
2456
                me = expr();
2457
                gme = true;
2458
        }
2459
        need(',');
2460
        p = inptr;
2461
        Rc = getRegisterX();
2462
        if (Rc == -1) {
2463
                inptr = p;
2464
                NextToken();
2465 48 robfinch
                val = expr();
2466 54 robfinch
                gval = true;
2467 48 robfinch
        }
2468 54 robfinch
        op =
2469
                (oc << 44LL) |
2470
                ((gval?1LL:0LL) << 32LL) |
2471
                ((gme?1LL:0LL) << 31LL) |
2472
                ((gmb?1:0) << 30) |
2473
                (Rt << 23) |
2474
                (1 << 6) |
2475
                0x22;
2476
        if (gmb)
2477
                op |= ((mb & 31) << 8) | (((mb >> 5) & 1) << 28);
2478
        else
2479
                op |= (Ra << 8);
2480
        if (gme)
2481
                op |= ((me & 31) << 13) | (((me >> 5) & 1) << 29);
2482
        else
2483
                op |= (Rb << 13);
2484
        if (gval)
2485
                op |= ((val & 31) << 18) | (((val >> 5) & 0x7ff) << 33LL);
2486
        else
2487
                op |= (Rc << 18);
2488
 
2489
        emit_insn(op, 0, 6);
2490
        ScanToEOL();
2491 48 robfinch
}
2492
 
2493
 
2494
// ---------------------------------------------------------------------------
2495
// bra label
2496
// ---------------------------------------------------------------------------
2497
 
2498
static void process_bra(int oc)
2499
{
2500
    int Ra = 0, Rb = 0;
2501
    int64_t val;
2502 54 robfinch
    int64_t disp, cdisp;
2503 48 robfinch
        bool ins48 = false;
2504
 
2505
    NextToken();
2506
    val = expr();
2507
    disp = val - (code_address + 4LL);
2508 54 robfinch
        cdisp = val - (code_address + 2LL);
2509 48 robfinch
        if (!IsNBit(disp, 12)) {
2510 54 robfinch
                error("Branch displacement too large");
2511 48 robfinch
                disp = val - (code_address + 6LL);
2512
                ins48 = true;
2513
        }
2514
        disp >>= 1;
2515 54 robfinch
        cdisp >>= 1;
2516
        if (cdisp > -512 && cdisp < 512) {      // disp+1 accounts for instruction size of 2 not 4
2517 48 robfinch
                emit_insn(
2518
                        (7 << 12) |
2519 54 robfinch
                        (((cdisp >> 6) & 0xf) << 8) |
2520 48 robfinch
                        (2 << 6) |
2521 54 robfinch
                        (cdisp & 0x3f), 0, 2
2522 48 robfinch
                );
2523
                return;
2524
        }
2525
        emit_insn((disp << 21) |
2526
                (0 << 18) |      // BEQ
2527
        (0 << 13) |
2528
        (0 << 8) |
2529
        0x30,!expand_flag,4
2530
    );
2531
}
2532
 
2533
// ----------------------------------------------------------------------------
2534
// chk r1,r2,r3,label
2535
// ----------------------------------------------------------------------------
2536
 
2537
static void process_chk(int opcode6)
2538
{
2539
        int Ra;
2540
        int Rb;
2541
        int Rc;
2542
        int64_t val, disp;
2543
 
2544
        Ra = getRegisterX();
2545
        need(',');
2546
        Rb = getRegisterX();
2547
        need(',');
2548
        Rc = getRegisterX();
2549
        need(',');
2550
        NextToken();
2551
        val = expr();
2552
    disp = val - code_address;
2553
        emit_insn(((disp >> 3) & 0x3FF) << 22 |
2554
                (Rc << 16) |
2555
                (Rb << 11) |
2556
                (Ra << 6) |
2557
                ((disp >> 2) & 1) |
2558
                opcode6,!expand_flag,4
2559
        );
2560
}
2561
 
2562
 
2563
static void process_chki(int opcode6)
2564
{
2565
        int Ra;
2566
        int Rb;
2567
        int64_t val, disp;
2568
 
2569
        Ra = getRegisterX();
2570
        need(',');
2571
        Rb = getRegisterX();
2572
        need(',');
2573
        NextToken();
2574
        val = expr();
2575
    disp = val - code_address;
2576
        if (val < LB16 || val > 32767LL) {
2577
                emit_insn((0x8000 << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
2578
                emit_insn(val,!expand_flag,2);
2579
                return;
2580
        }
2581
        emit_insn(((val & 0xFFFF) << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
2582
}
2583
 
2584
 
2585
// ---------------------------------------------------------------------------
2586
// fbeq.q fp1,fp0,label
2587
// ---------------------------------------------------------------------------
2588
 
2589
static void process_fbcc(int64_t opcode3)
2590
{
2591
    int Ra, Rb;
2592
    int64_t val;
2593
    int64_t disp;
2594
        int sz;
2595
        bool ins48 = false;
2596
 
2597
    sz = GetFPSize();
2598
    Ra = getFPRegister();
2599
    need(',');
2600
    Rb = getFPRegister();
2601
    need(',');
2602
    NextToken();
2603
 
2604
    val = expr();
2605
        disp = val - (code_address + 4);
2606
        if (!IsNBit(disp, 12)) {
2607
                disp = val - (code_address + 6);
2608
                ins48 = true;
2609
        }
2610
        disp >>= 1;
2611
        emit_insn(
2612
                (disp << 21LL) |
2613
                (opcode3 << 18) |
2614
                (Rb << 13) |
2615
                (Ra << 8) |
2616
                ((ins48 ? 1 : 0) << 6) |
2617
                0x05, !expand_flag, ins48 ? 6 : 4
2618
    );
2619
}
2620
 
2621
// ---------------------------------------------------------------------------
2622
// ---------------------------------------------------------------------------
2623
 
2624
static void process_call(int opcode)
2625
{
2626
        int64_t val;
2627
        int Ra = 0;
2628
 
2629
    NextToken();
2630
        if (token == '[')
2631
                val = 0;
2632
        else
2633
                val = expr();
2634
        if (token=='[') {
2635
                Ra = getRegisterX();
2636
                need(']');
2637
                if (Ra==31) {
2638
                        val -= code_address;
2639
                }
2640
        }
2641
        if (val==0) {
2642
                if (opcode==0x28)       // JMP [Ra]
2643
                        // jal r0,[Ra]
2644
                        emit_insn(
2645
                                (Ra << 6) |
2646
                                0x18,!expand_flag,4
2647
                        );
2648
                else
2649
                        // jal lr,[Ra]  - call [Ra]
2650
                        //emit_insn(
2651
                        //      (29 << 13) |
2652
                        //      (Ra << 8) |
2653
                        //      0x18,!expand_flag,4
2654
                        //);
2655
                        emit_insn(
2656
                                (2 << 12) |
2657
                                (((29 >> 1) & 0xf) << 8) |
2658
                                (3 << 6) |
2659
                                ((29 & 1) << 5) |
2660
                                Ra,0,2
2661
                        );
2662
                return;
2663
        }
2664
        if (code_bits > 27 && !IsNBit(val,40)) {
2665
                LoadConstant(val,23);
2666
                if (Ra!=0) {
2667
                        // add r23,r23,Ra
2668
                        emit_insn(
2669
                                (0x04 << 26) |
2670
                                (23 << 18) |
2671
                                (23 << 13) |
2672
                                (Ra << 8) |
2673
                                0x02,!expand_flag,4
2674
                                );
2675
                }
2676
                if (opcode==0x28)       // JMP
2677
                        // jal r0,[r23]
2678
                        emit_insn(
2679
                                (23 << 8) |
2680
                                0x18,!expand_flag,4
2681
                                );
2682
                else
2683
                        // jal lr,[r23] - call [r23]
2684
                        emit_insn(
2685
                                (29 << 13) |
2686
                                (23 << 8) |
2687
                                0x18,!expand_flag,4
2688
                                );
2689
                return;
2690
        }
2691
        if (!IsNBit(val, 24)) {
2692
                emit_insn(
2693
                        ((((val >> 1) & 0xFFFFFFFFFFLL)) << 8) |
2694
                        (1 << 6) |
2695
                        opcode, !expand_flag, 4
2696
                );
2697
                return;
2698
        }
2699
        emit_insn(
2700
                ((((val >> 1) & 0xFFFFFFLL)) << 8) |
2701
                opcode,!expand_flag,4
2702
                );
2703
}
2704
 
2705
static void process_iret(int op)
2706
{
2707
        int64_t val = 0;
2708
 
2709
    NextToken();
2710
        if (token=='#') {
2711
                val = expr();
2712
        }
2713
        emit_insn(
2714
                ((val & 0x3F) << 18) |
2715
                (0 << 12) |
2716
                (0 << 6) |
2717
                op,!expand_flag,5
2718
        );
2719
}
2720
 
2721
static void process_ret()
2722
{
2723
        int64_t val = 0;
2724
        bool ins48 = false;
2725
 
2726
    NextToken();
2727
        if (token=='#') {
2728
                val = expr();
2729
        }
2730
        // Compress ?
2731
        if (val >= 0 && val < 256) {
2732
                emit_insn(
2733
                        (2 << 12) |
2734
                        (((val >> 4) & 0x0F) << 8) |
2735 50 robfinch
                        (2 << 6) |
2736 48 robfinch
                        (((val >> 3) & 1) << 5),
2737
                        0, 2
2738
                );
2739
                return;
2740
        }
2741
        // If too large a constant, do the SP adjusment directly.
2742
        if (!IsNBit(val,30)) {
2743
                LoadConstant(val,23);
2744
                // add.w r63,r63,r23
2745
                emit_insn(
2746
                        (0x04LL << 26LL) |
2747
                        (3 << 23) |
2748
                        (regSP << 18) |
2749
                        (23 << 13) |
2750
                        (regSP << 8) |
2751
                        0x02,!expand_flag,4
2752
                        );
2753
                val = 0;
2754
        }
2755
        ins48 = !IsNBit(val, 14);
2756
        emit_insn(
2757
                (val << 18LL) |
2758
                (regLR << 13) |
2759
                (regSP << 8) |
2760
                (ins48 << 6) |
2761
                0x29,!expand_flag, ins48 ? 6 : 4
2762
        );
2763
}
2764
 
2765
// ----------------------------------------------------------------------------
2766
// inc -8[bp],#1
2767
// ----------------------------------------------------------------------------
2768
 
2769
static void process_inc(int64_t oc)
2770
{
2771
    int Ra;
2772
    int Rb;
2773
        int Sc;
2774
    int64_t incamt;
2775
    int64_t disp;
2776
    char *p;
2777
    int fixup = 5;
2778
    int neg = 0;
2779
 
2780
        if (oc == 0x25) neg = 1;
2781
        NextToken();
2782
    p = inptr;
2783
    mem_operand(&disp, &Ra, &Rb, &Sc);
2784
    incamt = 1;
2785
        if (token==']')
2786
       NextToken();
2787
    if (token==',') {
2788
        NextToken();
2789
        incamt = expr();
2790
        prevToken();
2791
    }
2792
        if (neg) incamt = -incamt;
2793
        if (Rb >= 0) {
2794
       if (disp != 0)
2795 54 robfinch
           error("displacement not allowed with indexed addressing");
2796 48 robfinch
       oc = 0x1A;  // INCX
2797
           // ToDo: fix this
2798
       emit_insn(
2799
                   (oc << 26LL) |
2800
                   (0 << 23) |           // Sc = 0
2801
                   (incamt << 18) |
2802
                   (23 << 13) |
2803
                   (Ra << 8) |
2804
                   0x16, !expand_flag, 4
2805
           );
2806
       return;
2807
    }
2808
    oc = 0x1A;        // INC
2809
    if (Ra < 0) Ra = 0;
2810
        incamt &= 31;
2811
        if (!IsNBit(disp, 30)) {
2812
                LoadConstant(disp, 23);
2813
                // Change to indexed addressing
2814
                emit_insn(
2815
                        (oc << 26LL) |
2816
                        (0 << 23) |              // Sc = 0
2817
                        (incamt << 18) |
2818
                        (23 << 13) |
2819
                        (Ra << 8) |
2820
                        0x16, !expand_flag, 4);
2821
                ScanToEOL();
2822
                return;
2823
        }
2824
        if (!IsNBit(disp, 14)) {
2825
                emit_insn(
2826
                        (disp << 18LL) |
2827
                        (incamt << 13) |
2828
                        (Ra << 8) |
2829
                        (1 << 6) |
2830
                        oc, !expand_flag, 6);
2831
                ScanToEOL();
2832
                return;
2833
        }
2834
        emit_insn(
2835
                (disp << 18LL) |
2836
                (incamt << 13) |
2837
                (Ra << 8) |
2838
                oc, !expand_flag, 4);
2839
        ScanToEOL();
2840
}
2841
 
2842
// ---------------------------------------------------------------------------
2843
// ---------------------------------------------------------------------------
2844
 
2845
static void process_brk()
2846
{
2847
        int64_t val;
2848
        int inc = 1;
2849
        int Ra = -1;
2850
 
2851
        Ra = getRegisterX();
2852
        if (Ra == -1) {
2853
                NextToken();
2854
                val = expr();
2855
                NextToken();
2856
                if (token == ',') {
2857
                        inc = (int)expr();
2858
                }
2859
                else
2860
                        prevToken();
2861
                emit_insn(
2862
                        ((inc & 0x1f) << 19) |
2863
                        ((val & 0x1FFLL) << 6) |
2864
                        0x00, !expand_flag, 5
2865
                );
2866
                return;
2867
        }
2868
        NextToken();
2869
        if (token == ',') {
2870
                inc = (int)expr();
2871
        }
2872
        else
2873
                prevToken();
2874
        emit_insn(
2875
                ((inc & 0x1f) << 19) |
2876
                (1 << 15) |
2877
                ((Ra & 0x3FLL) << 6) |
2878
                0x00, !expand_flag, 5
2879
        );
2880
}
2881
 
2882
// ---------------------------------------------------------------------------
2883
// ---------------------------------------------------------------------------
2884
 
2885
static void GetIndexScale(int *sc)
2886
{
2887
      int64_t val;
2888
 
2889
      NextToken();
2890
      val = expr();
2891
      prevToken();
2892
      switch(val) {
2893
      case 0: *sc = 0; break;
2894
      case 1: *sc = 0; break;
2895
      case 2: *sc = 1; break;
2896
      case 4: *sc = 2; break;
2897
      case 8: *sc = 3; break;
2898
      default: printf("Illegal scaling factor.\r\n");
2899
      }
2900
}
2901
 
2902
 
2903
// ---------------------------------------------------------------------------
2904
// expr
2905
// expr[Reg]
2906
// [Reg]
2907
// [Reg+Reg]
2908
// ---------------------------------------------------------------------------
2909
 
2910
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc)
2911
{
2912
     int64_t val;
2913
 
2914
     // chech params
2915
     if (disp == (int64_t *)NULL)
2916
         return;
2917
     if (regA == (int *)NULL)
2918
         return;
2919
         if (regB == (int *)NULL)
2920
                 return;
2921
         if (Sc == (int *)NULL)
2922
                 return;
2923
 
2924
     *disp = 0;
2925
     *regA = -1;
2926
         *regB = -1;
2927
         *Sc = 0;
2928
     if (token!='[') {;
2929
          val = expr();
2930
          *disp = val;
2931
     }
2932
     if (token=='[') {
2933
         *regA = getRegisterX();
2934
         if (*regA == -1) {
2935
             printf("expecting a register\r\n");
2936
         }
2937
                 if (token=='+') {
2938
                         *regB = getRegisterX();
2939
                         if (*regB == -1) {
2940
                                 printf("expecting a register\r\n");
2941
                         }
2942
              if (token=='*') {
2943
                  GetIndexScale(Sc);
2944
              }
2945
                 }
2946
         need(']');
2947
     }
2948
}
2949
 
2950
static void mem_voperand(int64_t *disp, int *regA, int *regB)
2951
{
2952
     int64_t val;
2953
 
2954
     // chech params
2955
     if (disp == (int64_t *)NULL)
2956
         return;
2957
     if (regA == (int *)NULL)
2958
         return;
2959
 
2960
     *disp = 0;
2961
     *regA = -1;
2962
         *regB = -1;
2963
     if (token!='[') {;
2964
          val = expr();
2965
          *disp = val;
2966
     }
2967
     if (token=='[') {
2968
         *regA = getRegisterX();
2969
         if (*regA == -1) {
2970
             printf("expecting a register\r\n");
2971
         }
2972
                 if (token=='+') {
2973
                         *regB = getVecRegister();
2974
                         if (*regB == -1) {
2975
                                 printf("expecting a vector register: %d\r\n", lineno);
2976
                         }
2977
                 }
2978
         need(']');
2979
     }
2980
}
2981
 
2982
// ---------------------------------------------------------------------------
2983
// If the displacement is too large the instruction is converted to an
2984
// indexed form and the displacement loaded into a second register.
2985
//
2986
// So
2987
//      sw   r2,$12345678[r2]
2988
// Becomes:
2989
//              ori  r23,r0,#$5678
2990
//      orq1 r23,#$1234
2991
//      sw   r2,[r2+r23]
2992
//
2993
// sw disp[r1],r2
2994
// sw [r1+r2],r3
2995
// ----------------------------------------------------------------------------
2996
 
2997
static void process_store(int64_t opcode6, int sz)
2998
{
2999 55 robfinch
  int Ra,Rb;
3000
  int Rs;
3001 48 robfinch
        int Sc;
3002 55 robfinch
  int64_t disp,val;
3003 48 robfinch
        int64_t aq = 0, rl = 0;
3004
        int ar;
3005
 
3006
        GetArBits(&aq, &rl);
3007
        ar = (int)((aq << 1LL) | rl);
3008
        Rs = getRegisterX();
3009 55 robfinch
  if (Rs < 0) {
3010
      printf("Expecting a source register (%d).\r\n", lineno);
3011
      printf("Line:%.60s\r\n",inptr);
3012
      ScanToEOL();
3013
      return;
3014
  }
3015
  expect(',');
3016
  mem_operand(&disp, &Ra, &Rb, &Sc);
3017 48 robfinch
        if (Ra > 0 && Rb > 0) {
3018
                switch (sz) {
3019
                case 1: opcode6 = 0x24; break;  // SCX
3020
                case 2: opcode6 = 0x14; break;  // SHX
3021
                case 4: opcode6 = 0x16; break;  // SWX
3022
                default:;
3023
                }
3024
                emit_insn(
3025
                        (opcode6 << 26LL) |
3026
                        (Sc << 23) |
3027
                        (Rs << 18) |
3028
                        (Rb << 13) |
3029
                        (Ra << 8) |
3030
                        0x16,!expand_flag,4);
3031
                return;
3032
        }
3033 55 robfinch
  if (Ra < 0) Ra = 0;
3034
  val = disp;
3035 48 robfinch
        if (Ra == 55)
3036
                val -= program_address;
3037
        if (sz == 4 && Ra == regSP) {
3038
                if ((val & 7) == 0) {
3039
                        if (val >= -128 && val < 128) {
3040
                                emit_insn(
3041
                                        (((val >> 4) & 0x0F) << 8) |
3042
                                        (9 << 12) |
3043
                                        (3 << 6) |
3044
                                        (((val >> 3) & 0x1) << 5) |
3045
                                        Rs, 0, 2
3046
                                );
3047
                                ScanToEOL();
3048
                                return;
3049
                        }
3050
                }
3051
        }
3052
        if (sz == 4 && Ra == regFP) {
3053
                if ((val & 7) == 0) {
3054
                        if (val >= -128 && val < 128) {
3055
                                emit_insn(
3056
                                        (((val >> 4) & 0x0F) << 8) |
3057
                                        (11 << 12) |
3058
                                        (3 << 6) |
3059
                                        (((val >> 3) & 0x1) << 5) |
3060
                                        Rs, 0, 2
3061
                                );
3062
                                ScanToEOL();
3063
                                return;
3064
                        }
3065
                }
3066
        }
3067
        if (!IsNBit(val,30)) {
3068
                LoadConstant(val,23);
3069
                // Change to indexed addressing
3070
                switch (sz) {
3071
                case 1: opcode6 = 0x24; break;
3072
                case 2: opcode6 = 0x14; break;
3073
                case 4: opcode6 = 0x16; break;
3074
                default: opcode6 = 0x15;
3075
                }
3076
                emit_insn(
3077
                        (opcode6 << 26LL) |
3078
                        (0 << 23) |              // Sc
3079
                        (Rs << 18) |
3080
                        (23 << 13) |
3081
                        (Ra << 8) |
3082 55 robfinch
                        0x16,!expand_flag,4);
3083 48 robfinch
                ScanToEOL();
3084
                return;
3085
        }
3086
        if (!IsNBit(val, 14)) {
3087
                emit_insn(
3088
                        ((val|sz) << 18) |
3089
                        (Rs << 13) |
3090
                        (Ra << 8) |
3091
                        (1 << 6) |
3092
                        opcode6, !expand_flag, 6);
3093
                ScanToEOL();
3094
                return;
3095
        }
3096
        emit_insn(
3097
                ((val|sz) << 18) |
3098
                (Rs << 13) |
3099
                (Ra << 8) |
3100
                opcode6,!expand_flag,4);
3101
    ScanToEOL();
3102
}
3103
/*
3104
static void process_storepair(int64_t opcode6)
3105
{
3106
        int Ra, Rb;
3107
        int Rs, Rs2;
3108
        int Sc;
3109
        int64_t disp, val;
3110
        int64_t aq = 0, rl = 0;
3111
        int ar;
3112
 
3113
        GetArBits(&aq, &rl);
3114
        ar = (int)((aq << 1LL) | rl);
3115
        Rs = getRegisterX();
3116
        if (Rs < 0) {
3117
                printf("Expecting a source register (%d).\r\n", lineno);
3118
                printf("Line:%.60s\r\n", inptr);
3119
                ScanToEOL();
3120
                return;
3121
        }
3122
        expect(',');
3123
        Rs2 = getRegisterX();
3124
        expect(',');
3125
        mem_operand(&disp, &Ra, &Rb, &Sc);
3126
        if (Ra > 0 && Rb > 0) {
3127
                emit_insn(
3128
                        (opcode6 << 34LL) |
3129
                        (ar << 26) |
3130
                        (Sc << 24) |
3131
                        (Rs << 18) |
3132
                        (Rb << 12) |
3133
                        (Ra << 6) |
3134
                        0x02, !expand_flag, 5);
3135
                return;
3136
        }
3137
        if (Ra < 0) Ra = 0;
3138
        val = disp;
3139
        if (Ra == 55)
3140
                val -= program_address;
3141
        if (!IsNBit(val, 14)) {
3142
                LoadConstant(val, 52);
3143
                // Change to indexed addressing
3144
                emit_insn(
3145
                        (opcode6 << 34LL) |
3146
                        (ar << 26) |
3147
                        (0 << 24) |             // Sc
3148
                        (Rs << 18) |
3149
                        (52 << 12) |
3150
                        (Ra << 6) |
3151
                        0x02, !expand_flag, 5);
3152
                ScanToEOL();
3153
                return;
3154
        }
3155
        emit_insn(
3156
                (val << 26LL) |
3157
                (ar << 24) |
3158
                (Rs2 << 18) |
3159
                (Rs << 12) |
3160
                (Ra << 6) |
3161
                opcode6, !expand_flag, 5, true);
3162
        ScanToEOL();
3163
}
3164
*/
3165
static void process_sv(int64_t opcode6)
3166
{
3167
    int Ra,Vb;
3168
    int Vs;
3169
    int64_t disp,val;
3170
        int64_t aq = 0, rl = 0;
3171
        int ar = 0;
3172
 
3173
        GetArBits(&aq, &rl);
3174
        ar = (int)((aq << 1LL) | rl);
3175
        Vs = getVecRegister();
3176
    if (Vs < 0 || Vs > 63) {
3177
        printf("Expecting a vector source register (%d).\r\n", lineno);
3178
        printf("Line:%.60s\r\n",inptr);
3179
        ScanToEOL();
3180
        return;
3181
    }
3182
    expect(',');
3183
    mem_voperand(&disp, &Ra, &Vb);
3184
        if (Ra > 0 && Vb > 0) {
3185
                emit_insn(
3186
                        (opcode6 << 34LL) |
3187
                        (ar << 26) |
3188
                        (Vs << 18) |
3189
                        (Vb << 12) |
3190
                        (Ra << 6) |
3191
                        0x02,!expand_flag,5);
3192
                return;
3193
        }
3194
    if (Ra < 0) Ra = 0;
3195
    val = disp;
3196
        //if (val < -32768 || val > 32767)
3197
        //      printf("SV displacement too large: %d\r\n", lineno);
3198
        if (!IsNBit(val, 20)) {
3199
                LoadConstant(val, 52);
3200
                // ToDo: store with indexed addressing
3201
                return;
3202
        }
3203
        emit_insn(
3204
                (val << 20) |
3205
                (ar << 18) |
3206
                (Vs << 12) |
3207
                (Ra << 6) |
3208
                opcode6,!expand_flag,5);
3209
    ScanToEOL();
3210
}
3211
 
3212
// ----------------------------------------------------------------------------
3213
// ----------------------------------------------------------------------------
3214
 
3215
static void process_ldi()
3216
{
3217 54 robfinch
  int Ra = 0;
3218
  int Rt;
3219
  int64_t val;
3220 48 robfinch
        char *p;
3221
        int sz = 3;
3222
 
3223 54 robfinch
  p = inptr;
3224 48 robfinch
        if (*p=='.')
3225
                getSz(&sz);
3226
        sz &= 3;
3227 54 robfinch
  Rt = getRegisterX();
3228
  expect(',');
3229
  val = expr();
3230 48 robfinch
        if (IsNBit(val, 5) && Rt != 0) {
3231
                emit_insn(
3232
                        (1 << 12) |
3233
                        (((val >> 1) & 0x0f) << 8)|
3234
                        (2 << 6) |
3235
                        ((val & 1) << 5) |
3236
                        Rt,
3237
                        !expand_flag,2
3238
                );
3239
                return;
3240
        }
3241
        if (IsNBit(val, 14)) {
3242
                emit_insn(
3243
                        (val << 18LL) |
3244
                        (Rt << 13) |
3245
                        (0 << 8) |               // ADDI
3246
                        0x04, !expand_flag, 4);
3247
                return;
3248
        }
3249
        if (IsNBit(val, 30)) {
3250
                emit_insn(
3251
                        (val << 18LL) |
3252
                        (Rt << 13) |
3253
                        (0 << 8) |               // ADDI
3254
                        (1 << 6) |
3255
                        0x04, !expand_flag, 6);
3256
                return;
3257
        }
3258
        if (IsNBit(val, 49)) {
3259
                emit_insn(
3260
                        ((val >> 30LL) << 13LL) |
3261
                        (Rt << 8) |
3262
                        (0 << 6) |
3263
                        0x27, !expand_flag, 4
3264
                );
3265
                emit_insn(
3266
                        (val << 18LL) |
3267
                        (Rt << 13) |
3268
                        (0 << 8) |               // ORI
3269
                        (1 << 6) |
3270
                        0x09, !expand_flag, 6);
3271
                return;
3272
        }
3273
        // 64 bit constant
3274
        emit_insn(
3275
                ((val >> 30LL) << 13LL) |
3276
                (Rt << 8) |
3277
                (1 << 6) |
3278
                0x27, !expand_flag, 6
3279
        );
3280
        emit_insn(
3281
                (val << 18LL) |
3282
                (Rt << 13) |
3283
                (0 << 8) |               // ORI
3284
                (1 << 6) |
3285
                0x09, !expand_flag, 6);
3286
        return;
3287
}
3288
 
3289
// ----------------------------------------------------------------------------
3290
// link #-40
3291
// ----------------------------------------------------------------------------
3292
 
3293
// ----------------------------------------------------------------------------
3294
// lw r1,disp[r2]
3295
// lw r1,[r2+r3]
3296
// ----------------------------------------------------------------------------
3297
 
3298
static void process_load(int64_t opcode6, int sz)
3299
{
3300 55 robfinch
  int Ra,Rb;
3301
  int Rt;
3302 48 robfinch
        int Sc;
3303 55 robfinch
  char *p;
3304
  int64_t disp;
3305
  int64_t val;
3306 48 robfinch
        int64_t aq = 0, rl = 0;
3307
        int ar;
3308 55 robfinch
  int fixup = 5;
3309 48 robfinch
 
3310
        GetArBits(&aq, &rl);
3311
        ar = (int)((aq << 1LL) | rl);
3312
        p = inptr;
3313
        if (opcode6==0x26)
3314
                Rt = getVecRegister();
3315
        else
3316
                Rt = getRegisterX();
3317 55 robfinch
  if (Rt < 0) {
3318
      printf("Expecting a target register (%d).\r\n", lineno);
3319
      printf("Line:%.60s\r\n",p);
3320
      ScanToEOL();
3321
      inptr-=2;
3322
      return;
3323
  }
3324
  expect(',');
3325
  mem_operand(&disp, &Ra, &Rb, &Sc);
3326 48 robfinch
        if (Ra > 0 && Rb > 0) {
3327
                // Trap LEA, convert to LEAX opcode
3328
                if (opcode6==0x04) // ADD is really LEA
3329
                        opcode6 = 0x18;
3330
                else {
3331
                        switch (sz) {
3332
                        case -1: opcode6 = 0x21; break; // LCUX
3333
                        case 1: opcode6 = 0x20; break;          // LCX
3334
                        case -2: opcode6 = 0x11; break; // LHUX
3335
                        case 2: opcode6 = 0x10; break;  // LHX
3336
                        case 4: opcode6 = 0x12; break;          // LWX
3337
                        }
3338
                }
3339
                emit_insn(
3340
                        (opcode6 << 26LL) |
3341
                        (Sc << 23) |
3342
                        (Rt << 18) |
3343
                        (Rb << 13) |
3344
                        (Ra << 8) |
3345
                        0x16,!expand_flag,4);
3346
                return;
3347
        }
3348 55 robfinch
  if (Ra < 0) Ra = 0;
3349 48 robfinch
    val = disp;
3350
        if (Ra == 55)
3351
                val -= program_address;
3352
        if (sz == 4 && Ra == regSP) {
3353
                if ((val & 7) == 0) {
3354
                        if (val >= -128 && val < 128) {
3355
                                emit_insn(
3356
                                        (((val >> 4) & 0x0F) << 8) |
3357
                                        (5 << 12) |
3358
                                        (3 << 6) |
3359
                                        (((val >> 3) & 0x1) << 5) |
3360
                                        Rt, 0, 2
3361
                                );
3362
                                ScanToEOL();
3363
                                return;
3364
                        }
3365
                }
3366
        }
3367
        if (sz == 4 && Ra == regFP) {
3368
                if ((val & 7) == 0) {
3369
                        if (val >= -128 && val < 128) {
3370
                                emit_insn(
3371
                                        (((val >> 4) & 0x0F) << 8) |
3372
                                        (7 << 12) |
3373
                                        (3 << 6) |
3374
                                        (((val >> 3) & 0x1) << 5) |
3375
                                        Rt, 0, 2
3376
                                );
3377
                                ScanToEOL();
3378
                                return;
3379
                        }
3380
                }
3381
        }
3382
        if (!IsNBit(val, 30)) {
3383
                LoadConstant(val, 23);
3384
                // Change to indexed addressing
3385
                switch (sz) {
3386
                case -1: opcode6 = 0x21;        // LCUX
3387
                case 1: opcode6 = 0x20;         // LCX
3388
                case -2: opcode6 = 0x11;        // LHUX
3389
                case 2: opcode6 = 0x10;         // LHX
3390
                case 4: opcode6 = 0x12;         // LWX
3391
                }
3392
                emit_insn(
3393
                        (opcode6 << 26LL) |
3394
                        (0 << 23) |              // Sc = 0
3395
                        (Rt << 18) |
3396
                        (23 << 13) |
3397
                        (Ra << 8) |
3398 55 robfinch
                        0x16,!expand_flag,4);
3399 48 robfinch
                ScanToEOL();
3400
                return;
3401
        }
3402
        if (!IsNBit(val, 14)) {
3403
                emit_insn(
3404
                        ((val|abs(sz)) << 18LL) |
3405
                        (Rt << 13) |
3406
                        (Ra << 8) |
3407
                        (1 << 6) |
3408
                        opcode6, !expand_flag, 6);
3409
                ScanToEOL();
3410
                return;
3411
        }
3412
        emit_insn(
3413
                ((val|abs(sz)) << 18LL) |
3414
                (Rt << 13) |
3415
                (Ra << 8) |
3416
                opcode6,!expand_flag,4);
3417
    ScanToEOL();
3418
}
3419
 
3420
static void process_cache(int opcode6)
3421
{
3422 55 robfinch
  int Ra,Rb;
3423 48 robfinch
        int Sc;
3424 55 robfinch
  char *p;
3425
  int64_t disp;
3426
  int64_t val;
3427
  int fixup = 5;
3428 48 robfinch
        int cmd;
3429
 
3430 55 robfinch
  p = inptr;
3431 48 robfinch
        NextToken();
3432
        cmd = (int)expr() & 0x1f;
3433 55 robfinch
  expect(',');
3434
  mem_operand(&disp, &Ra, &Rb, &Sc);
3435 48 robfinch
        if (Ra > 0 && Rb > 0) {
3436
                emit_insn(
3437
                        (opcode6 << 26) |
3438
                        (Sc << 21) |
3439
                        (cmd << 16) |
3440
                        (Rb << 11) |
3441
                        (Ra << 6) |
3442
                        0x16,!expand_flag,4);
3443
                return;
3444
        }
3445
    if (Ra < 0) Ra = 0;
3446
    val = disp;
3447
        if (!IsNBit(val,30)) {
3448
                LoadConstant(val,23);
3449
                // Change to indexed addressing
3450
                emit_insn(
3451
                        (opcode6 << 26) |
3452
                        (cmd << 18) |
3453
                        (23 << 13) |
3454
                        (Ra << 8) |
3455
                        0x16,!expand_flag,4);
3456
                ScanToEOL();
3457
                return;
3458
        }
3459
        if (!IsNBit(val, 14)) {
3460
                emit_insn(
3461
                        (val << 18LL) |
3462
                        (cmd << 13) |
3463
                        (Ra << 8) |
3464
                        (1 << 6) |
3465
                        opcode6, !expand_flag, 6);
3466
                return;
3467
        }
3468
        emit_insn(
3469
                (val << 18) |
3470
                (cmd << 13) |
3471
                (Ra << 8) |
3472
                opcode6,!expand_flag,4);
3473
    ScanToEOL();
3474
}
3475
 
3476
// ----------------------------------------------------------------------------
3477
// lw r1,disp[r2]
3478
// lw r1,[r2+r3]
3479
// ----------------------------------------------------------------------------
3480
 
3481 50 robfinch
static void ProcessLoadVolatile(int64_t opcode, int sz)
3482 48 robfinch
{
3483
    int Ra,Rb;
3484
    int Rt;
3485
        int Sc;
3486
    char *p;
3487
    int64_t disp;
3488
    int64_t val;
3489
    int fixup = 5;
3490
 
3491
    p = inptr;
3492
        Rt = getRegisterX();
3493
    if (Rt < 0) {
3494
        printf("Expecting a target register (%d).\r\n", lineno);
3495
        printf("Line:%.60s\r\n",p);
3496
        ScanToEOL();
3497
        inptr-=2;
3498
        return;
3499
    }
3500
    expect(',');
3501
    mem_operand(&disp, &Ra, &Rb, &Sc);
3502
        if (Ra > 0 && Rb > 0) {
3503 50 robfinch
                switch (sz) {
3504
                case -1: opcode = 0x01; // LVBUX
3505
                case 1: opcode = 0x00;          // LVBX
3506
                case -2: opcode = 0x03; // LVCUX
3507
                case 2: opcode = 0x02;          // LVCX
3508
                case -4: opcode = 0x05;         // LVHUX
3509
                case 4: opcode = 0x04;          // LVHX
3510
                case 8: opcode = 0x06;  // LVWX
3511
                }
3512 48 robfinch
                emit_insn(
3513 50 robfinch
                        (opcode << 26) |
3514
                        (Sc << 23) |
3515
                        (Rt << 18) |
3516
                        (Rb << 13) |
3517
                        (Ra << 8) |
3518
                        0x16,!expand_flag,4);
3519 48 robfinch
                return;
3520
        }
3521
    if (Ra < 0) Ra = 0;
3522
    val = disp;
3523 50 robfinch
        if (!IsNBit(val, 30)) {
3524
                LoadConstant(val, 23);
3525 48 robfinch
                // Change to indexed addressing
3526 50 robfinch
                switch (sz) {
3527
                case -1: opcode = 0x01; // LVBUX
3528
                case 1: opcode = 0x00;          // LVBX
3529
                case -2: opcode = 0x03; // LVCUX
3530
                case 2: opcode = 0x02;          // LVCX
3531
                case -4: opcode = 0x05;         // LVHUX
3532
                case 4: opcode = 0x04;          // LVHX
3533
                case 8: opcode = 0x06;  // LVWX
3534
                }
3535 48 robfinch
                emit_insn(
3536 50 robfinch
                        (opcode << 26LL) |
3537
                        (0 << 23) |              // Sc = 0
3538
                        (Rt << 18) |
3539
                        (23 << 13) |
3540
                        (Ra << 8) |
3541
                        0x02, !expand_flag, 4);
3542 48 robfinch
                ScanToEOL();
3543
                return;
3544
        }
3545 50 robfinch
        if (!IsNBit(val, 14)) {
3546
                emit_insn(
3547
                        ((val | abs(sz)) << 18LL) |
3548
                        (Rt << 13) |
3549
                        (Ra << 8) |
3550
                        (1 << 6) |
3551
                        opcode, !expand_flag, 6);
3552
                ScanToEOL();
3553
                return;
3554
        }
3555 48 robfinch
        emit_insn(
3556 50 robfinch
                ((val | abs(sz)) << 18LL) |
3557
                (Rt << 13) |
3558
                (Ra << 8) |
3559
                opcode, !expand_flag, 4);
3560 48 robfinch
    ScanToEOL();
3561
}
3562
 
3563
static void process_lv(int opcode6)
3564
{
3565
    int Ra,Vb;
3566
    int Vt;
3567
    char *p;
3568
    int64_t disp;
3569
    int64_t val;
3570
    int fixup = 5;
3571
 
3572
    p = inptr;
3573
        Vt = getVecRegister();
3574
    if (Vt < 0) {
3575
        printf("Expecting a vector target register (%d).\r\n", lineno);
3576
        printf("Line:%.60s\r\n",p);
3577
        ScanToEOL();
3578
        inptr-=2;
3579
        return;
3580
    }
3581
    expect(',');
3582
    mem_voperand(&disp, &Ra, &Vb);
3583
        if (Ra > 0 && Vb > 0) {
3584
                emit_insn(
3585
                        (opcode6 << 26) |
3586
                        (Vt << 16) |
3587
                        (Vb << 11) |
3588
                        (Ra << 6) |
3589
                        0x02,!expand_flag,4);
3590
                return;
3591
        }
3592
    if (Ra < 0) Ra = 0;
3593
    val = disp;
3594
        //if (val < -32768 || val > 32767)
3595
        //      printf("LV displacement too large: %d\r\n", lineno);
3596
        if (val >= -32768 && val < 32768) {
3597
                emit_insn(
3598
                        (val << 16) |
3599
                        (Vt << 11) |
3600
                        (Ra << 6) |
3601
                        opcode6,!expand_flag,4);
3602
                ScanToEOL();
3603
                return;
3604
        }
3605
        LoadConstant(val,23);
3606
        // add r23,r23,ra
3607
        if (Ra != 0)
3608
                emit_insn(
3609
                        (0x04 << 26) |
3610
                        (3 << 21) |
3611
                        (23 << 16) |
3612
                        (23 << 11) |
3613
                        (Ra << 6) |
3614
                        0x02,!expand_flag,4
3615
                );
3616
        emit_insn(
3617
                (Vt << 11) |
3618
                (23 << 6) |
3619
                opcode6,!expand_flag,4);
3620
        ScanToEOL();
3621
}
3622
 
3623
static void process_lsfloat(int64_t opcode6, int64_t opcode3)
3624
{
3625
    int Ra,Rb;
3626
    int Rt;
3627
        int Sc;
3628
    char *p;
3629
    int64_t disp;
3630
    int64_t val;
3631
    int fixup = 5;
3632
 
3633
    int  sz;
3634
    int rm;
3635
 
3636
    rm = 0;
3637
    sz = GetFPSize();
3638
    p = inptr;
3639
    Rt = getFPRegister();
3640
    if (Rt < 0) {
3641
        printf("Expecting a target register (1:%d).\r\n", lineno);
3642
        printf("Line:%.60s\r\n",p);
3643
        ScanToEOL();
3644
        inptr-=2;
3645
        return;
3646
    }
3647
    expect(',');
3648
    mem_operand(&disp, &Ra, &Rb, &Sc);
3649
        if (Ra > 0 && Rb > 0) {
3650
                emit_insn(
3651
                        ((opcode6+sz) << 26) |
3652
                        (Sc << 23) |
3653
                        (Rt << 18) |
3654
                        (Rb << 13) |
3655
                        (Ra << 8) |
3656
                        0x16,!expand_flag,4);
3657
                return;
3658
        }
3659
    if (Ra < 0) Ra = 0;
3660
    val = disp;
3661
        if (!IsNBit(val, 30)) {
3662
                LoadConstant(val, 23);
3663
                // Change to indexed addressing
3664
                emit_insn(
3665
                        ((opcode6+sz) << 26LL) |
3666
                        (0 << 23) |              // Sc = 0
3667
                        (Rt << 18) |
3668
                        (23 << 13) |
3669
                        (Ra << 8) |
3670
                        0x02, !expand_flag, 4);
3671
                ScanToEOL();
3672
                return;
3673
        }
3674
        switch (sz) {
3675
        case 0:  val &= 0xfffffffffffffffeLL; val |= 1; break;
3676
        case 1: val &= 0xfffffffffffffffcLL; val |= 2; break;
3677
        case 2: val &= 0xfffffffffffffff8LL; val |= 4; break;
3678
        case 4: val &= 0xfffffffffffffff0LL; val |= 8; break;
3679
        }
3680
        if (!IsNBit(val, 14)) {
3681
                emit_insn(
3682
                        (val << 18LL) |
3683
                        (Rt << 13) |
3684
                        (Ra << 8) |
3685
                        (1 << 6) |
3686
                        opcode6, !expand_flag, 6);
3687
                ScanToEOL();
3688
                return;
3689
        }
3690
        emit_insn(
3691
                (val << 18LL) |
3692
                (Rt << 13) |
3693
                (Ra << 8) |
3694
                opcode6, !expand_flag, 4);
3695
        ScanToEOL();
3696
 
3697
}
3698
 
3699
static void process_ld()
3700
{
3701
        int Rt;
3702
        char *p;
3703
 
3704
        p = inptr;
3705
        Rt = getRegisterX();
3706
        expect(',');
3707
//      NextToken();
3708
        if (token == '#') {
3709
                inptr = p;
3710
                process_ldi();
3711
                return;
3712
        }
3713
        // Else: do a word load
3714
        inptr = p;
3715
        process_load(0x20,4);
3716
}
3717
 
3718
// ----------------------------------------------------------------------------
3719
// ----------------------------------------------------------------------------
3720
 
3721
static void process_ltcb(int oc)
3722
{
3723
        int Rn;
3724
 
3725
        Rn = getRegisterX();
3726
        emit_insn(
3727
                (oc << 11) |
3728
                (Rn << 6) |
3729
                0x19,0,1
3730
                );
3731
        prevToken();
3732
}
3733
 
3734
// ----------------------------------------------------------------------------
3735
// mov r1,r2 -> translated to or Rt,Ra,#0
3736
// ----------------------------------------------------------------------------
3737
 
3738
static void process_mov(int64_t oc, int64_t fn)
3739
{
3740
     int Ra;
3741
     int Rt;
3742
     char *p;
3743
         int vec = 0;
3744
         int fp = 0;
3745
         int d3;
3746
         int rgs = 8;
3747
         int sz = 3;
3748
 
3749
         p = inptr;
3750
         if (*p == '.')
3751
                 getSz(&sz);
3752
 
3753
         d3 = 7;        // current to current
3754
         p = inptr;
3755
     Rt = getRegisterX();
3756
         if (Rt==-1) {
3757
                 inptr = p;
3758
                 Rt = getFPRegister();
3759
                 if (Rt == -1) {
3760
                         d3 = 4;
3761
                         inptr = p;
3762
                         vec = 1;
3763
                         Rt = getVecRegister();
3764
                 }
3765
                 else {
3766
                         d3 = 4;
3767
                         fp = 1;
3768
                 }
3769
         }
3770
         Rt &= 31;
3771
        if (inptr[-1]==':') {
3772
                if (*inptr=='x' || *inptr=='X') {
3773
                        d3 = 2;
3774
                        inptr++;
3775
                        NextToken();
3776
                }
3777
                else {
3778
                        rgs = (int)expr();
3779
                        d3 = 0;
3780
                }
3781
        }
3782
     need(',');
3783
         p = inptr;
3784
     Ra = getRegisterX();
3785
         if (Ra==-1) {
3786
                 inptr = p;
3787
                 Ra = getFPRegister();
3788
                 if (Ra == -1) {
3789
                         inptr = p;
3790
                         Ra = getVecRegister();
3791
                         vec |= 2;
3792
                 }
3793
                 else {
3794
                         if (fp == 1)
3795
                                 d3 = 6;
3796
                         else
3797
                                 d3 = 5;
3798
                         fp |= 2;
3799
                 }
3800
         }
3801
         Ra &= 31;
3802
        if (inptr[-1]==':') {
3803
                if (*inptr=='x' || *inptr=='X') {
3804
                        inptr++;
3805
                        d3 = 3;
3806
                        NextToken();
3807
                }
3808
                else {
3809
                        rgs = (int)expr();
3810
                        d3 = 1;
3811
                }
3812
        }
3813
         if (vec==1) {
3814
                 emit_insn(
3815
                         (0x33LL << 34LL) |
3816
                         (0x00LL << 28LL) |
3817
                         (Rt << 12) |
3818
                         (Ra << 6) |
3819
                         0x01,!expand_flag,5
3820
                 );
3821
                 return;
3822
         }
3823
         else if (vec==2) {
3824
                 emit_insn(
3825
                         (0x33LL << 34LL) |
3826
                         (0x01LL << 28LL) |
3827
                         (Rt << 12) |
3828
                         (Ra << 6) |
3829
                         0x01,!expand_flag,5
3830
                 );
3831
                 return;
3832
         }
3833
         else if (vec==3)
3834
                 printf("Unsupported mov operation. %d\n", lineno);
3835
         if (rgs < 0 || rgs > 63)
3836
                 printf("Illegal register set spec: %d\n", lineno);
3837
         rgs &= 0x31;
3838
         if (d3 == 7) {
3839
                 emit_insn(
3840
                         (0 << 12) |
3841
                         (3 << 6) |
3842
                         ((Rt >> 1) << 8) |
3843
                         ((Rt & 1) << 5) |
3844
                         (Ra),
3845
                 0,2);
3846
                 prevToken();
3847
                 return;
3848
         }
3849
         emit_insn(
3850 50 robfinch
                 (fn << 26LL) | // fn should be even
3851
                 (((rgs >> 5) & 1) << 26) |
3852 48 robfinch
                 (d3 << 23LL) |
3853
                 (rgs << 18) |
3854
                 (Rt << 13) |
3855
                 (Ra << 8) |
3856
                 oc,!expand_flag,4
3857
                 );
3858
        prevToken();
3859
}
3860
 
3861
static void process_vmov(int opcode, int func)
3862
{
3863
        int Vt, Va;
3864
        int Rt, Ra;
3865
 
3866
        Vt = getVecRegister();
3867
        if (Vt < 0x20) {
3868
                Rt = getRegisterX();
3869
                if (Rt < 0) {
3870
                        printf("Illegal register in vmov (%d)\n", lineno);
3871
                        ScanToEOL();
3872
                        return;
3873
                }
3874
                Va = getVecRegister();
3875
                if (Va < 0x20) {
3876
                        printf("Illegal register in vmov (%d)\n", lineno);
3877
                        ScanToEOL();
3878
                        return;
3879
                }
3880
                emit_insn(
3881
                        (func << 26) |
3882
                        (1 << 21) |
3883
                        ((Rt & 0x1f) << 11) |
3884
                        ((Va & 0x1F) << 6) |
3885
                        opcode,!expand_flag,4
3886
                        );
3887
                return;
3888
        }
3889
        need(',');
3890
        Ra = getRegisterX();
3891
        if (Ra < 0) {
3892
                printf("Illegal register in vmov (%d)\n", lineno);
3893
                ScanToEOL();
3894
                return;
3895
        }
3896
        emit_insn(
3897
                (func << 26) |
3898
                ((Vt & 0x1f) << 11) |
3899
                (Ra << 6) |
3900
                opcode,!expand_flag,4
3901
                );
3902
}
3903
 
3904
 
3905
// ----------------------------------------------------------------------------
3906
// shr r1,r2,#5
3907
// ----------------------------------------------------------------------------
3908
 
3909
static void process_shifti(int64_t op4)
3910
{
3911
     int Ra;
3912
     int Rt;
3913
         int sz = 3;
3914
         int64_t func6 = 0x0F;
3915
     int64_t val;
3916
         char *p = inptr;
3917
 
3918
         if (p[0]=='.')
3919
                 getSz(&sz);
3920
     Rt = getRegisterX();
3921
     need(',');
3922
     Ra = getRegisterX();
3923
     need(',');
3924
     NextToken();
3925
     val = expr();
3926
         val &= 63;
3927
         if (val < 32 && op4 == 0 && Rt==Ra) {
3928
                 emit_insn(
3929
                         (3 << 12) |
3930
                         (((val >> 1) & 0x0f) << 8) |
3931
                         (2 << 6) |
3932
                         ((val & 1) << 5) |
3933
                         Rt,0,2
3934
                 );
3935
                 return;
3936
         }
3937
         if (val > 31)
3938
                 func6 += 0x10;
3939
        emit_insn(
3940
                (func6 << 26LL) |
3941
                (op4 << 23LL) |
3942
                ((val & 0x1f) << 18) |
3943
                (Rt << 13) |
3944
                (Ra << 8) |
3945
                0x02,!expand_flag,4);
3946
}
3947
 
3948
// ----------------------------------------------------------------------------
3949
// SEI R1
3950
// SEI #5
3951
// ----------------------------------------------------------------------------
3952
 
3953
static void process_sei()
3954
{
3955
        int64_t val = 7;
3956
        int Ra = -1;
3957
    char *p;
3958
 
3959
        p = inptr;
3960
        NextToken();
3961
        if (token=='#')
3962
                val = expr();
3963
        else {
3964
                inptr = p;
3965
            Ra = getRegisterX();
3966
        }
3967
        if (Ra==-1) {
3968
                emit_insn(
3969
                        0xC0000002LL |
3970
                        ((val & 7) << 18) |
3971
                        (0 << 8),
3972
                        !expand_flag,4);
3973
        }
3974
        else {
3975
                emit_insn(
3976
                        0xC0000002LL |
3977
                        (0 << 18) |
3978
                        (Ra << 8),
3979
                        !expand_flag,4);
3980
        }
3981
}
3982
 
3983
// ----------------------------------------------------------------------------
3984
// REX r0,6,6,1
3985
// ----------------------------------------------------------------------------
3986
 
3987
static void process_rex()
3988
{
3989
        int64_t val = 7;
3990
        int Ra = -1;
3991
        int tgtol;
3992
        int pl;
3993
        int im;
3994
    char *p;
3995
 
3996
        p = inptr;
3997
    Ra = getRegisterX();
3998
        need(',');
3999
        NextToken();
4000
        tgtol = (int)expr() & 7;
4001
        if (tgtol==0)
4002
                printf("REX: Illegal redirect to user level %d.\n", lineno);
4003
        need(',');
4004
        NextToken();
4005
        pl = (int)expr() & 7;
4006
        need(',');
4007
        NextToken();
4008
        im = (int)expr() & 7;
4009
        emit_insn(
4010
                (im << 24) |
4011
                (pl << 16) |
4012
                (tgtol << 11) |
4013
                (Ra << 6) |
4014
                0x0D,!expand_flag,4
4015
        );
4016
}
4017
 
4018
// ----------------------------------------------------------------------------
4019
// shl r1,r2,r3
4020
// ----------------------------------------------------------------------------
4021
 
4022
static void process_shift(int op4)
4023
{
4024
     int Ra, Rb;
4025
     int Rt;
4026
     char *p;
4027
         int sz = 3;
4028
         int func6 = 0x2f;
4029
 
4030
         p = inptr;
4031
         if (p[0]=='.')
4032
                 getSz(&sz);
4033
     Rt = getRegisterX();
4034
     need(',');
4035
     Ra = getRegisterX();
4036
     need(',');
4037
     NextToken();
4038
         if (token=='#') {
4039
                 inptr = p;
4040
                 process_shifti(op4);
4041
         }
4042
         else {
4043
                prevToken();
4044
                Rb = getRegisterX();
4045
                emit_insn((func6 << 26) | (op4 << 23) | (Rt << 18)| (Rb << 12) | (Ra << 8) | 0x02,!expand_flag,4);
4046
         }
4047
}
4048
 
4049
// ----------------------------------------------------------------------------
4050
// gran r1
4051
// ----------------------------------------------------------------------------
4052
 
4053
static void process_gran(int oc)
4054
{
4055
    int Rt;
4056
 
4057
    Rt = getRegisterX();
4058
//    emitAlignedCode(0x01);
4059
    emitCode(0x00);
4060
    emitCode(Rt);
4061
    emitCode(0x00);
4062
    emitCode(oc);
4063
    prevToken();
4064
}
4065
 
4066
 
4067
// ----------------------------------------------------------------------------
4068
// ----------------------------------------------------------------------------
4069
 
4070
static void process_mffp(int oc)
4071
{
4072
    int fpr;
4073
    int Rt;
4074
 
4075
    Rt = getRegisterX();
4076
    need(',');
4077
    fpr = getFPRegister();
4078
    //emitAlignedCode(0x01);
4079
    emitCode(fpr);
4080
    emitCode(Rt);
4081
    emitCode(0x00);
4082
    emitCode(oc);
4083
    if (fpr >= 0)
4084
    prevToken();
4085
}
4086
 
4087
// ----------------------------------------------------------------------------
4088
// ----------------------------------------------------------------------------
4089
 
4090
static void process_fprdstat(int oc)
4091
{
4092
    int Rt;
4093
 
4094
    Rt = getRegisterX();
4095
    //emitAlignedCode(0x01);
4096
    emitCode(0x00);
4097
    emitCode(Rt);
4098
    emitCode(0x00);
4099
    emitCode(oc);
4100
}
4101
 
4102
 
4103
// ----------------------------------------------------------------------------
4104
// Four cases, two with extendable immediate constants
4105
//
4106
// csrrw        r2,#21,r3
4107
// csrrw        r4,#34,#1234
4108
// csrrw        r5,r4,#1234
4109
// csrrw        r6,r4,r5
4110
// ----------------------------------------------------------------------------
4111
 
4112
static void process_csrrw(int64_t op)
4113
{
4114
        int Rd;
4115
        int Rs;
4116
        int Rc;
4117
        int64_t val,val2;
4118
        char *p;
4119
        int sz = 3;
4120
 
4121
        p = inptr;
4122
        if (p[0] == '.')
4123
                getSz(&sz);
4124
        Rd = getRegisterX();
4125
        need(',');
4126
        p = inptr;
4127
        NextToken();
4128
        if (token=='#') {
4129
                val = expr();
4130
                need(',');
4131
                NextToken();
4132
                if (token=='#') {
4133
                        printf("Illegal CSR instruction.\r\n");
4134
                        return;
4135
                        val2 = expr();
4136
                        if (val2 < -15LL || val2 > 15LL) {
4137
                                emit_insn((val << 18) | (op << 16) | (0x10 << 6) | (Rd << 11) | 0x05,0,2);
4138
                                emit_insn(val2,0,2);
4139
                                return;
4140
                        }
4141
                        emit_insn((val << 18) | (op << 16) | ((val2 & 0x1f) << 6) | (Rd << 11) | 0x05,!expand_flag,2);
4142
                        return;
4143
                }
4144
                prevToken();
4145
                Rs = getRegisterX();
4146
                emit_insn(((val & 0x3FF) << 18) | (op << 30LL) | (Rs << 8) | (Rd << 13) | 0x05,!expand_flag,4);
4147
                prevToken();
4148
                return;
4149
                }
4150
        printf("Illegal CSR instruction.\r\n");
4151
        return;
4152
        inptr = p;
4153
        Rc = getRegisterX();
4154
        need(',');
4155
        NextToken();
4156
        if (token=='#') {
4157
                val2 = expr();
4158
                if (val2 < -15LL || val2 > 15LL) {
4159
                        emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | (0x10 << 6) | (Rc << 11) | 0x0C,0,2);
4160
                        emit_insn(val2,0,2);
4161
                        return;
4162
                }
4163
                emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | ((val2 & 0x1f) << 6) | (Rc << 11) | 0x0C,!expand_flag,2);
4164
                return;
4165
        }
4166
        prevToken();
4167
        Rs = getRegisterX();
4168
        emit_insn((0x3F << 26) | (op << 21) | (Rd << 16) | (Rc << 11) | (Rs << 6) | 0x0C,!expand_flag,2);
4169
        prevToken();
4170
        return;
4171
}
4172
 
4173
// ---------------------------------------------------------------------------
4174
// com r3,r3
4175
// - alternate mnemonic for xor Rn,Rn,#-1
4176
// ---------------------------------------------------------------------------
4177
 
4178
static void process_com()
4179
{
4180
    int Ra;
4181
    int Rt;
4182
        char *p;
4183
        int sz = 3;
4184
 
4185
        p = inptr;
4186
        if (p[0] == '.')
4187
                getSz(&sz);
4188
 
4189
    Rt = getRegisterX();
4190
    need(',');
4191
    Ra = getRegisterX();
4192
        emit_insn(
4193
                (0xFFFFFLL << 20) |
4194
                (sz << 18) |
4195
                (Rt << 12) |
4196
                (Ra << 6) |
4197
                0x0A,!expand_flag,5
4198
                );
4199
        prevToken();
4200
}
4201
 
4202
// ---------------------------------------------------------------------------
4203
// neg r3,r3
4204
// - alternate mnemonic for sub Rn,R0,Rn
4205
// ---------------------------------------------------------------------------
4206
 
4207
static void process_neg()
4208
{
4209
    int Ra;
4210
    int Rt;
4211
        char *p;
4212
        int sz = 3;
4213
 
4214
        p = inptr;
4215
        if (p[0] == '.')
4216
                getSz(&sz);
4217
 
4218
    Rt = getRegisterX();
4219
    need(',');
4220
    Ra = getRegisterX();
4221
        emit_insn(
4222
                (0x05LL << 34LL) |
4223
                (sz << 24) |
4224
                (Rt << 18) |
4225
                (Ra << 12) |
4226
                (0 << 6) |
4227
                0x02,!expand_flag,5
4228
                );
4229
        prevToken();
4230
}
4231
 
4232
static void process_sync(int oc)
4233
{
4234
//    emit_insn(oc,!expand_flag);
4235
}
4236
 
4237
 
4238
// ---------------------------------------------------------------------------
4239
// ---------------------------------------------------------------------------
4240
 
4241
static void process_vrrop(int funct6)
4242
{
4243
    int Va,Vb,Vt,Vm;
4244
    char *p;
4245
        int sz = 0x43;
4246
 
4247
    p = inptr;
4248
        if (*p=='.')
4249
                getSz(&sz);
4250
        if (sz==0x43)
4251
                sz = 0;
4252
        else if (sz==0x83)
4253
                sz = 1;
4254
    Vt = getVecRegister();
4255
    need(',');
4256
    Va = getVecRegister();
4257
    need(',');
4258
    Vb = getVecRegister();
4259
    need(',');
4260
    Vm = getVecRegister();
4261
        if (Vm < 0x20 || Vm > 0x23)
4262
                printf("Illegal vector mask register: %d\r\n", lineno);
4263
        Vm &= 0x7;
4264
    //prevToken();
4265
    emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Vb<<11)|(Va<<6)|0x01,!expand_flag,4);
4266
}
4267
 
4268
// ---------------------------------------------------------------------------
4269
// ---------------------------------------------------------------------------
4270
 
4271
static void process_vsrrop(int funct6)
4272
{
4273
    int Va,Rb,Vt,Vm;
4274
    char *p;
4275
        int sz = 0x43;
4276
 
4277
    p = inptr;
4278
        if (*p=='.')
4279
                getSz(&sz);
4280
        if (sz==0x43)
4281
                sz = 0;
4282
        else if (sz==0x83)
4283
                sz = 1;
4284
    Vt = getVecRegister();
4285
    need(',');
4286
    Va = getVecRegister();
4287
    need(',');
4288
    Rb = getRegisterX();
4289
    need(',');
4290
    Vm = getVecRegister();
4291
        if (Vm < 0x20 || Vm > 0x23)
4292
                printf("Illegal vector mask register: %d\r\n", lineno);
4293
        Vm &= 0x3;
4294
    //prevToken();
4295
    emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Rb<<11)|(Va<<6)|0x01,!expand_flag,4);
4296
}
4297
 
4298
// ----------------------------------------------------------------------------
4299
// ----------------------------------------------------------------------------
4300
 
4301
static void ProcessEOL(int opt)
4302
{
4303
    int64_t nn,mm,cai,caia;
4304
    int first;
4305
    int cc,jj;
4306
 
4307
     //printf("Line: %d\r", lineno);
4308
     expand_flag = 0;
4309
     compress_flag = 0;
4310
     segprefix = -1;
4311
     if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
4312
    nn = binstart;
4313
    cc = 2;
4314
    if (segment==codeseg) {
4315
       cc = 4;
4316
/*
4317
        if (sections[segment].bytes[binstart]==0x61) {
4318
            fprintf(ofp, "%06LLX ", ca);
4319
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
4320
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
4321
            }
4322
            fprintf(ofp, "   ; imm\n");
4323
             if (((ca+5) & 15)==15) {
4324
                 ca+=6;
4325
                 binstart+=6;
4326
                 nn++;
4327
             }
4328
             else {
4329
                  ca += 5;
4330
                  binstart += 5;
4331
             }
4332
        }
4333
*/
4334
/*
4335
        if (sections[segment].bytes[binstart]==0xfd) {
4336
            fprintf(ofp, "%06LLX ", ca);
4337
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
4338
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
4339
            }
4340
            fprintf(ofp, "   ; imm\n");
4341
             if (((ca+5) & 15)==15) {
4342
                 ca+=6;
4343
                 binstart+=6;
4344
                 nn++;
4345
             }
4346
             else {
4347
                  ca += 5;
4348
                  binstart += 5;
4349
             }
4350
        }
4351
         if (sections[segment].bytes[binstart]==0xfe) {
4352
            fprintf(ofp, "%06LLX ", ca);
4353
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
4354
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
4355
            }
4356
            fprintf(ofp, "   ; imm\n");
4357
             if (((ca+5) & 15)==15) {
4358
                 ca+=6;
4359
                 nn++;
4360
             }
4361
             else {
4362
                  ca += 5;
4363
             }
4364
        }
4365
*/
4366
    }
4367
 
4368
    first = 1;
4369
    while (nn < sections[segment].index) {
4370
        fprintf(ofp, "%06I64X ", ca);
4371
                caia = 0;
4372
        for (mm = nn; nn < mm + cc && nn < sections[segment].index; ) {
4373
                        cai = sections[segment].index - nn;
4374
                        // Output for instructions with multiple words
4375
                        if ((cai % 4) == 0 && cai < 20 && segment==codeseg)
4376
                                cai = 4;
4377
                        // Otherwise a big stream of information was output, likely data
4378
                        if (cai > 8) cai = 8;
4379
//                      for (jj = (int)cai-1; jj >= 0; jj--)
4380
//                              fprintf(ofp, "%02X", sections[segment].bytes[nn+jj]);
4381
                        for (jj = 0; jj < (int) cai; jj++)
4382
                                fprintf(ofp, "%02X ", sections[segment].bytes[nn + jj]);
4383
                        fprintf(ofp, " ");
4384
                        nn += cai;
4385
                        caia += cai;
4386
        }
4387
                for (jj = 8 - (int)caia; jj >= 0; jj--)
4388
                        fprintf(ofp, "   ");
4389
//        for (; nn < mm + caia; nn++)
4390
//            fprintf(ofp, "  ");
4391
        if (first & opt) {
4392
                        fprintf(ofp, "\t%.*s\n", inptr - stptr - 1, stptr);
4393
                        first = 0;
4394
        }
4395
        else
4396
            fprintf(ofp, opt ? "\n" : "; NOP Ramp\n");
4397
        ca += caia;
4398
    }
4399
    // empty (codeless) line
4400
    if (binstart==sections[segment].index) {
4401
        fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
4402
    }
4403
    } // bGen
4404
    if (opt) {
4405
       stptr = inptr;
4406
       lineno++;
4407
    }
4408
    binstart = sections[segment].index;
4409
    ca = sections[segment].address;
4410
}
4411
 
4412
// ----------------------------------------------------------------------------
4413
// ----------------------------------------------------------------------------
4414
 
4415
void FT64_processMaster()
4416
{
4417
    int nn;
4418
    int64_t bs1, bs2;
4419
 
4420
    lineno = 1;
4421
    binndx = 0;
4422
    binstart = 0;
4423
    bs1 = 0;
4424
    bs2 = 0;
4425
    inptr = &masterFile[0];
4426
    stptr = inptr;
4427
    code_address = 0;
4428
    bss_address = 0;
4429
    start_address = 0;
4430
    first_org = 1;
4431
    first_rodata = 1;
4432
    first_data = 1;
4433
    first_bss = 1;
4434
        expandedBlock = 0;
4435 55 robfinch
    if (pass==3) {
4436 48 robfinch
    htblmax = 0;
4437
    for (nn = 0; nn < 100000; nn++) {
4438
      hTable[nn].count = 0;
4439
      hTable[nn].opcode = 0;
4440
    }
4441
    }
4442
    for (nn = 0; nn < 12; nn++) {
4443
        sections[nn].index = 0;
4444
        if (nn == 0)
4445
        sections[nn].address = 0;
4446
        else
4447
        sections[nn].address = 0;
4448
        sections[nn].start = 0;
4449
        sections[nn].end = 0;
4450
    }
4451
    ca = code_address;
4452
    segment = codeseg;
4453
    memset(current_label,0,sizeof(current_label));
4454
    NextToken();
4455
    while (token != tk_eof) {
4456
//        printf("\t%.*s\n", inptr-stptr-1, stptr);
4457
//        printf("token=%d\r", token);
4458
          if (expandedBlock)
4459
             expand_flag = 1;
4460
        switch(token) {
4461
        case tk_eol: ProcessEOL(1); break;
4462
//        case tk_add:  process_add(); break;
4463
//              case tk_abs:  process_rop(0x04); break;
4464
                case tk_abs: process_rop(0x01); break;
4465 50 robfinch
        case tk_add:  process_rrop(0x04,0x04); break;
4466 48 robfinch
        case tk_addi: process_riop(0x04); break;
4467
        case tk_align: process_align(); continue; break;
4468 50 robfinch
        case tk_and:  process_rrop(0x08,0x08); break;
4469 48 robfinch
        case tk_andi:  process_riop(0x08); break;
4470
        case tk_asl: process_shift(0x2); break;
4471
        case tk_asr: process_shift(0x3); break;
4472
        case tk_bbc: process_beqi(0x26,1); break;
4473
        case tk_bbs: process_beqi(0x26,0); break;
4474
        case tk_begin_expand: expandedBlock = 1; break;
4475
        case tk_beq: process_bcc(0x30,0); break;
4476
        case tk_beqi: process_beqi(0x32,0); break;
4477
                case tk_bfchg: process_bitfield(2); break;
4478
                case tk_bfclr: process_bitfield(1); break;
4479
        case tk_bfext: process_bitfield(5); break;
4480
        case tk_bfextu: process_bitfield(6); break;
4481
                case tk_bfins: process_bitfield(3); break;
4482
                case tk_bfinsi: process_bitfield(4); break;
4483
                case tk_bfset: process_bitfield(0); break;
4484
        case tk_bge: process_bcc(0x30,3); break;
4485
        case tk_bgeu: process_bcc(0x30,5); break;
4486
        case tk_bgt: process_bcc(0x30,-2); break;
4487
        case tk_bgtu: process_bcc(0x30,-4); break;
4488
        case tk_ble: process_bcc(0x30,-3); break;
4489
        case tk_bleu: process_bcc(0x30,-5); break;
4490
        case tk_blt: process_bcc(0x30,2); break;
4491
        case tk_bltu: process_bcc(0x30,4); break;
4492
        case tk_bne: process_bcc(0x30,1); break;
4493
        case tk_bra: process_bra(0x01); break;
4494
                case tk_brk: process_brk(); break;
4495
        //case tk_bsr: process_bra(0x56); break;
4496
        case tk_bss:
4497
            if (first_bss) {
4498
                while(sections[segment].address & 4095)
4499
                    emitByte(0x00);
4500
                sections[3].address = sections[segment].address;
4501
                first_bss = 0;
4502
                binstart = sections[3].index;
4503
                ca = sections[3].address;
4504
            }
4505
            segment = bssseg;
4506
            break;
4507
                case tk_cache: process_cache(0x1E); break;
4508
                case tk_call:  process_call(0x19); break;
4509 55 robfinch
        case tk_cli: emit_insn(0xC0000002,!expand_flag,4); break;
4510 48 robfinch
                case tk_chk:  process_chk(0x34); break;
4511
                case tk_cmovenz: process_cmove(0x29); break;
4512 50 robfinch
                //case tk_cmp:  process_rrop(0x06); break;
4513
                //case tk_cmpi:  process_riop(0x06); break;
4514
                //case tk_cmpu:  process_rrop(0x07); break;
4515
                //case tk_cmpui:  process_riop(0x07); break;
4516 48 robfinch
        case tk_code: process_code(); break;
4517
        case tk_com: process_com(); break;
4518
        case tk_csrrc: process_csrrw(0x3); break;
4519
        case tk_csrrs: process_csrrw(0x2); break;
4520
        case tk_csrrw: process_csrrw(0x1); break;
4521
        case tk_csrrd: process_csrrw(0x0); break;
4522
        case tk_data:
4523
            if (first_data) {
4524
                while(sections[segment].address & 4095)
4525
                    emitByte(0x00);
4526
                sections[2].address = sections[segment].address;   // set starting address
4527
                first_data = 0;
4528
                binstart = sections[2].index;
4529
                ca = sections[2].address;
4530
            }
4531
            process_data(dataseg);
4532
            break;
4533
        case tk_db:  process_db(); break;
4534
                case tk_dbnz: process_dbnz(0x26,3); break;
4535
        case tk_dc:  process_dc(); break;
4536
                case tk_dec:    process_inc(0x25); break;
4537
                case tk_dh:  process_dh(); break;
4538
        case tk_dh_htbl:  process_dh_htbl(); break;
4539 50 robfinch
                case tk_div: process_rrop(0x3E,0x3E); break;
4540
                //case tk_divsu:        process_rrop(0x3D, -1); break;
4541
                case tk_divu: process_rrop(0x3C,0x3C); break;
4542
                case tk_dw:  process_dw(); break;
4543 48 robfinch
        case tk_end: goto j1;
4544
        case tk_end_expand: expandedBlock = 0; break;
4545
        case tk_endpublic: break;
4546 50 robfinch
        case tk_eor: process_rrop(0x0A,0x0A); break;
4547 48 robfinch
        case tk_eori: process_riop(0x0A); break;
4548
        case tk_extern: process_extern(); break;
4549 54 robfinch
                                case tk_file:
4550
                                        NextToken();
4551
                                        if (token==tk_strconst)
4552
                                                mname = std::string(laststr);
4553
                                        //NextToken();
4554
                                        //if (token == ',') {
4555
                                        //      NextToken();
4556
                                        //      lineno = expr();
4557
                                        //}
4558
                                        break;
4559 48 robfinch
                case tk_ftoi:   process_ftoi(0x12); break;
4560
                case tk_fadd:   process_fprrop(0x04); break;
4561
        case tk_fbeq:   process_fbcc(0); break;
4562
        case tk_fbge:   process_fbcc(3); break;
4563
        case tk_fblt:   process_fbcc(2); break;
4564
        case tk_fbne:   process_fbcc(1); break;
4565
                case tk_fdiv:   process_fprrop(0x09); break;
4566
        case tk_fill: process_fill(); break;
4567
                case tk_fmov:   process_fprop(0x10); break;
4568
                case tk_fmul:   process_fprrop(0x08); break;
4569
                case tk_fneg:   process_fprop(0x14); break;
4570
                case tk_fsub:   process_fprrop(0x05); break;
4571
                case tk_hint:   process_hint(); break;
4572
                case tk_ibne: process_ibne(0x26,2); break;
4573
                case tk_inc:    process_inc(0x1A); break;
4574
                case tk_if:             pif1 = inptr-2; doif(); break;
4575
                case tk_itof: process_itof(0x15); break;
4576
                case tk_iret:   process_iret(0xC8000002); break;
4577
                case tk_isnull:  process_rop(0x0C); break;
4578
                case tk_isptr:  process_rop(0x0D); break;
4579
        case tk_jal: process_jal(0x18); break;
4580
                case tk_jmp: process_call(0x28); break;
4581
        case tk_lb:  process_load(0x13,0); break;
4582
        case tk_lbu:  process_load(0x23,0); break;
4583
        case tk_lc:  process_load(0x20,1); break;
4584
        case tk_lcu:  process_load(0x20,-1); break;
4585
                case tk_ld:     process_ld(); break;
4586
        case tk_ldi: process_ldi(); break;
4587
        case tk_lea: process_load(0x04,0); break;
4588
                case tk_lf:      process_lsfloat(0x1b,0x00); break;
4589
        case tk_lh:  process_load(0x20,2); break;
4590
        case tk_lhu: process_load(0x20,-2); break;
4591
                //case tk_lui: process_lui(0x27); break;
4592
        case tk_lv:  process_lv(0x36); break;
4593 50 robfinch
                case tk_lvb: ProcessLoadVolatile(0x3B,1); break;
4594
                case tk_lvbu: ProcessLoadVolatile(0x3B,-1); break;
4595
                case tk_lvc: ProcessLoadVolatile(0x3B,2); break;
4596
                case tk_lvcu: ProcessLoadVolatile(0x3B,-2); break;
4597
                case tk_lvh: ProcessLoadVolatile(0x3B,4); break;
4598
                case tk_lvhu: ProcessLoadVolatile(0x3B,-4); break;
4599
                case tk_lvw: ProcessLoadVolatile(0x3B,8); break;
4600 48 robfinch
        case tk_lw:  process_load(0x20,4); break;
4601
        case tk_lwr:  process_load(0x1D,0); break;
4602 54 robfinch
                                case tk_macro:  process_macro(); break;
4603 55 robfinch
                case tk_memdb: emit_insn(0x04400002,!expand_flag,4); break;
4604
                case tk_memsb: emit_insn(0x04440002,!expand_flag,4); break;
4605 48 robfinch
                case tk_message: process_message(); break;
4606 50 robfinch
                case tk_mod: process_rrop(0x16,0x2E); break;
4607
                case tk_modu: process_rrop(0x14,-1); break;
4608 48 robfinch
        case tk_mov: process_mov(0x02, 0x22); break;
4609 50 robfinch
                case tk_mul: process_rrop(0x3A,0x3A); break;
4610
                //case tk_mulh: process_rrop(0x26, 0x3A); break;
4611
                case tk_mulu: process_rrop(0x38,0x38); break;
4612
                //case tk_muluh: process_rrop(0x24, 0x38); break;
4613
                case tk_neg: process_neg(); break;
4614 55 robfinch
        case tk_nop: emit_insn(0x1C,!expand_flag,4); break;
4615 48 robfinch
                case tk_not: process_rop(0x05); break;
4616
//        case tk_not: process_rop(0x07); break;
4617 50 robfinch
        case tk_or:  process_rrop(0x09,0x09); break;
4618 48 robfinch
        case tk_ori: process_riop(0x09); break;
4619
        case tk_org: process_org(); break;
4620 55 robfinch
                                case tk_plus: compress_flag = 0;  expand_flag = 1; break;
4621 48 robfinch
        case tk_public: process_public(); break;
4622
        case tk_rodata:
4623
            if (first_rodata) {
4624
                while(sections[segment].address & 4095)
4625
                    emitByte(0x00);
4626
                sections[1].address = sections[segment].address;
4627
                first_rodata = 0;
4628
                binstart = sections[1].index;
4629
                ca = sections[1].address;
4630
            }
4631
            segment = rodataseg;
4632
            break;
4633
                case tk_redor: process_rop(0x06); break;
4634
                case tk_ret: process_ret(); break;
4635
                case tk_rex: process_rex(); break;
4636
                case tk_rol: process_shift(0x4); break;
4637
                case tk_roli: process_shift(0xC); break;
4638
                case tk_ror: process_shift(0x5); break;
4639
                case tk_rori: process_shift(0xD); break;
4640
                case tk_rti: process_iret(0xC8000002); break;
4641
        case tk_sb:  process_store(0x15,0); break;
4642
        case tk_sc:  process_store(0x24,1); break;
4643
        case tk_sei: process_sei(); break;
4644
                //case tk_seq:  process_riop(0x1B,2); break;
4645
                case tk_sf:             process_lsfloat(0x2B,0x00); break;
4646
                case tk_sge:    process_setop(-6); break;
4647
                case tk_sgeu:   process_setiop(-7); break;
4648
                case tk_sgt:    process_setiop(-0x2C); break;
4649
                case tk_sgtu:   process_setiop(-0x1C); break;
4650
        //case tk_slt:  process_rrop(0x33,0x02,0x00); break;
4651
        //case tk_sltu:  process_rrop(0x33,0x03,0x00); break;
4652
        //case tk_slti:  process_riop(0x13,0x02); break;
4653
        //case tk_sltui:  process_riop(0x13,0x03); break;
4654
        case tk_sh:  process_store(0x24,2); break;
4655
        case tk_shl: process_shift(0x0); break;
4656
        case tk_shli: process_shifti(0x8); break;
4657
                case tk_shr: process_shift(0x1); break;
4658
        case tk_shri: process_shifti(0x9); break;
4659
                case tk_shru: process_shift(0x1); break;
4660
                case tk_shrui: process_shifti(0x9); break;
4661
                case tk_sle:    process_setop(0x28); break;
4662
                case tk_sleu:   process_setop(0x29); break;
4663
                case tk_slt:    process_setop(0x06); break;
4664
                case tk_sltu:   process_setop(0x07); break;
4665
                //case tk_sne:  process_setiop(0x1B,3); break;
4666
        case tk_slli: process_shifti(0x8); break;
4667
                case tk_srai: process_shifti(0xB); break;
4668
        case tk_srli: process_shifti(0x9); break;
4669 50 robfinch
        case tk_sub:  process_rrop(0x05,-0x04); break;
4670 48 robfinch
        case tk_subi:  process_riop(0x05); break;
4671
        case tk_sv:  process_sv(0x37); break;
4672
        case tk_sw:  process_store(0x24,4); break;
4673
        case tk_swc:  process_store(0x17,0); break;
4674
        case tk_swap: process_rop(0x03); break;
4675
                //case tk_swp:  process_storepair(0x27); break;
4676
                case tk_sxb: process_rop(0x1A); break;
4677
                case tk_sxc: process_rop(0x19); break;
4678
                case tk_sxh: process_rop(0x18); break;
4679 55 robfinch
                case tk_sync: emit_insn(0x04480002,!expand_flag,4); break;
4680 48 robfinch
                //case tk_unlink: emit_insn((0x1B << 26) | (0x1F << 16) | (30 << 11) | (0x1F << 6) | 0x02,0,4); break;
4681
                case tk_vadd: process_vrrop(0x04); break;
4682
                case tk_vadds: process_vsrrop(0x14); break;
4683
                case tk_vand: process_vrrop(0x08); break;
4684
                case tk_vands: process_vsrrop(0x18); break;
4685
                case tk_vdiv: process_vrrop(0x3E); break;
4686
                case tk_vdivs: process_vsrrop(0x2E); break;
4687
                case tk_vmov: process_vmov(0x02,0x33); break;
4688
                case tk_vmul: process_vrrop(0x3A); break;
4689
                case tk_vmuls: process_vsrrop(0x2A); break;
4690
                case tk_vor: process_vrrop(0x09); break;
4691
                case tk_vors: process_vsrrop(0x19); break;
4692
                case tk_vsub: process_vrrop(0x05); break;
4693
                case tk_vsubs: process_vsrrop(0x15); break;
4694
                case tk_vxor: process_vrrop(0x0A); break;
4695
                case tk_vxors: process_vsrrop(0x1A); break;
4696 50 robfinch
                case tk_xnor: process_rrop(0x0E,0x0E); break;
4697
                case tk_xor: process_rrop(0x0A,0x0A); break;
4698 48 robfinch
        case tk_xori: process_riop(0x0A); break;
4699
                case tk_zxb: process_rop(0x0A); break;
4700
                case tk_zxc: process_rop(0x09); break;
4701
                case tk_zxh: process_rop(0x08); break;
4702
                case tk_id:  process_label(); break;
4703
        case '-': compress_flag = 1; expand_flag = 0; break;
4704
        }
4705
        NextToken();
4706
    }
4707
j1:
4708
    ;
4709
}
4710
 

powered by: WebSVN 2.1.0

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