BrainF.cpp revision 89f6d88db334ba088672ae0753deb7d7b7509bac
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" 28e2c4304654442ca353b307d73c86dce2a4acadbfDuncan Sands#include "llvm/Intrinsics.h" 29bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#include "llvm/ADT/STLExtras.h" 30bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 31bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerusing namespace llvm; 32bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 33bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner//Set the constants for naming 34bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::tapereg = "tape"; 35bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::headreg = "head"; 36bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::label = "brainf"; 37bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::testreg = "test"; 38bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 39bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris LattnerModule *BrainF::parse(std::istream *in1, int mem, CompileFlags cf) { 40bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner in = in1; 41bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner memtotal = mem; 42bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner comflag = cf; 43bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 44bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner header(); 45bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner readloop(0, 0, 0); 46bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner delete builder; 47bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner return module; 48bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 49bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 50bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnervoid BrainF::header() { 51bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner module = new Module("BrainF"); 52bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 53bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function prototypes 54bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 55bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare void @llvm.memset.i32(i8 *, i8, i32, i32) 56e2c4304654442ca353b307d73c86dce2a4acadbfDuncan Sands Function *memset_func = Intrinsic::getDeclaration(module, Intrinsic::memset_i32); 57bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 58bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare i32 @getchar() 59bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getchar_func = cast<Function>(module-> 60bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getOrInsertFunction("getchar", IntegerType::Int32Ty, NULL)); 61bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 62bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare i32 @putchar(i32) 63bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner putchar_func = cast<Function>(module-> 64bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getOrInsertFunction("putchar", IntegerType::Int32Ty, 65bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner IntegerType::Int32Ty, NULL)); 66bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 67bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 68bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function header 69bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 70bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //define void @brainf() 71bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner brainf_func = cast<Function>(module-> 72bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getOrInsertFunction("brainf", Type::VoidTy, NULL)); 73bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 7489f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands builder = new IRBuilder(BasicBlock::Create(label, brainf_func)); 75bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 76bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%arr = malloc i8, i32 %d 77bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ConstantInt *val_mem = ConstantInt::get(APInt(32, memtotal)); 78bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ptr_arr = builder->CreateMalloc(IntegerType::Int8Ty, val_mem, "arr"); 79bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 80bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1) 81bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 82bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *memset_params[] = { 83bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ptr_arr, 84bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ConstantInt::get(APInt(8, 0)), 85bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner val_mem, 86bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ConstantInt::get(APInt(32, 1)) 87bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 88bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 89bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *memset_call = builder-> 90bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateCall(memset_func, memset_params, array_endof(memset_params)); 91bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner memset_call->setTailCall(false); 92bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 93bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 94bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%arrmax = getelementptr i8 *%arr, i32 %d 95bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (comflag & flag_arraybounds) { 96bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ptr_arrmax = builder-> 97bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateGEP(ptr_arr, ConstantInt::get(APInt(32, memtotal)), "arrmax"); 98bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 99bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 100bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = getelementptr i8 *%arr, i32 %d 101bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = builder->CreateGEP(ptr_arr, 102bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ConstantInt::get(APInt(32, memtotal/2)), 103bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner headreg); 104bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 105bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 106bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 107bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function footer 108bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 109bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //brainf.end: 110051a950000e21935165db56695e35bade668193bGabor Greif endbb = BasicBlock::Create(label, brainf_func); 111bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 112bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //free i8 *%arr 113bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner new FreeInst(ptr_arr, endbb); 114bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 115bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //ret void 116051a950000e21935165db56695e35bade668193bGabor Greif ReturnInst::Create(endbb); 117bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 118bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 119bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 120bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Error block for array out of bounds 121bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (comflag & flag_arraybounds) 122bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 123bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //@aberrormsg = internal constant [%d x i8] c"\00" 124bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Constant *msg_0 = ConstantArray:: 125bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner get("Error: The head has left the tape.", true); 126bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 127bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner GlobalVariable *aberrormsg = new GlobalVariable( 128bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner msg_0->getType(), 129bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner true, 130bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner GlobalValue::InternalLinkage, 131bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner msg_0, 132bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner "aberrormsg", 133bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner module); 134bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 135bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare i32 @puts(i8 *) 136bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Function *puts_func = cast<Function>(module-> 137bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getOrInsertFunction("puts", IntegerType::Int32Ty, 13843ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb PointerType::getUnqual(IntegerType::Int8Ty), NULL)); 139bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 140bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //brainf.aberror: 141051a950000e21935165db56695e35bade668193bGabor Greif aberrorbb = BasicBlock::Create(label, brainf_func); 142bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 143bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //call i32 @puts(i8 *getelementptr([%d x i8] *@aberrormsg, i32 0, i32 0)) 144bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 145bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Constant *zero_32 = Constant::getNullValue(IntegerType::Int32Ty); 146bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 147bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Constant *gep_params[] = { 148bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner zero_32, 149bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner zero_32 150bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 151bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 152bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Constant *msgptr = ConstantExpr:: 153bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getGetElementPtr(aberrormsg, gep_params, 154bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner array_lengthof(gep_params)); 155bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 156bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *puts_params[] = { 157bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner msgptr 158bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 159bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 160bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *puts_call = 161051a950000e21935165db56695e35bade668193bGabor Greif CallInst::Create(puts_func, 162051a950000e21935165db56695e35bade668193bGabor Greif puts_params, array_endof(puts_params), 163051a950000e21935165db56695e35bade668193bGabor Greif "", aberrorbb); 164bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner puts_call->setTailCall(false); 165bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 166bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 167bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %brainf.end 168051a950000e21935165db56695e35bade668193bGabor Greif BranchInst::Create(endbb, aberrorbb); 169bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 170bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 171bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 172bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnervoid BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { 173bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Symbol cursym = SYM_NONE; 174bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int curvalue = 0; 175bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Symbol nextsym = SYM_NONE; 176bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int nextvalue = 0; 177bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner char c; 178bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int loop; 179bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner int direction; 180bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 181bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner while(cursym != SYM_EOF && cursym != SYM_ENDLOOP) { 182bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Write out commands 183bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner switch(cursym) { 184bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_NONE: 185bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Do nothing 186bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 187bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 188bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_READ: 189bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 190bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = call i32 @getchar() 191bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *getchar_call = builder->CreateCall(getchar_func, tapereg); 192bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getchar_call->setTailCall(false); 193bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *tape_0 = getchar_call; 194bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 195bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = trunc i32 %tape.%d to i8 19689f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *tape_1 = builder-> 197bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateTrunc(tape_0, IntegerType::Int8Ty, tapereg); 198bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 199bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //store i8 %tape.%d, i8 *%head.%d 200bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateStore(tape_1, curhead); 201bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 202bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 203bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 204bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_WRITE: 205bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 206bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = load i8 *%head.%d 207bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner LoadInst *tape_0 = builder->CreateLoad(curhead, tapereg); 208bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 209bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = sext i8 %tape.%d to i32 21089f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *tape_1 = builder-> 211bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateSExt(tape_0, IntegerType::Int32Ty, tapereg); 212bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 213bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //call i32 @putchar(i32 %tape.%d) 214bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *putchar_params[] = { 215bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner tape_1 216bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner }; 217bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CallInst *putchar_call = builder-> 218bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateCall(putchar_func, 219bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner putchar_params, array_endof(putchar_params)); 220bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner putchar_call->setTailCall(false); 221bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 222bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 223bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 224bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_MOVE: 225bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 226bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = getelementptr i8 *%head.%d, i32 %d 227bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = builder-> 228bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateGEP(curhead, ConstantInt::get(APInt(32, curvalue)), 229bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner headreg); 230bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 231bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Error block for array out of bounds 232bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (comflag & flag_arraybounds) 233bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 234bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp uge i8 *%head.%d, %arrmax 23589f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *test_0 = builder-> 236bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateICmpUGE(curhead, ptr_arrmax, testreg); 237bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 238bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp ult i8 *%head.%d, %arr 23989f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *test_1 = builder-> 240bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateICmpULT(curhead, ptr_arr, testreg); 241bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 242bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = or i1 %test.%d, %test.%d 24389f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *test_2 = builder-> 244bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateOr(test_0, test_1, testreg); 245bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 246bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br i1 %test.%d, label %main.%d, label %main.%d 247051a950000e21935165db56695e35bade668193bGabor Greif BasicBlock *nextbb = BasicBlock::Create(label, brainf_func); 248bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateCondBr(test_2, aberrorbb, nextbb); 249bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 250bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 251bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(nextbb); 252bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 253bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 254bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 255bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 256bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_CHANGE: 257bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 258bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = load i8 *%head.%d 259bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner LoadInst *tape_0 = builder->CreateLoad(curhead, tapereg); 260bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 261bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = add i8 %tape.%d, %d 26289f6d88db334ba088672ae0753deb7d7b7509bacDuncan Sands Value *tape_1 = builder-> 263bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateAdd(tape_0, ConstantInt::get(APInt(8, curvalue)), tapereg); 264bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 265bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //store i8 %tape.%d, i8 *%head.%d\n" 266bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateStore(tape_1, curhead); 267bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 268bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 269bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 270bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case SYM_LOOP: 271bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 272bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %main.%d 273051a950000e21935165db56695e35bade668193bGabor Greif BasicBlock *testbb = BasicBlock::Create(label, brainf_func); 274bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(testbb); 275bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 276bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 277bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *bb_0 = builder->GetInsertBlock(); 278051a950000e21935165db56695e35bade668193bGabor Greif BasicBlock *bb_1 = BasicBlock::Create(label, brainf_func); 279bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(bb_1); 280bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 281bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Make part of PHI instruction now, wait until end of loop to finish 282051a950000e21935165db56695e35bade668193bGabor Greif PHINode *phi_0 = PHINode::Create(PointerType::getUnqual(IntegerType::Int8Ty), 283bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner headreg, testbb); 284bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi_0->reserveOperandSpace(2); 285bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi_0->addIncoming(curhead, bb_0); 286bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = phi_0; 287bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 288bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner readloop(phi_0, bb_1, testbb); 289bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 290bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 291bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 292bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner default: 293bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cerr<<"Error: Unknown symbol.\n"; 294bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 295bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 296bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 297bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 298bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = nextsym; 299bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue = nextvalue; 300bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_NONE; 301bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 302bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Reading stdin loop 303bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = (cursym == SYM_NONE) 304bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner || (cursym == SYM_MOVE) 305bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner || (cursym == SYM_CHANGE); 306bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner while(loop) { 307bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner *in>>c; 308bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (in->eof()) { 309bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 310bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_EOF; 311bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 312bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_EOF; 313bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 314bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 315bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 316bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner direction = 1; 317bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner switch(c) { 318bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '-': 319bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner direction = -1; 320bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Fall through 321bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 322bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '+': 323bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_CHANGE) { 324bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue += direction; 325bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 326bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 327bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 328bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_CHANGE; 329bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue = direction; 330bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 331bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 332bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_CHANGE; 333bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextvalue = direction; 334bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 335bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 336bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 337bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 338bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 339bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '<': 340bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner direction = -1; 341bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Fall through 342bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 343bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '>': 344bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_MOVE) { 345bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue += direction; 346bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 347bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 348bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 349bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_MOVE; 350bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curvalue = direction; 351bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // loop = 1 352bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 353bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_MOVE; 354bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextvalue = direction; 355bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 356bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 357bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 358bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 359bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 360bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case ',': 361bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 362bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_READ; 363bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 364bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_READ; 365bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 366bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 367bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 368bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 369bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '.': 370bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 371bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_WRITE; 372bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 373bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_WRITE; 374bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 375bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 376bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 377bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 378bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case '[': 379bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 380bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_LOOP; 381bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 382bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_LOOP; 383bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 384bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 385bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 386bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 387bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner case ']': 388bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_NONE) { 389bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cursym = SYM_ENDLOOP; 390bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } else { 391bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner nextsym = SYM_ENDLOOP; 392bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 393bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner loop = 0; 394bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 395bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 396bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Ignore other characters 397bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner default: 398bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner break; 399bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 400bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 401bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 402bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 403bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 404bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (cursym == SYM_ENDLOOP) { 405bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (!phi) { 406bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cerr<<"Error: Extra ']'\n"; 407bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 408bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 409bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 410bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner // Write loop test 411bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner { 412bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %main.%d 413bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(testbb); 414bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 415bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 416bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 417bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = phi i8 *[%head.%d, %main.%d], [%head.%d, %main.%d] 418bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Finish phi made at beginning of loop 419bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi->addIncoming(curhead, builder->GetInsertBlock()); 420bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Value *head_0 = phi; 421bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 422bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%tape.%d = load i8 *%head.%d 423bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner LoadInst *tape_0 = new LoadInst(head_0, tapereg, testbb); 424bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 425bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp eq i8 %tape.%d, 0 426bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ICmpInst *test_0 = new ICmpInst(ICmpInst::ICMP_EQ, tape_0, 427bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ConstantInt::get(APInt(8, 0)), testreg, 428bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner testbb); 429bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 430bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br i1 %test.%d, label %main.%d, label %main.%d 431051a950000e21935165db56695e35bade668193bGabor Greif BasicBlock *bb_0 = BasicBlock::Create(label, brainf_func); 432051a950000e21935165db56695e35bade668193bGabor Greif BranchInst::Create(bb_0, oldbb, test_0, testbb); 433bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 434bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 435bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(bb_0); 436bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 437bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%head.%d = phi i8 *[%head.%d, %main.%d] 438bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner PHINode *phi_1 = builder-> 43943ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb CreatePHI(PointerType::getUnqual(IntegerType::Int8Ty), headreg); 440bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi_1->reserveOperandSpace(1); 441bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner phi_1->addIncoming(head_0, testbb); 442bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner curhead = phi_1; 443bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 444bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 445bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner return; 446bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 447bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 448bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //End of the program, so go to return block 449bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(endbb); 450bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 451bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner if (phi) { 452bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cerr<<"Error: Missing ']'\n"; 453bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 454bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 455bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 456