1bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner//===-- BrainF.cpp - BrainF compiler example ----------------------------===// 2bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// 3bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// The LLVM Compiler Infrastructure 4bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// 5fc001bbfc360ab828e5a4b0cbe4bb7db87361b85Chris Lattner// This file is distributed under the University of Illinois Open Source 6fc001bbfc360ab828e5a4b0cbe4bb7db87361b85Chris Lattner// License. See LICENSE.TXT for details. 7bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// 8bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner//===--------------------------------------------------------------------===// 9bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// 10bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// This class compiles the BrainF language into LLVM assembly. 11bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// 12bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// The BrainF language has 8 commands: 13bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// Command Equivalent C Action 14bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// ------- ------------ ------ 15bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// , *h=getchar(); Read a character from stdin, 255 on EOF 16bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// . putchar(*h); Write a character to stdout 17bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// - --*h; Decrement tape 18bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// + ++*h; Increment tape 19bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// < --h; Move head left 20bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// > ++h; Move head right 21bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// [ while(*h) { Start loop 22bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// ] } End loop 23bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner// 24bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner//===--------------------------------------------------------------------===// 25bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 26bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#include "BrainF.h" 27bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#include "llvm/Constants.h" 2813ad5aaaff8a446758b402fd5e9aea22f5bc5682Victor Hernandez#include "llvm/Instructions.h" 29e2c4304654442ca353b307d73c86dce2a4acadbfDuncan Sands#include "llvm/Intrinsics.h" 30bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#include "llvm/ADT/STLExtras.h" 31ef5dc366e713f5d596f3625344d4ec6c10159ad5Chris Lattner#include <iostream> 32bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerusing namespace llvm; 33bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 34bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner//Set the constants for naming 35bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::tapereg = "tape"; 36bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::headreg = "head"; 37bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::label = "brainf"; 38bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::testreg = "test"; 39bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 408b477ed579794ba6d76915d56b3f448a7dd20120Owen AndersonModule *BrainF::parse(std::istream *in1, int mem, CompileFlags cf, 414434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& Context) { 42bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner in = in1; 43bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner memtotal = mem; 44bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner comflag = cf; 45bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 468b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson header(Context); 479adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson readloop(0, 0, 0, Context); 48bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner delete builder; 49bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner return module; 50bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 51bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 524434ed44c45c87a72b7a0bf2f91211f895022b91Owen Andersonvoid BrainF::header(LLVMContext& C) { 538b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson module = new Module("BrainF", C); 54bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 55bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function prototypes 56bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 579908fec11e5bfd90768f344df69416a6b621aba4Chris Lattner //declare void @llvm.memset.p0i8.i32(i8 *, i8, i32, i32, i1) 58e8b323aed4654548ea124811ce051d6b59061e74Francois Pichet Type *Tys[] = { Type::getInt8PtrTy(C), Type::getInt32Ty(C) }; 59824b958e6fb1236e92e4d07f3acf18fca107cdc0Chris Lattner Function *memset_func = Intrinsic::getDeclaration(module, Intrinsic::memset, 60eb9a85f09e18b3fe88499710404b38d3a9128f62Benjamin Kramer Tys); 61bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 62bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare i32 @getchar() 63bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getchar_func = cast<Function>(module-> 641d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson getOrInsertFunction("getchar", IntegerType::getInt32Ty(C), NULL)); 65bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 66bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare i32 @putchar(i32) 67bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner putchar_func = cast<Function>(module-> 681d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson getOrInsertFunction("putchar", IntegerType::getInt32Ty(C), 691d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson IntegerType::getInt32Ty(C), NULL)); 70bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 71bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 72bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function header 73bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 74bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //define void @brainf() 75bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner brainf_func = cast<Function>(module-> 761d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson getOrInsertFunction("brainf", Type::getVoidTy(C), NULL)); 77bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 781d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson builder = new IRBuilder<>(BasicBlock::Create(C, label, brainf_func)); 79bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 80bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%arr = malloc i8, i32 %d 81eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal)); 8213ad5aaaff8a446758b402fd5e9aea22f5bc5682Victor Hernandez BasicBlock* BB = builder->GetInsertBlock(); 834b3d5469fb7c25504fa20dc65640f02d79675d48Chris Lattner Type* IntPtrTy = IntegerType::getInt32Ty(C); 844b3d5469fb7c25504fa20dc65640f02d79675d48Chris Lattner Type* Int8Ty = IntegerType::getInt8Ty(C); 859d0b704e3ea418441001dac4d1a56c2c224cdbf5Victor Hernandez Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty); 869d0b704e3ea418441001dac4d1a56c2c224cdbf5Victor Hernandez allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy); 879d0b704e3ea418441001dac4d1a56c2c224cdbf5Victor Hernandez ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem, 889d0b704e3ea418441001dac4d1a56c2c224cdbf5Victor Hernandez NULL, "arr"); 8913ad5aaaff8a446758b402fd5e9aea22f5bc5682Victor Hernandez BB->getInstList().push_back(cast<Instruction>(ptr_arr)); 90bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 919908fec11e5bfd90768f344df69416a6b621aba4Chris Lattner //call void @llvm.memset.p0i8.i32(i8 *%arr, i8 0, i32 %d, i32 1, i1 0) 92bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 93bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *memset_params[] = { 94bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ptr_arr, 95eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(C, APInt(8, 0)), 96bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner val_mem, 979908fec11e5bfd90768f344df69416a6b621aba4Chris Lattner ConstantInt::get(C, APInt(32, 1)), 989908fec11e5bfd90768f344df69416a6b621aba4Chris Lattner ConstantInt::get(C, APInt(1, 0)) 99bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 100bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 101bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *memset_call = builder-> 1020bd9d3af54b62152355525bea7914bdef4600371Francois Pichet CreateCall(memset_func, memset_params); 103bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner memset_call->setTailCall(false); 104bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 105bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 106bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%arrmax = getelementptr i8 *%arr, i32 %d 107bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (comflag & flag_arraybounds) { 108bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ptr_arrmax = builder-> 109eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson CreateGEP(ptr_arr, ConstantInt::get(C, APInt(32, memtotal)), "arrmax"); 110bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 111bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 112bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = getelementptr i8 *%arr, i32 %d 113bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = builder->CreateGEP(ptr_arr, 114eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(C, APInt(32, memtotal/2)), 115bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner headreg); 116bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 117bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 118bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 119bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function footer 120bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 121bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //brainf.end: 1221d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson endbb = BasicBlock::Create(C, label, brainf_func); 123bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 124046e78ce55a7c3d82b7b6758d2d77f2d99f970bfVictor Hernandez //call free(i8 *%arr) 125046e78ce55a7c3d82b7b6758d2d77f2d99f970bfVictor Hernandez endbb->getInstList().push_back(CallInst::CreateFree(ptr_arr, endbb)); 126bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 127bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //ret void 1281d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ReturnInst::Create(C, endbb); 129bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 130bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 131bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 132bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Error block for array out of bounds 133bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (comflag & flag_arraybounds) 134bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 135bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //@aberrormsg = internal constant [%d x i8] c"\00" 1369adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson Constant *msg_0 = 137a0935775db5886ba8710840de868bbd84554da90Francois Pichet ConstantDataArray::getString(C, "Error: The head has left the tape.", 138a0935775db5886ba8710840de868bbd84554da90Francois Pichet true); 139bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 140bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner GlobalVariable *aberrormsg = new GlobalVariable( 141e9b11b431308f4766b73cda93e38ec930c912122Owen Anderson *module, 142bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner msg_0->getType(), 143bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner true, 144bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner GlobalValue::InternalLinkage, 145bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner msg_0, 146e9b11b431308f4766b73cda93e38ec930c912122Owen Anderson "aberrormsg"); 147bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 148bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare i32 @puts(i8 *) 149bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Function *puts_func = cast<Function>(module-> 1501d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson getOrInsertFunction("puts", IntegerType::getInt32Ty(C), 1511d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL)); 152bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 153bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //brainf.aberror: 1541d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson aberrorbb = BasicBlock::Create(C, label, brainf_func); 155bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 156bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //call i32 @puts(i8 *getelementptr([%d x i8] *@aberrormsg, i32 0, i32 0)) 157bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 1581d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Constant *zero_32 = Constant::getNullValue(IntegerType::getInt32Ty(C)); 159bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 160bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Constant *gep_params[] = { 161bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner zero_32, 162bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner zero_32 163bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 164bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 165bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Constant *msgptr = ConstantExpr:: 166dab3d29605a5c83db41b28176273ef55961120c1Jay Foad getGetElementPtr(aberrormsg, gep_params); 167bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 168bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *puts_params[] = { 169bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner msgptr 170bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 171bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 172bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *puts_call = 173051a950000e21935165db56695e35bade668193bGabor Greif CallInst::Create(puts_func, 1740bd9d3af54b62152355525bea7914bdef4600371Francois Pichet puts_params, 175051a950000e21935165db56695e35bade668193bGabor Greif "", aberrorbb); 176bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner puts_call->setTailCall(false); 177bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 178bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 179bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %brainf.end 180051a950000e21935165db56695e35bade668193bGabor Greif BranchInst::Create(endbb, aberrorbb); 181bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 182bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 183bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 1849adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Andersonvoid BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb, 1859adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson LLVMContext &C) { 186bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Symbol cursym = SYM_NONE; 187bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int curvalue = 0; 188bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Symbol nextsym = SYM_NONE; 189bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int nextvalue = 0; 190bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner char c; 191bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int loop; 192bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int direction; 193bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 194bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner while(cursym != SYM_EOF && cursym != SYM_ENDLOOP) { 195bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Write out commands 196bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner switch(cursym) { 197bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_NONE: 198bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Do nothing 199bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 200bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 201bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_READ: 202bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 203bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = call i32 @getchar() 204bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *getchar_call = builder->CreateCall(getchar_func, tapereg); 205bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getchar_call->setTailCall(false); 206bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *tape_0 = getchar_call; 207bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 208bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = trunc i32 %tape.%d to i8 20989f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *tape_1 = builder-> 2101d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson CreateTrunc(tape_0, IntegerType::getInt8Ty(C), tapereg); 211bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 212bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //store i8 %tape.%d, i8 *%head.%d 213bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateStore(tape_1, curhead); 214bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 215bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 216bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 217bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_WRITE: 218bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 219bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = load i8 *%head.%d 220bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner LoadInst *tape_0 = builder->CreateLoad(curhead, tapereg); 221bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 222bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = sext i8 %tape.%d to i32 22389f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *tape_1 = builder-> 2241d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson CreateSExt(tape_0, IntegerType::getInt32Ty(C), tapereg); 225bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 226bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //call i32 @putchar(i32 %tape.%d) 227bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *putchar_params[] = { 228bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner tape_1 229bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 230bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *putchar_call = builder-> 231bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateCall(putchar_func, 2320bd9d3af54b62152355525bea7914bdef4600371Francois Pichet putchar_params); 233bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner putchar_call->setTailCall(false); 234bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 235bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 236bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 237bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_MOVE: 238bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 239bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = getelementptr i8 *%head.%d, i32 %d 240bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = builder-> 241eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson CreateGEP(curhead, ConstantInt::get(C, APInt(32, curvalue)), 242bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner headreg); 243bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 244bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Error block for array out of bounds 245bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (comflag & flag_arraybounds) 246bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 247bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp uge i8 *%head.%d, %arrmax 24889f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *test_0 = builder-> 249bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateICmpUGE(curhead, ptr_arrmax, testreg); 250bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 251bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp ult i8 *%head.%d, %arr 25289f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *test_1 = builder-> 253bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateICmpULT(curhead, ptr_arr, testreg); 254bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 255bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = or i1 %test.%d, %test.%d 25689f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *test_2 = builder-> 257bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateOr(test_0, test_1, testreg); 258bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 259bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br i1 %test.%d, label %main.%d, label %main.%d 2601d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *nextbb = BasicBlock::Create(C, label, brainf_func); 261bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateCondBr(test_2, aberrorbb, nextbb); 262bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 263bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 264bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(nextbb); 265bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 266bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 267bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 268bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 269bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_CHANGE: 270bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 271bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = load i8 *%head.%d 272bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner LoadInst *tape_0 = builder->CreateLoad(curhead, tapereg); 273bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 274bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = add i8 %tape.%d, %d 27589f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *tape_1 = builder-> 276eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson CreateAdd(tape_0, ConstantInt::get(C, APInt(8, curvalue)), tapereg); 277bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 278bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //store i8 %tape.%d, i8 *%head.%d\n" 279bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateStore(tape_1, curhead); 280bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 281bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 282bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 283bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_LOOP: 284bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 285bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %main.%d 2861d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *testbb = BasicBlock::Create(C, label, brainf_func); 287bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(testbb); 288bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 289bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 290bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *bb_0 = builder->GetInsertBlock(); 2911d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *bb_1 = BasicBlock::Create(C, label, brainf_func); 292bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(bb_1); 293bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 294b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif // Make part of PHI instruction now, wait until end of loop to finish 295b1dbcd886a4b5597a839f299054b78b33fb2d6dfGabor Greif PHINode *phi_0 = 2961d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson PHINode::Create(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 2973ecfc861b4365f341c5c969b40e1afccde676e6fJay Foad 2, headreg, testbb); 298bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi_0->addIncoming(curhead, bb_0); 299bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = phi_0; 300bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 3019adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson readloop(phi_0, bb_1, testbb, C); 302bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 303bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 304bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 305bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner default: 306ef5dc366e713f5d596f3625344d4ec6c10159ad5Chris Lattner std::cerr << "Error: Unknown symbol.\n"; 307bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 308bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 309bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 310bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 311bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = nextsym; 312bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue = nextvalue; 313bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_NONE; 314bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 315bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Reading stdin loop 316bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = (cursym == SYM_NONE) 317bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner || (cursym == SYM_MOVE) 318bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner || (cursym == SYM_CHANGE); 319bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner while(loop) { 320bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner *in>>c; 321bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (in->eof()) { 322bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 323bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_EOF; 324bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 325bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_EOF; 326bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 327bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 328bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 329bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner direction = 1; 330bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner switch(c) { 331bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '-': 332bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner direction = -1; 333bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Fall through 334bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 335bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '+': 336bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_CHANGE) { 337bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue += direction; 338bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 339bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 340bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 341bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_CHANGE; 342bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue = direction; 343bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 344bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 345bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_CHANGE; 346bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextvalue = direction; 347bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 348bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 349bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 350bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 351bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 352bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '<': 353bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner direction = -1; 354bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Fall through 355bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 356bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '>': 357bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_MOVE) { 358bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue += direction; 359bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 360bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 361bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 362bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_MOVE; 363bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue = direction; 364bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 365bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 366bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_MOVE; 367bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextvalue = direction; 368bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 369bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 370bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 371bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 372bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 373bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case ',': 374bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 375bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_READ; 376bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 377bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_READ; 378bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 379bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 380bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 381bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 382bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '.': 383bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 384bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_WRITE; 385bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 386bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_WRITE; 387bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 388bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 389bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 390bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 391bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '[': 392bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 393bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_LOOP; 394bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 395bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_LOOP; 396bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 397bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 398bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 399bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 400bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case ']': 401bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 402bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_ENDLOOP; 403bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 404bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_ENDLOOP; 405bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 406bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 407bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 408bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 409bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Ignore other characters 410bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner default: 411bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 412bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 413bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 414bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 415bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 416bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 417bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_ENDLOOP) { 418bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (!phi) { 419ef5dc366e713f5d596f3625344d4ec6c10159ad5Chris Lattner std::cerr << "Error: Extra ']'\n"; 420bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 421bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 422bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 423bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Write loop test 424bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 425bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %main.%d 426bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(testbb); 427bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 428bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 429bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 430bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = phi i8 *[%head.%d, %main.%d], [%head.%d, %main.%d] 431bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Finish phi made at beginning of loop 432bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi->addIncoming(curhead, builder->GetInsertBlock()); 433bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *head_0 = phi; 434bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 435bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = load i8 *%head.%d 436bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner LoadInst *tape_0 = new LoadInst(head_0, tapereg, testbb); 437bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 438bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp eq i8 %tape.%d, 0 439333c40096561218bc3597cf153c0a3895274414cOwen Anderson ICmpInst *test_0 = new ICmpInst(*testbb, ICmpInst::ICMP_EQ, tape_0, 440eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson ConstantInt::get(C, APInt(8, 0)), testreg); 441bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 442bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br i1 %test.%d, label %main.%d, label %main.%d 4431d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *bb_0 = BasicBlock::Create(C, label, brainf_func); 444051a950000e21935165db56695e35bade668193bGabor Greif BranchInst::Create(bb_0, oldbb, test_0, testbb); 445bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 446bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 447bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(bb_0); 448bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 449bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = phi i8 *[%head.%d, %main.%d] 450bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner PHINode *phi_1 = builder-> 4513ecfc861b4365f341c5c969b40e1afccde676e6fJay Foad CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 1, 4523ecfc861b4365f341c5c969b40e1afccde676e6fJay Foad headreg); 453bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi_1->addIncoming(head_0, testbb); 454bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = phi_1; 455bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 456bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 457bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner return; 458bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 459bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 460bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //End of the program, so go to return block 461bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(endbb); 462bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 463bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (phi) { 464ef5dc366e713f5d596f3625344d4ec6c10159ad5Chris Lattner std::cerr << "Error: Missing ']'\n"; 465bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 466bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 467bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 468