On 2012-01-18, at 10:19 PM, Logiciel Gambit wrote:
Gambit-C v4.6.3 is now available.
Changelog: http://www.iro.umontreal.ca/~gambit/repo/.cgit.cgi/Gambit/log/
One of the important new features of Gambit-C is an X86 assembler which allows generating machine code on the fly and executing it, without the need for an external assembler. This is one of the important pieces of the X86 backend for Gambit that I have been working on recently. I also have an ARM assembler in the works, but it is not in this release.
Below is an example of dynamic X86 code generation and execution.
Marc
(include "~~lib/_asm#.scm") (include "~~lib/_x86#.scm") (include "~~lib/_codegen#.scm")
(define (u8vector->procedure code) (machine-code-block->procedure (u8vector->machine-code-block code)))
(define (u8vector->machine-code-block code) (let* ((len (u8vector-length code)) (mcb (##make-machine-code-block len))) (let loop ((i (fx- len 1))) (if (fx>= i 0) (begin (##machine-code-block-set! mcb i (u8vector-ref code i)) (loop (fx- i 1))) mcb))))
(define (machine-code-block->procedure mcb) (lambda (#!optional (arg1 0) (arg2 0) (arg3 0)) (##machine-code-block-exec mcb arg1 arg2 arg3)))
(define (create-procedure arch gen #!optional (show-listing? #t)) (let* ((cgc (make-codegen-context)) (endianness 'le))
(asm-init-code-block cgc 0 endianness) (codegen-context-listing-format-set! cgc 'nasm) (x86-arch-set! cgc arch)
(gen cgc)
(let ((code (asm-assemble-to-u8vector cgc))) (if show-listing? (asm-display-listing cgc (current-output-port) #t)) (u8vector->procedure code))))
(define f (create-procedure 'x86-64 (lambda (cgc) (x86-mov cgc (x86-rax) (x86-rdi)) ;; rdi = arg1 (on x86-64) (x86-imul cgc (x86-rax) (x86-rax) (x86-imm-int 7)) (x86-ret cgc))))
(pp (f 10))
;; Output : ;; ;; % gsc -i example.scm ;; 000000 bits 64 ;; 000000 4889f8 mov rax,rdi ;; 000003 486bc007 imul rax,rax,byte 7 ;; 000007 c3 ret ;; 70