|
|
|
@ -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:
|
|
|
|
|