ocaml/asmcomp/arm64/arch.ml

146 lines
4.4 KiB
OCaml
Raw Normal View History

(***********************************************************************)
(* *)
(* 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)