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:
parent
830ba4e764
commit
b9e7112d44
@ -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, ®op, &rm);
|
||||
AppendToBuffer("comisd %s,%s",
|
||||
NameOfXMMRegister(regop),
|
||||
NameOfXMMRegister(rm));
|
||||
data++;
|
||||
} else {
|
||||
UnimplementedInstruction();
|
||||
}
|
||||
} else {
|
||||
UnimplementedInstruction();
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user