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