Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/src/isa/s390x/inst/imms.rs
3088 views
1
//! S390x ISA definitions: immediate constants.
2
3
use crate::machinst::PrettyPrint;
4
use alloc::string::String;
5
6
/// An unsigned 12-bit immediate.
7
#[derive(Clone, Copy, Debug)]
8
pub struct UImm12 {
9
/// The value.
10
value: u16,
11
}
12
13
impl UImm12 {
14
pub fn maybe_from_u64(value: u64) -> Option<UImm12> {
15
if value < 4096 {
16
Some(UImm12 {
17
value: value as u16,
18
})
19
} else {
20
None
21
}
22
}
23
24
pub fn maybe_from_simm20(value: SImm20) -> Option<UImm12> {
25
let SImm20 { value } = value;
26
if value >= 0 {
27
Self::maybe_from_u64(value as u64)
28
} else {
29
None
30
}
31
}
32
33
/// Create a zero immediate of this format.
34
pub fn zero() -> UImm12 {
35
UImm12 { value: 0 }
36
}
37
38
/// Bits for encoding.
39
pub fn bits(&self) -> u32 {
40
u32::from(self.value)
41
}
42
}
43
44
/// A signed 20-bit immediate.
45
#[derive(Clone, Copy, Debug)]
46
pub struct SImm20 {
47
/// The value.
48
value: i32,
49
}
50
51
impl SImm20 {
52
pub fn maybe_from_i64(value: i64) -> Option<SImm20> {
53
if value >= -524288 && value < 524288 {
54
Some(SImm20 {
55
value: value as i32,
56
})
57
} else {
58
None
59
}
60
}
61
62
pub fn from_uimm12(value: UImm12) -> SImm20 {
63
SImm20 {
64
value: value.bits() as i32,
65
}
66
}
67
68
/// Bits for encoding.
69
pub fn bits(&self) -> u32 {
70
let encoded: u32 = self.value as u32;
71
encoded & 0xfffff
72
}
73
}
74
75
/// A 16-bit immediate with a {0,16,32,48}-bit shift.
76
#[derive(Clone, Copy, Debug)]
77
pub struct UImm16Shifted {
78
/// The value.
79
pub bits: u16,
80
/// Result is `bits` shifted 16*shift bits to the left.
81
pub shift: u8,
82
}
83
84
impl UImm16Shifted {
85
/// Construct a UImm16Shifted from an arbitrary 64-bit constant if possible.
86
pub fn maybe_from_u64(value: u64) -> Option<UImm16Shifted> {
87
let mask0 = 0x0000_0000_0000_ffffu64;
88
let mask1 = 0x0000_0000_ffff_0000u64;
89
let mask2 = 0x0000_ffff_0000_0000u64;
90
let mask3 = 0xffff_0000_0000_0000u64;
91
92
if value == (value & mask0) {
93
return Some(UImm16Shifted {
94
bits: (value & mask0) as u16,
95
shift: 0,
96
});
97
}
98
if value == (value & mask1) {
99
return Some(UImm16Shifted {
100
bits: ((value >> 16) & mask0) as u16,
101
shift: 1,
102
});
103
}
104
if value == (value & mask2) {
105
return Some(UImm16Shifted {
106
bits: ((value >> 32) & mask0) as u16,
107
shift: 2,
108
});
109
}
110
if value == (value & mask3) {
111
return Some(UImm16Shifted {
112
bits: ((value >> 48) & mask0) as u16,
113
shift: 3,
114
});
115
}
116
None
117
}
118
119
pub fn maybe_with_shift(imm: u16, shift: u8) -> Option<UImm16Shifted> {
120
let shift_enc = shift / 16;
121
if shift_enc > 3 {
122
None
123
} else {
124
Some(UImm16Shifted {
125
bits: imm,
126
shift: shift_enc,
127
})
128
}
129
}
130
131
pub fn negate_bits(&self) -> UImm16Shifted {
132
UImm16Shifted {
133
bits: !self.bits,
134
shift: self.shift,
135
}
136
}
137
}
138
139
/// A 32-bit immediate with a {0,32}-bit shift.
140
#[derive(Clone, Copy, Debug)]
141
pub struct UImm32Shifted {
142
/// The value.
143
pub bits: u32,
144
/// Result is `bits` shifted 32*shift bits to the left.
145
pub shift: u8,
146
}
147
148
impl UImm32Shifted {
149
/// Construct a UImm32Shifted from an arbitrary 64-bit constant if possible.
150
pub fn maybe_from_u64(value: u64) -> Option<UImm32Shifted> {
151
let mask0 = 0x0000_0000_ffff_ffffu64;
152
let mask1 = 0xffff_ffff_0000_0000u64;
153
154
if value == (value & mask0) {
155
return Some(UImm32Shifted {
156
bits: (value & mask0) as u32,
157
shift: 0,
158
});
159
}
160
if value == (value & mask1) {
161
return Some(UImm32Shifted {
162
bits: ((value >> 32) & mask0) as u32,
163
shift: 1,
164
});
165
}
166
None
167
}
168
169
pub fn maybe_with_shift(imm: u32, shift: u8) -> Option<UImm32Shifted> {
170
let shift_enc = shift / 32;
171
if shift_enc > 3 {
172
None
173
} else {
174
Some(UImm32Shifted {
175
bits: imm,
176
shift: shift_enc,
177
})
178
}
179
}
180
181
pub fn negate_bits(&self) -> UImm32Shifted {
182
UImm32Shifted {
183
bits: !self.bits,
184
shift: self.shift,
185
}
186
}
187
}
188
189
impl PrettyPrint for UImm12 {
190
fn pretty_print(&self, _: u8) -> String {
191
format!("{}", self.value)
192
}
193
}
194
195
impl PrettyPrint for SImm20 {
196
fn pretty_print(&self, _: u8) -> String {
197
format!("{}", self.value)
198
}
199
}
200
201
impl PrettyPrint for UImm16Shifted {
202
fn pretty_print(&self, _: u8) -> String {
203
format!("{}", self.bits)
204
}
205
}
206
207
impl PrettyPrint for UImm32Shifted {
208
fn pretty_print(&self, _: u8) -> String {
209
format!("{}", self.bits)
210
}
211
}
212
213