146 lines
4.4 KiB
OCaml
146 lines
4.4 KiB
OCaml
(***********************************************************************)
|
|
(* *)
|
|
(* OCaml *)
|
|
(* *)
|
|
(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *)
|
|
(* Benedikt Meurer, University of Siegen *)
|
|
(* *)
|
|
(* Copyright 2013 Institut National de Recherche en Informatique *)
|
|
(* et en Automatique. Copyright 2012 Benedikt Meurer. All rights *)
|
|
(* reserved. This file is distributed under the terms of the Q *)
|
|
(* Public License version 1.0. *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
let command_line_options = []
|
|
|
|
(* Specific operations for the ARM processor, 64-bit mode *)
|
|
|
|
open Format
|
|
|
|
let command_line_options = []
|
|
|
|
(* Addressing modes *)
|
|
|
|
type addressing_mode =
|
|
| Iindexed of int (* reg + displ *)
|
|
| Ibased of string * int (* global var + displ *)
|
|
|
|
(* We do not support the reg + shifted reg addressing mode, because
|
|
what we really need is reg + shifted reg + displ,
|
|
and this is decomposed in two instructions (reg + shifted reg -> tmp,
|
|
then addressing tmp + displ). *)
|
|
|
|
(* Specific operations *)
|
|
|
|
type specific_operation =
|
|
| Ishiftarith of arith_operation * int
|
|
| Ishiftcheckbound of int
|
|
| Imuladd (* multiply and add *)
|
|
| Imulsub (* multiply and subtract *)
|
|
| Inegmulf (* floating-point negate and multiply *)
|
|
| Imuladdf (* floating-point multiply and add *)
|
|
| Inegmuladdf (* floating-point negate, multiply and add *)
|
|
| Imulsubf (* floating-point multiply and subtract *)
|
|
| Inegmulsubf (* floating-point negate, multiply and subtract *)
|
|
| Isqrtf (* floating-point square root *)
|
|
| Ibswap of int (* endianess conversion *)
|
|
|
|
and arith_operation =
|
|
Ishiftadd
|
|
| Ishiftsub
|
|
|
|
(* Sizes, endianness *)
|
|
|
|
let big_endian = false
|
|
|
|
let size_addr = 8
|
|
let size_int = 8
|
|
let size_float = 8
|
|
|
|
let allow_unaligned_access = false
|
|
|
|
(* Behavior of division *)
|
|
|
|
let division_crashes_on_overflow = false
|
|
|
|
(* Operations on addressing modes *)
|
|
|
|
let identity_addressing = Iindexed 0
|
|
|
|
let offset_addressing addr delta =
|
|
match addr with
|
|
| Iindexed n -> Iindexed(n + delta)
|
|
| Ibased(s, n) -> Ibased(s, n + delta)
|
|
|
|
let num_args_addressing = function
|
|
| Iindexed n -> 1
|
|
| Ibased(s, n) -> 0
|
|
|
|
(* Printing operations and addressing modes *)
|
|
|
|
let print_addressing printreg addr ppf arg =
|
|
match addr with
|
|
| Iindexed n ->
|
|
printreg ppf arg.(0);
|
|
if n <> 0 then fprintf ppf " + %i" n
|
|
| Ibased(s, 0) ->
|
|
fprintf ppf "\"%s\"" s
|
|
| Ibased(s, n) ->
|
|
fprintf ppf "\"%s\" + %i" s n
|
|
|
|
let print_specific_operation printreg op ppf arg =
|
|
match op with
|
|
| Ishiftarith(op, shift) ->
|
|
let op_name = function
|
|
| Ishiftadd -> "+"
|
|
| Ishiftsub -> "-" in
|
|
let shift_mark =
|
|
if shift >= 0
|
|
then sprintf "<< %i" shift
|
|
else sprintf ">> %i" (-shift) in
|
|
fprintf ppf "%a %s %a %s"
|
|
printreg arg.(0) (op_name op) printreg arg.(1) shift_mark
|
|
| Ishiftcheckbound n ->
|
|
fprintf ppf "check %a >> %i > %a" printreg arg.(0) n printreg arg.(1)
|
|
| Imuladd ->
|
|
fprintf ppf "(%a * %a) + %a"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
printreg arg.(2)
|
|
| Imulsub ->
|
|
fprintf ppf "-(%a * %a) + %a"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
printreg arg.(2)
|
|
| Inegmulf ->
|
|
fprintf ppf "-f (%a *f %a)"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
| Imuladdf ->
|
|
fprintf ppf "%a +f (%a *f %a)"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
printreg arg.(2)
|
|
| Inegmuladdf ->
|
|
fprintf ppf "(-f %a) -f (%a *f %a)"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
printreg arg.(2)
|
|
| Imulsubf ->
|
|
fprintf ppf "%a -f (%a *f %a)"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
printreg arg.(2)
|
|
| Inegmulsubf ->
|
|
fprintf ppf "(-f %a) +f (%a *f %a)"
|
|
printreg arg.(0)
|
|
printreg arg.(1)
|
|
printreg arg.(2)
|
|
| Isqrtf ->
|
|
fprintf ppf "sqrtf %a"
|
|
printreg arg.(0)
|
|
| Ibswap n ->
|
|
fprintf ppf "bswap%i %a" n
|
|
printreg arg.(0)
|