ART: Vectorization opcode implementation fixes
This patch fixes the implementation of the x86 vectorization opcodes.
Change-Id: I0028d54a9fa6edce791b7e3a053002d076798748
Signed-off-by: Razvan A Lupusoru <razvan.a.lupusoru@intel.com>
Signed-off-by: Udayan Banerji <udayan.banerji@intel.com>
Signed-off-by: Philbert Lin <philbert.lin@intel.com>
diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc
index 7551add..1848abe 100644
--- a/disassembler/disassembler_x86.cc
+++ b/disassembler/disassembler_x86.cc
@@ -558,14 +558,19 @@
has_modrm = true;
src_reg_file = dst_reg_file = SSE;
break;
- case 0x62:
+ case 0x60: case 0x61: case 0x62: case 0x6C:
if (prefix[2] == 0x66) {
src_reg_file = dst_reg_file = SSE;
prefix[2] = 0; // Clear prefix now. It has served its purpose as part of the opcode.
} else {
src_reg_file = dst_reg_file = MMX;
}
- opcode << "punpckldq";
+ switch (*instr) {
+ case 0x60: opcode << "punpcklbw"; break;
+ case 0x61: opcode << "punpcklwd"; break;
+ case 0x62: opcode << "punpckldq"; break;
+ case 0x6c: opcode << "punpcklqdq"; break;
+ }
load = true;
has_modrm = true;
break;
@@ -650,7 +655,7 @@
} else {
dst_reg_file = MMX;
}
- static const char* x73_opcodes[] = {"unknown-73", "unknown-73", "psrlq", "unknown-73", "unknown-73", "unknown-73", "psllq", "unknown-73"};
+ static const char* x73_opcodes[] = {"unknown-73", "unknown-73", "psrlq", "psrldq", "unknown-73", "unknown-73", "psllq", "unknown-73"};
modrm_opcodes = x73_opcodes;
reg_is_opcode = true;
has_modrm = true;
@@ -800,6 +805,18 @@
opcode << "bswap";
reg_in_opcode = true;
break;
+ case 0xD4:
+ if (prefix[2] == 0x66) {
+ src_reg_file = dst_reg_file = SSE;
+ prefix[2] = 0;
+ } else {
+ src_reg_file = dst_reg_file = MMX;
+ }
+ opcode << "paddq";
+ prefix[2] = 0;
+ has_modrm = true;
+ load = true;
+ break;
case 0xDB:
if (prefix[2] == 0x66) {
src_reg_file = dst_reg_file = SSE;
@@ -847,66 +864,14 @@
has_modrm = true;
load = true;
break;
+ case 0xF4:
+ case 0xF6:
case 0xF8:
- if (prefix[2] == 0x66) {
- src_reg_file = dst_reg_file = SSE;
- prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode
- } else {
- src_reg_file = dst_reg_file = MMX;
- }
- opcode << "psubb";
- prefix[2] = 0;
- has_modrm = true;
- load = true;
- break;
case 0xF9:
- if (prefix[2] == 0x66) {
- src_reg_file = dst_reg_file = SSE;
- prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode
- } else {
- src_reg_file = dst_reg_file = MMX;
- }
- opcode << "psubw";
- prefix[2] = 0;
- has_modrm = true;
- load = true;
- break;
case 0xFA:
- if (prefix[2] == 0x66) {
- src_reg_file = dst_reg_file = SSE;
- prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode
- } else {
- src_reg_file = dst_reg_file = MMX;
- }
- opcode << "psubd";
- prefix[2] = 0;
- has_modrm = true;
- load = true;
- break;
+ case 0xFB:
case 0xFC:
- if (prefix[2] == 0x66) {
- src_reg_file = dst_reg_file = SSE;
- prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode
- } else {
- src_reg_file = dst_reg_file = MMX;
- }
- opcode << "paddb";
- prefix[2] = 0;
- has_modrm = true;
- load = true;
- break;
case 0xFD:
- if (prefix[2] == 0x66) {
- src_reg_file = dst_reg_file = SSE;
- prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode
- } else {
- src_reg_file = dst_reg_file = MMX;
- }
- opcode << "paddw";
- prefix[2] = 0;
- has_modrm = true;
- load = true;
- break;
case 0xFE:
if (prefix[2] == 0x66) {
src_reg_file = dst_reg_file = SSE;
@@ -914,7 +879,17 @@
} else {
src_reg_file = dst_reg_file = MMX;
}
- opcode << "paddd";
+ switch (*instr) {
+ case 0xF4: opcode << "pmuludq"; break;
+ case 0xF6: opcode << "psadbw"; break;
+ case 0xF8: opcode << "psubb"; break;
+ case 0xF9: opcode << "psubw"; break;
+ case 0xFA: opcode << "psubd"; break;
+ case 0xFB: opcode << "psubq"; break;
+ case 0xFC: opcode << "paddb"; break;
+ case 0xFD: opcode << "paddw"; break;
+ case 0xFE: opcode << "paddd"; break;
+ }
prefix[2] = 0;
has_modrm = true;
load = true;