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