Project

General

Profile

RE: A small C compiler generating Eigen IR ยป codegen.patch

Florian Negele, 17 June 2024 23:46

View differences:

ecc/codegen.cpp
case ND_VAR:
// Variable-length array, which is always local.
if (node->var->ty->kind == TY_VLA) {
r0 = e->Move(Code::Reg(types[ptr],Code::RFP, node->var->offset)); // mov ptr $0, ptr $fp%+d"
r0 = (Code::Reg(types[ptr],Code::RFP, node->var->offset)); // mov ptr $0, ptr $fp%+d"
return;
}
// Local variable
if (node->var->is_local) {
r0 = e->Move(Code::Reg(types[ptr],Code::RFP, node->var->offset)); // mov ptr $0, ptr $fp%+d"
r0 = (Code::Reg(types[ptr],Code::RFP, node->var->offset)); // mov ptr $0, ptr $fp%+d"
return;
}
......
#endif
// Function
if (node->ty->kind == TY_FUNC) {
r0 = e->Move(Code::Adr(types[fun],node->var->name)); // mov fun $0, fun @%s
r0 = (Code::Adr(types[fun],node->var->name)); // mov fun $0, fun @%s
return;
}
// Global variable
r0 = e->Move(Code::Adr(types[ptr],node->var->name)); // mov ptr $0, ptr @%s
r0 = (Code::Adr(types[ptr],node->var->name)); // mov ptr $0, ptr @%s
return;
case ND_DEREF:
gen_expr(node->lhs);
......
}
break;
case ND_VLA_PTR:
r0 = e->Move(Code::Reg(types[ptr], Code::RFP,node->var->offset)); // mov ptr $0, ptr $fp%+d
r0 = (Code::Reg(types[ptr], Code::RFP,node->var->offset)); // mov ptr $0, ptr $fp%+d
return;
}
......
}
const Code::Type type = getCodeType(ty);
r0 = e->MakeRegister(e->MakeMemory(type,r0)); // mov %s $0, %s [$0]
r0 = (e->MakeMemory(type,r0)); // mov %s $0, %s [$0]
// like Move, but reuses the register of r0 instead of allocating another one and really move
}
// Store $0 to the address on top of the stack
static void store(Type *ty) {
Smop tmpReg = pop(types[ptr]);
static void store(Type *ty, const Smop& tmpReg) {
switch (ty->kind) {
case TY_STRUCT:
......
if (to->kind == TY_BOOL) {
Code::Type type = getCodeType(from);
Code::Emitter2::Label yes = e->CreateLabel();
e->BranchEqual(yes,Code::Imm(type,0),reg); // breq +2, %s 0, %s %s", type, type, reg
type = getCodeType(to);
reg = e->Move(Code::Imm(type,0)); // mov %s %s, %s 0", type, reg, type
Code::Emitter2::Label end = e->CreateLabel();
e->Branch(end); // br +1
yes();
reg = e->Move(Code::Imm(type,1)); // mov %s %s, %s 1", type, reg, type
end();
e->BranchNotEqual(yes,Code::Imm(type,0),reg); // breq +2, %s 0, %s %s", type, type, reg
r0 = e->Set (yes, Code::Imm(type,0), Code::Imm(type,1));
return;
}
......
// If the return type is a large struct/union, the caller passes
// a pointer to a buffer as if it were the first argument.
if (node->ret_buffer) {
r0 = e->Move(Code::Reg(types[ptr], Code::RFP,node->ret_buffer->offset)); // mov ptr $0, ptr $fp%+d
r0 = Code::Reg(types[ptr], Code::RFP,node->ret_buffer->offset); // mov ptr $0, ptr $fp%+d
pushRes(types[ptr]);
stack++;
}
......
case TY_FLOAT:
case TY_DOUBLE:
case TY_LDOUBLE: {
r0 = e->Move(Code::FImm(ty,node->fval)); // mov %s $0, %s %Lf
r0 = (Code::FImm(ty,node->fval)); // mov %s $0, %s %Lf
return;
}
}
r0 = e->Move(Code::Imm(ty,node->val)); // mov %s $0, %s %Ld
r0 = (Code::Imm(ty,node->val)); // mov %s $0, %s %Ld
return;
}
case ND_NEG: {
......
gen_addr(node->lhs);
return;
case ND_ASSIGN:
case ND_ASSIGN: {
gen_addr(node->lhs);
pushRes(types[ptr]);
auto lhs = std::move (r0);
gen_expr(node->rhs);
if (node->lhs->kind == ND_MEMBER && node->lhs->member->is_bitfield) {
......
r9 = e->Move(Code::Imm(mty,~mask)); // mov %s %s, %s %ld
r0 = e->And(e->Convert(mty,r0), r9); // and %s $0, %s $0, %s %s
r0 = e->Or(r0, rdi); // or %s $0, %s $0, %s %s
store(node->ty);
store(node->ty, lhs);
// restore from r8:
r0 = e->Move(r8); // mov %s $0, %s %s
return;
}else {
store(node->ty);
store(node->ty, lhs);
return;
}
}
case ND_STMT_EXPR:
for (Node *n = node->body; n; n = n->next)
......
return;
case ND_MEMZERO:
r0 = e->Move(Code::Reg(types[ptr],Code::RFP,node->var->offset)); // mov ptr $0, ptr $fp%+d
r0 = (Code::Reg(types[ptr],Code::RFP,node->var->offset)); // mov ptr $0, ptr $fp%+d
e->Fill(r0,Code::Imm(types[ptr],node->var->ty->size), Code::Imm(types[u1],0)); // fill ptr $0, ptr %d, u1 0
return;
case ND_COND: {
......
if( ret )
{
const Code::Type type = getCodeType(ret);
r0 = e->Move(Code::Reg(type,Code::RRes)); // mov %s $0, %s $res
r0 = (Code::Reg(type,Code::RRes)); // mov %s $0, %s $res
}
depth -= stack_slots;
......
case TY_UNION:
copy_struct_mem();
break;
case TY_VOID:
case TY_VLA:
break;
default:
e->Move (Code::Reg {getCodeType(ty), Code::RRes}, r0);
}
returnType = getCodeType(ty);
}
......
{
Smop res = Code::Reg(returnType,Code::RRes);
setInt(0,res);
}else
e->Move(Code::Reg(returnType,Code::RRes), e->Convert(returnType,r0));
}
}
e->Leave();
if( isMain )
{
pushRes(types[s4]);
e->Push(Code::Reg {returnType, Code::RRes});
e->Call(Code::Adr(types[fun],"_Exit"),0); // call fun @_Exit, 0
}else
e->Return();
    (1-1/1)