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