summaryrefslogtreecommitdiff
path: root/ll
diff options
context:
space:
mode:
Diffstat (limited to 'll')
-rw-r--r--ll/Makefile16
-rw-r--r--ll/ding.c30
-rw-r--r--ll/gen.hs57
-rw-r--r--ll/test.ll104
4 files changed, 207 insertions, 0 deletions
diff --git a/ll/Makefile b/ll/Makefile
new file mode 100644
index 0000000..f19648f
--- /dev/null
+++ b/ll/Makefile
@@ -0,0 +1,16 @@
+.PHONY: all clean remake
+
+all: test
+
+clean:
+ rm test test.s
+
+remake: clean
+ make all
+
+
+test: test.s
+ clang -Wall -Wextra $< -o $@
+
+test.s: test.ll
+ llc -W $< -o $@
diff --git a/ll/ding.c b/ll/ding.c
new file mode 100644
index 0000000..b6b4bf2
--- /dev/null
+++ b/ll/ding.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int mandeliter(double x,double y){
+ double a=x,b=y;
+ int n=0;
+ while(n<256){
+ double na=a*a-b*b+x;
+ double nb=2*a*b+y;
+ a=na;
+ b=nb;
+ if(a*a+b*b>4)break;
+ n++;
+ }
+ return n;
+}
+
+int main(void){
+ double x,y;
+ y=1.5;
+ while(y>=-1.5){
+ x=-2;
+ while(x<=1){
+ int n=mandeliter(x,y);
+ printf("%3d ",n);
+ x+=0.0625;
+ }
+ y-=0.125;
+ putchar('\n');
+ }
+}
diff --git a/ll/gen.hs b/ll/gen.hs
new file mode 100644
index 0000000..907a489
--- /dev/null
+++ b/ll/gen.hs
@@ -0,0 +1,57 @@
+import qualified LLVM.General.AST.Type as AST
+import qualified LLVM.General.AST.Global as AST
+import qualified LLVM.General.AST.Constant as AST.C
+import qualified LLVM.General.AST.Operand as AST
+import qualified LLVM.General.AST.Name as AST
+import qualified LLVM.General.AST.Instruction as AST
+import qualified LLVM.General.AST as AST
+import qualified LLVM.General as General
+import qualified LLVM.General.Context as General
+import qualified LLVM.General.Target as General
+import Control.Monad.Except
+import qualified Data.ByteString as BS
+import System.Exit
+
+
+bb1 :: AST.BasicBlock
+bb1 = AST.BasicBlock (AST.Name "bb1")
+ [AST.Name "s" AST.:= AST.Add False False
+ (AST.LocalReference AST.i32 (AST.Name "argc"))
+ (AST.ConstantOperand (AST.C.Int 32 1))
+ []]
+ (AST.Do $ AST.Ret (Just $ AST.LocalReference AST.i32 (AST.Name "s")) [])
+
+func :: AST.Global
+func = AST.functionDefaults {
+ AST.returnType = AST.i32,
+ AST.name = AST.Name "main",
+ AST.parameters =
+ ([AST.Parameter AST.i32 (AST.Name "argc") [],
+ AST.Parameter (AST.ptr (AST.ptr AST.i8)) (AST.Name "argv") []],
+ False),
+ AST.basicBlocks = [bb1]
+ }
+
+topmod :: AST.Module
+topmod = AST.defaultModule {AST.moduleDefinitions = [AST.GlobalDefinition func]}
+
+
+assert :: ExceptT String IO a -> IO a
+assert ex = do
+ e <- runExceptT ex
+ either die return e >> (return $ (\(Right r) -> r) e)
+
+main :: IO ()
+main = do
+ General.withContext $ \context -> do
+ assert $ General.withModuleFromAST context topmod $ \genmod -> do
+ llvmasm <- General.moduleLLVMAssembly genmod
+ putStr llvmasm
+ putStrLn ""
+ assert $ General.withHostTargetMachine $ \machine -> do
+ General.getTargetMachineTriple machine >>= putStrLn
+ putStrLn ""
+ assert (General.moduleTargetAssembly machine genmod)
+ >>= putStr
+ bs <- assert $ General.moduleObject machine genmod
+ BS.writeFile "output_gen.o" bs
diff --git a/ll/test.ll b/ll/test.ll
new file mode 100644
index 0000000..8da7408
--- /dev/null
+++ b/ll/test.ll
@@ -0,0 +1,104 @@
+declare i32 @printf(i8*, ...)
+declare void @putchar(i32)
+
+
+@maxiter = internal constant i32 32
+@lbound = internal constant double -2.0
+@rbound = internal constant double 1.0
+@tbound = internal constant double 1.5
+@bbound = internal constant double -1.5
+@hincr = internal constant double 0.03125
+@vincr = internal constant double 0.0625
+
+
+define internal i32 @mandeliter(double %x, double %y) {
+entry:
+ br label %loopbody
+
+loopbody:
+ %a = phi double [%x, %entry], [%na, %increment]
+ %b = phi double [%y, %entry], [%nb, %increment]
+ %n = phi i32 [0, %entry], [%nn, %increment]
+
+ %a2 = fmul double %a, %a
+ %b2 = fmul double %b, %b
+ %a2mb2 = fsub double %a2, %b2
+ %na = fadd double %a2mb2, %x
+
+ %ab = fmul double %a, %b
+ %ab2 = fadd double %ab, %ab
+ %nb = fadd double %ab2, %y
+
+ %norm = fadd double %a2, %b2
+ %cmp = fcmp ogt double %norm, 4.0
+ br i1 %cmp, label %afterloop, label %increment
+
+increment:
+ %nn = add i32 %n, 1
+ %maxiter = load i32, i32* @maxiter
+ %icmp = icmp slt i32 %nn, %maxiter
+ br i1 %icmp, label %loopbody, label %afterloop
+
+afterloop:
+ %retn = phi i32 [%n, %loopbody], [%nn, %increment]
+ ret i32 %retn
+}
+
+
+@num_formatstr = internal constant [4 x i8] c"%d \00"
+
+define internal void @printnum32(i32 %n) {
+entry:
+ %f = getelementptr [4 x i8], [4 x i8]* @num_formatstr, i64 0, i32 0
+ call i32(i8*, ...) @printf(i8* %f, i32 %n)
+ ret void
+}
+
+define internal void @printnum8(i8 %n) {
+entry:
+ %n32 = sext i8 %n to i32
+ tail call void @printnum32(i32 %n32)
+ ret void
+}
+
+
+@shadestr = internal constant [10 x i8] c" .,-:!%@#\00"
+
+
+define i32 @main() {
+entry:
+ %lbound = load double, double* @lbound
+ %rbound = load double, double* @rbound
+ %tbound = load double, double* @tbound
+ %bbound = load double, double* @bbound
+ %hincr = load double, double* @hincr
+ %vincr = load double, double* @vincr
+ br label %yloop
+
+yloop:
+ %y = phi double [%tbound, %entry], [%ny, %yloop2]
+ br label %xloop
+
+xloop:
+ %x = phi double [%lbound, %yloop], [%nx, %xloop]
+ %n = call i32 @mandeliter(double %x, double %y)
+ %nL = mul i32 %n, 8
+ %maxiter = load i32, i32* @maxiter
+ %nLdM = sdiv i32 %nL, %maxiter
+ %shadechrp = getelementptr [10 x i8], [10 x i8]* @shadestr, i64 0, i32 %nLdM
+ %shadechr = load i8, i8* %shadechrp
+ %shadeint = sext i8 %shadechr to i32
+ call void @putchar(i32 %shadeint)
+ %nx = fadd double %x, %hincr
+ %xcmp = fcmp ole double %nx, %rbound
+ br i1 %xcmp, label %xloop, label %yloop2
+
+yloop2:
+ %ny = fsub double %y, %vincr
+ call void @putchar(i32 10)
+ %ycmp = fcmp oge double %ny, %bbound
+ br i1 %ycmp, label %yloop, label %return
+
+return:
+ ret i32 0
+}