Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: src/arm/disasm-arm.cc

Issue 17858002: ARM: Implement memcpy using NEON. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove "unaligned accesses" from C++ code Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 int FormatVFPinstruction(Instruction* instr, const char* format); 106 int FormatVFPinstruction(Instruction* instr, const char* format);
107 void PrintCondition(Instruction* instr); 107 void PrintCondition(Instruction* instr);
108 void PrintShiftRm(Instruction* instr); 108 void PrintShiftRm(Instruction* instr);
109 void PrintShiftImm(Instruction* instr); 109 void PrintShiftImm(Instruction* instr);
110 void PrintShiftSat(Instruction* instr); 110 void PrintShiftSat(Instruction* instr);
111 void PrintPU(Instruction* instr); 111 void PrintPU(Instruction* instr);
112 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc); 112 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
113 113
114 // Handle formatting of instructions and their options. 114 // Handle formatting of instructions and their options.
115 int FormatRegister(Instruction* instr, const char* option); 115 int FormatRegister(Instruction* instr, const char* option);
116 void FormatNeonList(int Vd, int type);
117 void FormatNeonMemory(int Rn, int align, int Rm);
116 int FormatOption(Instruction* instr, const char* option); 118 int FormatOption(Instruction* instr, const char* option);
117 void Format(Instruction* instr, const char* format); 119 void Format(Instruction* instr, const char* format);
118 void Unknown(Instruction* instr); 120 void Unknown(Instruction* instr);
119 121
120 // Each of these functions decodes one particular instruction type, a 3-bit 122 // Each of these functions decodes one particular instruction type, a 3-bit
121 // field in the instruction encoding. 123 // field in the instruction encoding.
122 // Types 0 and 1 are combined as they are largely the same except for the way 124 // Types 0 and 1 are combined as they are largely the same except for the way
123 // they interpret the shifter operand. 125 // they interpret the shifter operand.
124 void DecodeType01(Instruction* instr); 126 void DecodeType01(Instruction* instr);
125 void DecodeType2(Instruction* instr); 127 void DecodeType2(Instruction* instr);
126 void DecodeType3(Instruction* instr); 128 void DecodeType3(Instruction* instr);
127 void DecodeType4(Instruction* instr); 129 void DecodeType4(Instruction* instr);
128 void DecodeType5(Instruction* instr); 130 void DecodeType5(Instruction* instr);
129 void DecodeType6(Instruction* instr); 131 void DecodeType6(Instruction* instr);
130 // Type 7 includes special Debugger instructions. 132 // Type 7 includes special Debugger instructions.
131 int DecodeType7(Instruction* instr); 133 int DecodeType7(Instruction* instr);
132 // For VFP support. 134 // For VFP support.
133 void DecodeTypeVFP(Instruction* instr); 135 void DecodeTypeVFP(Instruction* instr);
134 void DecodeType6CoprocessorIns(Instruction* instr); 136 void DecodeType6CoprocessorIns(Instruction* instr);
135 137
138 void DecodeSpecialCondition(Instruction* instr);
139
136 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); 140 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr);
137 void DecodeVCMP(Instruction* instr); 141 void DecodeVCMP(Instruction* instr);
138 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); 142 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr);
139 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); 143 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr);
140 144
141 const disasm::NameConverter& converter_; 145 const disasm::NameConverter& converter_;
142 Vector<char> out_buffer_; 146 Vector<char> out_buffer_;
143 int out_buffer_pos_; 147 int out_buffer_pos_;
144 148
145 DISALLOW_COPY_AND_ASSIGN(Decoder); 149 DISALLOW_COPY_AND_ASSIGN(Decoder);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 return retval; 414 return retval;
411 } 415 }
412 416
413 417
414 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) { 418 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) {
415 Print(format); 419 Print(format);
416 return 0; 420 return 0;
417 } 421 }
418 422
419 423
424 void Decoder::FormatNeonList(int Vd, int type) {
425 if (type == nlt_1) {
426 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
427 "{d%d}", Vd);
428 } else if (type == nlt_2) {
429 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
430 "{d%d, d%d}", Vd, Vd + 1);
431 } else if (type == nlt_3) {
432 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
433 "{d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2);
434 } else if (type == nlt_4) {
435 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
436 "{d%d, d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2, Vd + 3);
437 }
438 }
439
440
441 void Decoder::FormatNeonMemory(int Rn, int align, int Rm) {
442 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
443 "[r%d", Rn);
444 if (align != 0) {
445 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
446 ":%d", (1 << align) << 6);
447 }
448 if (Rm == 15) {
449 Print("]");
450 } else if (Rm == 13) {
451 Print("]!");
452 } else {
453 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
454 "], r%d", Rm);
455 }
456 }
457
458
420 // Print the movw or movt instruction. 459 // Print the movw or movt instruction.
421 void Decoder::PrintMovwMovt(Instruction* instr) { 460 void Decoder::PrintMovwMovt(Instruction* instr) {
422 int imm = instr->ImmedMovwMovtValue(); 461 int imm = instr->ImmedMovwMovtValue();
423 int rd = instr->RdValue(); 462 int rd = instr->RdValue();
424 PrintRegister(rd); 463 PrintRegister(rd);
425 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, 464 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
426 ", #%d", imm); 465 ", #%d", imm);
427 } 466 }
428 467
429 468
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 1012
974 1013
975 void Decoder::DecodeType3(Instruction* instr) { 1014 void Decoder::DecodeType3(Instruction* instr) {
976 switch (instr->PUField()) { 1015 switch (instr->PUField()) {
977 case da_x: { 1016 case da_x: {
978 VERIFY(!instr->HasW()); 1017 VERIFY(!instr->HasW());
979 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); 1018 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
980 break; 1019 break;
981 } 1020 }
982 case ia_x: { 1021 case ia_x: {
983 if (instr->HasW()) { 1022 if (instr->Bit(4) == 0) {
984 VERIFY(instr->Bits(5, 4) == 0x1); 1023 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
985 if (instr->Bit(22) == 0x1) { 1024 } else {
986 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat"); 1025 if (instr->Bit(5) == 0) {
1026 switch (instr->Bits(22, 21)) {
1027 case 0:
1028 if (instr->Bit(20) == 0) {
1029 if (instr->Bit(6) == 0) {
1030 Format(instr, "pkhbt'cond 'rd, 'rn, 'rm, lsl #'imm05@07");
1031 } else {
1032 if (instr->Bits(11, 7) == 0) {
1033 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #32");
1034 } else {
1035 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #'imm05@07");
1036 }
1037 }
1038 } else {
1039 UNREACHABLE();
1040 }
1041 break;
1042 case 1:
1043 UNREACHABLE();
1044 break;
1045 case 2:
1046 UNREACHABLE();
1047 break;
1048 case 3:
1049 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat");
1050 break;
1051 }
987 } else { 1052 } else {
988 UNREACHABLE(); // SSAT. 1053 switch (instr->Bits(22, 21)) {
1054 case 0:
1055 UNREACHABLE();
1056 break;
1057 case 1:
1058 UNREACHABLE();
1059 break;
1060 case 2:
1061 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
1062 if (instr->Bits(19, 16) == 0xF) {
1063 switch (instr->Bits(11, 10)) {
1064 case 0:
1065 Format(instr, "uxtb16'cond 'rd, 'rm, ror #0");
1066 break;
1067 case 1:
1068 Format(instr, "uxtb16'cond 'rd, 'rm, ror #8");
1069 break;
1070 case 2:
1071 Format(instr, "uxtb16'cond 'rd, 'rm, ror #16");
1072 break;
1073 case 3:
1074 Format(instr, "uxtb16'cond 'rd, 'rm, ror #24");
1075 break;
1076 }
1077 } else {
1078 UNREACHABLE();
1079 }
1080 } else {
1081 UNREACHABLE();
1082 }
1083 break;
1084 case 3:
1085 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
1086 if (instr->Bits(19, 16) == 0xF) {
1087 switch (instr->Bits(11, 10)) {
1088 case 0:
1089 Format(instr, "uxtb'cond 'rd, 'rm, ror #0");
1090 break;
1091 case 1:
1092 Format(instr, "uxtb'cond 'rd, 'rm, ror #8");
1093 break;
1094 case 2:
1095 Format(instr, "uxtb'cond 'rd, 'rm, ror #16");
1096 break;
1097 case 3:
1098 Format(instr, "uxtb'cond 'rd, 'rm, ror #24");
1099 break;
1100 }
1101 } else {
1102 switch (instr->Bits(11, 10)) {
1103 case 0:
1104 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #0");
1105 break;
1106 case 1:
1107 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8");
1108 break;
1109 case 2:
1110 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16");
1111 break;
1112 case 3:
1113 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24");
1114 break;
1115 }
1116 }
1117 } else {
1118 UNREACHABLE();
1119 }
1120 break;
1121 }
989 } 1122 }
990 } else {
991 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
992 } 1123 }
993 break; 1124 break;
994 } 1125 }
995 case db_x: { 1126 case db_x: {
996 if (FLAG_enable_sudiv) { 1127 if (FLAG_enable_sudiv) {
997 if (!instr->HasW()) { 1128 if (!instr->HasW()) {
998 if (instr->Bits(5, 4) == 0x1) { 1129 if (instr->Bits(5, 4) == 0x1) {
999 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { 1130 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
1000 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs 1131 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs
1001 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs"); 1132 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs");
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 break; 1545 break;
1415 } 1546 }
1416 default: 1547 default:
1417 Unknown(instr); // Not used by V8. 1548 Unknown(instr); // Not used by V8.
1418 } 1549 }
1419 } else { 1550 } else {
1420 Unknown(instr); // Not used by V8. 1551 Unknown(instr); // Not used by V8.
1421 } 1552 }
1422 } 1553 }
1423 1554
1555 void Decoder::DecodeSpecialCondition(Instruction* instr) {
1556 switch (instr->SpecialValue()) {
1557 case 5:
1558 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
1559 (instr->Bit(4) == 1)) {
1560 // vmovl signed
1561 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1562 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
1563 int imm3 = instr->Bits(21, 19);
1564 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1565 "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm);
1566 } else {
1567 Unknown(instr);
1568 }
1569 break;
1570 case 7:
1571 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
1572 (instr->Bit(4) == 1)) {
1573 // vmovl unsigned
1574 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1575 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
1576 int imm3 = instr->Bits(21, 19);
1577 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1578 "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm);
1579 } else {
1580 Unknown(instr);
1581 }
1582 break;
1583 case 8:
1584 if (instr->Bits(21, 20) == 0) {
1585 // vst1
1586 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1587 int Rn = instr->VnValue();
1588 int type = instr->Bits(11, 8);
1589 int size = instr->Bits(7, 6);
1590 int align = instr->Bits(5, 4);
1591 int Rm = instr->VmValue();
1592 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1593 "vst1.%d ", (1 << size) << 3);
1594 FormatNeonList(Vd, type);
1595 Print(", ");
1596 FormatNeonMemory(Rn, align, Rm);
1597 } else if (instr->Bits(21, 20) == 2) {
1598 // vld1
1599 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1600 int Rn = instr->VnValue();
1601 int type = instr->Bits(11, 8);
1602 int size = instr->Bits(7, 6);
1603 int align = instr->Bits(5, 4);
1604 int Rm = instr->VmValue();
1605 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1606 "vld1.%d ", (1 << size) << 3);
1607 FormatNeonList(Vd, type);
1608 Print(", ");
1609 FormatNeonMemory(Rn, align, Rm);
1610 } else {
1611 Unknown(instr);
1612 }
1613 break;
1614 case 0xA:
1615 case 0xB:
1616 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) {
1617 int Rn = instr->Bits(19, 16);
1618 int offset = instr->Bits(11, 0);
1619 if (offset == 0) {
1620 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1621 "pld [r%d]", Rn);
1622 } else if (instr->Bit(23) == 0) {
1623 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1624 "pld [r%d, #-%d]", Rn, offset);
1625 } else {
1626 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1627 "pld [r%d, #+%d]", Rn, offset);
1628 }
1629 } else {
1630 Unknown(instr);
1631 }
1632 break;
1633 default:
1634 Unknown(instr);
1635 break;
1636 }
1637 }
1638
1424 #undef VERIFIY 1639 #undef VERIFIY
1425 1640
1426 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { 1641 bool Decoder::IsConstantPoolAt(byte* instr_ptr) {
1427 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); 1642 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
1428 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; 1643 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker;
1429 } 1644 }
1430 1645
1431 1646
1432 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { 1647 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) {
1433 if (IsConstantPoolAt(instr_ptr)) { 1648 if (IsConstantPoolAt(instr_ptr)) {
1434 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); 1649 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
1435 return DecodeConstantPoolLength(instruction_bits); 1650 return DecodeConstantPoolLength(instruction_bits);
1436 } else { 1651 } else {
1437 return -1; 1652 return -1;
1438 } 1653 }
1439 } 1654 }
1440 1655
1441 1656
1442 // Disassemble the instruction at *instr_ptr into the output buffer. 1657 // Disassemble the instruction at *instr_ptr into the output buffer.
1443 int Decoder::InstructionDecode(byte* instr_ptr) { 1658 int Decoder::InstructionDecode(byte* instr_ptr) {
1444 Instruction* instr = Instruction::At(instr_ptr); 1659 Instruction* instr = Instruction::At(instr_ptr);
1445 // Print raw instruction bytes. 1660 // Print raw instruction bytes.
1446 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, 1661 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1447 "%08x ", 1662 "%08x ",
1448 instr->InstructionBits()); 1663 instr->InstructionBits());
1449 if (instr->ConditionField() == kSpecialCondition) { 1664 if (instr->ConditionField() == kSpecialCondition) {
1450 Unknown(instr); 1665 DecodeSpecialCondition(instr);
1451 return Instruction::kInstrSize; 1666 return Instruction::kInstrSize;
1452 } 1667 }
1453 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); 1668 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
1454 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { 1669 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) {
1455 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, 1670 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
1456 "constant pool begin (length %d)", 1671 "constant pool begin (length %d)",
1457 DecodeConstantPoolLength(instruction_bits)); 1672 DecodeConstantPoolLength(instruction_bits));
1458 return Instruction::kInstrSize; 1673 return Instruction::kInstrSize;
1459 } 1674 }
1460 switch (instr->TypeValue()) { 1675 switch (instr->TypeValue()) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1572 v8::internal::PrintF( 1787 v8::internal::PrintF(
1573 f, "%p %08x %s\n", 1788 f, "%p %08x %s\n",
1574 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1789 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1575 } 1790 }
1576 } 1791 }
1577 1792
1578 1793
1579 } // namespace disasm 1794 } // namespace disasm
1580 1795
1581 #endif // V8_TARGET_ARCH_ARM 1796 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698