It looks like you don't mind the overhead of calling an OCaml function if the function you called can be written in the assembly. I just did some experiments, and you can do it using the method described above.
Here is what I did. To get a working assembly language template, I defined a simple function in OCaml and compiled with the -S flag.
$ cat sep.ml let addto x = x + 1 $ /usr/local/ocaml312/bin/ocamlopt -inline 0 -c -S sep.ml
Note: you need to specify -inline 0
to ensure that ocamlopt takes the code from your generated .o file, and not from the inline definition in the .cmx file.
You now have a file called sep.s. The addto
function looks like this (surprisingly good code, actually):
_camlSep__addto_1030: .L100: addq $2, %rax ret
For the test only, I changed 2 (which represents 1 in OCaml) to 4 (which represents 2 in OCaml). So now you have:
_camlSep__addto_1030: .L100: addq $4, %rax ret
Now compile this file by creating a deviant version of sep.o.
$ as -o sep.o sep.s
Essentially, you tricked ocamlopt into processing the code in sep.o as if it were encoded in OCaml. But you can write the code yourself in the assembly (if you do not violate any architectural assumptions).
You can link it to the main program and run it:
$ cat main.ml let main () = Printf.printf "%d\n" (Sep.addto 19) let () = main () $ /usr/local/ocaml312/bin/ocamlopt -o main sep.cmx main.ml $ main 21
As you can see, it runs the modified assembly code.
You can follow this procedure to create any OCaml functions called into the assembly code. If you don't mind the overhead of calling an OCaml function, this approach can do what you want.
I do not know how this trick will affect debugging and garbage collection processing, so I would not try this with a function that makes any allocations.
These tests were run on Mac OS X 10.6.8 using OCaml 3.12.0 (64-bit build). When I run the how, I run the OS X builder with Xcode 4.0.2, which uses the x86_64 architecture by default.