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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [CodeGenerator.c] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 37 robfinch
#include        <stdio.h>
2
#include        "c.h"
3
#include        "expr.h"
4
#include "Statement.h"
5
#include        "gen.h"
6
#include        "cglbdec.h"
7
 
8
/*
9
 *      68000 C compiler
10
 *
11
 *      Copyright 1984, 1985, 1986 Matthew Brandt.
12
 *  all commercial rights reserved.
13
 *
14
 *      This compiler is intended as an instructive tool for personal use. Any
15
 *      use for profit without the written consent of the author is prohibited.
16
 *
17
 *      This compiler may be distributed freely for non-commercial use as long
18
 *      as this notice stays intact. Please forward any enhancements or questions
19
 *      to:
20
 *
21
 *              Matthew Brandt
22
 *              Box 920337
23
 *              Norcross, Ga 30092
24
 */
25
 
26
/*
27
 *      this module contains all of the code generation routines
28
 *      for evaluating expressions and conditions.
29
 */
30
 
31
/*******************************************************
32
        Modified to support Raptor64 'C64' language
33
        by Robert Finch
34
        robfinch@opencores.org
35
*******************************************************/
36
 
37
AMODE *GenerateExpression();            /* forward ParseSpecifieraration */
38
 
39
extern int throwlab;
40
/*
41
 *      construct a reference node for an internal label number.
42
 */
43
AMODE *make_label(__int64 lab)
44
{
45
        struct enode    *lnode;
46
    struct amode    *ap;
47
    lnode = xalloc(sizeof(struct enode));
48
    lnode->nodetype = en_labcon;
49
    lnode->i = lab;
50
    ap = xalloc(sizeof(struct amode));
51
    ap->mode = am_direct;
52
    ap->offset = lnode;
53
    return ap;
54
}
55
 
56
AMODE *make_string(char *s)
57
{
58
        ENODE *lnode;
59
    AMODE *ap;
60
 
61
    lnode = xalloc(sizeof(struct enode));
62
    lnode->nodetype = en_nacon;
63
    lnode->sp = s;
64
    ap = allocAmode();
65
    ap->mode = am_direct;
66
    ap->offset = lnode;
67
    return ap;
68
}
69
 
70
/*
71
 *      make a node to reference an immediate value i.
72
 */
73
AMODE *make_immed(__int64 i)
74
{
75
        AMODE *ap;
76
    ENODE *ep;
77
    ep = xalloc(sizeof(struct enode));
78
    ep->nodetype = en_icon;
79
    ep->i = i;
80
    ap = allocAmode();
81
    ap->mode = am_immed;
82
    ap->offset = ep;
83
    return ap;
84
}
85
 
86
AMODE *make_indirect(int i)
87
{
88
        AMODE *ap;
89
    ENODE *ep;
90
    ep = xalloc(sizeof(struct enode));
91
    ep->nodetype = en_uw_ref;
92
    ep->i = 0;
93
    ap = allocAmode();
94
        ap->mode = am_ind;
95
        ap->preg = i;
96
    ap->offset = ep;
97
    return ap;
98
}
99
 
100
AMODE *make_indexed(__int64 o, int i)
101
{
102
        AMODE *ap;
103
    ENODE *ep;
104
    ep = xalloc(sizeof(struct enode));
105
    ep->nodetype = en_icon;
106
    ep->i = o;
107
    ap = allocAmode();
108
        ap->mode = am_indx;
109
        ap->preg = i;
110
    ap->offset = ep;
111
    return ap;
112
}
113
 
114
/*
115
 *      make a direct reference to a node.
116
 */
117
AMODE *make_offset(ENODE *node)
118
{
119
        AMODE *ap;
120
    ap = allocAmode();
121
    ap->mode = am_direct;
122
    ap->offset = node;
123
    return ap;
124
}
125
 
126
/*
127
 *      MakeLegalAmode will coerce the addressing mode in ap1 into a
128
 *      mode that is satisfactory for the flag word.
129
 */
130
void MakeLegalAmode(AMODE *ap,int flags, int size)
131
{
132
        AMODE *ap2;
133
        __int64 i;
134
 
135
        if (ap==NULL) return;
136
    if( ((flags & F_VOL) == 0) || ap->tempflag )
137
    {
138
        switch( ap->mode ) {
139
            case am_immed:
140
                                        i = ((ENODE *)(ap->offset))->i;
141
                                        if (flags & F_IMMED18) {
142
                                                if (i < 0x1ffff && i > -0x1ffff)
143
                                                        return;
144
                                        }
145
                    else if( flags & F_IMMED )
146
                        return;         /* mode ok */
147
                    break;
148
            case am_reg:
149
                    if( flags & F_REG )
150
                        return;
151
                    break;
152
            case am_ind:
153
                        case am_indx:
154
            case am_indx2:
155
                        case am_direct:
156
                        case am_indx3:
157
                    if( flags & F_MEM )
158
                        return;
159
                    break;
160
            }
161
        }
162
 
163
        if( flags & F_REG )
164
        {
165
            ReleaseTempRegister(ap);      /* maybe we can use it... */
166
            ap2 = GetTempRegister();      /* AllocateRegisterVars to dreg */
167
                        if (ap->mode == am_ind || ap->mode==am_indx) {
168
                                switch(size) {
169
                                case 1: GenerateDiadic(op_lb,0,ap2,ap); break;
170
                                case 2: GenerateDiadic(op_lc,0,ap2,ap); break;
171
                                case 4: GenerateDiadic(op_lh,0,ap2,ap); break;
172
                                case 8: GenerateDiadic(op_lw,0,ap2,ap); break;
173
                                }
174
                        }
175
                        else if (ap->mode==am_immed)
176
                                GenerateTriadic(op_ori,0,ap2,makereg(0),ap);
177
                        else {
178
                                if (ap->mode==am_reg)
179
                                        GenerateTriadic(op_or,0,ap2,ap,makereg(0));
180
                                else {
181
                                        switch(size) {
182
                                        case 1: GenerateDiadic(op_lb,0,ap2,ap); break;
183
                                        case 2: GenerateDiadic(op_lc,0,ap2,ap); break;
184
                                        case 4: GenerateDiadic(op_lh,0,ap2,ap); break;
185
                                        case 8: GenerateDiadic(op_lw,0,ap2,ap); break;
186
                                        }
187
                                }
188
                        }
189
            ap->mode = am_reg;
190
            ap->preg = ap2->preg;
191
            ap->deep = ap2->deep;
192
            ap->tempflag = 1;
193
            return;
194
        }
195
        if( size == 1 )
196
                {
197
                        ReleaseTempRegister(ap);
198
                        ap2 = GetTempRegister();
199
                        GenerateTriadic(op_or,0,ap2,ap,makereg(0));
200
                        GenerateTriadic(op_sext8,0,ap2,ap2,NULL);
201
                        ap->mode = ap2->mode;
202
                        ap->preg = ap2->preg;
203
                        ap->deep = ap2->deep;
204
                        size = 2;
205
        }
206
        ap2 = GetTempRegister();
207
                switch(ap->mode) {
208
                case am_ind:
209
                case am_indx:
210
                        switch(size) {
211
                        case 1: GenerateDiadic(op_lb,0,ap2,ap); break;
212
                        case 2: GenerateDiadic(op_lc,0,ap2,ap); break;
213
                        case 4: GenerateDiadic(op_lh,0,ap2,ap); break;
214
                        case 8: GenerateDiadic(op_lw,0,ap2,ap); break;
215
                        }
216
                        break;
217
                case am_immed:
218
                        GenerateTriadic(op_ori,0,ap2,makereg(0),ap);
219
                case am_reg:
220
                        GenerateTriadic(op_or,0,ap2,ap,makereg(0));
221
                default:
222
                        switch(size) {
223
                        case 1: GenerateDiadic(op_lb,0,ap2,ap); break;
224
                        case 2: GenerateDiadic(op_lc,0,ap2,ap); break;
225
                        case 4: GenerateDiadic(op_lh,0,ap2,ap); break;
226
                        case 8: GenerateDiadic(op_lw,0,ap2,ap); break;
227
                        }
228
                }
229
    ap->mode = am_reg;
230
    ap->preg = ap2->preg;
231
    ap->deep = ap2->deep;
232
    ap->tempflag = 1;
233
}
234
 
235
/*
236
 *      if isize is not equal to osize then the operand ap will be
237
 *      loaded into a register (if not already) and if osize is
238
 *      greater than isize it will be extended to match.
239
 */
240
void GenerateSignExtend(AMODE *ap, int isize, int osize, int flags)
241
{
242
        struct amode *ap2;
243
 
244
        if( isize == osize )
245
        return;
246
    if(ap->mode != am_reg)
247
        MakeLegalAmode(ap,flags & F_REG,isize);
248
    switch( isize )
249
    {
250
    case 1:     GenerateDiadic(op_sext8,0,ap,ap); break;
251
    case 2:     GenerateDiadic(op_sext16,0,ap,ap); break;
252
    case 4:     GenerateDiadic(op_sext32,0,ap,ap); break;
253
    }
254
}
255
 
256
/*
257
 *      return true if the node passed can be generated as a short
258
 *      offset.
259
 */
260
int isshort(ENODE *node)
261
{
262
        return node->nodetype == en_icon &&
263
        (node->i >= -32768 && node->i <= 32767);
264
}
265
 
266
/*
267
 *      return true if the node passed can be evaluated as a byte
268
 *      offset.
269
 */
270
int isbyte(ENODE *node)
271
{
272
        return node->nodetype == en_icon &&
273
       (-128 <= node->i && node->i <= 127);
274
}
275
 
276
int ischar(ENODE *node)
277
{
278
        return node->nodetype == en_icon &&
279
        (node->i >= -32768 && node->i <= 32767);
280
}
281
 
282
/*
283
 *      generate code to evaluate an index node (^+) and return
284
 *      the addressing mode of the result. This routine takes no
285
 *      flags since it always returns either am_ind or am_indx.
286
 */
287
AMODE *GenerateIndex(ENODE *node)
288
{
289
        AMODE *ap1, *ap2, *ap3;
290
 
291
    if( (node->p[0]->nodetype == en_tempref || node->p[0]->nodetype==en_regvar) && (node->p[1]->nodetype == en_tempref || node->p[1]->nodetype==en_regvar))
292
    {       /* both nodes are registers */
293
        ap1 = GenerateExpression(node->p[0],F_REG,8);
294
        ap2 = GenerateExpression(node->p[1],F_REG,8);
295
        ap1->mode = am_indx2;
296
        ap1->sreg = ap2->preg;
297
                ap1->offset = makeinode(en_icon,0);
298 51 robfinch
                ap1->scale = node->scale;
299 37 robfinch
        return ap1;
300
    }
301
    ap1 = GenerateExpression(node->p[0],F_REG | F_IMMED,8);
302
    if( ap1->mode == am_immed )
303
    {
304
                ap2 = GenerateExpression(node->p[1],F_REG,8);
305
                ap2->mode = am_indx;
306
                ap2->offset = ap1->offset;
307
                ReleaseTempRegister(ap1);
308
                return ap2;
309
    }
310
    ap2 = GenerateExpression(node->p[1],F_ALL,8);   /* get right op */
311
    if( ap2->mode == am_immed && ap1->mode == am_reg ) /* make am_indx */
312
    {
313
        ap2->mode = am_indx;
314
                ReleaseTempRegister(ap2);
315
        ap2->preg = ap1->preg;
316
        ap2->deep = ap1->deep;
317
        return ap2;
318
    }
319
        // ap1->mode must be F_REG
320
        MakeLegalAmode(ap2,F_REG,8);
321
//      ap3 = GetTempRegister();
322
//      GenerateTriadic(op_addu,0,ap3,ap1,ap2);             /* add left to address reg */
323
    ap1->mode = am_indx2;            /* make indirect */
324
        ap1->sreg = ap2->preg;
325
        ap1->offset = makeinode(en_icon,0);
326 51 robfinch
        ap1->scale = node->scale;
327 37 robfinch
//  ReleaseTempRegister(ap2);                    /* release any temps in ap2 */
328
//      ReleaseTempRegister(ap1);
329
    return ap1;                     /* return indirect */
330
}
331
 
332
long GetReferenceSize(ENODE *node)
333
{
334
    switch( node->nodetype )        /* get load size */
335
    {
336
    case en_b_ref:
337
    case en_ub_ref:
338
    case en_bfieldref:
339
    case en_ubfieldref:
340
            return 1;
341
        case en_c_ref:
342
        case en_uc_ref:
343
        case en_cfieldref:
344
        case en_ucfieldref:
345
                        return 2;
346
        case en_h_ref:
347
        case en_uh_ref:
348
        case en_hfieldref:
349
        case en_uhfieldref:
350
                        return 4;
351
    case en_w_ref:
352
        case en_uw_ref:
353
    case en_wfieldref:
354
        case en_uwfieldref:
355
        case en_tempref:
356
        case en_regvar:
357
            return 8;
358
    }
359
        return 8;
360
}
361
 
362
/*
363
 *      return the addressing mode of a dereferenced node.
364
 */
365
AMODE *GenerateDereference(ENODE *node,int flags,int size)
366
{
367
        struct amode    *ap1;
368
    int             siz1;
369
 
370
        siz1 = GetReferenceSize(node);
371
    if( node->p[0]->nodetype == en_add )
372
    {
373
        ap1 = GenerateIndex(node->p[0]);
374
        GenerateSignExtend(ap1,siz1,size,flags);
375
        MakeLegalAmode(ap1,flags,size);
376
        return ap1;
377
    }
378
    else if( node->p[0]->nodetype == en_autocon )
379
    {
380
        ap1 = xalloc(sizeof(struct amode));
381
        ap1->mode = am_indx;
382
        ap1->preg = 27;
383
        ap1->offset = makeinode(en_icon,node->p[0]->i);
384
        GenerateSignExtend(ap1,siz1,size,flags);
385
        MakeLegalAmode(ap1,flags,size);
386
        return ap1;
387
    }
388
    ap1 = GenerateExpression(node->p[0],F_REG | F_IMMED,4); /* generate address */
389
    if( ap1->mode == am_reg )
390
    {
391
        ap1->mode = am_ind;
392
        GenerateSignExtend(ap1,siz1,size,flags);
393
        MakeLegalAmode(ap1,flags,size);
394
        return ap1;
395
    }
396
    ap1->mode = am_direct;
397
    GenerateSignExtend(ap1,siz1,size,flags);
398
    MakeLegalAmode(ap1,flags,size);
399
    return ap1;
400
}
401
 
402
void SignExtendBitfield(ENODE *node, struct amode *ap3, __int64 mask)
403
{
404
        struct amode *ap2;
405
        __int64 umask;
406
 
407
        umask = 0x8000000000000000L | ~(mask >> 1);
408
        ap2 = GetTempRegister();
409
        GenerateTriadic(op_ori,0,ap2,makereg(0),make_immed(umask));
410
        GenerateTriadic(op_add,0,ap3,ap3,ap2);
411
        GenerateTriadic(op_xor,0,ap3,ap3,ap2);
412
        ReleaseTempRegister(ap2);
413
}
414
 
415
AMODE *GenerateBitfieldDereference(ENODE *node, int flags, int size)
416
{
417
    AMODE *ap, *ap1,*ap2,*ap3;
418
    long            mask,umask;
419
    int             width = node->bit_width + 1;
420
        int isSigned;
421
 
422
        isSigned = node->nodetype==en_wfieldref || node->nodetype==en_hfieldref || node->nodetype==en_cfieldref || node->nodetype==en_bfieldref;
423
        mask = 0;
424
        while (--width) mask = mask + mask + 1;
425
    ap = GenerateDereference(node, flags, node->esize);
426
    MakeLegalAmode(ap, flags, node->esize);
427
        ap3 = GetTempRegister();
428
        GenerateTriadic(op_or,0,ap3,ap,makereg(0));
429
        ReleaseTempRegister(ap);
430
    if (node->bit_offset > 0) {
431
                GenerateDiadic(op_shru, 0, ap3, make_immed((__int64) node->bit_offset));
432
                GenerateDiadic(op_and, 0, ap3, make_immed(mask));
433
                //MakeLegalAmode(ap, flags, node->esize);
434
                if (isSigned)
435
                        SignExtendBitfield(node, ap3, mask);
436
    }
437
        else {
438
                GenerateTriadic(op_and, 0, ap3, ap3, make_immed(mask));
439
                if (isSigned)
440
                        SignExtendBitfield(node, ap3, mask);
441
        }
442
    //mask = 0;
443
    //while (--width)   mask = mask + mask + 1;
444
//    GenerateDiadic(op_and, (int) node->esize, make_immed(mask), ap);
445
        MakeLegalAmode(ap3, flags, node->esize);
446
    return ap3;
447
}
448
 
449
/*
450
 *      generate code to evaluate a unary minus or complement.
451
 */
452
AMODE *GenerateUnary(ENODE *node,int flags, int size, int op)
453
{
454
        AMODE *ap,*ap1;
455
    ap = GenerateExpression(node->p[0],F_REG,size);
456
        ap1 = GetTempRegister();
457
    GenerateDiadic(op,0,ap1,ap);
458
    ReleaseTempRegister(ap);
459
    MakeLegalAmode(ap1,flags,size);
460
    return ap1;
461
}
462
 
463
AMODE *GenerateBinary(ENODE *node,int flags, int size, int op)
464
{
465
        AMODE *ap1, *ap2, *ap3;
466
        int op2;
467
    ap1 = GenerateExpression(node->p[0],F_REG,size);
468
    ap2 = GenerateExpression(node->p[1],F_REG|F_IMMED,size);
469
        ap3 = GetTempRegister();
470
        GenerateTriadic(op,0,ap3,ap1,ap2);
471
    ReleaseTempRegister(ap1);
472
    ReleaseTempRegister(ap2);
473
    MakeLegalAmode(ap3,flags,size);
474
    return ap3;
475
}
476
 
477
/*
478
 *      generate code to evaluate a mod operator or a divide
479
 *      operator.
480
 */
481
AMODE *GenerateModDiv(ENODE *node,int flags,int size, int op)
482
{
483 51 robfinch
        AMODE *ap1, *ap2, *ap3;
484 37 robfinch
 
485
    if( node->p[0]->nodetype == en_icon )
486
         swap_nodes(node);
487
    ap1 = GenerateExpression(node->p[0],F_REG,8);
488
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,8);
489 51 robfinch
        ap3 = GetTempRegister();
490
        GenerateTriadic(op,0,ap3,ap1,ap2);
491
//    GenerateDiadic(op_ext,0,ap3,0);
492
    MakeLegalAmode(ap3,flags,4);
493
    ReleaseTempRegister(ap1);
494 37 robfinch
    ReleaseTempRegister(ap2);
495 51 robfinch
    return ap3;
496 37 robfinch
}
497
 
498
/*
499
 *      exchange the two operands in a node.
500
 */
501
void swap_nodes(ENODE *node)
502
{
503
        ENODE *temp;
504
    temp = node->p[0];
505
    node->p[0] = node->p[1];
506
    node->p[1] = temp;
507
}
508
 
509
/*
510
 *      generate code to evaluate a multiply node. both operands
511
 *      are treated as words and the result is long and is always
512
 *      in a register so that the 68000 mul instruction can be used.
513
 */
514
AMODE *GenerateMultiply(ENODE *node, int flags, int size, int op)
515
{
516
        AMODE *ap1, *ap2, *ap3;
517
    if( node->p[0]->nodetype == en_icon )
518
        swap_nodes(node);
519
    ap1 = GenerateExpression(node->p[0],F_REG,8);
520
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,8);
521
ap3 = GetTempRegister();
522
        if (ap2->mode == am_immed) {
523
                if (op==op_mulu)
524
                        GenerateTriadic(op_mului,0,ap3,ap1,ap2);
525
                else
526
                        GenerateTriadic(op_mulsi,0,ap3,ap1,ap2);
527
        }
528
        else
529
                GenerateTriadic(op,0,ap3,ap1,ap2);
530
    ReleaseTempRegister(ap1);
531
    ReleaseTempRegister(ap2);
532
    MakeLegalAmode(ap3,flags,8);
533
    return ap3;
534
}
535
 
536
/*
537
 *      generate code to evaluate a condition operator node (?:)
538
 */
539
AMODE *gen_hook(ENODE *node,int flags, int size)
540
{
541
        AMODE *ap1, *ap2;
542
    int false_label, end_label;
543
 
544
    false_label = nextlabel++;
545
    end_label = nextlabel++;
546
    flags = (flags & F_REG) | F_VOL;
547
    GenerateFalseJump(node->p[0],false_label);
548
    node = node->p[1];
549
    ap1 = GenerateExpression(node->p[0],flags,size);
550
    ReleaseTempRegister(ap1);
551
    GenerateDiadic(op_bra,0,make_label(end_label),0);
552
    GenerateLabel(false_label);
553
    ap2 = GenerateExpression(node->p[1],flags,size);
554
    if( !equal_address(ap1,ap2) )
555
    {
556
        ReleaseTempRegister(ap2);
557
//        GetTempRegister();
558
                GenerateTriadic(op_or,0,ap1,makereg(0),ap2);
559
    }
560
    GenerateLabel(end_label);
561
    return ap1;
562
}
563
 
564
AMODE *GenerateAssignAdd(ENODE *node,int flags, int size, int op)
565
{
566
        AMODE *ap1, *ap2, *ap3;
567
    int             ssize, mask0, mask1;
568
    ssize = GetNaturalSize(node->p[0]);
569
    if( ssize > size )
570
            size = ssize;
571
    ap1 = GenerateExpression(node->p[0],F_ALL,ssize);
572
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size);
573
        if (ap2->mode ==am_immed)
574
                switch(op) {
575
                case op_addu:   op = op_addui; break;
576
                case op_add:    op = op_addui; break;
577
                case op_subu:   op = op_subui; break;
578
                case op_sub:    op = op_subui; break;
579
                }
580
        if (ap1->mode==am_reg) {
581
            GenerateTriadic(op,0,ap1,ap1,ap2);
582
        }
583
        else {
584
                ap3 = GetTempRegister();
585
                switch(ssize) {
586
                case 1: GenerateDiadic(op_lb,0,ap3,ap1); break;
587
                case 2: GenerateDiadic(op_lc,0,ap3,ap1); break;
588
                case 4: GenerateDiadic(op_lh,0,ap3,ap1); break;
589
                case 8: GenerateDiadic(op_lw,0,ap3,ap1); break;
590
                }
591
                GenerateTriadic(op,0,ap3,ap3,ap2);
592
                switch(ssize) {
593
                case 1: GenerateDiadic(op_sb,0,ap3,ap1); break;
594
                case 2: GenerateDiadic(op_sc,0,ap3,ap1); break;
595
                case 4: GenerateDiadic(op_sh,0,ap3,ap1); break;
596
                case 8: GenerateDiadic(op_sw,0,ap3,ap1); break;
597
                }
598
                ReleaseTempRegister(ap3);
599
        }
600
    ReleaseTempRegister(ap2);
601
    GenerateSignExtend(ap1,ssize,size,flags);
602
    MakeLegalAmode(ap1,flags,size);
603
    return ap1;
604
}
605
 
606
AMODE *GenerateAssignLogic(ENODE *node,int flags, int size, int op)
607
{
608
        AMODE *ap1, *ap2, *ap3;
609
    int             ssize, mask0, mask1;
610
    ssize = GetNaturalSize(node->p[0]);
611
    if( ssize > size )
612
            size = ssize;
613
    ap1 = GenerateExpression(node->p[0],F_ALL,ssize);
614
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size);
615
        if (ap2->mode==am_immed)
616
                switch(op) {
617
                case op_and:    op = op_andi; break;
618
                case op_or:             op = op_ori; break;
619
                case op_xor:    op = op_xori; break;
620
                }
621
        if (ap1->mode==am_reg) {
622
            GenerateTriadic(op,0,ap1,ap1,ap2);
623
        }
624
        else {
625
                ap3 = GetTempRegister();
626
                switch(ssize) {
627
                case 1: GenerateDiadic(op_lb,0,ap3,ap1); break;
628
                case 2: GenerateDiadic(op_lc,0,ap3,ap1); break;
629
                case 4: GenerateDiadic(op_lh,0,ap3,ap1); break;
630
                case 8: GenerateDiadic(op_lw,0,ap3,ap1); break;
631
                }
632
                GenerateTriadic(op,0,ap3,ap3,ap2);
633
                switch(ssize) {
634
                case 1: GenerateDiadic(op_sb,0,ap3,ap1); break;
635
                case 2: GenerateDiadic(op_sc,0,ap3,ap1); break;
636
                case 4: GenerateDiadic(op_sh,0,ap3,ap1); break;
637
                case 8: GenerateDiadic(op_sw,0,ap3,ap1); break;
638
                }
639
                ReleaseTempRegister(ap3);
640
        }
641
    ReleaseTempRegister(ap2);
642
    GenerateSignExtend(ap1,ssize,size,flags);
643
    MakeLegalAmode(ap1,flags,size);
644
    return ap1;
645
}
646
 
647
/*
648
 *      generate a *= node.
649
 */
650
AMODE *GenerateAssignMultiply(ENODE *node,int flags, int size, int op)
651
{
652
        AMODE *ap1, *ap2, *ap3;
653
    int             ssize, mask0, mask1;
654
    ssize = GetNaturalSize(node->p[0]);
655
    if( ssize > size )
656
            size = ssize;
657
    ap1 = GenerateExpression(node->p[0],F_ALL,ssize);
658
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size);
659
        if (ap2->mode==am_immed)
660
                switch(op) {
661
                case op_mulu:   op = op_mului; break;
662
                case op_muls:   op = op_mulsi; break;
663
                }
664
        if (ap1->mode==am_reg) {
665
            GenerateTriadic(op,0,ap1,ap1,ap2);
666
        }
667
        else {
668
                ap3 = GetTempRegister();
669
                switch(ssize) {
670
                case 1: GenerateDiadic(op_lb,0,ap3,ap1); break;
671
                case 2: GenerateDiadic(op_lc,0,ap3,ap1); break;
672
                case 4: GenerateDiadic(op_lh,0,ap3,ap1); break;
673
                case 8: GenerateDiadic(op_lw,0,ap3,ap1); break;
674
                }
675
                GenerateTriadic(op,0,ap3,ap3,ap2);
676
                switch(ssize) {
677
                case 1: GenerateDiadic(op_sb,0,ap3,ap1); break;
678
                case 2: GenerateDiadic(op_sc,0,ap3,ap1); break;
679
                case 4: GenerateDiadic(op_sh,0,ap3,ap1); break;
680
                case 8: GenerateDiadic(op_sw,0,ap3,ap1); break;
681
                }
682
                ReleaseTempRegister(ap3);
683
        }
684
    ReleaseTempRegister(ap2);
685
    GenerateSignExtend(ap1,ssize,size,flags);
686
    MakeLegalAmode(ap1,flags,size);
687
    return ap1;
688
}
689
 
690
/*
691
 *      generate /= and %= nodes.
692
 */
693
AMODE *gen_asmodiv(ENODE *node,int flags,int size,int op)
694
{
695
        AMODE *ap1, *ap2, *ap3;
696
    int             siz1;
697
 
698
    siz1 = GetNaturalSize(node->p[0]);
699
    ap1 = GetTempRegister();
700
    ap2 = GenerateExpression(node->p[0],F_ALL & ~F_IMMED,siz1);
701
        if (ap2->mode==am_reg && ap2->preg != ap1->preg)
702
                GenerateTriadic(op_or,0,ap1,ap2,makereg(0));
703
        else {
704
                switch(siz1) {
705
                case 1: GenerateDiadic(op_lb,0,ap1,ap2); break;
706
                case 2: GenerateDiadic(op_lc,0,ap1,ap2); break;
707
                case 4: GenerateDiadic(op_lh,0,ap1,ap2); break;
708
                case 8: GenerateDiadic(op_lw,0,ap1,ap2); break;
709
                }
710
        }
711
    GenerateSignExtend(ap1,siz1,8,flags);
712
    ap3 = GenerateExpression(node->p[1],F_REG,2);
713
    GenerateTriadic(op,0,ap1,ap1,ap3);
714
    ReleaseTempRegister(ap3);
715
    //GenerateDiadic(op_ext,0,ap1,0);
716
        if (ap2->mode==am_reg)
717
                GenerateTriadic(op_or,0,ap2,ap1,makereg(0));
718
        else
719
                switch(siz1) {
720
                        case 1: GenerateDiadic(op_sb,0,ap1,ap2); break;
721
                        case 2: GenerateDiadic(op_sc,0,ap1,ap2); break;
722
                        case 4: GenerateDiadic(op_sh,0,ap1,ap2); break;
723
                        case 8: GenerateDiadic(op_sw,0,ap1,ap2); break;
724
                }
725
    ReleaseTempRegister(ap2);
726
    MakeLegalAmode(ap1,flags,size);
727
    return ap1;
728
}
729
 
730
/*
731
 *      generate code for an assignment node. if the size of the
732
 *      assignment destination is larger than the size passed then
733
 *      everything below this node will be evaluated with the
734
 *      assignment size.
735
 */
736
AMODE *GenerateAssign(ENODE *node, int flags, int size)
737
{       struct amode    *ap1, *ap2 ,*ap3;
738
        int             ssize;
739
                ENODE *ep;
740
    if (node->p[0]->nodetype == en_uwfieldref ||
741
                node->p[0]->nodetype == en_wfieldref ||
742
                node->p[0]->nodetype == en_uhfieldref ||
743
                node->p[0]->nodetype == en_hfieldref ||
744
                node->p[0]->nodetype == en_ucfieldref ||
745
                node->p[0]->nodetype == en_cfieldref ||
746
                node->p[0]->nodetype == en_ubfieldref ||
747
                node->p[0]->nodetype == en_bfieldref) {
748
                long            mask;
749
                int             i;
750
                /*
751
                * Field assignment
752
                */
753
                /* get the value */
754
                ap1 = GenerateExpression(node->p[1], F_REG | F_VOL,8);
755
                i = node->p[0]->bit_width;
756
                for (mask = 0; i--; mask = mask + mask + 1);
757
                GenerateDiadic(op_and, 0, make_immed(mask), ap1);
758
                mask <<= node->p[0]->bit_offset;
759
                if (!(flags & F_NOVALUE)) {
760
                        /*
761
                        * result value needed
762
                        */
763
                        ap3 = GetTempRegister();
764
                        GenerateTriadic(op_or, 0, ap3, ap1, makereg(0));
765
                } else
766
            ap3 = ap1;
767
                if (node->p[0]->bit_offset > 0) {
768
                        if (node->p[0]->bit_offset < 9) {
769
                                GenerateTriadic(op_shl, 0, ap3,ap3,make_immed((long) node->p[0]->bit_offset));
770
                        }
771
                        else {
772
                                ap2 = GetTempRegister();
773
                                GenerateTriadic(op_ori, 0, ap2,makereg(0),make_immed((long) node->p[0]->bit_offset));
774
                                GenerateTriadic(op_shl, 0, ap3, ap3, ap2);
775
                                ReleaseTempRegister(ap2);
776
                        }
777
                }
778
                ep = makenode(en_w_ref, node->p[0]->p[0], NULL);
779
                ap2 = GenerateExpression(ep, F_MEM,8);
780
                //ap2 = GenerateExpression(node->v.p[0],F_ALL,4);
781
                GenerateTriadic(op_andi, 0, ap2,ap2,make_immed(~mask));
782
                GenerateTriadic(op_or, 0, ap2, ap2, ap3);
783
                ReleaseTempRegister(ap2);
784
                if (!(flags & F_NOVALUE)) {
785
                        ReleaseTempRegister(ap3);
786
                }
787
                MakeLegalAmode(ap1, flags, size);
788
                return ap1;
789
    }
790
 
791
        ssize = GetReferenceSize(node->p[0]);
792
        if( ssize > size )
793
                        size = ssize;
794
        ap2 = GenerateExpression(node->p[1],F_REG,size);
795
        ap1 = GenerateExpression(node->p[0],F_ALL,ssize);
796
        if (ap1->mode == am_reg) {
797
                GenerateDiadic(op_mov,0,ap1,ap2);
798
        }
799
        else {
800
                switch(size) {
801
                case 1: GenerateDiadic(op_sb,0,ap2,ap1); break;
802
                case 2: GenerateDiadic(op_sc,0,ap2,ap1); break;
803
                case 4: GenerateDiadic(op_sh,0,ap2,ap1); break;
804
                case 8: GenerateDiadic(op_sw,0,ap2,ap1); break;
805
                }
806
        }
807
        ReleaseTempRegister(ap1);
808
        return ap2;
809
}
810
 
811
/*
812
 *      generate an auto increment or decrement node. op should be
813
 *      either op_add (for increment) or op_sub (for decrement).
814
 */
815
AMODE *GenerateAutoIncrement(ENODE *node,int flags,int size,int op)
816
{
817
        AMODE *ap1, *ap2;
818
    int siz1;
819
 
820
    siz1 = GetNaturalSize(node->p[0]);
821
    if( flags & F_NOVALUE )         /* dont need result */
822
            {
823
            ap1 = GenerateExpression(node->p[0],F_ALL,siz1);
824
                        switch(op) {
825
                        case op_addu:   op = op_addui; break;
826
                        case op_add:    op = op_addui; break;
827
                        case op_subu:   op = op_subui; break;
828
                        case op_sub:    op = op_subui; break;
829
                        }
830
                        if (ap1->mode != am_reg) {
831
                                ap2 = GetTempRegister();
832
                                switch(size) {
833
                                case 1: GenerateTriadic(op_lb,0,ap2,ap1,NULL); break;
834
                                case 2: GenerateTriadic(op_lc,0,ap2,ap1,NULL); break;
835
                                case 4: GenerateTriadic(op_lh,0,ap2,ap1,NULL); break;
836
                                case 8: GenerateTriadic(op_lw,0,ap2,ap1,NULL); break;
837
                                }
838
                    GenerateTriadic(op,0,ap2,ap2,make_immed(node->i));
839
                                switch(size) {
840
                                case 1: GenerateTriadic(op_sb,0,ap2,ap1,NULL); break;
841
                                case 2: GenerateTriadic(op_sc,0,ap2,ap1,NULL); break;
842
                                case 4: GenerateTriadic(op_sh,0,ap2,ap1,NULL); break;
843
                                case 8: GenerateTriadic(op_sw,0,ap2,ap1,NULL); break;
844
                                }
845
                                ReleaseTempRegister(ap2);
846
                        }
847
                        else
848
                                GenerateTriadic(op,0,ap1,ap1,make_immed(node->i));
849
            ReleaseTempRegister(ap1);
850
            return ap1;
851
            }
852
    ap2 = GenerateExpression(node->p[0],F_ALL,siz1);
853
        if (ap2->mode == am_reg) {
854
            GenerateTriadic(op,0,ap2,ap2,make_immed(node->i));
855
                return ap2;
856
        }
857
        else {
858
            ap1 = GetTempRegister();
859
                switch(siz1) {
860
                case 1: GenerateDiadic(op_lb,0,ap1,ap2); break;
861
                case 2: GenerateDiadic(op_lc,0,ap1,ap2); break;
862
                case 4: GenerateDiadic(op_lh,0,ap1,ap2); break;
863
                case 8: GenerateDiadic(op_lw,0,ap1,ap2); break;
864
                }
865
                switch(op) {
866
                case op_addu:   op = op_addui; break;
867
                case op_add:    op = op_addui; break;
868
                case op_subu:   op = op_subui; break;
869
                case op_sub:    op = op_subui; break;
870
                }
871
                GenerateTriadic(op,0,ap1,ap1,make_immed(node->i));
872
                switch(siz1) {
873
                case 1: GenerateDiadic(op_sb,0,ap1,ap2); break;
874
                case 2: GenerateDiadic(op_sc,0,ap1,ap2); break;
875
                case 4: GenerateDiadic(op_sh,0,ap1,ap2); break;
876
                case 8: GenerateDiadic(op_sw,0,ap1,ap2); break;
877
                }
878
        }
879
    ReleaseTempRegister(ap2);
880
    GenerateSignExtend(ap1,siz1,size,flags);
881
    return ap1;
882
}
883
 
884
/*
885
 *      general expression evaluation. returns the addressing mode
886
 *      of the result.
887
 */
888
AMODE *GenerateExpression(ENODE *node, int flags, int size)
889
{
890
        AMODE *ap1, *ap2;
891
    int lab0, lab1;
892
    int natsize;
893
 
894
    if( node == NULL )
895
    {
896
        printf("DIAG - null node in GenerateExpression.\n");
897
        return NULL;
898
    }
899
    switch( node->nodetype )
900
            {
901
            case en_icon:
902
            case en_labcon:
903
            case en_nacon:
904
                    ap1 = allocAmode();
905
                    ap1->mode = am_immed;
906
                    ap1->offset = node;
907
                    MakeLegalAmode(ap1,flags,size);
908
                    return ap1;
909
            case en_autocon:
910
                    ap1 = GetTempRegister();
911
                    ap2 = allocAmode();
912
                    ap2->mode = am_indx;
913
                    ap2->preg = 27;          /* frame pointer */
914
                    ap2->offset = node;     /* use as constant node */
915
                    GenerateDiadic(op_lea,0,ap1,ap2);
916
                    MakeLegalAmode(ap1,flags,size);
917
                    return ap1;             /* return reg */
918
            case en_b_ref:
919
                        case en_c_ref:
920
                        case en_h_ref:
921
            case en_ub_ref:
922
                        case en_uc_ref:
923
                        case en_uh_ref:
924
            case en_w_ref:
925
                        case en_uw_ref:
926
                    return GenerateDereference(node,flags,size);
927
                        case en_uwfieldref:
928
                        case en_wfieldref:
929
                        case en_bfieldref:
930
                        case en_ubfieldref:
931
                        case en_cfieldref:
932
                        case en_ucfieldref:
933
                        case en_hfieldref:
934
                        case en_uhfieldref:
935
                                        return GenerateBitfieldDereference(node,flags,size);
936
                        case en_regvar:
937
            case en_tempref:
938
                    ap1 = xalloc(sizeof(struct amode));
939
                    ap1->mode = am_reg;
940
                    ap1->preg = node->i;
941
                    ap1->tempflag = 0;      /* not a temporary */
942
                    MakeLegalAmode(ap1,flags,size);
943
                    return ap1;
944
            case en_uminus: return GenerateUnary(node,flags,size,op_neg);
945
            case en_compl:  return GenerateUnary(node,flags,size,op_not);
946
            case en_add:    return GenerateBinary(node,flags,size,op_add);
947
            case en_sub:    return GenerateBinary(node,flags,size,op_sub);
948
            case en_and:    return GenerateBinary(node,flags,size,op_and);
949
            case en_or:     return GenerateBinary(node,flags,size,op_or);
950
                        case en_xor:    return GenerateBinary(node,flags,size,op_xor);
951
            case en_mul:    return GenerateMultiply(node,flags,size,op_muls);
952
            case en_mulu:   return GenerateMultiply(node,flags,size,op_mulu);
953
            case en_div:    return GenerateModDiv(node,flags,size,op_divs);
954
            case en_udiv:   return GenerateModDiv(node,flags,size,op_divu);
955
            case en_mod:    return GenerateModDiv(node,flags,size,op_mod);
956
            case en_umod:   return GenerateModDiv(node,flags,size,op_modu);
957
            case en_shl:    return GenerateShift(node,flags,size,op_shl);
958
            case en_shr:        return GenerateShift(node,flags,size,op_shr);
959
            case en_shru:   return GenerateShift(node,flags,size,op_shru);
960
            case en_asadd:  return GenerateAssignAdd(node,flags,size,op_add);
961
            case en_assub:  return GenerateAssignAdd(node,flags,size,op_sub);
962
            case en_asand:  return GenerateAssignLogic(node,flags,size,op_and);
963
            case en_asor:   return GenerateAssignLogic(node,flags,size,op_or);
964
                        case en_asxor:  return GenerateAssignLogic(node,flags,size,op_xor);
965
            case en_aslsh:
966
                    return GenerateAssignShift(node,flags,size,op_shl);
967
            case en_asrsh:
968
                    return GenerateAssignShift(node,flags,size,op_shr);
969
            case en_asmul: return GenerateAssignMultiply(node,flags,size,op_muls);
970
            case en_asmulu: return GenerateAssignMultiply(node,flags,size,op_mulu);
971
            case en_asdiv:
972
                    return gen_asmodiv(node,flags,size,op_divs);
973
            case en_asmod:
974
                    return gen_asmodiv(node,flags,size,op_muls);
975
            case en_assign:
976
                    return GenerateAssign(node,flags,size);
977
            case en_ainc:
978
                    return GenerateAutoIncrement(node,flags,size,op_add);
979
            case en_adec:
980
                    return GenerateAutoIncrement(node,flags,size,op_sub);
981
            case en_land:   case en_lor:
982
            case en_eq:     case en_ne:
983
            case en_lt:     case en_le:
984
            case en_gt:     case en_ge:
985
            case en_ult:    case en_ule:
986
            case en_ugt:    case en_uge:
987
            case en_not:
988
                    lab0 = nextlabel++;
989
                    lab1 = nextlabel++;
990
                    GenerateFalseJump(node,lab0);
991
                    ap1 = GetTempRegister();
992
                    GenerateTriadic(op_ori,0,ap1,makereg(0),make_immed(1));
993
                    GenerateTriadic(op_bra,0,make_label(lab1),NULL,NULL);
994
                    GenerateLabel(lab0);
995
                    GenerateTriadic(op_ori,0,ap1,makereg(0),make_immed(0));
996
                    GenerateLabel(lab1);
997
                    return ap1;
998
            case en_cond:
999
                    return gen_hook(node,flags,size);
1000
            case en_void:
1001
                    natsize = GetNaturalSize(node->p[0]);
1002
                    ReleaseTempRegister(GenerateExpression(node->p[0],F_ALL | F_NOVALUE,natsize));
1003
                    return GenerateExpression(node->p[1],flags,size);
1004
            case en_fcall:
1005
                    return GenerateFunctionCall(node,flags);
1006
            default:
1007
                    printf("DIAG - uncoded node in GenerateExpression.\n");
1008
                    return 0;
1009
            }
1010
}
1011
 
1012
/*
1013
 *      return the natural evaluation size of a node.
1014
 */
1015
int GetNaturalSize(ENODE *node)
1016
{
1017
        int     siz0, siz1;
1018
    if( node == NULL )
1019
            return 0;
1020
    switch( node->nodetype )
1021
        {
1022
                case en_uwfieldref:
1023
                case en_wfieldref:
1024
                        return 8;
1025
                case en_bfieldref:
1026
                case en_ubfieldref:
1027
                        return 1;
1028
                case en_cfieldref:
1029
                case en_ucfieldref:
1030
                        return 2;
1031
                case en_hfieldref:
1032
                case en_uhfieldref:
1033
                        return 4;
1034
        case en_icon:
1035
                if( -128 <= node->i && node->i <= 127 )
1036
                        return 1;
1037
                if( -32768 <= node->i && node->i <= 32767 )
1038
                        return 2;
1039
                                if (-2147483648L <= node->i && node->i <= 2147483647L)
1040
                                        return 4;
1041
                                return 8;
1042
        case en_fcall:  case en_labcon:
1043
        case en_nacon:  case en_autocon:
1044
                case en_tempref:
1045
                case en_regvar:
1046
        case en_cbw:
1047
                case en_ccw:
1048
                case en_chw:
1049
                return 8;
1050
                case en_b_ref:
1051
                case en_ub_ref:
1052
                return 1;
1053
        case en_cbc:
1054
                case en_c_ref:  return 2;
1055
                case en_uc_ref: return 2;
1056
                case en_cbh:    return 4;
1057
                case en_cch:    return 4;
1058
                case en_h_ref:  return 4;
1059
                case en_uh_ref: return 4;
1060
                case en_w_ref:  case en_uw_ref:
1061
                return 8;
1062
        case en_not:    case en_compl:
1063
        case en_uminus: case en_assign:
1064
        case en_ainc:   case en_adec:
1065
                return GetNaturalSize(node->p[0]);
1066
        case en_add:    case en_sub:
1067
        case en_mul:    case en_div:
1068
        case en_mod:    case en_and:
1069
        case en_or:     case en_xor:
1070
        case en_shl:    case en_shr:    case en_shru:
1071
        case en_eq:     case en_ne:
1072
        case en_lt:     case en_le:
1073
        case en_gt:     case en_ge:
1074
                case en_ult:    case en_ule:
1075
                case en_ugt:    case en_uge:
1076
        case en_land:   case en_lor:
1077
        case en_asadd:  case en_assub:
1078
        case en_asmul:  case en_asdiv:
1079
        case en_asmod:  case en_asand:
1080
                case en_asor:   case en_asxor:  case en_aslsh:
1081
        case en_asrsh:
1082
                siz0 = GetNaturalSize(node->p[0]);
1083
                siz1 = GetNaturalSize(node->p[1]);
1084
                if( siz1 > siz0 )
1085
                    return siz1;
1086
                else
1087
                    return siz0;
1088
        case en_void:   case en_cond:
1089
                return GetNaturalSize(node->p[1]);
1090
        default:
1091
                printf("DIAG - natural size error %d.\n", node->nodetype);
1092
                break;
1093
        }
1094
    return 0;
1095
}
1096
 
1097
 
1098
void gen_b(ENODE *node, int op, int label)
1099
{
1100
        int size;
1101
        struct amode *ap1, *ap2;
1102
 
1103
        size = GetNaturalSize(node);
1104
        ap1 = GenerateExpression(node->p[0],F_REG, size);
1105
        ap2 = GenerateExpression(node->p[1],F_REG|F_IMMED18,size);
1106
    GenerateTriadic(op,0,ap1,ap2,make_label(label));
1107
        ReleaseTempRegister(ap2);
1108
        ReleaseTempRegister(ap1);
1109
}
1110
/*
1111
 *      generate a jump to label if the node passed evaluates to
1112
 *      a true condition.
1113
 */
1114
void GenerateTrueJump(ENODE *node, int label)
1115
{       AMODE  *ap1,*ap2;
1116
        int             siz1;
1117
        int             lab0;
1118
                int size;
1119
        if( node == 0 )
1120
                return;
1121
        switch( node->nodetype )
1122
                {
1123
                case en_eq:     gen_b(node, op_beq, label); break;
1124
                case en_ne: gen_b(node, op_bne, label); break;
1125
                case en_lt: gen_b(node, op_blt, label); break;
1126
                case en_le:     gen_b(node, op_ble, label); break;
1127
                case en_gt: gen_b(node, op_bgt, label); break;
1128
                case en_ge: gen_b(node, op_bge, label); break;
1129
                case en_ult: gen_b(node, op_bltu, label); break;
1130
                case en_ule: gen_b(node, op_bleu, label); break;
1131
                case en_ugt: gen_b(node, op_bgtu, label); break;
1132
                case en_uge: gen_b(node, op_bgeu, label); break;
1133
                case en_land:
1134
                        lab0 = nextlabel++;
1135
                        GenerateFalseJump(node->p[0],lab0);
1136
                        GenerateTrueJump(node->p[1],label);
1137
                        GenerateLabel(lab0);
1138
                        break;
1139
                case en_lor:
1140
                        GenerateTrueJump(node->p[0],label);
1141
                        GenerateTrueJump(node->p[1],label);
1142
                        break;
1143
                case en_not:
1144
                        GenerateFalseJump(node->p[0],label);
1145
                        break;
1146
                default:
1147
                        siz1 = GetNaturalSize(node);
1148
                        ap1 = GenerateExpression(node,F_REG,siz1);
1149
//                        GenerateDiadic(op_tst,siz1,ap1,0);
1150
                        ReleaseTempRegister(ap1);
1151
                        GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(label));
1152
                        break;
1153
                }
1154
}
1155
 
1156
/*
1157
 *      generate code to execute a jump to label if the expression
1158
 *      passed is false.
1159
 */
1160
void GenerateFalseJump(ENODE *node,int label)
1161
{
1162
        AMODE *ap,*ap1,*ap2;
1163
                int size;
1164
        int             siz1;
1165
        int             lab0;
1166
        if( node == NULL )
1167
                return;
1168
        switch( node->nodetype )
1169
                {
1170
                case en_eq:     gen_b(node, op_bne, label); break;
1171
                case en_ne: gen_b(node, op_beq, label); break;
1172
                case en_lt: gen_b(node, op_bge, label); break;
1173
                case en_le: gen_b(node, op_bgt, label); break;
1174
                case en_gt: gen_b(node, op_ble, label); break;
1175
                case en_ge: gen_b(node, op_blt, label); break;
1176
                case en_ult: gen_b(node, op_bgeu, label); break;
1177
                case en_ule: gen_b(node, op_bgtu, label); break;
1178
                case en_ugt: gen_b(node, op_bleu, label); break;
1179
                case en_uge: gen_b(node, op_bltu, label); break;
1180
                case en_land:
1181
                        GenerateFalseJump(node->p[0],label);
1182
                        GenerateFalseJump(node->p[1],label);
1183
                        break;
1184
                case en_lor:
1185
                        lab0 = nextlabel++;
1186
                        GenerateTrueJump(node->p[0],lab0);
1187
                        GenerateFalseJump(node->p[1],label);
1188
                        GenerateLabel(lab0);
1189
                        break;
1190
                case en_not:
1191
                        GenerateTrueJump(node->p[0],label);
1192
                        break;
1193
                default:
1194
                        siz1 = GetNaturalSize(node);
1195
                        ap = GenerateExpression(node,F_REG,siz1);
1196
//                        GenerateDiadic(op_tst,siz1,ap,0);
1197
                        ReleaseTempRegister(ap);
1198
                        GenerateTriadic(op_beq,0,ap,makereg(0),make_label(label));
1199
                        break;
1200
                }
1201
}

powered by: WebSVN 2.1.0

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