120 |
120 |
121 callerFunctionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr. |
121 callerFunctionType := LLVMType function: { LLVMType intptr . LLVMType intptr } returning: LLVMType intptr. |
122 callerFunction := module addFunctionNamed: 'sum_caller' type: callerFunctionType. |
122 callerFunction := module addFunctionNamed: 'sum_caller' type: callerFunctionType. |
123 |
123 |
124 asm := callerFunction builder. |
124 asm := callerFunction builder. |
125 asm ret: (asm call: calleeFunction with: (callerFunction parameterAt: 1) with: (callerFunction parameterAt: 2)). |
125 asm ret: (asm call: calleeFunction _: { (callerFunction parameterAt: 1) . (callerFunction parameterAt: 2) }). |
126 self assert: (module dumpString = |
126 self assert: (module dumpString = |
127 '; ModuleID = ''example2_function_call'' |
127 '; ModuleID = ''example2_function_call'' |
128 |
128 |
129 define i64 @sum(i64, i64) { |
129 define i64 @sum(i64, i64) { |
130 entry: |
130 entry: |
131 %2 = add i64 %0, %1 |
131 %2 = add i64 %0, %1 |
172 |
172 |
173 mainFunctionType := LLVMType function: #() returning: LLVMType int32. |
173 mainFunctionType := LLVMType function: #() returning: LLVMType int32. |
174 mainFunction := module addFunctionNamed: 'main' type: mainFunctionType. |
174 mainFunction := module addFunctionNamed: 'main' type: mainFunctionType. |
175 |
175 |
176 asm := mainFunction builder. |
176 asm := mainFunction builder. |
177 asm call: printfFunction with: (asm gep: helloWorldString at: #(0 0)). |
177 asm call: printfFunction _: { asm gep: helloWorldString at: #(0 0) }. |
178 asm ret: (LLVMConstant sint32: 0). |
178 asm ret: (LLVMConstant sint32: 0). |
179 " |
179 " |
180 module writeBitcodeToFile: '/tmp/main.bc' |
180 module writeBitcodeToFile: '/tmp/main.bc' |
181 " |
181 " |
182 jit := LLVMExecutionEngine newForModule: module. |
182 jit := LLVMExecutionEngine newForModule: module. |
301 " |
301 " |
302 LLVMExamples example3_cond |
302 LLVMExamples example3_cond |
303 " |
303 " |
304 |
304 |
305 "Created: / 10-08-2015 / 09:46:29 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
305 "Created: / 10-08-2015 / 09:46:29 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
306 ! |
|
307 |
|
308 example5_factorial_with_overflow |
|
309 " |
|
310 Simple factorial using recursive algorithm. |
|
311 This one checks for overflow, if overflow happens, |
|
312 return -1 |
|
313 " |
|
314 |
|
315 | module |
|
316 functionType function asm |
|
317 "Variables" result i |
|
318 "Blocks" entry loop loopBody1 loopBody2 exit overflow |
|
319 smulWithOverflow |
|
320 smulWithOverflowValue |
|
321 jit externalFunction | |
|
322 |
|
323 module := LLVMModule newWithName: testSelector. |
|
324 |
|
325 functionType := LLVMType function: { LLVMType intptr } returning: LLVMType intptr. |
|
326 function := module addFunctionNamed: 'factorial' type: functionType. |
|
327 |
|
328 asm := LLVMBuilder new. |
|
329 entry := function entry. |
|
330 loop := function addBasicBlockNamed: 'loop'. |
|
331 loopBody1 := function addBasicBlockNamed: 'loopBody1'. |
|
332 loopBody2 := function addBasicBlockNamed: 'loopBody2'. |
|
333 exit := function addBasicBlockNamed: 'exit'. |
|
334 overflow := function addBasicBlockNamed: 'overflow'. |
|
335 |
|
336 "/ Generate function setup |
|
337 "/ |
|
338 "/ function f(v) { |
|
339 "/ var result; |
|
340 "/ var i; |
|
341 "/ result = 0; |
|
342 "/ i := v; |
|
343 asm block: entry. |
|
344 result := asm alloca: LLVMType intptr as: 'result'. |
|
345 i := asm alloca: LLVMType intptr as: 'i'. |
|
346 asm store: (function parameterAt: 1) _: i. |
|
347 asm store: (function parameterAt: 1) _: result. |
|
348 asm br: loop. |
|
349 |
|
350 "/ Generate loop that computes the factorial |
|
351 "/ |
|
352 "/ while ( i > 1 ) { |
|
353 "/ result = result * i if overflow goto overflow; |
|
354 "/ i = i - 1. |
|
355 "/ } |
|
356 "/ |
|
357 "/ First, get the llvm.smul.with.overflow intrinsic: |
|
358 smulWithOverflow := module getIntrinsicNamed: 'llvm.smul.with.overflow' types: { LLVMType intptr }. |
|
359 |
|
360 "/ Now code the loop |
|
361 asm block: loop. |
|
362 asm if: (asm icmp: (asm load: i) _: (LLVMConstant sintptr:1) cond: LLVMIntSGT) then: loopBody1 else: exit. |
|
363 asm block: loopBody1. |
|
364 smulWithOverflowValue := asm call: smulWithOverflow _: { (asm load: result) . (asm load: i) }. |
|
365 asm if: (asm extractvalue: smulWithOverflowValue at: 1) then: overflow else: loopBody2. |
|
366 asm block: loopBody2. |
|
367 asm store: (asm extractvalue: smulWithOverflowValue at: 0) _: result. |
|
368 asm store: (asm sub: (asm load: i) _: (LLVMConstant sintptr:1)) _: i. |
|
369 asm br: loop. |
|
370 |
|
371 "/ Generate return from function |
|
372 "/ |
|
373 "/ return result; |
|
374 "/ |
|
375 asm block: exit. |
|
376 asm ret: (asm load: result). |
|
377 |
|
378 "/ Generate overflow handler |
|
379 "/ overflow: |
|
380 "/ return -1; |
|
381 "/ |
|
382 asm block: overflow. |
|
383 asm ret: (LLVMConstant sintptr: -1). |
|
384 |
|
385 |
|
386 jit := LLVMExecutionEngine newForModule: module. |
|
387 externalFunction := jit externalOfFunction: function. |
|
388 |
|
389 self assert: (externalFunction callWith: 5) == 120. |
|
390 self assert: (externalFunction callWith: 1) == 1. |
|
391 self assert: (externalFunction callWith: 120) == -1. |
|
392 |
|
393 "sly LLVMExamples example3_cond |
|
394 " |
|
395 |
|
396 "Created: / 10-08-2015 / 17:12:00 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
397 "Modified: / 10-08-2015 / 18:58:51 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
306 ! ! |
398 ! ! |
307 |
399 |