| Index: runtime/vm/disassembler_arm64.cc
|
| ===================================================================
|
| --- runtime/vm/disassembler_arm64.cc (revision 36461)
|
| +++ runtime/vm/disassembler_arm64.cc (working copy)
|
| @@ -353,9 +353,29 @@
|
| }
|
| }
|
| case 'c': {
|
| - ASSERT(STRING_STARTS_WITH(format, "cond"));
|
| - PrintCondition(instr);
|
| - return 4;
|
| + if (format[1] == 's') {
|
| + ASSERT(STRING_STARTS_WITH(format, "csz"));
|
| + const int32_t imm5 = instr->Bits(16, 5);
|
| + char const* typ = "??";
|
| + if (imm5 & 0x1) {
|
| + typ = "b";
|
| + } else if (imm5 & 0x2) {
|
| + typ = "h";
|
| + } else if (imm5 & 0x4) {
|
| + typ = "s";
|
| + } else if (imm5 & 0x8) {
|
| + typ = "d";
|
| + }
|
| + buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
| + remaining_size_in_buffer(),
|
| + "%s",
|
| + typ);
|
| + return 3;
|
| + } else {
|
| + ASSERT(STRING_STARTS_WITH(format, "cond"));
|
| + PrintCondition(instr);
|
| + return 4;
|
| + }
|
| }
|
| case 'd': {
|
| if (format[4] == '2') {
|
| @@ -422,7 +442,35 @@
|
| return 2;
|
| }
|
| case 'i': { // 'imm12, 'imm16, 'immd
|
| - if (format[3] == '1') {
|
| + if (format[1] == 'd') {
|
| + // Element index for a SIMD copy instruction.
|
| + ASSERT(STRING_STARTS_WITH(format, "idx"));
|
| + const int32_t imm4 = instr->Bits(11, 4);
|
| + const int32_t imm5 = instr->Bits(16, 5);
|
| + int32_t shift = 0;
|
| + int32_t imm = -1;
|
| + if (format[3] == '4') {
|
| + imm = imm4;
|
| + } else if (format[3] == '5') {
|
| + imm = imm5;
|
| + shift = 1;
|
| + }
|
| + int32_t idx = -1;
|
| + if (imm5 & 0x1) {
|
| + idx = imm >> shift;
|
| + } else if (imm5 & 0x2) {
|
| + idx = imm >> (shift + 1);
|
| + } else if (imm5 & 0x4) {
|
| + idx = imm >> (shift + 2);
|
| + } else if (imm5 & 0x8) {
|
| + idx = imm >> (shift + 3);
|
| + }
|
| + buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
| + remaining_size_in_buffer(),
|
| + "[%d]",
|
| + idx);
|
| + return 4;
|
| + } else if (format[3] == '1') {
|
| uint64_t imm;
|
| int ret = 5;
|
| if (format[4] == '2') {
|
| @@ -490,7 +538,22 @@
|
| return FormatRegister(instr, format);
|
| }
|
| case 'v': {
|
| - return FormatVRegister(instr, format);
|
| + if (format[1] == 's') {
|
| + ASSERT(STRING_STARTS_WITH(format, "vsz"));
|
| + char const* sz_str;
|
| + if (instr->Bit(22) == 0) {
|
| + sz_str = "f32";
|
| + } else {
|
| + sz_str = "f64";
|
| + }
|
| + buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
|
| + remaining_size_in_buffer(),
|
| + "%s",
|
| + sz_str);
|
| + return 3;
|
| + } else {
|
| + return FormatVRegister(instr, format);
|
| + }
|
| }
|
| case 's': { // 's: S flag.
|
| if (format[1] == 'h') {
|
| @@ -960,8 +1023,55 @@
|
| }
|
|
|
|
|
| +void ARM64Decoder::DecodeSIMDCopy(Instr* instr) {
|
| + const int32_t Q = instr->Bit(30);
|
| + const int32_t op = instr->Bit(29);
|
| + const int32_t imm4 = instr->Bits(11, 4);
|
| +
|
| + if ((Q == 1) && (op == 0) && (imm4 == 0)) {
|
| + Format(instr, "vdup'csz 'vd, 'vn'idx5");
|
| + } else if ((Q == 1) && (op == 1)) {
|
| + Format(instr, "vins'csz 'vd'idx5, 'vn'idx4");
|
| + } else {
|
| + Unknown(instr);
|
| + }
|
| +}
|
| +
|
| +
|
| +void ARM64Decoder::DecodeSIMDThreeSame(Instr* instr) {
|
| + const int32_t Q = instr->Bit(30);
|
| + const int32_t U = instr->Bit(29);
|
| + const int32_t opcode = instr->Bits(11, 5);
|
| +
|
| + if (Q == 0) {
|
| + Unknown(instr);
|
| + return;
|
| + }
|
| +
|
| + if ((U == 0) && (opcode == 0x1a)) {
|
| + if (instr->Bit(23) == 0) {
|
| + Format(instr, "vadd'vsz 'vd, 'vn, 'vm");
|
| + } else {
|
| + Format(instr, "vsub'vsz 'vd, 'vn, 'vm");
|
| + }
|
| + } else if ((U == 1) && (opcode == 0x1b)) {
|
| + Format(instr, "vmul'vsz 'vd, 'vn, 'vm");
|
| + } else if ((U == 1) && (opcode == 0x1f)) {
|
| + Format(instr, "vdiv'vsz 'vd, 'vn, 'vm");
|
| + } else {
|
| + Unknown(instr);
|
| + }
|
| +}
|
| +
|
| +
|
| void ARM64Decoder::DecodeDPSimd1(Instr* instr) {
|
| - Unknown(instr);
|
| + if (instr->IsSIMDCopyOp()) {
|
| + DecodeSIMDCopy(instr);
|
| + } else if (instr->IsSIMDThreeSameOp()) {
|
| + DecodeSIMDThreeSame(instr);
|
| + } else {
|
| + Unknown(instr);
|
| + }
|
| }
|
|
|
|
|
|
|