Commit eaf850e2 authored by Miran.Karic's avatar Miran.Karic Committed by Commit Bot

MIPS: Fix ins and ext instructions in simulator.

Instructions ins and ext didn't work properly when size = 32 because of
incorrect mask initialization, this CL fixes this. A test for Ins is
also added.

BUG=

Change-Id: I95cc8e13aaa2341b34ae59dae1eefb64c551b8b4
Reviewed-on: https://chromium-review.googlesource.com/558872
Commit-Queue: Miran Karić <Miran.Karic@imgtec.com>
Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@imgtec.com>
Cr-Commit-Position: refs/heads/master@{#46378}
parent f6817f71
......@@ -4101,7 +4101,12 @@ void Simulator::DecodeTypeRegisterSPECIAL3() {
// Interpret sa field as 5-bit lsb of insert.
uint16_t lsb = sa();
uint16_t size = msb - lsb + 1;
uint32_t mask = (1 << size) - 1;
uint32_t mask;
if (size < 32) {
mask = (1 << size) - 1;
} else {
mask = std::numeric_limits<uint32_t>::max();
}
alu_out = (rt_u() & ~(mask << lsb)) | ((rs_u() & mask) << lsb);
// Ins instr leaves result in Rt, rather than Rd.
SetResult(rt_reg(), alu_out);
......@@ -4113,7 +4118,12 @@ void Simulator::DecodeTypeRegisterSPECIAL3() {
// Interpret sa field as 5-bit lsb of extract.
uint16_t lsb = sa();
uint16_t size = msb + 1;
uint32_t mask = (1 << size) - 1;
uint32_t mask;
if (size < 32) {
mask = (1 << size) - 1;
} else {
mask = std::numeric_limits<uint32_t>::max();
}
alu_out = (rs_u() & (mask << lsb)) >> lsb;
SetResult(rt_reg(), alu_out);
break;
......
......@@ -6134,6 +6134,59 @@ TEST(MSA_shf) {
}
}
uint32_t run_Ins(uint32_t imm, uint32_t source, uint16_t pos, uint16_t size) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
__ li(v0, imm);
__ li(t0, source);
__ Ins(v0, t0, pos, size);
__ jr(ra);
__ nop();
CodeDesc desc;
assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
uint32_t res = reinterpret_cast<uint32_t>(
CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
return res;
}
TEST(Ins) {
CcTest::InitializeVM();
// Test Ins macro-instruction.
struct TestCaseIns {
uint32_t imm;
uint32_t source;
uint16_t pos;
uint16_t size;
uint32_t expected_res;
};
// We load imm to v0 and source to t0 and then call
// Ins(v0, t0, pos, size) to test cases listed below.
struct TestCaseIns tc[] = {
// imm, source, pos, size, expected_res
{0x55555555, 0xabcdef01, 31, 1, 0xd5555555},
{0x55555555, 0xabcdef02, 30, 2, 0x95555555},
{0x01234567, 0xfabcdeff, 0, 32, 0xfabcdeff},
};
size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseIns);
for (size_t i = 0; i < nr_test_cases; ++i) {
CHECK_EQ(tc[i].expected_res,
run_Ins(tc[i].imm, tc[i].source, tc[i].pos, tc[i].size));
}
}
struct TestCaseMsaI5 {
uint64_t ws_lo;
uint64_t ws_hi;
......
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