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

Subversion Repositories thor

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 robfinch
#ifndef _TYPES_H
2
#define _TYPES_H
3
 
4
// ============================================================================
5
//        __
6
//   \\__/ o\    (C) 2012-2018  Robert Finch, Waterloo
7
//    \  __ /    All rights reserved.
8
//     \/_//     robfinch<remove>@finitron.ca
9
//       ||
10
//
11
// CC64 - 'C' derived language compiler
12
//  - 64 bit CPU
13
//
14
// This source file is free software: you can redistribute it and/or modify 
15
// it under the terms of the GNU Lesser General Public License as published 
16
// by the Free Software Foundation, either version 3 of the License, or     
17
// (at your option) any later version.                                      
18
//                                                                          
19
// This source file is distributed in the hope that it will be useful,      
20
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
21
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
22
// GNU General Public License for more details.                             
23
//                                                                          
24
// You should have received a copy of the GNU General Public License        
25
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
26
//                                                                          
27
// ============================================================================
28
//
29
class Operand;
30
class ENODE;
31
class Statement;
32
class BasicBlock;
33
class Instruction;
34
class Var;
35
class CSE;
36
class CSETable;
37
class Operand;
38
class SYM;
39
class Function;
40
class OCODE;
41
class PeepList;
42
 
43
class CompilerType
44
{
45
public:
46
        static CompilerType *alloc();
47
};
48
 
49
class MBlk
50
{
51
        static MBlk *first;
52
public:
53
        MBlk *next;
54
        static void ReleaseAll();
55
        static void *alloc(int sz);
56
};
57
 
58
struct slit {
59
    struct slit     *next;
60
    int             label;
61
    char            *str;
62
        char                    *nmspace;
63
};
64
 
65
struct scase {
66
        int label;
67
        int64_t val;
68
};
69
 
70
struct clit {
71
    struct clit *next;
72
    int     label;
73
        int             num;
74
    scase   *cases;
75
        char    *nmspace;
76
};
77
 
78
class C64PException
79
{
80
public:
81
        int errnum;
82
        int data;
83
        C64PException(int e, int d) { errnum = e; data = d; };
84
};
85
 
86
 
87
struct typ;
88
class Statement;
89
 
90
class TYP;
91
class SYM;
92
class TypeArray;
93
 
94
class DerivedMethod
95
{
96
public:
97
  int typeno;
98
  DerivedMethod *next;
99
  std::string *name;
100
};
101
 
102
// Class for representing tables. Small footprint.
103
 
104
class TABLE {
105
public:
106
        int head, tail;
107
        int base;
108
        int owner;
109
        static SYM *match[100];
110
        static int matchno;
111
        TABLE();
112
        static void CopySymbolTable(TABLE *dst, TABLE *src);
113
        void insert(SYM* sp);
114
        SYM *Find(std::string na,bool opt);
115
        int Find(std::string na);
116
        int Find(std::string na,__int16,TypeArray *typearray, bool exact);
117
        int FindRising(std::string na);
118
        TABLE *GetPtr(int n);
119
        void SetOwner(int n) { owner = n; };
120
        int GetHead() { return head; };
121
        void SetHead(int p) { head = p; };
122
        void SetTail(int p) { tail = p; };
123
        void Clear() { head = tail = base = 0; };
124
        void CopyTo(TABLE *dst) {
125
                dst->head = head;
126
                dst->tail = tail;
127
        };
128
        void MoveTo(TABLE *dst) {
129
                CopyTo(dst);
130
                Clear();
131
        };
132
        void SetBase(int b) { base = b; };
133
};
134
 
135
class PeepList
136
{
137
public:
138
        OCODE *head;
139
        OCODE *tail;
140
public:
141
        void Add(OCODE *cd);
142
        int Count(OCODE *pos);
143
        static OCODE *FindLabel(int64_t i);
144
        static void InsertBefore(OCODE *an, OCODE *cd);
145
        static void InsertAfter(OCODE *an, OCODE *cd);
146
        void RemoveCompilerHints2();
147
        void Remove();
148
 
149
        void loadHex(std::ifstream& ifs);
150
        void storeHex(txtoStream& ofs);
151
};
152
 
153
class PeepOpt
154
{
155
public:
156
        static void SetLabelReference();
157
        static void EliminateUnreferencedLabels();
158
};
159
 
160
class Function
161
{
162
public:
163
        unsigned int valid : 1;
164
        unsigned int IsPrototype : 1;
165
        unsigned int IsTask : 1;
166
        unsigned int IsInterrupt : 1;
167
        unsigned int IsNocall : 1;
168
        unsigned int IsPascal : 1;
169
        unsigned int IsLeaf : 1;
170
        unsigned int DoesThrow : 1;
171
        unsigned int UsesNew : 1;
172
        unsigned int UsesPredicate : 1;
173
        unsigned int IsVirtual : 1;
174
        unsigned int IsInline : 1;
175
        unsigned int UsesTemps : 1;             // uses temporary registers
176
        unsigned int UsesStackParms : 1;
177
        uint8_t NumRegisterVars;
178
        unsigned __int8 NumParms;
179
        unsigned __int8 numa;                   // number of stack parameters (autos)
180
        int stkspace;                                   // stack space used by function
181
        int argbot;
182
        int tempbot;
183
        TABLE proto;
184
        TABLE params;
185
        Statement *prolog;
186
        Statement *epilog;
187
        unsigned int stksize;
188
        CSETable *csetbl;
189
        SYM *sym;
190
        SYM *parms;                                           // List of parameters associated with symbol
191
        SYM *nextparm;
192
        DerivedMethod *derivitives;
193
        uint64_t mask, rmask;
194
        uint64_t fpmask, fprmask;
195
        uint64_t vmask, vrmask;
196
        BasicBlock *RootBlock;
197
        BasicBlock *LastBlock;
198
        BasicBlock *ReturnBlock;
199
        Var *varlist;
200
        PeepList pl;                                    // under construction
201
        OCODE *spAdjust;                                // place where sp adjustment takes place
202
        OCODE *rcode;
203
public:
204
        int GetTempBot() { return (tempbot); };
205
        void CheckParameterListMatch(Function *s1, Function *s2);
206
        bool CheckSignatureMatch(Function *a, Function *b) const;
207
        TypeArray *GetParameterTypes();
208
        TypeArray *GetProtoTypes();
209
        void PrintParameterTypes();
210
        std::string *BuildSignature(int opt = 0);
211
        Function *FindExactMatch(int mm);
212
        static Function *FindExactMatch(int mm, std::string name, int rettype, TypeArray *typearray);
213
        bool HasRegisterParameters();
214
        bool ProtoTypesMatch(Function *sym);
215
        bool ProtoTypesMatch(TypeArray *typearray);
216
        bool ParameterTypesMatch(Function *sym);
217
        bool ParameterTypesMatch(TypeArray *typearray);
218
        void BuildParameterList(int *num, int*numa);
219
        void AddParameters(SYM *list);
220
        void AddProto(SYM *list);
221
        void AddProto(TypeArray *);
222
        void AddDerived();
223
 
224
        void CheckForUndefinedLabels();
225
        void Summary(Statement *);
226
        Statement *ParseBody();
227
        void Init(int nump, int numa);
228
        int Parse();
229
        void InsertMethod();
230
 
231
        void SaveGPRegisterVars();
232
        void SaveFPRegisterVars();
233
        void SaveRegisterVars();
234
        void SaveRegisterArguments();
235
        void RestoreGPRegisterVars();
236
        void RestoreFPRegisterVars();
237
        void RestoreRegisterVars();
238
        void RestoreRegisterArguments();
239
        void SaveTemporaries(int *sp, int *fsp);
240
        void RestoreTemporaries(int sp, int fsp);
241
 
242
        void UnlinkStack();
243
 
244
        // Code generation
245
        void SetupReturnBlock();
246
        bool GenDefaultCatch();
247
        void GenReturn(Statement *stmt);
248
        void Gen();
249
 
250
        void CreateVars();
251
        void ComputeLiveVars();
252
        void DumpLiveVars();
253
};
254
 
255
class SYM {
256
public:
257
        int id;
258
        int parent;
259
        int next;
260
        std::string *name;
261
        std::string *name2;
262
        std::string *name3;
263
        std::string *shortname;
264
        std::string *mangledName;
265
        char nameext[4];
266
        char *realname;
267
        char *stkname;
268
    __int8 storage_class;
269
        unsigned int pos : 4;                   // position of the symbol (param, auto or return type)
270
        // Function attributes
271
        Function *fi;
272
        // Auto's are handled by compound statements
273
        TABLE lsyms;              // local symbols (goto labels)
274
        unsigned int IsParameter : 1;
275
        unsigned int IsRegister : 1;
276
        unsigned int IsAuto : 1;
277
        unsigned int isConst : 1;
278
        unsigned int IsKernel : 1;
279
        unsigned int IsPrivate : 1;
280
        unsigned int IsUndefined : 1;  // undefined function
281
        unsigned int ctor : 1;
282
        unsigned int dtor : 1;
283
        ENODE *initexp;
284
        __int16 reg;
285
    union {
286
        int64_t i;
287
        uint64_t u;
288
        double f;
289
        uint16_t wa[8];
290
        char *s;
291
    } value;
292
        Float128 f128;
293
        TYP *tp;
294
    Statement *stmt;
295
 
296
        static SYM *Copy(SYM *src);
297
        SYM *Find(std::string name);
298
        int FindNextExactMatch(int startpos, TypeArray *);
299
        SYM *FindRisingMatch(bool ignore = false);
300
        std::string *GetNameHash();
301
        std::string *BuildSignature(int opt);
302
        static SYM *GetPtr(int n);
303
        SYM *GetParentPtr();
304
        void SetName(std::string nm) {
305
       name = new std::string(nm);
306
       name2 = new std::string(nm);
307
       name3 = new std::string(nm);
308
           if (mangledName == nullptr)
309
                   mangledName = new std::string(nm);
310
        };
311
        void SetNext(int nxt) { next = nxt; };
312
        int GetNext() { return next; };
313
        SYM *GetNextPtr();
314
        int GetIndex();
315
        void SetType(TYP *t) {
316
                if (t == (TYP *)0x500000005) {
317
                        printf("Press key\n");
318
                        getchar();
319
        }
320
        else
321
                tp = t;
322
} ;
323
        void SetStorageOffset(TYP *head, int nbytes, int al, int ilc, int ztype);
324
        int AdjustNbytes(int nbytes, int al, int ztype);
325
};
326
 
327
class TYP {
328
public:
329
    e_bt type;
330
        __int16 typeno;                 // number of the type
331
        unsigned int val_flag : 1;       /* is it a value type */
332
        unsigned int isArray : 1;
333
        unsigned int isUnsigned : 1;
334
        unsigned int isShort : 1;
335
        unsigned int isVolatile : 1;
336
        unsigned int isIO : 1;
337
        unsigned int isConst : 1;       // const in declaration
338
        unsigned int isResv : 1;
339
        __int16 precision;                      // precision of the numeric in bits
340
        int8_t          bit_width;
341
        int8_t          bit_offset;
342
        int8_t          ven;                    // vector element number
343
        long        size;
344
        int8_t dimen;
345
        int numele;                                     // number of elements in array / vector length
346
        TABLE lst;
347
        int btp;
348
        TYP *GetBtp();
349
        static TYP *GetPtr(int n);
350
        int GetIndex();
351
        int GetHash();
352
        static int GetSize(int num);
353
        int GetElementSize();
354
        static int GetBasicType(int num);
355
        std::string *sname;
356
        unsigned int alignment;
357
        static TYP *Make(int bt, int siz);
358
        static TYP *Copy(TYP *src);
359
        bool IsScalar();
360
        bool IsFloatType() const { return (type==bt_quad || type==bt_float || type==bt_double || type==bt_triple); };
361
        bool IsVectorType() const { return (type==bt_vector); };
362
        bool IsUnion() const { return (type==bt_union); };
363
        bool IsStructType() const { return (type==bt_struct || type==bt_class || type==bt_union); };
364
        bool IsAggregateType() const { return (IsStructType() | isArray); };
365
        static bool IsSameType(TYP *a, TYP *b, bool exact);
366
        void put_ty();
367
 
368
        int Alignment();
369
        int walignment();
370
        int roundAlignment();
371
        int roundSize();
372
 
373
        ENODE *BuildEnodeTree();
374
 
375
        // Initialization
376
        int64_t InitializeArray();
377
        int64_t InitializeStruct();
378
        int64_t InitializeUnion();
379
        int64_t Initialize(int64_t val);
380
        int64_t Initialize();
381
 
382
        // GC support
383
        bool FindPointer();
384
        bool FindPointerInStruct();
385
        bool IsSkippable();
386
};
387
 
388
class TypeArray
389
{
390
public:
391
        int types[40];
392
        __int16 preg[40];
393
        int length;
394
        TypeArray();
395
        void Add(int tp, __int16 regno);
396
        void Add(TYP *tp, __int16 regno);
397
        bool IsEmpty();
398
        bool IsEqual(TypeArray *);
399
        bool IsLong(int);
400
        bool IsShort(int);
401
        bool IsChar(int);
402
        bool IsByte(int);
403
        bool IsInt(int);
404
        void Clear();
405
        TypeArray *Alloc();
406
        void Print(txtoStream *);
407
        void Print();
408
        std::string *BuildSignature();
409
};
410
 
411
class ENODE {
412
public:
413
        enum e_node nodetype;
414
        enum e_bt etype;
415
        long      esize;
416
        TYP *tp;
417
        SYM *sym;
418
        __int8 constflag;
419
        unsigned int segment : 4;
420
        unsigned int predreg : 4;
421
        unsigned int isVolatile : 1;
422
        unsigned int isIO : 1;
423
        unsigned int isUnsigned : 1;
424
        unsigned int isCheckExpr : 1;
425
        unsigned int isPascal : 1;
426
        ENODE *vmask;
427
        __int8 bit_width;
428
        __int8 bit_offset;
429
        __int8 scale;
430
        // The following could be in a value union
431
        int64_t i;
432
        double f;
433
        double f1, f2;
434
        Float128 f128;
435
        std::string *sp;
436
        std::string *msp;
437
        std::string *udnm;                      // undecorated name
438
        void *ctor;
439
        void *dtor;
440
        ENODE *p[3];
441
 
442
        ENODE *Clone();
443
 
444
        void SetType(TYP *t) { tp = t; if (t) etype = t->type; };
445
        bool IsPtr() { return (etype == bt_pointer || etype == bt_struct || etype == bt_union || etype == bt_class); };
446
        bool IsFloatType() { return (etype == bt_double || etype == bt_quad || etype == bt_float || etype == bt_triple); };
447
        bool IsUnsignedType() { return (etype == bt_ubyte || etype == bt_uchar || etype == bt_ushort || etype == bt_ulong || etype == bt_pointer); };
448
        bool IsBitfield();
449
        static bool IsEqualOperand(Operand *a, Operand *b);
450
        char fsize();
451
        long GetReferenceSize();
452
 
453
        static bool IsEqual(ENODE *a, ENODE *b);
454
 
455
        // Optimization
456
        void scanexpr(int duse);
457
        void repexpr();
458
 
459
        // Code generation
460
        Operand *GenIndex();
461
        Operand *GenHook(int flags, int size);
462
        Operand *GenShift(int flags, int size, int op);
463
        Operand *GenDivMod(int flags, int size, int op);
464
        Operand *GenUnary(int flags, int size, int op);
465
        Operand *GenBinary(int flags, int size, int op);
466
        Operand *GenAssignShift(int flags, int size, int op);
467
        Operand *GenAssignAdd(int flags, int size, int op);
468
        Operand *GenAssignLogic(int flags, int size, int op);
469
        Operand *GenLand(int flags, int op);
470
 
471
        void PutConstant(txtoStream& ofs, unsigned int lowhigh, unsigned int rshift);
472
        void PutConstantHex(txtoStream& ofs, unsigned int lowhigh, unsigned int rshift);
473
        static ENODE *GetConstantHex(std::ifstream& ifs);
474
};
475
 
476
 
477
class Operand : public CompilerType
478
{
479
public:
480
        int num;                                        // number of the operand
481
        unsigned int mode;
482
        unsigned int preg : 12;         // primary virtual register number
483
        unsigned int sreg : 12;         // secondary virtual register number (indexed addressing modes)
484
        unsigned short int pregs;       // subscripted register number
485
        unsigned short int sregs;
486
        unsigned int segment : 4;
487
        unsigned int defseg : 1;
488
        unsigned int tempflag : 1;
489
        unsigned int type : 16;
490
        char FloatSize;
491
        unsigned int isUnsigned : 1;
492
        unsigned int lowhigh : 2;
493
        unsigned int isVolatile : 1;
494
        unsigned int isPascal : 1;
495
        unsigned int rshift : 8;
496
        unsigned int isPtr : 1;
497
        short int pdeep;                // previous stack depth on allocation
498
        short int deep;           /* stack depth on allocation */
499
        short int deep2;
500
        ENODE *offset;
501
        int8_t scale;
502
        Operand *next;                  // For extended sizes (long)
503
public:
504
        Operand *Clone();
505
        static bool IsEqual(Operand *ap1, Operand *ap2);
506
        char fpsize();
507
 
508
        void GenZeroExtend(int isize, int osize);
509
        void GenSignExtend(int isize, int osize, int flags);
510
        void MakeLegal(int flags, int size);
511
 
512
        // Storage
513
        void PutAddressMode(txtoStream& ofs);
514
        void store(txtoStream& fp);
515
        void storeHex(txtoStream& fp);
516
        static Operand *loadHex(std::ifstream& fp);
517
        void load(std::ifstream fp);
518
};
519
 
520
// Output code structure
521
 
522
class OCODE : public CompilerType
523
{
524
public:
525
        OCODE *fwd, *back, *comment;
526
        BasicBlock *bb;
527
        Instruction *insn;
528
        short opcode;
529
        short length;
530
        unsigned int segment : 4;
531
        unsigned int isVolatile : 1;
532
        unsigned int isReferenced : 1;  // label is referenced by code
533
        unsigned int remove : 1;
534
        unsigned int remove2 : 1;
535
        unsigned int leader : 1;
536
        short pregreg;
537
        short predop;
538
        int loop_depth;
539
        Operand *oper1, *oper2, *oper3, *oper4;
540
        __int16 phiops[100];
541
public:
542
        static OCODE *MakeNew();
543
        static OCODE *Clone(OCODE *p);
544
        static bool IsEqualOperand(Operand *a, Operand *b) { return (Operand::IsEqual(a, b)); };
545
        void MarkRemove() { remove = true; };
546
        void MarkRemove2() { remove2 = true; };
547
        bool HasTargetReg() const;
548
        int GetTargetReg(int *rg1, int *rg2) const;
549
        bool HasSourceReg(int) const;
550
        //Edge *MakeEdge(OCODE *ip1, OCODE *ip2);
551
        // Optimizations
552
        void OptMove();
553
        void OptRedor();
554
 
555
        static OCODE *loadHex(std::ifstream& ifs);
556
        void store(txtoStream& ofs);
557
        void storeHex(txtoStream& ofs);
558
};
559
 
560
// Control Flow Graph
561
// For now everything in this class is static and there are no member variables
562
// to it.
563
class CFG
564
{
565
public:
566
        static void Create();
567
        static void CalcDominatorTree();
568
        static void CalcDominanceFrontiers();
569
        static void InsertPhiInsns();
570
        static OCODE *FindLabel(int64_t i) { return (PeepList::FindLabel(i)); };
571
        static void Rename();
572
        static void Search(BasicBlock *);
573
        static void Subscript(Operand *oper);
574
        static int WhichPred(BasicBlock *x, int y);
575
};
576
 
577
 
578
/*      output code structure   */
579
/*
580
OCODE {
581
        OCODE *fwd, *back, *comment;
582
        short opcode;
583
        short length;
584
        unsigned int isVolatile : 1;
585
        unsigned int isReferenced : 1;  // label is referenced by code
586
        unsigned int remove : 1;
587
        short pregreg;
588
        short predop;
589
        Operand *oper1, *oper2, *oper3, *oper4;
590
};
591
typedef OCODE OCODE;
592
*/
593
 
594
class IntStack
595
{
596
public:
597
        int *stk;
598
        int sp;
599
        int size;
600
public:
601
        static IntStack *MakeNew(int sz) {
602
                IntStack *s;
603
                s = (IntStack *)allocx(sizeof(IntStack));
604
                s->stk = (int *)allocx(sz * sizeof(int));
605
                s->sp = sz;
606
                s->size = sz;
607
                return (s);
608
        }
609
        static IntStack *MakeNew() {
610
                return (MakeNew(1000));
611
        }
612
        void push(int v) {
613
                if (sp > 0) {
614
                        sp--;
615
                        stk[sp] = v;
616
                }
617
                else
618
                        throw new C64PException(ERR_STACKFULL, 0);
619
        };
620
        int pop() {
621
                int v = 0;
622
                if (sp < size) {
623
                        v = stk[sp];
624
                        sp++;
625
                        return (v);
626
                }
627
                throw new C64PException(ERR_STACKEMPTY, 0);
628
        };
629
        int tos() {
630
                return (stk[sp]);
631
        };
632
        bool IsEmpty() { return (sp == size); };
633
};
634
 
635
class Edge : public CompilerType
636
{
637
public:
638
        bool backedge;
639
        Edge *next;
640
        Edge *prev;
641
        BasicBlock *src;
642
        BasicBlock *dst;
643
};
644
 
645
class BasicBlock : public CompilerType
646
{
647
public:
648
        int num;
649
        Edge *ohead;
650
        Edge *otail;
651
        Edge *ihead;
652
        Edge *itail;
653
        Edge *dhead;
654
        Edge *dtail;
655
public:
656
        int length;             // number of instructions
657
        unsigned int changed : 1;
658
        int depth;
659
        CSet *gen;              // use
660
        CSet *kill;             // def
661
        CSet *LiveIn;
662
        CSet *LiveOut;
663
        CSet *live;
664
        CSet *MustSpill;
665
        CSet *NeedLoad;
666
        CSet *DF;               // dominance frontier
667
        int HasAlready;
668
        int Work;
669
        static CSet *livo;
670
        BasicBlock *next;
671
        BasicBlock *prev;
672
        OCODE *code;
673
        OCODE *lcode;
674
public:
675
        static BasicBlock *MakeNew();
676
        static BasicBlock *Blockize(OCODE *start);
677
        Edge *MakeOutputEdge(BasicBlock *dst);
678
        Edge *MakeInputEdge(BasicBlock *src);
679
        Edge *MakeDomEdge(BasicBlock *dst);
680
        static void Unite(int father, int son);
681
        void ComputeLiveVars();
682
        void AddLiveOut(BasicBlock *ip);
683
        bool IsIdom(BasicBlock *b);
684
        void ExpandReturnBlocks();
685
 
686
        void UpdateLive(int);
687
        void CheckForDeaths(int r);
688
        static void ComputeSpillCosts();
689
        static void InsertMove(int reg, int rreg, int blk);
690
        void BuildLivesetFromLiveout();
691
        static void DepthSort();
692
        static bool Coalesce();
693
        void InsertSpillCode(int reg, int64_t offs);
694
        void InsertFillCode(int reg, int64_t offs);
695
        void Color();
696
        static void ColorAll();
697
};
698
 
699
class Map
700
{
701
public:
702
        int newnums[512];
703
};
704
 
705
// A "tree" is a "range" in Briggs terminology
706
class Tree : public CompilerType
707
{
708
public:
709
        int var;
710
        int num;
711
        CSet *blocks;
712
        int degree;
713
        int lattice;
714
        bool spill;
715
        __int8 color;
716
        __int8 regclass;                // 1 = integer, 2 = floating point, 4 = vector
717
        // Cost accounting
718
        float loads;
719
        float stores;
720
        float copies;
721
        float others;
722
        bool infinite;
723
        float cost;
724
        static int treeno;
725
public:
726
        Tree() { };
727
        static Tree *MakeNew();
728
        void ClearCosts();
729
        float SelectRatio() { return (cost / (float)degree); };
730
};
731
 
732
class Forest
733
{
734
public:
735
        short int treecount;
736
        Tree *trees[520];
737
        Function *func;
738
        CSet low, high;
739
        IntStack *stk;
740
        short int map[512];
741
        short int pass;
742
        // Cost accounting
743
        float loads;
744
        float stores;
745
        float copies;
746
        float others;
747
        bool infinite;
748
        float cost;
749
public:
750
        Forest() { stk = IntStack::MakeNew(100000); };
751
        Tree *MakeNewTree();
752
        Tree *PlantTree(Tree *t);
753
        void ClearCosts() {
754
                int r;
755
                for (r = 0; r < treecount; r++)
756
                        trees[r]->ClearCosts();
757
        }
758
        void ClearCut() {
759
                int r;
760
                for (r = 0; r < treecount; r++) {
761
                        delete trees[r];
762
                        trees[r] = nullptr;
763
                }
764
        };
765
        void CalcRegclass();
766
        void SummarizeCost();
767
        void Renumber();
768
        void push(int n) { stk->push(n); };
769
        int pop() { return (stk->pop()); };
770
        void Simplify();
771
        void Color();
772
        void Select() { Color(); };
773
        int SelectSpillCandidate();
774
        int GetSpillCount();
775
        int GetRegisterToSpill(int tree);
776
        bool SpillCode();
777
        bool IsAllTreesColored();
778
};
779
 
780
 
781
class Var : public CompilerType
782
{
783
public:
784
        Var *next;
785
        int num;
786
        int cnum;
787
        Forest trees;
788
        CSet *forest;
789
        CSet *visited;
790
        IntStack *istk;
791
        int subscript;
792
        int64_t spillOffset;    // offset in stack where spilled
793
        static int nvar;
794
public:
795
        static Var *MakeNew();
796
        void GrowTree(Tree *, BasicBlock *);
797
        // Create a forest for a specific Var
798
        void CreateForest();
799
        // Create a forest for each Var object
800
        static void CreateForests();
801
        static void Renumber(int old, int nw);
802
        static void RenumberNeg();
803
        static Var *Find(int);
804
        static Var *Find2(int);
805
        static Var *FindByCnum(int);
806
        static Var *FindByMac(int reg);
807
        static Var *FindByTreeno(int tn);
808
        static CSet *Find3(int reg, int blocknum);
809
        static int FindTreeno(int reg, int blocknum);
810
        static int PathCompress(int reg, int blocknum, int *);
811
        static void DumpForests(int);
812
        void Transplant(Var *);
813
        static bool Coalesce2();
814
        Var *GetVarToSpill(CSet *exc);
815
};
816
 
817
class IGraph
818
{
819
public:
820
        int *bitmatrix;
821
        short int *degrees;
822
        int **vecs;
823
        int size;
824
        int K;
825
        Forest *frst;
826
        int pass;
827
public:
828
        ~IGraph();
829
        void Destroy();
830
        void MakeNew(int n);
831
        void ClearBitmatrix();
832
        void Clear();
833
        int BitIndex(int x, int y, int *intndx, int *bitndx);
834
        void Add(int x, int y);
835
        void Add2(int x, int y);
836
        void AddToLive(BasicBlock *b, Operand *ap, OCODE *ip);
837
        void AddToVec(int x, int y);
838
        void InsertArgumentMoves();
839
        bool Remove(int n);
840
        static int FindTreeno(int reg, int blocknum) { return (Var::FindTreeno(reg, blocknum)); };
841
        bool DoesInterfere(int x, int y);
842
        int Degree(int n) { return ((int)degrees[n]); };
843
        int *GetNeighbours(int n, int *count) { if (count) *count = degrees[n]; return (vecs[n]); };
844
        void Unite(int father, int son);
845
        void Fill();
846
        void AllocVecs();
847
        void BuildAndCoalesce();
848
        void Print(int);
849
};
850
 
851
 
852
class Instruction
853
{
854
public:
855
        char *mnem;             // mnemonic
856
        short opcode;   // matches OCODE opcode
857
        short extime;   // execution time, divide may take hundreds of cycles
858
        unsigned int targetCount : 2;
859
        bool memacc;    // instruction accesses memory
860
        unsigned int regclass1; // register class 1=integer,2=floating point,4=vector
861
        unsigned int regclass2; // register class 1=integer,2=floating point,4=vector
862
        unsigned int regclass3; // register class 1=integer,2=floating point,4=vector
863
        unsigned int regclass4; // register class 1=integer,2=floating point,4=vector
864
public:
865
        bool IsFlowControl();
866
        bool IsSetInsn() {
867
                return (opcode == op_seq || opcode == op_sne
868
                        || opcode == op_slt || opcode == op_sle || opcode == op_sgt || opcode == op_sge
869
                        || opcode == op_sltu || opcode == op_sleu || opcode == op_sgtu || opcode == op_sgeu
870
                        );
871
        };
872
        static Instruction *FindByMnem(std::string& mn);
873
        static Instruction *Get(int op);
874
        inline bool HasTarget() { return (targetCount != 0); };
875
        int store(txtoStream& ofs);
876
        int storeHex(txtoStream& ofs);  // hex intermediate representation
877
        int storeHRR(txtoStream& ofs);  // human readable representation
878
        static Instruction *loadHex(std::ifstream& fp);
879
        int load(std::ifstream& ifs, Instruction **p);
880
};
881
 
882
class CSE {
883
public:
884
        short int nxt;
885
    ENODE *exp;           /* optimizable expression */
886
    short int       uses;           /* number of uses */
887
    short int       duses;          /* number of dereferenced uses */
888
    short int       reg;            /* AllocateRegisterVarsd register */
889
    unsigned int    voidf : 1;      /* cannot optimize flag */
890
    unsigned int    isfp : 1;
891
public:
892
        int OptimizationDesireability();
893
};
894
 
895
class CSETable
896
{
897
public:
898
        CSE table[500];
899
        short int csendx;
900
        short int cseiter;
901
public:
902
        CSE *First() { cseiter = 0; return &table[0]; };
903
        CSE *Next() { cseiter++; return (cseiter < csendx ? &table[cseiter] : nullptr); };
904
        void Clear() { ZeroMemory(table, sizeof(table)); csendx = 0; };
905
        void Sort(int (*)(const void *a, const void *b));
906
        void Assign(CSETable *);
907
        int voidauto2(ENODE *node);
908
        CSE *InsertNode(ENODE *node, int duse);
909
        CSE *Search(ENODE *node);
910
 
911
        void GenerateRegMask(CSE *csp, uint64_t *mask, uint64_t *rmask);
912
        int AllocateGPRegisters();
913
        int AllocateFPRegisters();
914
        int AllocateVectorRegisters();
915
        int AllocateRegisterVars();
916
        void InitializeTempRegs();
917
 
918
        int Optimize(Statement *);
919
 
920
        // Debugging
921
        void Dump();
922
};
923
 
924
class Statement {
925
public:
926
        __int8 stype;
927
        Statement *outer;
928
        Statement *next;
929
        Statement *prolog;
930
        Statement *epilog;
931
        bool nkd;
932
        int predreg;            // assigned predicate register
933
        ENODE *exp;         // condition or expression
934
        ENODE *initExpr;    // initialization expression - for loops
935
        ENODE *incrExpr;    // increment expression - for loops
936
        Statement *s1, *s2; // internal statements
937
        int num;                        // resulting expression type (hash code for throw)
938
        int64_t *label;     // label number for goto
939
        int64_t *casevals;      // case values
940
        TABLE ssyms;            // local symbols associated with statement
941
        char *fcname;       // firstcall block var name
942
        char *lptr;
943
        unsigned int prediction : 2;    // static prediction for if statements
944
        int depth;
945
 
946
        // Parsing
947
        static Statement *ParseStop();
948
        static Statement *ParseCompound();
949
        static Statement *ParseDo();
950
        static Statement *ParseFor();
951
        static Statement *ParseForever();
952
        static Statement *ParseFirstcall();
953
        static Statement *ParseIf();
954
        static Statement *ParseCatch();
955
        static Statement *ParseCase();
956
        int CheckForDuplicateCases();
957
        static Statement *ParseThrow();
958
        static Statement *ParseContinue();
959
        static Statement *ParseAsm();
960
        static Statement *ParseTry();
961
        static Statement *ParseExpression();
962
        static Statement *ParseLabel();
963
        static Statement *ParseWhile();
964
        static Statement *ParseUntil();
965
        static Statement *ParseGoto();
966
        static Statement *ParseReturn();
967
        static Statement *ParseBreak();
968
        static Statement *ParseSwitch();
969
        static Statement *Parse();
970
 
971
        // Optimization
972
        void scan();
973
        void scan_compound();
974
        void repcse();
975
        void repcse_compound();
976
 
977
        // Code generation
978
        void GenMixedSource();
979
        void GenerateStop();
980
        void GenerateAsm();
981
        void GenerateFirstcall();
982
        void GenerateWhile();
983
        void GenerateUntil();
984
        void GenerateFor();
985
        void GenerateForever();
986
        void GenerateIf();
987
        void GenerateDoWhile();
988
        void GenerateDoUntil();
989
        void GenerateDoLoop();
990
        void GenerateDoOnce();
991
        void GenerateCompound();
992
        void GenerateCase();
993
        void GenerateTry();
994
        void GenerateThrow();
995
        void GenerateCheck();
996
        void GenerateFuncBody();
997
        void GenerateSwitch();
998
        void GenerateLinearSwitch();
999
        void GenerateTabularSwitch();
1000
        void Generate();
1001
 
1002
};
1003
 
1004
class Stringx
1005
{
1006
public:
1007
  std::string str;
1008
};
1009
 
1010
class Declaration
1011
{
1012
        static void SetType(SYM *sp);
1013
public:
1014
        Declaration *next;
1015
        static void AssignParameterName();
1016
        static int declare(SYM *parent,TABLE *table,int al,int ilc,int ztype);
1017
        static void ParseVoid();
1018
        static void ParseConst();
1019
        static void ParseTypedef();
1020
        static void ParseNaked();
1021
        static void ParseShort();
1022
        static void ParseLong();
1023
        static void ParseInt();
1024
        static void ParseInt80();
1025
        static void ParseInt64();
1026
        static void ParseInt40();
1027
        static void ParseInt32();
1028
        static void ParseInt16();
1029
        static void ParseInt8();
1030
        static void ParseByte();
1031
        static void ParseFloat();
1032
        static void ParseDouble();
1033
        static void ParseTriple();
1034
        static void ParseFloat128();
1035
        static void ParseVector();
1036
        static void ParseVectorMask();
1037
        static SYM *ParseId();
1038
        static void ParseDoubleColon(SYM *sp);
1039
        static void ParseBitfieldSpec(bool isUnion);
1040
        static int ParseSpecifier(TABLE *table);
1041
        static SYM *ParsePrefixId();
1042
        static SYM *ParsePrefixOpenpa(bool isUnion);
1043
        static SYM *ParsePrefix(bool isUnion);
1044
        static void ParseSuffixOpenbr();
1045
        static void ParseSuffixOpenpa(Function *);
1046
        static SYM *ParseSuffix(SYM *sp);
1047
        static void ParseFunctionAttribute(Function *sym);
1048
 
1049
        static int GenStorage(int nbytes, int al, int ilc);
1050
};
1051
 
1052
class StructDeclaration : public Declaration
1053
{
1054
public:
1055
        static void ParseMembers(SYM * sym, TYP *tp, int ztype);
1056
        static int Parse(int ztype);
1057
};
1058
 
1059
class ClassDeclaration : public Declaration
1060
{
1061
public:
1062
        static void ParseMembers(SYM * sym, int ztype);
1063
        static int Parse(int ztype);
1064
};
1065
 
1066
class AutoDeclaration : public Declaration
1067
{
1068
public:
1069
        static void Parse(SYM *parent, TABLE *ssyms);
1070
};
1071
 
1072
class ParameterDeclaration : public Declaration
1073
{
1074
public:
1075
        static int Parse(int);
1076
};
1077
 
1078
class GlobalDeclaration : public Declaration
1079
{
1080
public:
1081
        void Parse();
1082
        static GlobalDeclaration *Make();
1083
};
1084
 
1085
class Compiler
1086
{
1087
public:
1088
        int typenum;
1089
        int symnum;
1090
        short int funcnum;
1091
        SYM symbolTable[32768];
1092
        Function functionTable[3000];
1093
        TYP typeTable[32768];
1094
        short int pass;
1095
public:
1096
        GlobalDeclaration *decls;
1097
        Compiler();
1098
        void compile();
1099
        int PreprocessFile(char *nm);
1100
        void CloseFiles();
1101
        void AddStandardTypes();
1102
        void AddBuiltinFunctions();
1103
        static int GetReturnBlockSize() { return (4 * 8); };
1104
        int main2(int c, char **argv);
1105
        void storeSymbols(std::ostream& ofs);
1106
};
1107
 
1108
class CPU
1109
{
1110
public:
1111
        bool SupportsPush;
1112
        bool SupportsPop;
1113
        bool SupportsLink;
1114
        bool SupportsUnlink;
1115
};
1116
 
1117
//#define SYM     struct sym
1118
//#define TYP     struct typ
1119
//#define TABLE   struct stab
1120
 
1121
 
1122
#endif

powered by: WebSVN 2.1.0

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