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

Subversion Repositories thor

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

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

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

powered by: WebSVN 2.1.0

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