aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-07-04 13:21:09 -0700
committeriximeow <me@iximeow.net>2021-07-04 13:21:09 -0700
commite15ef43a243ae0e0db369cead1786f4f2c4e690e (patch)
treee6ee5bebf5c1681cc67712b01d3b89c04b824af9 /src
parent2c84821ee0d9807d20ea82b8550edde09426a867 (diff)
support xacquire/xrelease prefixing
Diffstat (limited to 'src')
-rw-r--r--src/long_mode/display.rs25
-rw-r--r--src/long_mode/mod.rs42
-rw-r--r--src/protected_mode/display.rs25
-rw-r--r--src/protected_mode/mod.rs41
-rw-r--r--src/real_mode/display.rs25
-rw-r--r--src/real_mode/mod.rs41
6 files changed, 193 insertions, 6 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index 948df53..7f21b35 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -3311,8 +3311,14 @@ impl Instruction {
}
fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: &Y, _address: u64, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
+ if instr.xacquire() {
+ out.write_str("xacquire ")?;
+ }
+ if instr.xrelease() {
+ out.write_str("xrelease ")?;
+ }
if instr.prefixes.lock() {
- write!(out, "lock ")?;
+ out.write_str("lock ")?;
}
if instr.prefixes.rep_any() {
@@ -3423,8 +3429,23 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:
fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, _colors: &Y, _address: u64, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
let mut brace_count = 0;
+ let mut prefixed = false;
+
+ if instr.xacquire() {
+ out.write_str("xacquire ")?;
+ prefixed = true;
+ }
+ if instr.xrelease() {
+ out.write_str("xrelease ")?;
+ prefixed = true;
+ }
if instr.prefixes.lock() {
- out.write_str("lock { ")?;
+ out.write_str("lock ")?;
+ prefixed = true;
+ }
+
+ if prefixed {
+ out.write_str("{ ")?;
brace_count += 1;
}
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 79f3fee..6e3e21d 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -4470,6 +4470,48 @@ impl Instruction {
instr: self,
}
}
+
+ /// does this instruction include the `xacquire` hint for hardware lock elision?
+ pub fn xacquire(&self) -> bool {
+ if self.prefixes.repnz() {
+ // xacquire is permitted on typical `lock` instructions, OR `xchg` with memory operand,
+ // regardless of `lock` prefix.
+ if self.prefixes.lock() {
+ true
+ } else if self.opcode == Opcode::XCHG {
+ self.operands[0] != OperandSpec::RegMMM && self.operands[1] != OperandSpec::RegMMM
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ }
+
+ /// does this instruction include the `xrelease` hint for hardware lock elision?
+ pub fn xrelease(&self) -> bool {
+ if self.prefixes.rep() {
+ // xrelease is permitted on typical `lock` instructions, OR `xchg` with memory operand,
+ // regardless of `lock` prefix. additionally, xrelease is permitted on some forms of mov.
+ if self.prefixes.lock() {
+ true
+ } else if self.opcode == Opcode::XCHG {
+ self.operands[0] != OperandSpec::RegMMM && self.operands[1] != OperandSpec::RegMMM
+ } else if self.opcode == Opcode::MOV {
+ self.operands[0] != OperandSpec::RegMMM && (
+ self.operands[1] == OperandSpec::RegRRR ||
+ self.operands[1] == OperandSpec::ImmI8 ||
+ self.operands[1] == OperandSpec::ImmI16 ||
+ self.operands[1] == OperandSpec::ImmI32 ||
+ self.operands[1] == OperandSpec::ImmI64
+ )
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs
index c5892c2..0b11ea0 100644
--- a/src/protected_mode/display.rs
+++ b/src/protected_mode/display.rs
@@ -3324,8 +3324,14 @@ impl Instruction {
}
fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: &Y, _address: u32, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
+ if instr.xacquire() {
+ out.write_str("xacquire ")?;
+ }
+ if instr.xrelease() {
+ out.write_str("xrelease ")?;
+ }
if instr.prefixes.lock() {
- write!(out, "lock ")?;
+ out.write_str("lock ")?;
}
if instr.prefixes.rep_any() {
@@ -3436,8 +3442,23 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:
fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, _colors: &Y, _address: u32, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
let mut brace_count = 0;
+ let mut prefixed = false;
+
+ if instr.xacquire() {
+ out.write_str("xacquire ")?;
+ prefixed = true;
+ }
+ if instr.xrelease() {
+ out.write_str("xrelease ")?;
+ prefixed = true;
+ }
if instr.prefixes.lock() {
- out.write_str("lock { ")?;
+ out.write_str("lock ")?;
+ prefixed = true;
+ }
+
+ if prefixed {
+ out.write_str("{ ")?;
brace_count += 1;
}
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index f5d7981..aedbbea 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -4412,6 +4412,47 @@ impl Instruction {
instr: self,
}
}
+
+ /// does this instruction include the `xacquire` hint for hardware lock elision?
+ pub fn xacquire(&self) -> bool {
+ if self.prefixes.repnz() {
+ // xacquire is permitted on typical `lock` instructions, OR `xchg` with memory operand,
+ // regardless of `lock` prefix.
+ if self.prefixes.lock() {
+ true
+ } else if self.opcode == Opcode::XCHG {
+ self.operands[0] != OperandSpec::RegMMM && self.operands[1] != OperandSpec::RegMMM
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ }
+
+ /// does this instruction include the `xrelease` hint for hardware lock elision?
+ pub fn xrelease(&self) -> bool {
+ if self.prefixes.rep() {
+ // xrelease is permitted on typical `lock` instructions, OR `xchg` with memory operand,
+ // regardless of `lock` prefix. additionally, xrelease is permitted on some forms of mov.
+ if self.prefixes.lock() {
+ true
+ } else if self.opcode == Opcode::XCHG {
+ self.operands[0] != OperandSpec::RegMMM && self.operands[1] != OperandSpec::RegMMM
+ } else if self.opcode == Opcode::MOV {
+ self.operands[0] != OperandSpec::RegMMM && (
+ self.operands[1] == OperandSpec::RegRRR ||
+ self.operands[1] == OperandSpec::ImmI8 ||
+ self.operands[1] == OperandSpec::ImmI16 ||
+ self.operands[1] == OperandSpec::ImmI32
+ )
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
diff --git a/src/real_mode/display.rs b/src/real_mode/display.rs
index a6e0a32..29bfa3a 100644
--- a/src/real_mode/display.rs
+++ b/src/real_mode/display.rs
@@ -3324,8 +3324,14 @@ impl Instruction {
}
fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: &Y, _address: u32, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
+ if instr.xacquire() {
+ out.write_str("xacquire ")?;
+ }
+ if instr.xrelease() {
+ out.write_str("xrelease ")?;
+ }
if instr.prefixes.lock() {
- write!(out, "lock ")?;
+ out.write_str("lock ")?;
}
if instr.prefixes.rep_any() {
@@ -3436,8 +3442,23 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:
fn contextualize_c<T: fmt::Write, Y: YaxColors>(instr: &Instruction, _colors: &Y, _address: u32, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
let mut brace_count = 0;
+ let mut prefixed = false;
+
+ if instr.xacquire() {
+ out.write_str("xacquire ")?;
+ prefixed = true;
+ }
+ if instr.xrelease() {
+ out.write_str("xrelease ")?;
+ prefixed = true;
+ }
if instr.prefixes.lock() {
- out.write_str("lock { ")?;
+ out.write_str("lock ")?;
+ prefixed = true;
+ }
+
+ if prefixed {
+ out.write_str("{ ")?;
brace_count += 1;
}
diff --git a/src/real_mode/mod.rs b/src/real_mode/mod.rs
index 8376230..bfcb79f 100644
--- a/src/real_mode/mod.rs
+++ b/src/real_mode/mod.rs
@@ -4422,6 +4422,47 @@ impl Instruction {
instr: self,
}
}
+
+ /// does this instruction include the `xacquire` hint for hardware lock elision?
+ pub fn xacquire(&self) -> bool {
+ if self.prefixes.repnz() {
+ // xacquire is permitted on typical `lock` instructions, OR `xchg` with memory operand,
+ // regardless of `lock` prefix.
+ if self.prefixes.lock() {
+ true
+ } else if self.opcode == Opcode::XCHG {
+ self.operands[0] != OperandSpec::RegMMM && self.operands[1] != OperandSpec::RegMMM
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ }
+
+ /// does this instruction include the `xrelease` hint for hardware lock elision?
+ pub fn xrelease(&self) -> bool {
+ if self.prefixes.rep() {
+ // xrelease is permitted on typical `lock` instructions, OR `xchg` with memory operand,
+ // regardless of `lock` prefix. additionally, xrelease is permitted on some forms of mov.
+ if self.prefixes.lock() {
+ true
+ } else if self.opcode == Opcode::XCHG {
+ self.operands[0] != OperandSpec::RegMMM && self.operands[1] != OperandSpec::RegMMM
+ } else if self.opcode == Opcode::MOV {
+ self.operands[0] != OperandSpec::RegMMM && (
+ self.operands[1] == OperandSpec::RegRRR ||
+ self.operands[1] == OperandSpec::ImmI8 ||
+ self.operands[1] == OperandSpec::ImmI16 ||
+ self.operands[1] == OperandSpec::ImmI32
+ )
+ } else {
+ false
+ }
+ } else {
+ false
+ }
+ }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]