/* * File */ #include #include #include #include "AssemblerCode.h" #include "debug.h" extern int msglevel; using namespace std; AssemblerCode::AssemblerCode() { } AssemblerCode::~AssemblerCode() { } unsigned int AssemblerCode::GetStatementCount() const { return (statements.size()); } MStatement *AssemblerCode::GetStatement(unsigned int i) { return (statements.at(i)); } // Appends a statement void AssemblerCode::AppendStatement(MStatement *stmt) { statements.push_back(stmt); } // Inserts a statement before the i-th statement void AssemblerCode::InsertStatement(MStatement *stmt, unsigned int i) { statements.insert(statements.begin() + i, stmt); } // Removes the i-th statement void AssemblerCode::RemoveStatement(unsigned int i) { statements.erase(statements.begin() + i); } // Dump void AssemblerCode::Dump(FILE *file) { msglevel = 100; for (unsigned int i = 0; i < GetStatementCount(); ++i) { MStatement *stmt = GetStatement(i); /* Always valid values */ const char *opcode = MOperatorToString(stmt->GetOperator()); const char *hash = "\t# "; const char *comment = stmt->GetComment(); if (comment == NULL) { comment = ""; hash = ""; } string label = stmt->GetLabel(); if (label.empty()) { label = ""; } if (stmt->GetOperator() == MOP_LABEL) { pmesg(100, "===MStatement MOP_LABEL ===\n"); fprintf(file, "%s:\t%s%s\n", label.c_str(), hash, comment); continue; } pmesg(100, "=== MStatement ===\n"); if (stmt->GetOperand1() == NULL) { fprintf(file, "%s\t%s\t%s%s\n", label.c_str(), opcode, hash, comment); continue; } string op1 = MOperandToString(stmt->GetOperand1()); if (stmt->GetOperand2() == NULL) { fprintf(file, "%s\t%s\t%s\t%s%s\n", label.c_str(), opcode, op1.c_str(), hash, comment); continue; } string op2 = MOperandToString(stmt->GetOperand2()); if (stmt->GetOperand3() == NULL) { fprintf(file, "%s\t%s\t%s, %s\t%s%s\n", label.c_str(), opcode, op1.c_str(), op2.c_str(), hash, comment); continue; } string op3 = MOperandToString(stmt->GetOperand3()); fprintf(file, "%s\t%s\t%s, %s, %s\t%s%s\n", label.c_str(), opcode, op1.c_str(), op2.c_str(), op3.c_str(), hash, comment); } } string AssemblerCode::MOperandToString(MOperand *operand) { stringstream ss; pmesg(100, "Operand Type: "); switch (operand->GetOperandType()) { case MT_INT: // Integer immediate { pmesg(100, "MT_INT"); ss << operand->GetIntValue(); break; } case MT_REAL: // Real immediate { pmesg(100, "MT_REAL"); ss << showpoint << operand->GetRealValue(); break; } case MT_OFFSET: { pmesg(100, "MT_OFFSET"); int offset = operand->GetOffset(); const char *regstr = MRegisterTypeToString(operand->GetRegisterType()); ss << offset << '(' << regstr << ')'; break; } case MT_REGISTER: // Integer Register { pmesg(100, "MT_REGISTER"); const char *regstr = MRegisterTypeToString(operand->GetRegisterType()); ss << regstr; break; } case MT_ADDRESS: // Address operand { pmesg(100, "MT_REGISTER"); ss << operand->GetAddress(); break; } case MT_LABEL: { pmesg(100, "MT_LABEL"); ss << operand->GetLabel(); break; } default: return "?"; } pmesg(100, ": %s\n", ss.str().c_str()); return (ss.str()); } const char *AssemblerCode::MRegisterTypeToString(MRegisterType op) { const char *registertype_str[] = { "$0", // ZERO 0 "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra", "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31" }; return registertype_str[op]; }