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

Subversion Repositories thor

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
// CC64 - 'C' derived language compiler
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
Statement *Function::ParseBody()
29
{
30
        std::string lbl;
31
        char *p;
32
        OCODE *ip;
33
 
34
        dfs.printf("<Parse function body>:%s|\n", (char *)sym->name->c_str());
35
 
36
        lbl = std::string("");
37
        needpunc(begin, 47);
38
 
39
        tmpReset();
40
        //ParseAutoDeclarations();
41
        cseg();
42
        if (sym->storage_class == sc_static)
43
        {
44
                //strcpy(lbl,GetNamespace());
45
                //strcat(lbl,"_");
46
                //              strcpy(lbl,sp->name);
47
                lbl = *sym->mangledName;
48
                //gen_strlab(lbl);
49
        }
50
        //      put_label((unsigned int) sp->value.i);
51
        else {
52
                if (sym->storage_class == sc_global)
53
                        lbl = "public code ";
54
                //              strcat(lbl,sp->name);
55
                lbl += *sym->mangledName;
56
                //gen_strlab(lbl);
57
        }
58
        dfs.printf("B");
59
        p = my_strdup((char *)lbl.c_str());
60
        dfs.printf("b");
61
        if (!IsInline)
62
                GenerateMonadic(op_fnname, 0, make_string(p));
63
        currentFn = this;
64
        IsLeaf = TRUE;
65
        DoesThrow = FALSE;
66
        UsesPredicate = FALSE;
67
        UsesNew = FALSE;
68
        regmask = 0;
69
        bregmask = 0;
70
        currentStmt = (Statement *)NULL;
71
        dfs.printf("C");
72
        stmtdepth = 0;
73
        sym->stmt = Statement::ParseCompound();
74
        dfs.printf("D");
75
        //      stmt->stype = st_funcbody;
76
        while (lc_auto % sizeOfWord)    // round frame size to word
77
                ++lc_auto;
78
        stkspace = lc_auto;
79
        if (!IsInline) {
80
                pass = 1;
81
                ip = peep_tail;
82
                looplevel = 0;
83
                Gen();
84
                stkspace += (ArgRegCount - regFirstArg) * sizeOfWord;
85
                argbot = -stkspace;
86
                stkspace += GetTempMemSpace();
87
                tempbot = -stkspace;
88
                pass = 2;
89
                peep_tail = ip;
90
                peep_tail->fwd = nullptr;
91
                looplevel = 0;
92
                Gen();
93
                dfs.putch('E');
94
 
95
                flush_peep();
96
                if (sym->storage_class == sc_global) {
97
                        ofs.printf("endpublic\r\n\r\n");
98
                }
99
        }
100
        //if (sp->stkspace)
101
        //ofs.printf("%sSTKSIZE_ EQU %d\r\n", (char *)sp->mangledName->c_str(), sp->stkspace);
102
        isFuncBody = false;
103
        dfs.printf("</ParseFunctionBody>\n");
104
        return (sym->stmt);
105
}
106
 
107
void Function::Init(int nump, int numarg)
108
{
109
        IsNocall = isNocall;
110
        IsPascal = isPascal;
111
        sym->IsKernel = isKernel;
112
        IsInterrupt = isInterrupt;
113
        IsTask = isTask;
114
        NumParms = nump;
115
        numa = numarg;
116
        IsVirtual = isVirtual;
117
        IsInline = isInline;
118
 
119
        isPascal = FALSE;
120
        isKernel = FALSE;
121
        isOscall = FALSE;
122
        isInterrupt = FALSE;
123
        isTask = FALSE;
124
        isNocall = FALSE;
125
}
126
 
127
/*
128
*      funcbody starts with the current symbol being either
129
*      the first parameter id or the begin for the local
130
*      block. If begin is the current symbol then funcbody
131
*      assumes that the function has no parameters.
132
*/
133
int Function::Parse()
134
{
135
        Function *osp, *sp;
136
        int nump, numar;
137
        std::string nme;
138
 
139
        sp = this;
140
        dfs.puts("<ParseFunction>\n");
141
        isFuncBody = true;
142
        if (this == nullptr) {
143
                fatal("Compiler error: Function::Parse: SYM is NULL\r\n");
144
        }
145
        dfs.printf("***********************************\n");
146
        dfs.printf("***********************************\n");
147
        dfs.printf("***********************************\n");
148
        if (sym->parent)
149
                dfs.printf("Parent: %s\n", (char *)sym->GetParentPtr()->name->c_str());
150
        dfs.printf("Parsing function: %s\n", (char *)sym->name->c_str());
151
        dfs.printf("***********************************\n");
152
        dfs.printf("***********************************\n");
153
        dfs.printf("***********************************\n");
154
        stkname = ::stkname;
155
        if (verbose) printf("Parsing function: %s\r\n", (char *)sym->name->c_str());
156
        nump = nparms;
157
        iflevel = 0;
158
        looplevel = 0;
159
        foreverlevel = 0;
160
        // There could be unnamed parameters in a function prototype.
161
        dfs.printf("A");
162
        // declare parameters
163
        // Building a parameter list here allows both styles of parameter
164
        // declarations. the original 'C' style is parsed here. Originally the
165
        // parameter types appeared as list after the parenthesis and before the
166
        // function body.
167
        BuildParameterList(&nump, &numar);
168
        dfs.printf("B");
169
        sym->mangledName = BuildSignature(1);  // build against parameters
170
 
171
                                                                                          // If the symbol has a parent then it must be a class
172
                                                                                          // method. Search the parent table(s) for matching
173
                                                                                          // signatures.
174
        osp = this;
175
        nme = *sym->name;
176
        if (sym->parent) {
177
                Function *sp2;
178
                dfs.printf("Parent Class:%s|", (char *)sym->GetParentPtr()->name->c_str());
179
                sp2 = sym->GetParentPtr()->Find(nme)->fi;
180
                if (sp2) {
181
                        dfs.printf("Found at least inexact match");
182
                        sp2 = FindExactMatch(TABLE::matchno);
183
                }
184
                if (sp2 == nullptr)
185
                        error(ERR_METHOD_NOTFOUND);
186
                else
187
                        sp = sp2;
188
                PrintParameterTypes();
189
        }
190
        else {
191
                if (gsyms[0].Find(nme)) {
192
                        sp = TABLE::match[TABLE::matchno - 1]->fi;
193
                }
194
        }
195
        dfs.printf("C");
196
 
197
        if (sp != osp) {
198
                dfs.printf("Function::Parse: sp changed\n");
199
                params.CopyTo(&sp->params);
200
                proto.CopyTo(&sp->proto);
201
                sp->derivitives = derivitives;
202
                sp->sym->mangledName = sym->mangledName;
203
                // Should free osp here. It's not needed anymore
204
                FreeFunction(osp);
205
        }
206
        if (lastst == closepa) {
207
                NextToken();
208
                while (lastst == kw_attribute)
209
                        Declaration::ParseFunctionAttribute(sp);
210
        }
211
        dfs.printf("D");
212
        if (sp->sym->tp->type == bt_pointer) {
213
                if (lastst == assign) {
214
                        doinit(sp->sym);        // was doinit(sym);
215
                }
216
                sp->Init(nump, numar);
217
                return (1);
218
        }
219
j2:
220
        dfs.printf("E");
221
        if (lastst == semicolon) {      // Function prototype
222
                dfs.printf("e");
223
                sp->IsPrototype = 1;
224
                sp->Init(nump, numar);
225
                sp->params.MoveTo(&sp->proto);
226
                goto j1;
227
        }
228
        else if (lastst == kw_attribute) {
229
                while (lastst == kw_attribute) {
230
                        Declaration::ParseFunctionAttribute(sp);
231
                }
232
                goto j2;
233
        }
234
        else if (lastst != begin) {
235
                dfs.printf("F");
236
                //                      NextToken();
237
                //                      ParameterDeclaration::Parse(2);
238
                sp->BuildParameterList(&nump, &numar);
239
                // for old-style parameter list
240
                //needpunc(closepa);
241
                if (lastst == semicolon) {
242
                        sp->IsPrototype = 1;
243
                        sp->Init(nump, numar);
244
                }
245
                // Check for end of function parameter list.
246
                else if (funcdecl == 2 && lastst == closepa) {
247
                        ;
248
                }
249
                else {
250
                        sp->Init(nump, numar);
251
                        sp->sym->stmt = ParseBody();
252
                        Summary(sp->sym->stmt);
253
                }
254
        }
255
        //                error(ERR_BLOCK);
256
        else {
257
                dfs.printf("G");
258
                sp->Init(nump, numar);
259
                // Parsing declarations sets the storage class to extern when it really
260
                // should be global if there is a function body.
261
                if (sp->sym->storage_class == sc_external)
262
                        sp->sym->storage_class = sc_global;
263
                sp->sym->stmt = ParseBody();
264
                Summary(sp->sym->stmt);
265
        }
266
j1:
267
        dfs.printf("F");
268
        dfs.puts("</ParseFunction>\n");
269
        return (0);
270
}
271
 
272
// Push temporaries on the stack.
273
 
274
void Function::SaveGPRegisterVars()
275
{
276
        int cnt;
277
        int nn;
278
 
279
        if (mask != 0) {
280
                cnt = 0;
281
                GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(popcnt(mask) * 8));
282
                for (nn = 0; nn < 64; nn++) {
283
                        if (rmask & (0x8000000000000000ULL >> nn)) {
284
                                GenerateDiadic(op_sw, 0, makereg(nn), make_indexed(cnt, regSP));
285
                                cnt += sizeOfWord;
286
                        }
287
                }
288
        }
289
}
290
 
291
void Function::SaveFPRegisterVars()
292
{
293
        int cnt;
294
        int nn;
295
 
296
        if (fpmask != 0) {
297
                cnt = 0;
298
                GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(popcnt(fpmask) * 8));
299
                for (nn = 0; nn < 64; nn++) {
300
                        if (fprmask & (0x8000000000000000ULL >> nn)) {
301
                                GenerateDiadic(op_sf, 'd', makefpreg(nn), make_indexed(cnt, regSP));
302
                                cnt += sizeOfWord;
303
                        }
304
                }
305
        }
306
}
307
 
308
void Function::SaveRegisterVars()
309
{
310
        SaveGPRegisterVars();
311
        SaveFPRegisterVars();
312
}
313
 
314
 
315
// Saves any registers used as parameters in the calling function.
316
 
317
void Function::SaveRegisterArguments()
318
{
319
        TypeArray *ta;
320
        int count;
321
 
322
        if (this == nullptr)
323
                return;
324
        ta = GetProtoTypes();
325
        if (ta) {
326
                int nn;
327
                if (!cpu.SupportsPush) {
328
                        for (count = nn = 0; nn < ta->length; nn++)
329
                                if (ta->preg[nn]) {
330
                                        count++;
331
                                        if (ta->types[nn] == bt_quad || ta->types[nn] == bt_triple)
332
                                                count++;
333
                                }
334
                        GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(count * sizeOfWord));
335
                        for (count = nn = 0; nn < ta->length; nn++) {
336
                                if (ta->preg[nn]) {
337
                                        switch (ta->types[nn]) {
338
                                        case bt_quad:   GenerateDiadic(op_sf, 'q', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 2; break;
339
                                        case bt_float:  GenerateDiadic(op_sf, 'd', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 1; break;
340
                                        case bt_double: GenerateDiadic(op_sf, 'd', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 1; break;
341
                                        case bt_triple: GenerateDiadic(op_sf, 't', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 2; break;
342
                                        default:        GenerateDiadic(op_sw, 0, makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 1; break;
343
                                        }
344
                                }
345
                        }
346
                }
347
                else {
348
                        for (count = nn = 0; nn < ta->length; nn++) {
349
                                if (ta->preg[nn]) {
350
                                        switch (ta->types[nn]) {
351
                                        case bt_quad:   GenerateMonadic(op_pushf, 'q', makereg(ta->preg[nn] & 0x7fff)); break;
352
                                        case bt_float:  GenerateMonadic(op_pushf, 'd', makereg(ta->preg[nn] & 0x7fff)); break;
353
                                        case bt_double: GenerateMonadic(op_pushf, 'd', makereg(ta->preg[nn] & 0x7fff)); break;
354
                                        case bt_triple: GenerateMonadic(op_pushf, 't', makereg(ta->preg[nn] & 0x7fff)); break;
355
                                        default:        GenerateMonadic(op_push, 0, makereg(ta->preg[nn] & 0x7fff)); break;
356
                                        }
357
                                }
358
                        }
359
                }
360
        }
361
}
362
 
363
 
364
void Function::RestoreRegisterArguments()
365
{
366
        TypeArray *ta;
367
        int count;
368
 
369
        if (this == nullptr)
370
                return;
371
        ta = GetProtoTypes();
372
        if (ta) {
373
                int nn;
374
                for (count = nn = 0; nn < ta->length; nn++)
375
                        if (ta->preg[nn]) {
376
                                count++;
377
                                if (ta->types[nn] == bt_quad || ta->types[nn] == bt_triple)
378
                                        count++;
379
                        }
380
                GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(count * sizeOfWord));
381
                for (count = nn = 0; nn < ta->length; nn++) {
382
                        if (ta->preg[nn]) {
383
                                switch (ta->types[nn]) {
384
                                case bt_quad:   GenerateDiadic(op_lf, 'q', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 2; break;
385
                                case bt_float:  GenerateDiadic(op_lf, 'd', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 1; break;
386
                                case bt_double: GenerateDiadic(op_lf, 'd', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 1; break;
387
                                case bt_triple: GenerateDiadic(op_lf, 't', makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 2; break;
388
                                default:        GenerateDiadic(op_lw, 0, makereg(ta->preg[nn] & 0x7fff), make_indexed(count*sizeOfWord, regSP)); count += 1; break;
389
                                }
390
                        }
391
                }
392
        }
393
}
394
 
395
 
396
void Function::RestoreGPRegisterVars()
397
{
398
        int cnt2, cnt;
399
        int nn;
400
 
401
        if (save_mask != 0) {
402
                cnt2 = cnt = popcnt(save_mask)*sizeOfWord;
403
                cnt = 0;
404
                for (nn = 0; nn < 64; nn++) {
405
                        if (save_mask & (1LL << nn)) {
406
                                GenerateDiadic(op_lw, 0, makereg(nn), make_indexed(cnt, regSP));
407
                                cnt += sizeOfWord;
408
                        }
409
                }
410
                GenerateTriadic(op_add, 0, makereg(regSP), makereg(regSP), make_immed(cnt2));
411
        }
412
}
413
 
414
void Function::RestoreFPRegisterVars()
415
{
416
        int cnt2, cnt;
417
        int nn;
418
 
419
        if (fpsave_mask != 0) {
420
                cnt2 = cnt = popcnt(fpsave_mask)*sizeOfWord;
421
                cnt = 0;
422
                for (nn = 0; nn < 64; nn++) {
423
                        if (fpsave_mask & (1LL << nn)) {
424
                                GenerateDiadic(op_lf, 'd', makefpreg(nn), make_indexed(cnt, regSP));
425
                                cnt += sizeOfWord;
426
                        }
427
                }
428
                GenerateTriadic(op_add, 0, makereg(regSP), makereg(regSP), make_immed(cnt2));
429
        }
430
}
431
 
432
void Function::RestoreRegisterVars()
433
{
434
        RestoreGPRegisterVars();
435
        RestoreFPRegisterVars();
436
}
437
 
438
void Function::SaveTemporaries(int *sp, int *fsp)
439
{
440
        if (this) {
441
                if (UsesTemps) {
442
                        *sp = TempInvalidate(fsp);
443
                        //*fsp = TempFPInvalidate();
444
                }
445
        }
446
        else {
447
                *sp = TempInvalidate(fsp);
448
                //*fsp = TempFPInvalidate();
449
        }
450
}
451
 
452
void Function::RestoreTemporaries(int sp, int fsp)
453
{
454
        if (this) {
455
                if (UsesTemps) {
456
                        //TempFPRevalidate(fsp);
457
                        TempRevalidate(sp, fsp);
458
                }
459
        }
460
        else {
461
                //TempFPRevalidate(fsp);
462
                TempRevalidate(sp, fsp);
463
        }
464
}
465
 
466
 
467
// Unlink the stack
468
 
469
void Function::UnlinkStack()
470
{
471
        GenerateDiadic(op_mov, 0, makereg(regSP), makereg(regFP));
472
        GenerateDiadic(op_lw, 0, makereg(regFP), make_indirect(regSP));
473
        if (exceptions) {
474
                if (!IsLeaf || DoesThrow)
475
                        GenerateDiadic(op_lw, 0, makereg(regXLR), make_indexed(2 * sizeOfWord, regSP));
476
        }
477
        if (!IsLeaf)
478
                GenerateDiadic(op_lw, 0, makereg(regLR), make_indexed(3 * sizeOfWord, regSP));
479
        //      GenerateTriadic(op_add,0,makereg(regSP),makereg(regSP),make_immed(3*sizeOfWord));
480
}
481
 
482
bool Function::GenDefaultCatch()
483
{
484
        GenerateLabel(throwlab);
485
        if (IsLeaf) {
486
                if (DoesThrow) {
487
                        GenerateDiadic(op_lw, 0, makereg(regLR), make_indexed(2 * sizeOfWord, regFP));           // load throw return address from stack into LR
488
                        GenerateDiadic(op_sw, 0, makereg(regLR), make_indexed(3 * sizeOfWord, regFP));           // and store it back (so it can be loaded with the lm)
489
                                                                                                                                                                                                        //GenerateDiadic(op_spt,0,makereg(0),make_indexed(3 * sizeOfWord, regFP));
490
                                                                                                                                                                                                        //                      GenerateDiadic(op_bra,0,make_label(retlab),NULL);                               // goto regular return cleanup code
491
                        return (true);
492
                }
493
        }
494
        else {
495
                GenerateDiadic(op_lw, 0, makereg(regLR), make_indexed(2 * sizeOfWord, regFP));           // load throw return address from stack into LR
496
                GenerateDiadic(op_sw, 0, makereg(regLR), make_indexed(3 * sizeOfWord, regFP));           // and store it back (so it can be loaded with the lm)
497
                                                                                                                                                                                                //GenerateDiadic(op_spt, 0, makereg(0), make_indexed(3 * sizeOfWord, regFP));
498
                                                                                                                                                                                                //              GenerateDiadic(op_bra,0,make_label(retlab),NULL);                               // goto regular return cleanup code
499
                return (true);
500
        }
501
        return (false);
502
}
503
 
504
 
505
// For a leaf routine don't bother to store the link register.
506
void Function::SetupReturnBlock()
507
{
508
        Operand *ap;
509
        int n;
510
 
511
        GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(4 * sizeOfWord));
512
        GenerateDiadic(op_sw, 0, makereg(regFP), make_indirect(regSP));
513
        GenerateDiadic(op_sw, 0, makereg(regZero), make_indexed(sizeOfWord, regSP));
514
        //      GenerateTriadic(op_swp, 0, makereg(regFP), makereg(regZero), make_indirect(regSP));
515
        n = 0;
516
        if (exceptions) {
517
                if (!IsLeaf || DoesThrow) {
518
                        n = 1;
519
                        GenerateDiadic(op_sw, 0, makereg(regXLR), make_indexed(2 * sizeOfWord, regSP));
520
                }
521
        }
522
        if (!IsLeaf) {
523
                n |= 2;
524
                GenerateDiadic(op_sw, 0, makereg(regLR), make_indexed(3 * sizeOfWord, regSP));
525
        }
526
        /*
527
        switch (n) {
528
        case 0: break;
529
        case 1: GenerateDiadic(op_sw, 0, makereg(regXLR), make_indexed(2 * sizeOfWord, regSP)); break;
530
        case 2: GenerateDiadic(op_sw, 0, makereg(regLR), make_indexed(3 * sizeOfWord, regSP)); break;
531
        case 3: GenerateTriadic(op_swp, 0, makereg(regXLR), makereg(regLR), make_indexed(2 * sizeOfWord, regSP)); break;
532
        }
533
        */
534
        ap = make_label(throwlab);
535
        ap->mode = am_imm;
536
        if (exceptions && (!IsLeaf || DoesThrow))
537
                GenerateDiadic(op_ldi, 0, makereg(regXLR), ap);
538
        GenerateDiadic(op_mov, 0, makereg(regFP), makereg(regSP));
539
        GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(stkspace));
540
        spAdjust = peep_tail;
541
}
542
 
543
// Generate a return statement.
544
//
545
void Function::GenReturn(Statement *stmt)
546
{
547
        Operand *ap;
548
        int nn;
549
        int cnt, cnt2;
550
        int toAdd;
551
        SYM *p;
552
        bool isFloat;
553
 
554
        // Generate the return expression and force the result into r1.
555
        if (stmt != NULL && stmt->exp != NULL)
556
        {
557
                initstack();
558
                isFloat = sym->tp->GetBtp() && sym->tp->GetBtp()->IsFloatType();
559
                if (isFloat)
560
                        ap = GenerateExpression(stmt->exp, F_REG, sizeOfFP);
561
                else
562
                        ap = GenerateExpression(stmt->exp, F_REG | F_IMMED, sizeOfWord);
563
                GenerateMonadic(op_hint, 0, make_immed(2));
564
                if (ap->mode == am_imm)
565
                        GenLdi(makereg(1), ap);
566
                else if (ap->mode == am_reg) {
567
                        if (sym->tp->GetBtp() && (sym->tp->GetBtp()->type == bt_struct || sym->tp->GetBtp()->type == bt_union)) {
568
                                p = params.Find("_pHiddenStructPtr", false);
569
                                if (p) {
570
                                        if (p->IsRegister)
571
                                                GenerateDiadic(op_mov, 0, makereg(1), makereg(p->reg));
572
                                        else
573
                                                GenerateDiadic(op_lw, 0, makereg(1), make_indexed(p->value.i, regFP));
574
                                        GenerateMonadic(op_push, 0, make_immed(sym->tp->GetBtp()->size));
575
                                        GenerateMonadic(op_push, 0, ap);
576
                                        GenerateMonadic(op_push, 0, makereg(1));
577
                                        GenerateMonadic(op_call, 0, make_string("_memcpy"));
578
                                        GenerateTriadic(op_add, 0, makereg(regSP), makereg(regSP), make_immed(sizeOfWord * 3));
579
                                }
580
                                else {
581
                                        // ToDo compiler error
582
                                }
583
                        }
584
                        else {
585
                                if (sym->tp->GetBtp()->IsFloatType())
586
                                        GenerateDiadic(op_mov, 0, makefpreg(1), ap);
587
                                else if (sym->tp->GetBtp()->IsVectorType())
588
                                        GenerateDiadic(op_mov, 0, makevreg(1), ap);
589
                                else
590
                                        GenerateDiadic(op_mov, 0, makereg(1), ap);
591
                        }
592
                }
593
                else if (ap->mode == am_fpreg) {
594
                        if (isFloat)
595
                                GenerateDiadic(op_mov, 0, makefpreg(1), ap);
596
                        else
597
                                GenerateDiadic(op_mov, 0, makereg(1), ap);
598
                }
599
                else if (ap->type == stddouble.GetIndex()) {
600
                        if (isFloat)
601
                                GenerateDiadic(op_lf, 'd', makereg(1), ap);
602
                        else
603
                                GenerateDiadic(op_lw, 0, makereg(1), ap);
604
                }
605
                else {
606
                        if (sym->tp->GetBtp()->IsVectorType())
607
                                GenLoad(makevreg(1), ap, sizeOfWord, sizeOfWord);
608
                        else
609
                                GenLoad(makereg(1), ap, sizeOfWord, sizeOfWord);
610
                }
611
                ReleaseTempRegister(ap);
612
        }
613
 
614
        // Generate the return code only once. Branch to the return code for all returns.
615
        if (retlab != -1) {
616
                GenerateMonadic(op_bra, 0, make_label(retlab));
617
                return;
618
        }
619
        retlab = nextlabel++;
620
        GenerateLabel(retlab);
621
        rcode = peep_tail;
622
 
623
        if (currentFn->UsesNew) {
624
                GenerateTriadic(op_sub, 0, makereg(regSP), makereg(regSP), make_immed(8));
625
                GenerateDiadic(op_sw, 0, makereg(regFirstArg), make_indirect(regSP));
626
                GenerateDiadic(op_lea, 0, makereg(regFirstArg), make_indexed(-sizeOfWord, regFP));
627
                GenerateMonadic(op_call, 0, make_string("__AddGarbage"));
628
                GenerateDiadic(op_lw, 0, makereg(regFirstArg), make_indirect(regSP));
629
                GenerateTriadic(op_add, 0, makereg(regSP), makereg(regSP), make_immed(8));
630
        }
631
 
632
        // Unlock any semaphores that may have been set
633
        for (nn = lastsph - 1; nn >= 0; nn--)
634
                GenerateDiadic(op_sb, 0, makereg(0), make_string(semaphores[nn]));
635
 
636
        // Restore fp registers used as register variables.
637
        if (fpsave_mask != 0) {
638
                cnt2 = cnt = (popcnt(fpsave_mask) - 1)*sizeOfFP;
639
                for (nn = 31; nn >= 1; nn--) {
640
                        if (fpsave_mask & (1LL << nn)) {
641
                                GenerateDiadic(op_lw, 0, makereg(nn), make_indexed(cnt2 - cnt, regSP));
642
                                cnt -= sizeOfWord;
643
                        }
644
                }
645
                GenerateTriadic(op_add, 0, makereg(regSP), makereg(regSP), make_immed(cnt2 + sizeOfFP));
646
        }
647
        RestoreRegisterVars();
648
        if (IsNocall) {
649
                if (epilog) {
650
                        epilog->Generate();
651
                        return;
652
                }
653
                return;
654
        }
655
        UnlinkStack();
656
        toAdd = 4 * sizeOfWord;
657
 
658
        if (epilog) {
659
                epilog->Generate();
660
                return;
661
        }
662
 
663
        // If Pascal calling convention remove parameters from stack by adding to stack pointer
664
        // based on the number of parameters. However if a non-auto register parameter is
665
        // present, then don't add to the stack pointer for it. (Remove the previous add effect).
666
        if (IsPascal) {
667
                TypeArray *ta;
668
                int nn;
669
                ta = GetProtoTypes();
670
                for (nn = 0; nn < ta->length; nn++) {
671
                        switch (ta->types[nn]) {
672
                        case bt_float:
673
                        case bt_quad:
674
                                if (ta->preg[nn] && (ta->preg[nn] & 0x8000) == 0)
675
                                        ;
676
                                else
677
                                        toAdd += sizeOfFPQ;
678
                                break;
679
                        case bt_double:
680
                                if (ta->preg[nn] && (ta->preg[nn] & 0x8000) == 0)
681
                                        ;
682
                                else
683
                                        toAdd += sizeOfFPD;
684
                                break;
685
                        case bt_triple:
686
                                if (ta->preg[nn] && (ta->preg[nn] & 0x8000) == 0)
687
                                        ;
688
                                else
689
                                        toAdd += sizeOfFPT;
690
                                break;
691
                        default:
692
                                if (ta->preg[nn] && (ta->preg[nn] & 0x8000) == 0)
693
                                        ;
694
                                else
695
                                        toAdd += sizeOfWord;
696
                        }
697
                }
698
        }
699
        //      if (toAdd != 0)
700
        //              GenerateTriadic(op_add,0,makereg(regSP),makereg(regSP),make_immed(toAdd));
701
        // Generate the return instruction. For the Pascal calling convention pop the parameters
702
        // from the stack.
703
        if (IsInterrupt) {
704
                //RestoreRegisterSet(sym);
705
                GenerateZeradic(op_rti);
706
                return;
707
        }
708
 
709
        if (!IsInline) {
710
                GenerateMonadic(op_ret, 0, make_immed(toAdd));
711
                //GenerateMonadic(op_jal,0,make_indirect(regLR));
712
        }
713
        else
714
                GenerateTriadic(op_add, 0, makereg(regSP), makereg(regSP), make_immed(toAdd));
715
}
716
 
717
 
718
// Generate a function body.
719
//
720
void Function::Gen()
721
{
722
        int defcatch;
723
        Statement *stmt = this->sym->stmt;
724
        int lab0;
725
        int o_throwlab, o_retlab, o_contlab, o_breaklab;
726
        OCODE *ip;
727
        bool doCatch = true;
728
 
729
        o_throwlab = throwlab;
730
        o_retlab = retlab;
731
        o_contlab = contlab;
732
        o_breaklab = breaklab;
733
 
734
        throwlab = retlab = contlab = breaklab = -1;
735
        lastsph = 0;
736
        memset(semaphores, 0, sizeof(semaphores));
737
        throwlab = nextlabel++;
738
        defcatch = nextlabel++;
739
        lab0 = nextlabel++;
740
 
741
        while (lc_auto % sizeOfWord)    // round frame size to word
742
                ++lc_auto;
743
        if (IsInterrupt) {
744
                if (stkname) {
745
                        GenerateDiadic(op_lea, 0, makereg(SP), make_string(stkname));
746
                        GenerateTriadic(op_ori, 0, makereg(SP), makereg(SP), make_immed(0xFFFFF00000000000LL));
747
                }
748
                //SaveRegisterSet(sym);
749
        }
750
        // The prolog code can't be optimized because it'll run *before* any variables
751
        // assigned to registers are available. About all we can do here is constant
752
        // optimizations.
753
        if (prolog) {
754
                prolog->scan();
755
                prolog->Generate();
756
        }
757
        // Setup the return block.
758
        if (!IsNocall)
759
                SetupReturnBlock();
760
        if (optimize) {
761
                if (currentFn->csetbl == nullptr)
762
                        currentFn->csetbl = new CSETable;
763
                currentFn->csetbl->Optimize(stmt);
764
        }
765
        stmt->Generate();
766
 
767
        if (exceptions) {
768
                ip = peep_tail;
769
                GenerateMonadic(op_bra, 0, make_label(lab0));
770
                doCatch = GenDefaultCatch();
771
                GenerateLabel(lab0);
772
                if (!doCatch) {
773
                        peep_tail = ip;
774
                        peep_tail->fwd = nullptr;
775
                }
776
        }
777
 
778
        if (!IsInline)
779
                GenReturn(nullptr);
780
        /*
781
        // Inline code needs to branch around the default exception handler.
782
        if (exceptions && sym->IsInline)
783
        GenerateMonadic(op_bra,0,make_label(lab0));
784
        // Generate code for the hidden default catch
785
        if (exceptions)
786
        GenerateDefaultCatch(sym);
787
        if (exceptions && sym->IsInline)
788
        GenerateLabel(lab0);
789
        */
790
        throwlab = o_throwlab;
791
        retlab = o_retlab;
792
        contlab = o_contlab;
793
        breaklab = o_breaklab;
794
}
795
 
796
// Get the parameter types into an array of short integers.
797
// Only the first 20 parameters are processed.
798
//
799
TypeArray *Function::GetParameterTypes()
800
{
801
        TypeArray *i16;
802
        SYM *sp;
803
        int nn;
804
 
805
        //      printf("Enter GetParameterTypes()\r\n");
806
        i16 = new TypeArray();
807
        i16->Clear();
808
        sp = sym->GetPtr(params.GetHead());
809
        for (nn = 0; sp; nn++) {
810
                i16->Add(sp->tp, (__int16)(sp->IsRegister ? sp->reg : 0));
811
                sp = sp->GetNextPtr();
812
        }
813
        //      printf("Leave GetParameterTypes()\r\n");
814
        return i16;
815
}
816
 
817
TypeArray *Function::GetProtoTypes()
818
{
819
        TypeArray *i16;
820
        SYM *sp;
821
        int nn;
822
 
823
        //      printf("Enter GetParameterTypes()\r\n");
824
        nn = 0;
825
        i16 = new TypeArray();
826
        i16->Clear();
827
        if (this == nullptr)
828
                return (i16);
829
        sp = sym->GetPtr(proto.GetHead());
830
        // If there's no prototype try for a parameter list.
831
        if (sp == nullptr)
832
                return (GetParameterTypes());
833
        for (nn = 0; sp; nn++) {
834
                i16->Add(sp->tp, (__int16)sp->IsRegister ? sp->reg : 0);
835
                sp = sp->GetNextPtr();
836
        }
837
        //      printf("Leave GetParameterTypes()\r\n");
838
        return i16;
839
}
840
 
841
void Function::PrintParameterTypes()
842
{
843
        TypeArray *ta = GetParameterTypes();
844
        dfs.printf("Parameter types(%s)\n", (char *)sym->name->c_str());
845
        ta->Print();
846
        if (ta)
847
                delete[] ta;
848
        ta = GetProtoTypes();
849
        dfs.printf("Proto types(%s)\n", (char *)sym->name->c_str());
850
        ta->Print();
851
        if (ta)
852
                delete ta;
853
}
854
 
855
// Build a function signature string including
856
// the return type, base classes, and any parameters.
857
 
858
std::string *Function::BuildSignature(int opt)
859
{
860
        std::string *str;
861
        std::string *nh;
862
 
863
        dfs.printf("<BuildSignature>");
864
        if (this == nullptr) {
865
        }
866
        if (mangledNames) {
867
                str = new std::string("_Z");            // 'C' likes this
868
                dfs.printf("A");
869
                nh = sym->GetNameHash();
870
                dfs.printf("B");
871
                str->append(*nh);
872
                dfs.printf("C");
873
                delete nh;
874
                dfs.printf("D");
875
                if (sym->name > (std::string *)0x15)
876
                        str->append(*sym->name);
877
                if (opt) {
878
                        dfs.printf("E");
879
                        str->append(*GetParameterTypes()->BuildSignature());
880
                }
881
                else {
882
                        dfs.printf("F");
883
                        str->append(*GetProtoTypes()->BuildSignature());
884
                }
885
        }
886
        else {
887
                str = new std::string("");
888
                str->append(*sym->name);
889
        }
890
        dfs.printf(":%s</BuildSignature>", (char *)str->c_str());
891
        return str;
892
}
893
 
894
// Check if the passed parameter list matches the one in the
895
// symbol.
896
// Allows a null pointer to be passed indicating no parameters
897
 
898
bool Function::ProtoTypesMatch(TypeArray *ta)
899
{
900
        TypeArray *tb;
901
 
902
        tb = GetProtoTypes();
903
        if (tb->IsEqual(ta)) {
904
                delete tb;
905
                return true;
906
        }
907
        delete tb;
908
        return false;
909
}
910
 
911
bool Function::ParameterTypesMatch(TypeArray *ta)
912
{
913
        TypeArray *tb;
914
 
915
        tb = GetProtoTypes();
916
        if (tb->IsEqual(ta)) {
917
                delete tb;
918
                return true;
919
        }
920
        delete tb;
921
        return false;
922
}
923
 
924
// Check if the parameter type list of two different symbols
925
// match.
926
 
927
bool Function::ProtoTypesMatch(Function *sym)
928
{
929
        TypeArray *ta;
930
        bool ret;
931
 
932
        ta = sym->GetProtoTypes();
933
        ret = ProtoTypesMatch(ta);
934
        delete ta;
935
        return (ret);
936
}
937
 
938
bool Function::ParameterTypesMatch(Function *sym)
939
{
940
        TypeArray *ta;
941
        bool ret;
942
 
943
        ta = GetProtoTypes();
944
        ret = sym->ParameterTypesMatch(ta);
945
        delete ta;
946
        return (ret);
947
}
948
 
949
// First check the return type because it's simple to do.
950
// Then check the parameters.
951
 
952
bool Function::CheckSignatureMatch(Function *a, Function *b) const
953
{
954
        std::string ta, tb;
955
 
956
        //      if (a->tp->typeno != b->tp->typeno)
957
        //              return false;
958
 
959
        ta = a->BuildSignature()->substr(5);
960
        tb = b->BuildSignature()->substr(5);
961
        return (ta.compare(tb) == 0);
962
}
963
 
964
 
965
void Function::CheckParameterListMatch(Function *s1, Function *s2)
966
{
967
        if (!TYP::IsSameType(s1->parms->tp, s2->parms->tp, false))
968
                error(ERR_PARMLIST_MISMATCH);
969
}
970
 
971
 
972
// Parameters:
973
//    mm = number of entries to search (typically the value 
974
//         TABLE::matchno teh number of matches found
975
 
976
Function *Function::FindExactMatch(int mm)
977
{
978
        Function *sp1;
979
        int nn;
980
        TypeArray *ta, *tb;
981
 
982
        sp1 = nullptr;
983
        for (nn = 0; nn < mm; nn++) {
984
                dfs.printf("%d", nn);
985
                sp1 = TABLE::match[nn]->fi;
986
                // Matches sp1 prototype list against this's parameter list
987
                ta = sp1->GetProtoTypes();
988
                tb = GetParameterTypes();
989
                if (ta->IsEqual(tb)) {
990
                        delete ta;
991
                        delete tb;
992
                        return (sp1);
993
                }
994
                delete ta;
995
                delete tb;
996
        }
997
        return (nullptr);
998
}
999
 
1000
// Lookup the exactly matching method from the results returned by a
1001
// find operation. Find might return multiple values if there are 
1002
// overloaded functions.
1003
 
1004
Function *Function::FindExactMatch(int mm, std::string name, int rettype, TypeArray *typearray)
1005
{
1006
        Function *sp1;
1007
        int nn;
1008
        TypeArray *ta;
1009
 
1010
        sp1 = nullptr;
1011
        for (nn = 0; nn < mm; nn++) {
1012
                sp1 = TABLE::match[nn]->fi;
1013
                ta = sp1->GetProtoTypes();
1014
                if (ta->IsEqual(typearray)) {
1015
                        delete ta;
1016
                        return sp1;
1017
                }
1018
                delete ta;
1019
        }
1020
        return (nullptr);
1021
}
1022
 
1023
void Function::BuildParameterList(int *num, int *numa)
1024
{
1025
        int i, poffset, preg, fpreg;
1026
        SYM *sp1;
1027
        int onp;
1028
        int np;
1029
        bool noParmOffset = false;
1030
 
1031
        dfs.printf("<BuildParameterList\n>");
1032
        poffset = 0;//GetReturnBlockSize();
1033
                                //      sp->parms = (SYM *)NULL;
1034
        onp = nparms;
1035
        nparms = 0;
1036
        preg = regFirstArg;
1037
        fpreg = regFirstArg;
1038
        // Parameters will be inserted into the symbol's parameter list when
1039
        // declarations are processed.
1040
        np = ParameterDeclaration::Parse(1);
1041
        *num += np;
1042
        *numa = 0;
1043
        dfs.printf("B");
1044
        nparms = onp;
1045
        for (i = 0; i < np && i < 20; ++i) {
1046
                if ((sp1 = currentFn->params.Find(names[i].str, false)) == NULL) {
1047
                        dfs.printf("C");
1048
                        sp1 = makeint2(names[i].str);
1049
                        //                      lsyms.insert(sp1);
1050
                }
1051
                sp1->parent = sym->parent;
1052
                sp1->IsParameter = true;
1053
                sp1->value.i = poffset;
1054
                noParmOffset = false;
1055
                if (sp1->tp->IsFloatType()) {
1056
                        if (fpreg > regLastArg)
1057
                                sp1->IsRegister = false;
1058
                        if (sp1->IsRegister && sp1->tp->size < 11) {
1059
                                sp1->reg = sp1->IsAuto ? fpreg | 0x8000 : fpreg;
1060
                                fpreg++;
1061
                                if ((fpreg & 0x8000) == 0) {
1062
                                        noParmOffset = true;
1063
                                        sp1->value.i = -1;
1064
                                }
1065
                        }
1066
                        else
1067
                                sp1->IsRegister = false;
1068
                }
1069
                else {
1070
                        if (preg > regLastArg)
1071
                                sp1->IsRegister = false;
1072
                        if (sp1->IsRegister && sp1->tp->size < 11) {
1073
                                sp1->reg = sp1->IsAuto ? preg | 0x8000 : preg;
1074
                                preg++;
1075
                                if ((preg & 0x8000) == 0) {
1076
                                        noParmOffset = true;
1077
                                        sp1->value.i = -1;
1078
                                }
1079
                        }
1080
                        else
1081
                                sp1->IsRegister = false;
1082
                }
1083
                if (!sp1->IsRegister)
1084
                        *numa += 1;
1085
                // Check for aggregate types passed as parameters. Structs
1086
                // and unions use the type size. There could also be arrays
1087
                // passed.
1088
                if (!noParmOffset)
1089
                        poffset += round8(sp1->tp->size);
1090
                if (round8(sp1->tp->size) > 8 && !sp1->tp->IsVectorType())
1091
                        IsLeaf = FALSE;
1092
                sp1->storage_class = sc_auto;
1093
        }
1094
        // Process extra hidden parameter
1095
        // ToDo: verify that the hidden parameter is required here.
1096
        // It is generated while processing expressions. It may not be needed
1097
        // here.
1098
        if (sym->tp) {
1099
                if (sym->tp->GetBtp()) {
1100
                        if (sym->tp->GetBtp()->type == bt_struct || sym->tp->GetBtp()->type == bt_union || sym->tp->GetBtp()->type == bt_class) {
1101
                                sp1 = makeStructPtr("_pHiddenStructPtr");
1102
                                sp1->parent = sym->parent;
1103
                                sp1->value.i = poffset;
1104
                                poffset += sizeOfWord;
1105
                                sp1->storage_class = sc_register;
1106
                                sp1->IsAuto = false;
1107
                                sp1->next = 0;
1108
                                sp1->IsRegister = true;
1109
                                if (preg > regLastArg)
1110
                                        sp1->IsRegister = false;
1111
                                if (sp1->IsRegister && sp1->tp->size < 11) {
1112
                                        sp1->reg = sp1->IsAuto ? preg | 0x8000 : preg;
1113
                                        preg++;
1114
                                        if ((preg & 0x8000) == 0) {
1115
                                                noParmOffset = true;
1116
                                                sp1->value.i = -1;
1117
                                        }
1118
                                }
1119
                                else
1120
                                        sp1->IsRegister = false;
1121
                                // record parameter list
1122
                                params.insert(sp1);
1123
                                //              nparms++;
1124
                                if (!sp1->IsRegister)
1125
                                        *numa += 1;
1126
                                *num = *num + 1;
1127
                        }
1128
                }
1129
        }
1130
        dfs.printf("</BuildParameterList>\n");
1131
}
1132
 
1133
void Function::AddParameters(SYM *list)
1134
{
1135
        SYM *nxt;
1136
 
1137
        while (list) {
1138
                nxt = list->GetNextPtr();
1139
                params.insert(SYM::Copy(list));
1140
                list = nxt;
1141
        }
1142
 
1143
}
1144
 
1145
void Function::AddProto(SYM *list)
1146
{
1147
        SYM *nxt;
1148
 
1149
        while (list) {
1150
                nxt = list->GetNextPtr();
1151
                proto.insert(SYM::Copy(list));  // will clear next
1152
                list = nxt;
1153
        }
1154
}
1155
 
1156
void Function::AddProto(TypeArray *ta)
1157
{
1158
        SYM *sym;
1159
        int nn;
1160
        char buf[20];
1161
 
1162
        for (nn = 0; nn < ta->length; nn++) {
1163
                sym = allocSYM();
1164
                sprintf_s(buf, sizeof(buf), "_p%d", nn);
1165
                sym->SetName(std::string(buf));
1166
                sym->tp = TYP::Make(ta->types[nn], TYP::GetSize(ta->types[nn]));
1167
                sym->tp->type = (e_bt)TYP::GetBasicType(ta->types[nn]);
1168
                sym->IsRegister = ta->preg[nn] != 0;
1169
                sym->reg = ta->preg[nn];
1170
                proto.insert(sym);
1171
        }
1172
}
1173
 
1174
void Function::AddDerived()
1175
{
1176
        DerivedMethod *mthd;
1177
 
1178
        dfs.puts("<AddDerived>");
1179
        mthd = (DerivedMethod *)allocx(sizeof(DerivedMethod));
1180
        dfs.printf("A");
1181
        if (sym->tp == nullptr)
1182
                dfs.printf("Nullptr");
1183
        if (sym->GetParentPtr() == nullptr)
1184
                throw C64PException(ERR_NULLPOINTER, 10);
1185
        mthd->typeno = sym->GetParentPtr()->tp->typeno;
1186
        dfs.printf("B");
1187
        mthd->name = BuildSignature();
1188
 
1189
        dfs.printf("C");
1190
        if (derivitives) {
1191
                dfs.printf("D");
1192
                mthd->next = derivitives;
1193
        }
1194
        derivitives = mthd;
1195
        dfs.puts("</AddDerived>");
1196
}
1197
 
1198
bool Function::HasRegisterParameters()
1199
{
1200
        int nn;
1201
 
1202
        TypeArray *ta = GetParameterTypes();
1203
        for (nn = 0; nn < ta->length; nn++) {
1204
                if (ta->preg[nn] & 0x8000) {
1205
                        delete[] ta;
1206
                        return (true);
1207
                }
1208
        }
1209
        delete[] ta;
1210
        return (false);
1211
}
1212
 
1213
 
1214
void Function::CheckForUndefinedLabels()
1215
{
1216
        SYM *head = SYM::GetPtr(sym->lsyms.GetHead());
1217
 
1218
        while (head != 0) {
1219
                if (head->storage_class == sc_ulabel)
1220
                        lfs.printf("*** UNDEFINED LABEL - %s\n", (char *)head->name->c_str());
1221
                head = head->GetNextPtr();
1222
        }
1223
}
1224
 
1225
 
1226
void Function::Summary(Statement *stmt)
1227
{
1228
        dfs.printf("<FuncSummary>\n");
1229
        nl();
1230
        CheckForUndefinedLabels();
1231
        lc_auto = 0;
1232
        lfs.printf("\n\n*** local symbol table ***\n\n");
1233
        ListTable(&sym->lsyms, 0);
1234
        // Should recurse into all the compound statements
1235
        if (stmt == NULL)
1236
                dfs.printf("DIAG: null statement in funcbottom.\r\n");
1237
        else {
1238
                if (stmt->stype == st_compound)
1239
                        ListCompound(stmt);
1240
        }
1241
        lfs.printf("\n\n\n");
1242
        //    ReleaseLocalMemory();        // release local symbols
1243
        isPascal = FALSE;
1244
        isKernel = FALSE;
1245
        isOscall = FALSE;
1246
        isInterrupt = FALSE;
1247
        isNocall = FALSE;
1248
        dfs.printf("</FuncSummary>\n");
1249
}
1250
 
1251
 
1252
// When going to insert a class method, check the base classes to see if it's
1253
// a virtual function override. If it's an override, then add the method to
1254
// the list of overrides for the virtual function.
1255
 
1256
void Function::InsertMethod()
1257
{
1258
        int nn;
1259
        SYM *sy;
1260
        std::string name;
1261
 
1262
        name = *sym->name;
1263
        dfs.printf("<InsertMethod>%s type %d ", (char *)sym->name->c_str(), sym->tp->type);
1264
        sym->GetParentPtr()->tp->lst.insert(sym);
1265
        nn = sym->GetParentPtr()->tp->lst.FindRising(*sym->name);
1266
        sy = sym->FindRisingMatch(true);
1267
        if (sy) {
1268
                dfs.puts("Found in a base class:");
1269
                if (sy->fi->IsVirtual) {
1270
                        dfs.printf("Found virtual:");
1271
                        sy->fi->AddDerived();
1272
                }
1273
        }
1274
        dfs.printf("</InsertMethod>\n");
1275
}
1276
 
1277
void Function::CreateVars()
1278
{
1279
        BasicBlock *b;
1280
        int nn;
1281
        int num;
1282
 
1283
        varlist = nullptr;
1284
        Var::nvar = 0;
1285
        for (b = RootBlock; b; b = b->next) {
1286
                b->LiveOut->resetPtr();
1287
                for (nn = 0; nn < b->LiveOut->NumMember(); nn++) {
1288
                        num = b->LiveOut->nextMember();
1289
                        Var::Find(num); // find will create the var if not found
1290
                }
1291
                //for (nn = 0; nn < b->LiveIn->NumMember(); nn++) {
1292
                //      num = b->LiveIn->nextMember();
1293
                //      Var::Find(num); // find will create the var if not found
1294
                //}
1295
        }
1296
}
1297
 
1298
 
1299
void Function::ComputeLiveVars()
1300
{
1301
        BasicBlock *b;
1302
        bool changed;
1303
        int iter;
1304
        int changes;
1305
 
1306
        changed = false;
1307
        for (iter = 0; (iter == 0 || changed) && iter < 10000; iter++) {
1308
                changes = 0;
1309
                changed = false;
1310
                for (b = LastBlock; b; b = b->prev) {
1311
                        b->ComputeLiveVars();
1312
                        if (b->changed) {
1313
                                changes++;
1314
                                changed = true;
1315
                        }
1316
                }
1317
        }
1318
}
1319
 
1320
void Function::DumpLiveVars()
1321
{
1322
        BasicBlock *b;
1323
        int nn;
1324
        int lomax, limax;
1325
 
1326
        lomax = limax = 0;
1327
        for (b = RootBlock; b; b = b->next) {
1328
                lomax = max(lomax, b->LiveOut->NumMember());
1329
                limax = max(limax, b->LiveIn->NumMember());
1330
        }
1331
 
1332
        dfs.printf("<table style=\"width:100%\">\n");
1333
        //dfs.printf("<LiveVarTable>\n");
1334
        for (b = RootBlock; b; b = b->next) {
1335
                b->LiveIn->resetPtr();
1336
                b->LiveOut->resetPtr();
1337
                dfs.printf("<tr><td>%d: </td>", b->num);
1338
                for (nn = 0; nn < b->LiveIn->NumMember(); nn++)
1339
                        dfs.printf("<td>vi%d </td>", b->LiveIn->nextMember());
1340
                for (; nn < limax; nn++)
1341
                        dfs.printf("<td></td>");
1342
                dfs.printf("<td> || </td>");
1343
                for (nn = 0; nn < b->LiveOut->NumMember(); nn++)
1344
                        dfs.printf("<td>vo%d </td>", b->LiveOut->nextMember());
1345
                for (; nn < lomax; nn++)
1346
                        dfs.printf("<td></td>");
1347
                dfs.printf("</tr>\n");
1348
        }
1349
        //dfs.printf("</LiveVarTable>\n");
1350
        dfs.printf("</table>\n");
1351
}
1352
 
1353
 
1354
 
1355
 
1356
 
1357
 
1358
 

powered by: WebSVN 2.1.0

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