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

Subversion Repositories thor

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

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

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

powered by: WebSVN 2.1.0

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