more rex stuff
This commit is contained in:
+11
-15
@@ -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
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user