From 872cf6d06f4d77637b4627fdc583bab79ee2372f Mon Sep 17 00:00:00 2001 From: johannst Date: Mon, 27 Feb 2023 22:52:40 +0000 Subject: deploy: 6486b862edc2750dba83848f62d6c9f3d4c6d3c2 --- src/juicebox_asm/reg.rs.html | 648 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 648 insertions(+) create mode 100644 src/juicebox_asm/reg.rs.html (limited to 'src/juicebox_asm/reg.rs.html') diff --git a/src/juicebox_asm/reg.rs.html b/src/juicebox_asm/reg.rs.html new file mode 100644 index 0000000..65ff29e --- /dev/null +++ b/src/juicebox_asm/reg.rs.html @@ -0,0 +1,648 @@ +reg.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+
/// Trait to interact with register operands.
+pub(crate) trait Reg {
+    /// Get the raw x64 register code.
+    fn idx(&self) -> u8;
+
+    /// Check if the registers needs the `REX.W` bit.
+    fn rexw(&self) -> bool;
+
+    /// Check if the register is an extended registers.
+    fn is_ext(&self) -> bool {
+        self.idx() > 7
+    }
+
+    /// Check if the register requires a `REX` byte.
+    fn need_rex(&self) -> bool {
+        self.is_ext() || self.rexw()
+    }
+
+    /// Check if the register requires a `SIB` byte if used as addressing operand.
+    ///
+    /// See [64 bit
+    /// addressing](https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing) for
+    /// further details.
+    fn need_sib(&self) -> bool {
+        self.idx() == 4 || self.idx() == 12
+    }
+
+    /// Check if the register is interpreted as `PC` relative if used as addressing operand.
+    ///
+    /// See [64 bit
+    /// addressing](https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing) for
+    /// further details.
+    fn is_pc_rel(&self) -> bool {
+        self.idx() == 5 || self.idx() == 13
+    }
+}
+
+macro_rules! impl_reg {
+    (ENUM_ONLY, $name:ident, { $($reg:ident),+ $(,)? }) => {
+        /// General purpose register operands.
+        #[allow(non_camel_case_types)]
+        #[derive(Copy, Clone)]
+        #[repr(u8)]
+        pub enum $name {
+            $( $reg, )+
+        }
+
+        #[cfg(test)]
+        impl $name {
+            fn iter() -> impl Iterator<Item = &'static $name> {
+                use $name::*;
+                [$( $reg, )+].iter()
+            }
+        }
+    };
+
+    ($name:ident, $rexw:expr, { $($reg:ident),+ $(,)? }) => {
+        impl_reg!(ENUM_ONLY, $name, { $( $reg, )+ });
+
+        impl Reg for $name {
+            /// Get the raw x64 register code.
+            fn idx(&self) -> u8 {
+                *self as u8
+            }
+
+            /// Check if the registers needs the `REX.W` bit.
+            fn rexw(&self) -> bool {
+                $rexw
+            }
+        }
+    }
+}
+
+impl_reg!(Reg64, true,  { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8,  r9,  r10,  r11,  r12,  r13,  r14,  r15  });
+impl_reg!(Reg32, false, { eax, ecx, edx, ebx, esp, ebp, esi, edi, r8d, r9d, r10d, r11d, r12d, r13d, r14d, r15d });
+impl_reg!(Reg16, false, { ax,  cx,  dx,  bx,  sp,  bp,  si,  di,  r8w, r9w, r10w, r11w, r12w, r13w, r14w, r15w });
+impl_reg!(ENUM_ONLY,
+          Reg8,         { al,  cl,  dl,  bl,  spl, bpl, sil, dil, r8l, r9l, r10l, r11l, r12l, r13l, r14l, r15l,
+                          ah,  ch,  dh,  bh });
+
+impl Reg for Reg8 {
+    /// Get the raw x64 register code.
+    fn idx(&self) -> u8 {
+        match self {
+            Reg8::ah => 4,
+            Reg8::ch => 5,
+            Reg8::dh => 6,
+            Reg8::bh => 7,
+            _ => *self as u8,
+        }
+    }
+
+    /// Check if the registers needs the `REX.W` bit.
+    fn rexw(&self) -> bool {
+        false
+    }
+
+    /// Check whether the gp register needs a `REX` prefix
+    /// Check if the register requires a `REX` byte.
+    ///
+    /// For 1 byte addressing, register indexes `[4:7]` require a `REX` prefix, or else they will
+    /// be decoded as `{AH, CH, DH, BH}` accordingly.
+    ///
+    /// See [Registers](https://wiki.osdev.org/X86-64_Instruction_Encoding#Registers) for
+    /// further details or conduct `Table 3-1. Register Codes` in the *Intel Software Developers
+    /// Manual - Volume 2*.
+    fn need_rex(&self) -> bool {
+        self.idx() > 7 || matches!(self, Reg8::spl | Reg8::bpl | Reg8::sil | Reg8::dil)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_reg8() {
+        use Reg8::*;
+
+        for r in Reg8::iter() {
+            // Check register index.
+            let idx = match r {
+                al => 0,
+                cl => 1,
+                dl => 2,
+                bl => 3,
+                spl => 4,
+                bpl => 5,
+                sil => 6,
+                dil => 7,
+                r8l => 8,
+                r9l => 9,
+                r10l => 10,
+                r11l => 11,
+                r12l => 12,
+                r13l => 13,
+                r14l => 14,
+                r15l => 15,
+                ah => 4,
+                ch => 5,
+                dh => 6,
+                bh => 7,
+            };
+            assert_eq!(r.idx(), idx);
+
+            // Check REX.W bit.
+            assert_eq!(r.rexw(), false);
+
+            // Check need REX byte.
+            let rex = match r {
+                r8l | r9l | r10l | r11l | r12l | r13l | r14l | r15l | spl | bpl | sil | dil => true,
+                _ => false,
+            };
+            assert_eq!(r.need_rex(), rex);
+
+            // Check need SIB byte.
+            let sib = match r {
+                spl | r12l | ah => true,
+                _ => false,
+            };
+            assert_eq!(r.need_sib(), sib);
+
+            // Check if is PC relative addressing.
+            let rel = match r {
+                bpl | r13l | ch => true,
+                _ => false,
+            };
+            assert_eq!(r.is_pc_rel(), rel);
+        }
+    }
+
+    #[test]
+    fn test_reg16() {
+        use Reg16::*;
+
+        for r in Reg16::iter() {
+            // Check register index.
+            let idx = match r {
+                ax => 0,
+                cx => 1,
+                dx => 2,
+                bx => 3,
+                sp => 4,
+                bp => 5,
+                si => 6,
+                di => 7,
+                r8w => 8,
+                r9w => 9,
+                r10w => 10,
+                r11w => 11,
+                r12w => 12,
+                r13w => 13,
+                r14w => 14,
+                r15w => 15,
+            };
+            assert_eq!(r.idx(), idx);
+
+            // Check REX.W bit.
+            assert_eq!(r.rexw(), false);
+
+            // Check need REX byte.
+            let rex = match r {
+                r8w | r9w | r10w | r11w | r12w | r13w | r14w | r15w => true,
+                _ => false,
+            };
+            assert_eq!(r.need_rex(), rex);
+
+            // Check need SIB byte.
+            let sib = match r {
+                sp | r12w => true,
+                _ => false,
+            };
+            assert_eq!(r.need_sib(), sib);
+
+            // Check if is PC relative addressing.
+            let rel = match r {
+                bp | r13w => true,
+                _ => false,
+            };
+            assert_eq!(r.is_pc_rel(), rel);
+        }
+    }
+
+    #[test]
+    fn test_reg32() {
+        use Reg32::*;
+
+        for r in Reg32::iter() {
+            // Check register index.
+            let idx = match r {
+                eax => 0,
+                ecx => 1,
+                edx => 2,
+                ebx => 3,
+                esp => 4,
+                ebp => 5,
+                esi => 6,
+                edi => 7,
+                r8d => 8,
+                r9d => 9,
+                r10d => 10,
+                r11d => 11,
+                r12d => 12,
+                r13d => 13,
+                r14d => 14,
+                r15d => 15,
+            };
+            assert_eq!(r.idx(), idx);
+
+            // Check REX.W bit.
+            assert_eq!(r.rexw(), false);
+
+            // Check need REX byte.
+            let rex = match r {
+                r8d | r9d | r10d | r11d | r12d | r13d | r14d | r15d => true,
+                _ => false,
+            };
+            assert_eq!(r.need_rex(), rex);
+
+            // Check need SIB byte.
+            let sib = match r {
+                esp | r12d => true,
+                _ => false,
+            };
+            assert_eq!(r.need_sib(), sib);
+
+            // Check if is PC relative addressing.
+            let rel = match r {
+                ebp | r13d => true,
+                _ => false,
+            };
+            assert_eq!(r.is_pc_rel(), rel);
+        }
+    }
+
+    #[test]
+    fn test_reg64() {
+        use Reg64::*;
+
+        for r in Reg64::iter() {
+            // Check register index.
+            let idx = match r {
+                rax => 0,
+                rcx => 1,
+                rdx => 2,
+                rbx => 3,
+                rsp => 4,
+                rbp => 5,
+                rsi => 6,
+                rdi => 7,
+                r8 => 8,
+                r9 => 9,
+                r10 => 10,
+                r11 => 11,
+                r12 => 12,
+                r13 => 13,
+                r14 => 14,
+                r15 => 15,
+            };
+            assert_eq!(r.idx(), idx);
+
+            // Check REX.W bit.
+            assert_eq!(r.rexw(), true);
+
+            // Check need REX byte.
+            assert_eq!(r.need_rex(), true);
+
+            // Check need SIB byte.
+            let sib = match r {
+                rsp | r12 => true,
+                _ => false,
+            };
+            assert_eq!(r.need_sib(), sib);
+
+            // Check if is PC relative addressing.
+            let rel = match r {
+                rbp | r13 => true,
+                _ => false,
+            };
+            assert_eq!(r.is_pc_rel(), rel);
+        }
+    }
+}
+
+
\ No newline at end of file -- cgit v1.2.3