📄 tac.cpp
字号:
/* File: tac.cc
* -----------
* Implementation of Tac class and subclasses.
*/
#include "tac.h"
#include "declaration.h"
#include "type.h"
#include "mips.h"
#include "Ex86asm.h"
const char *Tac::opName[Tac::NumOps];
Tac::TacToWhat Tac::toWhat;
void Tac::InitOpNames() {
if (!opName[Add]) {
opName[Add] = "+"; // we're lazy and only fill in the ones we use
opName[Sub] = "-";
opName[Mul] = "*";
opName[Div] = "/";
opName[Mod] = "%";
opName[Eq] = "==";
opName[Less] = "<";
opName[And] = "&&";
opName[Or] = "||";
}
}
Tac::Tac(OpCode c) : code(c) { InitOpNames();}
Tac::OpCode Tac::OpCodeForName(const char *name) {
InitOpNames();
for (int i = 0; i < NumOps; i++)
if (opName[i] && !strcmp(opName[i], name))
return (OpCode)i;
Assert(0);
return Add; // can't get here, but compiler doesn't know that
}
const char *Tac::NameForOpCode(OpCode c) {
InitOpNames();
Assert(opName[c] != NULL);
return opName[c];
}
void Tac::Print() {
printf("\t%s ;\n", printed);
}
void Tac::Emit(Mips *mips) {
if (*printed)
mips->Emit("# %s", printed); // emit TAC as comment into assembly
EmitSpecific(mips);
}
void Tac::Emit(Ex86asm *x86) {
if (*printed)
x86->Emit("; %s", printed); // emit TAC as comment into assembly
EmitSpecific(x86);
}
LoadConstant::LoadConstant(Declaration *d, int v)
: Tac(Tac::LoadConstant), dst(d), val(v) {
sprintf(printed, "%s = %d", dst->GetName(), val);
}
void LoadConstant::EmitSpecific(Mips *mips) {
mips->EmitLoadConstant(dst, val);
}
void LoadConstant::EmitSpecific(Ex86asm *x86) {
x86->EmitLoadConstant(dst, val);
}
////////////////////////////////////////
LoadStringConstant::LoadStringConstant(Declaration *d, const char *s)
: Tac(Tac::LoadStringConstant), dst(d) {
const char *quote = (*s == '"') ? "" : "\"";
str = new char[strlen(s) + 2*strlen(quote) + 1];
sprintf(str, "%s%s%s", quote, s, quote);
quote = (strlen(str) > 50) ? "...\"" : "";
sprintf(printed, "%s = %.50s%s", dst->GetName(), str, quote);
}
void LoadStringConstant::EmitSpecific(Mips *mips) {
mips->EmitLoadStringConstant(dst, str);
}
void LoadStringConstant::EmitSpecific(Ex86asm *x86) {
x86->EmitLoadStringConstant(dst, str);
}
//////////////////////////////////////
LoadLabel::LoadLabel(Declaration *d, const char *l)
: Tac(Tac::LoadLabel), dst(d), label(strdup(l)) {
sprintf(printed, "%s = %s", dst->GetName(), label);
}
void LoadLabel::EmitSpecific(Mips *mips) {
mips->EmitLoadLabel(dst, label);
}
void LoadLabel::EmitSpecific(Ex86asm *x86) {
x86->EmitLoadLabel(dst, label);
}
///////////////////////////////////////
Assign::Assign(Declaration *d, Declaration *s)
: Tac(Tac::Assign), dst(d), src(s) {
sprintf(printed, "%s = %s", dst->GetName(), src->GetName());
}
void Assign::EmitSpecific(Mips *mips) {
mips->EmitCopy(dst, src);
}
void Assign::EmitSpecific(Ex86asm *x86) {
x86->EmitCopy(dst, src);
}
//////////////////////////
Load::Load(Declaration *d, Declaration *s, int off )
: Tac(Tac::Load), dst(d), src(s), offset(off) {
if (offset)
sprintf(printed, "%s = *(%s + %d)", dst->GetName(), src->GetName(), offset);
else
sprintf(printed, "%s = *(%s)", dst->GetName(), src->GetName());
}
void Load::EmitSpecific(Mips *mips) {
mips->EmitLoad(dst, src, offset);
}
void Load::EmitSpecific(Ex86asm *x86) {
x86->EmitLoad(dst, src, offset);
}
/////////////////////////////////////
Store::Store(Declaration *d, Declaration *s, int off )
: Tac(Tac::Store), dst(d), src(s), offset(off) {
if (offset)
sprintf(printed, "*(%s + %d) = %s", dst->GetName(), offset, src->GetName());
else
sprintf(printed, "*(%s) = %s", dst->GetName(), src->GetName());
}
void Store::EmitSpecific(Mips *mips) {
mips->EmitStore(dst, src, offset);
}
void Store::EmitSpecific(Ex86asm *x86) {
x86->EmitStore(dst, src, offset);
}
/////////////////////////
BinaryOp::BinaryOp(OpCode c, Declaration *d, Declaration *o1, Declaration *o2)
: Tac(c), dst(d), op1(o1), op2(o2) {
sprintf(printed, "%s = %s %s %s", dst->GetName(), op1->GetName(),
NameForOpCode(code), op2->GetName());
}
void BinaryOp::EmitSpecific(Mips *mips) {
mips->EmitBinaryOp(code, dst, op1, op2);
}
void BinaryOp::EmitSpecific(Ex86asm *x86) {
x86->EmitBinaryOp(code, dst, op1, op2);
}
//////////////////////////
Label::Label(const char *l) : Tac(Tac::Label), label(strdup(l)) {
*printed = '\0';
}
void Label::Print() {
printf("%s:\n", label);
}
void Label::EmitSpecific(Mips *mips) {
mips->EmitLabel(label);
}
void Label::EmitSpecific(Ex86asm *x86) {
if( !isFunLabel)
x86->EmitLabel(label);
}
/////////////////////////////////////
Goto::Goto(const char *l) : Tac(Tac::Goto), label(strdup(l)) {
sprintf(printed, "Goto %s", label);
}
void Goto::EmitSpecific(Mips *mips) {
mips->EmitGoto(label);
}
void Goto::EmitSpecific(Ex86asm *x86) {
x86->EmitGoto(label);
}
/////////////////////////////
IfZ::IfZ(Declaration *te, const char *l)
: Tac(Tac::IfZ), test(te), label(strdup(l)) {
sprintf(printed, "IfZ %s Goto %s", test->GetName(), label);
}
void IfZ::EmitSpecific(Mips *mips) {
mips->EmitIfZ(test, label);
}
void IfZ::EmitSpecific(Ex86asm *x86) {
x86->EmitIfZ(test, label);
}
/////////////////////////////////
BeginFunc::BeginFunc(Declaration *f) : Tac(Tac::BeginFunc), fn(f) {
sprintf(printed,"BeginFunc");
}
void BeginFunc::EmitSpecific(Mips *mips) {
Assert(fn->GetStackFrameSize() != Unassigned);
mips->EmitBeginFunction(fn->GetStackFrameSize());
}
void BeginFunc::EmitSpecific(Ex86asm *x86) {
Assert(fn->GetStackFrameSize() != Unassigned);
x86->EmitBeginFunction(fn,fn->GetStackFrameSize());
}
/////////////////////
EndFunc::EndFunc(Declaration *f) : Tac(Tac::EndFunc) ,fn(f){
sprintf(printed, "EndFunc");
}
void EndFunc::EmitSpecific(Mips *mips) {
mips->EmitEndFunction();
}
void EndFunc::EmitSpecific(Ex86asm *x86) {
x86->EmitEndFunction(fn);
}
///////////////////////
Return::Return(Declaration *v) : Tac(Tac::Return), val(v) {
sprintf(printed, "Return %s", val? val->GetName() : "");
}
void Return::EmitSpecific(Mips *mips) {
mips->EmitReturn(val);
}
void Return::EmitSpecific(Ex86asm *x86) {
x86->EmitReturn(val);
}
///////////////////////
PushParam::PushParam(Declaration *p)
: Tac(Tac::PushParam), param(p) {
sprintf(printed, "PushParam %s", param->GetName());
}
void PushParam::EmitSpecific(Mips *mips) {
mips->EmitArg(param);
}
void PushParam::EmitSpecific(Ex86asm *x86) {
x86->EmitArg(param);
}
////////////////////////
LCall::LCall(const char *l, int paramBytes, Declaration *d)
: Tac(Tac::LCall), label(strdup(l)), dst(d), numBytesOfParameters(paramBytes) {
sprintf(printed, "%s%sLCall %s", dst? dst->GetName(): "", dst?" = ":"", label);
}
void LCall::EmitSpecific(Mips *mips) {
mips->EmitLCall(dst, label, numBytesOfParameters);
}
void LCall::EmitSpecific(Ex86asm *x86) {
x86->EmitLCall(dst, label , numBytesOfParameters);
}
////////////////////////
ACall::ACall(Declaration *ma, int paramBytes, Declaration *d)
: Tac(Tac::ACall), dst(d), methodAddr(ma), numBytesOfParameters(paramBytes) {
sprintf(printed, "%s%sACall %s", dst? dst->GetName(): "", dst?" = ":"",
methodAddr->GetName());
}
void ACall::EmitSpecific(Mips *mips) {
mips->EmitACall(dst, methodAddr, numBytesOfParameters);
}
void ACall::EmitSpecific(Ex86asm *x86) {
x86->EmitACall(dst, methodAddr, numBytesOfParameters);
}
/////////////////////
VTable::VTable(const char *l, DeclList *m)
: Tac(Tac::VTable), methods(m), label(strdup(l)) {
sprintf(printed, "VTable for class %s", l);
}
void VTable::Print() {
printf("VTable %s =\n", label);
for (int i = 0; i < methods->NumElements(); i++)
printf("\t%s,\n", methods->Nth(i)->GetFunctionLabel());
printf("; \n");
}
void VTable::EmitSpecific(Mips *mips) {
mips->EmitVTable(label, methods);
}
void VTable::EmitSpecific(Ex86asm *x86) {
x86->EmitVTable(label, methods);
}
////////////////////////
void GVar::EmitSpecific(Ex86asm *x86) {
x86->EmitGVar(decl);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -