Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/meta/src/shared/immediates.rs
1693 views
1
use crate::cdsl::operands::{EnumValues, OperandKind, OperandKindFields};
2
3
use std::collections::HashMap;
4
5
pub(crate) struct Immediates {
6
/// A 64-bit immediate integer operand.
7
///
8
/// This type of immediate integer can interact with SSA values with any IntType type.
9
pub imm64: OperandKind,
10
11
/// An unsigned 8-bit immediate integer operand.
12
///
13
/// This small operand is used to indicate lane indexes in SIMD vectors and immediate bit
14
/// counts on shift instructions.
15
pub uimm8: OperandKind,
16
17
/// A 32-bit immediate signed offset.
18
///
19
/// This is used to represent an immediate address offset in load/store instructions.
20
pub offset32: OperandKind,
21
22
/// A 16-bit immediate floating point operand.
23
///
24
/// IEEE 754-2008 binary16 interchange format.
25
pub ieee16: OperandKind,
26
27
/// A 32-bit immediate floating point operand.
28
///
29
/// IEEE 754-2008 binary32 interchange format.
30
pub ieee32: OperandKind,
31
32
/// A 64-bit immediate floating point operand.
33
///
34
/// IEEE 754-2008 binary64 interchange format.
35
pub ieee64: OperandKind,
36
37
/// A condition code for comparing integer values.
38
///
39
/// This enumerated operand kind is used for the `icmp` instruction and corresponds to the
40
/// condcodes::IntCC` Rust type.
41
pub intcc: OperandKind,
42
43
/// A condition code for comparing floating point values.
44
///
45
/// This enumerated operand kind is used for the `fcmp` instruction and corresponds to the
46
/// `condcodes::FloatCC` Rust type.
47
pub floatcc: OperandKind,
48
49
/// Flags for memory operations like `load` and `store`.
50
pub memflags: OperandKind,
51
52
/// A trap code indicating the reason for trapping.
53
///
54
/// The Rust enum type also has a `User(u16)` variant for user-provided trap codes.
55
pub trapcode: OperandKind,
56
57
/// A code indicating the arithmetic operation to perform in an atomic_rmw memory access.
58
pub atomic_rmw_op: OperandKind,
59
}
60
61
fn new_imm(
62
format_field_name: &'static str,
63
rust_type: &'static str,
64
doc: &'static str,
65
) -> OperandKind {
66
OperandKind::new(
67
format_field_name,
68
rust_type,
69
OperandKindFields::ImmValue,
70
doc,
71
)
72
}
73
fn new_enum(
74
format_field_name: &'static str,
75
rust_type: &'static str,
76
values: EnumValues,
77
doc: &'static str,
78
) -> OperandKind {
79
OperandKind::new(
80
format_field_name,
81
rust_type,
82
OperandKindFields::ImmEnum(values),
83
doc,
84
)
85
}
86
87
impl Immediates {
88
pub fn new() -> Self {
89
Self {
90
imm64: new_imm(
91
"imm",
92
"ir::immediates::Imm64",
93
"A 64-bit immediate integer.",
94
),
95
uimm8: new_imm(
96
"imm",
97
"ir::immediates::Uimm8",
98
"An 8-bit immediate unsigned integer.",
99
),
100
offset32: new_imm(
101
"offset",
102
"ir::immediates::Offset32",
103
"A 32-bit immediate signed offset.",
104
),
105
ieee16: new_imm(
106
"imm",
107
"ir::immediates::Ieee16",
108
"A 16-bit immediate floating point number.",
109
),
110
ieee32: new_imm(
111
"imm",
112
"ir::immediates::Ieee32",
113
"A 32-bit immediate floating point number.",
114
),
115
ieee64: new_imm(
116
"imm",
117
"ir::immediates::Ieee64",
118
"A 64-bit immediate floating point number.",
119
),
120
intcc: {
121
let mut intcc_values = HashMap::new();
122
intcc_values.insert("eq", "Equal");
123
intcc_values.insert("ne", "NotEqual");
124
intcc_values.insert("sge", "SignedGreaterThanOrEqual");
125
intcc_values.insert("sgt", "SignedGreaterThan");
126
intcc_values.insert("sle", "SignedLessThanOrEqual");
127
intcc_values.insert("slt", "SignedLessThan");
128
intcc_values.insert("uge", "UnsignedGreaterThanOrEqual");
129
intcc_values.insert("ugt", "UnsignedGreaterThan");
130
intcc_values.insert("ule", "UnsignedLessThanOrEqual");
131
intcc_values.insert("ult", "UnsignedLessThan");
132
new_enum(
133
"cond",
134
"ir::condcodes::IntCC",
135
intcc_values,
136
"An integer comparison condition code.",
137
)
138
},
139
140
floatcc: {
141
let mut floatcc_values = HashMap::new();
142
floatcc_values.insert("ord", "Ordered");
143
floatcc_values.insert("uno", "Unordered");
144
floatcc_values.insert("eq", "Equal");
145
floatcc_values.insert("ne", "NotEqual");
146
floatcc_values.insert("one", "OrderedNotEqual");
147
floatcc_values.insert("ueq", "UnorderedOrEqual");
148
floatcc_values.insert("lt", "LessThan");
149
floatcc_values.insert("le", "LessThanOrEqual");
150
floatcc_values.insert("gt", "GreaterThan");
151
floatcc_values.insert("ge", "GreaterThanOrEqual");
152
floatcc_values.insert("ult", "UnorderedOrLessThan");
153
floatcc_values.insert("ule", "UnorderedOrLessThanOrEqual");
154
floatcc_values.insert("ugt", "UnorderedOrGreaterThan");
155
floatcc_values.insert("uge", "UnorderedOrGreaterThanOrEqual");
156
new_enum(
157
"cond",
158
"ir::condcodes::FloatCC",
159
floatcc_values,
160
"A floating point comparison condition code",
161
)
162
},
163
164
memflags: new_imm("flags", "ir::MemFlags", "Memory operation flags"),
165
166
trapcode: {
167
let mut trapcode_values = HashMap::new();
168
trapcode_values.insert("stk_ovf", "STACK_OVERFLOW");
169
trapcode_values.insert("heap_oob", "HEAP_OUT_OF_BOUNDS");
170
trapcode_values.insert("int_ovf", "INTEGER_OVERFLOW");
171
trapcode_values.insert("int_divz", "INTEGER_DIVISION_BY_ZERO");
172
trapcode_values.insert("bad_toint", "BAD_CONVERSION_TO_INTEGER");
173
new_enum(
174
"code",
175
"ir::TrapCode",
176
trapcode_values,
177
"A trap reason code.",
178
)
179
},
180
atomic_rmw_op: {
181
let mut atomic_rmw_op_values = HashMap::new();
182
atomic_rmw_op_values.insert("add", "Add");
183
atomic_rmw_op_values.insert("sub", "Sub");
184
atomic_rmw_op_values.insert("and", "And");
185
atomic_rmw_op_values.insert("nand", "Nand");
186
atomic_rmw_op_values.insert("or", "Or");
187
atomic_rmw_op_values.insert("xor", "Xor");
188
atomic_rmw_op_values.insert("xchg", "Xchg");
189
atomic_rmw_op_values.insert("umin", "Umin");
190
atomic_rmw_op_values.insert("umax", "Umax");
191
atomic_rmw_op_values.insert("smin", "Smin");
192
atomic_rmw_op_values.insert("smax", "Smax");
193
new_enum(
194
"op",
195
"ir::AtomicRmwOp",
196
atomic_rmw_op_values,
197
"Atomic Read-Modify-Write Ops",
198
)
199
},
200
}
201
}
202
}
203
204