Add support for comisd and cmov in IA-32 disassembler.

Review URL: http://codereview.chromium.org/266014

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3040 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2009-10-08 13:28:46 +00:00
parent 830ba4e764
commit b9e7112d44
2 changed files with 58 additions and 0 deletions

View File

@ -124,6 +124,14 @@ static const char* set_conditional_mnem[] = {
};
static const char* conditional_move_mnem[] = {
/*0*/ "cmovo", "cmovno", "cmovc", "cmovnc",
/*4*/ "cmovz", "cmovnz", "cmovna", "cmova",
/*8*/ "cmovs", "cmovns", "cmovpe", "cmovpo",
/*12*/ "cmovl", "cmovnl", "cmovng", "cmovg"
};
enum InstructionType {
NO_INSTR,
ZERO_OPERANDS_INSTR,
@ -311,6 +319,7 @@ class DisassemblerIA32 {
int JumpConditional(byte* data, const char* comment);
int JumpConditionalShort(byte* data, const char* comment);
int SetCC(byte* data);
int CMov(byte* data);
int FPUInstruction(byte* data);
void AppendToBuffer(const char* format, ...);
@ -614,6 +623,16 @@ int DisassemblerIA32::SetCC(byte* data) {
}
// Returns number of bytes used, including *data.
int DisassemblerIA32::CMov(byte* data) {
assert(*data == 0x0F);
byte cond = *(data + 1) & 0x0F;
const char* mnem = conditional_move_mnem[cond];
int op_size = PrintOperands(mnem, REG_OPER_OP_ORDER, data + 2);
return 2 + op_size; // includes 0x0F
}
// Returns number of bytes used, including *data.
int DisassemblerIA32::FPUInstruction(byte* data) {
byte b1 = *data;
@ -861,6 +880,8 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
data += PrintOperands(f0mnem, REG_OPER_OP_ORDER, data);
} else if ((f0byte & 0xF0) == 0x90) {
data += SetCC(data);
} else if ((f0byte & 0xF0) == 0x40) {
data += CMov(data);
} else {
data += 2;
if (f0byte == 0xAB || f0byte == 0xA5 || f0byte == 0xAD) {
@ -956,6 +977,19 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
AppendToBuffer("mov_w ");
data += PrintRightOperand(data);
AppendToBuffer(",%s", NameOfCPURegister(regop));
} else if (*data == 0x0F) {
data++;
if (*data == 0x2F) {
data++;
int mod, regop, rm;
get_modrm(*data, &mod, &regop, &rm);
AppendToBuffer("comisd %s,%s",
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
} else {
UnimplementedInstruction();
}
} else {
UnimplementedInstruction();
}

View File

@ -363,7 +363,31 @@ TEST(DisasmIa320) {
__ divsd(xmm1, xmm0);
__ movdbl(xmm1, Operand(ebx, ecx, times_4, 10000));
__ movdbl(Operand(ebx, ecx, times_4, 10000), xmm1);
__ comisd(xmm0, xmm1);
}
// cmov.
{
CHECK(CpuFeatures::IsSupported(CpuFeatures::CMOV));
CpuFeatures::Scope use_cmov(CpuFeatures::CMOV);
__ cmov(overflow, eax, Operand(eax, 0));
__ cmov(no_overflow, eax, Operand(eax, 1));
__ cmov(below, eax, Operand(eax, 2));
__ cmov(above_equal, eax, Operand(eax, 3));
__ cmov(equal, eax, Operand(ebx, 0));
__ cmov(not_equal, eax, Operand(ebx, 1));
__ cmov(below_equal, eax, Operand(ebx, 2));
__ cmov(above, eax, Operand(ebx, 3));
__ cmov(sign, eax, Operand(ecx, 0));
__ cmov(not_sign, eax, Operand(ecx, 1));
__ cmov(parity_even, eax, Operand(ecx, 2));
__ cmov(parity_odd, eax, Operand(ecx, 3));
__ cmov(less, eax, Operand(edx, 0));
__ cmov(greater_equal, eax, Operand(edx, 1));
__ cmov(less_equal, eax, Operand(edx, 2));
__ cmov(greater, eax, Operand(edx, 3));
}
__ ret(0);
CodeDesc desc;