Commit 43abbf64217a7ff4de3f1cb28bcbc511e0a9e9e0
1 parent
9399459476
Exists in
master
Short circuit && and ||
Showing 1 changed file with 26 additions and 8 deletions Inline Diff
ast_expr.cc
View file @
43abbf6
/* File: ast_expr.cc | 1 | 1 | /* File: ast_expr.cc | |
* ----------------- | 2 | 2 | * ----------------- | |
* Implementation of expression node classes. | 3 | 3 | * Implementation of expression node classes. | |
*/ | 4 | 4 | */ | |
5 | 5 | |||
#include <string.h> | 6 | 6 | #include <string.h> | |
#include "ast_expr.h" | 7 | 7 | #include "ast_expr.h" | |
#include "ast_type.h" | 8 | 8 | #include "ast_type.h" | |
#include "ast_decl.h" | 9 | 9 | #include "ast_decl.h" | |
#include "symtable.h" | 10 | 10 | #include "symtable.h" | |
11 | 11 | |||
IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { | 12 | 12 | IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { | |
value = val; | 13 | 13 | value = val; | |
} | 14 | 14 | } | |
void IntConstant::PrintChildren(int indentLevel) { | 15 | 15 | void IntConstant::PrintChildren(int indentLevel) { | |
printf("%d", value); | 16 | 16 | printf("%d", value); | |
} | 17 | 17 | } | |
18 | 18 | |||
FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { | 19 | 19 | FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { | |
value = val; | 20 | 20 | value = val; | |
} | 21 | 21 | } | |
void FloatConstant::PrintChildren(int indentLevel) { | 22 | 22 | void FloatConstant::PrintChildren(int indentLevel) { | |
printf("%g", value); | 23 | 23 | printf("%g", value); | |
} | 24 | 24 | } | |
25 | 25 | |||
BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { | 26 | 26 | BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { | |
value = val; | 27 | 27 | value = val; | |
} | 28 | 28 | } | |
void BoolConstant::PrintChildren(int indentLevel) { | 29 | 29 | void BoolConstant::PrintChildren(int indentLevel) { | |
printf("%s", value ? "true" : "false"); | 30 | 30 | printf("%s", value ? "true" : "false"); | |
} | 31 | 31 | } | |
32 | 32 | |||
VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { | 33 | 33 | VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { | |
Assert(ident != NULL); | 34 | 34 | Assert(ident != NULL); | |
this->id = ident; | 35 | 35 | this->id = ident; | |
} | 36 | 36 | } | |
37 | 37 | |||
void VarExpr::PrintChildren(int indentLevel) { | 38 | 38 | void VarExpr::PrintChildren(int indentLevel) { | |
id->Print(indentLevel+1); | 39 | 39 | id->Print(indentLevel+1); | |
} | 40 | 40 | } | |
41 | 41 | |||
Operator::Operator(yyltype loc, const char *tok) : Node(loc) { | 42 | 42 | Operator::Operator(yyltype loc, const char *tok) : Node(loc) { | |
Assert(tok != NULL); | 43 | 43 | Assert(tok != NULL); | |
strncpy(tokenString, tok, sizeof(tokenString)); | 44 | 44 | strncpy(tokenString, tok, sizeof(tokenString)); | |
} | 45 | 45 | } | |
46 | 46 | |||
void Operator::PrintChildren(int indentLevel) { | 47 | 47 | void Operator::PrintChildren(int indentLevel) { | |
printf("%s",tokenString); | 48 | 48 | printf("%s",tokenString); | |
} | 49 | 49 | } | |
50 | 50 | |||
bool Operator::IsOp(const char *op) const { | 51 | 51 | bool Operator::IsOp(const char *op) const { | |
return strcmp(tokenString, op) == 0; | 52 | 52 | return strcmp(tokenString, op) == 0; | |
} | 53 | 53 | } | |
54 | 54 | |||
CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) | 55 | 55 | CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) | |
: Expr(Join(l->GetLocation(), r->GetLocation())) { | 56 | 56 | : Expr(Join(l->GetLocation(), r->GetLocation())) { | |
Assert(l != NULL && o != NULL && r != NULL); | 57 | 57 | Assert(l != NULL && o != NULL && r != NULL); | |
(op=o)->SetParent(this); | 58 | 58 | (op=o)->SetParent(this); | |
(left=l)->SetParent(this); | 59 | 59 | (left=l)->SetParent(this); | |
(right=r)->SetParent(this); | 60 | 60 | (right=r)->SetParent(this); | |
} | 61 | 61 | } | |
62 | 62 | |||
CompoundExpr::CompoundExpr(Operator *o, Expr *r) | 63 | 63 | CompoundExpr::CompoundExpr(Operator *o, Expr *r) | |
: Expr(Join(o->GetLocation(), r->GetLocation())) { | 64 | 64 | : Expr(Join(o->GetLocation(), r->GetLocation())) { | |
Assert(o != NULL && r != NULL); | 65 | 65 | Assert(o != NULL && r != NULL); | |
left = NULL; | 66 | 66 | left = NULL; | |
(op=o)->SetParent(this); | 67 | 67 | (op=o)->SetParent(this); | |
(right=r)->SetParent(this); | 68 | 68 | (right=r)->SetParent(this); | |
} | 69 | 69 | } | |
70 | 70 | |||
CompoundExpr::CompoundExpr(Expr *l, Operator *o) | 71 | 71 | CompoundExpr::CompoundExpr(Expr *l, Operator *o) | |
: Expr(Join(l->GetLocation(), o->GetLocation())) { | 72 | 72 | : Expr(Join(l->GetLocation(), o->GetLocation())) { | |
Assert(l != NULL && o != NULL); | 73 | 73 | Assert(l != NULL && o != NULL); | |
(left=l)->SetParent(this); | 74 | 74 | (left=l)->SetParent(this); | |
(op=o)->SetParent(this); | 75 | 75 | (op=o)->SetParent(this); | |
} | 76 | 76 | } | |
77 | 77 | |||
void CompoundExpr::PrintChildren(int indentLevel) { | 78 | 78 | void CompoundExpr::PrintChildren(int indentLevel) { | |
if (left) left->Print(indentLevel+1); | 79 | 79 | if (left) left->Print(indentLevel+1); | |
op->Print(indentLevel+1); | 80 | 80 | op->Print(indentLevel+1); | |
if (right) right->Print(indentLevel+1); | 81 | 81 | if (right) right->Print(indentLevel+1); | |
} | 82 | 82 | } | |
83 | 83 | |||
ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) | 84 | 84 | ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) | |
: Expr(Join(c->GetLocation(), f->GetLocation())) { | 85 | 85 | : Expr(Join(c->GetLocation(), f->GetLocation())) { | |
Assert(c != NULL && t != NULL && f != NULL); | 86 | 86 | Assert(c != NULL && t != NULL && f != NULL); | |
(cond=c)->SetParent(this); | 87 | 87 | (cond=c)->SetParent(this); | |
(trueExpr=t)->SetParent(this); | 88 | 88 | (trueExpr=t)->SetParent(this); | |
(falseExpr=f)->SetParent(this); | 89 | 89 | (falseExpr=f)->SetParent(this); | |
} | 90 | 90 | } | |
91 | 91 | |||
void ConditionalExpr::PrintChildren(int indentLevel) { | 92 | 92 | void ConditionalExpr::PrintChildren(int indentLevel) { | |
cond->Print(indentLevel+1, "(cond) "); | 93 | 93 | cond->Print(indentLevel+1, "(cond) "); | |
trueExpr->Print(indentLevel+1, "(true) "); | 94 | 94 | trueExpr->Print(indentLevel+1, "(true) "); | |
falseExpr->Print(indentLevel+1, "(false) "); | 95 | 95 | falseExpr->Print(indentLevel+1, "(false) "); | |
} | 96 | 96 | } | |
ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { | 97 | 97 | ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { | |
(base=b)->SetParent(this); | 98 | 98 | (base=b)->SetParent(this); | |
(subscript=s)->SetParent(this); | 99 | 99 | (subscript=s)->SetParent(this); | |
} | 100 | 100 | } | |
101 | 101 | |||
void ArrayAccess::PrintChildren(int indentLevel) { | 102 | 102 | void ArrayAccess::PrintChildren(int indentLevel) { | |
base->Print(indentLevel+1); | 103 | 103 | base->Print(indentLevel+1); | |
subscript->Print(indentLevel+1, "(subscript) "); | 104 | 104 | subscript->Print(indentLevel+1, "(subscript) "); | |
} | 105 | 105 | } | |
106 | 106 | |||
FieldAccess::FieldAccess(Expr *b, Identifier *f) | 107 | 107 | FieldAccess::FieldAccess(Expr *b, Identifier *f) | |
: LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { | 108 | 108 | : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { | |
Assert(f != NULL); // b can be be NULL (just means no explicit base) | 109 | 109 | Assert(f != NULL); // b can be be NULL (just means no explicit base) | |
base = b; | 110 | 110 | base = b; | |
if (base) base->SetParent(this); | 111 | 111 | if (base) base->SetParent(this); | |
(field=f)->SetParent(this); | 112 | 112 | (field=f)->SetParent(this); | |
} | 113 | 113 | } | |
114 | 114 | |||
115 | 115 | |||
void FieldAccess::PrintChildren(int indentLevel) { | 116 | 116 | void FieldAccess::PrintChildren(int indentLevel) { | |
if (base) base->Print(indentLevel+1); | 117 | 117 | if (base) base->Print(indentLevel+1); | |
field->Print(indentLevel+1); | 118 | 118 | field->Print(indentLevel+1); | |
} | 119 | 119 | } | |
120 | 120 | |||
Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { | 121 | 121 | Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { | |
Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) | 122 | 122 | Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) | |
base = b; | 123 | 123 | base = b; | |
if (base) base->SetParent(this); | 124 | 124 | if (base) base->SetParent(this); | |
(field=f)->SetParent(this); | 125 | 125 | (field=f)->SetParent(this); | |
(actuals=a)->SetParentAll(this); | 126 | 126 | (actuals=a)->SetParentAll(this); | |
} | 127 | 127 | } | |
128 | 128 | |||
void Call::PrintChildren(int indentLevel) { | 129 | 129 | void Call::PrintChildren(int indentLevel) { | |
if (base) base->Print(indentLevel+1); | 130 | 130 | if (base) base->Print(indentLevel+1); | |
if (field) field->Print(indentLevel+1); | 131 | 131 | if (field) field->Print(indentLevel+1); | |
if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); | 132 | 132 | if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); | |
} | 133 | 133 | } | |
134 | 134 | |||
llvm::Value* VarExpr::Emit() { | 135 | 135 | llvm::Value* VarExpr::Emit() { | |
return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock()); | 136 | 136 | return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock()); | |
} | 137 | 137 | } | |
/* | 138 | 138 | /* | |
llvm::Value* AssignExpr::Emit() { | 139 | 139 | llvm::Value* AssignExpr::Emit() { | |
VarExpr* ve = dynamic_cast<VarExpr*>(left); | 140 | 140 | VarExpr* ve = dynamic_cast<VarExpr*>(left); | |
return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock()); | 141 | 141 | return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock()); | |
} | 142 | 142 | } | |
*/ | 143 | 143 | */ | |
144 | 144 | |||
string Operator::getToken() const { | 145 | 145 | string Operator::getToken() const { | |
return tokenString; | 146 | 146 | return tokenString; | |
} | 147 | 147 | } | |
148 | 148 | |||
llvm::Value* IntConstant::Emit() { | 149 | 149 | llvm::Value* IntConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | 150 | 150 | return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); | |
} | 151 | 151 | } | |
152 | 152 | |||
llvm::Value* FloatConstant::Emit() { | 153 | 153 | llvm::Value* FloatConstant::Emit() { | |
return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); | 154 | 154 | return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); | |
} | 155 | 155 | } | |
156 | 156 | |||
llvm::Value* BoolConstant::Emit() { | 157 | 157 | llvm::Value* BoolConstant::Emit() { | |
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value); | 158 | 158 | return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value); | |
} | 159 | 159 | } | |
160 | 160 | |||
llvm::Value* Call::Emit() { | 161 | 161 | llvm::Value* Call::Emit() { | |
vector<llvm::Value*> args; | 162 | 162 | vector<llvm::Value*> args; | |
for(int i = 0; i < actuals->NumElements(); i++) { | 163 | 163 | for(int i = 0; i < actuals->NumElements(); i++) { | |
args.push_back(actuals->Nth(i)->Emit()); | 164 | 164 | args.push_back(actuals->Nth(i)->Emit()); | |
} | 165 | 165 | } | |
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, "", irgen.GetBasicBlock()); | 166 | 166 | return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, "", irgen.GetBasicBlock()); | |
} | 167 | 167 | } | |
168 | 168 | |||
llvm::Value* ConditionalExpr::Emit() { | 169 | 169 | llvm::Value* ConditionalExpr::Emit() { | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 170 | 170 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
llvm::Value* t = trueExpr->Emit(); | 171 | 171 | llvm::Value* t = trueExpr->Emit(); | |
llvm::Value* f = falseExpr->Emit(); | 172 | 172 | llvm::Value* f = falseExpr->Emit(); | |
llvm::Value* c = cond->Emit(); | 173 | 173 | llvm::Value* c = cond->Emit(); | |
174 | 174 | |||
return llvm::SelectInst::Create(c, t, f, "", b); | 175 | 175 | return llvm::SelectInst::Create(c, t, f, "", b); | |
} | 176 | 176 | } | |
177 | 177 | |||
static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) { | 178 | 178 | static llvm::Value* typeConvert(llvm::Value* val, llvm::Value* target) { | |
if(val->getType() == target->getType()) return val; | 179 | 179 | if(val->getType() == target->getType()) return val; | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 180 | 180 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |
llvm::Value* ret = new llvm::AllocaInst(target->getType(), "", b); | 181 | 181 | llvm::Value* ret = new llvm::AllocaInst(target->getType(), "", b); | |
ret = new llvm::LoadInst(ret, "", b); | 182 | 182 | ret = new llvm::LoadInst(ret, "", b); | |
183 | 183 | |||
for(int i = 0; i < target->getType()->getVectorNumElements(); i++) { | 184 | 184 | for(int i = 0; i < target->getType()->getVectorNumElements(); i++) { | |
ret = llvm::InsertElementInst::Create(ret, val, llvm::ConstantInt::get(irgen.GetIntType(), i), "", b); | 185 | 185 | ret = llvm::InsertElementInst::Create(ret, val, llvm::ConstantInt::get(irgen.GetIntType(), i), "", b); | |
} | 186 | 186 | } | |
return ret; | 187 | 187 | return ret; | |
} | 188 | 188 | } | |
189 | 189 | |||
// TODO ++ and -- on vectors? | 190 | |||
llvm::Value* CompoundExpr::Emit() { | 191 | 190 | llvm::Value* CompoundExpr::Emit() { | |
191 | llvm::BasicBlock* b = irgen.GetBasicBlock(); | |||
192 | llvm::Function * func = irgen.GetFunction(); | |||
193 | llvm::LLVMContext* context = irgen.GetContext(); | |||
194 | //weird bc of short circuting | |||
195 | if(op->getToken() == "&&" || op->getToken() == "||") { | |||
196 | llvm::Value* val = new llvm::AllocaInst(llvm::Type::getInt1Ty(*context), "", b); | |||
197 | llvm::BasicBlock * otherBlock = llvm::BasicBlock::Create(*context, "otherBlock", func); | |||
198 | llvm::BasicBlock * falseBlock = llvm::BasicBlock::Create(*context, "falseBlock", func); | |||
199 | llvm::BasicBlock * trueBlock = llvm::BasicBlock::Create(*context, "trueBlock", func); | |||
200 | llvm::BasicBlock * footBlock = llvm::BasicBlock::Create(*context, "footBlock", func); | |||
201 | llvm::Value* l = left->Emit(); | |||
202 | b = irgen.GetBasicBlock(); | |||
203 | if(op->getToken() == "&&") llvm::BranchInst::Create(otherBlock, falseBlock, l, b); | |||
204 | if(op->getToken() == "||") llvm::BranchInst::Create(trueBlock, otherBlock, l, b); | |||
205 | irgen.SetBasicBlock(otherBlock); | |||
206 | llvm::Value* r = right->Emit(); | |||
207 | b = irgen.GetBasicBlock(); | |||
208 | llvm::BranchInst::Create(trueBlock, falseBlock, r, b); | |||
209 | new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), true), val, false, trueBlock); | |||
210 | llvm::BranchInst::Create(footBlock, trueBlock); | |||
211 | new llvm::StoreInst(llvm::ConstantInt::get(llvm::Type::getInt1Ty(*context), false), val, false, falseBlock); | |||
212 | llvm::BranchInst::Create(footBlock, falseBlock); | |||
213 | irgen.SetBasicBlock(footBlock); | |||
214 | return new llvm::LoadInst(val, "", footBlock); | |||
215 | } | |||
llvm::Value* l = left ? left->Emit() : NULL; | 192 | 216 | llvm::Value* l = left ? left->Emit() : NULL; | |
llvm::Value* r = right ? right->Emit() : NULL; | 193 | 217 | llvm::Value* r = right ? right->Emit() : NULL; | |
llvm::BasicBlock* b = irgen.GetBasicBlock(); | 194 | 218 | b = irgen.GetBasicBlock(); | |
//austins additional value | 195 | 219 | //austins additional value | |
llvm::Value *val; | 196 | 220 | llvm::Value *val; | |
if(!l || !r) { | 197 | 221 | if(!l || !r) { | |
if(op->getToken() == "-" && (l ? l->getType()->isFPOrFPVectorTy() : r->getType()->isFPOrFPVectorTy())) { | 198 | 222 | if(op->getToken() == "-" && (l ? l->getType()->isFPOrFPVectorTy() : r->getType()->isFPOrFPVectorTy())) { | |
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, typeConvert(llvm::ConstantFP::get(irgen.GetFloatType(), 0.0), (l?l:r)), l ? l : r, "", b); | 199 | 223 | return llvm::BinaryOperator::Create(llvm::Instruction::FSub, typeConvert(llvm::ConstantFP::get(irgen.GetFloatType(), 0.0), (l?l:r)), l ? l : r, "", b); | |
} | 200 | 224 | } | |
else if(op->getToken() == "-") { | 201 | 225 | else if(op->getToken() == "-") { | |
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, typeConvert(llvm::ConstantInt::get(irgen.GetIntType(), 0), (l?l:r)), l ? l : r, "", b); | 202 | 226 | return llvm::BinaryOperator::Create(llvm::Instruction::Sub, typeConvert(llvm::ConstantInt::get(irgen.GetIntType(), 0), (l?l:r)), l ? l : r, "", b); | |
} | 203 | 227 | } | |
else if(op->getToken() == "+") return l ? l : r; | 204 | 228 | else if(op->getToken() == "+") return l ? l : r; | |
VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); | 205 | 229 | VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); | |
llvm::Value* ret; | 206 | 230 | llvm::Value* ret; | |
llvm::Value* var = l ? l : r; | 207 | 231 | llvm::Value* var = l ? l : r; | |
208 | 232 | |||
if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); | 209 | 233 | if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); | |
else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | 210 | 234 | else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); | |
val = typeConvert(val, var); | 211 | 235 | val = typeConvert(val, var); | |
212 | 236 | |||
if(op->getToken() == "++") { | 213 | 237 | if(op->getToken() == "++") { | |
ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); | 214 | 238 | ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); | |
} | 215 | 239 | } | |
else if(op->getToken() == "--") { | 216 | 240 | else if(op->getToken() == "--") { | |
ret = llvm::BinaryOperator::CreateSub(var, val, "", b); | 217 | 241 | ret = llvm::BinaryOperator::CreateSub(var, val, "", b); | |
} | 218 | 242 | } | |
new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); | 219 | 243 | new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); | |
220 | 244 | |||
if(!l) return ret; | 221 | 245 | if(!l) return ret; | |
else return var; | 222 | 246 | else return var; | |
} | 223 | 247 | } | |
if(l->getType()->isVectorTy() && !r->getType()->isVectorTy()) r = typeConvert(r, l); | 224 | 248 | if(l->getType()->isVectorTy() && !r->getType()->isVectorTy()) r = typeConvert(r, l); | |
if(!l->getType()->isVectorTy() && r->getType()->isVectorTy()) l = typeConvert(l, r); | 225 | 249 | if(!l->getType()->isVectorTy() && r->getType()->isVectorTy()) l = typeConvert(l, r); | |
if(l->getType()->isFPOrFPVectorTy()) { | 226 | 250 | if(l->getType()->isFPOrFPVectorTy()) { | |
if(op->getToken() == "+") | 227 | 251 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | 228 | 252 | return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); | |
if(op->getToken() == "-") | 229 | 253 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | 230 | 254 | return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); | |
if(op->getToken() == "*") | 231 | 255 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | 232 | 256 | return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); | |
if(op->getToken() == "/") | 233 | 257 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | 234 | 258 | return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); | |
if(op->getToken() == "==") | 235 | 259 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | 236 | 260 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); | |
if(op->getToken() == "!=") | 237 | 261 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | 238 | 262 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); | |
if(op->getToken() == "<=") | 239 | 263 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | 240 | 264 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); | |
if(op->getToken() == ">=") | 241 | 265 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | 242 | 266 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); | |
if(op->getToken() == "<") | 243 | 267 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | 244 | 268 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); | |
if(op->getToken() == ">") | 245 | 269 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | 246 | 270 | return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); | |
} | 247 | 271 | } | |
if(l->getType()->isIntOrIntVectorTy()) { | 248 | 272 | if(l->getType()->isIntOrIntVectorTy()) { | |
if(op->getToken() == "+") | 249 | 273 | if(op->getToken() == "+") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | 250 | 274 | return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); | |
if(op->getToken() == "-") | 251 | 275 | if(op->getToken() == "-") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | 252 | 276 | return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); | |
if(op->getToken() == "*") | 253 | 277 | if(op->getToken() == "*") | |
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | 254 | 278 | return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); | |
if(op->getToken() == "/") | 255 | 279 | if(op->getToken() == "/") | |
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | 256 | 280 | return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); | |
if(op->getToken() == "==") | 257 | 281 | if(op->getToken() == "==") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | 258 | 282 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); | |
if(op->getToken() == "!=") | 259 | 283 | if(op->getToken() == "!=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | 260 | 284 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); | |
if(op->getToken() == "<=") | 261 | 285 | if(op->getToken() == "<=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | 262 | 286 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); | |
if(op->getToken() == ">=") | 263 | 287 | if(op->getToken() == ">=") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | 264 | 288 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); | |
if(op->getToken() == "<") | 265 | 289 | if(op->getToken() == "<") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | 266 | 290 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); | |
if(op->getToken() == ">") | 267 | 291 | if(op->getToken() == ">") | |
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | 268 | 292 | return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); | |
} | 269 | |||
if(op->getToken() == "&&") { | 270 | |||
return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); | 271 | |||
} | 272 | |||
if(op->getToken() == "||") { | 273 | |||
return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); | 274 | |||
} | 275 | 293 | } | |
return NULL; | 276 | 294 | return NULL; | |
} | 277 | 295 | } | |
278 | 296 | |||
//---------------------------------------------------------------------------------------- | 279 | 297 | //---------------------------------------------------------------------------------------- | |
//---------------------------------------------------------------------------------------- | 280 | 298 | //---------------------------------------------------------------------------------------- | |
281 | 299 | |||
llvm::Value * AssignExpr::Emit(){ | 282 | 300 | llvm::Value * AssignExpr::Emit(){ | |
llvm::Value * leftval; | 283 | 301 | llvm::Value * leftval; | |
llvm::Value * rightval; | 284 | 302 | llvm::Value * rightval; | |
285 | 303 | |||
FieldAccess * f = dynamic_cast<FieldAccess *>(left); | 286 | 304 | FieldAccess * f = dynamic_cast<FieldAccess *>(left); | |
if (f){ | 287 | 305 | if (f){ | |
return this->AssignField(); | 288 | 306 | return this->AssignField(); | |
} | 289 | 307 | } | |
leftval = left->Emit(); | 290 | 308 | leftval = left->Emit(); | |
rightval = right->Emit(); | 291 | 309 | rightval = right->Emit(); | |
292 | 310 | |||
string operationStr(op->getToken()); | 293 | 311 | string operationStr(op->getToken()); | |
294 | 312 | |||
VarExpr * vd = dynamic_cast<VarExpr *>(left); | 295 | 313 | VarExpr * vd = dynamic_cast<VarExpr *>(left); | |
296 | 314 | |||
llvm::Value * storeInst = NULL; | 297 | 315 | llvm::Value * storeInst = NULL; | |
if ( operationStr.compare("+=") == 0 ){ | 298 | 316 | if ( operationStr.compare("+=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 299 | 317 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); | 300 | 318 | storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 301 | 319 | if (vd){ | |
vd->AddressStore(storeInst); | 302 | 320 | vd->AddressStore(storeInst); | |
return storeInst; | 303 | 321 | return storeInst; | |
} | 304 | 322 | } | |
} | 305 | 323 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 306 | 324 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); | 307 | 325 | storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 308 | 326 | if (vd){ | |
vd->AddressStore(storeInst); | 309 | 327 | vd->AddressStore(storeInst); | |
return storeInst; | 310 | 328 | return storeInst; | |
} | 311 | 329 | } | |
} | 312 | 330 | } | |
else{ | 313 | 331 | else{ | |
storeInst = convert(leftval, rightval, 0); | 314 | 332 | storeInst = convert(leftval, rightval, 0); | |
if (vd){ | 315 | 333 | if (vd){ | |
vd->AddressStore(storeInst); | 316 | 334 | vd->AddressStore(storeInst); | |
return storeInst; | 317 | 335 | return storeInst; | |
} | 318 | 336 | } | |
} | 319 | 337 | } | |
} | 320 | 338 | } | |
else if ( operationStr.compare("=") == 0 ){ | 321 | 339 | else if ( operationStr.compare("=") == 0 ){ | |
if (vd){ | 322 | 340 | if (vd){ | |
vd->AddressStore(rightval); | 323 | 341 | vd->AddressStore(rightval); | |
return rightval; | 324 | 342 | return rightval; | |
} | 325 | 343 | } | |
return ((VarExpr *) left)->AddressStore(rightval); | 326 | 344 | return ((VarExpr *) left)->AddressStore(rightval); | |
} | 327 | 345 | } | |
else if ( operationStr.compare("-=") == 0 ){ | 328 | 346 | else if ( operationStr.compare("-=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 329 | 347 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); | 330 | 348 | storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 331 | 349 | if (vd){ | |
vd->AddressStore(storeInst); | 332 | 350 | vd->AddressStore(storeInst); | |
return storeInst; | 333 | 351 | return storeInst; | |
} | 334 | 352 | } | |
} | 335 | 353 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 336 | 354 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); | 337 | 355 | storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 338 | 356 | if (vd){ | |
vd->AddressStore(storeInst); | 339 | 357 | vd->AddressStore(storeInst); | |
return storeInst; | 340 | 358 | return storeInst; | |
} | 341 | 359 | } | |
} | 342 | 360 | } | |
else{ | 343 | 361 | else{ | |
storeInst = convert(leftval, rightval, 1); | 344 | 362 | storeInst = convert(leftval, rightval, 1); | |
if (vd){ | 345 | 363 | if (vd){ | |
vd->AddressStore(storeInst); | 346 | 364 | vd->AddressStore(storeInst); | |
return storeInst; | 347 | 365 | return storeInst; | |
} | 348 | 366 | } | |
} | 349 | 367 | } | |
} | 350 | 368 | } | |
else if ( operationStr.compare("/=") == 0 ){ | 351 | 369 | else if ( operationStr.compare("/=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 352 | 370 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); | 353 | 371 | storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 354 | 372 | if (vd){ | |
vd->AddressStore(storeInst); | 355 | 373 | vd->AddressStore(storeInst); | |
return storeInst; | 356 | 374 | return storeInst; | |
} | 357 | 375 | } | |
} | 358 | 376 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 359 | 377 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); | 360 | 378 | storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 361 | 379 | if (vd){ | |
vd->AddressStore(storeInst); | 362 | 380 | vd->AddressStore(storeInst); | |
return storeInst; | 363 | 381 | return storeInst; | |
} | 364 | 382 | } | |
} | 365 | 383 | } | |
else{ | 366 | 384 | else{ | |
storeInst = convert(leftval, rightval, 2); | 367 | 385 | storeInst = convert(leftval, rightval, 2); | |
if (vd){ | 368 | 386 | if (vd){ | |
vd->AddressStore(storeInst); | 369 | 387 | vd->AddressStore(storeInst); | |
return storeInst; | 370 | 388 | return storeInst; | |
} | 371 | 389 | } | |
} | 372 | 390 | } | |
} | 373 | 391 | } | |
else if ( operationStr.compare("*=") == 0 ){ | 374 | 392 | else if ( operationStr.compare("*=") == 0 ){ | |
if (leftval->getType()->isIntegerTy()){ | 375 | 393 | if (leftval->getType()->isIntegerTy()){ | |
storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); | 376 | 394 | storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 377 | 395 | if (vd){ | |
vd->AddressStore(storeInst); | 378 | 396 | vd->AddressStore(storeInst); | |
return storeInst; | 379 | 397 | return storeInst; | |
} | 380 | 398 | } | |
} | 381 | 399 | } | |
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | 382 | 400 | else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ | |
storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); | 383 | 401 | storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); | |
if (vd){ | 384 | 402 | if (vd){ | |
vd->AddressStore(storeInst); | 385 | 403 | vd->AddressStore(storeInst); | |
return storeInst; | 386 | 404 | return storeInst; | |
} | 387 | 405 | } | |
} | 388 | 406 | } | |
else{ | 389 | 407 | else{ | |
storeInst = convert(leftval, rightval, 3); | 390 | 408 | storeInst = convert(leftval, rightval, 3); | |
if (vd){ | 391 | 409 | if (vd){ | |
vd->AddressStore(storeInst); | 392 | 410 | vd->AddressStore(storeInst); | |
return storeInst; | 393 | 411 | return storeInst; | |
} | 394 | 412 | } | |
} | 395 | 413 | } | |
} | 396 | 414 | } | |
return NULL; | 397 | 415 | return NULL; | |
} | 398 | 416 | } | |
399 | 417 | |||
llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ | 400 | 418 | llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ | |
llvm::Type * intTyp = irgen.GetIntType(); | 401 | 419 | llvm::Type * intTyp = irgen.GetIntType(); | |
llvm::Type * fltTyp = irgen.GetFloatType(); | 402 | 420 | llvm::Type * fltTyp = irgen.GetFloatType(); | |
llvm::Value *idVal; | 403 | 421 | llvm::Value *idVal; | |
llvm::Value * element; | 404 | 422 | llvm::Value * element; | |
llvm::Value * retVal = vec; | 405 | 423 | llvm::Value * retVal = vec; | |
406 | 424 | |||
//get vector size | 407 | 425 | //get vector size | |
int numElements=-1; | 408 | 426 | int numElements=-1; | |
if(vec->getType()==irgen.GetVec2Type()){ | 409 | 427 | if(vec->getType()==irgen.GetVec2Type()){ | |
numElements=2; | 410 | 428 | numElements=2; | |
} | 411 | 429 | } | |
else if(vec->getType()==irgen.GetVec3Type()){ | 412 | 430 | else if(vec->getType()==irgen.GetVec3Type()){ | |
numElements=3; | 413 | 431 | numElements=3; | |
} | 414 | 432 | } | |
else if(vec->getType()==irgen.GetVec4Type()){ | 415 | 433 | else if(vec->getType()==irgen.GetVec4Type()){ | |
numElements=4; | 416 | 434 | numElements=4; | |
} | 417 | 435 | } | |
418 | 436 | |||
for (int i = 0; i < numElements; i++){ | 419 | 437 | for (int i = 0; i < numElements; i++){ | |
idVal = llvm::ConstantInt::get(intTyp, i); | 420 | 438 | idVal = llvm::ConstantInt::get(intTyp, i); | |
element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); | 421 | 439 | element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); | |
if (status == 0){ | 422 | 440 | if (status == 0){ | |
element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); | 423 | 441 | element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); | |
} | 424 | 442 | } | |
else if (status == 1){ | 425 | 443 | else if (status == 1){ | |
element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); | 426 | 444 | element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); | |
} | 427 | 445 | } | |
else if (status == 2){ | 428 | 446 | else if (status == 2){ | |
element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); | 429 | 447 | element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); | |
} | 430 | 448 | } | |
else{ | 431 | 449 | else{ | |
element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); | 432 | 450 | element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); | |
} | 433 | 451 | } | |
retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); | 434 | 452 | retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); | |
} | 435 | 453 | } | |
return retVal; | 436 | 454 | return retVal; | |
} | 437 | 455 | } | |
438 | 456 | |||
llvm::Value* VarExpr::AddressStore(llvm::Value *store){ | 439 | 457 | llvm::Value* VarExpr::AddressStore(llvm::Value *store){ | |
char * varname = GetIdentifier()->GetName(); | 440 | 458 | char * varname = GetIdentifier()->GetName(); | |
441 | 459 | |||
pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); | 442 | 460 | pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); | |
//value of symbol | 443 | 461 | //value of symbol | |
llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, false, irgen.GetBasicBlock()); | 444 | 462 | llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, false, irgen.GetBasicBlock()); | |
return storeInst; | 445 | 463 | return storeInst; | |
} | 446 | 464 | } | |
447 | 465 | |||
llvm::Value * AssignExpr::AssignField(){ | 448 | 466 | llvm::Value * AssignExpr::AssignField(){ | |
FieldAccess * f = (FieldAccess *) left; | 449 | 467 | FieldAccess * f = (FieldAccess *) left; | |
llvm::Value * rightval = right->Emit(); | 450 | 468 | llvm::Value * rightval = right->Emit(); | |
string operationStr(op->getToken()); | 451 | 469 | string operationStr(op->getToken()); | |
bool isFloat = rightval->getType()->isFloatingPointTy(); | 452 | 470 | bool isFloat = rightval->getType()->isFloatingPointTy(); | |
llvm::Type * intTyp = irgen.GetIntType(); | 453 | 471 | llvm::Type * intTyp = irgen.GetIntType(); | |
char * ptr = f->getField()->GetName();; | 454 | 472 | char * ptr = f->getField()->GetName();; | |
455 | 473 | |||
std::vector<llvm::Constant *> maskI; | 456 | 474 | std::vector<llvm::Constant *> maskI; | |
for(; *ptr; ptr++){ | 457 | 475 | for(; *ptr; ptr++){ | |
if(*ptr =='x'){ | 458 | 476 | if(*ptr =='x'){ | |
maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); | 459 | 477 | maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); | |
} | 460 | 478 | } | |
else if(*ptr='y'){ | 461 | 479 | else if(*ptr='y'){ | |
maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); | 462 | 480 | maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); | |
} | 463 | 481 | } | |
else if(*ptr='z'){ | 464 | 482 | else if(*ptr='z'){ | |
maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); | 465 | 483 | maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); | |
} | 466 | 484 | } | |
else if(*ptr='w'){ | 467 | 485 | else if(*ptr='w'){ | |
maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); | 468 | 486 | maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); | |
} | 469 | 487 | } | |
} | 470 | 488 | } | |
471 | 489 | |||
llvm::Value * element; | 472 | 490 | llvm::Value * element; | |
llvm::Value * rightop = rightval; | 473 | 491 | llvm::Value * rightop = rightval; | |
llvm::Value * baseF = f->getBase()->Emit(); | 474 | 492 | llvm::Value * baseF = f->getBase()->Emit(); | |
llvm::Value * storeInst = f->getBase()->Emit(); | 475 | 493 | llvm::Value * storeInst = f->getBase()->Emit(); | |
476 | 494 | |||
477 | 495 | |||
for (int i = 0; i < maskI.size(); i++){ | 478 | 496 | for (int i = 0; i < maskI.size(); i++){ | |
element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock()); | 479 | 497 | element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock()); | |
if (rightval->getType()->isVectorTy()){ | 480 | 498 | if (rightval->getType()->isVectorTy()){ | |
rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); | 481 | 499 | rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); | |
} | 482 | 500 | } | |
if (!operationStr.compare("=")){ | 483 | 501 | if (!operationStr.compare("=")){ | |
storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); | 484 | 502 | storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); | |
} | 485 | 503 | } | |
if (!operationStr.compare("+=")){ | 486 | 504 | if (!operationStr.compare("+=")){ | |
element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); | 487 | 505 | element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); | |
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | 488 | 506 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |
} | 489 | 507 | } | |
if (!operationStr.compare("-=")){ | 490 | 508 | if (!operationStr.compare("-=")){ | |
element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); | 491 | 509 | element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); | |
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | 492 | 510 | storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); | |
} | 493 | 511 | } | |
if (!operationStr.compare("*=")){ | 494 | 512 | if (!operationStr.compare("*=")){ | |
element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); | 495 | 513 | element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); |