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();
self.prefix16(width);
if src.requires_rex() || dst.requires_rex() {
self.bytes.push(rex(width, src, 0, dst));
}
self.rex(width, src, 0, dst);
self.bytes.push(0x88 | width.not8());
self.bytes.push(modrm_regs(src, dst));
}
@@ -46,9 +44,7 @@ impl Code {
if src_width <= Width::B32 {
dst = dst.lower64();
}
if dst.requires_rex() {
self.bytes.push(rex(dst, 0, 0, dst));
}
self.rex(dst, 0, 0, dst);
self.bytes.push(0xb0 | (dst.not8() << 3) | dst.base());
self.imm(src, dst.width());
}
@@ -62,9 +58,7 @@ impl Code {
}
self.prefix32(&src)?;
self.prefix16(dst);
if dst.requires_rex() | src.reg.gt8() {
self.bytes.push(rex(dst, dst, 0, src));
}
self.rex(dst, dst, 0, src);
self.bytes.push(0x8a | dst.not8());
self.modrm_regdisp(dst, src);
}
@@ -79,9 +73,7 @@ impl Code {
}
self.prefix32(&dst)?;
self.prefix16(src);
if src.requires_rex() | dst.reg.gt8() {
self.bytes.push(rex(src, src, 0, dst));
}
self.rex(src, src, 0, dst);
self.bytes.push(0x88 | src.not8());
self.modrm_regdisp(src, dst);
}
@@ -100,9 +92,7 @@ impl Code {
}
self.prefix32(&dst)?;
self.prefix16(encode_width);
if dst.reg.gt8() || dst.width == Width::B64 {
self.bytes.push(rex(dst, 0, 0, dst));
}
self.rex(dst, 0, 0, dst);
self.bytes.push(0xc6 | encode_width.not8());
self.modrm_regdisp(None, dst);
self.imm(src, encode_width);
@@ -202,6 +192,12 @@ impl Code {
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) {
const I8_MIN: i32 = i8::MIN 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
}
pub trait RexBit {
fn rex(self) -> bool;
pub trait RexBit: Sized {
fn rex(&self) -> bool;
fn req(&self) -> bool {
false
}
}
impl RexBit for u8 {
fn rex(self) -> bool {
self != 0
fn rex(&self) -> bool {
*self != 0
}
}
impl RexBit for Reg {
fn rex(self) -> bool {
fn rex(&self) -> bool {
self.gt8()
}
fn req(&self) -> bool {
self.gt4() && (self.width() == Width::B8) && !self.high()
}
}
impl RexBit for Mem {
fn rex(self) -> bool {
fn rex(&self) -> bool {
self.reg.rex()
}
}
pub trait RexW {
fn rexw(self) -> bool;
fn rexw(&self) -> bool;
}
impl RexW for Width {
fn rexw(self) -> bool {
self == Width::B64
fn rexw(&self) -> bool {
*self == Width::B64
}
}
impl RexW for Reg {
fn rexw(self) -> bool {
fn rexw(&self) -> bool {
self.width().rexw()
}
}
impl RexW for u8 {
fn rexw(self) -> bool {
self == 1
fn rexw(&self) -> bool {
*self == 1
}
}
impl RexW for Mem {
fn rexw(self) -> bool {
fn rexw(&self) -> bool {
self.width.rexw()
}
}