From 1b3210488e83a5db401110253d18b3c6c13ec8ec Mon Sep 17 00:00:00 2001 From: Austin Sun Date: Sun, 22 May 2016 09:35:47 -0700 Subject: [PATCH] hope this works still got some syntax --- ast_expr.cc | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- ast_expr.h | 5 ++ irgen.cc | 21 ++++++ irgen.h | 13 ++++ 4 files changed, 274 insertions(+), 1 deletion(-) diff --git a/ast_expr.cc b/ast_expr.cc index 07405e2..00279d7 100644 --- a/ast_expr.cc +++ b/ast_expr.cc @@ -135,11 +135,12 @@ void Call::PrintChildren(int indentLevel) { llvm::Value* VarExpr::Emit() { return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock()); } - +/* llvm::Value* AssignExpr::Emit() { VarExpr* ve = dynamic_cast(left); return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock()); } + */ string Operator::getToken() const { return tokenString; @@ -243,3 +244,236 @@ llvm::Value* CompoundExpr::Emit() { return NULL; } +//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- +llvm::Value * AssignExpr::AssignField(){ + FieldAccess * f = (FieldAccess *) left; + llvm::Value * rightval = right->Emit(); + string operationStr(op->getToken()); + bool isFloat = rightval->getType()->isFloatingPointTy(); + llvm::Type * intTyp = irgen.GetIntType(); + char * ptr = f->getField()->GetName();; + + std::vector maskI; + for(; *ptr; ptr++){ + switch(*ptr){ + case 'x': + maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); + break; + case 'y': + maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); + break; + case 'z': + maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); + break; + case 'w': + maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); + break; + default: + break; + } + } + llvm::Value * element; + llvm::Value * rightop = rightval; + llvm::Value * base_field = f->getBase()->Emit(); + llvm::Value * storeInst = f->getBase()->Emit(); + + + for (int i = 0; i < maskI.size(); i++){ + element = llvm::ExtractElementInst::Create (base_field, maskI[i], "", irgen.GetBasicBlock()); + if (rightval->getType()->isVectorTy()){ + rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); + } + if (!operationStr.compare("=")){ + storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); + } + if (!operationStr.compare("+=")){ + element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); + storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); + } + if (!operationStr.compare("-=")){ + element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); + storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); + } + if (!operationStr.compare("*=")){ + element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); + storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); + } + if (!operationStr.compare("/=")){ + element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock()); + storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); + } + } + VarExpr * ve = dynamic_cast(f->getBase()); + ve->AddressStore(storeInst); + if (isFloat){ + return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock()); + } + return storeInst; +} + +llvm::Value * AssignExpr::Emit(){ + llvm::Value * leftval; + llvm::Value * rightval; + + FieldAccess * f = dynamic_cast(left); + if (f){ + return this->AssignField(); + } + leftval = left->Emit(); + rightval = right->Emit(); + + string operationStr(op->getToken()); + + VarExpr * vd = dynamic_cast(left); + + llvm::Value * storeInst = NULL; + if ( operationStr.compare("=") == 0 ){ + if (vd){ + vd->AddressStore(rightval); + return rightval; + } + return ((VarExpr *) left)->AddressStore(rightval); + } + else if ( operationStr.compare("+=") == 0 ){ + if (leftval->getType()->isIntegerTy()){ + storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ + storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else{ + storeInst = convert(leftval, rightval, 0); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + } + else if ( operationStr.compare("-=") == 0 ){ + if (leftval->getType()->isIntegerTy()){ + storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ + storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else{ + storeInst = convert(leftval, rightval, 1); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + } + else if ( operationStr.compare("*=") == 0 ){ + if (leftval->getType()->isIntegerTy()){ + storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ + storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else{ + storeInst = convert(leftval, rightval, 3); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + } + else if ( operationStr.compare("/=") == 0 ){ + if (leftval->getType()->isIntegerTy()){ + storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ + storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + else{ + storeInst = convert(leftval, rightval, 2); + if (vd){ + vd->AddressStore(storeInst); + return storeInst; + } + } + } + return NULL; +} + +llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ + llvm::Type * intTyp = irgen.GetIntType(); + llvm::Type * fltTyp = irgen.GetFloatType(); + llvm::Value *idVal; + llvm::Value * element; + llvm::Value * retVal = vec; + + //get vector size + int numElements=-1; + if(vec->getType()==irgen.GetVec2Type()){ + numElements=2; + } + else if(vec->getType()==irgen.GetVec3Type()){ + numElements=3; + } + else if(vec->getType()==irgen.GetVec4Type()){ + numElements=4; + } + + for (int i = 0; i < numElements; i++){ + idVal = llvm::ConstantInt::get(intTyp, i); + element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); + if (status == 0){ + element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); + } + else if (status == 1){ + element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); + } + else if (status == 2){ + element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); + } + else{ + element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); + } + retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); + } + return retVal; +} + +llvm::Value* VarExpr::AddressStore(llvm::Value *store){ + char * varname = GetIdentifier()->GetName(); + + pair symbol = findSymbol(string(varname)); + //value of symbol + llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, "",irgen.GetBasicBlock()); + return storeInst; +} diff --git a/ast_expr.h b/ast_expr.h index e1290a0..5d11ccb 100644 --- a/ast_expr.h +++ b/ast_expr.h @@ -94,6 +94,7 @@ class VarExpr : public Expr void PrintChildren(int indentLevel); Identifier *GetIdentifier() {return id;} llvm::Value* Emit(); + llvm::Value * AddressStore(llvm::Value* store); }; class Operator : public Node @@ -160,6 +161,8 @@ class AssignExpr : public CompoundExpr AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} const char *GetPrintNameForNode() { return "AssignExpr"; } llvm::Value* Emit(); + llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status ); + llvm::Value *AssignField(); }; class PostfixExpr : public CompoundExpr @@ -212,6 +215,8 @@ class FieldAccess : public LValue FieldAccess(Expr *base, Identifier *field); //ok to pass NULL base const char *GetPrintNameForNode() { return "FieldAccess"; } void PrintChildren(int indentLevel); + Expr * getBase(){ return base; } + Identifier * getField(){return field;} }; /* Like field access, call is used both for qualified base.field() diff --git a/irgen.cc b/irgen.cc index ef3c21a..aede77d 100644 --- a/irgen.cc +++ b/irgen.cc @@ -82,3 +82,24 @@ const char *IRGenerator::TargetLayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i3 const char *IRGenerator::TargetTriple = "x86_64-redhat-linux-gnu"; +llvm::Type *IRGenerator::GetVec2Type() const{ + return llvm::VectorType::get(llvm::Type::getFloatTy(*context), 2); +} +llvm::Type *IRGenerator::GetVec3Type() const{ + return llvm::VectorType::get(llvm::Type::getFloatTy(*context), 3); +} +llvm::Type *IRGenerator::GetVec4Type() const{ + return llvm::VectorType::get(llvm::Type::getFloatTy(*context), 4); +} +llvm::Type *IRGenerator::GetMat2Type() const{ + llvm::Type *elementTy = llvm::VectorType::get(llvm::Type::getFloatTy(*context), 2); + return llvm::ArrayType::get(elementTy, 2); +} +llvm::Type *IRGenerator::GetMat3Type() const{ + llvm::Type *elementTy = llvm::VectorType::get(llvm::Type::getFloatTy(*context), 3); + return llvm::ArrayType::get(elementTy, 3); +} +llvm::Type *IRGenerator::GetMat4Type() const{ + llvm::Type *elementTy = llvm::VectorType::get(llvm::Type::getFloatTy(*context), 4); + return llvm::ArrayType::get(elementTy, 4); +} diff --git a/irgen.h b/irgen.h index 177e7f5..91115d0 100644 --- a/irgen.h +++ b/irgen.h @@ -42,6 +42,18 @@ class IRGenerator { llvm::Type *GetBoolType() const; llvm::Type *GetFloatType() const; + llvm::Type *GetVec2Type() const; + + llvm::Type *GetVec3Type() const; + + llvm::Type *GetVec4Type() const; + + llvm::Type *GetMat2Type() const; + + llvm::Type *GetMat3Type() const; + + llvm::Type *GetMat4Type() const; + private: llvm::LLVMContext *context; llvm::Module *module; @@ -54,6 +66,7 @@ class IRGenerator { static const char *TargetTriple; static const char *TargetLayout; + }; extern IRGenerator irgen; -- 1.9.1