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

Subversion Repositories thor

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

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 process_shifti(int oc, int funct3, int funct7);
29
static void ProcessEOL(int opt);
30
extern void process_message();
31
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc);
32
extern void emitNybble(int64_t);
33
extern char *pif1;
34
extern int first_rodata;
35
extern int first_data;
36
extern int first_bss;
37
extern int htable[100000];
38
extern int htblcnt[100000];
39
extern int htblmax;
40
extern int pass;
41
 
42
static double ca;
43
 
44
extern int use_gp;
45
 
46
#define OPT64     0
47
#define OPTX32    1
48
#define OPTLUI0   0
49
#define LB16    -31653LL
50
 
51
static int regSP = 63;
52
static int regFP = 62;
53
static int regLR = 61;
54
static int regXL = 60;
55
static int regGP = 59;
56
static int regTP = 58;
57
static int regCnst;
58
 
59
// ----------------------------------------------------------------------------
60
// Return the register number or -1 if not a register.
61
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
62
// ----------------------------------------------------------------------------
63
 
64
static int getRegisterX()
65
{
66
    int reg;
67
 
68
    while(isspace(*inptr)) inptr++;
69
        if (*inptr == '$')
70
                inptr++;
71
    switch(*inptr) {
72
    case 'r': case 'R':
73
        if ((inptr[1]=='a' || inptr[1]=='A') && !isIdentChar(inptr[2])) {
74
            inptr += 2;
75
            NextToken();
76
            return regLR;
77
        }
78
         if (isdigit(inptr[1])) {
79
             reg = inptr[1]-'0';
80
             if (isdigit(inptr[2])) {
81
                 reg = 10 * reg + (inptr[2]-'0');
82
                 if (isdigit(inptr[3])) {
83
                     reg = 10 * reg + (inptr[3]-'0');
84
                     if (isIdentChar(inptr[4]))
85
                         return -1;
86
                     inptr += 4;
87
                     NextToken();
88
                     return reg;
89
                 }
90
                 else if (isIdentChar(inptr[3]))
91
                     return -1;
92
                 else {
93
                     inptr += 3;
94
                     NextToken();
95
                     return reg;
96
                 }
97
             }
98
             else if (isIdentChar(inptr[2]))
99
                 return -1;
100
             else {
101
                 inptr += 2;
102
                 NextToken();
103
                 return reg;
104
             }
105
         }
106
         else return -1;
107
    case 'a': case 'A':
108
         if (isdigit(inptr[1])) {
109
             reg = inptr[1]-'0' + 35;
110
             if (isIdentChar(inptr[2]))
111
                 return -1;
112
             else {
113
                 inptr += 2;
114
                 NextToken();
115
                 return reg;
116
             }
117
         }
118
         else return -1;
119
    case 'f': case 'F':
120
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
121
            inptr += 2;
122
            NextToken();
123
            return regFP;
124
        }
125
        break;
126
    case 'g': case 'G':
127
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
128
            inptr += 2;
129
            NextToken();
130
            return regGP;
131
        }
132
        break;
133
    case 'p': case 'P':
134
        if ((inptr[1]=='C' || inptr[1]=='c') && !isIdentChar(inptr[2])) {
135
            inptr += 2;
136
            NextToken();
137
            return 31;
138
        }
139
        break;
140
    case 's': case 'S':
141
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
142
            inptr += 2;
143
            NextToken();
144
            return (regSP);
145
        }
146
        break;
147
    case 't': case 'T':
148
         if (isdigit(inptr[1])) {
149
             reg = inptr[1]-'0' + 5;
150
             if (isdigit(inptr[2])) {
151
                 reg = 10 * reg + (inptr[2]-'0');
152
                 if (isdigit(inptr[3])) {
153
                     reg = 10 * reg + (inptr[3]-'0');
154
                     if (isIdentChar(inptr[4]))
155
                         return -1;
156
                     inptr += 4;
157
                     NextToken();
158
                     return reg;
159
                 }
160
                 else if (isIdentChar(inptr[3]))
161
                     return -1;
162
                 else {
163
                     inptr += 3;
164
                     NextToken();
165
                     return reg;
166
                 }
167
             }
168
             if (isIdentChar(inptr[2]))
169
                 return -1;
170
             else {
171
                 inptr += 2;
172
                 NextToken();
173
                 return (reg);
174
             }
175
         }
176
        if ((inptr[1]=='P' || inptr[1]=='p') && !isIdentChar(inptr[2])) {
177
            inptr += 2;
178
            NextToken();
179
            return (regTP);
180
        }
181
        /*
182
        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
183
            inptr += 2;
184
            NextToken();
185
            return 24;
186
        }
187
        */
188
        break;
189
        // lr
190
    case 'l': case 'L':
191
        if ((inptr[1]=='R' || inptr[1]=='r') && !isIdentChar(inptr[2])) {
192
            inptr += 2;
193
            NextToken();
194
            return (regLR);
195
        }
196
        break;
197
        // xlr
198
    case 'x': case 'X':
199
        if ((inptr[1]=='L' || inptr[1]=='l') && (inptr[2]=='R' || inptr[2]=='r') &&
200
                        !isIdentChar(inptr[3])) {
201
            inptr += 3;
202
            NextToken();
203
            return (regXL);
204
        }
205
        break;
206
        case 'v': case 'V':
207
         if (isdigit(inptr[1])) {
208
             reg = inptr[1]-'0' + 1;
209
             if (isIdentChar(inptr[2]))
210
                 return -1;
211
             else {
212
                 inptr += 2;
213
                 NextToken();
214
                 return (reg);
215
             }
216
         }
217
                 break;
218
    default:
219
        return -1;
220
    }
221
    return -1;
222
}
223
 
224
static int isdelim(char ch)
225
{
226
    return ch==',' || ch=='[' || ch=='(' || ch==']' || ch==')' || ch=='.';
227
}
228
 
229
// ----------------------------------------------------------------------------
230
// ----------------------------------------------------------------------------
231
 
232
int GetConstantReg()
233
{
234
        static int which = 51;
235
        which++;
236
        if (which > 55)
237
                which = 52;
238
        regCnst = which;
239
        return (which);
240
}
241
 
242
// ----------------------------------------------------------------------------
243
// Return the register number or -1 if not a register.
244
// Parses pretty register names like SP or BP in addition to r1,r2,etc.
245
// ----------------------------------------------------------------------------
246
 
247
static int getVecRegister()
248
{
249
    int reg;
250
 
251
    while(isspace(*inptr)) inptr++;
252
    switch(*inptr) {
253
    case 'v': case 'V':
254
         if (isdigit(inptr[1])) {
255
             reg = inptr[1]-'0';
256
             if (isdigit(inptr[2])) {
257
                 reg = 10 * reg + (inptr[2]-'0');
258
                 if (isdigit(inptr[3])) {
259
                     reg = 10 * reg + (inptr[3]-'0');
260
                     if (isIdentChar(inptr[4]))
261
                         return -1;
262
                     inptr += 4;
263
                     NextToken();
264
                     return reg;
265
                 }
266
                 else if (isIdentChar(inptr[3]))
267
                     return -1;
268
                 else {
269
                     inptr += 3;
270
                     NextToken();
271
                     return reg;
272
                 }
273
             }
274
             else if (isIdentChar(inptr[2]))
275
                 return -1;
276
             else {
277
                 inptr += 2;
278
                 NextToken();
279
                 return reg;
280
             }
281
         }
282
                 else if (inptr[1]=='l' || inptr[1]=='L') {
283
                         if (!isIdentChar(inptr[2])) {
284
                                 inptr += 2;
285
                                 NextToken();
286
                                 return 0x28;
287
                         }
288
                 }
289
         else if (inptr[1]=='m' || inptr[1]=='M') {
290
                         if (isdigit(inptr[2])) {
291
                                 if (inptr[2] >= '0' && inptr[2] <= '7') {
292
                                         if (!isIdentChar(inptr[3])) {
293
                                                 return 0x20 | (inptr[2]-'0');
294
                                         }
295
                                 }
296
                         }
297
                 }
298
                 return -1;
299
        }
300
    return -1;
301
}
302
 
303
// ----------------------------------------------------------------------------
304
// Get the friendly name of a special purpose register.
305
// ----------------------------------------------------------------------------
306
 
307
static int DSD7_getSprRegister()
308
{
309
    int reg = -1;
310
    int pr;
311
 
312
    while(isspace(*inptr)) inptr++;
313
//    reg = getCodeareg();
314
    if (reg >= 0) {
315
       reg |= 0x10;
316
       return reg;
317
    }
318
    if (inptr[0]=='p' || inptr[0]=='P') {
319
         if (isdigit(inptr[1]) && isdigit(inptr[2])) {
320
              pr = ((inptr[1]-'0' * 10) + (inptr[2]-'0'));
321
              if (!isIdentChar(inptr[3])) {
322
                  inptr += 3;
323
                  NextToken();
324
                  return pr | 0x40;
325
              }
326
         }
327
         else if (isdigit(inptr[1])) {
328
              pr = (inptr[1]-'0');
329
              if (!isIdentChar(inptr[2])) {
330
                  inptr += 2;
331
                  NextToken();
332
                  return pr | 0x40;
333
              }
334
         }
335
     }
336
 
337
    while(isspace(*inptr)) inptr++;
338
    switch(*inptr) {
339
 
340
    case '0':
341
    case '1':
342
    case '2':
343
    case '3':
344
    case '4':
345
    case '5':
346
    case '6':
347
    case '7':
348
    case '8':
349
    case '9':
350
         NextToken();
351
         NextToken();
352
         return (int)ival.low & 0xFFF;
353
 
354
    // arg1
355
    case 'a': case 'A':
356
         if ((inptr[1]=='r' || inptr[1]=='R') &&
357
             (inptr[2]=='g' || inptr[2]=='G') &&
358
             (inptr[3]=='1' || inptr[3]=='1') &&
359
             !isIdentChar(inptr[4])) {
360
             inptr += 4;
361
             NextToken();
362
             return 58;
363
         }
364
         break;
365
    // bear
366
    case 'b': case 'B':
367
         if ((inptr[1]=='e' || inptr[1]=='E') &&
368
             (inptr[2]=='a' || inptr[2]=='A') &&
369
             (inptr[3]=='r' || inptr[3]=='R') &&
370
             !isIdentChar(inptr[4])) {
371
             inptr += 4;
372
             NextToken();
373
             return 11;
374
         }
375
         break;
376
    // cas clk cr0 cr3 cs CPL
377
    case 'c': case 'C':
378
         if ((inptr[1]=='a' || inptr[1]=='A') &&
379
             (inptr[2]=='s' || inptr[2]=='S') &&
380
             !isIdentChar(inptr[3])) {
381
             inptr += 3;
382
             NextToken();
383
             return 44;
384
         }
385
         if ((inptr[1]=='l' || inptr[1]=='L') &&
386
             (inptr[2]=='k' || inptr[2]=='K') &&
387
             !isIdentChar(inptr[3])) {
388
             inptr += 3;
389
             NextToken();
390
             return 0x06;
391
         }
392
         if ((inptr[1]=='r' || inptr[1]=='R') &&
393
             (inptr[2]=='0') &&
394
             !isIdentChar(inptr[3])) {
395
             inptr += 3;
396
             NextToken();
397
             return 0x00;
398
         }
399
         if ((inptr[1]=='r' || inptr[1]=='R') &&
400
             (inptr[2]=='3') &&
401
             !isIdentChar(inptr[3])) {
402
             inptr += 3;
403
             NextToken();
404
             return 0x03;
405
         }
406
        if ((inptr[1]=='s' || inptr[1]=='S') &&
407
            !isIdentChar(inptr[2])) {
408
            if (inptr[2]=='.') {
409
               if ((inptr[3]=='l' || inptr[3]=='L') &&
410
                   (inptr[4]=='m' || inptr[4]=='M') &&
411
                   (inptr[5]=='t' || inptr[5]=='T') &&
412
                   !isIdentChar(inptr[6])) {
413
                       inptr += 6;
414
                       NextToken();
415
                       return 0x2F;
416
               }
417
            }
418
            inptr += 2;
419
            NextToken();
420
            return 0x27;
421
        }
422
         if ((inptr[1]=='p' || inptr[1]=='P') &&
423
             (inptr[2]=='l' || inptr[2]=='L') &&
424
             !isIdentChar(inptr[3])) {
425
             inptr += 3;
426
             NextToken();
427
             return 42;
428
         }
429
         break;
430
 
431
    // dbad0 dbad1 dbctrl dpc dsp ds
432
    case 'd': case 'D':
433
         if ((inptr[1]=='b' || inptr[1]=='B') &&
434
             (inptr[2]=='a' || inptr[2]=='A') &&
435
             (inptr[3]=='d' || inptr[3]=='D') &&
436
             (inptr[4]=='0' || inptr[4]=='0') &&
437
             !isIdentChar(inptr[5])) {
438
             inptr += 5;
439
             NextToken();
440
             return 50;
441
         }
442
         if ((inptr[1]=='b' || inptr[1]=='B') &&
443
             (inptr[2]=='a' || inptr[2]=='A') &&
444
             (inptr[3]=='d' || inptr[3]=='D') &&
445
             (inptr[4]=='1' || inptr[4]=='1') &&
446
             !isIdentChar(inptr[5])) {
447
             inptr += 5;
448
             NextToken();
449
             return 51;
450
         }
451
         if ((inptr[1]=='b' || inptr[1]=='B') &&
452
             (inptr[2]=='a' || inptr[2]=='A') &&
453
             (inptr[3]=='d' || inptr[3]=='D') &&
454
             (inptr[4]=='2' || inptr[4]=='2') &&
455
             !isIdentChar(inptr[5])) {
456
             inptr += 5;
457
             NextToken();
458
             return 52;
459
         }
460
         if ((inptr[1]=='b' || inptr[1]=='B') &&
461
             (inptr[2]=='a' || inptr[2]=='A') &&
462
             (inptr[3]=='d' || inptr[3]=='D') &&
463
             (inptr[4]=='3' || inptr[4]=='3') &&
464
             !isIdentChar(inptr[5])) {
465
             inptr += 5;
466
             NextToken();
467
             return 53;
468
         }
469
         if ((inptr[1]=='b' || inptr[1]=='B') &&
470
             (inptr[2]=='c' || inptr[2]=='C') &&
471
             (inptr[3]=='t' || inptr[3]=='T') &&
472
             (inptr[4]=='r' || inptr[4]=='R') &&
473
             (inptr[5]=='l' || inptr[5]=='L') &&
474
             !isIdentChar(inptr[6])) {
475
             inptr += 6;
476
             NextToken();
477
             return 54;
478
         }
479
         if ((inptr[1]=='p' || inptr[1]=='P') &&
480
             (inptr[2]=='c' || inptr[2]=='C') &&
481
             !isIdentChar(inptr[3])) {
482
             inptr += 3;
483
             NextToken();
484
             return 7;
485
         }
486
         if (
487
             (inptr[1]=='b' || inptr[1]=='B') &&
488
             (inptr[2]=='p' || inptr[2]=='P') &&
489
             (inptr[3]=='c' || inptr[3]=='C') &&
490
             !isIdentChar(inptr[4])) {
491
             inptr += 4;
492
             NextToken();
493
             return 7;
494
         }
495
         if ((inptr[1]=='s' || inptr[1]=='S') &&
496
             (inptr[2]=='p' || inptr[2]=='P') &&
497
             !isIdentChar(inptr[3])) {
498
             inptr += 3;
499
             NextToken();
500
             return 16;
501
         }
502
        if ((inptr[1]=='s' || inptr[1]=='S') &&
503
            !isIdentChar(inptr[2])) {
504
            if (inptr[2]=='.') {
505
               if ((inptr[3]=='l' || inptr[3]=='L') &&
506
                   (inptr[4]=='m' || inptr[4]=='M') &&
507
                   (inptr[5]=='t' || inptr[5]=='T') &&
508
                   !isIdentChar(inptr[6])) {
509
                       inptr += 6;
510
                       NextToken();
511
                       return 0x29;
512
               }
513
            }
514
            inptr += 2;
515
            NextToken();
516
            return 0x21;
517
        }
518
         break;
519
 
520
    // ea epc esp es
521
    case 'e': case 'E':
522
         if ((inptr[1]=='a' || inptr[1]=='A') &&
523
             !isIdentChar(inptr[2])) {
524
             inptr += 2;
525
             NextToken();
526
             return 40;
527
         }
528
         if ((inptr[1]=='p' || inptr[1]=='P') &&
529
             (inptr[2]=='c' || inptr[2]=='C') &&
530
             !isIdentChar(inptr[3])) {
531
             inptr += 3;
532
             NextToken();
533
             return 9;
534
         }
535
         if ((inptr[1]=='s' || inptr[1]=='S') &&
536
             (inptr[2]=='p' || inptr[2]=='P') &&
537
             !isIdentChar(inptr[3])) {
538
             inptr += 3;
539
             NextToken();
540
             return 17;
541
         }
542
        if ((inptr[1]=='s' || inptr[1]=='S') &&
543
            !isIdentChar(inptr[2])) {
544
            if (inptr[2]=='.') {
545
               if ((inptr[3]=='l' || inptr[3]=='L') &&
546
                   (inptr[4]=='m' || inptr[4]=='M') &&
547
                   (inptr[5]=='t' || inptr[5]=='T') &&
548
                   !isIdentChar(inptr[6])) {
549
                       inptr += 6;
550
                       NextToken();
551
                       return 0x2A;
552
               }
553
            }
554
            inptr += 2;
555
            NextToken();
556
            return 0x22;
557
        }
558
         break;
559
 
560
    // fault_pc fs
561
    case 'f': case 'F':
562
         if ((inptr[1]=='a' || inptr[1]=='A') &&
563
             (inptr[2]=='u' || inptr[2]=='U') &&
564
             (inptr[3]=='l' || inptr[3]=='L') &&
565
             (inptr[4]=='t' || inptr[4]=='T') &&
566
             (inptr[5]=='_' || inptr[5]=='_') &&
567
             (inptr[6]=='p' || inptr[6]=='P') &&
568
             (inptr[7]=='c' || inptr[7]=='C') &&
569
             !isIdentChar(inptr[8])) {
570
             inptr += 8;
571
             NextToken();
572
             return 0x08;
573
         }
574
        if ((inptr[1]=='s' || inptr[1]=='S') &&
575
            !isIdentChar(inptr[2])) {
576
            if (inptr[2]=='.') {
577
               if ((inptr[3]=='l' || inptr[3]=='L') &&
578
                   (inptr[4]=='m' || inptr[4]=='M') &&
579
                   (inptr[5]=='t' || inptr[5]=='T') &&
580
                   !isIdentChar(inptr[6])) {
581
                       inptr += 6;
582
                       NextToken();
583
                       return 0x2B;
584
               }
585
            }
586
            inptr += 2;
587
            NextToken();
588
            return 0x23;
589
        }
590
         break;
591
 
592
    // gs GDT
593
    case 'g': case 'G':
594
        if ((inptr[1]=='s' || inptr[1]=='S') &&
595
            !isIdentChar(inptr[2])) {
596
            if (inptr[2]=='.') {
597
               if ((inptr[3]=='l' || inptr[3]=='L') &&
598
                   (inptr[4]=='m' || inptr[4]=='M') &&
599
                   (inptr[5]=='t' || inptr[5]=='T') &&
600
                   !isIdentChar(inptr[6])) {
601
                       inptr += 6;
602
                       NextToken();
603
                       return 0x2C;
604
               }
605
            }
606
            inptr += 2;
607
            NextToken();
608
            return 0x24;
609
        }
610
        if ((inptr[1]=='d' || inptr[1]=='D') &&
611
           (inptr[2]=='t' || inptr[2]=='T') &&
612
            !isIdentChar(inptr[3])) {
613
            inptr += 3;
614
            NextToken();
615
            return 41;
616
        }
617
        break;
618
 
619
    // history
620
    case 'h': case 'H':
621
         if ((inptr[1]=='i' || inptr[1]=='I') &&
622
             (inptr[2]=='s' || inptr[2]=='S') &&
623
             (inptr[3]=='t' || inptr[3]=='T') &&
624
             (inptr[4]=='o' || inptr[4]=='O') &&
625
             (inptr[5]=='r' || inptr[5]=='R') &&
626
             (inptr[6]=='y' || inptr[6]=='Y') &&
627
             !isIdentChar(inptr[7])) {
628
             inptr += 7;
629
             NextToken();
630
             return 0x0D;
631
         }
632
        if ((inptr[1]=='s' || inptr[1]=='S') &&
633
            !isIdentChar(inptr[2])) {
634
            if (inptr[2]=='.') {
635
               if ((inptr[3]=='l' || inptr[3]=='L') &&
636
                   (inptr[4]=='m' || inptr[4]=='M') &&
637
                   (inptr[5]=='t' || inptr[5]=='T') &&
638
                   !isIdentChar(inptr[6])) {
639
                       inptr += 6;
640
                       NextToken();
641
                       return 0x2D;
642
               }
643
            }
644
            inptr += 2;
645
            NextToken();
646
            return 0x25;
647
        }
648
         break;
649
 
650
    // ipc isp ivno
651
    case 'i': case 'I':
652
         if ((inptr[1]=='p' || inptr[1]=='P') &&
653
             (inptr[2]=='c' || inptr[2]=='C') &&
654
             !isIdentChar(inptr[3])) {
655
             inptr += 3;
656
             NextToken();
657
             return 8;
658
         }
659
         if ((inptr[1]=='s' || inptr[1]=='S') &&
660
             (inptr[2]=='p' || inptr[2]=='P') &&
661
             !isIdentChar(inptr[3])) {
662
             inptr += 3;
663
             NextToken();
664
             return 15;
665
         }
666
         if ((inptr[1]=='v' || inptr[1]=='V') &&
667
             (inptr[2]=='n' || inptr[2]=='N') &&
668
             (inptr[3]=='o' || inptr[3]=='O') &&
669
             !isIdentChar(inptr[4])) {
670
             inptr += 4;
671
             NextToken();
672
             return 0x0C;
673
         }
674
         break;
675
 
676
 
677
    // LC LDT
678
    case 'l': case 'L':
679
         if ((inptr[1]=='c' || inptr[1]=='C') &&
680
             !isIdentChar(inptr[2])) {
681
             inptr += 2;
682
             NextToken();
683
             return 0x33;
684
         }
685
         if ((inptr[1]=='d' || inptr[1]=='D') &&
686
            (inptr[2]=='t' || inptr[2]=='T') &&
687
             !isIdentChar(inptr[3])) {
688
             inptr += 3;
689
             NextToken();
690
             return 40;
691
         }
692
         break;
693
 
694
    // pregs
695
    case 'p': case 'P':
696
         if ((inptr[1]=='r' || inptr[1]=='R') &&
697
             (inptr[2]=='e' || inptr[2]=='E') &&
698
             (inptr[3]=='g' || inptr[3]=='G') &&
699
             (inptr[4]=='s' || inptr[4]=='S') &&
700
             !isIdentChar(inptr[5])) {
701
             inptr += 5;
702
             NextToken();
703
             return 52;
704
         }
705
         break;
706
 
707
    // rand
708
    case 'r': case 'R':
709
         if ((inptr[1]=='a' || inptr[1]=='A') &&
710
             (inptr[2]=='n' || inptr[2]=='N') &&
711
             (inptr[3]=='d' || inptr[3]=='D') &&
712
             !isIdentChar(inptr[4])) {
713
             inptr += 4;
714
             NextToken();
715
             return 0x12;
716
         }
717
         break;
718
    // ss_ll srand1 srand2 ss segsw segbase seglmt segacr
719
    case 's': case 'S':
720
         if ((inptr[1]=='s' || inptr[1]=='S') &&
721
             (inptr[2]=='_' || inptr[2]=='_') &&
722
             (inptr[3]=='l' || inptr[3]=='L') &&
723
             (inptr[4]=='l' || inptr[4]=='L') &&
724
             !isIdentChar(inptr[5])) {
725
             inptr += 5;
726
             NextToken();
727
             return 0x1A;
728
         }
729
         if ((inptr[1]=='r' || inptr[1]=='R') &&
730
             (inptr[2]=='a' || inptr[2]=='A') &&
731
             (inptr[3]=='n' || inptr[3]=='N') &&
732
             (inptr[4]=='d' || inptr[4]=='D') &&
733
             (inptr[5]=='1') &&
734
             !isIdentChar(inptr[6])) {
735
             inptr += 6;
736
             NextToken();
737
             return 0x10;
738
         }
739
         if ((inptr[1]=='r' || inptr[1]=='R') &&
740
             (inptr[2]=='a' || inptr[2]=='A') &&
741
             (inptr[3]=='n' || inptr[3]=='N') &&
742
             (inptr[4]=='d' || inptr[4]=='D') &&
743
             (inptr[5]=='2') &&
744
             !isIdentChar(inptr[6])) {
745
             inptr += 6;
746
             NextToken();
747
             return 0x11;
748
         }
749
         if ((inptr[1]=='p' || inptr[1]=='P') &&
750
             (inptr[2]=='r' || inptr[2]=='R') &&
751
             isdigit(inptr[3]) && isdigit(inptr[4]) &&
752
             !isIdentChar(inptr[5])) {
753
             inptr += 5;
754
             NextToken();
755
             return (inptr[3]-'0')*10 + (inptr[4]-'0');
756
         }
757
        if ((inptr[1]=='s' || inptr[1]=='S') &&
758
            !isIdentChar(inptr[2])) {
759
            if (inptr[2]=='.') {
760
               if ((inptr[3]=='l' || inptr[3]=='L') &&
761
                   (inptr[4]=='m' || inptr[4]=='M') &&
762
                   (inptr[5]=='t' || inptr[5]=='T') &&
763
                   !isIdentChar(inptr[6])) {
764
                       inptr += 6;
765
                       NextToken();
766
                       return 0x2E;
767
               }
768
            }
769
            inptr += 2;
770
            NextToken();
771
            return 0x26;
772
         }
773
         // segxxx
774
         if ((inptr[1]=='e' || inptr[1]=='E') &&
775
             (inptr[2]=='g' || inptr[2]=='G')) {
776
             // segsw
777
             if ((inptr[3]=='s' || inptr[3]=='S') &&
778
                  (inptr[4]=='w' || inptr[4]=='W') &&
779
                  !isIdentChar(inptr[5])) {
780
               inptr += 5;
781
               NextToken();
782
               return 43;
783
             }
784
             // segbase
785
             if ((inptr[3]=='b' || inptr[3]=='B') &&
786
                  (inptr[4]=='a' || inptr[4]=='A') &&
787
                  (inptr[5]=='s' || inptr[5]=='S') &&
788
                  (inptr[6]=='e' || inptr[6]=='E') &&
789
                  !isIdentChar(inptr[7])) {
790
               inptr += 7;
791
               NextToken();
792
               return 44;
793
             }
794
             // seglmt
795
             if ((inptr[3]=='l' || inptr[3]=='L') &&
796
                  (inptr[4]=='m' || inptr[4]=='M') &&
797
                  (inptr[5]=='t' || inptr[5]=='T') &&
798
                  !isIdentChar(inptr[6])) {
799
               inptr += 6;
800
               NextToken();
801
               return 45;
802
             }
803
             // segacr
804
             if ((inptr[3]=='a' || inptr[3]=='A') &&
805
                  (inptr[4]=='c' || inptr[4]=='C') &&
806
                  (inptr[5]=='r' || inptr[5]=='R') &&
807
                  !isIdentChar(inptr[6])) {
808
               inptr += 6;
809
               NextToken();
810
               return 47;
811
             }
812
         }
813
         break;
814
 
815
    // tag tick 
816
    case 't': case 'T':
817
         if ((inptr[1]=='i' || inptr[1]=='I') &&
818
             (inptr[2]=='c' || inptr[2]=='C') &&
819
             (inptr[3]=='k' || inptr[3]=='K') &&
820
             !isIdentChar(inptr[4])) {
821
             inptr += 4;
822
             NextToken();
823
             return 0x32;
824
         }
825
         if ((inptr[1]=='a' || inptr[1]=='A') &&
826
             (inptr[2]=='g' || inptr[2]=='G') &&
827
             !isIdentChar(inptr[3])) {
828
             inptr += 3;
829
             NextToken();
830
             return 41;
831
         }
832
         break;
833
 
834
    // vbr
835
    case 'v': case 'V':
836
         if ((inptr[1]=='b' || inptr[1]=='B') &&
837
             (inptr[2]=='r' || inptr[2]=='R') &&
838
             !isIdentChar(inptr[3])) {
839
             inptr += 3;
840
             NextToken();
841
             return 10;
842
         }
843
         break;
844
    case 'z': case 'Z':
845
        if ((inptr[1]=='s' || inptr[1]=='S') &&
846
            !isIdentChar(inptr[2])) {
847
            if (inptr[2]=='.') {
848
               if ((inptr[3]=='l' || inptr[3]=='L') &&
849
                   (inptr[4]=='m' || inptr[4]=='M') &&
850
                   (inptr[5]=='t' || inptr[5]=='T') &&
851
                   !isIdentChar(inptr[6])) {
852
                       inptr += 6;
853
                       NextToken();
854
                       return 0x28;
855
               }
856
            }
857
            inptr += 2;
858
            NextToken();
859
            return 0x20;
860
        }
861
        break;
862
    }
863
    return -1;
864
}
865
 
866
// ---------------------------------------------------------------------------
867
// Process the size specifier for a FP instruction.
868
// ---------------------------------------------------------------------------
869
static int GetFPSize()
870
{
871
        int sz;
872
 
873
    sz = 'q';
874
    if (*inptr=='.') {
875
        inptr++;
876
        if (strchr("sdtqSDTQ",*inptr)) {
877
            sz = tolower(*inptr);
878
            inptr++;
879
        }
880
        else
881
            printf("Illegal float size.\r\n");
882
    }
883
        switch(sz) {
884
        case 's':       sz = 0; break;
885
        case 'd':       sz = 1; break;
886
        case 't':       sz = 2; break;
887
        case 'q':       sz = 3; break;
888
        default:        sz = 3; break;
889
        }
890
        return (sz);
891
}
892
 
893
// ---------------------------------------------------------------------------
894
// ---------------------------------------------------------------------------
895
 
896
static void emit_prefix(int64_t val)
897
{
898
        // Fit in 42 bits ?
899
        if (val < -0x20000000000LL || val > 0x1FFFFFFFFFFLL) {
900
                emitCode((((val >> 16) & 3) << 6) | 0x1A);
901
                emitCode((val >> 18) & 255);
902
                emitCode((val >> 26) & 255);
903
                emitCode((val >> 34) & 255);
904
                emitCode((((val >> 42) & 3) << 6) | 0x1B);
905
                emitCode((val >> 44) & 255);
906
                emitCode((val >> 52) & 255);
907
                emitCode((val >> 60) & 255);
908
        }
909
        // Fit in 16 bits ?
910
        else if (val < -32768 || val > 32768) {
911
                emitCode((((val >> 16) & 3) << 6) | 0x1A);
912
                emitCode((val >> 18) & 255);
913
                emitCode((val >> 26) & 255);
914
                emitCode((val >> 34) & 255);
915
        }
916
}
917
 
918
// ---------------------------------------------------------------------------
919
// ---------------------------------------------------------------------------
920
 
921
static void emit_insn(int64_t oc, int can_compress, int sz)
922
{
923
    int ndx;
924
 
925
    if (pass==3 && can_compress && gCanCompress) {
926
       for (ndx = 0; ndx < htblmax; ndx++) {
927
         if ((int)oc == hTable[ndx].opcode) {
928
           hTable[ndx].count++;
929
           return;
930
         }
931
       }
932
       if (htblmax < 100000) {
933
          hTable[htblmax].opcode = (int)oc;
934
          hTable[htblmax].count = 1;
935
          htblmax++;
936
          return;
937
       }
938
       printf("Too many instructions.\r\n");
939
       return;
940
    }
941
    if (pass > 3) {
942
     if (can_compress && gCanCompress) {
943
       for (ndx = 0; ndx < htblmax; ndx++) {
944
         if ((int)oc == hTable[ndx].opcode) {
945
           emitCode((ndx << 6)|0x1F);
946
                   num_bytes += 2;
947
                   num_insns += 1;
948
           return;
949
         }
950
       }
951
     }
952
         emitNybble(oc & 15);
953
         emitNybble((oc >> 4) & 15);
954
         emitNybble((oc >> 8) & 15);
955
         emitNybble((oc >> 12) & 15);
956
         emitNybble((oc >> 16) & 15);
957
         emitNybble((oc >> 20) & 15);
958
         emitNybble((oc >> 24) & 15);
959
         emitNybble((oc >> 28) & 15);
960
         emitNybble((oc >> 32) & 15);
961
     num_bytes += 4.5;
962
        if ((code_address & 31)==31)
963
                 emitNybble(0);
964
 
965
        //if (sz==3) {
966
        //      emitCode((int)(oc >> 16));
967
 //         num_bytes += 2;
968
        //      emitCode(oc >> 32);
969
 //         num_bytes += 2;
970
        //}
971
    num_insns += 1;
972
    /*
973
    if (processOpt==2) {
974
       for (ndx = 0; ndx < htblmax; ndx++) {
975
         if (oc == hTable[ndx].opcode) {
976
           printf("found opcode\n");
977
           emitAlignedCode(((ndx & 8) << 4)|0x50|(ndx & 0x7));
978
           emitCode(ndx >> 4);
979
           return;
980
         }
981
       }
982
     emitAlignedCode(oc & 255);
983
     emitCode((oc >> 8) & 255);
984
     emitCode((oc >> 16) & 255);
985
     emitCode((oc >> 24) & 255);
986
    }
987
    else {
988
     emitAlignedCode(oc & 255);
989
     emitCode((oc >> 8) & 255);
990
     emitCode((oc >> 16) & 255);
991
     emitCode((oc >> 24) & 255);
992
    */
993
    }
994
}
995
 
996
// ----------------------------------------------------------------------------
997
// ----------------------------------------------------------------------------
998
static void getSz(int *sz)
999
{
1000
        if (*inptr=='.')
1001
                inptr++;
1002
    *sz = inptr[0];
1003
    switch(*sz) {
1004
    case 'b': case 'B': *sz = 0; break;
1005
    case 'c': case 'C': *sz = 1; break;
1006
    case 'h': case 'H': *sz = 2; break;
1007
    case 'w': case 'W': *sz = 3; break;
1008
        case 'd': case 'D': *sz = 0x83; break;
1009
        case 'i': case 'I': *sz = 0x43; break;
1010
    default:
1011
             printf("%d bad size.\r\n", lineno);
1012
             *sz = 3;
1013
    }
1014
    inptr += 1;
1015
}
1016
 
1017
// ---------------------------------------------------------------------------
1018
// addi r1,r2,#1234
1019
//
1020
// A value that is too large has to be loaded into a register then the
1021
// instruction converted to a registered form.
1022
// So
1023
//              addi    r1,r2,#$12345678
1024
// Becomes:
1025
//              ori             r23,r0,#$5678
1026
//              oriq1   r23,#$1234
1027
//              addi    r1,r2,r23
1028
// ---------------------------------------------------------------------------
1029
 
1030
static void process_riop(int64_t opcode6)
1031
{
1032
    int Ra;
1033
    int Rt;
1034
    char *p;
1035
    int64_t val;
1036
 
1037
    p = inptr;
1038
    Rt = getRegisterX();
1039
    need(',');
1040
    Ra = getRegisterX();
1041
    need(',');
1042
    NextToken();
1043
    val = expr();
1044
        if (opcode6==0x05)      { // subi
1045
                val = -val;
1046
                opcode6 = 0x04; // change to addi
1047
        }
1048
        if (val < -131072 || val > 131072) {
1049
                GetConstantReg();
1050
                emit_insn(
1051
                        (val << 18) |
1052
                        (regCnst << 12) |
1053
                        (0 << 6) |
1054
                        0x09,!expand_flag,4);   // ORI
1055
                val >>= 16;
1056
                emit_insn(
1057
                        (val << 18) |
1058
                        (regCnst << 12) |
1059
                        (0 << 6) |
1060
                        (1 << 6) |
1061
                        0x1A,!expand_flag,4);   // ORQ1
1062
                val >>= 16;
1063
                if (val != 0) {
1064
                        emit_insn(
1065
                                (val << 18) |
1066
                                (regCnst << 12) |
1067
                                (0 << 6) |
1068
                                (2 << 6) |
1069
                                0x1A,!expand_flag,4);   // ORQ2
1070
                }
1071
                val >>= 16;
1072
                if (val != 0) {
1073
                        emit_insn(
1074
                                (val << 18) |
1075
                                (regCnst << 12) |
1076
                                (0 << 6) |
1077
                                (3 << 6) |
1078
                                0x1A,!expand_flag,4);   // ORQ3
1079
                }
1080
                emit_insn(
1081
                        (opcode6 << 30) |
1082
                        (3 << 24) |             // set size to word size op
1083
                        (Rt << 18) |
1084
                        (regCnst << 12) |
1085
                        (Ra << 6) |
1086
                        0x02,!expand_flag,4);
1087
                return;
1088
        }
1089
        emit_insn(((val & 0x3FFFF) << 18)|(Rt << 12)|(Ra << 6)|opcode6,!expand_flag,4);
1090
}
1091
 
1092
// ---------------------------------------------------------------------------
1093
// slti r1,r2,#1234
1094
//
1095
// A value that is too large has to be loaded into a register then the
1096
// instruction converted to a registered form.
1097
// ---------------------------------------------------------------------------
1098
 
1099
static void process_setiop(int opcode6, int cond4)
1100
{
1101
    int Ra;
1102
    int Rt;
1103
    char *p;
1104
    int64_t val;
1105
 
1106
    p = inptr;
1107
    Rt = getRegisterX();
1108
    need(',');
1109
    Ra = getRegisterX();
1110
    need(',');
1111
    NextToken();
1112
    val = expr();
1113
        if (val < -1024 || val > 1023) {
1114
                GetConstantReg();
1115
                emit_insn(
1116
                        (val << 16) |
1117
                        (regCnst << 11) |
1118
                        (0 << 6) |
1119
                        0x09,!expand_flag,4);   // ORI
1120
                val >>= 16;
1121
                emit_insn(
1122
                        (val << 16) |
1123
                        (regCnst << 11) |
1124
                        (0 << 6) |
1125
                        (1 << 6) |
1126
                        0x1A,!expand_flag,4);   // ORQ1
1127
                val >>= 16;
1128
                if (val != 0) {
1129
                        emit_insn(
1130
                                (val << 16) |
1131
                                (regCnst << 11) |
1132
                                (0 << 6) |
1133
                                (2 << 6) |
1134
                                0x1A,!expand_flag,4);   // ORQ2
1135
                }
1136
                val >>= 16;
1137
                if (val != 0) {
1138
                        emit_insn(
1139
                                (val << 16) |
1140
                                (regCnst << 11) |
1141
                                (0 << 6) |
1142
                                (3 << 6) |
1143
                                0x1A,!expand_flag,4);   // ORQ3
1144
                }
1145
                emit_insn(
1146
                        (((cond4 >= 12 && cond4 <= 15) ? 7 : 6) << 26) |
1147
                        ((cond4 & 7) << 23) |
1148
                        (3 << 21) |             // set size to word size op
1149
                        (Rt << 16) |
1150
                        (regCnst << 11) |
1151
                        (Ra << 6) |
1152
                        0x02,!expand_flag,4);
1153
                return;
1154
        }
1155
        emit_insn(
1156
                (cond4<<28)|
1157
                ((val & 0xFFF) << 16)|
1158
                (Rt << 11)|(Ra << 6)|
1159
                opcode6,!expand_flag,4);
1160
}
1161
 
1162
// ---------------------------------------------------------------------------
1163
// ---------------------------------------------------------------------------
1164
 
1165
static void process_rrop(int64_t funct6)
1166
{
1167
    int Ra,Rb,Rt;
1168
    char *p;
1169
        int sz = 3;
1170
 
1171
    p = inptr;
1172
        if (*p=='.')
1173
                getSz(&sz);
1174
    Rt = getRegisterX();
1175
    need(',');
1176
    Ra = getRegisterX();
1177
    need(',');
1178
    NextToken();
1179
    if (token=='#') {
1180
        inptr = p;
1181
        process_riop(funct6);
1182
        return;
1183
    }
1184
    prevToken();
1185
    Rb = getRegisterX();
1186
    //prevToken();
1187
        if (funct6==0x2ELL || funct6==0x2CLL || funct6==0x2DLL) {
1188
                funct6 += 0x10LL;       // change to divmod
1189
            emit_insn((funct6<<30)||(Rt<<24)|(Rb<<12)|(Ra<<6)|0x02,!expand_flag,4);
1190
                return;
1191
        }
1192
        // No size is emitted for divides
1193
        else if (funct6==0x3CLL || funct6==0x3DLL || funct6==0x3ELL) {
1194
            emit_insn((funct6<<30)||(Rt<<18)|(Rb<<12)|(Ra<<6)|0x02,!expand_flag,4);
1195
                return;
1196
        }
1197
        if (funct6==0x07) {     // CMPU
1198
            emit_insn((0x06LL<<30)|(0x01 << 26)|(sz << 24)|(Rt<<18)|(Rb<<12)|(Ra<<6)|0x02,!expand_flag,4);
1199
                return;
1200
        }
1201
    emit_insn((funct6<<30)|(sz << 24)|(Rt<<18)|(Rb<<12)|(Ra<<6)|0x02,!expand_flag,4);
1202
}
1203
 
1204
// ---------------------------------------------------------------------------
1205
// jmp main
1206
// jal [r19]
1207
// ---------------------------------------------------------------------------
1208
 
1209
static void process_jal(int oc)
1210
{
1211
    int64_t addr, val;
1212
    int Ra;
1213
    int Rt;
1214
        bool noRt;
1215
 
1216
        noRt = false;
1217
        Ra = 0;
1218
    Rt = 0;
1219
    NextToken();
1220
    if (token=='(' || token=='[') {
1221
j1:
1222
       Ra = getRegisterX();
1223
       if (Ra==-1) {
1224
           printf("Expecting a register\r\n");
1225
           return;
1226
       }
1227
       // Simple jmp [Rn]
1228
       else {
1229
            if (token != ')' && token!=']')
1230
                printf("Missing close bracket\r\n");
1231
            emit_insn((Ra << 6)|(Rt<<11)|0x18,0,4);
1232
            return;
1233
       }
1234
    }
1235
    prevToken();
1236
    Rt = getRegisterX();
1237
    if (Rt >= 0) {
1238
        need(',');
1239
        NextToken();
1240
        // jal Rt,[Ra]
1241
        if (token=='(' || token=='[')
1242
           goto j1;
1243
    }
1244
    else {
1245
        Rt = 0;
1246
                noRt = true;
1247
        }
1248
        addr = expr();
1249
    // d(Rn)? 
1250
    //NextToken();
1251
    if (token=='(' || token=='[') {
1252
        Ra = getRegisterX();
1253
        if (Ra==-1) {
1254
            printf("Illegal jump address mode.\r\n");
1255
            Ra = 0;
1256
        }
1257
                if (Ra==31)     // program counter relative ?
1258
                        addr -= code_address;
1259
        }
1260
        val = addr;
1261
        if (noRt && val > 0xfffffffff8000000LL && val < 0x7ffffffLL) {
1262
                emit_insn(
1263
                        (((val & 0xfffffff) >> 2) << 6) |
1264
                        0x19,0,4
1265
                );
1266
                return;
1267
        }
1268
        if (val < -131072 || val > 131071) {
1269
                GetConstantReg();
1270
                emit_insn(
1271
                        (val << 16) |
1272
                        (regCnst << 11) |
1273
                        (0 << 6) |
1274
                        0x09,!expand_flag,4);   // ORI
1275
                val >>= 16;
1276
                emit_insn(
1277
                        (val << 16) |
1278
                        (regCnst << 11) |
1279
                        (0 << 6) |
1280
                        (1 << 6) |
1281
                        0x1A,!expand_flag,4);   // ORQ1
1282
                val >>= 16;
1283
                if (val != 0) {
1284
                        emit_insn(
1285
                                (val << 16) |
1286
                                (regCnst << 11) |
1287
                                (0 << 6) |
1288
                                (2 << 6) |
1289
                                0x1A,!expand_flag,4);   // ORQ2
1290
                }
1291
                val >>= 16;
1292
                if (val != 0) {
1293
                        emit_insn(
1294
                                (val << 16) |
1295
                                (regCnst << 11) |
1296
                                (0 << 6) |
1297
                                (3 << 6) |
1298
                                0x1A,!expand_flag,4);   // ORQ3
1299
                }
1300
                if (Ra != 0) {
1301
                        // add r23,r23,Ra
1302
                        emit_insn(
1303
                                (0x04 << 26) |
1304
                                (regCnst << 16) |
1305
                                (regCnst << 11) |
1306
                                (Ra << 6) |
1307
                                0x02,0,4
1308
                                );
1309
                        // jal Rt,r23
1310
                        emit_insn(
1311
                                (0 << 16) |
1312
                                (Rt << 11) |
1313
                                (regCnst << 6) | 0x18,!expand_flag,4);
1314
                        return;
1315
                }
1316
                emit_insn(
1317
                        (0 << 16) |
1318
                        (Rt << 11) |
1319
                        (regCnst << 6) | 0x18,!expand_flag,4);
1320
                return;
1321
        }
1322
        emit_insn((addr << 16) | (Rt << 11) | (Ra << 6) | 0x18,!expand_flag,4);
1323
}
1324
 
1325
// ---------------------------------------------------------------------------
1326
// subui r1,r2,#1234
1327
// ---------------------------------------------------------------------------
1328
/*
1329
static void process_riop(int oc)
1330
{
1331
    int Ra;
1332
    int Rt;
1333
    char *p;
1334
    int64_t val;
1335
 
1336
    p = inptr;
1337
    Rt = getRegisterX();
1338
    need(',');
1339
    Ra = getRegisterX();
1340
    need(',');
1341
    NextToken();
1342
    val = expr();
1343
 
1344
   if (lastsym != (SYM *)NULL)
1345
       emitImm16(val,!lastsym->defined);
1346
   else
1347
       emitImm16(val,0);
1348
 
1349
    emitImm16(val,lastsym!=(SYM*)NULL);
1350
    emitAlignedCode(oc);
1351
    if (bGen)
1352
    if (lastsym && !use_gp) {
1353
        if( lastsym->segment < 5)
1354
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
1355
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
1356
    }
1357
    emitCode(Ra);
1358
    emitCode(Rt);
1359
    emitCode(val & 255);
1360
    emitCode((val >> 8) & 255);
1361
}
1362
*/
1363
// ---------------------------------------------------------------------------
1364
// fabs.d fp1,fp2[,rm]
1365
// ---------------------------------------------------------------------------
1366
 
1367
static void process_fprop(int oc)
1368
{
1369
    int Ra;
1370
    int Rt;
1371
    char *p;
1372
    int fmt;
1373
    int rm;
1374
 
1375
    rm = 0;
1376
    fmt = GetFPSize();
1377
    p = inptr;
1378
    if (oc==0x01)        // fcmp
1379
        Rt = getRegisterX();
1380
    else
1381
        Rt = getFPRegister();
1382
    need(',');
1383
    Ra = getFPRegister();
1384
    if (token==',')
1385
       rm = getFPRoundMode();
1386
    prevToken();
1387
    emit_insn(
1388
                        (fmt << 27)|
1389
                        (rm << 24)|
1390
                        (Rt << 18)|
1391
                        (oc << 12)|
1392
                        (Ra << 6) |
1393
                        0x36,!expand_flag,2
1394
                        );
1395
}
1396
 
1397
// ---------------------------------------------------------------------------
1398
// fadd.d fp1,fp2,fp12[,rm]
1399
// fcmp.d r1,fp3,fp10[,rm]
1400
// ---------------------------------------------------------------------------
1401
 
1402
static void process_fprrop(int oc)
1403
{
1404
    int Ra;
1405
    int Rb;
1406
    int Rt;
1407
    char *p;
1408
    int fmt;
1409
    int rm;
1410
 
1411
    rm = 0;
1412
    fmt = GetFPSize();
1413
    p = inptr;
1414
    if (oc==0x01)        // fcmp
1415
        Rt = getRegisterX();
1416
    else
1417
        Rt = getFPRegister();
1418
    need(',');
1419
    Ra = getFPRegister();
1420
    need(',');
1421
    Rb = getFPRegister();
1422
    if (token==',')
1423
       rm = getFPRoundMode();
1424
    prevToken();
1425
    emit_insn(
1426
                        (oc << 29)|
1427
                        (fmt << 27)|
1428
                        (rm << 24)|
1429
                        (Rt << 18)|
1430
                        (Rb << 12)|
1431
                        (Ra << 6) |
1432
                        0x36,!expand_flag,4
1433
                        );
1434
}
1435
 
1436
// ---------------------------------------------------------------------------
1437
// fcx r0,#2
1438
// fdx r1,#0
1439
// ---------------------------------------------------------------------------
1440
 
1441
static void process_fpstat(int oc)
1442
{
1443
    int Ra;
1444
    int64_t bits;
1445
    char *p;
1446
 
1447
    p = inptr;
1448
    bits = 0;
1449
    Ra = getRegisterX();
1450
    if (token==',') {
1451
       NextToken();
1452
       bits = expr();
1453
    }
1454
    prevToken();
1455
        emit_insn(
1456
                ((bits & 0x3F) << 18) |
1457
                (oc << 12) |
1458
                (Ra << 6) |
1459
                0x36,!expand_flag,2
1460
                );
1461
}
1462
 
1463
// ---------------------------------------------------------------------------
1464
// not r3,r3
1465
// ---------------------------------------------------------------------------
1466
 
1467
static void process_rop(int oc)
1468
{
1469
    int Ra;
1470
    int Rt;
1471
 
1472
    Rt = getRegisterX();
1473
    need(',');
1474
    Ra = getRegisterX();
1475
        emit_insn(
1476
                (1 << 26) |
1477
                (oc << 21) |
1478
                (Rt << 16) |
1479
                (Ra << 6) |
1480
                0x02,!expand_flag,4
1481
                );
1482
        prevToken();
1483
}
1484
 
1485
// ---------------------------------------------------------------------------
1486
// beqi r2,#123,label
1487
// ---------------------------------------------------------------------------
1488
 
1489
static void process_beqi(int opcode6, int opcode3)
1490
{
1491
    int Ra;
1492
    int64_t val, imm;
1493
    int64_t disp;
1494
 
1495
    Ra = getRegisterX();
1496
    need(',');
1497
    NextToken();
1498
    imm = expr();
1499
        need(',');
1500
        NextToken();
1501
        val = expr();
1502
        disp = val - (code_address + 4);
1503
        if (imm < -256 || imm > 255) {
1504
                printf("Branch immediate too large: %d %d", lineno, imm);
1505
        }
1506
        emit_insn((((disp >> 3) & 0x3FF) << 22) |
1507
                (opcode3 << 17) |
1508
                ((imm & 0x1FF) << 11) |
1509
                (Ra << 6) |
1510
                ((disp>>2) & 1) |
1511
                opcode6,0,4
1512
        );
1513
    return;
1514
}
1515
 
1516
 
1517
// ---------------------------------------------------------------------------
1518
// beq r1,r2,label
1519
// bne r2,r3,r4
1520
//
1521
// When opcode4 is negative it indicates to swap the a and b registers. This
1522
// allows source code to use alternate forms of branch conditions.
1523
// ---------------------------------------------------------------------------
1524
 
1525
static void process_bcc(int64_t opcode6, int64_t opcode4)
1526
{
1527
    int Ra, Rb, Rc, pred;
1528
    int64_t val;
1529
    int64_t disp;
1530
        char *p, *p1;
1531
 
1532
        pred = 0;
1533
        p1 = inptr;
1534
    Ra = getRegisterX();
1535
    need(',');
1536
    Rb = getRegisterX();
1537
    need(',');
1538
        p = inptr;
1539
        Rc = getRegisterX();
1540
        if (Rc==-1) {
1541
                inptr = p;
1542
            NextToken();
1543
                if (token=='#' && opcode4==0) {
1544
                        inptr = p1;
1545
                        process_beqi(0x32,0);
1546
                        return;
1547
                }
1548
                val = expr();
1549
                disp = val - (code_address + 4);
1550
                if (token==',') {
1551
                        NextToken();
1552
                        pred = (int)expr();
1553
                }
1554
                if (opcode4 < 0) {
1555
                        opcode4 = -opcode4;
1556
                        emit_insn(((disp >> 3) & 0x3FF) << 24 |
1557
                                ((pred & 3) << 22) |
1558
                                (opcode4 << 18) |
1559
                                (Ra << 12) |
1560
                                (Rb << 6) |
1561
                                ((disp >> 2) & 1) |
1562
                                opcode6,0,4
1563
                        );
1564
                        return;
1565
                }
1566
            emit_insn(((disp >> 3) & 0x3FF) << 24 |
1567
                        ((pred & 3) << 22) |
1568
                        (opcode4 << 18) |
1569
                        (Rb << 12) |
1570
                        (Ra << 6) |
1571
                        ((disp >> 2) & 1) |
1572
                        opcode6,0,4
1573
                );
1574
                return;
1575
        }
1576
        if (token==',') {
1577
                NextToken();
1578
                pred = (int)expr();
1579
        }
1580
        if (opcode4 < 0) {
1581
                opcode4 = -opcode4;
1582
                emit_insn(
1583
                        ((pred & 3) << 28) |
1584
                        (opcode4 << 24) |
1585
                        (Rc << 18) |
1586
                        (Ra << 12) |
1587
                        (Rb << 6) |
1588
                        0x03,0,4
1589
                );
1590
        }
1591
        emit_insn(
1592
                ((pred & 3) << 28) |
1593
                (opcode4 << 24) |
1594
                (Rc << 18) |
1595
                (Rb << 12) |
1596
                (Ra << 6) |
1597
                0x03,0,4
1598
        );
1599
}
1600
 
1601
// ---------------------------------------------------------------------------
1602
// bfextu r1,r2,#1,#63
1603
// ---------------------------------------------------------------------------
1604
 
1605
static void process_bitfield(int oc)
1606
{
1607
    int Ra;
1608
    int Rt;
1609
    int64_t mb;
1610
    int64_t me;
1611
 
1612
    Rt = getRegisterX();
1613
    need(',');
1614
    Ra = getRegisterX();
1615
    need(',');
1616
    NextToken();
1617
    mb = expr();
1618
    need(',');
1619
    NextToken();
1620
    me = expr();
1621
        emit_insn(
1622
                (oc << 28) |
1623
                (me << 22) |
1624
                (mb << 16) |
1625
                (Rt << 11) |
1626
                (Ra << 6) |
1627
                0x22,0,4
1628
        );
1629
}
1630
 
1631
 
1632
// ---------------------------------------------------------------------------
1633
// bra label
1634
// ---------------------------------------------------------------------------
1635
 
1636
static void process_bra(int oc)
1637
{
1638
    int Ra = 0, Rb = 0;
1639
    int64_t val;
1640
    int64_t disp;
1641
 
1642
    NextToken();
1643
    val = expr();
1644
    disp = val - (code_address + 4);
1645
    emit_insn((((disp >> 3) & 0xFFF) << 24) |
1646
                (3 << 22) |     // static predict taken
1647
                (0 << 18) |
1648
        (0 << 12) |
1649
        (0 << 6) |
1650
                ((disp>>2) & 1) |
1651
        0x30,0,4
1652
    );
1653
}
1654
 
1655
// ----------------------------------------------------------------------------
1656
// chk r1,r2,r3,label
1657
// ----------------------------------------------------------------------------
1658
 
1659
static void process_chk(int opcode6)
1660
{
1661
        int Ra;
1662
        int Rb;
1663
        int Rc;
1664
        int64_t val, disp;
1665
 
1666
        Ra = getRegisterX();
1667
        need(',');
1668
        Rb = getRegisterX();
1669
        need(',');
1670
        Rc = getRegisterX();
1671
        need(',');
1672
        NextToken();
1673
        val = expr();
1674
    disp = val - code_address;
1675
        emit_insn(((disp >> 3) & 0x3FF) << 22 |
1676
                (Rc << 16) |
1677
                (Rb << 11) |
1678
                (Ra << 6) |
1679
                ((disp >> 2) & 1) |
1680
                opcode6,!expand_flag,4
1681
        );
1682
}
1683
 
1684
 
1685
static void process_chki(int opcode6)
1686
{
1687
        int Ra;
1688
        int Rb;
1689
        int64_t val, disp;
1690
 
1691
        Ra = getRegisterX();
1692
        need(',');
1693
        Rb = getRegisterX();
1694
        need(',');
1695
        NextToken();
1696
        val = expr();
1697
    disp = val - code_address;
1698
        if (val < LB16 || val > 32767LL) {
1699
                emit_insn((0x8000 << 16)|(Rb << 11)|(Ra << 6)|opcode6,0,2);
1700
                emit_insn(val,0,2);
1701
                return;
1702
        }
1703
        emit_insn(((val & 0xFFFF) << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,2);
1704
}
1705
 
1706
 
1707
// ---------------------------------------------------------------------------
1708
// fbeq.q fp1,fp0,label
1709
// ---------------------------------------------------------------------------
1710
 
1711
static void process_fbcc(int opcode3)
1712
{
1713
    int Ra, Rb;
1714
    int64_t val;
1715
    int64_t disp;
1716
        int sz;
1717
 
1718
    sz = GetFPSize();
1719
    Ra = getFPRegister();
1720
    need(',');
1721
    Rb = getFPRegister();
1722
    need(',');
1723
    NextToken();
1724
 
1725
    val = expr();
1726
    disp = val - code_address;
1727
        if (disp < -255 || disp > 255) {
1728
                // Flip the test
1729
                switch(opcode3) {
1730
                case 0:  opcode3 = 1; break;
1731
                case 1: opcode3 = 0; break;
1732
                case 2: opcode3 = 3; break;
1733
                case 3: opcode3 = 2; break;
1734
                case 4: opcode3 = 5; break;
1735
                case 5: opcode3 = 4; break;
1736
                case 6: opcode3 = 7; break;
1737
                case 7: opcode3 = 6; break;
1738
                }
1739
                emit_insn(
1740
                        (sz << 27) |
1741
                        (4 << 21) |
1742
                        (opcode3 << 18) |
1743
                        (Rb << 12) |
1744
                        (Ra << 6) |
1745
                        0x01,0,2
1746
                );
1747
                emit_insn((disp & 0x1FFF) << 19 |
1748
                        0x12,0,2
1749
                );
1750
                return;
1751
        }
1752
    emit_insn(
1753
                (((disp & 0x1FF) >> 6) << 29) |
1754
                (sz << 27) |
1755
                ((disp & 0x3F) << 21) |
1756
                (opcode3 << 18) |
1757
        (Rb << 12) |
1758
        (Ra << 6) |
1759
        0x01,0,2
1760
    );
1761
}
1762
 
1763
// ---------------------------------------------------------------------------
1764
// ---------------------------------------------------------------------------
1765
 
1766
static void process_call(int64_t opcode)
1767
{
1768
        int64_t val;
1769
        int Ra = 0;
1770
 
1771
    NextToken();
1772
        val = expr();
1773
        if (token=='[') {
1774
                Ra = getRegisterX();
1775
                need(']');
1776
                if (Ra==31) {
1777
                        val -= code_address;
1778
                }
1779
        }
1780
        if (val==0) {
1781
                if (opcode==0x28)       // JMP [Ra]
1782
                        // jal r0,[Ra]
1783
                        emit_insn(
1784
                                (Ra << 6) |
1785
                                0x18,0,4
1786
                        );
1787
                else
1788
                        // jal lr,[Ra]  - call [Ra]
1789
                        emit_insn(
1790
                                (regLR << 12) |
1791
                                (Ra << 6) |
1792
                                0x18,0,4
1793
                        );
1794
                return;
1795
        }
1796
        if (code_bits > 27 && (val < 0xFFFFFFFFF8000000LL || val > 0x7FFFFFFLL)) {
1797
                emit_insn(
1798
                        (val << 18) |
1799
                        (23 << 12) |
1800
                        (0 << 6) |
1801
                        0x09,!expand_flag,4);   // ORI
1802
                val >>= 16;
1803
                emit_insn(
1804
                        (val << 18) |
1805
                        (23 << 12) |
1806
                        (0 << 6) |
1807
                        (1 << 6) |
1808
                        0x1A,!expand_flag,4);   // ORQ1
1809
                val >>= 16;
1810
                if (val != 0) {
1811
                        emit_insn(
1812
                                (val << 18) |
1813
                                (23 << 12) |
1814
                                (0 << 6) |
1815
                                (2 << 6) |
1816
                                0x1A,!expand_flag,4);   // ORQ2
1817
                }
1818
                val >>= 16;
1819
                if (val != 0) {
1820
                        emit_insn(
1821
                                (val << 18) |
1822
                                (23 << 12) |
1823
                                (0 << 6) |
1824
                                (3 << 6) |
1825
                                0x1A,!expand_flag,4);   // ORQ3
1826
                }
1827
                if (Ra!=0) {
1828
                        // add r23,r23,Ra
1829
                        emit_insn(
1830
                                (0x04 << 30) |
1831
                                (23 << 18) |
1832
                                (23 << 11) |
1833
                                (Ra << 6) |
1834
                                0x02,0,4
1835
                                );
1836
                }
1837
                if (opcode==0x28)       // JMP
1838
                        // jal r0,[r23]
1839
                        emit_insn(
1840
                                (23 << 6) |
1841
                                0x18,0,4
1842
                                );
1843
                else
1844
                        // jal lr,[r23] - call [r23]
1845
                        emit_insn(
1846
                                (regLR << 12) |
1847
                                (23 << 6) |
1848
                                0x18,0,4
1849
                                );
1850
                return;
1851
        }
1852
        emit_insn(
1853
                (((val & 0xFFFFFFFF) >> 2) << 6) |
1854
                0x19,0,4
1855
                );
1856
}
1857
 
1858
static void process_iret(int op)
1859
{
1860
        int64_t val = 0;
1861
 
1862
    NextToken();
1863
        if (token=='#') {
1864
                val = expr();
1865
        }
1866
        emit_insn(
1867
                ((val & 0x3F) << 16) |
1868
                (0 << 11) |
1869
                (0 << 6) |
1870
                op,0,4
1871
        );
1872
}
1873
 
1874
static void process_ret()
1875
{
1876
        int64_t val = 0;
1877
 
1878
    NextToken();
1879
        if (token=='#') {
1880
                val = expr();
1881
        }
1882
        emit_prefix(val);
1883
        emit_insn(
1884
                (((val==0?8:val) & 0xFFFF) << 16) |
1885
                (31 << 11) |
1886
                (31 << 6) |
1887
                0x29,0,4
1888
        );
1889
}
1890
 
1891
// ----------------------------------------------------------------------------
1892
// inc -8[bp],#1
1893
// ----------------------------------------------------------------------------
1894
 
1895
static void process_inc(int oc)
1896
{
1897
    int Ra;
1898
    int Rb;
1899
        int Sc;
1900
    int64_t incamt;
1901
    int64_t disp;
1902
    char *p;
1903
    int fixup = 5;
1904
    int neg = 0;
1905
 
1906
    NextToken();
1907
    p = inptr;
1908
    mem_operand(&disp, &Ra, &Rb, &Sc);
1909
    incamt = 1;
1910
    if (token==']')
1911
       NextToken();
1912
    if (token==',') {
1913
        NextToken();
1914
        incamt = expr();
1915
        prevToken();
1916
    }
1917
    if (Rb >= 0) {
1918
       if (disp != 0)
1919
           printf("displacement not allowed with indexed addressing.\r\n");
1920
       oc = 0x6F;  // INCX
1921
           // ToDo: fix this
1922
       emit_insn(
1923
           ((disp & 0xFF) << 24) |
1924
           (Rb << 17) |
1925
           ((incamt & 0x1F) << 12) |
1926
           (Ra << 7) |
1927
           oc,0,2
1928
       );
1929
       return;
1930
    }
1931
    if (oc==0x25) neg = 1;
1932
    oc = 0x24;        // INC
1933
    if (Ra < 0) Ra = 0;
1934
    if (neg) incamt = -incamt;
1935
        if (disp < LB16 || disp > 32767LL) {
1936
                emit_insn(
1937
                        (0x8000 << 16) |
1938
                        ((incamt & 0x1f) << 11) |
1939
                        (Ra << 6) |
1940
                        oc,0,2);
1941
                emit_insn(disp,0,2);
1942
        }
1943
        else {
1944
                emit_insn(
1945
                        (disp << 16) |
1946
                        ((incamt & 0x1f) << 11) |
1947
                        (Ra << 6) |
1948
                        oc,!expand_flag,2);
1949
    }
1950
    ScanToEOL();
1951
}
1952
 
1953
// ---------------------------------------------------------------------------
1954
// ---------------------------------------------------------------------------
1955
 
1956
static void process_brk()
1957
{
1958
        int64_t val;
1959
        int inc = 1;
1960
 
1961
    NextToken();
1962
        val = expr();
1963
        NextToken();
1964
        if (token==',') {
1965
                inc = (int)expr();
1966
        }
1967
        else
1968
                prevToken();
1969
        emit_insn(
1970
                (inc << 15) |
1971
                ((val & 0x1FF) << 6) |
1972
                0x00,0,4
1973
        );
1974
}
1975
 
1976
// ---------------------------------------------------------------------------
1977
// ---------------------------------------------------------------------------
1978
 
1979
static void GetIndexScale(int *sc)
1980
{
1981
      int64_t val;
1982
 
1983
      NextToken();
1984
      val = expr();
1985
      prevToken();
1986
      switch(val) {
1987
      case 0: *sc = 0; break;
1988
      case 1: *sc = 0; break;
1989
      case 2: *sc = 1; break;
1990
      case 4: *sc = 2; break;
1991
      case 8: *sc = 3; break;
1992
      default: printf("Illegal scaling factor.\r\n");
1993
      }
1994
}
1995
 
1996
 
1997
// ---------------------------------------------------------------------------
1998
// expr
1999
// expr[Reg]
2000
// [Reg]
2001
// [Reg+Reg]
2002
// ---------------------------------------------------------------------------
2003
 
2004
static void mem_operand(int64_t *disp, int *regA, int *regB, int *Sc)
2005
{
2006
     int64_t val;
2007
 
2008
     // chech params
2009
     if (disp == (int64_t *)NULL)
2010
         return;
2011
     if (regA == (int *)NULL)
2012
         return;
2013
 
2014
     *disp = 0;
2015
     *regA = -1;
2016
         *regB = -1;
2017
         *Sc = 0;
2018
     if (token!='[') {;
2019
          val = expr();
2020
          *disp = val;
2021
     }
2022
     if (token=='[') {
2023
         *regA = getRegisterX();
2024
         if (*regA == -1) {
2025
             printf("expecting a register\r\n");
2026
         }
2027
                 if (token=='+') {
2028
                         *regB = getRegisterX();
2029
                         if (*regB == -1) {
2030
                                 printf("expecting a register\r\n");
2031
                         }
2032
              if (token=='*') {
2033
                  GetIndexScale(Sc);
2034
              }
2035
                 }
2036
         need(']');
2037
     }
2038
}
2039
 
2040
static void mem_voperand(int64_t *disp, int *regA, int *regB)
2041
{
2042
     int64_t val;
2043
 
2044
     // chech params
2045
     if (disp == (int64_t *)NULL)
2046
         return;
2047
     if (regA == (int *)NULL)
2048
         return;
2049
 
2050
     *disp = 0;
2051
     *regA = -1;
2052
         *regB = -1;
2053
     if (token!='[') {;
2054
          val = expr();
2055
          *disp = val;
2056
     }
2057
     if (token=='[') {
2058
         *regA = getRegisterX();
2059
         if (*regA == -1) {
2060
             printf("expecting a register\r\n");
2061
         }
2062
                 if (token=='+') {
2063
                         *regB = getVecRegister();
2064
                         if (*regB == -1) {
2065
                                 printf("expecting a vector register: %d\r\n", lineno);
2066
                         }
2067
                 }
2068
         need(']');
2069
     }
2070
}
2071
 
2072
// ---------------------------------------------------------------------------
2073
// If the displacement is too large the instruction is converted to an
2074
// indexed form and the displacement loaded into a second register.
2075
//
2076
// So
2077
//      sw   r2,$12345678[r2]
2078
// Becomes:
2079
//              ori  r23,r0,#$5678
2080
//      orq1 r23,#$1234
2081
//      sw   r2,[r2+r23]
2082
//
2083
// sw disp[r1],r2
2084
// sw [r1+r2],r3
2085
// ----------------------------------------------------------------------------
2086
 
2087
static void process_store(int64_t opcode6)
2088
{
2089
    int Ra,Rb;
2090
    int Rs;
2091
        int Sc;
2092
    int64_t disp,val;
2093
 
2094
    Rs = getRegisterX();
2095
    if (Rs < 0) {
2096
        printf("Expecting a source register (%d).\r\n", lineno);
2097
        printf("Line:%.60s\r\n",inptr);
2098
        ScanToEOL();
2099
        return;
2100
    }
2101
    expect(',');
2102
    mem_operand(&disp, &Ra, &Rb, &Sc);
2103
        if (Ra > 0 && Rb > 0) {
2104
                emit_insn(
2105
                        (opcode6 << 30) |
2106
                        (Sc << 24) |
2107
                        (Rs << 18) |
2108
                        (Rb << 12) |
2109
                        (Ra << 6) |
2110
                        0x02,!expand_flag,4);
2111
                return;
2112
        }
2113
    if (Ra < 0) Ra = 0;
2114
    val = disp;
2115
        if (val < -131072 || val > 131071) {
2116
                GetConstantReg();
2117
                emit_insn(
2118
                        (val  << 18) |
2119
                        (regCnst << 12) |
2120
                        (0 << 6) |
2121
                        0x09,!expand_flag,4);
2122
                emit_insn(
2123
                        ((val >> 16) << 18) |
2124
                        (regCnst << 12) |
2125
                        (0 << 6) |
2126
                        (1 << 6) |
2127
                        0x1A,!expand_flag,4);   // ORQ1
2128
                // Change to indexed addressing
2129
                emit_insn(
2130
                        (opcode6 << 30) |
2131
                        (Rs << 18) |
2132
                        (regCnst << 12) |
2133
                        (Ra << 6) |
2134
                        0x02,!expand_flag,4);
2135
                ScanToEOL();
2136
                return;
2137
        }
2138
        emit_insn(
2139
                (val << 18) |
2140
                (Rs << 12) |
2141
                (Ra << 6) |
2142
                opcode6,!expand_flag,4);
2143
    ScanToEOL();
2144
}
2145
 
2146
static void process_sv(int opcode6)
2147
{
2148
    int Ra,Vb;
2149
    int Vs;
2150
    int64_t disp,val;
2151
 
2152
    Vs = getVecRegister();
2153
    if (Vs < 0 || Vs > 31) {
2154
        printf("Expecting a vector source register (%d).\r\n", lineno);
2155
        printf("Line:%.60s\r\n",inptr);
2156
        ScanToEOL();
2157
        return;
2158
    }
2159
    expect(',');
2160
    mem_voperand(&disp, &Ra, &Vb);
2161
        if (Ra > 0 && Vb > 0) {
2162
                emit_insn(
2163
                        (opcode6 << 26) |
2164
                        (Vs << 16) |
2165
                        (Vb << 11) |
2166
                        (Ra << 6) |
2167
                        0x02,!expand_flag,4);
2168
                return;
2169
        }
2170
    if (Ra < 0) Ra = 0;
2171
    val = disp;
2172
        //if (val < -32768 || val > 32767)
2173
        //      printf("SV displacement too large: %d\r\n", lineno);
2174
        emit_prefix(val);
2175
        emit_insn(
2176
                (val << 16) |
2177
                (Vs << 11) |
2178
                (Ra << 6) |
2179
                opcode6,!expand_flag,4);
2180
    ScanToEOL();
2181
}
2182
 
2183
// ----------------------------------------------------------------------------
2184
// ----------------------------------------------------------------------------
2185
 
2186
static void process_ldi()
2187
{
2188
    int Ra = 0;
2189
    int Rt;
2190
    int64_t val;
2191
    int opcode6 = 0x09;  // ORI
2192
        int sz = 3;
2193
        char *p;
2194
 
2195
    p = inptr;
2196
        if (*p=='.')
2197
                getSz(&sz);
2198
    Rt = getRegisterX();
2199
    expect(',');
2200
    val = expr();
2201
        if (val < -32768 || val > 32767) {
2202
                emit_insn(
2203
                        (val << 16) |
2204
                        (23 << 11) |
2205
                        (0 << 6) |
2206
                        0x09,!expand_flag,4);   // ORI
2207
                val >>= 16;
2208
                emit_insn(
2209
                        (val << 16) |
2210
                        (23 << 11) |
2211
                        (0 << 6) |
2212
                        (1 << 6) |
2213
                        0x1A,!expand_flag,4);   // ORQ1
2214
                val >>= 16;
2215
                if (val != 0) {
2216
                        emit_insn(
2217
                                (val << 16) |
2218
                                (23 << 11) |
2219
                                (0 << 6) |
2220
                                (2 << 6) |
2221
                                0x1A,!expand_flag,4);   // ORQ2
2222
                }
2223
                val >>= 16;
2224
                if (val != 0) {
2225
                        emit_insn(
2226
                                (val << 16) |
2227
                                (23 << 11) |
2228
                                (0 << 6) |
2229
                                (3 << 6) |
2230
                                0x1A,!expand_flag,4);   // ORQ3
2231
                }
2232
                emit_insn(
2233
                        (opcode6 << 26) |
2234
                        (sz << 21) |
2235
                        (Rt << 16) |
2236
                        (23 << 11) |
2237
                        (Ra << 6) |
2238
                        0x02,!expand_flag,4);
2239
                return;
2240
        }
2241
        emit_insn(
2242
                (val << 16) |
2243
                (Rt << 11) |
2244
                opcode6,!expand_flag,4
2245
        );
2246
}
2247
 
2248
// ----------------------------------------------------------------------------
2249
// link #-40
2250
// ----------------------------------------------------------------------------
2251
 
2252
static void process_link(int opcode6)
2253
{
2254
    int Ra = 31;
2255
    int Rb = 30;
2256
    char *p;
2257
    int64_t val;
2258
 
2259
    p = inptr;
2260
    Rb = getRegisterX();
2261
        if (Rb==-1)
2262
                Rb = 30;
2263
        else
2264
                expect(',');
2265
    NextToken();
2266
    val = expr();
2267
        emit_prefix(val);
2268
        emit_insn(((val & 0xFFFF) << 16)|(Rb << 11)|(Ra << 6)|opcode6,!expand_flag,4);
2269
}
2270
 
2271
// ----------------------------------------------------------------------------
2272
// lw r1,disp[r2]
2273
// lw r1,[r2+r3]
2274
// ----------------------------------------------------------------------------
2275
 
2276
static void process_load(int64_t opcode6)
2277
{
2278
    int Ra,Rb;
2279
    int Rt;
2280
        int Sc;
2281
    char *p;
2282
    int64_t disp;
2283
    int64_t val;
2284
    int fixup = 5;
2285
 
2286
    p = inptr;
2287
        if (opcode6==0x26LL)
2288
                Rt = getVecRegister();
2289
        else
2290
                Rt = getRegisterX();
2291
    if (Rt < 0) {
2292
        printf("Expecting a target register (%d).\r\n", lineno);
2293
        printf("Line:%.60s\r\n",p);
2294
        ScanToEOL();
2295
        inptr-=2;
2296
        return;
2297
    }
2298
    expect(',');
2299
    mem_operand(&disp, &Ra, &Rb, &Sc);
2300
        if (Ra > 0 && Rb > 0) {
2301
                // Trap LEA, convert to LEAX opcode
2302
                if (opcode6==0x04) // ADD is really LEA
2303
                        opcode6 = 0x18;
2304
                emit_insn(
2305
                        (opcode6 << 30) |
2306
                        (Sc << 24) |
2307
                        (Rt << 18) |
2308
                        (Rb << 12) |
2309
                        (Ra << 6) |
2310
                        0x02,!expand_flag,4);
2311
                return;
2312
        }
2313
    if (Ra < 0) Ra = 0;
2314
    val = disp;
2315
        if (val < -131072 || val > 131071) {
2316
                GetConstantReg();
2317
                emit_insn(
2318
                        (val  << 18) |
2319
                        (regCnst << 12) |
2320
                        (0 << 6) |
2321
                        0x09,!expand_flag,4);
2322
                emit_insn(
2323
                        ((val >> 16) << 18) |
2324
                        (regCnst << 12) |
2325
                        (0 << 6) |
2326
                        (1 << 6) |
2327
                        0x1A,!expand_flag,4);   // ORQ1
2328
                // Change to indexed addressing
2329
                emit_insn(
2330
                        (opcode6 << 30) |
2331
                        (Rt << 18) |
2332
                        (regCnst << 12) |
2333
                        (Ra << 6) |
2334
                        0x02,!expand_flag,4);
2335
                ScanToEOL();
2336
                return;
2337
        }
2338
        emit_insn(
2339
                (val << 18) |
2340
                (Rt << 12) |
2341
                (Ra << 6) |
2342
                opcode6,!expand_flag,4);
2343
    ScanToEOL();
2344
}
2345
 
2346
static void process_lv(int opcode6)
2347
{
2348
    int Ra,Vb;
2349
    int Vt;
2350
    char *p;
2351
    int64_t disp;
2352
    int64_t val;
2353
    int fixup = 5;
2354
 
2355
    p = inptr;
2356
        Vt = getVecRegister();
2357
    if (Vt < 0) {
2358
        printf("Expecting a vector target register (%d).\r\n", lineno);
2359
        printf("Line:%.60s\r\n",p);
2360
        ScanToEOL();
2361
        inptr-=2;
2362
        return;
2363
    }
2364
    expect(',');
2365
    mem_voperand(&disp, &Ra, &Vb);
2366
        if (Ra > 0 && Vb > 0) {
2367
                emit_insn(
2368
                        (opcode6 << 26) |
2369
                        (Vt << 16) |
2370
                        (Vb << 11) |
2371
                        (Ra << 6) |
2372
                        0x02,!expand_flag,4);
2373
                return;
2374
        }
2375
    if (Ra < 0) Ra = 0;
2376
    val = disp;
2377
        //if (val < -32768 || val > 32767)
2378
        //      printf("LV displacement too large: %d\r\n", lineno);
2379
        emit_prefix(val);
2380
        emit_insn(
2381
                (val << 16) |
2382
                (Vt << 11) |
2383
                (Ra << 6) |
2384
                opcode6,!expand_flag,4);
2385
    ScanToEOL();
2386
}
2387
 
2388
static void process_lsfloat(int opcode6)
2389
{
2390
    int Ra,Rb;
2391
    int Rt;
2392
        int Sc;
2393
    char *p;
2394
    int64_t disp;
2395
    int64_t val;
2396
    int fixup = 5;
2397
 
2398
    int  sz;
2399
    int rm;
2400
 
2401
    rm = 0;
2402
    sz = GetFPSize();
2403
    p = inptr;
2404
    Rt = getFPRegister();
2405
    if (Rt < 0) {
2406
        printf("Expecting a target register (1:%d).\r\n", lineno);
2407
        printf("Line:%.60s\r\n",p);
2408
        ScanToEOL();
2409
        inptr-=2;
2410
        return;
2411
    }
2412
    expect(',');
2413
    mem_operand(&disp, &Ra, &Rb, &Sc);
2414
        if (Ra > 0 && Rb > 0) {
2415
                emit_insn(
2416
                        (1L << 29) |
2417
                        (sz << 27) |
2418
                        (Rt << 18) |
2419
                        (Rb << 12) |
2420
                        (Ra << 6) |
2421
                        opcode6,!expand_flag,2);
2422
                return;
2423
        }
2424
    if (Ra < 0) Ra = 0;
2425
    val = disp;
2426
        if (val < -15LL || val > 15LL) {
2427
                emit_insn(
2428
                        (sz << 27) |
2429
                        (Rt << 18) |
2430
                        (0x10 << 11) |
2431
                        (Ra << 6) |
2432
                        opcode6,0,2);
2433
                emit_insn(val,0,2);
2434
        }
2435
        else {
2436
                emit_insn(
2437
                        (sz << 27) |
2438
                        (Rt << 18) |
2439
                        ((val & 0x1f) << 11) |
2440
                        (Ra << 6) |
2441
                        opcode6,!expand_flag,2);
2442
    }
2443
    ScanToEOL();
2444
}
2445
 
2446
static void process_ld()
2447
{
2448
        int Rt;
2449
        char *p;
2450
 
2451
        p = inptr;
2452
        Rt = getRegisterX();
2453
        expect(',');
2454
//      NextToken();
2455
        if (token == '#') {
2456
                inptr = p;
2457
                process_ldi();
2458
                return;
2459
        }
2460
        // Else: do a word load
2461
        inptr = p;
2462
        process_load(0x22);
2463
}
2464
 
2465
// ----------------------------------------------------------------------------
2466
// ----------------------------------------------------------------------------
2467
 
2468
static void process_ltcb(int oc)
2469
{
2470
        int Rn;
2471
 
2472
        Rn = getRegisterX();
2473
        emit_insn(
2474
                (oc << 11) |
2475
                (Rn << 6) |
2476
                0x19,0,1
2477
                );
2478
        prevToken();
2479
}
2480
 
2481
// ----------------------------------------------------------------------------
2482
// mov r1,r2 -> translated to or Rt,Ra,#0
2483
// ----------------------------------------------------------------------------
2484
 
2485
static void process_mov(int oc)
2486
{
2487
     int Ra;
2488
     int Rt;
2489
     char *p;
2490
         int vec = 0;
2491
 
2492
         p = inptr;
2493
     Rt = getRegisterX();
2494
         if (Rt==-1) {
2495
                 inptr = p;
2496
                 Rt = getVecRegister() & 15;
2497
                 vec = 1;
2498
         }
2499
     need(',');
2500
         p = inptr;
2501
     Ra = getRegisterX();
2502
         if (Ra==-1) {
2503
                 inptr = p;
2504
                 Ra = getVecRegister() & 15;
2505
                 vec = 2;
2506
         }
2507
         if (vec==1) {
2508
                 emit_insn(
2509
                         (0x33 << 26) |
2510
                         (0x00 << 21) |
2511
                         (Rt << 11) |
2512
                         (Ra << 6) |
2513
                         0x01,0,4
2514
                 );
2515
                 return;
2516
         }
2517
         else if (vec==2) {
2518
                 emit_insn(
2519
                         (0x33 << 26) |
2520
                         (0x01 << 21) |
2521
                         (Rt << 11) |
2522
                         (Ra << 6) |
2523
                         0x01,0,4
2524
                 );
2525
                 return;
2526
         }
2527
         emit_insn(
2528
                 (Rt << 11) |
2529
                 (Ra << 6) |
2530
                 oc,0,4
2531
                 );
2532
        prevToken();
2533
}
2534
 
2535
// ----------------------------------------------------------------------------
2536
// shr r1,r2,#5
2537
// ----------------------------------------------------------------------------
2538
 
2539
static void process_shifti(int64_t op4)
2540
{
2541
     int Ra;
2542
     int Rt;
2543
         int sz = 3;
2544
         int64_t func6 = 3;
2545
     int64_t val;
2546
         char *p = inptr;
2547
 
2548
         if (p[0]=='.')
2549
                 getSz(&sz);
2550
     Rt = getRegisterX();
2551
     need(',');
2552
     Ra = getRegisterX();
2553
     need(',');
2554
     NextToken();
2555
     val = expr();
2556
        switch(sz) {
2557
        case 0:  func6 = 0x1F;
2558
        case 1: func6 = 0x2F;
2559
        case 2: func6 = 0x3F;
2560
        default:        func6 = 0x0F;
2561
        }
2562
        emit_insn((func6 << 30) | (op4 << 26) | ((val & 0x3f) << 18) | (Rt << 12) | (Ra << 6) | 0x02,!expand_flag,4);
2563
}
2564
 
2565
// ----------------------------------------------------------------------------
2566
// SEI R1
2567
// SEI #5
2568
// ----------------------------------------------------------------------------
2569
 
2570
static void process_sei()
2571
{
2572
        int64_t val = 7;
2573
        int Ra = -1;
2574
    char *p;
2575
 
2576
        p = inptr;
2577
        NextToken();
2578
        if (token=='#')
2579
                val = expr();
2580
        else {
2581
                inptr = p;
2582
            Ra = getRegisterX();
2583
        }
2584
        if (Ra==-1) {
2585
                emit_insn(
2586
                        0xC0000002 |
2587
                        ((val & 7) << 11) |
2588
                        (0 << 6),
2589
                        0,4);
2590
        }
2591
        else {
2592
                emit_insn(
2593
                        0xC0000002 |
2594
                        (0 << 11) |
2595
                        (Ra << 6),
2596
                        0,4);
2597
        }
2598
}
2599
 
2600
// ----------------------------------------------------------------------------
2601
// shl r1,r2,r3
2602
// ----------------------------------------------------------------------------
2603
 
2604
static void process_shift(int64_t op4)
2605
{
2606
     int Ra, Rb;
2607
     int Rt;
2608
     char *p;
2609
         int sz = 3;
2610
         int64_t func6 = 3;
2611
 
2612
         p = inptr;
2613
         if (p[0]=='.')
2614
                 getSz(&sz);
2615
     Rt = getRegisterX();
2616
     need(',');
2617
     Ra = getRegisterX();
2618
     need(',');
2619
     NextToken();
2620
         if (token=='#') {
2621
                 inptr = p;
2622
                 process_shifti(op4 + 0x8);
2623
         }
2624
         else {
2625
                prevToken();
2626
                Rb = getRegisterX();
2627
                switch(sz) {
2628
                case 0:  func6 = 0x1FLL;
2629
                case 1: func6 = 0x2FLL;
2630
                case 2: func6 = 0x3FLL;
2631
                default:        func6 = 0x0FLL;
2632
                }
2633
                emit_insn((func6 << 30) | (op4 << 26) | (Rt << 18)| (Rb << 12) | (Ra << 6) | 0x02,!expand_flag,4);
2634
         }
2635
}
2636
 
2637
// ----------------------------------------------------------------------------
2638
// gran r1
2639
// ----------------------------------------------------------------------------
2640
 
2641
static void process_gran(int oc)
2642
{
2643
    int Rt;
2644
 
2645
    Rt = getRegisterX();
2646
//    emitAlignedCode(0x01);
2647
    emitCode(0x00);
2648
    emitCode(Rt);
2649
    emitCode(0x00);
2650
    emitCode(oc);
2651
    prevToken();
2652
}
2653
 
2654
 
2655
// ----------------------------------------------------------------------------
2656
// ----------------------------------------------------------------------------
2657
 
2658
static void process_mffp(int oc)
2659
{
2660
    int fpr;
2661
    int Rt;
2662
 
2663
    Rt = getRegisterX();
2664
    need(',');
2665
    fpr = getFPRegister();
2666
    //emitAlignedCode(0x01);
2667
    emitCode(fpr);
2668
    emitCode(Rt);
2669
    emitCode(0x00);
2670
    emitCode(oc);
2671
    if (fpr >= 0)
2672
    prevToken();
2673
}
2674
 
2675
// ----------------------------------------------------------------------------
2676
// ----------------------------------------------------------------------------
2677
 
2678
static void process_fprdstat(int oc)
2679
{
2680
    int Rt;
2681
 
2682
    Rt = getRegisterX();
2683
    //emitAlignedCode(0x01);
2684
    emitCode(0x00);
2685
    emitCode(Rt);
2686
    emitCode(0x00);
2687
    emitCode(oc);
2688
}
2689
 
2690
 
2691
// ----------------------------------------------------------------------------
2692
// Four cases, two with extendable immediate constants
2693
//
2694
// csrrw        r2,#21,r3
2695
// csrrw        r4,#34,#1234
2696
// csrrw        r5,r4,#1234
2697
// csrrw        r6,r4,r5
2698
// ----------------------------------------------------------------------------
2699
 
2700
static void process_csrrw(int op)
2701
{
2702
        int Rd;
2703
        int Rs;
2704
        int Rc;
2705
        int64_t val,val2;
2706
        char *p;
2707
 
2708
        Rd = getRegisterX();
2709
        need(',');
2710
        p = inptr;
2711
        NextToken();
2712
        if (token=='#') {
2713
                val = expr();
2714
                need(',');
2715
                NextToken();
2716
                if (token=='#') {
2717
                        printf("Illegal CSR instruction.\r\n");
2718
                        return;
2719
                        val2 = expr();
2720
                        if (val2 < -15LL || val2 > 15LL) {
2721
                                emit_insn((val << 18) | (op << 16) | (0x10 << 6) | (Rd << 11) | 0x0F,0,2);
2722
                                emit_insn(val2,0,2);
2723
                                return;
2724
                        }
2725
                        emit_insn((val << 18) | (op << 16) | ((val2 & 0x1f) << 6) | (Rd << 11) | 0x0F,!expand_flag,2);
2726
                        return;
2727
                }
2728
                prevToken();
2729
                Rs = getRegisterX();
2730
                emit_insn(((val & 0xfff) << 16) | (op << 30) | (Rs << 6) | (Rd << 11) | 0x0E,!expand_flag,4);
2731
                prevToken();
2732
                return;
2733
                }
2734
        printf("Illegal CSR instruction.\r\n");
2735
        return;
2736
        inptr = p;
2737
        Rc = getRegisterX();
2738
        need(',');
2739
        NextToken();
2740
        if (token=='#') {
2741
                val2 = expr();
2742
                if (val2 < -15LL || val2 > 15LL) {
2743
                        emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | (0x10 << 6) | (Rc << 11) | 0x0C,0,2);
2744
                        emit_insn(val2,0,2);
2745
                        return;
2746
                }
2747
                emit_insn((0x0F << 26) | (op << 21) | (Rd << 16) | ((val2 & 0x1f) << 6) | (Rc << 11) | 0x0C,!expand_flag,2);
2748
                return;
2749
        }
2750
        prevToken();
2751
        Rs = getRegisterX();
2752
        emit_insn((0x3F << 26) | (op << 21) | (Rd << 16) | (Rc << 11) | (Rs << 6) | 0x0C,!expand_flag,2);
2753
        prevToken();
2754
        return;
2755
}
2756
 
2757
// ---------------------------------------------------------------------------
2758
// com r3,r3
2759
// - alternate mnemonic for xor Rn,Rn,#-1
2760
// ---------------------------------------------------------------------------
2761
 
2762
static void process_com()
2763
{
2764
    int Ra;
2765
    int Rt;
2766
 
2767
    Rt = getRegisterX();
2768
    need(',');
2769
    Ra = getRegisterX();
2770
        emit_insn(
2771
                (0xFFFF << 16) |
2772
                (Rt << 11) |
2773
                (Ra << 6) |
2774
                0x0A,!expand_flag,4
2775
                );
2776
        prevToken();
2777
}
2778
 
2779
// ---------------------------------------------------------------------------
2780
// com r3,r3
2781
// - alternate mnemonic for xor Rn,Rn,#-1
2782
// ---------------------------------------------------------------------------
2783
 
2784
static void process_neg()
2785
{
2786
    int Ra;
2787
    int Rt;
2788
 
2789
    Rt = getRegisterX();
2790
    need(',');
2791
    Ra = getRegisterX();
2792
        emit_insn(
2793
                (0x05 << 26) |
2794
                (Rt << 16) |
2795
                (Ra << 11) |
2796
                (0 << 6) |
2797
                0x02,!expand_flag,4
2798
                );
2799
        prevToken();
2800
}
2801
 
2802
// ----------------------------------------------------------------------------
2803
// push r1
2804
// push #123
2805
// ----------------------------------------------------------------------------
2806
 
2807
static void process_push(int func, int amt)
2808
{
2809
    int Ra,Rb;
2810
        int FRa;
2811
        int sz;
2812
    int64_t val;
2813
 
2814
    Ra = -1;
2815
    Rb = -1;
2816
    sz = GetFPSize();
2817
    NextToken();
2818
    if (token=='#') {  // Filter to PUSH
2819
                //printf("Illegal push/pop instruction: %d.\r\n", lineno);
2820
                //return;
2821
       val = expr();
2822
            if (val > 32767 || val < -32768) {
2823
                        emit_insn(
2824
                                (val << 16) |
2825
                                (23 << 11) |
2826
                                (0 << 6) |
2827
                                0x09,!expand_flag,4);   // ORI
2828
                        val >>= 16;
2829
                        emit_insn(
2830
                                (val << 16) |
2831
                                (23 << 11) |
2832
                                (0 << 6) |
2833
                                (1 << 6) |
2834
                                0x1A,!expand_flag,4);   // ORQ1
2835
                        val >>= 16;
2836
                        if (val != 0) {
2837
                                emit_insn(
2838
                                        (val << 16) |
2839
                                        (23 << 11) |
2840
                                        (0 << 6) |
2841
                                        (2 << 6) |
2842
                                        0x1A,!expand_flag,4);   // ORQ2
2843
                        }
2844
                        val >>= 16;
2845
                        if (val != 0) {
2846
                                emit_insn(
2847
                                        (val << 16) |
2848
                                        (23 << 11) |
2849
                                        (0 << 6) |
2850
                                        (3 << 6) |
2851
                                        0x1A,!expand_flag,4);   // ORQ3
2852
                        }
2853
                        Ra = 23;
2854
                        goto j1;
2855
                }
2856
                else
2857
                        emit_insn(
2858
                                ((val & 0xFFFFLL) << 16) |
2859
                                (0x1F << 11) |
2860
                                (0x1F << 6) |
2861
                                0x1F,  // PUSHC
2862
                                0,4
2863
                        );
2864
        return;
2865
    }
2866
    prevToken();
2867
        FRa = getFPRegister();
2868
        if (FRa==-1) {
2869
                prevToken();
2870
                Ra = getRegisterX();
2871
        }
2872
        else {
2873
                emit_insn(
2874
                        (func << 14) |
2875
                        (sz << 12) |
2876
                        (FRa << 6) |
2877
                        0x19,0,1
2878
                        );
2879
                prevToken();
2880
                return;
2881
        }
2882
    if (Ra == -1) {
2883
                Ra = 0;
2884
        printf("%d: unknown register.\r\n", lineno);
2885
    }
2886
j1:
2887
    emit_insn(
2888
                (func << 26) |
2889
                ((amt & 31) << 21) |
2890
                (0x1F << 16) |
2891
                (Ra << 11) |
2892
                (0x1F << 6) |
2893
                0x02,0,4);
2894
    prevToken();
2895
}
2896
 
2897
static void process_sync(int oc)
2898
{
2899
//    emit_insn(oc,!expand_flag);
2900
}
2901
 
2902
 
2903
// ---------------------------------------------------------------------------
2904
// ---------------------------------------------------------------------------
2905
 
2906
static void process_vrrop(int funct6)
2907
{
2908
    int Va,Vb,Vt,Vm;
2909
    char *p;
2910
        int sz = 0x43;
2911
 
2912
    p = inptr;
2913
        if (*p=='.')
2914
                getSz(&sz);
2915
        if (sz==0x43)
2916
                sz = 0;
2917
        else if (sz==0x83)
2918
                sz = 1;
2919
    Vt = getVecRegister();
2920
    need(',');
2921
    Va = getVecRegister();
2922
    need(',');
2923
    Vb = getVecRegister();
2924
    need(',');
2925
    Vm = getVecRegister();
2926
        if (Vm < 0x20 || Vm > 0x23)
2927
                printf("Illegal vector mask register: %d\r\n", lineno);
2928
        Vm &= 0x3;
2929
    //prevToken();
2930
    emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Vb<<11)|(Va<<6)|0x01,!expand_flag,4);
2931
}
2932
 
2933
// ---------------------------------------------------------------------------
2934
// ---------------------------------------------------------------------------
2935
 
2936
static void process_vsrrop(int funct6)
2937
{
2938
    int Va,Rb,Vt,Vm;
2939
    char *p;
2940
        int sz = 0x43;
2941
 
2942
    p = inptr;
2943
        if (*p=='.')
2944
                getSz(&sz);
2945
        if (sz==0x43)
2946
                sz = 0;
2947
        else if (sz==0x83)
2948
                sz = 1;
2949
    Vt = getVecRegister();
2950
    need(',');
2951
    Va = getVecRegister();
2952
    need(',');
2953
    Rb = getRegisterX();
2954
    need(',');
2955
    Vm = getVecRegister();
2956
        if (Vm < 0x20 || Vm > 0x23)
2957
                printf("Illegal vector mask register: %d\r\n", lineno);
2958
        Vm &= 0x3;
2959
    //prevToken();
2960
    emit_insn((funct6<<26)|(Vm<<23)|(sz << 21)|(Vt<<16)|(Rb<<11)|(Va<<6)|0x01,!expand_flag,4);
2961
}
2962
 
2963
// ----------------------------------------------------------------------------
2964
// ----------------------------------------------------------------------------
2965
 
2966
static void ProcessEOL(int opt)
2967
{
2968
    int64_t nn,mm,wd;
2969
        float nf;
2970
    int first;
2971
    double cc;
2972
        int evn;
2973
 
2974
     //printf("Line: %d\r", lineno);
2975
     expand_flag = 0;
2976
     compress_flag = 0;
2977
     segprefix = -1;
2978
     if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
2979
    nn = binstart;
2980
    cc = 2;
2981
    if (segment==codeseg) {
2982
       cc = 4.5;
2983
/*
2984
        if (sections[segment].bytes[binstart]==0x61) {
2985
            fprintf(ofp, "%06LLX ", (int)ca);
2986
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
2987
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
2988
            }
2989
            fprintf(ofp, "   ; imm\n");
2990
             if (((ca+5) & 15)==15) {
2991
                 ca+=6;
2992
                 binstart+=6;
2993
                 nn++;
2994
             }
2995
             else {
2996
                  ca += 5;
2997
                  binstart += 5;
2998
             }
2999
        }
3000
*/
3001
/*
3002
        if (sections[segment].bytes[binstart]==0xfd) {
3003
            fprintf(ofp, "%06LLX ", ca);
3004
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
3005
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
3006
            }
3007
            fprintf(ofp, "   ; imm\n");
3008
             if (((ca+5) & 15)==15) {
3009
                 ca+=6;
3010
                 binstart+=6;
3011
                 nn++;
3012
             }
3013
             else {
3014
                  ca += 5;
3015
                  binstart += 5;
3016
             }
3017
        }
3018
         if (sections[segment].bytes[binstart]==0xfe) {
3019
            fprintf(ofp, "%06LLX ", ca);
3020
            for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
3021
                fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
3022
            }
3023
            fprintf(ofp, "   ; imm\n");
3024
             if (((ca+5) & 15)==15) {
3025
                 ca+=6;
3026
                 nn++;
3027
             }
3028
             else {
3029
                  ca += 5;
3030
             }
3031
        }
3032
*/
3033
    }
3034
 
3035
    first = 1;
3036
        nf = nn;
3037
    while (nn < sections[segment].index) {
3038
        fprintf(ofp, "%06LLX ", (int)ca & 0xFFFFFC);
3039
                evn = 0;
3040
        for (mm = nf; nf < mm + cc && nf < sections[segment].index; nf+=4.5) {
3041
                        nn = (int)nf;
3042
                        switch((int)ca & 31) {
3043
                        case 0:
3044
                        case 9:
3045
                        case 18:
3046
                        case 27:
3047
                                wd = ((int64_t)sections[segment].bytes[nn]) |
3048
                                        ((int64_t)sections[segment].bytes[nn+1] << 8) |
3049
                                        ((int64_t)sections[segment].bytes[nn+2] << 16) |
3050
                                        ((int64_t)sections[segment].bytes[nn+3] << 24) |
3051
                                        (((int64_t)sections[segment].bytes[nn+4] & 15) << 32);
3052
                                fprintf(ofp, "%09I64X ", wd);
3053
                                break;
3054
                        case 4:
3055
                        case 13:
3056
                        case 22:
3057
                        case 31:
3058
                                wd = ((int64_t)sections[segment].bytes[nn] >> 4) |
3059
                                        ((int64_t)sections[segment].bytes[nn+1] << 4) |
3060
                                        ((int64_t)sections[segment].bytes[nn+2] << 12) |
3061
                                        ((int64_t)sections[segment].bytes[nn+3] << 20) |
3062
                                        ((int64_t)sections[segment].bytes[nn+4] << 28);
3063
                                fprintf(ofp, "%09I64X ", wd);
3064
                                break;
3065
                        case 5: case 14:
3066
                                wd = ((int64_t)sections[segment].bytes[nn]) |
3067
                                        ((int64_t)sections[segment].bytes[nn+1] << 8) |
3068
                                        ((int64_t)sections[segment].bytes[nn+2] << 16) |
3069
                                        ((int64_t)sections[segment].bytes[nn+3] << 24) |
3070
                                        (((int64_t)sections[segment].bytes[nn+4] & 15) << 32);
3071
                                fprintf(ofp, "*** %09I64X ", wd);
3072
                                break;
3073
                        }
3074
            //fprintf(ofp, "%02X%02X%02X%02X ", sections[segment].bytes[nn+3], sections[segment].bytes[nn+2], sections[segment].bytes[nn+1], sections[segment].bytes[nn]);
3075
        }
3076
        for (; nn < mm + cc; nn++)
3077
            fprintf(ofp, "   ");
3078
        if (first & opt) {
3079
            fprintf(ofp, "\t%.*s\n", inptr-stptr-1, stptr);
3080
            first = 0;
3081
        }
3082
        else
3083
            fprintf(ofp, opt ? "\n" : "; NOP Ramp\n");
3084
        ca += cc;
3085
    }
3086
    // empty (codeless) line
3087
    if (binstart==sections[segment].index) {
3088
        fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
3089
    }
3090
    } // bGen
3091
    if (opt) {
3092
       stptr = inptr;
3093
       lineno++;
3094
    }
3095
    binstart = sections[segment].index;
3096
    ca = sections[segment].address;
3097
}
3098
 
3099
// ----------------------------------------------------------------------------
3100
// ----------------------------------------------------------------------------
3101
 
3102
void FT64x36_processMaster()
3103
{
3104
    int nn;
3105
    int64_t bs1, bs2;
3106
 
3107
    lineno = 1;
3108
    binndx = 0;
3109
    binstart = 0;
3110
    bs1 = 0;
3111
    bs2 = 0;
3112
    inptr = &masterFile[0];
3113
    stptr = inptr;
3114
    code_address = 0;
3115
    bss_address = 0;
3116
    start_address = 0;
3117
    first_org = 1;
3118
    first_rodata = 1;
3119
    first_data = 1;
3120
    first_bss = 1;
3121
        expandedBlock = 1;
3122
    if (pass<3) {
3123
    htblmax = 0;
3124
    for (nn = 0; nn < 100000; nn++) {
3125
      hTable[nn].count = 0;
3126
      hTable[nn].opcode = 0;
3127
    }
3128
    }
3129
    for (nn = 0; nn < 12; nn++) {
3130
        sections[nn].index = 0;
3131
        if (nn == 0)
3132
        sections[nn].address = 0;
3133
        else
3134
        sections[nn].address = 0;
3135
        sections[nn].start = 0;
3136
        sections[nn].end = 0;
3137
    }
3138
    ca = code_address;
3139
    segment = codeseg;
3140
    memset(current_label,0,sizeof(current_label));
3141
    NextToken();
3142
    while (token != tk_eof) {
3143
//        printf("\t%.*s\n", inptr-stptr-1, stptr);
3144
//        printf("token=%d\r", token);
3145
          if (expandedBlock)
3146
             expand_flag = 1;
3147
        switch(token) {
3148
        case tk_eol: ProcessEOL(1); break;
3149
//        case tk_add:  process_add(); break;
3150
//              case tk_abs:  process_rop(0x04); break;
3151
        case tk_add:  process_rrop(0x04); break;
3152
        case tk_addi: process_riop(0x04); break;
3153
        case tk_align: process_align(); continue; break;
3154
        case tk_and:  process_rrop(0x08); break;
3155
        case tk_andi:  process_riop(0x08); break;
3156
        case tk_asl: process_shift(0x2); break;
3157
        case tk_asr: process_shift(0x3); break;
3158
        case tk_bbc: process_beqi(0x26,1); break;
3159
        case tk_bbs: process_beqi(0x26,0); break;
3160
        case tk_begin_expand: expandedBlock = 1; break;
3161
        case tk_beq: process_bcc(0x30,0); break;
3162
        case tk_beqi: process_beqi(0x32,0); break;
3163
                case tk_bfchg: process_bitfield(2); break;
3164
                case tk_bfclr: process_bitfield(1); break;
3165
        case tk_bfext: process_bitfield(5); break;
3166
        case tk_bfextu: process_bitfield(6); break;
3167
                case tk_bfset: process_bitfield(0); break;
3168
        case tk_bge: process_bcc(0x30,3); break;
3169
        case tk_bgeu: process_bcc(0x30,5); break;
3170
        case tk_bgt: process_bcc(0x30,-2); break;
3171
        case tk_bgtu: process_bcc(0x30,-4); break;
3172
        case tk_ble: process_bcc(0x30,-3); break;
3173
        case tk_bleu: process_bcc(0x30,-5); break;
3174
        case tk_blt: process_bcc(0x30,2); break;
3175
        case tk_bltu: process_bcc(0x30,4); break;
3176
        case tk_bne: process_bcc(0x30,1); break;
3177
        case tk_bra: process_bra(0x01); break;
3178
                case tk_brk: process_brk(); break;
3179
        //case tk_bsr: process_bra(0x56); break;
3180
        case tk_bss:
3181
            if (first_bss) {
3182
                while(sections[segment].address & 4095)
3183
                    emitByte(0x00);
3184
                sections[3].address = sections[segment].address;
3185
                first_bss = 0;
3186
                binstart = sections[3].index;
3187
                ca = sections[3].address;
3188
            }
3189
            segment = bssseg;
3190
            break;
3191
                case tk_call:  process_call(0x19); break;
3192
        case tk_cli: emit_insn(0xC0000002,0,4); break;
3193
                case tk_chk:  process_chk(0x34); break;
3194
                case tk_cmp:  process_rrop(0x06); break;
3195
                case tk_cmpi:  process_riop(0x06); break;
3196
                case tk_cmpu:  process_rrop(0x07); break;
3197
                case tk_cmpui:  process_riop(0x07); break;
3198
        case tk_code: process_code(); break;
3199
        case tk_com: process_com(); break;
3200
        case tk_csrrc: process_csrrw(0x3); break;
3201
        case tk_csrrs: process_csrrw(0x2); break;
3202
        case tk_csrrw: process_csrrw(0x1); break;
3203
        case tk_csrrd: process_csrrw(0x0); break;
3204
        case tk_data:
3205
            if (first_data) {
3206
                while(sections[segment].address & 4095)
3207
                    emitByte(0x00);
3208
                sections[2].address = sections[segment].address;   // set starting address
3209
                first_data = 0;
3210
                binstart = sections[2].index;
3211
                ca = sections[2].address;
3212
            }
3213
            process_data(dataseg);
3214
            break;
3215
        case tk_db:  process_db(); break;
3216
        case tk_dc:  process_dc(); break;
3217
        case tk_dh:  process_dh(); break;
3218
        case tk_dh_htbl:  process_dh_htbl(); break;
3219
        case tk_dw:  process_dw(); break;
3220
        case tk_end: goto j1;
3221
        case tk_end_expand: expandedBlock = 0; break;
3222
        case tk_endpublic: break;
3223
        case tk_eor: process_rrop(0x0A); break;
3224
        case tk_eori: process_riop(0x0A); break;
3225
        case tk_extern: process_extern(); break;
3226
        case tk_fill: process_fill(); break;
3227
                case tk_hint:   process_hint(); break;
3228
                case tk_if:             pif1 = inptr-2; doif(); break;
3229
                case tk_iret:   process_iret(0xC8000002); break;
3230
        case tk_jal: process_jal(0x18); break;
3231
                case tk_jmp: process_call(0x28); break;
3232
        case tk_lb:  process_load(0x13); break;
3233
        case tk_lbu:  process_load(0x23); break;
3234
        case tk_lc:  process_load(0x20); break;
3235
        case tk_lcu:  process_load(0x21); break;
3236
                case tk_ld:     process_ld(); break;
3237
        case tk_ldi: process_ldi(); break;
3238
        case tk_lea: process_load(0x04); break;
3239
        case tk_lh:  process_load(0x10); break;
3240
        case tk_lhu: process_load(0x11); break;
3241
                case tk_link:   process_link(0x2A); break;
3242
        case tk_lv:  process_lv(0x36); break;
3243
        case tk_lw:  process_load(0x12); break;
3244
                case tk_memdb: emit_insn(0xD0000002,0,4); break;
3245
                case tk_memsb: emit_insn(0xD4000002,0,4); break;
3246
                case tk_message: process_message(); break;
3247
                case tk_mod: process_riop(0x2E); break;
3248
                case tk_modu: process_riop(0x2C); break;
3249
        case tk_mov: process_mov(0x09); break;
3250
        case tk_neg: process_neg(); break;
3251
        case tk_nop: emit_insn(0x1C,0,4); break;
3252
                case tk_not: process_rop(0x05); break;
3253
//        case tk_not: process_rop(0x07); break;
3254
        case tk_or:  process_rrop(0x09); break;
3255
        case tk_ori: process_riop(0x09); break;
3256
        case tk_org: process_org(); break;
3257
        case tk_plus: expand_flag = 1; break;
3258
                case tk_pop:    process_push(0x1A,8); break;
3259
        case tk_public: process_public(); break;
3260
                case tk_push:   process_push(0x19,-8); break;
3261
        case tk_rodata:
3262
            if (first_rodata) {
3263
                while(sections[segment].address & 4095)
3264
                    emitByte(0x00);
3265
                sections[1].address = sections[segment].address;
3266
                first_rodata = 0;
3267
                binstart = sections[1].index;
3268
                ca = sections[1].address;
3269
            }
3270
            segment = rodataseg;
3271
            break;
3272
                case tk_ret: process_ret(); break;
3273
                case tk_rol: process_shift(0x4); break;
3274
                case tk_roli: process_shift(0xC); break;
3275
                case tk_ror: process_shift(0x5); break;
3276
                case tk_rori: process_shift(0xD); break;
3277
                case tk_rti: process_iret(0xC8000002); break;
3278
        case tk_sb:  process_store(0x15); break;
3279
        case tk_sc:  process_store(0x24); break;
3280
        case tk_sei: process_sei(); break;
3281
                case tk_seq:    process_setiop(0x1B,2); break;
3282
                case tk_sge:    process_setiop(0x1B,5); break;
3283
                case tk_sgeu:   process_setiop(0x1B,13); break;
3284
                case tk_sgt:    process_setiop(0x1B,7); break;
3285
                case tk_sgtu:   process_setiop(0x1B,15); break;
3286
        //case tk_slt:  process_rrop(0x33,0x02,0x00); break;
3287
        //case tk_sltu:  process_rrop(0x33,0x03,0x00); break;
3288
        //case tk_slti:  process_riop(0x13,0x02); break;
3289
        //case tk_sltui:  process_riop(0x13,0x03); break;
3290
        case tk_sh:  process_store(0x14); break;
3291
        case tk_shl: process_shift(0x0); break;
3292
        case tk_shli: process_shifti(0x8); break;
3293
                case tk_shr: process_shift(0x1); break;
3294
        case tk_shri: process_shifti(0x9); break;
3295
                case tk_shru: process_shift(0x1); break;
3296
                case tk_shrui: process_shifti(0x9); break;
3297
                case tk_sle:    process_setiop(0x1B,6); break;
3298
                case tk_sleu:   process_setiop(0x1B,14); break;
3299
                case tk_slt:    process_setiop(0x1B,4); break;
3300
                case tk_sltu:   process_setiop(0x1B,12); break;
3301
                case tk_sne:    process_setiop(0x1B,3); break;
3302
        case tk_slli: process_shifti(0x8); break;
3303
        case tk_srai: process_shifti(0xB); break;
3304
        case tk_srli: process_shifti(0x9); break;
3305
        case tk_sub:  process_rrop(0x05); break;
3306
        case tk_subi:  process_riop(0x05); break;
3307
        case tk_sv:  process_sv(0x37); break;
3308
        case tk_sw:  process_store(0x16); break;
3309
        case tk_swap: process_rop(0x03); break;
3310
        case tk_sync: emit_insn(0x88000002,0,4); break;
3311
                case tk_unlink: emit_insn((0x1B << 26) | (0x1F << 16) | (30 << 11) | (0x1F << 6) | 0x02,0,4); break;
3312
                case tk_vadd: process_vrrop(0x04); break;
3313
                case tk_vadds: process_vsrrop(0x14); break;
3314
                case tk_vand: process_vrrop(0x08); break;
3315
                case tk_vands: process_vsrrop(0x18); break;
3316
                case tk_vdiv: process_vrrop(0x3E); break;
3317
                case tk_vdivs: process_vsrrop(0x2E); break;
3318
                case tk_vmul: process_vrrop(0x3A); break;
3319
                case tk_vmuls: process_vsrrop(0x2A); break;
3320
                case tk_vor: process_vrrop(0x09); break;
3321
                case tk_vors: process_vsrrop(0x19); break;
3322
                case tk_vsub: process_vrrop(0x05); break;
3323
                case tk_vsubs: process_vsrrop(0x15); break;
3324
                case tk_vxor: process_vrrop(0x0A); break;
3325
                case tk_vxors: process_vsrrop(0x1A); break;
3326
        case tk_xor: process_rrop(0x0A); break;
3327
        case tk_xori: process_riop(0x0A); break;
3328
        case tk_id:  process_label(); break;
3329
        case '-': compress_flag = 1; break;
3330
        }
3331
        NextToken();
3332
    }
3333
j1:
3334
    ;
3335
}
3336
 

powered by: WebSVN 2.1.0

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