#ifndef REGISTERMANAGER_H #define REGISTERMANAGER_H #include "Symbol.h" #include "globals.h" #include "StackFrameManager.h" #include "AssemblerCode.h" /* Keeps track of what registers are associated with symbols. Loads the appropriate registers and generates spill code if needed. */ class RegisterManager { public: // constructor RegisterManager(StackFrameManager& sfm, AssemblerCode& ac); // Get the register associated with symbol. // Register is of same type as the return type of the symbol. // Generates loading code if needed. MRegisterType GetRegister(Symbol *symbol); // Gets an integer register associated with symbol. // Generates loading code if needed. MRegisterType GetIntRegister(Symbol *symbol); // Gets a float register associated with symbol. // Generates loading code if needed. MRegisterType GetFloatRegister(Symbol *symbol); // Get temponary register, which rotates MRegisterType GetTempRegister(); // Write back all registers and unassociate all symbols. void SpillAll(); private: StackFrameManager& sfm; AssemblerCode& ac; // Find the register associated with symbol and return its index // Returns -1 if not found int FindSymbol(Symbol *symbols[], int size, Symbol *symbol) const; // Find an unused register and returns its index // Returns -1 if not found int FindUnused(Symbol *symbols[], int size) const; int PickSpillRegister(MRegisterType registers[], int size) const; // Clears the symbol associated with the register and generates spill code void SpillIntRegister(int idx); void SpillFloatRegister(int idx); void GenerateIntSpillCode(MRegisterType reg, Symbol *symbol); void GenerateFloatSpillCode(MRegisterType reg, Symbol *symbol); void GenerateIntLoadCode(MRegisterType reg, Symbol *symbol); void GenerateFloatLoadCode(MRegisterType reg, Symbol *symbol); static const int int_reg_size = 18; // number of integer registers static MRegisterType int_registers[int_reg_size]; // the integer registers that can be used Symbol *int_symbols[int_reg_size]; // symbols associated with integer registers static const int float_reg_size = 15; // number of float registers static MRegisterType float_registers[float_reg_size]; // the float registers that can be used Symbol *float_symbols[float_reg_size]; // symbols associated with integer registers static const int tmp_reg_size = 4; static MRegisterType tmp_registers[tmp_reg_size]; }; #endif /* REGISTERMANAGER_H */