| 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) {
|
|
|