mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-10 16:24:04 +00:00
Remove BFtoLLVM. It was old, and a poor example because it didn't use best practices for making
a LLVM frontend in C++. Maybe someday it will be rewritten.. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37858 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3d6fac3993
commit
241c3dac3f
@ -1,209 +0,0 @@
|
|||||||
//===-- BFtoLLVM.cpp - BF language Front End for LLVM ---------------------===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// This is a simple front end for the BF language. It is compatible with the
|
|
||||||
// language as described in "The BrainF*** Language Specification (01 January
|
|
||||||
// 2002)", which is available from http://esoteric.sange.fi/ENSI . It does not
|
|
||||||
// implement the optional keyword # ("Output partial tape state").
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
#include <fstream>
|
|
||||||
#include <cerrno>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
void emitDeclarations(std::ofstream &dest) {
|
|
||||||
dest << "; This assembly code brought to you by BFtoLLVM\n"
|
|
||||||
<< "\nimplementation\n"
|
|
||||||
<< "\n; Declarations\n"
|
|
||||||
<< "\ndeclare int %getchar()\n"
|
|
||||||
<< "declare int %putchar(int)\n"
|
|
||||||
<< "declare void %llvm.memset.i32(sbyte*, ubyte, uint, uint)\n"
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void emitMainFunctionProlog(std::ofstream &dest) {
|
|
||||||
dest << "\n; Main function\n"
|
|
||||||
<< "int %main(int %argc, sbyte** %argv) {\n"
|
|
||||||
<< "\nentry:\n"
|
|
||||||
<< "%arr = alloca sbyte, uint 30000\n"
|
|
||||||
<< "call void (sbyte*, ubyte, uint, uint)* %llvm.memset.i32"
|
|
||||||
<< "(sbyte* %arr, ubyte 0, uint 30000, uint 1)\n"
|
|
||||||
<< "%ptrbox = alloca sbyte*\n"
|
|
||||||
<< "store sbyte* %arr, sbyte **%ptrbox\n"
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void emitMainFunctionEpilog(std::ofstream &dest) {
|
|
||||||
dest << "ret int 0\n"
|
|
||||||
<< "}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string gensym (const std::string varName, bool percent = true) {
|
|
||||||
char buf[80];
|
|
||||||
static unsigned int SymbolCounter = 0;
|
|
||||||
sprintf (buf, "%s%s%u", percent ? "%" : "", varName.c_str(), SymbolCounter++);
|
|
||||||
return std::string (buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void emitArith (std::string op, char delta, std::ofstream &dest) {
|
|
||||||
std::string ptr = gensym (op + "ptr"),
|
|
||||||
val = gensym (op + "val"),
|
|
||||||
result = gensym (op + "result");
|
|
||||||
dest << ptr << " = load sbyte** %ptrbox\n"
|
|
||||||
<< val << " = load sbyte* " << ptr << "\n"
|
|
||||||
<< result << " = add sbyte " << val << ", " << (int)delta << "\n"
|
|
||||||
<< "store sbyte " << result << ", sbyte* " << ptr << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// + becomes ++*p; and - becomes --*p;
|
|
||||||
void emitPlus (std::ofstream &dest, int ct) { emitArith ("plus", +ct, dest); }
|
|
||||||
void emitMinus (std::ofstream &dest, int ct) { emitArith ("minus", -ct, dest); }
|
|
||||||
|
|
||||||
void emitLoadAndCast (std::string ptr, std::string val, std::string cast,
|
|
||||||
std::string type, std::ofstream &dest) {
|
|
||||||
dest << ptr << " = load sbyte** %ptrbox\n"
|
|
||||||
<< val << " = load sbyte* " << ptr << "\n"
|
|
||||||
<< cast << " = cast sbyte " << val << " to " << type << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// , becomes *p = getchar();
|
|
||||||
void emitComma(std::ofstream &dest, int ct) {
|
|
||||||
assert (ct == 1);
|
|
||||||
std::string ptr = gensym("commaptr"), read = gensym("commaread"),
|
|
||||||
cast = gensym("commacast");
|
|
||||||
dest << ptr << " = load sbyte** %ptrbox\n"
|
|
||||||
<< read << " = call int %getchar()\n"
|
|
||||||
<< cast << " = cast int " << read << " to sbyte\n"
|
|
||||||
<< "store sbyte " << cast << ", sbyte* " << ptr << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// . becomes putchar(*p);
|
|
||||||
void emitDot(std::ofstream &dest, int ct) {
|
|
||||||
assert (ct == 1);
|
|
||||||
std::string ptr = gensym("dotptr"), val = gensym("dotval"),
|
|
||||||
cast = gensym("dotcast");
|
|
||||||
emitLoadAndCast (ptr, val, cast, "int", dest);
|
|
||||||
dest << "call int %putchar(int " << cast << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void emitPointerArith(std::string opname, int delta, std::ofstream &dest) {
|
|
||||||
std::string ptr = gensym(opname + "ptr"), result = gensym(opname + "result");
|
|
||||||
dest << ptr << " = load sbyte** %ptrbox\n"
|
|
||||||
<< result << " = getelementptr sbyte* " << ptr << ", int " << delta
|
|
||||||
<< "\n"
|
|
||||||
<< "store sbyte* " << result << ", sbyte** %ptrbox\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// < becomes --p; and > becomes ++p;
|
|
||||||
void emitLT(std::ofstream &dest, int ct) { emitPointerArith ("lt", -ct, dest); }
|
|
||||||
void emitGT(std::ofstream &dest, int ct) { emitPointerArith ("gt", +ct, dest); }
|
|
||||||
|
|
||||||
static std::vector<std::string> whileStack;
|
|
||||||
|
|
||||||
// [ becomes while (*p) {
|
|
||||||
void emitLeftBracket(std::ofstream &dest, int ct) {
|
|
||||||
assert (ct == 1);
|
|
||||||
std::string whileName = gensym ("While", false);
|
|
||||||
whileStack.push_back (whileName);
|
|
||||||
dest << "br label %testFor" << whileName << "\n"
|
|
||||||
<< "\ninside" << whileName << ":\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// ] becomes }
|
|
||||||
void emitRightBracket(std::ofstream &dest, int ct) {
|
|
||||||
assert (ct == 1);
|
|
||||||
std::string whileName = whileStack.back (),
|
|
||||||
ptr = gensym("bracketptr"),
|
|
||||||
val = gensym("bracketval"),
|
|
||||||
cast = gensym("bracketcast");
|
|
||||||
whileStack.pop_back ();
|
|
||||||
dest << "br label %testFor" << whileName << "\n"
|
|
||||||
<< "\ntestFor" << whileName << ":\n";
|
|
||||||
emitLoadAndCast (ptr, val, cast, "bool", dest);
|
|
||||||
dest << "br bool " << cast << ", label %inside" << whileName << ", "
|
|
||||||
<< "label %after" << whileName << "\n"
|
|
||||||
<< "\nafter" << whileName << ":\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void (*FuncTy)(std::ofstream &, int);
|
|
||||||
static FuncTy table[256];
|
|
||||||
static bool multi[256];
|
|
||||||
|
|
||||||
void consume (int ch, int repeatCount, std::ofstream &dest) {
|
|
||||||
FuncTy func = table[ch];
|
|
||||||
if (!func)
|
|
||||||
return;
|
|
||||||
else if (multi[ch])
|
|
||||||
func (dest, repeatCount);
|
|
||||||
else
|
|
||||||
for (int i = 0; i < repeatCount; ++i)
|
|
||||||
func (dest, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void initializeTable() {
|
|
||||||
memset (table, 0, 256);
|
|
||||||
memset (multi, 0, 256);
|
|
||||||
table[(int)'+'] = emitPlus; multi[(int)'+'] = true;
|
|
||||||
table[(int)'-'] = emitMinus; multi[(int)'-'] = true;
|
|
||||||
table[(int)','] = emitComma; multi[(int)','] = false;
|
|
||||||
table[(int)'.'] = emitDot; multi[(int)'.'] = false;
|
|
||||||
table[(int)'<'] = emitLT; multi[(int)'<'] = true;
|
|
||||||
table[(int)'>'] = emitGT; multi[(int)'>'] = true;
|
|
||||||
table[(int)'['] = emitLeftBracket; multi[(int)'['] = false;
|
|
||||||
table[(int)']'] = emitRightBracket; multi[(int)']'] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main (int argc, char **argv) {
|
|
||||||
if (argc != 3) {
|
|
||||||
std::cerr << "usage: " << argv[0] << " input-source output-llvm\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *sourceFileName = argv[1];
|
|
||||||
char *destFileName = argv[2];
|
|
||||||
|
|
||||||
std::ifstream src (sourceFileName);
|
|
||||||
if (!src.good()) {
|
|
||||||
std::cerr << sourceFileName << ": " << strerror(errno) << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ofstream dest (destFileName);
|
|
||||||
if (!dest.good()) {
|
|
||||||
std::cerr << destFileName << ": " << strerror(errno) << "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
emitDeclarations(dest);
|
|
||||||
emitMainFunctionProlog(dest);
|
|
||||||
|
|
||||||
initializeTable();
|
|
||||||
char ch, lastCh;
|
|
||||||
src >> lastCh;
|
|
||||||
int repeatCount = 1;
|
|
||||||
for (src >> ch; !src.eof (); src >> ch, ++repeatCount)
|
|
||||||
if (ch != lastCh) {
|
|
||||||
consume (lastCh, repeatCount, dest);
|
|
||||||
lastCh = ch;
|
|
||||||
repeatCount = 0;
|
|
||||||
}
|
|
||||||
consume (lastCh, repeatCount, dest);
|
|
||||||
|
|
||||||
emitMainFunctionEpilog(dest);
|
|
||||||
|
|
||||||
src.close();
|
|
||||||
dest.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
##===- examples/BFtoLLVM/Makefile --------------------------*- Makefile -*-===##
|
|
||||||
#
|
|
||||||
# The LLVM Compiler Infrastructure
|
|
||||||
#
|
|
||||||
# This file was developed by the LLVM research group and is distributed under
|
|
||||||
# the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
||||||
#
|
|
||||||
##===----------------------------------------------------------------------===##
|
|
||||||
|
|
||||||
LEVEL = ../..
|
|
||||||
TOOLNAME = BFtoLLVM
|
|
||||||
EXAMPLE_TOOL = 1
|
|
||||||
include $(LEVEL)/Makefile.common
|
|
@ -1,45 +0,0 @@
|
|||||||
##===- examples/BFtoLLVM/tests/Makefile --------------------*- Makefile -*-===##
|
|
||||||
#
|
|
||||||
# The LLVM Compiler Infrastructure
|
|
||||||
#
|
|
||||||
# This file was developed by the LLVM research group and is distributed under
|
|
||||||
# the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
||||||
#
|
|
||||||
##===----------------------------------------------------------------------===##
|
|
||||||
|
|
||||||
# Makefile for bf2llvm tests.
|
|
||||||
|
|
||||||
LEVEL = ../../..
|
|
||||||
BFTOLLVM = $(LLVMTOOLCURRENT)/BFtoLLVM
|
|
||||||
|
|
||||||
include $(LEVEL)/Makefile.common
|
|
||||||
|
|
||||||
all:: check
|
|
||||||
|
|
||||||
clean::
|
|
||||||
rm -rf Output
|
|
||||||
|
|
||||||
.SUFFIXES: .ll .gccas.bc .llvm .cbe.c .cbe
|
|
||||||
|
|
||||||
Output/%.ll: %.b $(BFTOLLVM) Output/.dir
|
|
||||||
$(BFTOLLVM) $< $@
|
|
||||||
|
|
||||||
Output/%.gccas.bc: Output/%.ll Output/.dir
|
|
||||||
$(LGCCAS) $< -o $@
|
|
||||||
|
|
||||||
Output/%.llvm Output/%.llvm.bc: Output/%.gccas.bc Output/.dir
|
|
||||||
$(LGCCLD) $< -lc -lcrtend -o Output/$*.llvm
|
|
||||||
|
|
||||||
Output/%.cbe.c: Output/%.llvm.bc Output/.dir
|
|
||||||
$(LLC) -march=c -f -o=$@ $<
|
|
||||||
|
|
||||||
Output/%.cbe: Output/%.cbe.c Output/.dir
|
|
||||||
$(CC) -O2 $< -o $@
|
|
||||||
|
|
||||||
check: Output/hello.cbe hello.expected-out
|
|
||||||
@echo "Running test"
|
|
||||||
Output/hello.cbe > Output/hello.out-cbe
|
|
||||||
@echo "Checking result"
|
|
||||||
diff Output/hello.out-cbe hello.expected-out
|
|
||||||
@echo "Test passed"
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
Hello World program
|
|
||||||
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
|
|
||||||
<.#>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[
|
|
||||||
<++++>-]<+.[-]++++++++++.
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
Hello World!
|
|
@ -10,7 +10,7 @@ LEVEL=..
|
|||||||
|
|
||||||
include $(LEVEL)/Makefile.config
|
include $(LEVEL)/Makefile.config
|
||||||
|
|
||||||
PARALLEL_DIRS:= Fibonacci HowToUseJIT ModuleMaker BFtoLLVM
|
PARALLEL_DIRS:= Fibonacci HowToUseJIT ModuleMaker
|
||||||
|
|
||||||
ifeq ($(HAVE_PTHREAD),1)
|
ifeq ($(HAVE_PTHREAD),1)
|
||||||
PARALLEL_DIRS += ParallelJIT
|
PARALLEL_DIRS += ParallelJIT
|
||||||
|
Loading…
Reference in New Issue
Block a user