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