| Index: src/mips64/simulator-mips64.cc
|
| diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
|
| index ebccc7dc7fcee2c3e2966de28a706a0fd3c8754c..28c1f10704c46046201b59cc897d744c5dda16c7 100644
|
| --- a/src/mips64/simulator-mips64.cc
|
| +++ b/src/mips64/simulator-mips64.cc
|
| @@ -3977,12 +3977,48 @@ void Simulator::DecodeTypeRegisterSPECIAL3() {
|
| alu_out = static_cast<int64_t>(static_cast<int32_t>(output));
|
| break;
|
| }
|
| - case SEB:
|
| - case SEH:
|
| - case WSBH:
|
| - alu_out = 0x12345678;
|
| - UNREACHABLE();
|
| + case SEB: {
|
| + int8_t input = static_cast<int8_t>(rt());
|
| + int32_t output = 0x000000FF & input;
|
| + int32_t mask = 0x00000080;
|
| +
|
| + if (mask & input) output += 0xFFFFFF00;
|
| +
|
| + alu_out = static_cast<int32_t>(output);
|
| + break;
|
| + }
|
| + case SEH: {
|
| + int16_t input = static_cast<int16_t>(rt());
|
| + int32_t output = 0x0000FFFF & input;
|
| + int32_t mask = 0x00008000;
|
| +
|
| + if (mask & input) output += 0xFFFF0000;
|
| +
|
| + alu_out = static_cast<int32_t>(output);
|
| + break;
|
| + }
|
| + case WSBH: {
|
| + int32_t input = static_cast<int32_t>(rt());
|
| + int32_t output = 0;
|
| +
|
| + uint32_t mask = 0xFF000000;
|
| + for (int i = 0; i < 4; i++) {
|
| + uint32_t tmp = mask & input;
|
| + if (i % 2 == 0) {
|
| + tmp = tmp >> 8;
|
| + } else {
|
| + tmp = tmp << 8;
|
| + }
|
| + output = output | tmp;
|
| + mask = mask >> 8;
|
| + }
|
| + mask = 0x80000000;
|
| +
|
| + if (mask & output) output += 0XFFFFFFFF00000000;
|
| +
|
| + alu_out = static_cast<int64_t>(output);
|
| break;
|
| + }
|
| default: {
|
| const uint8_t bp2 = get_instr()->Bp2Value();
|
| sa >>= kBp2Bits;
|
| @@ -4041,11 +4077,47 @@ void Simulator::DecodeTypeRegisterSPECIAL3() {
|
| }
|
| break;
|
| }
|
| - case DSBH:
|
| - case DSHD:
|
| - alu_out = 0x12345678;
|
| - UNREACHABLE();
|
| + case DSBH: {
|
| + int64_t input = static_cast<int64_t>(rt());
|
| + int64_t output = 0;
|
| +
|
| + uint64_t mask = 0xFF00000000000000;
|
| + for (int i = 0; i < 8; i++) {
|
| + uint64_t tmp = mask & input;
|
| + if (i % 2 == 0)
|
| + tmp = tmp >> 8;
|
| + else
|
| + tmp = tmp << 8;
|
| +
|
| + output = output | tmp;
|
| + mask = mask >> 8;
|
| + }
|
| +
|
| + alu_out = static_cast<int64_t>(output);
|
| break;
|
| + }
|
| + case DSHD: {
|
| + int64_t input = static_cast<int64_t>(rt());
|
| + int64_t output = 0;
|
| +
|
| + uint64_t mask = 0xFFFF000000000000;
|
| + for (int i = 0; i < 4; i++) {
|
| + uint64_t tmp = mask & input;
|
| + if (i == 0)
|
| + tmp = tmp >> 48;
|
| + else if (i == 1)
|
| + tmp = tmp >> 16;
|
| + else if (i == 2)
|
| + tmp = tmp << 16;
|
| + else
|
| + tmp = tmp << 48;
|
| + output = output | tmp;
|
| + mask = mask >> 16;
|
| + }
|
| +
|
| + alu_out = static_cast<int64_t>(output);
|
| + break;
|
| + }
|
| default: {
|
| const uint8_t bp3 = get_instr()->Bp3Value();
|
| sa >>= kBp3Bits;
|
| @@ -4095,31 +4167,7 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
|
| DecodeTypeRegisterSPECIAL2();
|
| break;
|
| case SPECIAL3:
|
| - switch (instr->FunctionFieldRaw()) {
|
| - case BSHFL: {
|
| - int32_t saVal = sa();
|
| - saVal >>= kBp2Bits;
|
| - switch (saVal) {
|
| - case ALIGN: {
|
| - DecodeTypeRegisterSPECIAL3();
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - case DBSHFL: {
|
| - int32_t saVal = sa();
|
| - saVal >>= kBp2Bits;
|
| - switch (saVal) {
|
| - case DALIGN: {
|
| - DecodeTypeRegisterSPECIAL3();
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - default:
|
| - DecodeTypeRegisterSPECIAL3();
|
| - break;
|
| - }
|
| + DecodeTypeRegisterSPECIAL3();
|
| break;
|
| // Unimplemented opcodes raised an error in the configuration step before,
|
| // so we can use the default here to set the destination register in common
|
|
|