// Generator.h: interface for the CGenerator class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_GENERATOR_H__BD70E9FD_FD67_4D65_9D95_983152A8C543__INCLUDED_) #define AFX_GENERATOR_H__BD70E9FD_FD67_4D65_9D95_983152A8C543__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // note, to invoke objdump from command line use // objdump --target binary --architecture=i386 --disassemble-all dump.obj > dump.txt #include "TarmacGlobals.h" #include "Profiler.h" #include "x86asm.h" #include "CodeCache.h" typedef enum { EAX = 0, ECX, EDX, EBX, ESP, EBP, ESI, EDI } x86Registers; // // Details of where each armlet variable is held // typedef enum { locNATIVEREGISTER, locNATIVEFLAG, locMEMORY } variableLocations; struct VariableLocation { uint32 location; uint8 reg; // x86 reg if their }; struct RegisterAllocation { VariableLocation varLocation[maxTemp]; // array of all locations of variables uint8 registerUse[EDI]; // array of x86 registers detailing which armlet variable is in each one }; // // Structure for keeping track of gotos to be backpatched // struct GotoBackpatch { uint32 armletNumber; // armlet number goto was jumping to uint32 gotoPtr; // offset to instruction in nativeChunk->area }; class CGenerator { public: void setCodeCache(CCodeCache* aCodeCache); void generate(Armlet** aArmletChunk, int aTotalArmlets); CGenerator(); virtual ~CGenerator(); private: void allocateRegAllocation(RegisterAllocation* oldRegAl, RegisterAllocation* newRegAl); RegisterAllocation* copyRegisterAllocation(RegisterAllocation* sourceRA); void spillAll(); void regAllocateChangeBlock(Armlet* armlet); void shedConstantPool(); void genCmp2(Armlet* armlet); void genSub6(Armlet* armlet); void genSub1(Armlet* armlet); CLinkedList* gotoPatchList; // list of forward-referencing-gotos to be backpatched void addConstant(uint8 variable, uint32 value); void genMov2(uint8 rd, uint32 value); void genCmp1(Armlet* armlet); void genMov1(Armlet* armlet); void postFlags(uint8 outflags, uint8 nativeChanged, uint8 destReg); void preFlags(uint8 outflags, uint8 nativeChanged); uint8 getVariableOffset(uint8 variable); uint8 getVariableInRegister(uint8 variable); uint8 putVariableInRegister(uint8 variable); void genAdd4(Armlet* armlet, uint8 rb, uint8 rc); void genAdd3(Armlet* armlet, uint8 ra, uint8 rb); void genAdd2(Armlet* armlet, uint8 rb, uint32 value); void genAdd1(Armlet* armlet, uint32 value); inline void updateAddFlags(uint32 result, uint32 operand1, uint32 operand2); inline void updateSubFlags(uint32 result, uint32 operand1, uint32 operand2); inline void updateNZFlags(uint32 value); RegisterAllocation* regAl; // current register allocation RegisterAllocation** basicBlockRA; // array of reg allocations for each leader of basic block BOOL constantValid[maxTemp]; // flag for whether entry is valid or not uint32 constantPool[maxTemp]; // create constant pool uint32* armletNumberToAreaAddress; // array of code area addresses from armlet numbers uint defaultAreaSize; // size of buffer to allocate initially void assemble(const int wasteArgument, ... ); int totalArmlets; // number of armlets in chunk Armlet** armletChunk; // buffer of armlets representing the chunk NativeChunk* nativeChunk; // current native chunk being recompiled int armletCounter; // number of next armlet to be recompiled void chooseStw(Armlet* armlet); void chooseLdw(Armlet* armlet); void chooseStb(Armlet* armlet); void chooseLdb(Armlet* armlet); void chooseMul(Armlet* armlet); void chooseRor(Armlet* armlet); void chooseAsr(Armlet* armlet); void chooseLsr(Armlet* armlet); void chooseLsl(Armlet* armlet); void chooseOrr(Armlet* armlet); void chooseSbc(Armlet* armlet); void chooseAdc(Armlet* armlet); void chooseAdd(Armlet* armlet); void chooseSub(Armlet* armlet); void chooseEor(Armlet* armlet); void chooseAnd(Armlet* armlet); void chooseRrx(Armlet* armlet); void chooseCmn(Armlet* armlet); void chooseCmp(Armlet* armlet); void chooseTeq(Armlet* armlet); void chooseTst(Armlet* armlet); void chooseMvn(Armlet* armlet); void chooseMov(Armlet* armlet); void chooseIntCheck(Armlet* armlet); void chooseGetPC(Armlet* armlet); void chooseMovc(Armlet* armlet); void chooseSetPC(Armlet* armlet); void chooseSetTrans(Armlet* armlet); void chooseClearTrans(Armlet* armlet); void chooseLeave(Armlet* armlet); void chooseGoto(Armlet* armlet, uint8 conditionCode); void chooseRule(Armlet* armlet); }; #endif // !defined(AFX_GENERATOR_H__BD70E9FD_FD67_4D65_9D95_983152A8C543__INCLUDED_)