| 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
|