-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathCFlat.ml
135 lines (111 loc) · 2.99 KB
/
CFlat.ml
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
(* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. *)
(* Licensed under the Apache 2.0 License. *)
(** CFlat, without structures and with computed stack frames. *)
(** The point of this IR is to:
* - compute the size of the stack frames;
* - remove structs and enums, favoring instead n-ary parameters and variables,
* along with constant numbers for enums.
* We keep the size of machine operations, so that we know which sequence of
* instructions to emit (e.g. for small int types, we want to add a
* truncation); we also keep the signedness to pick the right operator.
*)
open Common
module K = Constant
module Sizes = struct
(** There are only two sizes for values in Wasm. A Low* 64-bit integer maps to
* I64; everything else maps to I32. *)
type size =
| I32
| I64
[@@deriving show]
(* We may want, however, to adopt a more optimal representation for arrays, and
* store bytes within arrays. Therefore, there is a different notion of how
* arrays are indexed. *)
and array_size =
| A8
| A16
| A32
| A64
let string_of_size = function
| I32 -> "I32"
| I64 -> "I64"
let string_of_array_size = function
| A8 -> "8"
| A16 -> "16"
| A32 -> "32"
| A64 -> "64"
let size_of_width (w: K.width) =
let open K in
match w with
| UInt64 | Int64 ->
I64
| _ ->
I32
let array_size_of_width (w: K.width) =
let open K in
match w with
| UInt64 | Int64 | CInt ->
A64
| UInt32 | Int32 ->
A32
| UInt16 | Int16 ->
A16
| UInt8 | Int8 ->
A8
| Bool ->
invalid_arg "array_size_of_width"
let bytes_in = function
| A8 -> 1
| A16 -> 2
| A32 -> 4
| A64 -> 8
end
open Sizes
type program =
decl list
and decl =
| Global of ident * size * expr * expr list * bool
| Function of function_t
| ExternalFunction of ident * size list (* args *) * size list (* ret *)
| ExternalGlobal of ident * size
and function_t = {
name: ident;
args: size list;
ret: size list;
locals: locals;
body: expr;
public: bool;
}
(* This is NOT De Bruijn *)
and locals =
size list
and constant =
K.width * string
and expr =
| Var of var
| GetGlobal of ident
| Constant of constant
| Assign of var * expr
| StringLiteral of string
| Abort of expr
| IfThenElse of expr * expr * expr * size
| While of expr * expr
| Switch of expr * (constant * expr) list * expr option (* default case *) * size
| Sequence of expr list
| Ignore of expr * size
| BufCreate of lifetime * expr * array_size
| BufSub of expr * expr * array_size
| BufRead of expr * int * array_size
(** Constant offset expressed in number of BYTES. *)
| BufWrite of expr * int * expr * array_size
(** Ibid. *)
| CallOp of op * expr list
| CallFunc of ident * expr list
| Cast of expr * K.width * K.width
(** from; to *)
[@@deriving show]
and var =
int (** NOT De Bruijn *)
and op = K.width * K.op
and ident =
string