Chromium Code Reviews| Index: src/mips/simulator-mips.cc |
| diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc |
| index 9526f28e0510f6637492f1f3c6cedb7509664ca3..5bb924edeaf697a44043c7a3df8cc02a8224356a 100644 |
| --- a/src/mips/simulator-mips.cc |
| +++ b/src/mips/simulator-mips.cc |
| @@ -4263,20 +4263,107 @@ void Simulator::DecodeTypeMsaI8() { |
| DCHECK(IsMipsArchVariant(kMips32r6)); |
| DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask; |
| + int8_t i8 = instr_.MsaImm8Value() & 0xFFu; |
|
Ilija.Pavlovic1
2017/05/29 07:31:21
Is this mask 0xFFu needed?
dusan.simicic
2017/05/29 16:32:15
Not needed, MsaImm8Value() method returns 8bit val
|
| 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]; |
|
Ilija.Pavlovic1
2017/05/29 07:31:21
Value 16 is used in all subsequent "case" statemen
dusan.simicic
2017/05/29 16:32:15
Done. Also added definition for msa_reg_t union.
|
| + 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]; |
|
Ilija.Pavlovic1
2017/05/29 07:31:21
Value 8 as constant WRLEN_16?
dusan.simicic
2017/05/29 16:32:15
Done.
|
| + 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]; |
|
Ilija.Pavlovic1
2017/05/29 07:31:21
Value 4 as constant WRLEN_32?
dusan.simicic
2017/05/29 16:32:15
Done.
|
| + 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(); |
| } |
| @@ -4355,9 +4442,44 @@ void Simulator::DecodeTypeMsaELM() { |
| UNREACHABLE(); |
| } |
| break; |
| + case INSERT: |
| + switch (DecodeMsaDataFormat()) { |
| + case MSA_BYTE: { |
| + DCHECK(n < 16); |
| + int8_t wd[16]; |
| + int32_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]; |
| + int32_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]; |
| + int32_t rs = get_register(instr_.WsValue()); |
| + get_msa_register(instr_.WdValue(), wd); |
| + wd[n] = rs; |
| + set_msa_register(instr_.WdValue(), wd); |
| + TraceMSARegWr(wd, WORD); |
| + break; |
| + } |
| + default: |
| + UNREACHABLE(); |
| + } |
| + break; |
| case SLDI: |
| case SPLATI: |
| - case INSERT: |
| case INSVE: |
| UNIMPLEMENTED(); |
| break; |