| Index: src/mips64/simulator-mips64.cc
|
| diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
|
| index 3b2886498adc61ebd06540f00045eb14a019b49f..fba99aca83603fad5727c83db719ae2d30df56c9 100644
|
| --- a/src/mips64/simulator-mips64.cc
|
| +++ b/src/mips64/simulator-mips64.cc
|
| @@ -4485,20 +4485,107 @@ void Simulator::DecodeTypeMsaI8() {
|
| DCHECK(kArchVariant == kMips64r6);
|
| DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask;
|
| + int8_t i8 = instr_.MsaImm8Value() & 0xFFu;
|
|
|
| switch (opcode) {
|
| - case ANDI_B:
|
| - case ORI_B:
|
| - case NORI_B:
|
| - case XORI_B:
|
| - case BMNZI_B:
|
| - case BMZI_B:
|
| - case BSELI_B:
|
| - case SHF_B:
|
| - case SHF_H:
|
| - case SHF_W:
|
| - UNIMPLEMENTED();
|
| - break;
|
| + case ANDI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = ws[i] & i8;
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case ORI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = ws[i] | i8;
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case NORI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = ~(ws[i] | i8);
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case XORI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = ws[i] ^ i8;
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case BMNZI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = (ws[i] & i8) | (wd[i] & ~i8);
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case BMZI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = (ws[i] & ~i8) | (wd[i] & i8);
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case BSELI_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = (ws[i] & ~wd[i]) | (wd[i] & i8);
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case SHF_B: {
|
| + int8_t ws[16], wd[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 16; i++) {
|
| + int j = i % 4;
|
| + int k = (i8 >> (2 * j)) & 0x3;
|
| + wd[i] = ws[i - j + k];
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + } break;
|
| + case SHF_H: {
|
| + int16_t ws[8], wd[8];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 8; i++) {
|
| + int j = i % 4;
|
| + int k = (i8 >> (2 * j)) & 0x3;
|
| + wd[i] = ws[i - j + k];
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, HALF);
|
| + } break;
|
| + case SHF_W: {
|
| + int32_t ws[4], wd[4];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + for (int i = 0; i < 4; i++) {
|
| + int j = (i8 >> (2 * i)) & 0x3;
|
| + wd[i] = ws[j];
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, WORD);
|
| + } break;
|
| default:
|
| UNREACHABLE();
|
| }
|
| @@ -4586,9 +4673,54 @@ void Simulator::DecodeTypeMsaELM() {
|
| UNREACHABLE();
|
| }
|
| break;
|
| + case INSERT:
|
| + switch (DecodeMsaDataFormat()) {
|
| + case MSA_BYTE: {
|
| + DCHECK(n < 16);
|
| + int8_t wd[16];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + wd[n] = rs & 0xFFu;
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + break;
|
| + }
|
| + case MSA_HALF: {
|
| + DCHECK(n < 8);
|
| + int16_t wd[8];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + wd[n] = rs & 0xFFFFu;
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, HALF);
|
| + break;
|
| + }
|
| + case MSA_WORD: {
|
| + DCHECK(n < 4);
|
| + int32_t wd[4];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + wd[n] = rs & 0xFFFFFFFFu;
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, WORD);
|
| + break;
|
| + }
|
| + case MSA_DWORD: {
|
| + DCHECK(n < 2);
|
| + int64_t wd[2];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + get_msa_register(instr_.WdValue(), wd);
|
| + wd[n] = rs;
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, DWORD);
|
| + break;
|
| + }
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + break;
|
| case SLDI:
|
| case SPLATI:
|
| - case INSERT:
|
| case INSVE:
|
| UNIMPLEMENTED();
|
| break;
|
|
|