Commit d18e118f authored by ulan@chromium.org's avatar ulan@chromium.org

ARM: Fix disassembly of some VFP instructions with condition codes

Previously, we would disassemble some VFP instructions like this:

  vmla.f64eq d16, d17, d18

This patch moves the condition to the right place:

  vmlaeq.f64 d16, d17, d18

Spotted by Rodolph Perfetta!

BUG=none

Review URL: https://chromiumcodereview.appspot.com/12335129
Patch from Hans Wennborg <hans@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13752 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 610d78cd
......@@ -1124,16 +1124,16 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
// vmov register to register.
if (instr->SzValue() == 0x1) {
Format(instr, "vmov.f64'cond 'Dd, 'Dm");
Format(instr, "vmov'cond.f64 'Dd, 'Dm");
} else {
Format(instr, "vmov.f32'cond 'Sd, 'Sm");
Format(instr, "vmov'cond.f32 'Sd, 'Sm");
}
} else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
// vabs
Format(instr, "vabs.f64'cond 'Dd, 'Dm");
Format(instr, "vabs'cond.f64 'Dd, 'Dm");
} else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
// vneg
Format(instr, "vneg.f64'cond 'Dd, 'Dm");
Format(instr, "vneg'cond.f64 'Dd, 'Dm");
} else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
DecodeVCVTBetweenDoubleAndSingle(instr);
} else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
......@@ -1145,10 +1145,10 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
(instr->Opc3Value() & 0x1)) {
DecodeVCMP(instr);
} else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
Format(instr, "vsqrt.f64'cond 'Dd, 'Dm");
Format(instr, "vsqrt'cond.f64 'Dd, 'Dm");
} else if (instr->Opc3Value() == 0x0) {
if (instr->SzValue() == 0x1) {
Format(instr, "vmov.f64'cond 'Dd, 'd");
Format(instr, "vmov'cond.f64 'Dd, 'd");
} else {
Unknown(instr); // Not used by V8.
}
......@@ -1158,34 +1158,34 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
} else if (instr->Opc1Value() == 0x3) {
if (instr->SzValue() == 0x1) {
if (instr->Opc3Value() & 0x1) {
Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm");
} else {
Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm");
}
} else {
Unknown(instr); // Not used by V8.
}
} else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
if (instr->SzValue() == 0x1) {
Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
}
} else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) {
if (instr->SzValue() == 0x1) {
Format(instr, "vmla.f64'cond 'Dd, 'Dn, 'Dm");
Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
}
} else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) {
if (instr->SzValue() == 0x1) {
Format(instr, "vmls.f64'cond 'Dd, 'Dn, 'Dm");
Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
}
} else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
if (instr->SzValue() == 0x1) {
Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm");
Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm");
} else {
Unknown(instr); // Not used by V8.
}
......@@ -1200,9 +1200,9 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
(instr->VCValue() == 0x1) &&
(instr->Bit(23) == 0x0)) {
if (instr->Bit(21) == 0x0) {
Format(instr, "vmov.32'cond 'Dd[0], 'rt");
Format(instr, "vmov'cond.32 'Dd[0], 'rt");
} else {
Format(instr, "vmov.32'cond 'Dd[1], 'rt");
Format(instr, "vmov'cond.32 'Dd[1], 'rt");
}
} else if ((instr->VCValue() == 0x0) &&
(instr->VAValue() == 0x7) &&
......@@ -1251,9 +1251,9 @@ void Decoder::DecodeVCMP(Instruction* instr) {
if (dp_operation && !raise_exception_for_qnan) {
if (instr->Opc2Value() == 0x4) {
Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
Format(instr, "vcmp'cond.f64 'Dd, 'Dm");
} else if (instr->Opc2Value() == 0x5) {
Format(instr, "vcmp.f64'cond 'Dd, #0.0");
Format(instr, "vcmp'cond.f64 'Dd, #0.0");
} else {
Unknown(instr); // invalid
}
......@@ -1270,9 +1270,9 @@ void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
bool double_to_single = (instr->SzValue() == 1);
if (double_to_single) {
Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm");
Format(instr, "vcvt'cond.f32.f64 'Sd, 'Dm");
} else {
Format(instr, "vcvt.f64.f32'cond 'Dd, 'Sm");
Format(instr, "vcvt'cond.f64.f32 'Dd, 'Sm");
}
}
......@@ -1289,15 +1289,15 @@ void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
if (dp_operation) {
if (unsigned_integer) {
Format(instr, "vcvt.u32.f64'cond 'Sd, 'Dm");
Format(instr, "vcvt'cond.u32.f64 'Sd, 'Dm");
} else {
Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm");
Format(instr, "vcvt'cond.s32.f64 'Sd, 'Dm");
}
} else {
if (unsigned_integer) {
Format(instr, "vcvt.u32.f32'cond 'Sd, 'Sm");
Format(instr, "vcvt'cond.u32.f32 'Sd, 'Sm");
} else {
Format(instr, "vcvt.s32.f32'cond 'Sd, 'Sm");
Format(instr, "vcvt'cond.s32.f32 'Sd, 'Sm");
}
}
} else {
......@@ -1305,15 +1305,15 @@ void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) {
if (dp_operation) {
if (unsigned_integer) {
Format(instr, "vcvt.f64.u32'cond 'Dd, 'Sm");
Format(instr, "vcvt'cond.f64.u32 'Dd, 'Sm");
} else {
Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm");
Format(instr, "vcvt'cond.f64.s32 'Dd, 'Sm");
}
} else {
if (unsigned_integer) {
Format(instr, "vcvt.f32.u32'cond 'Sd, 'Sm");
Format(instr, "vcvt'cond.f32.u32 'Sd, 'Sm");
} else {
Format(instr, "vcvt.f32.s32'cond 'Sd, 'Sm");
Format(instr, "vcvt'cond.f32.s32 'Sd, 'Sm");
}
}
}
......
......@@ -432,7 +432,7 @@ TEST(Vfp) {
COMPARE(vmov(d0, d1),
"eeb00b41 vmov.f64 d0, d1");
COMPARE(vmov(d3, d3, eq),
"0eb03b43 vmov.f64eq d3, d3");
"0eb03b43 vmoveq.f64 d3, d3");
COMPARE(vmov(s0, s31),
"eeb00a6f vmov.f32 s0, s31");
......@@ -450,32 +450,32 @@ TEST(Vfp) {
COMPARE(vabs(d0, d1),
"eeb00bc1 vabs.f64 d0, d1");
COMPARE(vabs(d3, d4, mi),
"4eb03bc4 vabs.f64mi d3, d4");
"4eb03bc4 vabsmi.f64 d3, d4");
COMPARE(vneg(d0, d1),
"eeb10b41 vneg.f64 d0, d1");
COMPARE(vneg(d3, d4, mi),
"4eb13b44 vneg.f64mi d3, d4");
"4eb13b44 vnegmi.f64 d3, d4");
COMPARE(vadd(d0, d1, d2),
"ee310b02 vadd.f64 d0, d1, d2");
COMPARE(vadd(d3, d4, d5, mi),
"4e343b05 vadd.f64mi d3, d4, d5");
"4e343b05 vaddmi.f64 d3, d4, d5");
COMPARE(vsub(d0, d1, d2),
"ee310b42 vsub.f64 d0, d1, d2");
COMPARE(vsub(d3, d4, d5, ne),
"1e343b45 vsub.f64ne d3, d4, d5");
"1e343b45 vsubne.f64 d3, d4, d5");
COMPARE(vmul(d2, d1, d0),
"ee212b00 vmul.f64 d2, d1, d0");
COMPARE(vmul(d6, d4, d5, cc),
"3e246b05 vmul.f64cc d6, d4, d5");
"3e246b05 vmulcc.f64 d6, d4, d5");
COMPARE(vdiv(d2, d2, d2),
"ee822b02 vdiv.f64 d2, d2, d2");
COMPARE(vdiv(d6, d7, d7, hi),
"8e876b07 vdiv.f64hi d6, d7, d7");
"8e876b07 vdivhi.f64 d6, d7, d7");
COMPARE(vcmp(d0, d1),
"eeb40b41 vcmp.f64 d0, d1");
......@@ -485,7 +485,7 @@ TEST(Vfp) {
COMPARE(vsqrt(d0, d0),
"eeb10bc0 vsqrt.f64 d0, d0");
COMPARE(vsqrt(d2, d3, ne),
"1eb12bc3 vsqrt.f64ne d2, d3");
"1eb12bc3 vsqrtne.f64 d2, d3");
COMPARE(vmov(d0, 1.0),
"eeb70b00 vmov.f64 d0, #1");
......@@ -565,12 +565,12 @@ TEST(Vfp) {
COMPARE(vmla(d2, d1, d0),
"ee012b00 vmla.f64 d2, d1, d0");
COMPARE(vmla(d6, d4, d5, cc),
"3e046b05 vmla.f64cc d6, d4, d5");
"3e046b05 vmlacc.f64 d6, d4, d5");
COMPARE(vmls(d2, d1, d0),
"ee012b40 vmls.f64 d2, d1, d0");
COMPARE(vmls(d6, d4, d5, cc),
"3e046b45 vmls.f64cc d6, d4, d5");
"3e046b45 vmlscc.f64 d6, d4, d5");
COMPARE(vcvt_u32_f64(s0, d0),
"eebc0bc0 vcvt.u32.f64 s0, d0");
......
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