92 lines
3.0 KiB
OCaml
92 lines
3.0 KiB
OCaml
(**************************************************************************)
|
|
(* *)
|
|
(* 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 }
|