Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/meta/src/isa/riscv64.rs
1693 views
1
use crate::cdsl::isa::TargetIsa;
2
use crate::cdsl::settings::{PredicateNode, SettingGroupBuilder};
3
4
macro_rules! define_zvl_ext {
5
(DEF: $settings:expr, $size:expr) => {{
6
let name = concat!("has_zvl", $size, "b");
7
let desc = concat!("has extension Zvl", $size, "b?");
8
let comment = concat!(
9
"Zvl",
10
$size,
11
"b: Vector register has a minimum of ",
12
$size,
13
" bits"
14
);
15
$settings.add_bool(&name, &desc, &comment, false)
16
}};
17
($settings:expr, $size:expr $(, $implies:expr)*) => {{
18
let has_feature = define_zvl_ext!(DEF: $settings, $size);
19
20
let name = concat!("zvl", $size, "b");
21
let desc = concat!("Has a vector register size of at least ", $size, " bits");
22
23
let preset = $settings.add_preset(&name, &desc, preset!(has_feature $( && $implies )*));
24
(has_feature, preset)
25
}};
26
}
27
28
pub(crate) fn define() -> TargetIsa {
29
let mut setting = SettingGroupBuilder::new("riscv64");
30
31
// We target a minimum of riscv64g. That means that we have the following extensions by default:
32
//
33
// * M (integer multiplication and division)
34
// * A (atomic instructions)
35
// * F (single-precision floating point)
36
// * D (double-precision floating point)
37
// * Zicsr (control and status register instructions)
38
// * Zifencei (instruction-fetch fence)
39
40
let has_m = setting.add_bool(
41
"has_m",
42
"has extension M?",
43
"Integer multiplication and division",
44
true,
45
);
46
let has_a = setting.add_bool("has_a", "has extension A?", "Atomic instructions", true);
47
let has_f = setting.add_bool(
48
"has_f",
49
"has extension F?",
50
"Single-precision floating point",
51
true,
52
);
53
let has_d = setting.add_bool(
54
"has_d",
55
"has extension D?",
56
"Double-precision floating point",
57
true,
58
);
59
60
let _has_zfa = setting.add_bool(
61
"has_zfa",
62
"has extension Zfa?",
63
"Zfa: Extension for Additional Floating-Point Instructions",
64
false,
65
);
66
67
let _has_zfhmin = setting.add_bool(
68
"has_zfhmin",
69
"has extension Zfhmin?",
70
"Zfhmin: Minimal Half-Precision Floating-Point",
71
false,
72
);
73
74
let _has_zfh = setting.add_bool(
75
"has_zfh",
76
"has extension Zfh?",
77
"Zfh: Half-Precision Floating-Point Instructions",
78
false,
79
);
80
81
let _has_v = setting.add_bool(
82
"has_v",
83
"has extension V?",
84
"Vector instruction support",
85
false,
86
);
87
88
let _has_zvfh = setting.add_bool(
89
"has_zvfh",
90
"has extension Zvfh?",
91
"Zvfh: Vector Extension for Half-Precision Floating-Point",
92
false,
93
);
94
95
let has_zca = setting.add_bool(
96
"has_zca",
97
"has extension Zca?",
98
"Zca is the C extension without floating point loads",
99
false,
100
);
101
let has_zcd = setting.add_bool(
102
"has_zcd",
103
"has extension Zcd?",
104
"Zcd contains only the double precision floating point loads from the C extension",
105
false,
106
);
107
setting.add_preset(
108
"has_c",
109
"Support for compressed instructions",
110
preset!(has_zca && has_zcd),
111
);
112
113
let _has_zcb = setting.add_bool(
114
"has_zcb",
115
"has extension Zcb?",
116
"Zcb: Extra compressed instructions",
117
false,
118
);
119
120
let _has_zbkb = setting.add_bool(
121
"has_zbkb",
122
"has extension zbkb?",
123
"Zbkb: Bit-manipulation for Cryptography",
124
false,
125
);
126
let _has_zba = setting.add_bool(
127
"has_zba",
128
"has extension zba?",
129
"Zba: Address Generation",
130
false,
131
);
132
let _has_zbb = setting.add_bool(
133
"has_zbb",
134
"has extension zbb?",
135
"Zbb: Basic bit-manipulation",
136
false,
137
);
138
let _has_zbc = setting.add_bool(
139
"has_zbc",
140
"has extension zbc?",
141
"Zbc: Carry-less multiplication",
142
false,
143
);
144
let _has_zbs = setting.add_bool(
145
"has_zbs",
146
"has extension zbs?",
147
"Zbs: Single-bit instructions",
148
false,
149
);
150
let _has_zicond = setting.add_bool(
151
"has_zicond",
152
"has extension zicond?",
153
"ZiCond: Integer Conditional Operations",
154
false,
155
);
156
157
let has_zicsr = setting.add_bool(
158
"has_zicsr",
159
"has extension zicsr?",
160
"Zicsr: Control and Status Register (CSR) Instructions",
161
true,
162
);
163
let has_zifencei = setting.add_bool(
164
"has_zifencei",
165
"has extension zifencei?",
166
"Zifencei: Instruction-Fetch Fence",
167
true,
168
);
169
170
// Zvl*: Minimum Vector Length Standard Extensions
171
// These extension specify the minimum number of bits in a vector register.
172
// Since it is a minimum, Zvl64b implies Zvl32b, Zvl128b implies Zvl64b, etc.
173
// The V extension supports a maximum of 64K bits in a single register.
174
//
175
// See: https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#181-zvl-minimum-vector-length-standard-extensions
176
let (_, zvl32b) = define_zvl_ext!(setting, 32);
177
let (_, zvl64b) = define_zvl_ext!(setting, 64, zvl32b);
178
let (_, zvl128b) = define_zvl_ext!(setting, 128, zvl64b);
179
let (_, zvl256b) = define_zvl_ext!(setting, 256, zvl128b);
180
let (_, zvl512b) = define_zvl_ext!(setting, 512, zvl256b);
181
let (_, zvl1024b) = define_zvl_ext!(setting, 1024, zvl512b);
182
let (_, zvl2048b) = define_zvl_ext!(setting, 2048, zvl1024b);
183
let (_, zvl4096b) = define_zvl_ext!(setting, 4096, zvl2048b);
184
let (_, zvl8192b) = define_zvl_ext!(setting, 8192, zvl4096b);
185
let (_, zvl16384b) = define_zvl_ext!(setting, 16384, zvl8192b);
186
let (_, zvl32768b) = define_zvl_ext!(setting, 32768, zvl16384b);
187
let (_, _zvl65536b) = define_zvl_ext!(setting, 65536, zvl32768b);
188
189
setting.add_predicate(
190
"has_g",
191
predicate!(has_m && has_a && has_f && has_d && has_zicsr && has_zifencei),
192
);
193
194
TargetIsa::new("riscv64", setting.build())
195
}
196
197