Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: test/cctest/test-assembler-mips64.cc

Issue 2892163002: MIPS64: Add optimizations to li macro. (Closed)
Patch Set: Add Subu optimization Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 6039 matching lines...) Expand 10 before | Expand all | Expand 10 after
6050 TEST(maddf_msubf_d) { 6050 TEST(maddf_msubf_d) {
6051 if (kArchVariant != kMips64r6) return; 6051 if (kArchVariant != kMips64r6) return;
6052 helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) { 6052 helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) {
6053 __ maddf_d(f4, f6, f8); 6053 __ maddf_d(f4, f6, f8);
6054 __ Sdc1(f4, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add))); 6054 __ Sdc1(f4, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add)));
6055 __ msubf_d(f16, f6, f8); 6055 __ msubf_d(f16, f6, f8);
6056 __ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub))); 6056 __ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub)));
6057 }); 6057 });
6058 } 6058 }
6059 6059
6060 uint64_t run_Subu(uint64_t imm, int32_t num_instr) {
6061 Isolate* isolate = CcTest::i_isolate();
6062 HandleScope scope(isolate);
6063
6064 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
6065
6066 Label code_start;
6067 __ bind(&code_start);
6068 __ Subu(v0, zero_reg, Operand(imm));
6069 CHECK_EQ(assm.SizeOfCodeGeneratedSince(&code_start),
6070 num_instr * Assembler::kInstrSize);
6071 __ jr(ra);
6072 __ nop();
6073
6074 CodeDesc desc;
6075 assm.GetCode(&desc);
6076 Handle<Code> code = isolate->factory()->NewCode(
6077 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
6078 F2 f = FUNCTION_CAST<F2>(code->entry());
6079
6080 uint64_t res = reinterpret_cast<uint64_t>(
6081 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
6082
6083 return res;
6084 }
6085
6086 TEST(Subu) {
6087 CcTest::InitializeVM();
6088
6089 // Test Subu macro-instruction for min_int16 and max_int16 border cases.
6090 // For subtracting int16 immediate values we use addiu.
6091
6092 struct TestCaseSubu {
6093 uint64_t imm;
6094 uint64_t expected_res;
6095 int32_t num_instr;
6096 };
6097
6098 // We call Subu(v0, zero_reg, imm) to test cases listed below.
6099 // 0 - imm = expected_res
6100 struct TestCaseSubu tc[] = {
6101 // imm, expected_res, num_instr
6102 {0xffffffffffff8000, 0x8000, 2}, // min_int16
6103 // Generates ori + addu
6104 // We can't have just addiu because -min_int16 > max_int16 so use
6105 // register. We can load min_int16 to at register with addiu and then
6106 // subtract at with subu, but now we use ori + addu because -min_int16 can
6107 // be loaded using ori.
6108 {0x8000, 0xffffffffffff8000, 1}, // max_int16 + 1
6109 // Generates addiu
6110 // max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use addiu.
6111 {0xffffffffffff7fff, 0x8001, 2}, // min_int16 - 1
6112 // Generates ori + addu
6113 // To load this value to at we need two instructions and another one to
6114 // subtract, lui + ori + subu. But we can load -value to at using just
6115 // ori and then add at register with addu.
6116 {0x8001, 0xffffffffffff7fff, 2}, // max_int16 + 2
6117 // Generates ori + subu
6118 // Not int16 but is uint16, load value to at with ori and subtract with
6119 // subu.
6120 {0x00010000, 0xffffffffffff0000, 2},
6121 // Generates lui + subu
6122 // Load value using lui to at and subtract with subu.
6123 {0x00010001, 0xfffffffffffeffff, 3},
6124 // Generates lui + ori + subu
6125 // We have to generate three instructions in this case.
6126 };
6127
6128 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseSubu);
6129 for (size_t i = 0; i < nr_test_cases; ++i) {
6130 CHECK_EQ(tc[i].expected_res, run_Subu(tc[i].imm, tc[i].num_instr));
6131 }
6132 }
6133
6134 uint64_t run_li(uint64_t imm, int32_t num_instr) {
6135 Isolate* isolate = CcTest::i_isolate();
6136 HandleScope scope(isolate);
6137
6138 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
6139
6140 Label code_start;
6141 __ bind(&code_start);
6142 __ li(v0, Operand(imm));
6143 CHECK_EQ(assm.SizeOfCodeGeneratedSince(&code_start),
6144 num_instr * Assembler::kInstrSize);
6145 __ jr(ra);
6146 __ nop();
6147
6148 CodeDesc desc;
6149 assm.GetCode(&desc);
6150 Handle<Code> code = isolate->factory()->NewCode(
6151 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
6152 F2 f = FUNCTION_CAST<F2>(code->entry());
6153
6154 uint64_t res = reinterpret_cast<uint64_t>(
6155 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
6156
6157 return res;
6158 }
6159
6160 TEST(li) {
6161 CcTest::InitializeVM();
6162
6163 // Test li macro-instruction for border cases.
6164
6165 struct TestCase_li {
6166 uint64_t imm;
6167 int32_t r2_num_instr;
6168 int32_t r6_num_instr;
6169 };
6170
6171 // We call li(v0, imm) to test cases listed below.
6172 struct TestCase_li tc[] = {
6173 // imm, r2_num_instr, r6_num_instr
6174 {0xffffffffffff8000, 1, 1}, // min_int16
6175 // Generates daddiu
6176 // This is int16 value and we can load it using just daddiu.
6177 {0x8000, 1, 1}, // max_int16 + 1
6178 // Generates ori
6179 // max_int16 + 1 is not int16 but is uint16, just use ori.
6180 {0xffffffffffff7fff, 2, 2}, // min_int16 - 1
6181 // Generates lui + ori
6182 // We load int32 value using lui + ori.
6183 {0x8001, 1, 1}, // max_int16 + 2
6184 // Generates ori
6185 // Also an uint16 value, use ori.
6186 {0x00010000, 1, 1}, // max_uint16 + 1
6187 // Generates lui
6188 // Low 16 bits are 0, load value using lui.
6189 {0x00010001, 2, 2}, // max_uint16 + 2
6190 // Generates lui + ori
6191 // We have to generate two instructions in this case.
6192 {0x00000000ffffffff, 2, 2}, // max_uint32
6193 // r2 - daddiu + dsrl32
6194 // r6 - daddiu + dahi
6195 {0x00000000fffffffe, 3, 2}, // max_uint32 - 1
6196 // r2 - lui + ori + dsll
6197 // r6 - daddiu + dahi
6198 {0x00ffff000000fffe, 3, 3},
6199 // ori + dsll32 + ori
6200 {0x00000001fffffffe, 4, 2}, // max_uint32 << 1
6201 // r2 - lui + ori + dsll + ori
6202 // r6 - daddiu + dahi
6203 {0x0000fffffffffffe, 5, 2}, // max_uint48 - 1
6204 // r2 - ori + dsll + ori + dsll + ori
6205 // r6 - daddiu + dati
6206 {0xffffffff00000000, 2, 2}, // max_uint32 << 32
6207 // r2 - daddiu + dsll32
6208 // r6 - ori + dahi
6209 // We need ori to clear register before loading value using dahi.
6210 {0xffffffff80000000, 1, 1}, // min_int32
6211 // lui
6212 {0x0000000080000000, 2, 2}, // max_int32 + 1
6213 // r2 - ori + dsll
6214 // r6 - lui + dahi
6215 {0x0000800000000000, 2, 2},
6216 // ori + dsll32
6217 {0xffff800000000000, 2, 2},
6218 // r2 - daddiu + dsll32
6219 // r6 - ori + dahi
6220 {0xffff80000000ffff, 3, 2},
6221 // r2 - daddiu + dsll32 + ori
6222 // r6 - ori + dahi
6223 {0xffffff123000ffff, 3, 3},
6224 // daddiu + dsll + ori
6225 {0xffff00000000ffff, 3, 2},
6226 // r2 - daddiu + dsll32 + ori
6227 // r6 - ori + dati
6228 {0xffff8000ffff0000, 3, 2},
6229 // r2 - lui + ori + dsll
6230 // r6 - lui + dahi
6231 {0x1234ffff80000000, 3, 2},
6232 // r2 - lui + ori + dsll
6233 // r6 - lui + dati
6234 {0x1234ffff80010000, 5, 2},
6235 // r2 - lui + ori + dsll + ori + dsll
6236 // r6 - lui + dati
6237 {0xffff8000ffff8000, 2, 2},
6238 // r2 - daddiu + dinsu
6239 // r6 - daddiu + dahi
6240 {0xffff0000ffff8000, 5, 3},
6241 // r2 - lui + dsll + ori + dsll + ori
6242 // r6 - daddiu + dahi + dati
6243 {0x8000000080000000, 2, 2},
6244 // lui + dinsu
6245 {0xabcd0000abcd0000, 2, 2},
6246 // lui + dinsu
6247 {0x8000800080008000, 3, 3},
6248 // lui + ori + dinsu
6249 {0xabcd1234abcd1234, 3, 3},
6250 // lui + ori + dinsu
6251 {0xffff800080008000, 4, 3},
6252 // r2 - lui + ori + dsll + ori
6253 // r6 - lui + ori + dahi
6254 {0xffffabcd, 3, 2},
6255 // r2 - ori + dsll + ori
6256 // r6 - daddiu + dahi
6257 {0x1ffffabcd, 4, 2},
6258 // r2 - lui + ori + dsll + ori
6259 // r6 - daddiu + dahi
6260 {0xffffffffabcd, 5, 2},
6261 // r2 - ori + dsll + ori + dsll + ori
6262 // r6 - daddiu + dati
6263 {0x1ffffffffabcd, 6, 2},
6264 // r2 - lui + ori + dsll + ori + dsll + ori
6265 // r6 - daddiu + dati
6266 {0xffff7fff80010000, 5, 2},
6267 // r2 - lui + ori + dsll + ori + dsll
6268 // r6 - lui + dahi
6269 // Here lui sets high 32 bits to 1 so dahi can be used to get target
6270 // value.
6271 {0x00007fff7fff0000, 3, 2},
6272 // r2 - lui + ori + dsll
6273 // r6 - lui + dahi
6274 // High 32 bits are not set so dahi can be used to get target value.
6275 {0xffff7fff7fff0000, 5, 3},
6276 // r2 - lui + ori + dsll + ori + dsll
6277 // r6 - lui + dahi + dati
6278 // High 32 bits are not set so just dahi can't be used to get target
6279 // value.
6280 {0x00007fff80010000, 3, 3},
6281 // r2 - lui + ori + dsll
6282 // r6 - lui + ori + dsll
6283 // High 32 bits are set so just dahi can't be used to get target value.
6284 };
6285
6286 size_t nr_test_cases = sizeof(tc) / sizeof(TestCase_li);
6287 for (size_t i = 0; i < nr_test_cases; ++i) {
6288 if (kArchVariant == kMips64r2) {
6289 CHECK_EQ(tc[i].imm, run_li(tc[i].imm, tc[i].r2_num_instr));
6290 } else {
6291 CHECK_EQ(tc[i].imm, run_li(tc[i].imm, tc[i].r6_num_instr));
6292 }
6293 }
6294 }
6295
6060 uint64_t run_Dins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) { 6296 uint64_t run_Dins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) {
6061 Isolate* isolate = CcTest::i_isolate(); 6297 Isolate* isolate = CcTest::i_isolate();
6062 HandleScope scope(isolate); 6298 HandleScope scope(isolate);
6063 6299
6064 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); 6300 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
6065 6301
6066 __ li(v0, imm); 6302 __ li(v0, imm);
6067 __ li(t0, source); 6303 __ li(t0, source);
6068 __ Dins(v0, t0, pos, size); 6304 __ Dins(v0, t0, pos, size);
6069 __ jr(ra); 6305 __ jr(ra);
(...skipping 21 matching lines...) Expand all
6091 uint64_t source; 6327 uint64_t source;
6092 uint16_t pos; 6328 uint16_t pos;
6093 uint16_t size; 6329 uint16_t size;
6094 uint64_t expected_res; 6330 uint64_t expected_res;
6095 }; 6331 };
6096 6332
6097 // We load imm to v0 and source to t0 and then call 6333 // We load imm to v0 and source to t0 and then call
6098 // Dins(v0, t0, pos, size) to test cases listed below. 6334 // Dins(v0, t0, pos, size) to test cases listed below.
6099 struct TestCaseDins tc[] = { 6335 struct TestCaseDins tc[] = {
6100 // imm, source, pos, size, expected_res 6336 // imm, source, pos, size, expected_res
6101 {0x5555555555555555, 0x1ABCDEF01, 31, 1, 0x55555555D5555555}, 6337 {0x5555555555555555, 0x1abcdef01, 31, 1, 0x55555555d5555555},
6102 {0x5555555555555555, 0x1ABCDEF02, 30, 2, 0x5555555595555555}, 6338 {0x5555555555555555, 0x1abcdef02, 30, 2, 0x5555555595555555},
6103 {0x201234567, 0x1FABCDEFF, 0, 32, 0x2FABCDEFF}, 6339 {0x201234567, 0x1fabcdeff, 0, 32, 0x2fabcdeff},
6104 {0x201234567, 0x7FABCDEFF, 31, 2, 0x381234567}, 6340 {0x201234567, 0x7fabcdeff, 31, 2, 0x381234567},
6105 {0x800000000, 0x7FABCDEFF, 0, 33, 0x9FABCDEFF}, 6341 {0x800000000, 0x7fabcdeff, 0, 33, 0x9fabcdeff},
6106 {0x1234, 0xABCDABCDABCDABCD, 0, 64, 0xABCDABCDABCDABCD}, 6342 {0x1234, 0xabcdabcdabcdabcd, 0, 64, 0xabcdabcdabcdabcd},
6107 {0xABCD, 0xABCEABCF, 32, 1, 0x10000ABCD}, 6343 {0xabcd, 0xabceabcf, 32, 1, 0x10000abcd},
6108 {0xABCD, 0xABCEABCF, 63, 1, 0x800000000000ABCD}, 6344 {0xabcd, 0xabceabcf, 63, 1, 0x800000000000abcd},
6109 {0xABCD, 0xABC1ABC2ABC3ABC4, 32, 32, 0xABC3ABC40000ABCD}, 6345 {0x10000abcd, 0xabc1abc2abc3abc4, 32, 32, 0xabc3abc40000abcd},
6110 }; 6346 };
6111 6347
6112 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDins); 6348 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDins);
6113 for (size_t i = 0; i < nr_test_cases; ++i) { 6349 for (size_t i = 0; i < nr_test_cases; ++i) {
6114 CHECK_EQ(tc[i].expected_res, 6350 CHECK_EQ(tc[i].expected_res,
6115 run_Dins(tc[i].imm, tc[i].source, tc[i].pos, tc[i].size)); 6351 run_Dins(tc[i].imm, tc[i].source, tc[i].pos, tc[i].size));
6116 } 6352 }
6117 } 6353 }
6118 6354
6119 #undef __ 6355 #undef __
OLDNEW
« src/mips64/constants-mips64.h ('K') | « test/cctest/test-assembler-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698