diff --git a/bindings/ocaml/backends/META.llvm_backend.in b/bindings/ocaml/backends/META.llvm_backend.in new file mode 100644 index 00000000000..0d4a6d68465 --- /dev/null +++ b/bindings/ocaml/backends/META.llvm_backend.in @@ -0,0 +1,8 @@ +name = "llvm_@TARGET@" +version = "@PACKAGE_VERSION@" +description = "@TARGET@ Backend for LLVM" +requires = "llvm" +archive(byte) = "llvm_@TARGET@.cma" +archive(native) = "llvm_@TARGET@.cmxa" +directory = "." +linkopts = "-ccopt -lstdc++" \ No newline at end of file diff --git a/bindings/ocaml/backends/Makefile b/bindings/ocaml/backends/Makefile new file mode 100644 index 00000000000..7698d6e0285 --- /dev/null +++ b/bindings/ocaml/backends/Makefile @@ -0,0 +1,56 @@ +##===- bindings/ocaml/backends/Makefile --------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This is the master makefile for backend-specific bindings. It works by +# creating a stub makefile for each configured target, e.g. Makefile.ARM, and +# invoking it to compile the corresponding library, e.g. Llvm_ARM. +# +# This scheme allows to keep changes to Makefile.ocaml minimal. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../../.. +ExtraMakefiles = $(PROJ_OBJ_DIR)/Makefile.common + +include $(LEVEL)/Makefile.config +include $(LEVEL)/Makefile.common + +all-local:: all-backends +clean-local:: clean-backends +install-local:: install-backends +uninstall-local:: uninstall-backends + +stubs: + $(Verb) for i in $(TARGETS_TO_BUILD); do \ + $(ECHO) "TARGET := $$i" > Makefile.$$i; \ + $(ECHO) "include Makefile.common" >> Makefile.$$i; \ + done + +all-backends: stubs + $(Verb) for i in $(TARGETS_TO_BUILD); do \ + $(MAKE) -f Makefile.$$i all; \ + done + +clean-backends: stubs + $(Verb) for i in $(TARGETS_TO_BUILD); do \ + $(MAKE) -f Makefile.$$i clean; \ + $(RM) -f Makefile.$$i; \ + done + +install-backends: stubs + $(Verb) for i in $(TARGETS_TO_BUILD); do \ + $(MAKE) -f Makefile.$$i install; \ + done + +uninstall-backends: stubs + $(Verb) for i in $(TARGETS_TO_BUILD); do \ + $(MAKE) -f Makefile.$$i uninstall; \ + done + +.PHONY: all-backends clean-backends install-backends uninstall-backends diff --git a/bindings/ocaml/backends/Makefile.common b/bindings/ocaml/backends/Makefile.common new file mode 100644 index 00000000000..be65dd0f861 --- /dev/null +++ b/bindings/ocaml/backends/Makefile.common @@ -0,0 +1,65 @@ +##===- bindings/ocaml/backends/Makefile.common -------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This is the slave makefile for backend-specific bindings. This makefile should +# be included after defining TARGET. It will then substitute @TARGET@ for +# the value of TARGET in various *.in files and build an OCaml library in +# a regular way. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../../.. +LIBRARYNAME := llvm_$(TARGET) +UsedComponents := $(TARGET) +UsedOcamlInterfaces := llvm + +include $(LEVEL)/Makefile.config + +SOURCES := $(TARGET)_ocaml.c +OcamlHeaders1 := $(PROJ_SRC_DIR)/llvm_$(TARGET).mli +OcamlSources1 := $(PROJ_SRC_DIR)/llvm_$(TARGET).ml + +include ../Makefile.ocaml + +$(ObjDir)/llvm_$(TARGET).ml: $(PROJ_SRC_DIR)/llvm_backend.ml.in $(ObjDir)/.dir + $(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' $< > $@ + +$(ObjDir)/llvm_$(TARGET).mli: $(PROJ_SRC_DIR)/llvm_backend.mli.in $(ObjDir)/.dir + $(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' $< > $@ + +$(ObjDir)/$(TARGET)_ocaml.o: $(PROJ_SRC_DIR)/backend_ocaml.c $(ObjDir)/.dir + $(Echo) "Compiling $*.c for $(BuildMode) build" $(PIC_FLAG) + $(Verb) $(Compile.C) -DTARGET=$(TARGET) $< -o $@ + + +##===- OCamlFind Package --------------------------------------------------===## + +all-local:: copy-meta +install-local:: install-meta +uninstall-local:: uninstall-meta + +DestMETA := $(PROJ_libocamldir)/META.llvm_$(TARGET) + +# Easy way of generating META in the objdir +copy-meta: $(OcamlDir)/META.llvm_$(TARGET) + +$(OcamlDir)/META.llvm_$(TARGET): META.llvm_backend.in + $(Verb) $(SED) -e 's/@TARGET@/$(TARGET)/' \ + -e 's/@PACKAGE_VERSION@/$(LLVMVersion)/' $< > $@ + +install-meta:: $(OcamlDir)/META.llvm_$(TARGET) + $(Echo) "Install $(BuildMode) $(DestMETA)" + $(Verb) $(MKDIR) $(PROJ_libocamldir) + $(Verb) $(DataInstall) $< "$(DestMETA)" + +uninstall-meta:: + $(Echo) "Uninstalling $(DestMETA)" + -$(Verb) $(RM) -f "$(DestMETA)" + +.PHONY: copy-meta install-meta uninstall-meta diff --git a/bindings/ocaml/backends/backend_ocaml.c b/bindings/ocaml/backends/backend_ocaml.c new file mode 100644 index 00000000000..fd6d06d90fb --- /dev/null +++ b/bindings/ocaml/backends/backend_ocaml.c @@ -0,0 +1,37 @@ +/*===-- backend_ocaml.c - LLVM OCaml Glue -----------------------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file glues LLVM's OCaml interface to its C interface. These functions *| +|* are by and large transparent wrappers to the corresponding C functions. *| +|* *| +|* Note that these functions intentionally take liberties with the CAMLparamX *| +|* macros, since most of the parameters are not GC heap objects. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c/Target.h" +#include "caml/alloc.h" +#include "caml/memory.h" + +#define INITIALIZER1(target) \ + CAMLprim value llvm_initialize_ ## target(value Unit) { \ + LLVMInitialize ## target ## TargetInfo(); \ + LLVMInitialize ## target ## Target(); \ + LLVMInitialize ## target ## TargetMC(); \ + // TODO: Figure out how to call these only for targets \ + // which support them. \ + // LLVMInitialize ## target ## AsmPrinter(); \ + // LLVMInitialize ## target ## AsmParser(); \ + // LLVMInitialize ## target ## Disassembler(); \ + return Val_unit; \ + } + +#define INITIALIZER(target) INITIALIZER1(target) + +INITIALIZER(TARGET) diff --git a/bindings/ocaml/backends/llvm_backend.ml.in b/bindings/ocaml/backends/llvm_backend.ml.in new file mode 100644 index 00000000000..bd1e5860aa2 --- /dev/null +++ b/bindings/ocaml/backends/llvm_backend.ml.in @@ -0,0 +1,10 @@ +(*===-- llvm_backend.ml.in - LLVM OCaml Interface -------------*- OCaml -*-===* + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===*) + +external initialize : unit -> unit = "llvm_initialize_@TARGET@" diff --git a/bindings/ocaml/backends/llvm_backend.mli.in b/bindings/ocaml/backends/llvm_backend.mli.in new file mode 100644 index 00000000000..9506789a7fd --- /dev/null +++ b/bindings/ocaml/backends/llvm_backend.mli.in @@ -0,0 +1,19 @@ +(*===-- llvm_backend.mli.in - LLVM OCaml Interface ------------*- OCaml -*-===* + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===*) + +(** @TARGET@ Initialization. + + This interface provides an OCaml API for initialization of + the @TARGET@ LLVM target. By referencing this module, you will cause + OCaml to load or link in the LLVM libraries corresponding to the target. + By calling [initialize], you will register components of this target + in the target registry, which is necessary in order to emit assembly, + object files, and so on. *) + +external initialize : unit -> unit = "llvm_initialize_@TARGET@" \ No newline at end of file