4 * ----------------------------------------------------------------
7 * Copyright (C) 2001 Jason Hickey, Caltech
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Author: Jason Hickey
24 * @email{jyh@cs.caltech.edu}
60 module Pos
= MakePos
(struct let name = "X86_as_code" end)
64 * Assemble the instructon.
66 let assem_inst buf pos inst
=
67 let pos = inst_pos inst
pos in
68 let next = new_symbol_string
"inst" in
79 as_print_empty_inst buf nop_opcodes
82 | MOV
(pre
, op1
, op2
) ->
83 as_print_binary_int_inst buf mov_opcodes
pos pre op1 op2
next
84 | MOVS
(pre
, op1
, op2
) ->
85 as_print_binary_int_inst buf movs_opcodes
pos pre op1 op2
next
86 | MOVZ
(pre
, op1
, op2
) ->
87 as_print_binary_int_inst buf movz_opcodes
pos pre op1 op2
next
89 as_print_empty_pre_inst buf rmovs_opcodes pre
93 as_print_unary_int_inst buf not_opcodes
pos pre op
next
95 as_print_unary_int_inst buf neg_opcodes
pos pre op
next
97 as_print_unary_int_inst buf inc_opcodes
pos pre op
next
99 as_print_unary_int_inst buf dec_opcodes
pos pre op
next
100 | LEA
(pre
, op1
, op2
) ->
101 as_print_binary_int_inst buf lea_opcodes
pos pre op1 op2
next
102 | ADD
(pre
, op1
, op2
) ->
103 as_print_binary_int_inst buf add_opcodes
pos pre op1 op2
next
104 | ADC
(pre
, op1
, op2
) ->
105 as_print_binary_int_inst buf adc_opcodes
pos pre op1 op2
next
106 | SUB
(pre
, op1
, op2
) ->
107 as_print_binary_int_inst buf sub_opcodes
pos pre op1 op2
next
108 | SBB
(pre
, op1
, op2
) ->
109 as_print_binary_int_inst buf sbb_opcodes
pos pre op1 op2
next
111 as_print_unary_int_inst buf mul_opcodes
pos pre op
next
112 | IMUL
(pre
, op1
, op2
) ->
113 as_print_imul_inst buf
pos pre op1 op2
next
115 as_print_unary_int_inst buf div_opcodes
pos pre op
next
117 as_print_unary_int_inst buf idiv_opcodes
pos pre op
next
119 as_print_empty_inst buf cltd_opcodes
120 | AND
(pre
, op1
, op2
) ->
121 as_print_binary_int_inst buf and_opcodes
pos pre op1 op2
next
122 | OR
(pre
, op1
, op2
) ->
123 as_print_binary_int_inst buf or_opcodes
pos pre op1 op2
next
124 | XOR
(pre
, op1
, op2
) ->
125 as_print_binary_int_inst buf xor_opcodes
pos pre op1 op2
next
126 | SAL
(pre
, op1
, op2
) ->
127 as_print_shift_inst buf sal_opcodes
pos pre op1 op2
128 | SAR
(pre
, op1
, op2
) ->
129 as_print_shift_inst buf sar_opcodes
pos pre op1 op2
130 | SHL
(pre
, op1
, op2
) ->
131 as_print_shift_inst buf shl_opcodes
pos pre op1 op2
132 | SHR
(pre
, op1
, op2
) ->
133 as_print_shift_inst buf shr_opcodes
pos pre op1 op2
134 | SHLD
(pre
, op1
, op2
, op3
) ->
135 as_print_shiftd_inst buf shld_opcodes
pos pre op1 op2 op3
136 | SHRD
(pre
, op1
, op2
, op3
) ->
137 as_print_shiftd_inst buf shrd_opcodes
pos pre op1 op2 op3
140 as_print_unary_int_inst buf push_opcodes
pos pre op
next
142 as_print_unary_int_inst buf pop_opcodes
pos pre op
next
145 as_print_unary_int_inst buf call_opcodes
pos IL op
next
147 as_print_empty_inst buf ret_opcodes
149 | CMP
(pre
, op1
, op2
) ->
150 as_print_binary_int_inst buf cmp_opcodes
pos pre op1 op2
next
151 | TEST
(pre
, op1
, op2
) ->
152 as_print_binary_int_inst buf test_opcodes
pos pre op1 op2
next
156 as_print_jmp_inst buf
pos op
next
158 as_print_jcc_inst buf
pos cc op
next
160 as_print_setcc_inst buf
pos cc op
164 as_print_binary_mmx_inst buf movd_opcodes
pos op1 op2
next
166 as_print_binary_mmx_inst buf movq_opcodes
pos op1 op2
next
170 as_print_empty_float_inst buf finit_opcodes
172 as_print_unary_float_inst buf fstcw_opcodes
pos FS op
174 as_print_unary_float_inst buf fldcw_opcodes
pos FS op
176 as_print_unary_float_inst buf fld_opcodes
pos pre op
178 as_print_unary_float_inst buf fild_opcodes
pos FS op
180 as_print_unary_float_inst buf fild_opcodes
pos FL op
182 as_print_unary_float_inst buf fst_opcodes
pos pre op
184 as_print_unary_float_inst buf fstp_opcodes
pos pre op
186 as_print_unary_float_inst buf fist_opcodes
pos FS op
188 as_print_unary_float_inst buf fistp_opcodes
pos FS op
190 as_print_unary_float_inst buf fistp_opcodes
pos FL op
192 as_print_unary_float_inst buf fxch_opcodes
pos FT op
194 as_print_empty_float_inst buf fchs_opcodes
196 as_print_unary_float_inst buf faddp_opcodes
pos FT st1
198 as_print_unary_float_inst buf fsubp_opcodes
pos FT st1
200 as_print_unary_float_inst buf fmulp_opcodes
pos FT st1
202 as_print_unary_float_inst buf fdivp_opcodes
pos FT st1
204 as_print_unary_float_inst buf fsubrp_opcodes
pos FT st1
206 as_print_unary_float_inst buf fdivrp_opcodes
pos FT st1
208 as_print_empty_float_inst buf fprem_opcodes
210 as_print_empty_float_inst buf fsin_opcodes
212 as_print_empty_float_inst buf fcos_opcodes
214 as_print_empty_float_inst buf fpatan_opcodes
216 as_print_empty_float_inst buf fsqrt_opcodes
218 as_print_unary_float_inst buf fucom_opcodes
pos FT st1
220 as_print_unary_float_inst buf fucomp_opcodes
pos FT st1
222 as_print_empty_float_inst buf fucompp_opcodes
224 as_print_empty_float_inst buf fstsw_opcodes
226 as_print_binary_float_inst buf fadd_opcodes
pos FL op1 op2
228 as_print_binary_float_inst buf fsub_opcodes
pos FL op1 op2
230 as_print_binary_float_inst buf fmul_opcodes
pos FL op1 op2
232 as_print_binary_float_inst buf fdiv_opcodes
pos FL op1 op2
233 | FSUBR
(op1
, op2
) ->
234 as_print_binary_float_inst buf fsubr_opcodes
pos FL op1 op2
235 | FDIVR
(op1
, op2
) ->
236 as_print_binary_float_inst buf fdivr_opcodes
pos FL op1 op2
237 | FMOV
(pre1
, op1
, pre2
, op2
) ->
238 as_print_unary_float_inst buf fld_opcodes
pos pre2 op2
;
239 as_print_unary_float_inst buf fst_opcodes
pos pre1 op1
240 | FMOVP
(pre1
, op1
, pre2
, op2
) ->
241 as_print_unary_float_inst buf fld_opcodes
pos pre2 op2
;
242 as_print_unary_float_inst buf fstp_opcodes
pos pre1 op1
244 (* Special instructions *)
245 | RES
(label
, _
, mem
, ptr
) ->
246 as_print_unary_int_inst buf push_opcodes
pos IL label
next;
247 as_print_unary_int_inst buf push_opcodes
pos IL mem
next;
248 as_print_unary_int_inst buf push_opcodes
pos IL ptr
next;
249 as_print_unary_int_inst buf call_opcodes
pos IL
(ImmediateLabel gc_label
) next;
250 as_print_binary_int_inst buf add_opcodes
pos IL
(Register esp
) (ImmediateNumber
(OffNumber
(Int32.of_int
12))) next
251 | COW
(label
, _
, mem
, ptr
, copy_ptr
) ->
252 as_print_unary_int_inst buf push_opcodes
pos IL copy_ptr
next;
253 as_print_unary_int_inst buf push_opcodes
pos IL label
next;
254 as_print_unary_int_inst buf push_opcodes
pos IL mem
next;
255 as_print_unary_int_inst buf push_opcodes
pos IL ptr
next;
256 as_print_unary_int_inst buf call_opcodes
pos IL
(ImmediateLabel copy_on_write_label
) next;
257 as_print_binary_int_inst buf add_opcodes
pos IL
(Register esp
) (ImmediateNumber
(OffNumber
(Int32.of_int
16))) next
259 as_print_unary_int_inst buf push_opcodes
pos IL label
next;
260 as_print_unary_int_inst buf push_opcodes
pos IL
(ImmediateNumber
(OffNumber
(Int32.of_int
0))) next;
261 as_print_unary_int_inst buf push_opcodes
pos IL
(ImmediateNumber
(OffNumber
(Int32.of_int
0))) next;
262 as_print_unary_int_inst buf push_opcodes
pos IL
(ImmediateNumber
(OffNumber
(Int32.of_int
0))) next;
263 as_print_unary_int_inst buf push_opcodes
pos IL
(Register ebp
) next;
264 as_print_unary_int_inst buf push_opcodes
pos IL
(Register edi
) next;
265 as_print_unary_int_inst buf push_opcodes
pos IL
(Register esi
) next;
266 as_print_unary_int_inst buf push_opcodes
pos IL
(Register edx
) next;
267 as_print_unary_int_inst buf push_opcodes
pos IL
(Register ecx
) next;
268 as_print_unary_int_inst buf push_opcodes
pos IL
(Register ebx
) next;
269 as_print_unary_int_inst buf push_opcodes
pos IL
(Register eax
) next;
270 as_print_unary_int_inst buf push_opcodes
pos IL
(Register esp
) next
273 bfd_print_label buf SymTemp
next;
279 let assem_block buf export block
=
280 let { block_label
= label
;
282 block_index
= index_flag
;
283 block_align
= align_flag
;
284 block_arity
= arity_tag
;
287 let pos = var_exp_pos label
in
288 let pos = string_pos
"assem_block" pos in
289 (* Align if necessary *)
291 bfd_align buf align_block
295 (* If the index is set, then add space and the index *)
296 (match index_flag
, arity_tag
with
297 Some index
, Some arity
->
298 (* Add the index to the function index table.
299 See arch/x86/runtime/x86_runtime.h for format. *)
300 bfd_skip buf index_skip
0x90; (* NOP *)
301 (* Function header begins here *)
302 as_print_imm32 buf
(OffLabel arity
);
303 bfd_print_int32 buf
Int32.zero
;
304 as_print_imm32 buf
(OffOr
(OffLabel index
, OffNumber
X86_runtime.aggr_shift_mask32
));
308 raise
(X86Exception
(pos, StringError
"block_index and block_arity must be both set or both cleared")));
310 (* If there is a global binding, add it at this point *)
312 let { export_name
= s
} = SymbolTable.find export label
in
313 bfd_print_label buf SymGlobal
(Symbol.add s
)
318 (* Add the label at this program point *)
319 bfd_print_label buf SymLocal label
;
321 (* Print all the instructons *)
322 ignore
(List.fold_left
(assem_inst buf
) pos insts
)
325 * Assemble a list.of blocks.
327 let assem_blocks buf export blocks
=
328 List.iter
(assem_block buf export
) blocks
331 * Assemble all the block's text.
332 * We'll sweep for data separately.
334 let as_print_code buf blocks export
=
335 let sect = text_section buf
in
336 let buf = section_buf
sect in
337 bfd_print_label
buf SymLocal
X86_stab.text_sym
;
338 Trace.iter
(assem_block buf export
) blocks
;
339 bfd_align
buf align_block
342 * Assemble the code and print the function table info.
344 let assem_code buf info blocks
=
345 let { bfd_export
= export
} = info
in
346 as_print_code buf blocks export
349 * Print the arity tag table.
351 let as_print_arity_table buf arity
=
352 let lookup_arity name =
354 snd
(ArityTable.find arity
name)
359 let sect = absolute_section
buf in
360 let buf = section_buf
sect in
361 let tag_exit = lookup_arity exit_arity_tag
in
362 let tag_uncaught_exception = lookup_arity uncaught_exception_arity_tag
in
363 ArityTable.iter
(fun _
(label
, index
) ->
364 as_print_equ_int32
buf SymLocal label index
) arity
;
365 as_print_equ_int32
buf SymGlobal exit_arity_label
tag_exit;
366 as_print_equ_int32
buf SymGlobal uncaught_exception_arity_label
tag_uncaught_exception
369 * Print the function table.
371 let as_print_function_label buf (label
, _
) =
372 as_print_abs32
buf label
374 let as_print_function_table buf funs
=
375 let sect = data_section
buf in
376 let buf = section_buf
sect in
378 bfd_print_label
buf SymGlobal function_base_label
;
379 as_print_abs32
buf exit_label
;
380 as_print_abs32
buf uncaught_exception_label
;
381 List.iter
(as_print_function_label buf) funs
;
382 bfd_print_label
buf SymGlobal function_limit_label
385 * Print the function tags.
387 let as_print_function_tag buf off
(_
, tag
) =
388 as_print_equ_int
buf SymLocal tag off
;
391 let as_print_function_tag_table buf funs
=
392 let sect = absolute_section
buf in
393 let buf = section_buf
sect in
394 as_print_equ_int
buf SymGlobal exit_tag_label
0;
395 as_print_equ_int
buf SymGlobal uncaught_exception_tag_label
4;
396 let size = List.fold_left
(as_print_function_tag buf) 8 funs
in
397 as_print_equ_int
buf SymGlobal function_size_label
size
399 let assem_fun_table buf info
=
400 let { bfd_fun_tags
= funs
;
401 bfd_arity_tags
= arity
;
404 as_print_function_table buf funs
;
405 as_print_function_tag_table buf funs
;
406 as_print_arity_table buf arity
409 * Collect all the blocks with index labels.
411 let get_block_tag funs block
=
412 let { block_label
= label
;
422 let get_fun_tags blocks
=
423 List.rev
(Trace.fold
get_block_tag [] blocks
)
430 * Caml-master: "compile"