(**************************************************************************) (* *) (* OCaml *) (* *) (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) (* *) (* Copyright 1996 Institut National de Recherche en Informatique et *) (* en Automatique. *) (* *) (* All rights reserved. This file is distributed under the terms of *) (* the GNU Lesser General Public License version 2.1, with the *) (* special exception on linking described in the file LICENSE. *) (* *) (**************************************************************************) open Mach (* Transformation of Mach code into a list of pseudo-instructions. *) type label = Cmm.label type instruction = { mutable desc: instruction_desc; mutable next: instruction; arg: Reg.t array; res: Reg.t array; dbg: Debuginfo.t; live: Reg.Set.t } and instruction_desc = | Lprologue | Lend | Lop of Mach.operation | Lreloadretaddr | Lreturn | Llabel of label | Lbranch of label | Lcondbranch of Mach.test * label | Lcondbranch3 of label option * label option * label option | Lswitch of label array | Lentertrap | Ladjust_trap_depth of { delta_traps : int; } | Lpushtrap of { lbl_handler : label; } | Lpoptrap | Lraise of Lambda.raise_kind let has_fallthrough = function | Lreturn | Lbranch _ | Lswitch _ | Lraise _ | Lop Itailcall_ind | Lop (Itailcall_imm _) -> false | _ -> true type fundecl = { fun_name: string; fun_body: instruction; fun_fast: bool; fun_dbg : Debuginfo.t; fun_tailrec_entry_point_label : label; fun_contains_calls: bool; fun_num_stack_slots: int array; fun_frame_required: bool; fun_prologue_required: bool; } (* Invert a test *) let invert_integer_test = function Isigned cmp -> Isigned(Cmm.negate_integer_comparison cmp) | Iunsigned cmp -> Iunsigned(Cmm.negate_integer_comparison cmp) let invert_test = function Itruetest -> Ifalsetest | Ifalsetest -> Itruetest | Iinttest(cmp) -> Iinttest(invert_integer_test cmp) | Iinttest_imm(cmp, n) -> Iinttest_imm(invert_integer_test cmp, n) | Ifloattest(cmp) -> Ifloattest(Cmm.negate_float_comparison cmp) | Ieventest -> Ioddtest | Ioddtest -> Ieventest (* The "end" instruction *) let rec end_instr = { desc = Lend; next = end_instr; arg = [||]; res = [||]; dbg = Debuginfo.none; live = Reg.Set.empty } (* Cons an instruction (live, debug empty) *) let instr_cons d a r n = { desc = d; next = n; arg = a; res = r; dbg = Debuginfo.none; live = Reg.Set.empty }