]> git.lizzy.rs Git - rust.git/blob - src/boot/be/abi.ml
Populate tree.
[rust.git] / src / boot / be / abi.ml
1
2 (*
3  * The 'abi' structure is pretty much just a grab-bag of machine
4  * dependencies and structure-layout information. Part of the latter
5  * is shared with trans and semant.
6  *
7  * Make some attempt to factor it as time goes by.
8  *)
9
10 (* Word offsets for structure fields in rust-internal.h, and elsewhere in
11    compiler. *)
12
13 let rc_base_field_refcnt = 0;;
14
15 let task_field_refcnt = rc_base_field_refcnt;;
16 let task_field_stk = task_field_refcnt + 1;;
17 let task_field_runtime_sp = task_field_stk + 1;;
18 let task_field_rust_sp = task_field_runtime_sp + 1;;
19 let task_field_gc_alloc_chain = task_field_rust_sp + 1;;
20 let task_field_dom = task_field_gc_alloc_chain + 1;;
21 let n_visible_task_fields = task_field_dom + 1;;
22
23 let dom_field_interrupt_flag = 0;;
24
25 let frame_glue_fns_field_mark = 0;;
26 let frame_glue_fns_field_drop = 1;;
27 let frame_glue_fns_field_reloc = 2;;
28
29 let exterior_rc_slot_field_refcnt = 0;;
30 let exterior_rc_slot_field_body = 1;;
31
32 let exterior_gc_slot_field_next = (-2);;
33 let exterior_gc_slot_field_ctrl = (-1);;
34 let exterior_gc_slot_field_refcnt = 0;;
35 let exterior_gc_slot_field_body = 1;;
36
37 let exterior_rc_header_size = 1;;
38 let exterior_gc_header_size = 3;;
39
40 let exterior_gc_malloc_return_adjustment = 2;;
41
42 let stk_field_valgrind_id = 0 + 1;;
43 let stk_field_limit = stk_field_valgrind_id + 1;;
44 let stk_field_data = stk_field_limit + 1;;
45
46 let binding_size = 2;;
47 let binding_field_item = 0;;
48 let binding_field_binding = 1;;
49
50 let general_code_alignment = 16;;
51
52 let tydesc_field_first_param = 0;;
53 let tydesc_field_size = 1;;
54 let tydesc_field_align = 2;;
55 let tydesc_field_copy_glue = 3;;
56 let tydesc_field_drop_glue = 4;;
57 let tydesc_field_free_glue = 5;;
58 let tydesc_field_mark_glue = 6;;
59 let tydesc_field_obj_drop_glue = 7;;
60
61 let vec_elt_rc = 0;;
62 let vec_elt_alloc = 1;;
63 let vec_elt_fill = 2;;
64 let vec_elt_data = 3;;
65
66 let calltup_elt_out_ptr = 0;;
67 let calltup_elt_task_ptr = 1;;
68 let calltup_elt_ty_params = 2;;
69 let calltup_elt_args = 3;;
70 let calltup_elt_iterator_args = 4;;
71 let calltup_elt_indirect_args = 5;;
72
73 let iterator_args_elt_block_fn = 0;;
74 let iterator_args_elt_outer_frame_ptr = 1;;
75
76 let indirect_args_elt_closure = 0;;
77
78 (* ty_params, src, dst, tydesc, taskptr. *)
79 let worst_case_glue_call_args = 5;;
80
81 type abi =
82   {
83     abi_word_sz: int64;
84     abi_word_bits: Il.bits;
85     abi_word_ty: Common.ty_mach;
86
87     abi_is_2addr_machine: bool;
88     abi_has_pcrel_data: bool;
89     abi_has_pcrel_code: bool;
90
91     abi_n_hardregs: int;
92     abi_str_of_hardreg: (int -> string);
93
94     abi_prealloc_quad: (Il.quad' -> Il.quad');
95     abi_constrain_vregs: (Il.quad -> Bits.t array -> unit);
96
97     abi_emit_fn_prologue: (Il.emitter
98                            -> Common.size        (* framesz *)
99                              -> Common.size      (* callsz  *)
100                                -> Common.nabi
101                                  -> Common.fixup (* grow_task *)
102                                    -> unit);
103
104     abi_emit_fn_epilogue: (Il.emitter -> unit);
105
106     abi_emit_fn_tail_call: (Il.emitter
107                             -> int64            (* caller_callsz *)
108                               -> int64          (* caller_argsz  *)
109                                 -> Il.code      (* callee_code   *)
110                                   -> int64      (* callee_argsz  *)
111                                     -> unit);
112
113     abi_clobbers: (Il.quad -> Il.hreg list);
114
115     abi_emit_native_call: (Il.emitter
116                            -> Il.cell                 (* ret    *)
117                              -> Common.nabi
118                                -> Common.fixup        (* callee *)
119                                  -> Il.operand array  (* args   *)
120                                    -> unit);
121
122     abi_emit_native_void_call: (Il.emitter
123                                 -> Common.nabi
124                                   -> Common.fixup             (* callee *)
125                                     -> Il.operand array       (* args   *)
126                                       -> unit);
127
128     abi_emit_native_call_in_thunk: (Il.emitter
129                                     -> Il.cell                (* ret    *)
130                                       -> Common.nabi
131                                         -> Il.operand         (* callee *)
132                                           -> Il.operand array (* args   *)
133                                             -> unit);
134     abi_emit_inline_memcpy: (Il.emitter
135                              -> int64           (* n_bytes   *)
136                                -> Il.reg        (* dst_ptr   *)
137                                  -> Il.reg      (* src_ptr   *)
138                                    -> Il.reg    (* tmp_reg   *)
139                                      -> bool    (* ascending *)
140                                        -> unit);
141
142     (* Global glue. *)
143     abi_activate: (Il.emitter -> unit);
144     abi_yield: (Il.emitter -> unit);
145     abi_unwind: (Il.emitter -> Common.nabi -> Common.fixup -> unit);
146     abi_get_next_pc_thunk:
147       ((Il.reg                   (* output            *)
148         * Common.fixup           (* thunk in objfile  *)
149         * (Il.emitter -> unit))  (* fn to make thunk  *)
150          option);
151
152     abi_sp_reg: Il.reg;
153     abi_fp_reg: Il.reg;
154     abi_dwarf_fp_reg: int;
155     abi_tp_cell: Il.cell;
156     abi_implicit_args_sz: int64;
157     abi_frame_base_sz: int64;
158     abi_frame_info_sz: int64;
159     abi_spill_slot: (Il.spill -> Il.mem);
160   }
161 ;;
162
163 let load_fixup_addr
164     (e:Il.emitter)
165     (out_reg:Il.reg)
166     (fix:Common.fixup)
167     (rty:Il.referent_ty)
168     : unit =
169
170   let cell = Il.Reg (out_reg, Il.AddrTy rty) in
171   let op = Il.ImmPtr (fix, rty) in
172     Il.emit e (Il.lea cell op);
173 ;;
174
175 let load_fixup_codeptr
176     (e:Il.emitter)
177     (out_reg:Il.reg)
178     (fixup:Common.fixup)
179     (has_pcrel_code:bool)
180     (indirect:bool)
181     : Il.code =
182   if indirect
183   then
184     begin
185       load_fixup_addr e out_reg fixup (Il.ScalarTy (Il.AddrTy Il.CodeTy));
186       Il.CodePtr (Il.Cell (Il.Mem (Il.RegIn (out_reg, None),
187                                    Il.ScalarTy (Il.AddrTy Il.CodeTy))))
188     end
189   else
190     if has_pcrel_code
191     then (Il.CodePtr (Il.ImmPtr (fixup, Il.CodeTy)))
192     else
193       begin
194         load_fixup_addr e out_reg fixup Il.CodeTy;
195         Il.CodePtr (Il.Cell (Il.Reg (out_reg, Il.AddrTy Il.CodeTy)))
196       end
197 ;;
198
199
200 (* 
201  * Local Variables:
202  * fill-column: 78; 
203  * indent-tabs-mode: nil
204  * buffer-file-coding-system: utf-8-unix
205  * compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; 
206  * End:
207  *)