From 521d50fcc059a8c7793f8535f7e88a0cfb7b2009 Mon Sep 17 00:00:00 2001 From: Austin Sun Date: Sun, 22 May 2016 15:28:49 -0700 Subject: [PATCH] wol --- ast_expr.cc | 208 +++++++++++++++++++++++++++++++++++------------------------- ast_expr.h | 1 + 2 files changed, 124 insertions(+), 85 deletions(-) diff --git a/ast_expr.cc b/ast_expr.cc index 00279d7..edc0124 100644 --- a/ast_expr.cc +++ b/ast_expr.cc @@ -12,21 +12,21 @@ IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { value = val; } -void IntConstant::PrintChildren(int indentLevel) { +void IntConstant::PrintChildren(int indentLevel) { printf("%d", value); } FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { value = val; } -void FloatConstant::PrintChildren(int indentLevel) { +void FloatConstant::PrintChildren(int indentLevel) { printf("%g", value); } BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { value = val; } -void BoolConstant::PrintChildren(int indentLevel) { +void BoolConstant::PrintChildren(int indentLevel) { printf("%s", value ? "true" : "false"); } @@ -104,7 +104,7 @@ void ArrayAccess::PrintChildren(int indentLevel) { subscript->Print(indentLevel+1, "(subscript) "); } -FieldAccess::FieldAccess(Expr *b, Identifier *f) +FieldAccess::FieldAccess(Expr *b, Identifier *f) : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { Assert(f != NULL); // b can be be NULL (just means no explicit base) base = b; @@ -246,71 +246,6 @@ llvm::Value* CompoundExpr::Emit() { //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- -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; @@ -328,14 +263,7 @@ llvm::Value * AssignExpr::Emit(){ 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 ( operationStr.compare("+=") == 0 ){ if (leftval->getType()->isIntegerTy()){ storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); if (vd){ @@ -358,6 +286,13 @@ llvm::Value * AssignExpr::Emit(){ } } } + else 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::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); @@ -381,46 +316,46 @@ llvm::Value * AssignExpr::Emit(){ } } } - else if ( operationStr.compare("*=") == 0 ){ + else if ( operationStr.compare("/=") == 0 ){ if (leftval->getType()->isIntegerTy()){ - storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); + 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::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); + storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); if (vd){ vd->AddressStore(storeInst); return storeInst; } } else{ - storeInst = convert(leftval, rightval, 3); + storeInst = convert(leftval, rightval, 2); if (vd){ vd->AddressStore(storeInst); return storeInst; } } } - else if ( operationStr.compare("/=") == 0 ){ + else if ( operationStr.compare("*=") == 0 ){ if (leftval->getType()->isIntegerTy()){ - storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); + 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::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); + storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); if (vd){ vd->AddressStore(storeInst); return storeInst; } } else{ - storeInst = convert(leftval, rightval, 2); + storeInst = convert(leftval, rightval, 3); if (vd){ vd->AddressStore(storeInst); return storeInst; @@ -477,3 +412,106 @@ llvm::Value* VarExpr::AddressStore(llvm::Value *store){ llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, "",irgen.GetBasicBlock()); return storeInst; } + +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++){ + if(*ptr =='x'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); + } + else if(*ptr='y'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); + } + else if(*ptr='z'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); + } + else if(*ptr='w'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); + } + } + + llvm::Value * element; + llvm::Value * rightop = rightval; + llvm::Value * baseF = f->getBase()->Emit(); + llvm::Value * storeInst = f->getBase()->Emit(); + + + for (int i = 0; i < maskI.size(); i++){ + element = llvm::ExtractElementInst::Create (baseF, 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 * FieldAccess::Emit(){ + char * mask = this->getField()->GetName(); + char * ptr = mask; + + llvm::Type * intTyp = irgen.GetIntType(); + std::vector maskI; + + int count = 0; + int valNum = -1; + for(; *ptr; ptr++){ + if(*ptr =='x'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); + valNum=0; + } + else if(*ptr='y'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); + valNum=1; + } + else if(*ptr='z'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); + valNum=2; + } + else if(*ptr='w'){ + maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); + valNum=3; + } + count++; + } + llvm::Value * elemt; + llvm::Value * baseF = base->Emit(); + if (count == 1){ + elemt = llvm::ExtractElementInst::Create (baseF, maskI.back(), "", irgen.GetBasicBlock()); + return elemt; + } + llvm::ConstantVector *masky = (llvm::ConstantVector *) llvm::ConstantVector::get(maskI); + llvm::Value * val = new llvm::ShuffleVectorInst(baseF,llvm::UndefValue::get(baseF->getType()), masky,"",irgen.GetBasicBlock()); + return val; +} \ No newline at end of file diff --git a/ast_expr.h b/ast_expr.h index 5d11ccb..1eb1e02 100644 --- a/ast_expr.h +++ b/ast_expr.h @@ -217,6 +217,7 @@ class FieldAccess : public LValue void PrintChildren(int indentLevel); Expr * getBase(){ return base; } Identifier * getField(){return field;} + llvm::Value *Emit(); }; /* Like field access, call is used both for qualified base.field() -- 1.9.1