Index: test/cctest/test-assembler-mips64.cc |
diff --git a/test/cctest/test-assembler-mips64.cc b/test/cctest/test-assembler-mips64.cc |
index 0e46f2ca9b424710c6b2d2ed495c160bb9b15afb..74a7482158da50fb8a941604700e87d4a37d61ca 100644 |
--- a/test/cctest/test-assembler-mips64.cc |
+++ b/test/cctest/test-assembler-mips64.cc |
@@ -6057,4 +6057,125 @@ TEST(maddf_msubf_d) { |
}); |
} |
+uint64_t run_Dins(uint64_t imm, uint64_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); |
+ __ Dins(v0, t0, pos, size); |
+ __ jr(ra); |
+ __ nop(); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+ F2 f = FUNCTION_CAST<F2>(code->entry()); |
+ |
+ uint64_t res = reinterpret_cast<uint64_t>( |
+ CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
+ |
+ return res; |
+} |
+ |
+TEST(Dins) { |
+ CcTest::InitializeVM(); |
+ |
+ // Test Dins macro-instruction. |
+ |
+ struct TestCaseDins { |
+ uint64_t imm; |
Ilija.Pavlovic1
2017/05/09 09:17:46
Instead "imm" maybe more suitable name is "res".
miran.karic
2017/05/09 13:52:43
This is initial value of target register, not resu
|
+ uint64_t source; |
+ uint16_t pos; |
+ uint16_t size; |
+ uint64_t expected_res; |
+ }; |
+ |
+ // We load imm to v0 and source to t0 and then call |
+ // Dins(v0, t0, pos, size) to test cases listed below. |
+ struct TestCaseDins tc[] = { |
+ // imm, source, pos, size, expected_res |
+ {0x0, 0x1FABCDEFF, 31, 1, 0x80000000}, |
Ilija.Pavlovic1
2017/05/09 09:17:46
Instead 0x0, use another value (for example 0xAAAA
miran.karic
2017/05/09 13:52:43
Yes I think that will be better, I adjusted test c
|
+ {0x0, 0x1FABCDEFF, 30, 2, 0xc0000000}, |
+ {0x0, 0x1FABCDEFF, 0, 32, 0xFABCDEFF}, |
+ {0x0, 0x7FABCDEFF, 31, 2, 0x180000000}, |
+ {0x0, 0x7FABCDEFF, 0, 33, 0x1FABCDEFF}, |
+ {0x0, 0xABCDABCDABCDABCD, 0, 64, 0xABCDABCDABCDABCD}, |
+ {0x0, 0xABCEABCFABCEABCF, 32, 1, 0x100000000}, |
+ {0x0, 0xABCEABCFABCEABCF, 63, 1, 0x8000000000000000}, |
+ {0x0, 0xABCEABCFABCEABCF, 32, 32, 0xABCEABCF00000000}, |
+ }; |
+ |
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDins); |
+ for (size_t i = 0; i < nr_test_cases; ++i) { |
+ CHECK_EQ(tc[i].expected_res, |
+ run_Dins(tc[i].imm, tc[i].source, tc[i].pos, tc[i].size)); |
+ } |
+} |
+ |
+uint64_t getExpectedValueDINS(uint64_t rt, uint64_t rs, int pos, int size) { |
+ uint64_t res = rt; |
+ int i; |
+ uint64_t bitVal; |
+ for (i = 0; i < size; i++) { |
+ bitVal = rs & (1 << i); |
+ if (bitVal > 0) bitVal = 1; |
+ res = res | bitVal << (i + pos); // Works only for rs equals all ones! |
+ } |
+ return res; |
+} |
+ |
+TEST(Dins_all) { |
Ilija.Pavlovic1
2017/05/09 09:17:46
Maybe not needed to go through all combinations.
miran.karic
2017/05/09 13:52:43
I agree, I removed this test and only left Dins te
|
+ CcTest::InitializeVM(); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ HandleScope scope(isolate); |
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
+ |
+ // Test Dins macro-instruction. |
+ |
+ const uint64_t rt = 0; |
+ const uint64_t rs = std::numeric_limits<uint64_t>::max(); |
+ Label exit, error; |
+ uint64_t result; |
+ |
+ int iPos, iSize; |
+ // Run through all possible Dins pos and size inputs. |
+ for (iPos = 0; iPos < 64; ++iPos) { |
+ for (iSize = 1; iSize <= 64 - iPos; ++iSize) { |
+ result = getExpectedValueDINS(rt, rs, iPos, iSize); |
+ __ li(a0, rt); |
+ __ li(a1, rs); |
+ __ Dins(a0, a1, iPos, iSize); |
+ __ Branch(&error, ne, a0, Operand(result)); |
+ __ nop(); |
+ } |
+ } |
+ |
+ // Everything was correctly executed. Load the expected result. |
+ __ li(v0, 0x31415926); |
+ __ b(&exit); |
+ __ nop(); |
+ |
+ __ bind(&error); |
+ // Got an error. Return a wrong result. |
+ __ li(v0, 666); |
+ |
+ __ bind(&exit); |
+ __ jr(ra); |
+ __ nop(); |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+ F2 f = FUNCTION_CAST<F2>(code->entry()); |
+ int64_t res = |
+ reinterpret_cast<int64_t>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
+ |
+ CHECK_EQ(0x31415926L, res); |
+} |
+ |
#undef __ |