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

Subversion Repositories thor

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

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

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2014  Robert Finch, Stratford
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// A64 - 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 emitAlignedCode(int cd);
29
static void process_shifti(int oc);
30
 
31
int first_rodata;
32
int first_data;
33
int first_bss;
34
 
35
// ---------------------------------------------------------------------------
36
// ---------------------------------------------------------------------------
37
 
38
static void emit_insn(int64_t oc)
39
{
40
     emitAlignedCode(oc & 255);
41
     emitCode((oc >> 8) & 255);
42
     emitCode((oc >> 16) & 255);
43
     emitCode((oc >> 24) & 255);
44
     emitCode((oc >> 32) & 255);
45
}
46
 
47
 
48
// ---------------------------------------------------------------------------
49
// Emit code aligned to a code address.
50
// ---------------------------------------------------------------------------
51
 
52
static void emitAlignedCode(int cd)
53
{
54
     int64_t ad;
55
 
56
     ad = code_address & 15;
57
     while (ad != 0 && ad != 5 && ad != 10) {
58
         emitByte(0x00);
59
         ad = code_address & 15;
60
     }
61
     ad = code_address & 0xfff;
62
     if ((ad > 0xFF0 && cd == 0xFD) || (ad > 0xFEA && cd == 0x61)) {
63
         emit_insn(0xEAEAEAEAEA);
64
         emit_insn(0xEAEAEAEAEA);
65
         if (cd==0x61)
66
             emit_insn(0xEAEAEAEAEA);
67
         ad = code_address & 0xfff;
68
         while (ad != 0 && ad != 5 && ad != 10) {
69
             emitByte(0x00);
70
             ad = code_address & 15;
71
         }
72
     }
73
     emitByte(cd);
74
}
75
 
76
// ----------------------------------------------------------------------------
77
// Bump up the address to the next aligned code address.
78
// ----------------------------------------------------------------------------
79
 
80
void Table888_bump_address()
81
{
82
//     if ((*address & 15)==15)
83
//         *address = *address + 1;
84
     if (segment==codeseg) {
85
         while ((sections[segment].address & 15) != 0 &&
86
                (sections[segment].address & 15) != 5 &&
87
                (sections[segment].address & 15) != 10) {
88
               emitByte(0x00);
89
         }
90
     }
91
}
92
 
93
 
94
// ---------------------------------------------------------------------------
95
// Emit constant extension for memory operands.
96
// ---------------------------------------------------------------------------
97
 
98
static void emitImm4(int64_t v, int force)
99
{
100
     if (v < -8L || v > 7L || force) {
101
          emitAlignedCode(0xfd);
102
          emitCode((v >> 4) & 255);
103
          emitCode((v >> 12) & 255);
104
          emitCode((v >> 20) & 255);
105
          emitCode((v >> 28) & 255);
106
     }
107
     if (((v < 0) && ((v >> 36) != -1L)) || ((v > 0) && ((v >> 36) != 0L)) || (force && data_bits > 36)) {
108
          emitAlignedCode(0xfe);
109
          emitCode((v >> 36) & 255);
110
          emitCode((v >> 44) & 255);
111
          emitCode((v >> 52) & 255);
112
          emitCode((v >> 60) & 255);
113
     }
114
}
115
 
116
// ---------------------------------------------------------------------------
117
// Emit constant extension for memory operands.
118
// ---------------------------------------------------------------------------
119
 
120
static void emitImm8(int64_t v, int force)
121
{
122
     if (v < -128L || v > 127L || force) {
123
          emitAlignedCode(0xfd);
124
          emitCode((v >> 8) & 255);
125
          emitCode((v >> 16) & 255);
126
          emitCode((v >> 24) & 255);
127
          emitCode((v >> 32) & 255);
128
     }
129
     if (((v < 0) && ((v >> 40) != -1L)) || ((v > 0) && ((v >> 40) != 0L)) || (force && data_bits > 40)) {
130
          emitAlignedCode(0xfe);
131
          emitCode((v >> 40) & 255);
132
          emitCode((v >> 48) & 255);
133
          emitCode((v >> 56) & 255);
134
          emitCode(0x00);
135
     }
136
}
137
 
138
// ---------------------------------------------------------------------------
139
// Emit constant extension for memory operands.
140
// ---------------------------------------------------------------------------
141
 
142
static void emitImm14(int64_t v, int force)
143
{
144
     if (v < -8192L || v > 8191L || force) {
145
          emitAlignedCode(0xfd);
146
          emitCode((v >> 14) & 255);
147
          emitCode((v >> 22) & 255);
148
          emitCode((v >> 30) & 255);
149
          emitCode((v >> 38) & 255);
150
     }
151
     if (((v < 0) && ((v >> 46) != -1L)) || ((v > 0) && ((v >> 46) != 0L)) || (force && data_bits > 46)) {
152
          emitAlignedCode(0xfe);
153
          emitCode((v >> 46) & 255);
154
          emitCode((v >> 54) & 255);
155
          emitCode((v >> 62) & 255);
156
          emitCode(0x00);
157
     }
158
}
159
 
160
// ---------------------------------------------------------------------------
161
// Emit constant extension for 16-bit operands.
162
// ---------------------------------------------------------------------------
163
 
164
static void emitImm16(int64_t v, int force)
165
{
166
     if (v < -32768L || v > 32767L || force) {
167
          emitAlignedCode(0xfd);
168
          emitCode((v >> 16) & 255);
169
          emitCode((v >> 24) & 255);
170
          emitCode((v >> 32) & 255);
171
          emitCode((v >> 40) & 255);
172
     }
173
     if (((v < 0) && ((v >> 48) != -1L)) || ((v > 0) && ((v >> 48) != 0L)) || (force && (code_bits > 48 || data_bits > 48))) {
174
          emitAlignedCode(0xfe);
175
          emitCode((v >> 48) & 255);
176
          emitCode((v >> 56) & 255);
177
          emitCode(0x00);
178
          emitCode(0x00);
179
     }
180
}
181
 
182
// ---------------------------------------------------------------------------
183
// Emit constant extension for 24-bit operands.
184
// ---------------------------------------------------------------------------
185
 
186
static void emitImm24(int64_t v, int force)
187
{
188
     if (v < -8388608L || v > 8388607L || force) {
189
          emitAlignedCode(0xfd);
190
          emitCode((v >> 24) & 255);
191
          emitCode((v >> 32) & 255);
192
          emitCode((v >> 40) & 255);
193
          emitCode((v >> 48) & 255);
194
     }
195
     if (((v < 0) && ((v >> 56) != -1L)) || ((v > 0) && ((v >> 56) != 0L)) || (force && (code_bits > 56 || data_bits > 56))) {
196
          emitAlignedCode(0xfe);
197
          emitCode((v >> 56) & 255);
198
          emitCode(0x00);
199
          emitCode(0x00);
200
          emitCode(0x00);
201
     }
202
}
203
 
204
// ---------------------------------------------------------------------------
205
// Emit constant extension for 32-bit operands.
206
// ---------------------------------------------------------------------------
207
 
208
static void emitImm32(int64_t v, int force)
209
{
210
     if (v < -2147483648LL || v > 2147483647LL || force) {
211
          emitAlignedCode(0xfd);
212
          emitCode((v >> 32) & 255);
213
          emitCode((v >> 40) & 255);
214
          emitCode((v >> 48) & 255);
215
          emitCode((v >> 56) & 255);
216
     }
217
}
218
 
219
// ---------------------------------------------------------------------------
220
// jmp main
221
// jsr [r19]
222
// jmp (tbl,r2)
223
// ---------------------------------------------------------------------------
224
 
225
static void process_jmp(int oc)
226
{
227
    int64_t addr;
228
    int Ra;
229
 
230
    NextToken();
231
    // Memory indirect ?
232
    if (token=='(' || token=='[') {
233
       Ra = getRegister();
234
       if (Ra==-1) {
235
           Ra = 0;
236
           NextToken();
237
           addr = expr();
238
           prevToken();
239
           if (token==',') {
240
               Ra = getRegister();
241
               if (Ra==-1) Ra = 0;
242
           }
243
           if (token!=')' && token != ']')
244
               printf("Missing close bracket.\r\n");
245
           emitImm24(addr,lastsym!=(SYM*)NULL);
246
           emitAlignedCode(oc+2);
247
            if (bGen)
248
                if (lastsym) {
249
                    if( lastsym->segment < 5)
250
                        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 2 | (lastsym->isExtern ? 128 : 0) | (code_bits << 8));
251
                }
252
           emitCode(Ra);
253
           emitCode(addr & 255);
254
           emitCode((addr >> 8) & 255);
255
           emitCode((addr >> 16) & 255);
256
           return;
257
       }
258
       // Simple [Rn]
259
       else {
260
            if (token != ')' && token!=']')
261
                printf("Missing close bracket\r\n");
262
            emitAlignedCode(oc + 4);
263
            emitCode(Ra);
264
            emitCode(0x00);
265
            emitCode(0x00);
266
            emitCode(0x00);
267
            return;
268
       }
269
    }
270
    addr = expr();
271
    prevToken();
272
    // d(Rn)? 
273
    if (token=='(' || token=='[') {
274
        Ra = getRegister();
275
        if (Ra==-1) {
276
            printf("Illegal jump address mode.\r\n");
277
            Ra = 0;
278
        }
279
        emitImm24(addr,0);
280
        emitAlignedCode(oc+4);
281
        emitCode(Ra);
282
        emitCode(addr & 255);
283
        emitCode((addr >> 8) & 255);
284
        emitCode((addr >> 16) & 255);
285
        return;
286
    }
287
 
288
    emitImm32(addr, code_bits > 32);
289
    emitAlignedCode(oc);
290
    if (bGen)
291
       if (lastsym) {
292
            if( lastsym->segment < 5)
293
                sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 1 | (lastsym->isExtern ? 128 : 0) | (code_bits << 8));
294
        }
295
    emitCode(addr & 255);
296
    emitCode((addr >> 8) & 255);
297
    emitCode((addr >> 16) & 255);
298
    emitCode((addr >> 24) & 255);
299
}
300
 
301
// ---------------------------------------------------------------------------
302
// subui r1,r2,#1234
303
// ---------------------------------------------------------------------------
304
 
305
static void process_riop(int oc)
306
{
307
    int Ra;
308
    int Rt;
309
    char *p;
310
    int64_t val;
311
 
312
    p = inptr;
313
    Rt = getRegister();
314
    need(',');
315
    Ra = getRegister();
316
    need(',');
317
    NextToken();
318
    val = expr();
319
    emitImm16(val,lastsym!=(SYM*)NULL);
320
    emitAlignedCode(oc);
321
    if (bGen)
322
    if (lastsym) {
323
        if( lastsym->segment < 5)
324
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 3 | (lastsym->isExtern ? 128 : 0) |
325
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
326
    }
327
    emitCode(Ra);
328
    emitCode(Rt);
329
    emitCode(val & 255);
330
    emitCode((val >> 8) & 255);
331
}
332
 
333
// ---------------------------------------------------------------------------
334
// addu r1,r2,r12
335
// ---------------------------------------------------------------------------
336
 
337
static void process_rrop(int oc)
338
{
339
    int Ra;
340
    int Rb;
341
    int Rt;
342
    char *p;
343
 
344
    p = inptr;
345
    Rt = getRegister();
346
    need(',');
347
    Ra = getRegister();
348
    need(',');
349
    NextToken();
350
    if (token=='#') {
351
        inptr = p;
352
        switch(oc) {
353
        case 0x04: process_riop(0x04); return;  // add
354
        case 0x14: process_riop(0x14); return;  // addu
355
        case 0x05: process_riop(0x05); return;  // sub
356
        case 0x15: process_riop(0x15); return;  // subu
357
        case 0x06: process_riop(0x06); return;  // cmp
358
        case 0x07: process_riop(0x07); return;  // mul
359
        case 0x08: process_riop(0x08); return;  // div
360
        case 0x09: process_riop(0x09); return;  // mod
361
        case 0x17: process_riop(0x17); return;  // mulu
362
        case 0x18: process_riop(0x18); return;  // divu
363
        case 0x19: process_riop(0x19); return;  // modu
364
        case 0x20: process_riop(0x0C); return;  // and
365
        case 0x21: process_riop(0x0D); return;  // or
366
        case 0x22: process_riop(0x0E); return;  // eor
367
        // Sxx
368
        case 0x60: process_riop(0x30); return;
369
        case 0x61: process_riop(0x31); return;
370
        case 0x68: process_riop(0x38); return;
371
        case 0x69: process_riop(0x39); return;
372
        case 0x6A: process_riop(0x3A); return;
373
        case 0x6B: process_riop(0x3B); return;
374
        case 0x6C: process_riop(0x3C); return;
375
        case 0x6D: process_riop(0x3D); return;
376
        case 0x6E: process_riop(0x3E); return;
377
        case 0x6F: process_riop(0x3F); return;
378
        // Shift
379
        case 0x40: process_shifti(0x50); return;
380
        case 0x41: process_shifti(0x51); return;
381
        case 0x42: process_shifti(0x52); return;
382
        case 0x43: process_shifti(0x53); return;
383
        case 0x44: process_shifti(0x54); return;
384
        }
385
        return;
386
    }
387
    prevToken();
388
    Rb = getRegister();
389
    prevToken();
390
    emitAlignedCode(2);
391
    emitCode(Ra);
392
    emitCode(Rb);
393
    emitCode(Rt);
394
    emitCode(oc);
395
}
396
 
397
// ---------------------------------------------------------------------------
398
// not r3,r3
399
// ---------------------------------------------------------------------------
400
 
401
static void process_rop(int oc)
402
{
403
    int Ra;
404
    int Rt;
405
 
406
    Rt = getRegister();
407
    need(',');
408
    Ra = getRegister();
409
    prevToken();
410
    emitAlignedCode(1);
411
    emitCode(Ra);
412
    emitCode(Rt);
413
    emitCode(0x00);
414
    emitCode(oc);
415
}
416
 
417
// ---------------------------------------------------------------------------
418
// brnz r1,label
419
// ---------------------------------------------------------------------------
420
 
421
static void process_bcc(int oc)
422
{
423
    int Ra;
424
    int64_t val;
425
    int64_t disp;
426
    int64_t ad;
427
 
428
    Ra = getRegister();
429
    need(',');
430
    NextToken();
431
    val = expr();
432
    ad = code_address + 5;
433
    if ((ad & 15)==15)
434
       ad++;
435
    disp = (val & 0xFFFFFFFFFFFF0000L) - (ad & 0xFFFFFFFFFFFF0000L);
436
    emitAlignedCode(oc);
437
    emitCode(Ra);
438
    emitCode(val & 255);
439
    emitCode((val >> 8) & 255);
440
    emitCode((disp >> 16) & 31);
441
}
442
 
443
// ---------------------------------------------------------------------------
444
// bra label
445
// ---------------------------------------------------------------------------
446
 
447
static void process_bra(int oc)
448
{
449
    int64_t val;
450
    int64_t disp;
451
    int64_t ad;
452
 
453
    NextToken();
454
    val = expr();
455
    ad = code_address + 5;
456
    if ((ad & 15)==15)
457
       ad++;
458
    disp = (val & 0xFFFFFFFFFFFF0000L) - (ad & 0xFFFFFFFFFFFF0000L);
459
    emitAlignedCode(oc);
460
    emitCode(0x00);
461
    emitCode(val & 255);
462
    emitCode((val >> 8) & 255);
463
    emitCode((disp >> 16) & 31);
464
}
465
 
466
// ---------------------------------------------------------------------------
467
// expr
468
// expr[Reg]
469
// expr[Reg+Reg*sc]
470
// [Reg]
471
// [Reg+Reg*sc]
472
// ---------------------------------------------------------------------------
473
 
474
static void mem_operand(int64_t *disp, int *regA, int *regB, int *sc, int *sg)
475
{
476
     int64_t val;
477
 
478
     // chech params
479
     if (disp == (int64_t *)NULL)
480
         return;
481
     if (regA == (int *)NULL)
482
         return;
483
     if (regB == (int *)NULL)
484
         return;
485
     if (sc==(int *)NULL)
486
         return;
487
     if (sg==(int *)NULL)
488
         return;
489
 
490
     *disp = 0;
491
     *regA = -1;
492
     *regB = -1;
493
     *sc = 0;
494
     *sg = 1;
495
     if (token!='[') {;
496
          val = expr();
497
          *disp = val;
498
     }
499
     if (token=='[') {
500
         *regA = getRegister();
501
         if (*regA == -1) {
502
             printf("expecting a register\r\n");
503
         }
504
         if (*regA==255 || *regA==253)
505
            *sg = 2;
506
         else if (*regA==254 || *regA==252)
507
            *sg = 0;
508
//         NextToken();
509
         if (token=='+') {
510
              *sc = 0;
511
              *regB = getRegister();
512
              if (*regB == -1) {
513
                  printf("expecting a register\r\n");
514
              }
515
              if (token=='*' && !fSeg)
516
                  printf("Index scaling not supported.\r\n");
517
              if (token=='*') {
518
                  NextToken();
519
                  val = expr();
520
                  prevToken();
521
//                  if (token!=tk_icon) {
522
//                      printf("expecting a scaling factor.\r\n");
523
//                      printf("token %d %c\r\n", token, token);
524
//                  }
525
                  switch(val) {
526
                  case 0: *sc = 0; break;
527
                  case 1: *sc = 0; break;
528
                  case 2: *sc = 1; break;
529
                  case 4: *sc = 2; break;
530
                  case 8: *sc = 3; break;
531
                  default: printf("Illegal scaling factor.\r\n");
532
                  }
533
              }
534
         }
535
         need(']');
536
     }
537
}
538
 
539
// ---------------------------------------------------------------------------
540
// sw disp[r1],r2
541
// sw [r1+r2],r3
542
// ----------------------------------------------------------------------------
543
 
544
static void process_store(int oc)
545
{
546
    int Ra;
547
    int Rb;
548
    int Rs;
549
    int sc;
550
    int sg;
551
    int fixup;
552
    int64_t disp;
553
 
554
    Rs = getRegister();
555
    expect(',');
556
    mem_operand(&disp, &Ra, &Rb, &sc, &sg);
557
    if (segprefix >= 0)
558
       sg = segprefix;
559
    if (Rs < 0) {
560
        printf("Expecting a source register.\r\n");
561
        ScanToEOL();
562
        return;
563
    }
564
    if (Rb > 0) {
565
       if (fSeg) {
566
           fixup = 5;
567
           emitImm4(disp,lastsym!=(SYM*)NULL);
568
       }
569
       else {
570
           fixup = 7;
571
           emitImm8(disp,lastsym!=(SYM*)NULL);
572
       }
573
       emitAlignedCode(oc + 8);
574
        if (bGen)
575
        if (lastsym) {
576
        if( lastsym->segment < 5)
577
            sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | fixup | (lastsym->isExtern ? 128 : 0)|
578
            (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
579
        }
580
       emitCode(Ra);
581
       emitCode(Rb);
582
       emitCode(Rs);
583
       if (fSeg)
584
            emitCode((disp << 4) | sc | ((sg & 3) << 2));
585
       else
586
            emitCode(disp & 255);
587
       return;
588
    }
589
    if (fSeg) {
590
        fixup = 4;
591
        if (disp < 0xFFFFFFFFFFFFE000LL || disp > 0x1FFFLL)
592
           emitImm14(disp,lastsym!=(SYM*)NULL);
593
    }
594
    else {
595
        fixup = 3;
596
        if (disp < 0xFFFFFFFFFFFF8000LL || disp > 0x7FFFLL)
597
           emitImm16(disp,lastsym!=(SYM*)NULL);
598
    }
599
    emitAlignedCode(oc);
600
    if (bGen && lastsym)
601
    if( lastsym->segment < 5)
602
    sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | fixup | (lastsym->isExtern ? 128 : 0)|
603
    (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
604
    if (Ra < 0) Ra = 0;
605
    emitCode(Ra);
606
    emitCode(Rs);
607
    if (fSeg) {
608
        emitCode(((disp << 2) & 0xFC) | (sg & 3));
609
        emitCode((disp >> 6) & 255);
610
    }
611
    else {
612
        emitCode(disp & 0xFF);
613
        emitCode((disp >> 8) & 255);
614
    }
615
    ScanToEOL();
616
}
617
 
618
// ----------------------------------------------------------------------------
619
// ----------------------------------------------------------------------------
620
 
621
static void process_ldi(int oc)
622
{
623
    int Rt;
624
    int64_t val;
625
 
626
    Rt = getRegister();
627
    expect(',');
628
    val = expr();
629
    emitImm24(val,lastsym!=(SYM*)NULL);
630
    emitAlignedCode(oc);
631
    if (bGen && lastsym)
632
    if( lastsym->segment < 5)
633
    sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 2 | (lastsym->isExtern ? 128 : 0)|
634
    (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
635
    emitCode(Rt);
636
    emitCode(val & 255);
637
    emitCode((val >> 8) & 255);
638
    emitCode((val >> 16) & 255);
639
}
640
 
641
// ----------------------------------------------------------------------------
642
// lw r1,disp[r2]
643
// lw r1,[r2+r3]
644
// ----------------------------------------------------------------------------
645
 
646
static void process_load(int oc)
647
{
648
    int Ra;
649
    int Rb;
650
    int Rt;
651
    int sc;
652
    int sg;
653
    char *p;
654
    int64_t disp;
655
    int fixup = 5;
656
 
657
    p = inptr;
658
    Rt = getRegister();
659
    if (Rt < 0) {
660
        printf("Expecting a target register.\r\n");
661
//        printf("Line:%.60s\r\n",p);
662
        ScanToEOL();
663
        inptr-=2;
664
        return;
665
    }
666
    expect(',');
667
    mem_operand(&disp, &Ra, &Rb, &sc, &sg);
668
    if (segprefix >= 0)
669
        sg = segprefix;
670
    if (Rb >= 0) {
671
       if (fSeg) {
672
           emitImm4(disp,lastsym!=(SYM*)NULL);
673
           fixup = 5;
674
       }
675
       else {
676
           emitImm8(disp,lastsym!=(SYM*)NULL);
677
           fixup = 7;
678
       }
679
       if (oc==0x87) {
680
          printf("Address mode not supported.\r\n");
681
          return;
682
       }
683
       if (oc==0x92) oc = 0x8F;  // LEA
684
       else oc = oc + 8;
685
       emitAlignedCode(oc);
686
        if (bGen && lastsym)
687
        if( lastsym->segment < 5)
688
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | fixup | (lastsym->isExtern ? 128 : 0)|
689
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
690
       emitCode(Ra);
691
       emitCode(Rb);
692
       emitCode(Rt);
693
       if (fSeg)
694
           emitCode((disp << 4) | sc | ((sg & 3) << 2));
695
       else
696
           emitCode(disp & 255);
697
       return;
698
    }
699
    if (fSeg) {
700
        fixup = 4;       // 14 bit
701
        if (disp < 0xFFFFFFFFFFFFE000LL || disp > 0x1FFFLL)
702
           emitImm14(disp,lastsym!=(SYM*)NULL);
703
    }
704
    else {
705
        fixup = 3;       // 16 bit
706
        if (disp < 0xFFFFFFFFFFFF8000LL || disp > 0x7FFFLL)
707
           emitImm16(disp,lastsym!=(SYM*)NULL);
708
    }
709
    emitAlignedCode(oc);
710
    if (bGen && lastsym)
711
    if( lastsym->segment < 5)
712
    sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | fixup | (lastsym->isExtern ? 128 : 0)|
713
    (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
714
    if (Ra < 0) Ra = 0;
715
    emitCode(Ra);
716
    emitCode(Rt);
717
    if (fSeg) {
718
        emitCode(((disp << 2) & 0xFC) | (sg & 3));
719
        emitCode((disp >> 6) & 255);
720
    }
721
    else {
722
        emitCode(disp & 0xFF);
723
        emitCode((disp >> 8) & 255);
724
    }
725
    ScanToEOL();
726
}
727
 
728
// ----------------------------------------------------------------------------
729
// lmr r1,r12,[r252]
730
// ----------------------------------------------------------------------------
731
 
732
static void process_lmr(int oc)
733
{
734
    int Ra;
735
    int Rb;
736
    int Rc;
737
 
738
    Ra = getRegister();
739
    need(',');
740
    Rb = getRegister();
741
    need(',');
742
    NextToken();
743
    if (token=='[') {
744
        Rc = getRegister();
745
        need(']');
746
    }
747
    else
748
        Rc = getRegister();
749
    emitAlignedCode(0x02);
750
    emitCode(Ra);
751
    emitCode(Rb);
752
    emitCode(Rc);
753
    emitCode(oc);
754
}
755
 
756
// ----------------------------------------------------------------------------
757
// push r1/r2/r3/r4
758
// push #123
759
// ----------------------------------------------------------------------------
760
 
761
static void process_pushpop(int oc)
762
{
763
    int Ra,Rb,Rc,Rd;
764
    int64_t val;
765
 
766
    Ra = -1;
767
    Rb = -1;
768
    Rc = -1;
769
    Rd = -1;
770
    NextToken();
771
    if (token=='#' && oc==0xA6) {  // Filter to PUSH
772
       val = expr();
773
       emitImm32(val,(code_bits > 32 || data_bits > 32) && lastsym!=(SYM *)NULL);
774
       emitAlignedCode(0xAD);
775
        if (bGen && lastsym)
776
        if( lastsym->segment < 5)
777
        sections[segment+7].AddRel(sections[segment].index,((lastsym->ord+1) << 32) | 1 | (lastsym->isExtern ? 128 : 0)|
778
        (lastsym->segment==codeseg ? code_bits << 8 : data_bits << 8));
779
       emitCode(val & 255);
780
       emitCode((val >> 8) & 255);
781
       emitCode((val >> 16) & 255);
782
       emitCode((val >> 24) & 255);
783
    }
784
    else {
785
        prevToken();
786
        Ra = getRegister();
787
        if (token=='/' || token==',') {
788
            Rb = getRegister();
789
            if (token=='/' || token==',') {
790
                Rc = getRegister();
791
                if (token=='/' || token==',') {
792
                    Rd = getRegister();
793
                }
794
            }
795
        }
796
        prevToken();
797
        emitAlignedCode(oc);
798
        emitCode(Ra>=0 ? Ra : 0);
799
        emitCode(Rb>=0 ? Rb : 0);
800
        emitCode(Rc>=0 ? Rc : 0);
801
        emitCode(Rd>=0 ? Rd : 0);
802
    }
803
}
804
 
805
// ----------------------------------------------------------------------------
806
// mov r1,r2
807
// ----------------------------------------------------------------------------
808
 
809
static void process_mov(int oc)
810
{
811
     int Ra;
812
     int Rt;
813
 
814
     Rt = getRegister();
815
     need(',');
816
     Ra = getRegister();
817
     emitAlignedCode(0x01);
818
     emitCode(Ra);
819
     emitCode(Rt);
820
     emitCode(0x00);
821
     emitCode(oc);
822
     prevToken();
823
}
824
 
825
// ----------------------------------------------------------------------------
826
// rts
827
// rts #24
828
// ----------------------------------------------------------------------------
829
 
830
static void process_rts(int oc)
831
{
832
     int64_t val;
833
 
834
     val = 0;
835
     NextToken();
836
     if (token=='#') {
837
        val = expr();
838
     }
839
     emitAlignedCode(oc);
840
     emitCode(0x00);
841
     emitCode(val & 255);
842
     emitCode((val >> 8) & 255);
843
     emitCode(0x00);
844
}
845
 
846
// ----------------------------------------------------------------------------
847
// shli r1,r2,#5
848
// ----------------------------------------------------------------------------
849
 
850
static void process_shifti(int oc)
851
{
852
     int Ra;
853
     int Rt;
854
     int64_t val;
855
 
856
     Rt = getRegister();
857
     need(',');
858
     Ra = getRegister();
859
     need(',');
860
     NextToken();
861
     val = expr();
862
     emitAlignedCode(0x02);
863
     emitCode(Ra);
864
     emitCode(val & 63);
865
     emitCode(Rt);
866
     emitCode(oc);
867
}
868
 
869
// ----------------------------------------------------------------------------
870
// gran r1
871
// ----------------------------------------------------------------------------
872
 
873
static void process_gran(int oc)
874
{
875
    int Rt;
876
 
877
    Rt = getRegister();
878
    emitAlignedCode(0x01);
879
    emitCode(0x00);
880
    emitCode(Rt);
881
    emitCode(0x00);
882
    emitCode(oc);
883
    prevToken();
884
}
885
 
886
// ----------------------------------------------------------------------------
887
// ----------------------------------------------------------------------------
888
 
889
static void process_mtspr(int oc)
890
{
891
    int spr;
892
    int Ra;
893
 
894
    spr = getSprRegister();
895
    need(',');
896
    Ra = getRegister();
897
    emitAlignedCode(0x01);
898
    emitCode(Ra);
899
    emitCode(spr);
900
    emitCode(0x00);
901
    emitCode(oc);
902
    if (Ra >= 0)
903
    prevToken();
904
}
905
 
906
// ----------------------------------------------------------------------------
907
// ----------------------------------------------------------------------------
908
 
909
static void process_mfspr(int oc)
910
{
911
    int spr;
912
    int Rt;
913
 
914
    Rt = getRegister();
915
    need(',');
916
    spr = getSprRegister();
917
    emitAlignedCode(0x01);
918
    emitCode(spr);
919
    emitCode(Rt);
920
    emitCode(0x00);
921
    emitCode(oc);
922
    if (spr >= 0)
923
    prevToken();
924
}
925
 
926
// ----------------------------------------------------------------------------
927
// ----------------------------------------------------------------------------
928
 
929
void Table888_processMaster()
930
{
931
    int nn,mm;
932
    int64_t ca;
933
    int first;
934
    int64_t bs1, bs2;
935
 
936
    lineno = 1;
937
    binndx = 0;
938
    binstart = 0;
939
    bs1 = 0;
940
    bs2 = 0;
941
    inptr = &masterFile[0];
942
    stptr = inptr;
943
    code_address = 0x200;
944
    bss_address = 0;
945
    start_address = 0x200;
946
    first_org = 1;
947
    first_rodata = 1;
948
    first_data = 1;
949
    for (nn = 0; nn < 12; nn++) {
950
        sections[nn].index = 0;
951
        sections[nn].address = 0;
952
        sections[nn].start = 0;
953
        sections[nn].end = 0;
954
    }
955
    ca = code_address;
956
    segment = codeseg;
957
    memset(current_label,0,sizeof(current_label));
958
    NextToken();
959
    while (token != tk_eof) {
960
        switch(token) {
961
        case tk_eol:
962
             //printf("Line: %d\r\n", lineno);
963
             segprefix = -1;
964
             if (bGen && (segment==codeseg || segment==dataseg || segment==rodataseg)) {
965
             if ((ca & 15)==15 && segment==codeseg) {
966
                 ca++;
967
                 binstart++;
968
             }
969
            nn = binstart;
970
            if (segment==codeseg) {
971
                if (sections[segment].bytes[binstart]==0xfd) {
972
                    fprintf(ofp, "%06LLX ", ca);
973
                    for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
974
                        fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
975
                    }
976
                    fprintf(ofp, "   ; imm\n");
977
                     if (((ca+5) & 15)==15) {
978
                         ca+=6;
979
                         binstart+=6;
980
                         nn++;
981
                     }
982
                     else {
983
                          ca += 5;
984
                          binstart += 5;
985
                     }
986
                }
987
                 if (sections[segment].bytes[binstart]==0xfe) {
988
                    fprintf(ofp, "%06LLX ", ca);
989
                    for (nn = binstart; nn < binstart + 5 && nn < sections[segment].index; nn++) {
990
                        fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
991
                    }
992
                    fprintf(ofp, "   ; imm\n");
993
                     if (((ca+5) & 15)==15) {
994
                         ca+=6;
995
                         nn++;
996
                     }
997
                     else {
998
                          ca += 5;
999
                     }
1000
                }
1001
            }
1002
            first = 1;
1003
            while (nn < sections[segment].index) {
1004
                fprintf(ofp, "%06LLX ", ca);
1005
                for (mm = nn; nn < mm + 8 && nn < sections[segment].index; nn++) {
1006
                    fprintf(ofp, "%02X ", sections[segment].bytes[nn]);
1007
                }
1008
                for (; nn < mm + 8; nn++)
1009
                    fprintf(ofp, "   ");
1010
                if (first) {
1011
                    fprintf(ofp, "\t%.*s\n", inptr-stptr-1, stptr);
1012
                    first = 0;
1013
                }
1014
                else
1015
                    fprintf(ofp, "\n");
1016
                ca += 8;
1017
            }
1018
            // empty (codeless) line
1019
            if (binstart==sections[segment].index) {
1020
                fprintf(ofp, "%24s\t%.*s", "", inptr-stptr, stptr);
1021
            }
1022
            } // bGen
1023
            stptr = inptr;
1024
            binstart = sections[segment].index;
1025
            ca = sections[segment].address;
1026
            lineno++;
1027
            break;
1028
        case tk_add:  process_rrop(0x04); break;
1029
        case tk_addi: process_riop(0x04); break;
1030
        case tk_addu: process_rrop(0x14); break;
1031
        case tk_addui: process_riop(0x14); break;
1032
        case tk_align: process_align(); continue; break;
1033
        case tk_and:  process_rrop(0x20); break;
1034
        case tk_andi:  process_riop(0x0C); break;
1035
        case tk_asr:  process_rrop(0x44); break;
1036
        case tk_asri: process_shifti(0x54); break;
1037
        case tk_beq: process_bcc(0x40); break;
1038
        case tk_bge: process_bcc(0x4A); break;
1039
        case tk_bgeu: process_bcc(0x4E); break;
1040
        case tk_bgt: process_bcc(0x48); break;
1041
        case tk_bgtu: process_bcc(0x4C); break;
1042
        case tk_ble: process_bcc(0x49); break;
1043
        case tk_bleu: process_bcc(0x4D); break;
1044
        case tk_blt: process_bcc(0x4B); break;
1045
        case tk_bltu: process_bcc(0x4F); break;
1046
        case tk_bmi: process_bcc(0x44); break;
1047
        case tk_bne: process_bcc(0x41); break;
1048
        case tk_bpl: process_bcc(0x45); break;
1049
        case tk_bra: process_bra(0x46); break;
1050
        case tk_brnz: process_bcc(0x59); break;
1051
        case tk_brz:  process_bcc(0x58); break;
1052
        case tk_bvc: process_bcc(0x43); break;
1053
        case tk_bvs: process_bcc(0x42); break;
1054
        case tk_bsr: process_bra(0x56); break;
1055
        case tk_bss: segment = bssseg; break;
1056
        case tk_cli: emit_insn(0x3100000001); break;
1057
        case tk_cmp: process_rrop(0x06); break;
1058
        case tk_code: process_code(); break;
1059
        case tk_com: process_rop(0x06); break;
1060
        case tk_cs:  segprefix = 0; break;
1061
        case tk_data:
1062
            if (first_data) {
1063
                while(sections[segment].address & 4095)
1064
                    emitByte(0x00);
1065
                sections[2].address = sections[segment].address;   // set starting address
1066
                first_data = 0;
1067
                binstart = sections[2].index;
1068
                ca = sections[2].address;
1069
            }
1070
            process_data(dataseg);
1071
            break;
1072
        case tk_db:  process_db(); break;
1073
        case tk_dbnz: process_bcc(0x5A); break;
1074
        case tk_dc:  process_dc(); break;
1075
        case tk_dh:  process_dh(); break;
1076
        case tk_div: process_rrop(0x08); break;
1077
        case tk_divu: process_rrop(0x18); break;
1078
        case tk_ds:  segprefix = 1; break;
1079
        case tk_dw:  process_dw(); break;
1080
        case tk_end: goto j1;
1081
        case tk_endpublic: break;
1082
        case tk_eor: process_rrop(0x22); break;
1083
        case tk_eori: process_riop(0x0E); break;
1084
        case tk_extern: process_extern(); break;
1085
        case tk_fill: process_fill(); break;
1086
        case tk_gran: process_gran(0x14); break;
1087
        case tk_jmp: process_jmp(0x50); break;
1088
        case tk_jsr: process_jmp(0x51); break;
1089
        case tk_lb:  process_load(0x80); break;
1090
        case tk_lbu: process_load(0x81); break;
1091
        case tk_lc:  process_load(0x82); break;
1092
        case tk_lcu: process_load(0x83); break;
1093
        case tk_ldi: process_ldi(0x16); break;
1094
        case tk_lea: process_load(0x92); break;
1095
        case tk_lh:  process_load(0x84); break;
1096
        case tk_lhu: process_load(0x85); break;
1097
        case tk_lmr: process_lmr(0x31); break;
1098
        case tk_lw:  process_load(0x86); break;
1099
        case tk_mfspr: process_mfspr(0x49); break;
1100
        case tk_mod: process_rrop(0x09); break;
1101
        case tk_modu: process_rrop(0x19); break;
1102
        case tk_mov: process_mov(0x04); break;
1103
        case tk_mtspr: process_mtspr(0x48); break;
1104
        case tk_mul: process_rrop(0x07); break;
1105
        case tk_muli: process_riop(0x07); break;
1106
        case tk_mulu: process_rrop(0x17); break;
1107
        case tk_mului: process_riop(0x17); break;
1108
        case tk_neg: process_rop(0x05); break;
1109
        case tk_nop: emit_insn(0xEAEAEAEAEA); break;
1110
        case tk_not: process_rop(0x07); break;
1111
        case tk_or:  process_rrop(0x21); break;
1112
        case tk_ori: process_riop(0x0D); break;
1113
        case tk_org: process_org(); break;
1114
        case tk_php: emit_insn(0x3200000001); break;
1115
        case tk_plp: emit_insn(0x3300000001); break;
1116
        case tk_pop:  process_pushpop(0xA7); break;
1117
        case tk_public: process_public(); break;
1118
        case tk_push: process_pushpop(0xA6); break;
1119
        case tk_rodata:
1120
            if (first_rodata) {
1121
                while(sections[segment].address & 4095)
1122
                    emitByte(0x00);
1123
                sections[1].address = sections[segment].address;
1124
                first_rodata = 0;
1125
                binstart = sections[1].index;
1126
                ca = sections[1].address;
1127
            }
1128
            segment = rodataseg;
1129
            break;
1130
        case tk_rol: process_rrop(0x41); break;
1131
        case tk_ror: process_rrop(0x43); break;
1132
        case tk_rti: emit_insn(0x4000000001); break;
1133
        case tk_rts: process_rts(0x60); break;
1134
        case tk_sb:  process_store(0xa0); break;
1135
        case tk_sc:  process_store(0xa1); break;
1136
        case tk_sei: emit_insn(0x3000000001); break;
1137
        case tk_seq:  process_rrop(0x60); break;
1138
        case tk_seqi: process_riop(0x30); break;
1139
        case tk_sge:  process_rrop(0x6A); break;
1140
        case tk_sgt:  process_rrop(0x68); break;
1141
        case tk_sle:  process_rrop(0x69); break;
1142
        case tk_slt:  process_rrop(0x6B); break;
1143
        case tk_sgeu:  process_rrop(0x6E); break;
1144
        case tk_sgtu:  process_rrop(0x6C); break;
1145
        case tk_sleu:  process_rrop(0x6D); break;
1146
        case tk_sltu:  process_rrop(0x6F); break;
1147
        case tk_sgei:  process_rrop(0x3A); break;
1148
        case tk_sgti:  process_rrop(0x38); break;
1149
        case tk_slei:  process_rrop(0x39); break;
1150
        case tk_slti:  process_rrop(0x3B); break;
1151
        case tk_sgeui:  process_rrop(0x3E); break;
1152
        case tk_sgtui:  process_rrop(0x3C); break;
1153
        case tk_sleui:  process_rrop(0x3D); break;
1154
        case tk_sltui:  process_rrop(0x3F); break;
1155
        case tk_sne:  process_rrop(0x61); break;
1156
        case tk_snei: process_riop(0x31); break;
1157
        case tk_sh:  process_store(0xa2); break;
1158
        case tk_shl:  process_rrop(0x40); break;
1159
        case tk_shli: process_shifti(0x50); break;
1160
        case tk_shru: process_rrop(0x42); break;
1161
        case tk_shrui: process_shifti(0x52); break;
1162
        case tk_smr: process_lmr(0x30); break;
1163
        case tk_ss:  segprefix = 2; break;
1164
        case tk_sub:  process_rrop(0x05); break;
1165
        case tk_subi: process_riop(0x05); break;
1166
        case tk_subu: process_rrop(0x15); break;
1167
        case tk_subui: process_riop(0x15); break;
1168
        case tk_sxb: process_rop(0x08); break;
1169
        case tk_sxc: process_rop(0x09); break;
1170
        case tk_sxh: process_rop(0x0A); break;
1171
        case tk_sw:  process_store(0xa3); break;
1172
        case tk_swap: process_rop(0x03); break;
1173
        case tk_xor: process_rrop(0x22); break;
1174
        case tk_xori: process_riop(0x0E); break;
1175
        case tk_id:  process_label(); break;
1176
        }
1177
        NextToken();
1178
    }
1179
j1:
1180
    ;
1181
}
1182
 

powered by: WebSVN 2.1.0

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