aboutsummaryrefslogtreecommitdiff
path: root/src/boot/llvm/llabi.ml
blob: 5ff63ba50a2b44220ad9134c4c92a5b9366ef6cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
(*
 * LLVM integration with the Rust runtime.
 *)

type abi = {
  crate_ty:   Llvm.lltype;
  task_ty:    Llvm.lltype;
  word_ty:    Llvm.lltype;
  tydesc_ty:  Llvm.lltype;
  rust_start: Llvm.llvalue;
};;

let declare_abi (llctx:Llvm.llcontext) (llmod:Llvm.llmodule) : abi =
  let i32 = Llvm.i32_type llctx in
  (* FIXME: Use Llvm_target.intptr_type for more platform support. *)
  let word_ty = i32 in
  let p ty = Llvm.pointer_type ty in

  let crate_ty =
    (* TODO: other architectures besides x86 *)
    let crate_opaque_ty = Llvm.opaque_type llctx in
    let crate_tyhandle = Llvm.handle_to_type (Llvm.struct_type llctx [|
        i32;                              (* ptrdiff_t image_base_off *)
        Llvm.pointer_type crate_opaque_ty;(* uintptr_t self_addr *)
        i32;                              (* ptrdiff_t debug_abbrev_off *)
        i32;                              (* size_t debug_abbrev_sz *)
        i32;                              (* ptrdiff_t debug_info_off *)
        i32;                              (* size_t debug_info_sz *)
        i32;                              (* size_t activate_glue_off *)
        i32;                              (* size_t yield_glue_off *)
        i32;                              (* size_t unwind_glue_off *)
        i32;                              (* size_t gc_glue_off *)
        i32;                              (* size_t main_exit_task_glue_off *)
        i32;                              (* int n_rust_syms *)
        i32;                              (* int n_c_syms *)
        i32                               (* int n_libs *)
      |])
    in
    Llvm.refine_type crate_opaque_ty (Llvm.type_of_handle crate_tyhandle);
    Llvm.type_of_handle crate_tyhandle
  in
  ignore (Llvm.define_type_name "rust_crate" crate_ty llmod);

  let task_ty =
    (* TODO: other architectures besides x86 *)
    Llvm.struct_type llctx [|
      i32;                    (* size_t refcnt *)
      Llvm.pointer_type i32;  (* rust_task *_delegate *)
      Llvm.pointer_type i32;  (* stk_seg *stk *)
      Llvm.pointer_type i32;  (* uintptr_t runtime_sp *)
      Llvm.pointer_type i32;  (* uintptr_t rust_sp *)
      Llvm.pointer_type i32;  (* rust_rt *rt *)
      Llvm.pointer_type i32   (* rust_crate_cache *cache *)
    |]
  in
  ignore (Llvm.define_type_name "rust_task" task_ty llmod);

    (* This is the type_desc struct in rust_internal.h *)
  let tydesc_ty =
    (* TODO: other architectures besides x86 *)
    let tydesc_opaque_ty = Llvm.opaque_type llctx in
    let tydesc_tyhandle = Llvm.handle_to_type (Llvm.struct_type llctx [|
        p (p tydesc_opaque_ty);  (* const type_desc **first_param *)
        word_ty;                 (* size_t size *)
        word_ty;                 (* size_t align *)
        word_ty;                 (* uintptr_t copy_glue_off *)
        word_ty;                 (* uintptr_t drop_glue_off *)
        word_ty;                 (* uintptr_t free_glue_off *)
        word_ty;                 (* uintptr_t sever_glue_off *)
        word_ty;                 (* uintptr_t mark_glue_off *)
        word_ty;                 (* uintptr_t obj_drop_glue_off *)
      |])
    in
    Llvm.refine_type tydesc_opaque_ty (Llvm.type_of_handle tydesc_tyhandle);
    Llvm.type_of_handle tydesc_tyhandle
  in
  ignore (Llvm.define_type_name "type_desc" tydesc_ty llmod);

  let rust_start_ty =
    (* Rust's main function can have several types, so we cast them
       all to uintptr_t. *)
    let main_ty = word_ty in
    let args_ty = [| main_ty; Llvm.pointer_type crate_ty; i32; i32 |] in
      Llvm.function_type i32 args_ty
  in
  {
    crate_ty = crate_ty;
    task_ty = task_ty;
    word_ty = word_ty;
    tydesc_ty = tydesc_ty;
    rust_start = Llvm.declare_function "rust_start" rust_start_ty llmod
  }
;;