BrainF.cpp revision fc001bbfc360ab828e5a4b0cbe4bb7db87361b85
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" 28bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner#include "llvm/ADT/STLExtras.h" 29bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 30bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerusing namespace llvm; 31bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 32bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner//Set the constants for naming 33bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::tapereg = "tape"; 34bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::headreg = "head"; 35bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::label = "brainf"; 36bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnerconst char *BrainF::testreg = "test"; 37bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 38bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris LattnerModule *BrainF::parse(std::istream *in1, int mem, CompileFlags cf) { 39bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner in = in1; 40bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner memtotal = mem; 41bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner comflag = cf; 42bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 43bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner header(); 44bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner readloop(0, 0, 0); 45bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner delete builder; 46bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner return module; 47bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 48bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 49bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattnervoid BrainF::header() { 50bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner module = new Module("BrainF"); 51bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 52bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Function prototypes 53bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 54bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //declare void @llvm.memset.i32(i8 *, i8, i32, i32) 55bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner Function *memset_func = cast<Function>(module-> 56bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner getOrInsertFunction("llvm.memset.i32", Type::VoidTy, 5743ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb PointerType::getUnqual(IntegerType::Int8Ty), 58bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner IntegerType::Int8Ty, IntegerType::Int32Ty, 59bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner IntegerType::Int32Ty, NULL)); 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 77bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder = new LLVMBuilder(new BasicBlock(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: 113bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner endbb = new BasicBlock(label, brainf_func); 114bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 115bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //free i8 *%arr 116bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner new FreeInst(ptr_arr, endbb); 117bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 118bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //ret void 119bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner new ReturnInst(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: 144bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner aberrorbb = new BasicBlock(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 = 164bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner new CallInst(puts_func, 165bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner puts_params, array_endof(puts_params), 166bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner "", aberrorbb); 167bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner puts_call->setTailCall(false); 168bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 169bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 170bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //br label %brainf.end 171bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner new BranchInst(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 199bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner TruncInst *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 213bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner SExtInst *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 238bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ICmpInst *test_0 = builder-> 239bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateICmpUGE(curhead, ptr_arrmax, testreg); 240bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 241bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = icmp ult i8 *%head.%d, %arr 242bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner ICmpInst *test_1 = builder-> 243bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner CreateICmpULT(curhead, ptr_arr, testreg); 244bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 245bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //%test.%d = or i1 %test.%d, %test.%d 246bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BinaryOperator *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 250bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *nextbb = new BasicBlock(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 265bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BinaryOperator *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 276bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *testbb = new BasicBlock(label, brainf_func); 277bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->CreateBr(testbb); 278bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 279bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //main.%d: 280bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *bb_0 = builder->GetInsertBlock(); 281bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *bb_1 = new BasicBlock(label, brainf_func); 282bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner builder->SetInsertPoint(bb_1); 283bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 284bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner //Make part of PHI instruction now, wait until end of loop to finish 28543ad6b3e0d6ada51e9b23aab3e061187f1f5710cChristopher Lamb PHINode *phi_0 = new PHINode(PointerType::getUnqual(IntegerType::Int8Ty), 286bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 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: 296bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 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) { 409bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner 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 434bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner BasicBlock *bb_0 = new BasicBlock(label, brainf_func); 435bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner new BranchInst(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) { 455bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner cerr<<"Error: Missing ']'\n"; 456bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner abort(); 457bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner } 458bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9Chris Lattner} 459