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 5495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5506 TEST(maddf_msubf_d) { | 5506 TEST(maddf_msubf_d) { |
5507 if (!IsMipsArchVariant(kMips32r6)) return; | 5507 if (!IsMipsArchVariant(kMips32r6)) return; |
5508 helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) { | 5508 helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) { |
5509 __ maddf_d(f4, f6, f8); | 5509 __ maddf_d(f4, f6, f8); |
5510 __ Sdc1(f4, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add))); | 5510 __ Sdc1(f4, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add))); |
5511 __ msubf_d(f16, f6, f8); | 5511 __ msubf_d(f16, f6, f8); |
5512 __ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub))); | 5512 __ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub))); |
5513 }); | 5513 }); |
5514 } | 5514 } |
5515 | 5515 |
| 5516 uint32_t run_Subu(uint32_t imm, int32_t num_instr) { |
| 5517 Isolate* isolate = CcTest::i_isolate(); |
| 5518 HandleScope scope(isolate); |
| 5519 |
| 5520 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| 5521 |
| 5522 Label code_start; |
| 5523 __ bind(&code_start); |
| 5524 __ Subu(v0, zero_reg, imm); |
| 5525 CHECK_EQ(assm.SizeOfCodeGeneratedSince(&code_start), |
| 5526 num_instr * Assembler::kInstrSize); |
| 5527 __ jr(ra); |
| 5528 __ nop(); |
| 5529 |
| 5530 CodeDesc desc; |
| 5531 assm.GetCode(&desc); |
| 5532 Handle<Code> code = isolate->factory()->NewCode( |
| 5533 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5534 F2 f = FUNCTION_CAST<F2>(code->entry()); |
| 5535 |
| 5536 uint32_t res = reinterpret_cast<uint32_t>( |
| 5537 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
| 5538 |
| 5539 return res; |
| 5540 } |
| 5541 |
| 5542 TEST(Subu) { |
| 5543 CcTest::InitializeVM(); |
| 5544 |
| 5545 // Test Subu macro-instruction for min_int16 and max_int16 border cases. |
| 5546 // For subtracting int16 immediate values we use addiu. |
| 5547 |
| 5548 struct TestCaseSubu { |
| 5549 uint32_t imm; |
| 5550 uint32_t expected_res; |
| 5551 int32_t num_instr; |
| 5552 }; |
| 5553 |
| 5554 // We call Subu(v0, zero_reg, imm) to test cases listed below. |
| 5555 // 0 - imm = expected_res |
| 5556 struct TestCaseSubu tc[] = { |
| 5557 // imm, expected_res, num_instr |
| 5558 {0xffff8000, 0x00008000, 2}, // min_int16 |
| 5559 // Generates ori + addu |
| 5560 // We can't have just addiu because -min_int16 > max_int16 so use |
| 5561 // register. We can load min_int16 to at register with addiu and then |
| 5562 // subtract at with subu, but now we use ori + addu because -min_int16 can |
| 5563 // be loaded using ori. |
| 5564 {0x8000, 0xffff8000, 1}, // max_int16 + 1 |
| 5565 // Generates addiu |
| 5566 // max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use addiu. |
| 5567 {0xffff7fff, 0x8001, 2}, // min_int16 - 1 |
| 5568 // Generates ori + addu |
| 5569 // To load this value to at we need two instructions and another one to |
| 5570 // subtract, lui + ori + subu. But we can load -value to at using just |
| 5571 // ori and then add at register with addu. |
| 5572 {0x8001, 0xffff7fff, 2}, // max_int16 + 2 |
| 5573 // Generates ori + subu |
| 5574 // Not int16 but is uint16, load value to at with ori and subtract with |
| 5575 // subu. |
| 5576 {0x00010000, 0xffff0000, 2}, |
| 5577 // Generates lui + subu |
| 5578 // Load value using lui to at and subtract with subu. |
| 5579 {0x00010001, 0xfffeffff, 3}, |
| 5580 // Generates lui + ori + subu |
| 5581 // We have to generate three instructions in this case. |
| 5582 }; |
| 5583 |
| 5584 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseSubu); |
| 5585 for (size_t i = 0; i < nr_test_cases; ++i) { |
| 5586 CHECK_EQ(tc[i].expected_res, run_Subu(tc[i].imm, tc[i].num_instr)); |
| 5587 } |
| 5588 } |
| 5589 |
5516 #undef __ | 5590 #undef __ |
OLD | NEW |