Skip to content

Commit

Permalink
initial checkin
Browse files Browse the repository at this point in the history
  • Loading branch information
MORITA Hajime committed Aug 24, 2008
0 parents commit 4c96967
Show file tree
Hide file tree
Showing 12 changed files with 5,398 additions and 0 deletions.
551 changes: 551 additions & 0 deletions JSBackend.cpp

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions JSTargetMachine.h
@@ -0,0 +1,45 @@
//===-- JSTargetMachine.h - TargetMachine for the JavaScript backend ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the TargetMachine that is used by the C backend.
//
//===----------------------------------------------------------------------===//

#ifndef JSTARGETMACHINE_H
#define JSTARGETMACHINE_H

#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetData.h"

namespace llvm {

struct JSTargetMachine : public TargetMachine {
const TargetData DataLayout; // Calculates type size & alignment

JSTargetMachine(const Module &M, const std::string &FS)
: DataLayout(&M) {}

virtual FileModel::Model addPassesToEmitFile(PassManagerBase &PM,
std::ostream &Out,
CodeGenFileType FileType,
bool /*Fast*/);

virtual bool addPassesToEmitFileFinish(PassManagerBase &,
MachineCodeEmitter *, bool /*Fast*/);

// This class always works, but shouldn't be the default in most cases.
static unsigned getModuleMatchQuality(const Module &M) { return 1; }

virtual const TargetData *getTargetData() const { return &DataLayout; }
};

} // End llvm namespace


#endif
137 changes: 137 additions & 0 deletions MEMO.txt
@@ -0,0 +1,137 @@

* TODO

+ 関数定義
> ローカル変数
+ stub
+ 単体 alloca
+ 配列 alloca
+ 構造体 alloca
- 名前に . が入るのをなんとかする
- phi node
- どうやるとできる?
- 現状の for loop は store しちゃってる
- 定数
+ 整数
- 浮動小数
- もっとややこしいの
- load
+ store
- 四則演算
- 制御構造
- if/else
- for
- while
- do/while
- switch
- 関数呼び出し
- 引数
- 構造体
- ローカル
- 引数
- 戻り値
- ポインタ
- ポインタ
- 配列
- 配列の配列
- 関数ポインタ
- キャスト
- 外部関数 (宣言)
- グローバル変数

- リンク


------

int addition_and_multiplication() {
int a = 1;
int b = 2;
int c = a + b;
return c*2;
}

----

function addition_and_multiplication() {
var a;
a = 1;
var b;
b = 2;
var c;
c = a + b;
var mul = c*2;
return mul;
}

----
- 配列アクセスは runtime に.
- 構造体もかなー...
----

* ポインタ
- adaptor object
function Ptr(ref) {
this.__ref = ref;
}

function PtrToArray(ref, arr, idx) {
this.__ref = ref;
this.__arr = arr;
this.__idx = idx;
}

- isDirectAlloca の値は特別扱い
- load でそのまま値を代入 (__ref を辿らない)
- 値として出てきたら Ptr でラップする (つじつまあわせで indirect する)

* 分岐/スコープ

- basic block の名前でローカル関数をつくる
- 分岐は __next に行き先ブロック関数を代入
- return は __next に null;

function foo() {
var __label_1 = function() {
alert("label_1");
__next = __label_2;
};
var __label_2 = function() {
alert("label_2");
__next = null;
};

var __next = __label_1;
while (__next) {
var __tocall = __next;
__tocall();
}
}

------
switch/case が自然という説

function foo() {
var __bb = 0;
while(0 <= __bb) {
switch(__bb) {
case 0:
alert("label_1");
__bb = 1;
break;
case 1:
alert("label_2");
__bb = -1;
break;
}
}
}

* 制限
- キャスト -> 型情報, サイズとかに依存されるとアウト.
- union も当然ダメ.
- アドレスに細工はアウト
- 下位ビットになんか入れとくとか

http://llvm.org/ : LLVM 公式サイト
http://llvm.org/devmtg/2008-08/ : 2008 LLVM Developers' Meeting (スライドとビデオ)
21 changes: 21 additions & 0 deletions Makefile
@@ -0,0 +1,21 @@
#===- tools/llc/Makefile -----------------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LEVEL = ../..
TOOLNAME = jsllc

# Include this here so we can get the configuration of the targets
# that have been configured for construction. We have to do this
# early so we can set up LINK_COMPONENTS before including Makefile.rules
include $(LEVEL)/Makefile.config

LINK_COMPONENTS := $(TARGETS_TO_BUILD) bitreader

include $(LLVM_SRC_ROOT)/Makefile.rules

25 changes: 25 additions & 0 deletions README.txt
@@ -0,0 +1,25 @@

* JSBackend : toy llvm backend for javascript

components:
- jsllc : llc dialect to (only) use JSBackend.
see hello/Makefile to know how to use
- JSBackend: CBackend-based code generator

build:

# checkout llvm trunk
$ svn co llvm http://llvm.org/svn/llvm-project/llvm/trunk/
# make llvm
$ cd trunk
$ configure; make
# checkout jsllc into "tools" directory
$ cd tools
$ git clone http://github.com/omo/jsllc/master
# make jsllc
$ cd jsllc
$ make
# try the example
$ cd hello
$ make
$ firefox hello.html
16 changes: 16 additions & 0 deletions hello/Makefile
@@ -0,0 +1,16 @@
BIN_DIR=../../../Debug/bin/
SRC=hello.c
all:
${BIN_DIR}/clang --emit-llvm-bc hello.c
${BIN_DIR}/clang --emit-llvm hello.c
${BIN_DIR}/opt --std-compile-opts -print hello.bc -o=- > hello_opt.bc 2> hello_opt.ll
${BIN_DIR}/jsllc hello_opt.bc -o hello_opt.js
${BIN_DIR}/jsllc hello.bc -o hello.js

clean:
-rm *.ll
-rm *.bc
-rm *_opt.*
-rm hello.js

.PHONY: all
48 changes: 48 additions & 0 deletions hello/hello.c
@@ -0,0 +1,48 @@

void* malloc(int);
void putc(char);
void extern_puts(const char*);

int add(int a, int b) {
int x = a + b;
return x;
}

int fac(int n) {
int x = 1, i = 0;
for (i=0; i<n; i++) { x *= (i+1); }
return x;
}

void puts(const char* str) {
while (*str) {
putc(*(str++));
}
}

void put_hello() {
puts("hello\n");
}

void put_hello_extern() {
extern_puts("hello\n");
}

void upcase(char* str) {
while (*str) {
if ('A' <= *str && *str <= 'z') { *str -= ('a' - 'A'); }
str++;
}
}

void put_hello_upcase() {
char hello[] = "hello";
upcase(hello);
puts(hello);
}

void put_hello_upcase_extern() {
char hello[] = "hello";
upcase(hello);
extern_puts(hello);
}
33 changes: 33 additions & 0 deletions hello/hello.html
@@ -0,0 +1,33 @@
<html>
<head>
<script src="prototype.js" ></script>
<script src="jsbe.js" ></script>
<script src="hello_opt.js" ></script>
<script>
function hello_onload() {
__JSBE.print = function(x) {
var e = $('console')
e.innerHTML = e.innerHTML + x;
}
}

function hello_eval_form() {
eval($('toeval').value);
}
</script>
</head>
<body onload="hello_onload();">
<pre id="console"
style="font-size:40; font-family:verdana; font-weight:bold; background-color: #ccc;
height: 5em; overflow:auto">
&nbsp;
</pre>
<form>
<textarea id="toeval"
style="font-size:16; font-family:verdana; width:80%;">
</textarea>
<br />
<input type="button" onclick="hello_eval_form()" value="eval!"/>
</form>
</body>
</html>

0 comments on commit 4c96967

Please sign in to comment.