cranelift_assembler_x64/
imm.rs1use crate::api::CodeSink;
4use std::fmt;
5
6macro_rules! hexify {
10 ($n:expr) => {
11 format!("$0x{:x}", $n)
12 };
13}
14
15macro_rules! hexify_sign_extend {
17 ($n:expr, $from:ty => $to:ty) => {{
18 let from: $from = $n; let to = <$to>::from(from);
20 format!("$0x{:x}", to)
21 }};
22}
23
24#[derive(Clone, Copy, Debug)]
26#[cfg_attr(any(test, feature = "fuzz"), derive(arbitrary::Arbitrary))]
27pub struct Imm8(u8);
28
29impl Imm8 {
30 #[must_use]
31 pub fn new(value: u8) -> Self {
32 Self(value)
33 }
34
35 #[must_use]
36 pub fn value(&self) -> u8 {
37 self.0
38 }
39
40 pub fn encode(&self, sink: &mut impl CodeSink) {
41 sink.put1(self.0);
42 }
43}
44
45impl fmt::Display for Imm8 {
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 write!(f, "$0x{:x}", self.0)
48 }
49}
50
51#[derive(Clone, Copy, Debug)]
53#[cfg_attr(any(test, feature = "fuzz"), derive(arbitrary::Arbitrary))]
54pub struct Simm8(i8);
55
56impl Simm8 {
57 #[must_use]
58 pub fn new(value: i8) -> Self {
59 Self(value)
60 }
61
62 #[must_use]
63 pub fn value(&self) -> i8 {
64 self.0
65 }
66
67 pub fn encode(&self, sink: &mut impl CodeSink) {
68 sink.put1(self.0 as u8);
69 }
70
71 #[must_use]
72 pub fn to_string(&self, extend: Extension) -> String {
73 use Extension::{None, SignExtendLong, SignExtendQuad, SignExtendWord};
74 match extend {
75 None => hexify!(self.0),
76 SignExtendWord => hexify_sign_extend!(self.0, i8 => i16),
77 SignExtendLong => hexify_sign_extend!(self.0, i8 => i32),
78 SignExtendQuad => hexify_sign_extend!(self.0, i8 => i64),
79 }
80 }
81}
82
83#[derive(Clone, Debug)]
85#[cfg_attr(any(test, feature = "fuzz"), derive(arbitrary::Arbitrary))]
86pub struct Imm16(u16);
87
88impl Imm16 {
89 #[must_use]
90 pub fn new(value: u16) -> Self {
91 Self(value)
92 }
93
94 #[must_use]
95 pub fn value(&self) -> u16 {
96 self.0
97 }
98
99 pub fn encode(&self, sink: &mut impl CodeSink) {
100 sink.put2(self.0);
101 }
102}
103
104impl fmt::Display for Imm16 {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 write!(f, "$0x{:x}", self.0)
107 }
108}
109
110#[derive(Clone, Debug)]
112#[cfg_attr(any(test, feature = "fuzz"), derive(arbitrary::Arbitrary))]
113pub struct Simm16(i16);
114
115impl Simm16 {
116 #[must_use]
117 pub fn new(value: i16) -> Self {
118 Self(value)
119 }
120
121 #[must_use]
122 pub fn value(&self) -> i16 {
123 self.0
124 }
125
126 pub fn encode(&self, sink: &mut impl CodeSink) {
127 sink.put2(self.0 as u16);
128 }
129
130 #[must_use]
131 pub fn to_string(&self, extend: Extension) -> String {
132 use Extension::{None, SignExtendLong, SignExtendQuad, SignExtendWord};
133 match extend {
134 None => hexify!(self.0),
135 SignExtendWord => unreachable!("the 16-bit value is already 16 bits"),
136 SignExtendLong => hexify_sign_extend!(self.0, i16 => i32),
137 SignExtendQuad => hexify_sign_extend!(self.0, i16 => i64),
138 }
139 }
140}
141
142#[derive(Clone, Debug)]
148#[cfg_attr(any(test, feature = "fuzz"), derive(arbitrary::Arbitrary))]
149pub struct Imm32(u32);
150
151impl Imm32 {
152 #[must_use]
153 pub fn new(value: u32) -> Self {
154 Self(value)
155 }
156
157 #[must_use]
158 pub fn value(&self) -> u32 {
159 self.0
160 }
161
162 pub fn encode(&self, sink: &mut impl CodeSink) {
163 sink.put4(self.0);
164 }
165}
166
167impl fmt::Display for Imm32 {
168 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169 write!(f, "$0x{:x}", self.0)
170 }
171}
172
173#[derive(Clone, Debug)]
179#[cfg_attr(any(test, feature = "fuzz"), derive(arbitrary::Arbitrary))]
180pub struct Simm32(i32);
181
182impl Simm32 {
183 #[must_use]
184 pub fn new(value: i32) -> Self {
185 Self(value)
186 }
187
188 #[must_use]
189 pub fn value(&self) -> i32 {
190 self.0
191 }
192
193 pub fn encode(&self, sink: &mut impl CodeSink) {
194 sink.put4(self.0 as u32);
195 }
196
197 #[must_use]
198 pub fn to_string(&self, extend: Extension) -> String {
199 use Extension::{None, SignExtendLong, SignExtendQuad, SignExtendWord};
200 match extend {
201 None => hexify!(self.0),
202 SignExtendWord => unreachable!("cannot sign extend a 32-bit value to 16 bits"),
203 SignExtendLong => unreachable!("the 32-bit value is already 32 bits"),
204 SignExtendQuad => hexify_sign_extend!(self.0, i32 => i64),
205 }
206 }
207}
208
209#[derive(Clone, Copy, Debug)]
211pub enum Extension {
212 None,
213 SignExtendQuad,
214 SignExtendLong,
215 SignExtendWord,
216}