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