LLVMExamples.st
changeset 23 0744cd9c0acc
parent 22 789a35bd30ac
child 24 7e7ddd55174c
--- a/LLVMExamples.st	Sat Aug 08 04:43:00 2015 +0100
+++ b/LLVMExamples.st	Mon Aug 10 10:33:42 2015 +0100
@@ -228,5 +228,80 @@
     "
 
     "Created: / 08-08-2015 / 04:16:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+example5_factorial
+    "
+    S simple factorial using recursive algorithm.
+    No negative argument or overflow checks
+    "    
+
+    | module 
+      functionType function asm 
+      "Variables" result i 
+      "Blocks"    entry loop loopBody exit
+      jit externalFunction |
+
+    module := LLVMModule newWithName: testSelector.
+
+    functionType := LLVMType function: { LLVMType intptr } returning: LLVMType intptr.
+    function := module addFunctionNamed: 'factorial' type: functionType.
+
+    asm := LLVMBuilder new.
+    entry := function entry.
+    loop  := function addBasicBlockNamed: 'loop'.
+    loopBody  := function addBasicBlockNamed: 'loopBody'.
+    exit  := function addBasicBlockNamed: 'exit'.
+
+    "/ Generate function setup
+    "/ 
+    "/   function f(v) {
+    "/     var result;
+    "/     var i;
+    "/     result = 0;
+    "/     i := v;
+    asm block: entry.
+    result := asm alloca: LLVMType intptr as: 'result'.
+    i := asm alloca: LLVMType intptr as: 'i'.
+    asm store: (function parameterAt: 1)   _: i.
+    asm store: (function parameterAt: 1) _: result.
+    asm br: loop.
+
+    "/ Generate loop that computes the factorial
+    "/ 
+    "/     while ( i > 1 ) {
+    "/       result = result * i;
+    "/       i = i - 1.
+    "/     }
+    "/ 
+    "/ Note, that unlike 'traditional' assemblers, there's no
+    "/ fall-through instruction, so we have to introduce a block 
+    "/ loop's body which will become a target for conditional's
+    "/ then-branch.
+    asm block: loop.
+    asm if: (asm icmp: (asm load: i) _: (LLVMConstant sintptr:1) cond: LLVMIntSGT) then: loopBody else: exit.
+    asm block: loopBody.
+    asm store: (asm mul: (asm load: result) _: (asm load: i)) _: result.
+    asm store: (asm sub: (asm load: i) _: (LLVMConstant sintptr:1)) _: i.
+    asm br: loop.
+
+    "/ Generate return from function
+    "/ 
+    "/     return result;
+    "/ 
+    asm block: exit.
+    asm ret: (asm load: result).
+
+    jit := LLVMExecutionEngine newForModule: module.
+    externalFunction := jit externalOfFunction: function.
+
+    self assert: (externalFunction callWith: 5) == 120.
+    self assert: (externalFunction callWith: 1) == 1.
+
+    "
+    LLVMExamples example3_cond
+    "
+
+    "Created: / 10-08-2015 / 09:46:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !