more rex stuff

This commit is contained in:
2026-06-12 23:27:33 -04:00
parent 550d58d6f4
commit bdeb0d821c
2 changed files with 30 additions and 28 deletions
+11 -15
View File
@@ -25,9 +25,7 @@ impl Code {
} }
let width = dst.width(); let width = dst.width();
self.prefix16(width); self.prefix16(width);
if src.requires_rex() || dst.requires_rex() { self.rex(width, src, 0, dst);
self.bytes.push(rex(width, src, 0, dst));
}
self.bytes.push(0x88 | width.not8()); self.bytes.push(0x88 | width.not8());
self.bytes.push(modrm_regs(src, dst)); self.bytes.push(modrm_regs(src, dst));
} }
@@ -46,9 +44,7 @@ impl Code {
if src_width <= Width::B32 { if src_width <= Width::B32 {
dst = dst.lower64(); dst = dst.lower64();
} }
if dst.requires_rex() { self.rex(dst, 0, 0, dst);
self.bytes.push(rex(dst, 0, 0, dst));
}
self.bytes.push(0xb0 | (dst.not8() << 3) | dst.base()); self.bytes.push(0xb0 | (dst.not8() << 3) | dst.base());
self.imm(src, dst.width()); self.imm(src, dst.width());
} }
@@ -62,9 +58,7 @@ impl Code {
} }
self.prefix32(&src)?; self.prefix32(&src)?;
self.prefix16(dst); self.prefix16(dst);
if dst.requires_rex() | src.reg.gt8() { self.rex(dst, dst, 0, src);
self.bytes.push(rex(dst, dst, 0, src));
}
self.bytes.push(0x8a | dst.not8()); self.bytes.push(0x8a | dst.not8());
self.modrm_regdisp(dst, src); self.modrm_regdisp(dst, src);
} }
@@ -79,9 +73,7 @@ impl Code {
} }
self.prefix32(&dst)?; self.prefix32(&dst)?;
self.prefix16(src); self.prefix16(src);
if src.requires_rex() | dst.reg.gt8() { self.rex(src, src, 0, dst);
self.bytes.push(rex(src, src, 0, dst));
}
self.bytes.push(0x88 | src.not8()); self.bytes.push(0x88 | src.not8());
self.modrm_regdisp(src, dst); self.modrm_regdisp(src, dst);
} }
@@ -100,9 +92,7 @@ impl Code {
} }
self.prefix32(&dst)?; self.prefix32(&dst)?;
self.prefix16(encode_width); self.prefix16(encode_width);
if dst.reg.gt8() || dst.width == Width::B64 { self.rex(dst, 0, 0, dst);
self.bytes.push(rex(dst, 0, 0, dst));
}
self.bytes.push(0xc6 | encode_width.not8()); self.bytes.push(0xc6 | encode_width.not8());
self.modrm_regdisp(None, dst); self.modrm_regdisp(None, dst);
self.imm(src, encode_width); self.imm(src, encode_width);
@@ -202,6 +192,12 @@ impl Code {
Ok(()) Ok(())
} }
fn rex(&mut self, w: impl RexW, r: impl RexBit, x: u8, b: impl RexBit) {
if w.rexw() || r.rex() || x.rex() || b.rex() | r.req() | b.req() {
self.bytes.push(rex(w, r, x, b));
}
}
fn modrm_regdisp(&mut self, reg: impl Into<Option<Reg>>, mem: Mem) { fn modrm_regdisp(&mut self, reg: impl Into<Option<Reg>>, mem: Mem) {
const I8_MIN: i32 = i8::MIN as i32; const I8_MIN: i32 = i8::MIN as i32;
const I8_MAX: i32 = i8::MAX as i32; const I8_MAX: i32 = i8::MAX as i32;
+19 -13
View File
@@ -25,52 +25,58 @@ fn bit(val: bool, pos: u8) -> u8 {
(val as u8) << pos (val as u8) << pos
} }
pub trait RexBit { pub trait RexBit: Sized {
fn rex(self) -> bool; fn rex(&self) -> bool;
fn req(&self) -> bool {
false
}
} }
impl RexBit for u8 { impl RexBit for u8 {
fn rex(self) -> bool { fn rex(&self) -> bool {
self != 0 *self != 0
} }
} }
impl RexBit for Reg { impl RexBit for Reg {
fn rex(self) -> bool { fn rex(&self) -> bool {
self.gt8() self.gt8()
} }
fn req(&self) -> bool {
self.gt4() && (self.width() == Width::B8) && !self.high()
}
} }
impl RexBit for Mem { impl RexBit for Mem {
fn rex(self) -> bool { fn rex(&self) -> bool {
self.reg.rex() self.reg.rex()
} }
} }
pub trait RexW { pub trait RexW {
fn rexw(self) -> bool; fn rexw(&self) -> bool;
} }
impl RexW for Width { impl RexW for Width {
fn rexw(self) -> bool { fn rexw(&self) -> bool {
self == Width::B64 *self == Width::B64
} }
} }
impl RexW for Reg { impl RexW for Reg {
fn rexw(self) -> bool { fn rexw(&self) -> bool {
self.width().rexw() self.width().rexw()
} }
} }
impl RexW for u8 { impl RexW for u8 {
fn rexw(self) -> bool { fn rexw(&self) -> bool {
self == 1 *self == 1
} }
} }
impl RexW for Mem { impl RexW for Mem {
fn rexw(self) -> bool { fn rexw(&self) -> bool {
self.width.rexw() self.width.rexw()
} }
} }