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

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [GenerateStatement.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
        Modified to support Raptor64 'C64' language
27
        by Robert Finch
28
        robfinch@opencores.org
29
*******************************************************/
30
 
31
int     breaklab;
32
int     contlab;
33
int     retlab;
34
int             throwlab;
35
 
36
int lastsph;
37
char *semaphores[20];
38
 
39
extern TYP              stdfunc;
40
 
41
 
42
int bitsset(int mask)
43
{
44
        int nn,bs=0;
45
        for (nn =0; nn < 32; nn++)
46
                if (mask & (1 << nn)) bs++;
47
        return bs;
48
}
49
 
50
AMODE *makereg(int r)
51
{
52
        AMODE *ap;
53
    ap = allocAmode();
54
    ap->mode = am_reg;
55
    ap->preg = r;
56
    return ap;
57
}
58
 
59
/*
60
 *      generate the mask address structure.
61
 */
62
AMODE *make_mask(int mask)
63
{
64
        AMODE *ap;
65
    ap = allocAmode();
66
    ap->mode = am_mask;
67
    ap->offset = mask;
68
    return ap;
69
}
70
 
71
/*
72
 *      make a direct reference to an immediate value.
73
 */
74
AMODE *make_direct(__int64 i)
75
{
76
        return make_offset(makeinode(en_icon,i,0));
77
}
78
 
79
/*
80
 *      generate a direct reference to a string label.
81
 */
82
AMODE *make_strlab(char *s)
83
{
84
        AMODE *ap;
85
    ap = allocAmode();
86
    ap->mode = am_direct;
87
    ap->offset = makesnode(en_nacon,s);
88
    return ap;
89
}
90
 
91
/*
92
 *      generate code to evaluate a while statement.
93
 */
94
void GenerateWhile(struct snode *stmt)
95
{
96
        int lab1, lab2;
97
 
98
    initstack();            /* initialize temp registers */
99
    lab1 = contlab;         /* save old continue label */
100
    lab2 = breaklab;        /* save old break label */
101
    contlab = nextlabel++;  /* new continue label */
102
    GenerateLabel(contlab);
103
    if( stmt->s1 != NULL )      /* has block */
104
    {
105
                breaklab = nextlabel++;
106
                initstack();
107
                GenerateFalseJump(stmt->exp,breaklab);
108
                GenerateStatement(stmt->s1);
109
                GenerateDiadic(op_bra,0,make_label(contlab),NULL);
110
                GenerateLabel(breaklab);
111
                breaklab = lab2;        /* restore old break label */
112
    }
113
    else                                                /* no loop code */
114
    {
115
                initstack();
116
                GenerateTrueJump(stmt->exp,contlab);
117
    }
118
    contlab = lab1;         /* restore old continue label */
119
}
120
 
121
/*
122
 *      generate code to evaluate an until statement.
123
 */
124
void GenerateUntil(Statement *stmt)
125
{
126
        int lab1, lab2;
127
 
128
        initstack();            /* initialize temp registers */
129
        lab1 = contlab;         /* save old continue label */
130
        lab2 = breaklab;        /* save old break label */
131
        contlab = nextlabel++;  /* new continue label */
132
        GenerateLabel(contlab);
133
        if( stmt->s1 != NULL )      /* has block */
134
                {
135
                breaklab = nextlabel++;
136
                initstack();
137
                GenerateTrueJump(stmt->exp,breaklab);
138
                GenerateStatement(stmt->s1);
139
                GenerateDiadic(op_bra,0,make_label(contlab),NULL);
140
                GenerateLabel(breaklab);
141
                breaklab = lab2;        /* restore old break label */
142
                }
143
        else                                            /* no loop code */
144
                {
145
                initstack();
146
                GenerateFalseJump(stmt->exp,contlab);
147
                }
148
        contlab = lab1;         /* restore old continue label */
149
}
150
 
151
 
152
//      generate code to evaluate a for loop
153
//
154
void GenerateFor(struct snode *stmt)
155
{
156
        int     old_break, old_cont, exit_label, loop_label;
157
    old_break = breaklab;
158
    old_cont = contlab;
159
    loop_label = nextlabel++;
160
    exit_label = nextlabel++;
161
    contlab = loop_label;
162
    initstack();
163
    if( stmt->initExpr != NULL )
164
            GenerateExpression(stmt->initExpr,F_ALL | F_NOVALUE
165
                    ,GetNaturalSize(stmt->initExpr));
166
    GenerateLabel(loop_label);
167
    initstack();
168
    if( stmt->exp != NULL )
169
            GenerateFalseJump(stmt->exp,exit_label);
170
    if( stmt->s1 != NULL )
171
        {
172
            breaklab = exit_label;
173
            GenerateStatement(stmt->s1);
174
        }
175
    initstack();
176
    if( stmt->incrExpr != NULL )
177
            GenerateExpression(stmt->incrExpr,F_ALL | F_NOVALUE,GetNaturalSize(stmt->incrExpr));
178
    GenerateTriadic(op_bra,0,make_label(loop_label),NULL,NULL);
179
    breaklab = old_break;
180
    contlab = old_cont;
181
    GenerateLabel(exit_label);
182
}
183
 
184
 
185
//     generate code to evaluate a forever loop
186
//
187
void GenerateForever(Statement *stmt)
188
{
189
        int old_break, old_cont, exit_label, loop_label;
190
    old_break = breaklab;
191
    old_cont = contlab;
192
    loop_label = nextlabel++;
193
    exit_label = nextlabel++;
194
    contlab = loop_label;
195
    GenerateLabel(loop_label);
196
    if( stmt->s1 != NULL )
197
        {
198
        breaklab = exit_label;
199
        GenerateStatement(stmt->s1);
200
        }
201
    GenerateDiadic(op_bra,0,make_label(loop_label),NULL);
202
    breaklab = old_break;
203
    contlab = old_cont;
204
    GenerateLabel(exit_label);
205
}
206
 
207
/*
208
 *      generate code to evaluate an if statement.
209
 */
210
void GenerateIf(struct snode *stmt)
211
{       int     lab1, lab2, oldbreak;
212
        lab1 = nextlabel++;     /* else label */
213
        lab2 = nextlabel++;     /* exit label */
214
        oldbreak = breaklab;    /* save break label */
215
        initstack();            /* clear temps */
216
        GenerateFalseJump(stmt->exp,lab1);
217
        if( stmt->s1 != 0 && stmt->s1->next != 0 )
218
                if( stmt->s2 != 0 )
219
                        breaklab = lab2;
220
                else
221
                        breaklab = lab1;
222
        GenerateStatement(stmt->s1);
223
        if( stmt->s2 != 0 )             /* else part exists */
224
                {
225
                GenerateDiadic(op_bra,0,make_label(lab2),0);
226
                GenerateLabel(lab1);
227
                if( stmt->s2 == 0 || stmt->s2->next == 0 )
228
                        breaklab = oldbreak;
229
                else
230
                        breaklab = lab2;
231
                GenerateStatement(stmt->s2);
232
                GenerateLabel(lab2);
233
                }
234
        else                            /* no else code */
235
                GenerateLabel(lab1);
236
        breaklab = oldbreak;
237
}
238
 
239
/*
240
 *      generate code for a do - while loop.
241
 */
242
void GenerateDo(struct snode *stmt)
243
{
244
        int     oldcont, oldbreak;
245
    oldcont = contlab;
246
    oldbreak = breaklab;
247
    contlab = nextlabel++;
248
    GenerateLabel(contlab);
249
    if( stmt->s1 != 0 && stmt->s1->next != 0 )
250
            {
251
            breaklab = nextlabel++;
252
            GenerateStatement(stmt->s1);      /* generate body */
253
            initstack();
254
            GenerateTrueJump(stmt->exp,contlab);
255
            GenerateLabel(breaklab);
256
            }
257
    else
258
            {
259
            GenerateStatement(stmt->s1);
260
            initstack();
261
            GenerateTrueJump(stmt->exp,contlab);
262
            }
263
    breaklab = oldbreak;
264
    contlab = oldcont;
265
}
266
 
267
/*
268
 *      generate code for a do - while loop.
269
 */
270
void GenerateDoUntil(struct snode *stmt)
271
{
272
        int     oldcont, oldbreak;
273
    oldcont = contlab;
274
    oldbreak = breaklab;
275
    contlab = nextlabel++;
276
    GenerateLabel(contlab);
277
    if( stmt->s1 != 0 && stmt->s1->next != 0 )
278
    {
279
        breaklab = nextlabel++;
280
        GenerateStatement(stmt->s1);      /* generate body */
281
        initstack();
282
        GenerateFalseJump(stmt->exp,contlab);
283
        GenerateLabel(breaklab);
284
    }
285
    else
286
    {
287
        GenerateStatement(stmt->s1);
288
        initstack();
289
        GenerateFalseJump(stmt->exp,contlab);
290
    }
291
    breaklab = oldbreak;
292
    contlab = oldcont;
293
}
294
 
295
/*
296
 *      generate a call to a library routine.
297
 */
298
void call_library(char *lib_name)
299
{
300
        SYM     *sp;
301
    sp = gsearch(lib_name);
302
    if( sp == NULL )
303
    {
304
                ++global_flag;
305
                sp = allocSYM();
306
                sp->tp = &stdfunc;
307
                sp->name = lib_name;
308
                sp->storage_class = sc_external;
309
                insert(sp,&gsyms);
310
                --global_flag;
311
    }
312
    GenerateDiadic(op_call,0,make_strlab(lib_name),NULL);
313
}
314
 
315
/*
316
 *      generate a linear search switch statement.
317
 */
318
void GenerateSwitch(Statement *stmt)
319
{
320
        int             curlab;
321
        int *bf;
322
        int nn;
323
        struct snode    *defcase;
324
        struct amode    *ap;
325
        curlab = nextlabel++;
326
        defcase = 0;
327
        initstack();
328
        ap = GenerateExpression(stmt->exp,F_REG,4);
329
        if( ap->preg != 0 )
330
                GenerateTriadic(op_or,0,makereg(1),ap,makereg(0));
331
        stmt = stmt->s1;
332
        while( stmt != NULL )
333
        {
334
            if( stmt->s2 )          /* default case ? */
335
            {
336
                                stmt->label = curlab;
337
                                defcase = stmt;
338
            }
339
            else
340
            {
341
                                bf = stmt->label;
342
                                for (nn = bf[0]; nn >= 1; nn--)
343
                                        GenerateTriadic(op_beq,0,makereg(1),make_immed(bf[nn]),make_label(curlab));
344
                        //GenerateDiadic(op_dw,0,make_label(curlab), make_direct(stmt->label));
345
                    stmt->label = curlab;
346
            }
347
            if( stmt->s1 != NULL && stmt->next != NULL )
348
                curlab = nextlabel++;
349
            stmt = stmt->next;
350
        }
351
        if( defcase == NULL )
352
            GenerateTriadic(op_bra,0,make_label(breaklab),NULL,NULL);
353
        else
354
                        GenerateTriadic(op_bra,0,make_label(defcase->label),NULL,NULL);
355
}
356
 
357
 
358
//      generate all cases for a switch statement.
359
//
360
void GenerateCase(Statement *stmt)
361
{
362
        while( stmt != NULL )
363
    {
364
                if( stmt->s1 != NULL )
365
                {
366
                        GenerateLabel(stmt->label);
367
                        GenerateStatement(stmt->s1);
368
                }
369
                else if( stmt->next == NULL )
370
                        GenerateLabel(stmt->label);
371
                stmt = stmt->next;
372
    }
373
}
374
 
375
/*
376
 *      analyze and generate best switch statement.
377
 */
378
genxswitch(Statement *stmt)
379
{
380
        int     oldbreak;
381
    oldbreak = breaklab;
382
    breaklab = nextlabel++;
383
    GenerateSwitch(stmt);
384
    GenerateCase(stmt->s1);
385
    GenerateLabel(breaklab);
386
    breaklab = oldbreak;
387
}
388
 
389
int popcnt(int m)
390
{
391
        int n;
392
        int cnt;
393
 
394
        cnt =0;
395
        for (n = 0; n < 32; n = n + 1)
396
                if (m & (1 << n)) cnt = cnt + 1;
397
        return cnt;
398
}
399
/*
400
void gen_regsave()
401
{
402
        int lab1;
403
 
404
        lab1 = nextlabel++;
405
        GenerateLabel(lab1);
406
        GenerateDiadic(op_tas,1,make_strlab("sfRunningTCB"),NULL);
407
        GenerateDiadic(op_bmi,0,make_label(lab1),NULL);
408
        GenerateDiadic(op_move,0,makereg(1),make_strlab("a0save"));
409
        GenerateDiadic(op_move,0,make_strlab("RunningTCB"),makereg(1));
410
        GenerateDiadic(op_movem,0,make_strlab("d0-d7/a0-a7"),make_strlab("(a0)"));
411
        GenerateDiadic(op_move,0,make_strlab("a0save"),make_strlab("32(a0)"));
412
        GenerateDiadic(op_move,0,make_strlab("usp"),makereg(1));
413
        GenerateDiadic(op_move,0,makereg(1),make_strlab("64(a0)"));
414
        GenerateDiadic(op_move,0,make_strlab("4(a7)"),make_strlab("68(a0)"));
415
 
416
        //GenerateDiadic(op_move,4,make_string("sr"),make_string("_TCBsrsave"));
417
        //GenerateDiadic(op_movem,4,make_mask(0xFFFF),make_string("_TCBregsave"));
418
        //GenerateDiadic(op_move,4,make_string("usp"),make_string("a0"));
419
        //GenerateDiadic(op_move,4,make_string("a0"),make_string("_TCBuspsave"));
420
}
421
 
422
void gen_regrestore()
423
{
424
        GenerateDiadic(op_move,0,make_strlab("_TCBuspsave"),make_string("a0"));
425
        GenerateDiadic(op_move,0,make_string("a0"),make_string("usp"));
426
        GenerateDiadic(op_movem,0,make_string("_TCBregsave"),make_mask(0xFFFF));
427
        GenerateDiadic(op_move,0,make_string("_TCBsrsave"),make_string("sr"));
428
}
429
*/
430
/*
431
void gen_vortex(struct snode *stmt)
432
{
433
    int lab1;
434
 
435
    lab1 = nextlabel++;
436
    GenerateDiadic(op_bra,0,make_label(lab1),0);
437
    //gen_ilabel(stmt->label);
438
        gen_regsave();
439
        GenerateStatement(stmt->s1);
440
        gen_regrestore();
441
        GenerateDiadic(op_rte,0,0,0);
442
    GenerateLabel(lab1);
443
}
444
*/
445
 
446
void GenerateTry(Statement *stmt)
447
{
448
    int lab1,curlab;
449
        int oldthrow;
450
        char buf[20];
451
        AMODE *ap;
452
        SYM *sym;
453
 
454
    lab1 = nextlabel++;
455
        oldthrow = throwlab;
456
        throwlab = nextlabel++;
457
 
458
        GenerateDiadic(op_lea,0,makereg(28),make_label(throwlab));
459
        GenerateStatement(stmt->s1);
460
    GenerateDiadic(op_bra,0,make_label(lab1),NULL);
461
        GenerateLabel(throwlab);
462
        stmt = stmt->s2;
463
        while (stmt) {
464
                throwlab = oldthrow;
465
                curlab = nextlabel++;
466
                GenerateLabel(curlab);
467
                if (stmt->s2==99999)
468
                        ;
469
                else
470
                        GenerateTriadic(op_bnei,0,makereg(2),make_immed((int)stmt->s2),make_label(nextlabel));
471
                // move the throw expression result in 'r1' into the catch variable.
472
                sym = (SYM *)stmt->label;
473
                if (sym) {
474
                        switch(sym->tp->size) {
475
                        case 1: GenerateDiadic(op_sb,0,makereg(1),make_indexed(sym->value.i,27));
476
                        case 2: GenerateDiadic(op_sc,0,makereg(1),make_indexed(sym->value.i,27));
477
                        case 4: GenerateDiadic(op_sh,0,makereg(1),make_indexed(sym->value.i,27));
478
                        case 8: GenerateDiadic(op_sw,0,makereg(1),make_indexed(sym->value.i,27));
479
                        }
480
                }
481
                GenerateStatement(stmt->s1);
482
                stmt=stmt->next;
483
        }
484
    GenerateLabel(lab1);
485
        GenerateDiadic(op_lea,0,makereg(28),make_label(oldthrow));
486
}
487
 
488
void GenerateThrow(Statement *stmt)
489
{
490
        AMODE *ap;
491
 
492
    if( stmt != NULL && stmt->exp != NULL )
493
        {
494
                initstack();
495
                ap = GenerateExpression(stmt->exp,F_ALL,8);
496
                if (ap->mode==am_immed)
497
                        GenerateTriadic(op_ori,0,makereg(1),makereg(0),ap);
498
                else if( ap->mode != am_reg)
499
                        GenerateDiadic(op_lw,0,makereg(1),ap);
500
                else if (ap->preg != 1 )
501
                        GenerateTriadic(op_or,0,makereg(1),ap,makereg(0));
502
                ReleaseTempRegister(ap);
503
                GenerateTriadic(op_ori,0,makereg(2),makereg(0),make_immed((int)stmt->label));
504
        }
505
        GenerateDiadic(op_bra,0,make_label(throwlab),NULL);
506
}
507
/*
508
void GenerateCritical(struct snode *stmt)
509
{
510
        int lab1;
511
 
512
        lab1 = nextlabel++;
513
        semaphores[lastsph] = stmt->label;
514
        lastsph++;
515
    GenerateLabel(lab1);
516
        GenerateDiadic(op_tas,0,make_string(stmt->label),NULL);
517
        GenerateDiadic(op_bmi,0,make_label(lab1),NULL);
518
        GenerateStatement(stmt->s1);
519
        --lastsph;
520
        semaphores[lastsph] = NULL;
521
        GenerateDiadic(op_move,0,make_immed(0),make_string(stmt->label));
522
}
523
*/
524
 
525
void GenerateSpinlock(Statement *stmt)
526
{
527
        int lab1, lab2, lab3, lab4;
528
        AMODE *ap1, *ap2;
529 51 robfinch
        AMODE *ap;
530 37 robfinch
 
531
        lab1 = nextlabel++;
532 51 robfinch
        lab2 = nextlabel++;
533
        lab3 = nextlabel++;
534
 
535
    if( stmt != NULL && stmt->exp != NULL )
536
        {
537
                initstack();
538
                ap1 = GetTempRegister();
539
                ap2 = GetTempRegister();
540
                ap = GenerateExpression(stmt->exp,F_REG,8);
541
                if (stmt->initExpr)
542
                        GenerateTriadic(op_ori, 0, ap1,makereg(0),make_immed(stmt->initExpr));
543 37 robfinch
                GenerateLabel(lab1);
544 51 robfinch
                if (stmt->initExpr) {
545
                        GenerateTriadic(op_sub, 0, ap1, ap1, make_immed(1));
546
                        GenerateTriadic(op_beq, 0, ap1, makereg(0), make_label(lab2));
547
                }
548
                GenerateDiadic(op_inbu, 0, ap2, make_indexed(stmt->incrExpr,ap->preg));
549
                GenerateTriadic(op_beq, 0, ap2, makereg(0), make_label(lab1));
550
                ReleaseTempRegister(ap2);
551
                GenerateStatement(stmt->s1);
552
                // unlock
553
                GenerateDiadic(op_outb, 0, makereg(0), make_indexed(stmt->incrExpr,ap->preg));
554
                if (stmt->initExpr) {
555
                        GenerateTriadic(op_bra,0,make_label(lab3),NULL,NULL);
556
                        GenerateLabel(lab2);
557
                        GenerateStatement(stmt->s2);
558
                        GenerateLabel(lab3);
559
                }
560
                else {
561
                        printf("Warning: The lockfail code is unreachable because spinlock tries are infinite.\r\n");
562
                }
563 37 robfinch
        }
564 51 robfinch
 
565
        //ap1 = GetTempRegister();
566
        //ap2 = GetTempRegister();
567
        //if (stmt->exp) {
568
        //      lab2 = nextlabel++;
569
        //      GenerateTriadic(op_ori,0,ap2,makereg(0),make_immed(stmt->exp));
570
        //    GenerateLabel(lab1);
571
        //      GenerateTriadic(op_beq,0,ap2,makereg(0),make_label(lab2));
572
        //      GenerateTriadic(op_subui,0,ap2,ap2,make_immed(1));
573
        //      GenerateTriadic(op_lwr,0,ap1,make_string(stmt->label),NULL);
574
        //      GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(lab1),NULL);
575
        //      GenerateTriadic(op_not,0,ap1,ap1,NULL);
576
        //      GenerateTriadic(op_swc,0,ap1,make_string(stmt->label),NULL);
577
        //      GenerateTriadic(op_bnr,0,make_label(lab1),NULL,NULL);
578
        //}
579
        //else {
580
        //      GenerateLabel(lab1);
581
        //      GenerateTriadic(op_lwr,0,ap1,make_string(stmt->label),NULL);
582
        //      GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(lab1),NULL);
583
        //      GenerateTriadic(op_not,0,ap1,ap1,NULL);
584
        //      GenerateTriadic(op_swc,0,ap1,make_string(stmt->label),NULL);
585
        //      GenerateTriadic(op_bnr,0,make_label(lab1),NULL,NULL);
586
        //}
587
        //ReleaseTempRegister(ap1);
588
        //ReleaseTempRegister(ap2);
589
        //GenerateStatement(stmt->s1);
590
        //GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->label));
591
        //if (stmt->exp) {
592
        //      lab3 = nextlabel++;
593
        //      GenerateTriadic(op_bra,0,make_label(lab3),NULL,NULL);
594
        //      GenerateLabel(lab2);
595
        //      GenerateStatement(stmt->s2);
596
        //      GenerateLabel(lab3);
597
        //}
598
        //else {
599
        //      printf("Warning: The lockfail code is unreachable because spinlock tries are infinite.\r\n");
600
        //}
601 37 robfinch
}
602
 
603
void GenerateSpinUnlock(struct snode *stmt)
604
{
605 51 robfinch
        AMODE *ap;
606
 
607
    if( stmt != NULL && stmt->exp != NULL )
608
        {
609
                initstack();
610
                ap = GenerateExpression(stmt->exp,F_REG|F_IMMED,8);
611
                // Force return value into register 1
612
                if( ap->preg != 1 ) {
613
                        if (ap->mode == am_immed)
614
                                GenerateTriadic(op_ori, 0, makereg(1),makereg(0),ap);
615
                        else
616
                                GenerateDiadic(op_mov, 0, makereg(1),ap);
617
                        GenerateDiadic(op_outb, 0, makereg(0),make_indexed(stmt->incrExpr,1));
618
                }
619
        }
620
 
621
//      GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->label));
622 37 robfinch
}
623
/*
624
 *      genstmt will generate a statement and follow the next pointer
625
 *      until the block is generated.
626
 */
627
void GenerateStatement(struct snode *stmt)
628
{
629
        while( stmt != NULL )
630
    {
631
        switch( stmt->stype )
632
                {
633
                                //case st_vortex:
634
                                //              gen_vortex(stmt);
635
                                //              break;
636
                                case st_try:
637
                                                GenerateTry(stmt);
638
                                                break;
639
                                case st_throw:
640
                                                GenerateThrow(stmt);
641
                                                break;
642
                                case st_intoff:
643
                                                GenerateIntoff(stmt);
644
                                                break;
645
                                case st_stop:
646
                                                GenerateStop(stmt);
647
                                                break;
648
                                case st_inton:
649
                                                GenerateInton(stmt);
650
                                                break;
651
                                case st_asm:
652
                                                GenerateAsm(stmt);
653
                                                break;
654
                case st_label:
655
                        GenerateLabel(stmt->label);
656
                        break;
657
                case st_goto:
658
                        GenerateDiadic(op_bra,0,make_label(stmt->label),0);
659
                        break;
660
                                //case st_critical:
661
    //                    GenerateCritical(stmt);
662
    //                    break;
663
                                case st_spinlock:
664
                                                GenerateSpinlock(stmt);
665
                                                break;
666
                                case st_spinunlock:
667
                                                GenerateSpinUnlock(stmt);
668
                                                break;
669
                case st_expr:
670
                        initstack();
671
                        GenerateExpression(stmt->exp,F_ALL | F_NOVALUE,
672
                                GetNaturalSize(stmt->exp));
673
                        break;
674
                case st_return:
675
                        GenerateReturn(currentFn,stmt);
676
                        break;
677
                case st_if:
678
                        GenerateIf(stmt);
679
                        break;
680
                case st_do:
681
                        GenerateDo(stmt);
682
                        break;
683
                case st_dountil:
684
                        GenerateDoUntil(stmt);
685
                        break;
686
                case st_doloop:
687
                        GenerateForever(stmt);
688
                        break;
689
                case st_while:
690
                        GenerateWhile(stmt);
691
                        break;
692
                case st_until:
693
                        GenerateUntil(stmt);
694
                        break;
695
                case st_for:
696
                        GenerateFor(stmt);
697
                        break;
698
                case st_forever:
699
                        GenerateForever(stmt);
700
                        break;
701
                case st_firstcall:
702
                        GenerateFirstcall(stmt);
703
                        break;
704
                case st_continue:
705
                        GenerateDiadic(op_bra,0,make_label(contlab),0);
706
                        break;
707
                case st_break:
708
                        GenerateDiadic(op_bra,0,make_label(breaklab),0);
709
                        break;
710
                case st_switch:
711
                        genxswitch(stmt);
712
                        break;
713
                default:
714
                        printf("DIAG - unknown statement.\n");
715
                        break;
716
                }
717
        stmt = stmt->next;
718
    }
719
}
720
 
721
void GenerateIntoff(Statement *stmt)
722
{
723
//      GenerateDiadic(op_move,0,make_string("sr"),make_string("_TCBsrsave"));
724
        GenerateDiadic(op_sei,0,NULL,NULL);
725
}
726
 
727
void GenerateInton(Statement *stmt)
728
{
729
//      GenerateDiadic(op_move,0,make_string("_TCBsrsave"),make_string("sr"));
730
}
731
 
732
void GenerateStop(Statement *stmt)
733
{
734
        GenerateDiadic(op_stop,0,make_immed(0),NULL);
735
}
736
 
737
void GenerateAsm(Statement *stmt)
738
{
739
        GenerateTriadic(op_asm,0,make_string(stmt->label),NULL,NULL);
740
}
741
 
742
void GenerateFirstcall(Statement *stmt)
743
{
744
        int     lab1, lab2, lab3,lab4,lab5,lab6,lab7;
745
        char buf[20];
746
        AMODE *ap1,*ap2;
747
 
748
    lab1 = contlab;         /* save old continue label */
749
    lab2 = breaklab;        /* save old break label */
750
    contlab = nextlabel++;  /* new continue label */
751
        lab3 = nextlabel++;
752
        lab4 = nextlabel++;
753
        lab5 = nextlabel++;
754
        lab6 = nextlabel++;
755
        lab7 = nextlabel++;
756
    if( stmt->s1 != NULL )      /* has block */
757
    {
758
        breaklab = nextlabel++;
759
        GenerateLabel(lab3);    // marks address of brf
760
        GenerateDiadic(op_bra,0,make_label(lab7),NULL);  // branch to the firstcall statement
761
        GenerateLabel(lab6);    // prevent optimizer from optimizing move away
762
                GenerateDiadic(op_bra,0,make_label(breaklab),NULL);      // then branch around it
763
        GenerateLabel(lab7);    // prevent optimizer from optimizing move away
764
                ap1 = GetTempRegister();
765
                ap2 = GetTempRegister();
766
                GenerateDiadic(op_lea,0,ap2,make_label(lab3));
767
                GenerateTriadic(op_andi,0,ap2,ap2,make_immed(0x0c));
768
                GenerateTriadic(op_beqi,0,ap2,make_immed(0x08L),make_label(lab4));
769
                GenerateTriadic(op_beqi,0,ap2,make_immed(0x04L),make_label(lab5));
770
                GenerateDiadic(op_lea,0,ap2,make_label(lab3));
771
                GenerateDiadic(op_lw,0,ap1,make_indirect(ap2->preg));
772
                GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xFFFFFC0000000000L));
773
                GenerateTriadic(op_ori,0,ap1,ap1,make_immed(0x000037800000000L));        // nop instruction
774
                GenerateDiadic(op_sw,0,ap1,make_indirect(ap2->preg));
775
                GenerateDiadic(op_cache,0,make_string("invil"),make_indirect(ap2->preg));
776
                GenerateDiadic(op_bra,0,make_label(lab6),NULL);
777
                GenerateLabel(lab4);
778
                GenerateDiadic(op_lea,0,ap2,make_label(lab3));
779
                GenerateDiadic(op_lw,0,ap1,make_indirect(ap2->preg));
780
                GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0x00000000000FFFFFL));
781
                GenerateTriadic(op_ori,0,ap1,ap1,make_immed(0x3780000000000000L));       // nop instruction
782
                GenerateDiadic(op_sw,0,ap1,make_indirect(ap2->preg));
783
                GenerateDiadic(op_cache,0,make_string("invil"),make_indirect(ap2->preg));
784
                GenerateDiadic(op_bra,0,make_label(lab6),NULL);
785
                GenerateLabel(lab5);
786
                GenerateDiadic(op_lea,0,ap2,make_label(lab3));
787
                GenerateDiadic(op_lw,0,ap1,make_indexed(4,ap2->preg));
788
                GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xFFFFFFFFFFF00000L));
789
                GenerateTriadic(op_ori,0,ap1,ap1,make_immed(0x00000000000DE000L));       // nop instruction
790
                GenerateDiadic(op_sw,0,ap1,make_indexed(4,ap2->preg));
791
                GenerateDiadic(op_cache,0,make_string("invil"),make_indexed(4,ap2->preg));
792
                GenerateLabel(lab6);
793
                GenerateStatement(stmt->s1);
794
        GenerateLabel(breaklab);
795
        breaklab = lab2;        /* restore old break label */
796
    }
797
    contlab = lab1;         /* restore old continue label */
798
}

powered by: WebSVN 2.1.0

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