1dfc58e3bcfcb8f37796b2ca1c289dd202f26d03cSylvestre Ledru/*===-- target_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\
23e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                                                                            *|
33e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                     The LLVM Compiler Infrastructure                       *|
43e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                                                                            *|
53e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|* This file is distributed under the University of Illinois Open Source      *|
63e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|* License. See LICENSE.TXT for details.                                      *|
73e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                                                                            *|
83e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*===----------------------------------------------------------------------===*|
93e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                                                                            *|
10dfc58e3bcfcb8f37796b2ca1c289dd202f26d03cSylvestre Ledru|* This file glues LLVM's OCaml interface to its C interface. These functions *|
113e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|* are by and large transparent wrappers to the corresponding C functions.    *|
123e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                                                                            *|
133e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|* Note that these functions intentionally take liberties with the CAMLparamX *|
143e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|* macros, since most of the parameters are not GC heap objects.              *|
153e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen|*                                                                            *|
163e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen\*===----------------------------------------------------------------------===*/
173e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
183e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen#include "llvm-c/Target.h"
19b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#include "llvm-c/TargetMachine.h"
203e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen#include "caml/alloc.h"
21b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#include "caml/fail.h"
22b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#include "caml/memory.h"
2326f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov#include "caml/custom.h"
2426f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov
25b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/*===---- Exceptions ------------------------------------------------------===*/
26b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
27b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic value llvm_target_error_exn;
28b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
29b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_register_target_exns(value Error) {
30b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  llvm_target_error_exn = Field(Error, 0);
31b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  register_global_root(&llvm_target_error_exn);
32b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_unit;
33b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
34b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
35b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic void llvm_raise(value Prototype, char *Message) {
36b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CAMLparam1(Prototype);
37b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CAMLlocal1(CamlMessage);
38b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
39b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CamlMessage = copy_string(Message);
40b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMDisposeMessage(Message);
41b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
42b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  raise_with_arg(Prototype, CamlMessage);
43b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  abort(); /* NOTREACHED */
44b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#ifdef CAMLnoreturn
45b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
46b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#endif
47b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
48b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
49b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic value llvm_string_of_message(char* Message) {
50b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  value String = caml_copy_string(Message);
51b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMDisposeMessage(Message);
52b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
53b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return String;
54b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
55b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
56b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/*===---- Data Layout -----------------------------------------------------===*/
57b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
5804deb4957ab253c02bce9d982d69396954744a41Peter Zotov#define DataLayout_val(v)  (*(LLVMTargetDataRef *)(Data_custom_val(v)))
5926f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov
6004deb4957ab253c02bce9d982d69396954744a41Peter Zotovstatic void llvm_finalize_data_layout(value DataLayout) {
6104deb4957ab253c02bce9d982d69396954744a41Peter Zotov  LLVMDisposeTargetData(DataLayout_val(DataLayout));
6226f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov}
6326f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov
6404deb4957ab253c02bce9d982d69396954744a41Peter Zotovstatic struct custom_operations llvm_data_layout_ops = {
6504deb4957ab253c02bce9d982d69396954744a41Peter Zotov  (char *) "LLVMDataLayout",
6604deb4957ab253c02bce9d982d69396954744a41Peter Zotov  llvm_finalize_data_layout,
6726f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov  custom_compare_default,
6826f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov  custom_hash_default,
6926f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov  custom_serialize_default,
7026f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov  custom_deserialize_default
7126f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov#ifdef custom_compare_ext_default
7226f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov  , custom_compare_ext_default
7326f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov#endif
7426f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov};
7526f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov
7604deb4957ab253c02bce9d982d69396954744a41Peter Zotovvalue llvm_alloc_data_layout(LLVMTargetDataRef DataLayout) {
77b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  value V = alloc_custom(&llvm_data_layout_ops, sizeof(LLVMTargetDataRef),
78b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                         0, 1);
7904deb4957ab253c02bce9d982d69396954744a41Peter Zotov  DataLayout_val(V) = DataLayout;
8026f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov  return V;
8126f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov}
823e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
83791cfc211a9801002bfda6b3eb4de7e041f04f53Micah Villmow/* string -> DataLayout.t */
8404deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_of_string(value StringRep) {
8504deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return llvm_alloc_data_layout(LLVMCreateTargetData(String_val(StringRep)));
863e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
873e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
88791cfc211a9801002bfda6b3eb4de7e041f04f53Micah Villmow/* DataLayout.t -> string */
8904deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_as_string(value TD) {
9004deb4957ab253c02bce9d982d69396954744a41Peter Zotov  char *StringRep = LLVMCopyStringRepOfTargetData(DataLayout_val(TD));
913e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen  value Copy = copy_string(StringRep);
923e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen  LLVMDisposeMessage(StringRep);
933e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen  return Copy;
943e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
953e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
9604deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* [<Llvm.PassManager.any] Llvm.PassManager.t -> DataLayout.t -> unit */
9704deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_add_to_pass_manager(LLVMPassManagerRef PM,
9804deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                                   value DL) {
9904deb4957ab253c02bce9d982d69396954744a41Peter Zotov  LLVMAddTargetData(DataLayout_val(DL), PM);
10004deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_unit;
10104deb4957ab253c02bce9d982d69396954744a41Peter Zotov}
10204deb4957ab253c02bce9d982d69396954744a41Peter Zotov
103791cfc211a9801002bfda6b3eb4de7e041f04f53Micah Villmow/* DataLayout.t -> Endian.t */
10404deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_byte_order(value DL) {
10504deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMByteOrder(DataLayout_val(DL)));
1063e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1073e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
108791cfc211a9801002bfda6b3eb4de7e041f04f53Micah Villmow/* DataLayout.t -> int */
10904deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_pointer_size(value DL) {
11004deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMPointerSize(DataLayout_val(DL)));
11126f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov}
11226f3bd89660e46a76a3b0267b23b00d917a45404Peter Zotov
11304deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.llcontext -> DataLayout.t -> Llvm.lltype */
11404deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim LLVMTypeRef llvm_datalayout_intptr_type(LLVMContextRef C, value DL) {
11504deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return LLVMIntPtrTypeInContext(C, DataLayout_val(DL));;
1163e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1173e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
11804deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* int -> DataLayout.t -> int */
11904deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_qualified_pointer_size(value AS, value DL) {
12004deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMPointerSizeForAS(DataLayout_val(DL), Int_val(AS)));
121fa6ab4393ebb7add77a4a957dc50453d07b54a62Peter Zotov}
122fa6ab4393ebb7add77a4a957dc50453d07b54a62Peter Zotov
12304deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.llcontext -> int -> DataLayout.t -> Llvm.lltype */
12404deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim LLVMTypeRef llvm_datalayout_qualified_intptr_type(LLVMContextRef C,
12504deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                                           value AS,
12604deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                                           value DL) {
12704deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return LLVMIntPtrTypeForASInContext(C, DataLayout_val(DL), Int_val(AS));
128fa6ab4393ebb7add77a4a957dc50453d07b54a62Peter Zotov}
129fa6ab4393ebb7add77a4a957dc50453d07b54a62Peter Zotov
13004deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> DataLayout.t -> Int64.t */
13104deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_size_in_bits(LLVMTypeRef Ty, value DL) {
13204deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return caml_copy_int64(LLVMSizeOfTypeInBits(DataLayout_val(DL), Ty));
1333e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1343e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
13504deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> DataLayout.t -> Int64.t */
13604deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_store_size(LLVMTypeRef Ty, value DL) {
13704deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return caml_copy_int64(LLVMStoreSizeOfType(DataLayout_val(DL), Ty));
1383e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1393e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
14004deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> DataLayout.t -> Int64.t */
14104deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_abi_size(LLVMTypeRef Ty, value DL) {
14204deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return caml_copy_int64(LLVMABISizeOfType(DataLayout_val(DL), Ty));
1433e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1443e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
14504deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> DataLayout.t -> int */
14604deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_abi_align(LLVMTypeRef Ty, value DL) {
14704deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMABIAlignmentOfType(DataLayout_val(DL), Ty));
1483e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1493e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
15004deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> DataLayout.t -> int */
15104deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_stack_align(LLVMTypeRef Ty, value DL) {
15204deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMCallFrameAlignmentOfType(DataLayout_val(DL), Ty));
1533e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1543e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
15504deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> DataLayout.t -> int */
15604deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_preferred_align(LLVMTypeRef Ty, value DL) {
15704deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMPreferredAlignmentOfType(DataLayout_val(DL), Ty));
1583e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1593e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
16004deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.llvalue -> DataLayout.t -> int */
16104deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_preferred_align_of_global(LLVMValueRef GlobalVar,
16204deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                                         value DL) {
16304deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMPreferredAlignmentOfGlobal(DataLayout_val(DL), GlobalVar));
1643e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1653e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
16604deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> Int64.t -> DataLayout.t -> int */
16704deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_element_at_offset(LLVMTypeRef Ty, value Offset,
16804deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                                 value DL) {
16904deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return Val_int(LLVMElementAtOffset(DataLayout_val(DL), Ty,
17004deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                     Int64_val(Offset)));
1713e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
1723e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen
17304deb4957ab253c02bce9d982d69396954744a41Peter Zotov/* Llvm.lltype -> int -> DataLayout.t -> Int64.t */
17404deb4957ab253c02bce9d982d69396954744a41Peter ZotovCAMLprim value llvm_datalayout_offset_of_element(LLVMTypeRef Ty, value Index,
17504deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                                 value DL) {
17604deb4957ab253c02bce9d982d69396954744a41Peter Zotov  return caml_copy_int64(LLVMOffsetOfElement(DataLayout_val(DL), Ty,
17704deb4957ab253c02bce9d982d69396954744a41Peter Zotov                                             Int_val(Index)));
1783e0c83559397c87e06ef29c41385e7adc34573c2Gordon Henriksen}
179b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
180b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/*===---- Target ----------------------------------------------------------===*/
181b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
182b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic value llvm_target_option(LLVMTargetRef Target) {
183b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(Target != NULL) {
184b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    value Result = caml_alloc_small(1, 0);
185b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    Store_field(Result, 0, (value) Target);
186b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    return Result;
187b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  }
188b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
189b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_int(0);
190b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
191b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
192b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* unit -> string */
193b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_default_triple(value Unit) {
194b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  char *TripleCStr = LLVMGetDefaultTargetTriple();
195b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  value TripleStr = caml_copy_string(TripleCStr);
196b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMDisposeMessage(TripleCStr);
197b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
198b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return TripleStr;
199b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
200b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
201b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* unit -> Target.t option */
202b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_first(value Unit) {
203b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_target_option(LLVMGetFirstTarget());
204b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
205b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
206b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Target.t -> Target.t option */
207b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_succ(LLVMTargetRef Target) {
208b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_target_option(LLVMGetNextTarget(Target));
209b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
210b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
211b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* string -> Target.t option */
212b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_by_name(value Name) {
213b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_target_option(LLVMGetTargetFromName(String_val(Name)));
214b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
215b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
216b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* string -> Target.t */
217b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim LLVMTargetRef llvm_target_by_triple(value Triple) {
218b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMTargetRef T;
219b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  char *Error;
220b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
221b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(LLVMGetTargetFromTriple(String_val(Triple), &T, &Error))
222b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    llvm_raise(llvm_target_error_exn, Error);
223b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
224b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return T;
225b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
226b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
227b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Target.t -> string */
228b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_name(LLVMTargetRef Target) {
229b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return caml_copy_string(LLVMGetTargetName(Target));
230b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
231b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
232b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Target.t -> string */
233b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_description(LLVMTargetRef Target) {
234b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return caml_copy_string(LLVMGetTargetDescription(Target));
235b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
236b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
237b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Target.t -> bool */
238b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_has_jit(LLVMTargetRef Target) {
239b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_bool(LLVMTargetHasJIT(Target));
240b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
241b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
242b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Target.t -> bool */
243b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_has_target_machine(LLVMTargetRef Target) {
244b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_bool(LLVMTargetHasTargetMachine(Target));
245b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
246b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
247b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Target.t -> bool */
248b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_target_has_asm_backend(LLVMTargetRef Target) {
249b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_bool(LLVMTargetHasAsmBackend(Target));
250b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
251b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
252b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/*===---- Target Machine --------------------------------------------------===*/
253b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
254b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#define TargetMachine_val(v)  (*(LLVMTargetMachineRef *)(Data_custom_val(v)))
255b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
256b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic void llvm_finalize_target_machine(value Machine) {
257b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMDisposeTargetMachine(TargetMachine_val(Machine));
258b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
259b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
260b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic struct custom_operations llvm_target_machine_ops = {
261b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  (char *) "LLVMTargetMachine",
262b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  llvm_finalize_target_machine,
263b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  custom_compare_default,
264b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  custom_hash_default,
265b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  custom_serialize_default,
266b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  custom_deserialize_default
267b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#ifdef custom_compare_ext_default
268b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  , custom_compare_ext_default
269b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov#endif
270b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov};
271b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
272b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotovstatic value llvm_alloc_targetmachine(LLVMTargetMachineRef Machine) {
273b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  value V = alloc_custom(&llvm_target_machine_ops, sizeof(LLVMTargetMachineRef),
274b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                         0, 1);
275b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  TargetMachine_val(V) = Machine;
276b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return V;
277b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
278b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
279b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* triple:string -> ?cpu:string -> ?features:string
280b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov   ?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t
281b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov   ?code_model:CodeModel.t -> Target.t -> TargetMachine.t */
282b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_create_targetmachine_native(value Triple, value CPU,
283b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                  value Features, value OptLevel, value RelocMode,
284b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                  value CodeModel, LLVMTargetRef Target) {
285b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMTargetMachineRef Machine;
286b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  const char *CPUStr = "", *FeaturesStr = "";
287b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMCodeGenOptLevel OptLevelEnum = LLVMCodeGenLevelDefault;
288b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMRelocMode RelocModeEnum = LLVMRelocDefault;
289b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMCodeModel CodeModelEnum = LLVMCodeModelDefault;
290b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
291b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(CPU != Val_int(0))
292b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    CPUStr = String_val(Field(CPU, 0));
293b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(Features != Val_int(0))
294b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    FeaturesStr = String_val(Field(Features, 0));
295b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(OptLevel != Val_int(0))
296b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    OptLevelEnum = Int_val(Field(OptLevel, 0));
297b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(RelocMode != Val_int(0))
298b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    RelocModeEnum = Int_val(Field(RelocMode, 0));
299b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(CodeModel != Val_int(0))
300b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    CodeModelEnum = Int_val(Field(CodeModel, 0));
301b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
302b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  Machine = LLVMCreateTargetMachine(Target, String_val(Triple), CPUStr,
303b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                FeaturesStr, OptLevelEnum, RelocModeEnum, CodeModelEnum);
304b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
305b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_alloc_targetmachine(Machine);
306b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
307b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
308b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_create_targetmachine_bytecode(value *argv, int argn) {
309b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_create_targetmachine_native(argv[0], argv[1], argv[2], argv[3],
310b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                    argv[4], argv[5], (LLVMTargetRef) argv[6]);
311b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
312b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
313b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* TargetMachine.t -> Target.t */
314b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim LLVMTargetRef llvm_targetmachine_target(value Machine) {
315b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return LLVMGetTargetMachineTarget(TargetMachine_val(Machine));
316b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
317b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
318b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* TargetMachine.t -> string */
319b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_targetmachine_triple(value Machine) {
320b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_string_of_message(LLVMGetTargetMachineTriple(
321b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                TargetMachine_val(Machine)));
322b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
323b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
324b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* TargetMachine.t -> string */
325b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_targetmachine_cpu(value Machine) {
326b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_string_of_message(LLVMGetTargetMachineCPU(
327b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                TargetMachine_val(Machine)));
328b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
329b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
330b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* TargetMachine.t -> string */
331b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_targetmachine_features(value Machine) {
332b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return llvm_string_of_message(LLVMGetTargetMachineFeatureString(
333b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                TargetMachine_val(Machine)));
334b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
335b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
336b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* TargetMachine.t -> DataLayout.t */
337b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_targetmachine_data_layout(value Machine) {
338b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CAMLparam1(Machine);
339b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CAMLlocal1(DataLayout);
340b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
341b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  /* LLVMGetTargetMachineData returns a pointer owned by the TargetMachine,
342b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov     so it is impossible to wrap it with llvm_alloc_target_data, which assumes
343b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov     that OCaml owns the pointer. */
344b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMTargetDataRef OrigDataLayout;
345b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  OrigDataLayout = LLVMGetTargetMachineData(TargetMachine_val(Machine));
346b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
347b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  char* TargetDataCStr;
348b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
349b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
350b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMDisposeMessage(TargetDataCStr);
351b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
352b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  CAMLreturn(DataLayout);
353b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
354b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
355cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/* bool -> TargetMachine.t -> unit */
356cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesCAMLprim value llvm_targetmachine_set_verbose_asm(value Verb, value Machine) {
357b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMSetTargetMachineAsmVerbosity(TargetMachine_val(Machine), Bool_val(Verb));
358b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_unit;
359b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
360b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
361b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Llvm.llmodule -> CodeGenFileType.t -> string -> TargetMachine.t -> unit */
362b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim value llvm_targetmachine_emit_to_file(LLVMModuleRef Module,
363b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                            value FileType, value FileName, value Machine) {
364b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  char* ErrorMessage;
365b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
366b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(LLVMTargetMachineEmitToFile(TargetMachine_val(Machine), Module,
367b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                 String_val(FileName), Int_val(FileType),
368b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                 &ErrorMessage)) {
369b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    llvm_raise(llvm_target_error_exn, ErrorMessage);
370b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  }
371b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
372b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Val_unit;
373b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
374b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
375b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov/* Llvm.llmodule -> CodeGenFileType.t -> TargetMachine.t ->
376b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov   Llvm.llmemorybuffer */
377b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter ZotovCAMLprim LLVMMemoryBufferRef llvm_targetmachine_emit_to_memory_buffer(
378b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                LLVMModuleRef Module, value FileType,
379b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                value Machine) {
380b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  char* ErrorMessage;
381b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  LLVMMemoryBufferRef Buffer;
382b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
383b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  if(LLVMTargetMachineEmitToMemoryBuffer(TargetMachine_val(Machine), Module,
384b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                         Int_val(FileType), &ErrorMessage,
385b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov                                         &Buffer)) {
386b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov    llvm_raise(llvm_target_error_exn, ErrorMessage);
387b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  }
388b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov
389b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov  return Buffer;
390b6703ff81b4739be67ae7b07f1bfcfb6f157f891Peter Zotov}
391