Index: src/mips64/simulator-mips64.cc |
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc |
index c0a1e6e868f1624ffd799dff81e2d8ca4384b130..320b97296aed7ceb3e1a5adc2c29b3d3d3f29a2b 100644 |
--- a/src/mips64/simulator-mips64.cc |
+++ b/src/mips64/simulator-mips64.cc |
@@ -4037,73 +4037,101 @@ void Simulator::DecodeTypeRegisterSPECIAL2() { |
void Simulator::DecodeTypeRegisterSPECIAL3() { |
int64_t alu_out; |
switch (instr_.FunctionFieldRaw()) { |
- case INS: { // Mips64r2 instruction. |
- // Interpret rd field as 5-bit msb of insert. |
- uint16_t msb = rd_reg(); |
- // Interpret sa field as 5-bit lsb of insert. |
- uint16_t lsb = sa(); |
- uint16_t size = msb - lsb + 1; |
- uint64_t mask = (1ULL << size) - 1; |
- alu_out = static_cast<int32_t>((rt_u() & ~(mask << lsb)) | |
- ((rs_u() & mask) << lsb)); |
- SetResult(rt_reg(), alu_out); |
- break; |
- } |
- case DINS: { // Mips64r2 instruction. |
- // Interpret rd field as 5-bit msb of insert. |
- uint16_t msb = rd_reg(); |
- // Interpret sa field as 5-bit lsb of insert. |
- uint16_t lsb = sa(); |
- uint16_t size = msb - lsb + 1; |
- uint64_t mask = (1ULL << size) - 1; |
- alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb); |
- SetResult(rt_reg(), alu_out); |
- break; |
- } |
- case EXT: { // Mips64r2 instruction. |
- // Interpret rd field as 5-bit msb of extract. |
- uint16_t msb = rd_reg(); |
+ case EXT: { // Mips32r2 instruction. |
+ // Interpret rd field as 5-bit msbd of extract. |
+ uint16_t msbd = rd_reg(); |
// Interpret sa field as 5-bit lsb of extract. |
uint16_t lsb = sa(); |
- uint16_t size = msb + 1; |
+ uint16_t size = msbd + 1; |
uint64_t mask = (1ULL << size) - 1; |
alu_out = static_cast<int32_t>((rs_u() & (mask << lsb)) >> lsb); |
SetResult(rt_reg(), alu_out); |
break; |
} |
case DEXT: { // Mips64r2 instruction. |
- // Interpret rd field as 5-bit msb of extract. |
- uint16_t msb = rd_reg(); |
+ // Interpret rd field as 5-bit msbd of extract. |
+ uint16_t msbd = rd_reg(); |
// Interpret sa field as 5-bit lsb of extract. |
uint16_t lsb = sa(); |
- uint16_t size = msb + 1; |
+ uint16_t size = msbd + 1; |
uint64_t mask = (size == 64) ? UINT64_MAX : (1ULL << size) - 1; |
alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb); |
SetResult(rt_reg(), alu_out); |
break; |
} |
case DEXTM: { |
- // Interpret rd field as 5-bit msb of extract. |
- uint16_t msb = rd_reg(); |
+ // Interpret rd field as 5-bit msbdminus32 of extract. |
+ uint16_t msbdminus32 = rd_reg(); |
// Interpret sa field as 5-bit lsb of extract. |
uint16_t lsb = sa(); |
- uint16_t size = msb + 33; |
+ uint16_t size = msbdminus32 + 1 + 32; |
uint64_t mask = (size == 64) ? UINT64_MAX : (1ULL << size) - 1; |
alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb); |
SetResult(rt_reg(), alu_out); |
break; |
} |
case DEXTU: { |
- // Interpret rd field as 5-bit msb of extract. |
- uint16_t msb = rd_reg(); |
- // Interpret sa field as 5-bit lsb of extract. |
+ // Interpret rd field as 5-bit msbd of extract. |
+ uint16_t msbd = rd_reg(); |
+ // Interpret sa field as 5-bit lsbminus32 of extract and add 32 to get |
+ // lsb. |
uint16_t lsb = sa() + 32; |
- uint16_t size = msb + 1; |
+ uint16_t size = msbd + 1; |
uint64_t mask = (size == 64) ? UINT64_MAX : (1ULL << size) - 1; |
alu_out = static_cast<int64_t>((rs_u() & (mask << lsb)) >> lsb); |
SetResult(rt_reg(), alu_out); |
break; |
} |
+ case INS: { // Mips32r2 instruction. |
+ // Interpret rd field as 5-bit msb of insert. |
+ uint16_t msb = rd_reg(); |
+ // Interpret sa field as 5-bit lsb of insert. |
+ uint16_t lsb = sa(); |
+ uint16_t size = msb - lsb + 1; |
+ uint64_t mask = (1ULL << size) - 1; |
+ alu_out = static_cast<int32_t>((rt_u() & ~(mask << lsb)) | |
+ ((rs_u() & mask) << lsb)); |
+ SetResult(rt_reg(), alu_out); |
+ break; |
+ } |
+ case DINS: { // Mips64r2 instruction. |
+ // Interpret rd field as 5-bit msb of insert. |
+ uint16_t msb = rd_reg(); |
+ // Interpret sa field as 5-bit lsb of insert. |
+ uint16_t lsb = sa(); |
+ uint16_t size = msb - lsb + 1; |
+ uint64_t mask = (1ULL << size) - 1; |
+ alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb); |
+ SetResult(rt_reg(), alu_out); |
+ break; |
+ } |
+ case DINSM: { // Mips64r2 instruction. |
+ // Interpret rd field as 5-bit msbminus32 of insert. |
+ uint16_t msbminus32 = rd_reg(); |
+ // Interpret sa field as 5-bit lsb of insert. |
+ uint16_t lsb = sa(); |
+ uint16_t size = msbminus32 + 32 - lsb + 1; |
+ uint64_t mask; |
+ if (size < 64) |
+ mask = (1ULL << size) - 1; |
+ else |
+ mask = std::numeric_limits<uint64_t>::max(); |
+ alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb); |
+ SetResult(rt_reg(), alu_out); |
+ break; |
+ } |
+ case DINSU: { // Mips64r2 instruction. |
+ // Interpret rd field as 5-bit msbminus32 of insert. |
+ uint16_t msbminus32 = rd_reg(); |
+ // Interpret rd field as 5-bit lsbminus32 of insert. |
+ uint16_t lsbminus32 = sa(); |
+ uint16_t lsb = lsbminus32 + 32; |
+ uint16_t size = msbminus32 + 32 - lsb + 1; |
+ uint64_t mask = (1ULL << size) - 1; |
+ alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb); |
+ SetResult(rt_reg(), alu_out); |
+ break; |
+ } |
case BSHFL: { |
int32_t sa = instr_.SaFieldRaw() >> kSaShift; |
switch (sa) { |