Commit 34ed2470 authored by Dusan Simicic's avatar Dusan Simicic Committed by Commit Bot

MIPS[64]: Implement MSA I10 instructions in simulator

Bug: 
Change-Id: Ib252b157977fe97f6f4ceb6e7f696f14ca12680e
Reviewed-on: https://chromium-review.googlesource.com/574595
Commit-Queue: Ivica Bogosavljevic <ivica.bogosavljevic@imgtec.com>
Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@imgtec.com>
Cr-Commit-Position: refs/heads/master@{#46783}
parent 99bbf7b7
......@@ -4496,11 +4496,37 @@ void Simulator::DecodeTypeMsaI10() {
DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask;
int64_t s10 = (static_cast<int64_t>(instr_.MsaImm10Value()) << 54) >> 54;
msa_reg_t wd;
#define MSA_I10_DF(elem, num_of_lanes, T) \
for (int i = 0; i < num_of_lanes; ++i) { \
wd.elem[i] = static_cast<T>(s10); \
} \
set_msa_register(instr_.WdValue(), wd.elem); \
TraceMSARegWr(wd.elem)
if (opcode == LDI) {
UNIMPLEMENTED();
switch (DecodeMsaDataFormat()) {
case MSA_BYTE:
MSA_I10_DF(b, kMSALanesByte, int8_t);
break;
case MSA_HALF:
MSA_I10_DF(h, kMSALanesHalf, int16_t);
break;
case MSA_WORD:
MSA_I10_DF(w, kMSALanesWord, int32_t);
break;
case MSA_DWORD:
MSA_I10_DF(d, kMSALanesDword, int64_t);
break;
default:
UNREACHABLE();
}
} else {
UNREACHABLE();
}
#undef MSA_I10_DF
}
void Simulator::DecodeTypeMsaELM() {
......
......@@ -4708,11 +4708,37 @@ void Simulator::DecodeTypeMsaI10() {
DCHECK(kArchVariant == kMips64r6);
DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask;
int64_t s10 = (static_cast<int64_t>(instr_.MsaImm10Value()) << 54) >> 54;
msa_reg_t wd;
#define MSA_I10_DF(elem, num_of_lanes, T) \
for (int i = 0; i < num_of_lanes; ++i) { \
wd.elem[i] = static_cast<T>(s10); \
} \
set_msa_register(instr_.WdValue(), wd.elem); \
TraceMSARegWr(wd.elem)
if (opcode == LDI) {
UNIMPLEMENTED();
switch (DecodeMsaDataFormat()) {
case MSA_BYTE:
MSA_I10_DF(b, kMSALanesByte, int8_t);
break;
case MSA_HALF:
MSA_I10_DF(h, kMSALanesHalf, int16_t);
break;
case MSA_WORD:
MSA_I10_DF(w, kMSALanesWord, int32_t);
break;
case MSA_DWORD:
MSA_I10_DF(d, kMSALanesDword, int64_t);
break;
default:
UNREACHABLE();
}
} else {
UNREACHABLE();
}
#undef MSA_I10_DF
}
void Simulator::DecodeTypeMsaELM() {
......
......@@ -7499,4 +7499,82 @@ TEST(MSA_sat_s_sat_u) {
#undef M_MAX_UINT
}
template <typename InstFunc, typename OperFunc>
void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc,
OperFunc GenerateOperationFunc) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
CpuFeatureScope fscope(&assm, MIPS_SIMD);
msa_reg_t res;
GenerateVectorInstructionFunc(assm, input);
__ copy_u_w(t2, w0, 0);
__ sw(t2, MemOperand(a0, 0));
__ copy_u_w(t2, w0, 1);
__ sw(t2, MemOperand(a0, 4));
__ copy_u_w(t2, w0, 2);
__ sw(t2, MemOperand(a0, 8));
__ copy_u_w(t2, w0, 3);
__ sw(t2, MemOperand(a0, 12));
__ jr(ra);
__ nop();
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
(CALL_GENERATED_CODE(isolate, f, &res, 0, 0, 0, 0));
CHECK_EQ(GenerateOperationFunc(input), res.d[0]);
CHECK_EQ(GenerateOperationFunc(input), res.d[1]);
}
TEST(MSA_ldi) {
if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
CcTest::InitializeVM();
int32_t tc[] = {0, -1, 1, 0x000000e1, 0xffffffb0,
0xffffffde, 0x00000136, 0x000001ff, 0xfffffe00};
#define LDI_DF(lanes, mask) \
[](int32_t s10) { \
uint64_t res = 0; \
int elem_size = kMSARegSize / lanes; \
int64_t s10_64 = \
ArithmeticShiftRight(static_cast<int64_t>(s10) << 54, 54); \
for (int i = 0; i < lanes / 2; ++i) { \
int shift = elem_size * i; \
res |= static_cast<uint64_t>(s10_64 & mask) << shift; \
} \
return res; \
}
for (size_t i = 0; i < sizeof(tc) / sizeof(int32_t); ++i) {
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_b(w0, s10); },
LDI_DF(kMSALanesByte, UINT8_MAX));
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_h(w0, s10); },
LDI_DF(kMSALanesHalf, UINT16_MAX));
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_w(w0, s10); },
LDI_DF(kMSALanesWord, UINT32_MAX));
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_d(w0, s10); },
LDI_DF(kMSALanesDword, UINT64_MAX));
}
#undef LDI_DF
}
#undef __
......@@ -8360,4 +8360,82 @@ TEST(MSA_sat_s_sat_u) {
#undef M_MAX_UINT
}
template <typename InstFunc, typename OperFunc>
void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc,
OperFunc GenerateOperationFunc) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
CpuFeatureScope fscope(&assm, MIPS_SIMD);
msa_reg_t res;
GenerateVectorInstructionFunc(assm, input);
__ copy_u_w(t2, w0, 0);
__ sw(t2, MemOperand(a0, 0));
__ copy_u_w(t2, w0, 1);
__ sw(t2, MemOperand(a0, 4));
__ copy_u_w(t2, w0, 2);
__ sw(t2, MemOperand(a0, 8));
__ copy_u_w(t2, w0, 3);
__ sw(t2, MemOperand(a0, 12));
__ jr(ra);
__ nop();
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
code->Print(std::cout);
#endif
F3 f = FUNCTION_CAST<F3>(code->entry());
(CALL_GENERATED_CODE(isolate, f, &res, 0, 0, 0, 0));
CHECK_EQ(GenerateOperationFunc(input), res.d[0]);
CHECK_EQ(GenerateOperationFunc(input), res.d[1]);
}
TEST(MSA_ldi) {
if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
return;
CcTest::InitializeVM();
int32_t tc[] = {0, -1, 1, 0x000000e1, 0xffffffb0,
0xffffffde, 0x00000136, 0x000001ff, 0xfffffe00};
#define LDI_DF(lanes, mask) \
[](int32_t s10) { \
uint64_t res = 0; \
int elem_size = kMSARegSize / lanes; \
int64_t s10_64 = \
ArithmeticShiftRight(static_cast<int64_t>(s10) << 54, 54); \
for (int i = 0; i < lanes / 2; ++i) { \
int shift = elem_size * i; \
res |= static_cast<uint64_t>(s10_64 & mask) << shift; \
} \
return res; \
}
for (size_t i = 0; i < sizeof(tc) / sizeof(int32_t); ++i) {
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_b(w0, s10); },
LDI_DF(kMSALanesByte, UINT8_MAX));
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_h(w0, s10); },
LDI_DF(kMSALanesHalf, UINT16_MAX));
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_w(w0, s10); },
LDI_DF(kMSALanesWord, UINT32_MAX));
run_msa_i10(tc[i],
[](MacroAssembler& assm, int32_t s10) { __ ldi_d(w0, s10); },
LDI_DF(kMSALanesDword, UINT64_MAX));
}
#undef LDI_DF
}
#undef __
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment