Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 5035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5046 }; | 5046 }; |
| 5047 | 5047 |
| 5048 nr_test_cases = sizeof(dahi_tc) / sizeof(TestCaseAui); | 5048 nr_test_cases = sizeof(dahi_tc) / sizeof(TestCaseAui); |
| 5049 for (size_t i = 0; i < nr_test_cases; ++i) { | 5049 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 5050 uint64_t res = run_dahi(dahi_tc[i].rs, dahi_tc[i].offset); | 5050 uint64_t res = run_dahi(dahi_tc[i].rs, dahi_tc[i].offset); |
| 5051 CHECK_EQ(dahi_tc[i].ref_res, res); | 5051 CHECK_EQ(dahi_tc[i].ref_res, res); |
| 5052 } | 5052 } |
| 5053 } | 5053 } |
| 5054 } | 5054 } |
| 5055 | 5055 |
| 5056 | 5056 uint64_t run_li_macro(uint64_t imm, LiFlags mode, int32_t num_instr = 0) { |
| 5057 uint64_t run_li_macro(uint64_t rs, LiFlags mode) { | |
| 5058 Isolate* isolate = CcTest::i_isolate(); | 5057 Isolate* isolate = CcTest::i_isolate(); |
| 5059 HandleScope scope(isolate); | 5058 HandleScope scope(isolate); |
| 5060 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); | 5059 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| 5061 | 5060 |
| 5062 __ li(a0, rs, mode); | 5061 Label code_start; |
| 5063 __ mov(v0, a0); | 5062 __ bind(&code_start); |
| 5063 __ li(v0, imm, mode); | |
| 5064 if (num_instr > 0) | |
| 5065 CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr); | |
|
dusan.simicic
2017/05/23 12:17:38
Add {} around CHECK_EQ().
miran.karic
2017/05/23 14:19:25
Done.
| |
| 5064 __ jr(ra); | 5066 __ jr(ra); |
| 5065 __ nop(); | 5067 __ nop(); |
| 5066 | 5068 |
| 5067 CodeDesc desc; | 5069 CodeDesc desc; |
| 5068 assm.GetCode(&desc); | 5070 assm.GetCode(&desc); |
| 5069 Handle<Code> code = isolate->factory()->NewCode( | 5071 Handle<Code> code = isolate->factory()->NewCode( |
| 5070 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | 5072 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5071 | |
| 5072 F2 f = FUNCTION_CAST<F2>(code->entry()); | 5073 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 5073 | 5074 |
| 5074 uint64_t res = reinterpret_cast<uint64_t>( | 5075 uint64_t res = reinterpret_cast<uint64_t>( |
| 5075 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); | 5076 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
| 5076 | 5077 |
| 5077 return res; | 5078 return res; |
| 5078 } | 5079 } |
| 5079 | 5080 |
| 5080 | 5081 |
| 5081 TEST(li_macro) { | 5082 TEST(li_macro) { |
| 5082 CcTest::InitializeVM(); | 5083 CcTest::InitializeVM(); |
| 5083 | 5084 |
| 5084 uint64_t inputs[] = { | 5085 // Test li macro-instruction for border cases. |
| 5085 0x0000000000000000, 0x000000000000ffff, 0x00000000ffffffff, | 5086 |
| 5086 0x0000ffffffffffff, 0xffffffffffffffff, 0xffff000000000000, | 5087 struct TestCase_li { |
| 5087 0xffffffff00000000, 0xffffffffffff0000, 0xffff0000ffff0000, | 5088 uint64_t imm; |
| 5088 0x0000ffffffff0000, 0x0000ffff0000ffff, 0x00007fffffffffff, | 5089 int32_t r2_num_instr; |
| 5089 0x7fffffffffffffff, 0x000000007fffffff, 0x00007fff7fffffff, | 5090 int32_t r6_num_instr; |
| 5090 }; | 5091 }; |
| 5091 | 5092 |
| 5092 size_t nr_test_cases = sizeof(inputs) / sizeof(inputs[0]); | 5093 // We call li(v0, imm) to test cases listed below. |
| 5094 struct TestCase_li tc[] = { | |
| 5095 // imm, r2_num_instr, r6_num_instr | |
| 5096 {0xffffffffffff8000, 1, 1}, // min_int16 | |
| 5097 // Generates daddiu | |
| 5098 // This is int16 value and we can load it using just daddiu. | |
|
dusan.simicic
2017/05/23 12:17:38
Comments are usually placed before code sequence,
miran.karic
2017/05/23 14:19:24
Acknowledged. I think that would be more confusing
| |
| 5099 {0x8000, 1, 1}, // max_int16 + 1 | |
| 5100 // Generates ori | |
| 5101 // max_int16 + 1 is not int16 but is uint16, just use ori. | |
| 5102 {0xffffffffffff7fff, 2, 2}, // min_int16 - 1 | |
| 5103 // Generates lui + ori | |
| 5104 // We load int32 value using lui + ori. | |
| 5105 {0x8001, 1, 1}, // max_int16 + 2 | |
| 5106 // Generates ori | |
| 5107 // Also an uint16 value, use ori. | |
| 5108 {0x00010000, 1, 1}, // max_uint16 + 1 | |
| 5109 // Generates lui | |
| 5110 // Low 16 bits are 0, load value using lui. | |
| 5111 {0x00010001, 2, 2}, // max_uint16 + 2 | |
| 5112 // Generates lui + ori | |
| 5113 // We have to generate two instructions in this case. | |
| 5114 {0x00000000ffffffff, 2, 2}, // max_uint32 | |
| 5115 // r2 - daddiu + dsrl32 | |
| 5116 // r6 - daddiu + dahi | |
| 5117 {0x00000000fffffffe, 3, 2}, // max_uint32 - 1 | |
| 5118 // r2 - lui + ori + dsll | |
| 5119 // r6 - daddiu + dahi | |
| 5120 {0x00ffff000000fffe, 3, 3}, | |
| 5121 // ori + dsll32 + ori | |
| 5122 {0x00000001fffffffe, 4, 2}, // max_uint32 << 1 | |
| 5123 // r2 - lui + ori + dsll + ori | |
| 5124 // r6 - daddiu + dahi | |
| 5125 {0x0000fffffffffffe, 5, 2}, // max_uint48 - 1 | |
| 5126 // r2 - ori + dsll + ori + dsll + ori | |
| 5127 // r6 - daddiu + dati | |
| 5128 {0xffffffff00000000, 2, 2}, // max_uint32 << 32 | |
| 5129 // r2 - daddiu + dsll32 | |
| 5130 // r6 - ori + dahi | |
| 5131 // We need ori to clear register before loading value using dahi. | |
| 5132 {0xffffffff80000000, 1, 1}, // min_int32 | |
| 5133 // lui | |
| 5134 {0x0000000080000000, 2, 2}, // max_int32 + 1 | |
| 5135 // r2 - ori + dsll | |
| 5136 // r6 - lui + dahi | |
| 5137 {0x0000800000000000, 2, 2}, | |
| 5138 // ori + dsll32 | |
| 5139 {0xffff800000000000, 2, 2}, | |
| 5140 // r2 - daddiu + dsll32 | |
| 5141 // r6 - ori + dahi | |
| 5142 {0xffff80000000ffff, 3, 2}, | |
| 5143 // r2 - daddiu + dsll32 + ori | |
| 5144 // r6 - ori + dahi | |
| 5145 {0xffffff123000ffff, 3, 3}, | |
| 5146 // daddiu + dsll + ori | |
| 5147 {0xffff00000000ffff, 3, 2}, | |
| 5148 // r2 - daddiu + dsll32 + ori | |
| 5149 // r6 - ori + dati | |
| 5150 {0xffff8000ffff0000, 3, 2}, | |
| 5151 // r2 - lui + ori + dsll | |
| 5152 // r6 - lui + dahi | |
| 5153 {0x1234ffff80000000, 3, 2}, | |
| 5154 // r2 - lui + ori + dsll | |
| 5155 // r6 - lui + dati | |
| 5156 {0x1234ffff80010000, 5, 2}, | |
| 5157 // r2 - lui + ori + dsll + ori + dsll | |
| 5158 // r6 - lui + dati | |
| 5159 {0xffff8000ffff8000, 2, 2}, | |
| 5160 // r2 - daddiu + dinsu | |
| 5161 // r6 - daddiu + dahi | |
| 5162 {0xffff0000ffff8000, 5, 3}, | |
| 5163 // r2 - lui + dsll + ori + dsll + ori | |
| 5164 // r6 - daddiu + dahi + dati | |
| 5165 {0x8000000080000000, 2, 2}, | |
| 5166 // lui + dinsu | |
| 5167 {0xabcd0000abcd0000, 2, 2}, | |
| 5168 // lui + dinsu | |
| 5169 {0x8000800080008000, 3, 3}, | |
| 5170 // lui + ori + dinsu | |
| 5171 {0xabcd1234abcd1234, 3, 3}, | |
| 5172 // lui + ori + dinsu | |
| 5173 {0xffff800080008000, 4, 3}, | |
| 5174 // r2 - lui + ori + dsll + ori | |
| 5175 // r6 - lui + ori + dahi | |
| 5176 {0xffffabcd, 3, 2}, | |
| 5177 // r2 - ori + dsll + ori | |
| 5178 // r6 - daddiu + dahi | |
| 5179 {0x1ffffabcd, 4, 2}, | |
| 5180 // r2 - lui + ori + dsll + ori | |
| 5181 // r6 - daddiu + dahi | |
| 5182 {0xffffffffabcd, 5, 2}, | |
| 5183 // r2 - ori + dsll + ori + dsll + ori | |
| 5184 // r6 - daddiu + dati | |
| 5185 {0x1ffffffffabcd, 6, 2}, | |
| 5186 // r2 - lui + ori + dsll + ori + dsll + ori | |
| 5187 // r6 - daddiu + dati | |
| 5188 {0xffff7fff80010000, 5, 2}, | |
| 5189 // r2 - lui + ori + dsll + ori + dsll | |
| 5190 // r6 - lui + dahi | |
| 5191 // Here lui sets high 32 bits to 1 so dahi can be used to get target | |
| 5192 // value. | |
| 5193 {0x00007fff7fff0000, 3, 2}, | |
| 5194 // r2 - lui + ori + dsll | |
| 5195 // r6 - lui + dahi | |
| 5196 // High 32 bits are not set so dahi can be used to get target value. | |
| 5197 {0xffff7fff7fff0000, 5, 3}, | |
| 5198 // r2 - lui + ori + dsll + ori + dsll | |
| 5199 // r6 - lui + dahi + dati | |
| 5200 // High 32 bits are not set so just dahi can't be used to get target | |
| 5201 // value. | |
| 5202 {0x00007fff80010000, 3, 3}, | |
| 5203 // r2 - lui + ori + dsll | |
| 5204 // r6 - lui + ori + dsll | |
| 5205 // High 32 bits are set so can't just use lui + dahi to get target value. | |
| 5206 {0x1234abcd87654321, 6, 4}, | |
| 5207 // r2 - lui + ori + dsll + ori + dsll + ori | |
| 5208 // r6 - lui + ori + dahi + dati | |
| 5209 // Load using full instruction sequence. | |
| 5210 }; | |
| 5211 | |
| 5212 size_t nr_test_cases = sizeof(tc) / sizeof(TestCase_li); | |
| 5093 for (size_t i = 0; i < nr_test_cases; ++i) { | 5213 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 5094 uint64_t res = run_li_macro(inputs[i], OPTIMIZE_SIZE); | 5214 if (kArchVariant == kMips64r2) { |
| 5095 CHECK_EQ(inputs[i], res); | 5215 CHECK_EQ(tc[i].imm, |
| 5096 res = run_li_macro(inputs[i], CONSTANT_SIZE); | 5216 run_li_macro(tc[i].imm, OPTIMIZE_SIZE, tc[i].r2_num_instr)); |
| 5097 CHECK_EQ(inputs[i], res); | 5217 } else { |
| 5098 if (is_int48(inputs[i])) { | 5218 CHECK_EQ(tc[i].imm, |
| 5099 res = run_li_macro(inputs[i], ADDRESS_LOAD); | 5219 run_li_macro(tc[i].imm, OPTIMIZE_SIZE, tc[i].r6_num_instr)); |
| 5100 CHECK_EQ(inputs[i], res); | 5220 } |
| 5221 CHECK_EQ(tc[i].imm, run_li_macro(tc[i].imm, CONSTANT_SIZE)); | |
| 5222 if (is_int48(tc[i].imm)) { | |
| 5223 CHECK_EQ(tc[i].imm, run_li_macro(tc[i].imm, ADDRESS_LOAD)); | |
| 5101 } | 5224 } |
| 5102 } | 5225 } |
| 5103 } | 5226 } |
| 5104 | 5227 |
| 5105 | 5228 |
| 5106 uint64_t run_lwpc(int offset) { | 5229 uint64_t run_lwpc(int offset) { |
| 5107 Isolate* isolate = CcTest::i_isolate(); | 5230 Isolate* isolate = CcTest::i_isolate(); |
| 5108 HandleScope scope(isolate); | 5231 HandleScope scope(isolate); |
| 5109 | 5232 |
| 5110 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); | 5233 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| (...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6050 TEST(maddf_msubf_d) { | 6173 TEST(maddf_msubf_d) { |
| 6051 if (kArchVariant != kMips64r6) return; | 6174 if (kArchVariant != kMips64r6) return; |
| 6052 helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) { | 6175 helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) { |
| 6053 __ maddf_d(f4, f6, f8); | 6176 __ maddf_d(f4, f6, f8); |
| 6054 __ Sdc1(f4, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add))); | 6177 __ Sdc1(f4, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add))); |
| 6055 __ msubf_d(f16, f6, f8); | 6178 __ msubf_d(f16, f6, f8); |
| 6056 __ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub))); | 6179 __ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub))); |
| 6057 }); | 6180 }); |
| 6058 } | 6181 } |
| 6059 | 6182 |
| 6183 uint64_t run_Subu(uint64_t imm, int32_t num_instr) { | |
| 6184 Isolate* isolate = CcTest::i_isolate(); | |
| 6185 HandleScope scope(isolate); | |
| 6186 | |
| 6187 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); | |
| 6188 | |
| 6189 Label code_start; | |
| 6190 __ bind(&code_start); | |
| 6191 __ Subu(v0, zero_reg, Operand(imm)); | |
| 6192 CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr); | |
| 6193 __ jr(ra); | |
| 6194 __ nop(); | |
| 6195 | |
| 6196 CodeDesc desc; | |
| 6197 assm.GetCode(&desc); | |
| 6198 Handle<Code> code = isolate->factory()->NewCode( | |
| 6199 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 6200 F2 f = FUNCTION_CAST<F2>(code->entry()); | |
| 6201 | |
| 6202 uint64_t res = reinterpret_cast<uint64_t>( | |
| 6203 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); | |
| 6204 | |
| 6205 return res; | |
| 6206 } | |
| 6207 | |
| 6208 TEST(Subu) { | |
| 6209 CcTest::InitializeVM(); | |
| 6210 | |
| 6211 // Test Subu macro-instruction for min_int16 and max_int16 border cases. | |
| 6212 // For subtracting int16 immediate values we use addiu. | |
| 6213 | |
| 6214 struct TestCaseSubu { | |
| 6215 uint64_t imm; | |
| 6216 uint64_t expected_res; | |
| 6217 int32_t num_instr; | |
| 6218 }; | |
| 6219 | |
| 6220 // We call Subu(v0, zero_reg, imm) to test cases listed below. | |
| 6221 // 0 - imm = expected_res | |
| 6222 struct TestCaseSubu tc[] = { | |
| 6223 // imm, expected_res, num_instr | |
| 6224 {0xffffffffffff8000, 0x8000, 2}, // min_int16 | |
| 6225 // Generates ori + addu | |
| 6226 // We can't have just addiu because -min_int16 > max_int16 so use | |
| 6227 // register. We can load min_int16 to at register with addiu and then | |
| 6228 // subtract at with subu, but now we use ori + addu because -min_int16 can | |
| 6229 // be loaded using ori. | |
| 6230 {0x8000, 0xffffffffffff8000, 1}, // max_int16 + 1 | |
| 6231 // Generates addiu | |
| 6232 // max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use addiu. | |
| 6233 {0xffffffffffff7fff, 0x8001, 2}, // min_int16 - 1 | |
| 6234 // Generates ori + addu | |
| 6235 // To load this value to at we need two instructions and another one to | |
| 6236 // subtract, lui + ori + subu. But we can load -value to at using just | |
| 6237 // ori and then add at register with addu. | |
| 6238 {0x8001, 0xffffffffffff7fff, 2}, // max_int16 + 2 | |
| 6239 // Generates ori + subu | |
| 6240 // Not int16 but is uint16, load value to at with ori and subtract with | |
| 6241 // subu. | |
| 6242 {0x00010000, 0xffffffffffff0000, 2}, | |
| 6243 // Generates lui + subu | |
| 6244 // Load value using lui to at and subtract with subu. | |
| 6245 {0x00010001, 0xfffffffffffeffff, 3}, | |
| 6246 // Generates lui + ori + subu | |
| 6247 // We have to generate three instructions in this case. | |
| 6248 {0x7fffffff, 0xffffffff80000001, 3}, // max_int32 | |
| 6249 // Generates lui + ori + subu | |
| 6250 {0xffffffff80000000, 0xffffffff80000000, 2}, // min_int32 | |
| 6251 // Generates lui + subu | |
| 6252 // The result of 0 - min_int32 eqauls max_int32 + 1, which wraps around to | |
| 6253 // min_int32 again. | |
| 6254 }; | |
| 6255 | |
| 6256 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseSubu); | |
| 6257 for (size_t i = 0; i < nr_test_cases; ++i) { | |
| 6258 CHECK_EQ(tc[i].expected_res, run_Subu(tc[i].imm, tc[i].num_instr)); | |
| 6259 } | |
| 6260 } | |
| 6261 | |
| 6262 uint64_t run_Dsubu(uint64_t imm, int32_t num_instr) { | |
| 6263 Isolate* isolate = CcTest::i_isolate(); | |
| 6264 HandleScope scope(isolate); | |
| 6265 | |
| 6266 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); | |
| 6267 | |
| 6268 Label code_start; | |
| 6269 __ bind(&code_start); | |
| 6270 __ Dsubu(v0, zero_reg, Operand(imm)); | |
| 6271 CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr); | |
| 6272 __ jr(ra); | |
| 6273 __ nop(); | |
| 6274 | |
| 6275 CodeDesc desc; | |
| 6276 assm.GetCode(&desc); | |
| 6277 Handle<Code> code = isolate->factory()->NewCode( | |
| 6278 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); | |
| 6279 F2 f = FUNCTION_CAST<F2>(code->entry()); | |
| 6280 | |
| 6281 uint64_t res = reinterpret_cast<uint64_t>( | |
| 6282 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); | |
| 6283 | |
| 6284 return res; | |
| 6285 } | |
| 6286 | |
| 6287 TEST(Dsubu) { | |
| 6288 CcTest::InitializeVM(); | |
| 6289 | |
| 6290 // Test Dsubu macro-instruction for min_int16 and max_int16 border cases. | |
| 6291 // For subtracting int16 immediate values we use daddiu. | |
| 6292 | |
| 6293 struct TestCaseDsubu { | |
| 6294 uint64_t imm; | |
| 6295 uint64_t expected_res; | |
| 6296 int32_t num_instr; | |
| 6297 }; | |
| 6298 | |
| 6299 // We call Dsubu(v0, zero_reg, imm) to test cases listed below. | |
| 6300 // 0 - imm = expected_res | |
| 6301 struct TestCaseDsubu tc[] = { | |
| 6302 // imm, expected_res, num_instr | |
| 6303 {0xffffffffffff8000, 0x8000, 2}, // min_int16 | |
| 6304 // Generates ori + daddu | |
| 6305 // We can't have just daddiu because -min_int16 > max_int16 so use | |
| 6306 // register. We can load min_int16 to at register with daddiu and then | |
| 6307 // subtract at with dsubu, but now we use ori + daddu because -min_int16 | |
| 6308 // can be loaded using ori. | |
| 6309 {0x8000, 0xffffffffffff8000, 1}, // max_int16 + 1 | |
| 6310 // Generates daddiu | |
| 6311 // max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use daddiu. | |
| 6312 {0xffffffffffff7fff, 0x8001, 2}, // min_int16 - 1 | |
| 6313 // Generates ori + daddu | |
| 6314 // To load this value to at we need two instructions and another one to | |
| 6315 // subtract, lui + ori + dsubu. But we can load -value to at using just | |
| 6316 // ori and then dadd at register with daddu. | |
| 6317 {0x8001, 0xffffffffffff7fff, 2}, // max_int16 + 2 | |
| 6318 // Generates ori + dsubu | |
| 6319 // Not int16 but is uint16, load value to at with ori and subtract with | |
| 6320 // dsubu. | |
| 6321 {0x00010000, 0xffffffffffff0000, 2}, | |
| 6322 // Generates lui + dsubu | |
| 6323 // Load value using lui to at and subtract with dsubu. | |
| 6324 {0x00010001, 0xfffffffffffeffff, 3}, | |
| 6325 // Generates lui + ori + dsubu | |
| 6326 // We have to generate three instructions in this case. | |
| 6327 {0x7fffffff, 0xffffffff80000001, 3}, // max_int32 | |
| 6328 // Generates lui + ori + dsubu | |
| 6329 {0xffffffff80000000, 0x0000000080000000, 2}, // min_int32 | |
| 6330 // Generates lui + dsubu | |
| 6331 // The result of 0 - min_int32 eqauls max_int32 + 1, which fits into a 64 | |
| 6332 // bit register, Dsubu gives a different result here. | |
| 6333 {0x7fffffffffffffff, 0x8000000000000001, 3}, // max_int64 | |
| 6334 // r2 - Generates daddiu + dsrl + dsubu | |
| 6335 // r6 - Generates daddiu + dati + dsubu | |
| 6336 {0x8000000000000000, 0x8000000000000000, 3}, // min_int64 | |
| 6337 // r2 - Generates daddiu + dsrl32 + dsubu | |
| 6338 // r6 - Generates ori + dati + dsubu | |
| 6339 // The result of 0 - min_int64 eqauls max_int64 + 1, which wraps around to | |
| 6340 // min_int64 again. | |
| 6341 }; | |
| 6342 | |
| 6343 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDsubu); | |
| 6344 for (size_t i = 0; i < nr_test_cases; ++i) { | |
| 6345 CHECK_EQ(tc[i].expected_res, run_Dsubu(tc[i].imm, tc[i].num_instr)); | |
| 6346 } | |
| 6347 } | |
| 6348 | |
| 6060 uint64_t run_Dins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) { | 6349 uint64_t run_Dins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) { |
| 6061 Isolate* isolate = CcTest::i_isolate(); | 6350 Isolate* isolate = CcTest::i_isolate(); |
| 6062 HandleScope scope(isolate); | 6351 HandleScope scope(isolate); |
| 6063 | 6352 |
| 6064 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); | 6353 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| 6065 | 6354 |
| 6066 __ li(v0, imm); | 6355 __ li(v0, imm); |
| 6067 __ li(t0, source); | 6356 __ li(t0, source); |
| 6068 __ Dins(v0, t0, pos, size); | 6357 __ Dins(v0, t0, pos, size); |
| 6069 __ jr(ra); | 6358 __ jr(ra); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 6091 uint64_t source; | 6380 uint64_t source; |
| 6092 uint16_t pos; | 6381 uint16_t pos; |
| 6093 uint16_t size; | 6382 uint16_t size; |
| 6094 uint64_t expected_res; | 6383 uint64_t expected_res; |
| 6095 }; | 6384 }; |
| 6096 | 6385 |
| 6097 // We load imm to v0 and source to t0 and then call | 6386 // We load imm to v0 and source to t0 and then call |
| 6098 // Dins(v0, t0, pos, size) to test cases listed below. | 6387 // Dins(v0, t0, pos, size) to test cases listed below. |
| 6099 struct TestCaseDins tc[] = { | 6388 struct TestCaseDins tc[] = { |
| 6100 // imm, source, pos, size, expected_res | 6389 // imm, source, pos, size, expected_res |
| 6101 {0x5555555555555555, 0x1ABCDEF01, 31, 1, 0x55555555D5555555}, | 6390 {0x5555555555555555, 0x1abcdef01, 31, 1, 0x55555555d5555555}, |
| 6102 {0x5555555555555555, 0x1ABCDEF02, 30, 2, 0x5555555595555555}, | 6391 {0x5555555555555555, 0x1abcdef02, 30, 2, 0x5555555595555555}, |
| 6103 {0x201234567, 0x1FABCDEFF, 0, 32, 0x2FABCDEFF}, | 6392 {0x201234567, 0x1fabcdeff, 0, 32, 0x2fabcdeff}, |
| 6104 {0x201234567, 0x7FABCDEFF, 31, 2, 0x381234567}, | 6393 {0x201234567, 0x7fabcdeff, 31, 2, 0x381234567}, |
| 6105 {0x800000000, 0x7FABCDEFF, 0, 33, 0x9FABCDEFF}, | 6394 {0x800000000, 0x7fabcdeff, 0, 33, 0x9fabcdeff}, |
| 6106 {0x1234, 0xABCDABCDABCDABCD, 0, 64, 0xABCDABCDABCDABCD}, | 6395 {0x1234, 0xabcdabcdabcdabcd, 0, 64, 0xabcdabcdabcdabcd}, |
| 6107 {0xABCD, 0xABCEABCF, 32, 1, 0x10000ABCD}, | 6396 {0xabcd, 0xabceabcf, 32, 1, 0x10000abcd}, |
| 6108 {0xABCD, 0xABCEABCF, 63, 1, 0x800000000000ABCD}, | 6397 {0xabcd, 0xabceabcf, 63, 1, 0x800000000000abcd}, |
| 6109 {0xABCD, 0xABC1ABC2ABC3ABC4, 32, 32, 0xABC3ABC40000ABCD}, | 6398 {0x10000abcd, 0xabc1abc2abc3abc4, 32, 32, 0xabc3abc40000abcd}, |
| 6110 }; | 6399 }; |
| 6111 | 6400 |
| 6112 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDins); | 6401 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDins); |
| 6113 for (size_t i = 0; i < nr_test_cases; ++i) { | 6402 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 6114 CHECK_EQ(tc[i].expected_res, | 6403 CHECK_EQ(tc[i].expected_res, |
| 6115 run_Dins(tc[i].imm, tc[i].source, tc[i].pos, tc[i].size)); | 6404 run_Dins(tc[i].imm, tc[i].source, tc[i].pos, tc[i].size)); |
| 6116 } | 6405 } |
| 6117 } | 6406 } |
| 6118 | 6407 |
| 6119 #undef __ | 6408 #undef __ |
| OLD | NEW |