/* isx - intermediate sequenced executable - the paraFlow * intermediate code. A fairly standard "three address code" * that is a lower level representation than the parse tree but * higher level than actual machine code. The format is * opCode dest left right * which is interpreted as * dest = left opCode right * so * + x 3 8 represents x = 3 + 8 * * t1 t2 t3 represents t1 = t2*t3 * = x y represents x = y * - u v represents u = -v */ #ifndef ISX_H #define ISX_H #ifndef PFSTRUCT_H #include "pfStruct.h" #endif #ifndef DLIST_H #include "dlist.h" #endif #ifndef ISXLIVEVAR_H #include "isxLiveVar.h" #endif #ifndef PFTOKEN_H #include "pfToken.h" #endif enum isxOpType /* What sort of operation - corresponds roughly to an * assembly language instruction without type or address * considerations. */ { poInit, /* Variable initialization */ poAssign, /* Variable (re)assignment */ poPlus, /* dest = left + right */ poMinus, /* dest = left - right */ poMul, /* dest = left * right */ poDiv, /* dest = left / right */ poMod, /* dest = left % right */ poBitAnd, /* dest = left & right */ poBitOr, /* dest = left | right */ poBitXor, /* dest = left ^ right */ poShiftLeft, /* dest = left << right */ poShiftRight,/* dest = left >> right */ poNegate, /* dest = -left */ poFlipBits, /* dest = ~left */ poInput, /* An input parameter: dest = left */ poCall, /* Call subroutine: call left */ poOutput, /* An output parameter dest = left */ poLabel, /* Some misc label. */ poLoopStart, /* Start of some sort of loop. Also a label. */ poLoopEnd, /* End of some sort of loop. Also a label. */ poCondStart, /* Start of if/else or case */ poCondCase, /* Start of a particular case. Also a label. */ poCondEnd, /* End of if/else or case. Also a label. */ poJump, /* Unconditional jump */ poBeq, /* Branch if two things are the same. */ poBne, /* Branch if two things are different. */ poBlt, /* Branch if a < b. */ poBle, /* Branch if a <= b. */ poBgt, /* Branch if a > b. */ poBge, /* Branch if a >= b. */ poBz, /* Branch if a == 0 */ poBnz, /* Branch if a != 0 */ poFuncStart,/* Declare start of function */ poFuncEnd, /* Declare end of function. */ poReturnVal,/* Declare return value. */ poCast, /* Convert from one type to another. */ poVarInit, /* Variable type initialization */ poVarAssign, /* Variable type (re)assignment */ poVarInput, /* Variable type subroutine input */ poIndirect, /* dest = *(left+right) where right may be null */ }; char *isxOpTypeToString(enum isxOpType val); /* Convert isxValType to string. */ enum isxValType /* Simplified value type system. */ { ivZero, ivBit, ivByte, ivShort, ivInt, ivLong, ivFloat, ivDouble, ivString, ivObject, ivVar, ivJump, }; char *isxValTypeToString(enum isxValType val); /* Convert isxValType to string. */ enum isxValType isxValTypeFromTy(struct pfCompile *pfc, struct pfType *ty); /* Return isxValType corresponding to pfType */ enum isxAddressType /* Address type */ { iadZero, iadConst, iadRealVar, iadTempVar, iadInStack, iadOutStack, iadOperator, iadLabel, iadLoopInfo, iadReturnVar, iadRecodedType, }; struct isxLoopVar /* Information about a "hot" variable in a loop. That is one * that is live at end of loop, and used within the loop. */ { struct isxLoopVar *next; struct isxAddress *iad; /* Associated address including weight. */ struct isxReg *reg; /* Assigned register if any. */ }; struct isxLoopInfo /* Information associated with a loop. */ { struct isxLoopInfo *next; /* Younger sibling. */ struct isxLoopInfo *children;/* Eldest child. */ struct dlNode *start; /* Loop start instruction. */ struct dlNode *end; /* Loop end instruction. */ int instructionCount; /* Number of instructions in loop */ struct isxAddress *iad; /* Associated isxAddress */ int iteration; /* How many times we've been through */ struct isxLoopVar *hotLive; /* Variables good to put in registers, * most important first. */ }; #ifdef OLD struct ctar; #endif /* OLD */ struct isxToken /* A smaller version of lexical token for code generator. */ { enum pfTokType type; /* Token type. */ union pfTokVal val; /* Type-dependent value. */ }; union isxAddressVal /* Variable part of an isx code address. */ { struct isxToken isxTok; /* For constants */ struct pfVar *var; /* For real vars */ int tempMemLoc; /* Memory location for temps, 0 for none */ int ioOffset; /* Stack offset. */ struct isxLoopInfo *loopy; /* Information on loop */ }; struct isxAddress /* A piece of data somewhere */ { struct isxAddress *next; /* For multivalued functions */ char *name; /* Not allocated here. */ enum isxAddressType adType;/* Address type */ enum isxValType valType; /* Value type */ union isxAddressVal val; /* Address value */ int stackOffset; /* Stack offset. */ struct isxReg *reg; /* Register if any */ float weight; /* Number of uses, scaled for loops */ int recodedType; /* Recoded run-time type info. */ bool isVar; /* True if it is a variable type */ }; struct isxLiveVar; /* Defined in isxLiveVar.h */ struct isx /* An instruction in our intermediate language. */ { enum isxOpType opType; /* Opcode - add, mul, branch, etc. */ struct isxAddress *dest; /* Destination address */ struct isxAddress *left; /* Left (or only) source address. */ struct isxAddress *right; /* Right (optional) source address.*/ struct isxLiveVar *liveList;/* List of live vars after instruction. */ void *cpuInfo; /* Machine-specific register info. */ }; struct isxReg /* Represents a CPU register. */ { int size; /* Size in bytes. */ char *byteName; /* Register name when used for bytes. */ char *shortName; /* Register name when used for shorts. */ char *intName; /* Register name when used for ints. */ char *longName; /* Register name when used for longs. */ char *floatName; /* Register name when used for floats. */ char *doubleName; /* Register name when used for doubles. */ char *pointerName; /* Register name when used for pointers. */ struct isxAddress *contents; /* What if anything register holds */ struct isxAddress *reserved; /* Register reserved for this var. */ bool isLive; /* True if holds live variable. */ int regIx; /* Index of register in regInfo */ }; struct isx *isxNew(struct pfCompile *pfc, enum isxOpType opType, struct isxAddress *dest, struct isxAddress *left, struct isxAddress *right); /* Make new isx instruction. */ struct isx *isxAddNew(struct pfCompile *pfc, enum isxOpType opType, struct isxAddress *dest, struct isxAddress *left, struct isxAddress *right, struct dlList *iList); /* Make new isx instruction, and hang it on iList */ char *isxRegName(struct isxReg *reg, enum isxValType valType); /* Get name of reg for given type. */ struct isxAddress *isxTempVarAddress(struct pfCompile *pfc, struct hash *hash, double weight, enum isxValType valType); /* Create a new temporary var */ struct isxAddress *isxConstAddress(enum pfTokType tokType, union pfTokVal tokVal, enum isxValType valType); /* Get place to put constant. */ struct isxAddress *isxRecodedTypeAddress(struct pfCompile *pfc, struct pfType *type); /* Get type info. */ struct isxAddress *isxIoAddress(int offset, enum isxValType valType, enum isxAddressType adType); /* Return reference to an io stack address */ struct isxAddress *isxCallAddress(char *name); /* Create reference to a function */ struct isxAddress *isxTempLabelAddress(struct pfCompile *pfc); /* Create reference to a temporary label for jumping to. */ void isxAddressDump(struct isxAddress *iad, FILE *f); /* Print variable name or n/a */ void isxDump(struct isx *isx, FILE *f); /* Dump out isx code */ void isxDumpList(struct dlList *list, FILE *f); /* Dump all of isx in list */ void isxStatement(struct pfCompile *pfc, struct pfParse *pp, struct hash *varHash, double weight, struct dlList *iList); /* Generate intermediate code for statement. */ void isxAddReturnInfo(struct pfCompile *pfc, struct pfParse *outTuple, struct hash *varHash, struct dlList *iList); /* Add instructions for return parameters. */ struct isxList /* A list of instructions, and a list of loop information */ { struct dlList *iList; /* List of instructions */ struct isxLoopInfo *loopList; /* List of loops */ }; struct isxList *isxListNew(); /* Create new empty isxList */ struct isxList *isxModuleVars(struct pfCompile *pfc, struct pfParse *module); /* Convert module-level and static function variables to an isxList */ struct isxList *isxCodeFunction(struct pfCompile *pfc, struct pfParse *funcPp); /* Generate code for a function */ #define isxPrefixC "_" /* Prefix before symbols shared with C. */ #endif /* ISX_H */