Commit 9cf93e1c authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: Add cmpxchg and lock instructions to x64 and ia32 {dis,}assemblers.

  port 5c22cf5a (r36341)

  original commit message:

BUG=

Review-Url: https://codereview.chromium.org/1990133002
Cr-Commit-Position: refs/heads/master@{#36345}
parent 32ba3c91
......@@ -601,6 +601,33 @@ void Assembler::xchg_w(Register reg, const Operand& op) {
emit_operand(reg, op);
}
void Assembler::lock() {
EnsureSpace ensure_space(this);
EMIT(0xF0);
}
void Assembler::cmpxchg(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0xB1);
emit_operand(src, dst);
}
void Assembler::cmpxchg_b(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
EMIT(0x0F);
EMIT(0xB0);
emit_operand(src, dst);
}
void Assembler::cmpxchg_w(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
EMIT(0x66);
EMIT(0x0F);
EMIT(0xB1);
emit_operand(src, dst);
}
void Assembler::adc(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
emit_arith(2, Operand(dst), Immediate(imm32));
......
......@@ -654,6 +654,14 @@ class Assembler : public AssemblerBase {
void xchg_b(Register reg, const Operand& op);
void xchg_w(Register reg, const Operand& op);
// Lock prefix
void lock();
// CompareExchange
void cmpxchg(const Operand& dst, Register src);
void cmpxchg_b(const Operand& dst, Register src);
void cmpxchg_w(const Operand& dst, Register src);
// Arithmetics
void adc(Register dst, int32_t imm32);
void adc(Register dst, const Operand& src);
......
......@@ -920,6 +920,10 @@ static const char* F0Mnem(byte f0byte) {
return "shrd"; // 3-operand version.
case 0xAB:
return "bts";
case 0xB0:
return "cmpxchg_b";
case 0xB1:
return "cmpxchg";
case 0xBC:
return "bsf";
case 0xBD:
......@@ -943,7 +947,11 @@ int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
} else if (*data == 0x2E /*cs*/) {
branch_hint = "predicted not taken";
data++;
} else if (*data == 0xF0 /*lock*/) {
AppendToBuffer("lock ");
data++;
}
bool processed = true; // Will be set to false if the current instruction
// is not in 'instructions' table.
const InstructionDesc& idesc = instruction_table_->Get(*data);
......@@ -1162,6 +1170,24 @@ int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
} else {
AppendToBuffer(",%s,cl", NameOfCPURegister(regop));
}
} else if (f0byte == 0xB0) {
// cmpxchg_b
data += 2;
AppendToBuffer("%s ", f0mnem);
int mod, regop, rm;
get_modrm(*data, &mod, &regop, &rm);
data += PrintRightOperand(data);
AppendToBuffer(",%s", NameOfByteCPURegister(regop));
} else if (f0byte == 0xB1) {
// cmpxchg
data += 2;
data += PrintOperands(f0mnem, OPER_REG_OP_ORDER, data);
} else if (f0byte == 0xBC) {
data += 2;
int mod, regop, rm;
get_modrm(*data, &mod, &regop, &rm);
AppendToBuffer("%s %s,", f0mnem, NameOfCPURegister(regop));
data += PrintRightOperand(data);
} else if (f0byte == 0xBD) {
data += 2;
int mod, regop, rm;
......@@ -1272,9 +1298,8 @@ int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
data++;
int mod, regop, rm;
get_modrm(*data, &mod, &regop, &rm);
AppendToBuffer("xchg_w ");
AppendToBuffer("xchg_w %s,", NameOfCPURegister(regop));
data += PrintRightOperand(data);
AppendToBuffer(",%s", NameOfCPURegister(regop));
} else if (*data == 0x89) {
data++;
int mod, regop, rm;
......@@ -1513,6 +1538,9 @@ int DisassemblerX87::InstructionDecode(v8::internal::Vector<char> out_buffer,
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
} else if (*data == 0xB1) {
data++;
data += PrintOperands("cmpxchg_w", OPER_REG_OP_ORDER, data);
} else {
UnimplementedInstruction();
}
......
......@@ -395,12 +395,30 @@ TEST(DisasmIa320) {
// xchg.
{
__ xchg_b(eax, Operand(eax, 8));
__ xchg_w(eax, Operand(ebx, 8));
__ xchg(eax, eax);
__ xchg(eax, ebx);
__ xchg(ebx, ebx);
__ xchg(ebx, Operand(esp, 12));
}
// cmpxchg.
{
__ cmpxchg_b(Operand(esp, 12), eax);
__ cmpxchg_w(Operand(ebx, ecx, times_4, 10000), eax);
__ cmpxchg(Operand(ebx, ecx, times_4, 10000), eax);
}
// lock prefix.
{
__ lock();
__ cmpxchg(Operand(esp, 12), ebx);
__ lock();
__ xchg_w(eax, Operand(ecx, 8));
}
// Nop instructions
for (int i = 0; i < 16; i++) {
__ Nop(i);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment