Modified something

main
Odeinjul 12 months ago
parent d9ce28b743
commit c512f5c08e
No known key found for this signature in database
GPG Key ID: E384228B2B38FFBB

@ -76,6 +76,8 @@ class IRBuilder: public SyntaxTree::Visitor
{
private:
void TypeConvert(Ptr<Value> origin, Ptr<Type> expected);
void BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp op);
void BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinaryCondOp op);
virtual void visit(SyntaxTree::InitVal &) override final;
virtual void visit(SyntaxTree::Assembly &) override final;
virtual void visit(SyntaxTree::FuncDef &) override final;

@ -74,6 +74,244 @@ Ptr<Type> GetParamType(SyntaxTree::Type type, bool isPtr = false){
}
}
void IRBuilder::BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp op){
bool isFloat = false;
int lInt, rInt;
float lFloat, rFloat;
if (dynamic_pointer_cast<Constant>(lhs) && dynamic_pointer_cast<Constant>(rhs)) {
if (dynamic_pointer_cast<ConstantFloat>(lhs) || dynamic_pointer_cast<ConstantFloat>(rhs)) {
isFloat = true;
lFloat = dynamic_pointer_cast<ConstantFloat>(lhs)->get_value();
rFloat = dynamic_pointer_cast<ConstantFloat>(rhs)->get_value();
}
else {
isFloat = false;
lInt = dynamic_pointer_cast<ConstantInt>(lhs)->get_value();
rInt = dynamic_pointer_cast<ConstantInt>(rhs)->get_value();
}
switch (op) {
case SyntaxTree::BinOp::PLUS:
if (isFloat) {
tmpInst = CONST_FLOAT(lFloat + rFloat);
} else
tmpInst = CONST_INT(lInt + rInt);
break;
case SyntaxTree::BinOp::MINUS:
if (isFloat) {
tmpInst = CONST_FLOAT(lFloat - rFloat);
} else
tmpInst = CONST_INT(lInt - rInt);
break;
case SyntaxTree::BinOp::MULTIPLY:
if (isFloat) {
tmpInst = CONST_FLOAT(lFloat * rFloat);
} else
tmpInst = CONST_INT(lInt * rInt);
break;
case SyntaxTree::BinOp::DIVIDE:
if (isFloat) {
tmpInst = CONST_FLOAT(lFloat / rFloat);
} else {
tmpInst = CONST_INT(lInt / rInt);
}
break;
case SyntaxTree::BinOp::MODULO:
if (isFloat) { ;// not support
} else {
tmpInst = CONST_INT(lInt % rInt);
}
break;
}
} else {
if (lhs->get_type()->is_pointer_type()) {
lhs = builder->create_load(lhs);
}
if (rhs->get_type()->is_pointer_type()) {
rhs = builder->create_load(rhs);
}
if (lhs->get_type()->is_float_type() &&
rhs->get_type()->is_integer_type()) {
rhs = builder->create_sitofp(rhs, FLOAT_T);
}
if (lhs->get_type()->is_integer_type() &&
rhs->get_type()->is_float_type()) {
lhs = builder->create_sitofp(lhs, FLOAT_T);
}
isFloat = lhs->get_type()->is_float_type();
switch (op) {
case SyntaxTree::BinOp::PLUS:
if (isFloat) {
tmpInst = builder->create_fadd(lhs, rhs);
} else
tmpInst = builder->create_iadd(lhs, rhs);
break;
case SyntaxTree::BinOp::MINUS:
if (isFloat) {
tmpInst = builder->create_fsub(lhs, rhs);
} else
tmpInst = builder->create_isub(lhs, rhs);
break;
case SyntaxTree::BinOp::MULTIPLY:
if (isFloat) {
tmpInst = builder->create_fmul(lhs, rhs);
} else
tmpInst = builder->create_imul(lhs, rhs);
break;
case SyntaxTree::BinOp::DIVIDE:
if (isFloat) {
tmpInst = builder->create_fdiv(lhs, rhs);
} else {
tmpInst = builder->create_isdiv(lhs, rhs);
}
break;
case SyntaxTree::BinOp::MODULO:
if (isFloat) { ;// not support
} else {
tmpInst = builder->create_isrem(lhs, rhs);
}
break;
}
}
}
void IRBuilder::BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinaryCondOp op) {
bool isFloat = false;
int lInt, rInt;
float lFloat, rFloat;
if (dynamic_pointer_cast<Constant>(lhs) && dynamic_pointer_cast<Constant>(rhs)) {
if (dynamic_pointer_cast<ConstantFloat>(lhs) || dynamic_pointer_cast<ConstantFloat>(rhs)) {
isFloat = true;
lFloat = dynamic_pointer_cast<ConstantFloat>(lhs)->get_value();
rFloat = dynamic_pointer_cast<ConstantFloat>(rhs)->get_value();
}
else {
isFloat = false;
lInt = dynamic_pointer_cast<ConstantInt>(lhs)->get_value();
rInt = dynamic_pointer_cast<ConstantInt>(rhs)->get_value();
}
switch (op) {
case SyntaxTree::BinaryCondOp::LT:
if (isFloat) {
tmpInst = CONST_INT(lFloat < rFloat);
}
else {
tmpInst = CONST_INT(lInt < rInt);
}
break;
case SyntaxTree::BinaryCondOp::LTE:
if (isFloat) {
tmpInst = CONST_INT(lFloat <= rFloat);
}
else {
tmpInst = CONST_INT(lInt <= rInt);
}
break;
case SyntaxTree::BinaryCondOp::GT:
if (isFloat) {
tmpInst = CONST_INT(lFloat > rFloat);
}
else {
tmpInst = CONST_INT(lInt > rInt);
}
break;
case SyntaxTree::BinaryCondOp::GTE:
if (isFloat) {
tmpInst = CONST_INT(lFloat >= rFloat);
}
else {
tmpInst = CONST_INT(lInt >= rInt);
}
break;
case SyntaxTree::BinaryCondOp::EQ:
if (isFloat) {
tmpInst = CONST_INT(lFloat == rFloat);
}
else {
tmpInst = CONST_INT(lInt == rInt);
}
break;
case SyntaxTree::BinaryCondOp::NEQ:
if (isFloat) {
tmpInst = CONST_INT(lFloat != rFloat);
}
else {
tmpInst = CONST_INT(lInt != rInt);
}
break;
default:
break;
}
} else {
if (lhs->get_type()->is_pointer_type()) {
lhs = builder->create_load(lhs);
}
if (rhs->get_type()->is_pointer_type()) {
rhs = builder->create_load(rhs);
}
if (lhs->get_type()->is_float_type() &&
rhs->get_type()->is_integer_type()) {
rhs = builder->create_sitofp(rhs, FLOAT_T);
}
if (lhs->get_type()->is_integer_type() &&
rhs->get_type()->is_float_type()) {
lhs = builder->create_sitofp(lhs, FLOAT_T);
}
isFloat = lhs->get_type()->is_float_type();
switch (op) {
case SyntaxTree::BinaryCondOp::LT:
if (isFloat) {
tmpInst = builder->create_fcmp_lt(lhs, rhs);
}
else {
tmpInst = builder->create_icmp_gt(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::LTE:
if (isFloat) {
tmpInst = builder->create_fcmp_le(lhs, rhs);
}
else {
tmpInst = builder->create_icmp_le(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::GT:
if (isFloat) {
tmpInst = builder->create_fcmp_gt(lhs, rhs);
}
else {
tmpInst = builder->create_icmp_gt(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::GTE:
if (isFloat) {
tmpInst = builder->create_fcmp_ge(lhs, rhs);
}
else {
tmpInst = builder->create_icmp_ge(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::EQ:
if (isFloat) {
tmpInst = builder->create_fcmp_eq(lhs, rhs);
}
else {
tmpInst = builder->create_icmp_eq(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::NEQ:
if (isFloat) {
tmpInst = builder->create_fcmp_ne(lhs, rhs);
}
else {
tmpInst = builder->create_icmp_ne(lhs, rhs);
}
break;
default:
break;
}
}
}
void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> expected) {
if (dynamic_pointer_cast<Constant>(origin) == nullptr) {
auto type = origin->get_type();
@ -121,7 +359,6 @@ void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> expected) {
}
return;
}
}
@ -549,58 +786,13 @@ void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {
}
}
// TODO
// FINISH
void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {
node.lhs->accept(*this);
auto lhs = tmpInst;
if (isAddr) {
lhs = builder->create_load(lhs);
isAddr = false;
}
node.rhs->accept(*this);
auto rhs = tmpInst;
if(isAddr){
rhs = builder->create_load(rhs);
isAddr = false;
}
switch (node.op) {
case SyntaxTree::BinOp::PLUS:
if(isFloat){
tmpInst = builder->create_fadd(lhs, rhs);
}
else
tmpInst = builder->create_iadd(lhs, rhs);
break;
case SyntaxTree::BinOp::MINUS:
if(isFloat){
tmpInst = builder->create_fsub(lhs, rhs);
}
else
tmpInst = builder->create_isub(lhs, rhs);
break;
case SyntaxTree::BinOp::MULTIPLY:
if(isFloat){
tmpInst = builder->create_fmul(lhs, rhs);
}
else
tmpInst = builder->create_imul(lhs, rhs);
break;
case SyntaxTree::BinOp::DIVIDE:
if(isFloat){
tmpInst = builder->create_fdiv(lhs, rhs);
} else {
tmpInst = builder->create_isdiv(lhs, rhs);
}
break;
case SyntaxTree::BinOp::MODULO:
if(isFloat){
;// not support
} else {
tmpInst = builder->create_isrem(lhs, rhs);
}
break;
}
BinaryExprGen(lhs, rhs, node.op);
}
// FINISH
@ -617,7 +809,7 @@ void IRBuilder::visit(SyntaxTree::UnaryExpr &node) {
} else if (constFloat != nullptr) {
tmpInst = CONST_FLOAT(-constFloat->get_value());
} else {
//TODO;
BinaryExprGen(CONST_INT(0), tmpInst, SyntaxTree::BinOp::MINUS);
}
break;
default:

Loading…
Cancel
Save