aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-08-09 00:32:49 -0700
committeriximeow <me@iximeow.net>2020-08-09 01:39:01 -0700
commit2bf6df7ff4101b4e7cf14807b5e9def85d92e1cd (patch)
treee2555f6a9468582422baafe95aea243a2a05d7a1
parenta3f848e3426175d9ac782c19de4855de260d76a9 (diff)
display opt, aykm
the arms of the match in regspec_label referenced tables that were not const. consequently, they would be rebuilt when reached, every time the match is incanted. this holds through even when regspec_label is inlined. each arm could be a const array for a small and easy change, but to avoid the indirect dispatch on spec.bank i've reorganized register names into a single const array and selected values for `RegisterBank` such that indices into that array can be formed. for my next trick, i may make `REG_NAMES` a `*const u8`, with indices picking offsets into the table - 8-byte offsets might do? this should compact down size a little more by removing a pointer and size qword for each string.
-rw-r--r--src/long_mode/display.rs74
-rw-r--r--src/long_mode/mod.rs20
2 files changed, 36 insertions, 58 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index a4a4d79..42d3683 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -115,55 +115,33 @@ impl fmt::Display for Segment {
}
}
+// register names are grouped by indices scaled by 16.
+// xmm, ymm, zmm all get two indices.
+const REG_NAMES: &[&'static str] = &[
+ "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d",
+ "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w",
+ "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "", "", "", "", "", "", "", "",
+ "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b",
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15",
+ "dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7", "dr8", "dr9", "dr10", "dr11", "dr12", "dr13", "dr14", "dr15",
+ "cs", "ds", "es", "fs", "gs", "ss", "", "",
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
+ "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
+ "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
+ "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31",
+ "st(0)", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)",
+ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
+ "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7",
+ "eip", "k1", "k2", "k3", "k4", "k5", "k6", "k7",
+ "rip", "k1", "k2", "k3", "k4", "k5", "k6", "k7",
+ "eflags", "k1", "k2", "k3", "k4", "k5", "k6", "k7",
+ "rflags", "k1", "k2", "k3", "k4", "k5", "k6", "k7",
+];
+
pub(crate) fn regspec_label(spec: &RegSpec) -> &'static str {
- match spec.bank {
- RegisterBank::Q => {
- ["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"][spec.num as usize]
- },
- RegisterBank::D => {
- ["eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"][spec.num as usize]
- },
- RegisterBank::W => {
- ["ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"][spec.num as usize]
- },
- RegisterBank::B => {
- ["al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"][spec.num as usize]
- },
- RegisterBank::rB => {
- ["al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"][spec.num as usize]
- },
- RegisterBank::EIP => { "eip" },
- RegisterBank::RIP => { "rip" },
- RegisterBank::EFlags => { "eflags" },
- RegisterBank::RFlags => { "rflags" },
- RegisterBank::CR => {
- ["cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", "cr8", "cr9", "cr10", "cr11", "cr12", "cr13", "cr14", "cr15"][spec.num as usize]
- }
- RegisterBank::DR => {
- ["dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7", "dr8", "dr9", "dr10", "dr11", "dr12", "dr13", "dr14", "dr15"][spec.num as usize]
- }
- RegisterBank::X => {
- ["xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"][spec.num as usize]
- },
- RegisterBank::Y => {
- ["ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15"][spec.num as usize]
- },
- RegisterBank::Z => {
- ["zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31"][spec.num as usize]
- },
- RegisterBank::ST => {
- ["st(0)", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)"][spec.num as usize]
- },
- RegisterBank::MM => {
- ["mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"][spec.num as usize]
- }
- RegisterBank::S => {
- ["cs", "ds", "es", "fs", "gs", "ss"][spec.num as usize]
- }
- RegisterBank::K => {
- ["k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7"][spec.num as usize]
- }
- }
+ unsafe { REG_NAMES.get_unchecked((spec.num as u16 + ((spec.bank as u16) << 3)) as usize) }
}
impl fmt::Display for RegSpec {
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 9d3b05a..3b3bddb 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -508,21 +508,21 @@ fn operand_size() {
#[cfg(feature="use-serde")]
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub enum RegisterBank {
- Q, D, W, B, rB, // Quadword, Dword, Word, Byte
- CR, DR, S, EIP, RIP, EFlags, RFlags, // Control reg, Debug reg, Selector, ...
- X, Y, Z, // XMM, YMM, ZMM
- ST, MM, // ST, MM regs (x87, mmx)
- K, // AVX512 mask registers
+ Q = 0, D = 2, W = 4, B = 6, rB = 8, // Quadword, Dword, Word, Byte
+ CR = 10, DR = 12, S = 14, EIP = 30, RIP = 31, EFlags = 32, RFlags = 33, // Control reg, Debug reg, Selector, ...
+ X = 15, Y = 19, Z = 23, // XMM, YMM, ZMM
+ ST = 27, MM = 28, // ST, MM regs (x87, mmx)
+ K = 29, // AVX512 mask registers
}
#[allow(non_camel_case_types)]
#[cfg(not(feature="use-serde"))]
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum RegisterBank {
- Q, D, W, B, rB, // Quadword, Dword, Word, Byte
- CR, DR, S, EIP, RIP, EFlags, RFlags, // Control reg, Debug reg, Selector, ...
- X, Y, Z, // XMM, YMM, ZMM
- ST, MM, // ST, MM regs (x87, mmx)
- K, // AVX512 mask registers
+ Q = 0, D = 2, W = 4, B = 6, rB = 8, // Quadword, Dword, Word, Byte
+ CR = 10, DR = 12, S = 14, EIP = 30, RIP = 31, EFlags = 32, RFlags = 33, // Control reg, Debug reg, Selector, ...
+ X = 15, Y = 19, Z = 23, // XMM, YMM, ZMM
+ ST = 27, MM = 28, // ST, MM regs (x87, mmx)
+ K = 29, // AVX512 mask registers
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]