--- 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>"
! !