summaryrefslogtreecommitdiff
path: root/asmcomp/power/arch.ml
blob: aa4588415e8b0da1b07600488b738ed397bc99b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# 2 "asmcomp/power/arch.ml"
(**************************************************************************)
(*                                                                        *)
(*                                 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.          *)
(*                                                                        *)
(**************************************************************************)

(* Specific operations for the PowerPC processor *)

open Format

let ppc64 =
  match Config.model with
  | "ppc" -> false
  | "ppc64" | "ppc64le" -> true
  | _ -> assert false

type abi = ELF32 | ELF64v1 | ELF64v2

let abi =
  match Config.model with
  | "ppc" -> ELF32
  | "ppc64" -> ELF64v1
  | "ppc64le" -> ELF64v2
  | _ -> assert false

type cmm_label = int
(* Do not introduce a dependency to Cmm *)

(* Machine-specific command-line options *)

let big_toc = ref true

let command_line_options = [
  "-flarge-toc", Arg.Set big_toc,
     " Support TOC (table of contents) greater than 64 kbytes (default)";
  "-fsmall-toc", Arg.Clear big_toc,
     " TOC (table of contents) is limited to 64 kbytes"
]

(* Specific operations *)

type specific_operation =
    Imultaddf                           (* multiply and add *)
  | Imultsubf                           (* multiply and subtract *)
  | Ialloc_far of                       (* allocation in large functions *)
      { bytes : int; dbginfo : Debuginfo.alloc_dbginfo }
  | Ipoll_far of { return_label : cmm_label option }

(* Addressing modes *)

type addressing_mode =
    Ibased of string * int              (* symbol + displ *)
  | Iindexed of int                     (* reg + displ *)
  | Iindexed2                           (* reg + reg *)

(* Sizes, endianness *)

let big_endian =
  match Config.model with
  | "ppc" -> true
  | "ppc64" -> true
  | "ppc64le" -> false
  | _ -> assert false

let size_addr = if ppc64 then 8 else 4
let size_int = size_addr
let size_float = 8

let allow_unaligned_access = true

(* Behavior of division *)

let division_crashes_on_overflow = true

(* Operations on addressing modes *)

let identity_addressing = Iindexed 0

let offset_addressing addr delta =
  match addr with
    Ibased(s, n) -> Ibased(s, n + delta)
  | Iindexed n -> Iindexed(n + delta)
  | Iindexed2 -> assert false

let num_args_addressing = function
    Ibased _ -> 0
  | Iindexed _ -> 1
  | Iindexed2 -> 2

(* Printing operations and addressing modes *)

let print_addressing printreg addr ppf arg =
  match addr with
  | Ibased(s, n) ->
      let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in
      fprintf ppf "\"%s\"%s" s idx
  | Iindexed n ->
      let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in
      fprintf ppf "%a%s" printreg arg.(0) idx
  | Iindexed2 ->
      fprintf ppf "%a + %a" printreg arg.(0) printreg arg.(1)

let print_specific_operation printreg op ppf arg =
  match op with
  | Imultaddf ->
      fprintf ppf "%a *f %a +f %a"
        printreg arg.(0) printreg arg.(1) printreg arg.(2)
  | Imultsubf ->
      fprintf ppf "%a *f %a -f %a"
        printreg arg.(0) printreg arg.(1) printreg arg.(2)
  | Ialloc_far { bytes; _ } ->
      fprintf ppf "alloc_far %d" bytes
  | Ipoll_far _ ->
      fprintf ppf "poll_far"

(* Specific operations that are pure *)

let operation_is_pure = function
  | Ialloc_far _ | Ipoll_far _ -> false
  | _ -> true

(* Specific operations that can raise *)

let operation_can_raise = function
  | Ialloc_far _ | Ipoll_far _ -> true
  | _ -> false