MIPS: use DAHI/DATH for li macro on mips64r6.

BUG=

Review URL: https://codereview.chromium.org/1522573002

Cr-Commit-Position: refs/heads/master@{#34176}
This commit is contained in:
alan.li 2016-02-20 08:24:13 -08:00 committed by Commit bot
parent 4efc32ea3e
commit 1f5b84e467
2 changed files with 132 additions and 32 deletions

View File

@ -1376,39 +1376,71 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
ori(rd, rd, (j.imm64_ & kImm16Mask));
}
} else {
if (is_int48(j.imm64_)) {
if ((j.imm64_ >> 32) & kImm16Mask) {
lui(rd, (j.imm64_ >> 32) & kImm16Mask);
if ((j.imm64_ >> 16) & kImm16Mask) {
ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
}
} else {
ori(rd, zero_reg, (j.imm64_ >> 16) & kImm16Mask);
if (kArchVariant == kMips64r6) {
int64_t imm = j.imm64_;
bool lui_emited = false;
if (((imm >> kLuiShift) & kImm16Mask) != 0) {
lui(rd, (imm >> kLuiShift) & kImm16Mask);
lui_emited = true;
}
dsll(rd, rd, 16);
if (j.imm64_ & kImm16Mask) {
ori(rd, rd, j.imm64_ & kImm16Mask);
if ((imm & kImm16Mask) != 0) {
ori(rd, rd, (imm & kImm16Mask));
} else if (!lui_emited) {
or_(rd, zero_reg, zero_reg);
}
if ((imm >> 31) & 0x1) {
imm = (imm >> 32) + 1;
} else {
imm = imm >> 32;
}
if (imm & kImm16Mask) {
dahi(rd, imm & kImm16Mask);
}
if (!is_int48(j.imm64_)) {
if ((imm >> 15) & 0x1) {
imm = (imm >> 16) + 1;
} else {
imm = imm >> 16;
}
if (imm & kImm16Mask) {
dati(rd, imm & kImm16Mask);
}
}
} else {
lui(rd, (j.imm64_ >> 48) & kImm16Mask);
if ((j.imm64_ >> 32) & kImm16Mask) {
ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
}
if ((j.imm64_ >> 16) & kImm16Mask) {
dsll(rd, rd, 16);
ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
if (j.imm64_ & kImm16Mask) {
dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
if (is_int48(j.imm64_)) {
if ((j.imm64_ >> 32) & kImm16Mask) {
lui(rd, (j.imm64_ >> 32) & kImm16Mask);
if ((j.imm64_ >> 16) & kImm16Mask) {
ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
}
} else {
dsll(rd, rd, 16);
ori(rd, zero_reg, (j.imm64_ >> 16) & kImm16Mask);
}
dsll(rd, rd, 16);
if (j.imm64_ & kImm16Mask) {
ori(rd, rd, j.imm64_ & kImm16Mask);
}
} else {
if (j.imm64_ & kImm16Mask) {
dsll32(rd, rd, 0);
ori(rd, rd, j.imm64_ & kImm16Mask);
lui(rd, (j.imm64_ >> 48) & kImm16Mask);
if ((j.imm64_ >> 32) & kImm16Mask) {
ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
}
if ((j.imm64_ >> 16) & kImm16Mask) {
dsll(rd, rd, 16);
ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
if (j.imm64_ & kImm16Mask) {
dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
} else {
dsll(rd, rd, 16);
}
} else {
dsll32(rd, rd, 0);
if (j.imm64_ & kImm16Mask) {
dsll32(rd, rd, 0);
ori(rd, rd, j.imm64_ & kImm16Mask);
} else {
dsll32(rd, rd, 0);
}
}
}
}
@ -1427,12 +1459,32 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
} else {
lui(rd, (j.imm64_ >> 48) & kImm16Mask);
ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
dsll(rd, rd, 16);
ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
if (kArchVariant == kMips64r6) {
int64_t imm = j.imm64_;
lui(rd, (imm >> kLuiShift) & kImm16Mask);
if (imm & kImm16Mask) {
ori(rd, rd, (imm & kImm16Mask));
}
if ((imm >> 31) & 0x1) {
imm = (imm >> 32) + 1;
} else {
imm = imm >> 32;
}
dahi(rd, imm & kImm16Mask);
if ((imm >> 15) & 0x1) {
imm = (imm >> 16) + 1;
} else {
imm = imm >> 16;
}
dati(rd, imm & kImm16Mask);
} else {
lui(rd, (j.imm64_ >> 48) & kImm16Mask);
ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
dsll(rd, rd, 16);
ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
}
}
}

View File

@ -5008,6 +5008,54 @@ TEST(r6_aui_family) {
}
uint64_t run_li_macro(uint64_t rs, LiFlags mode) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
__ li(a0, rs, mode);
__ mov(v0, a0);
__ 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(li_macro) {
CcTest::InitializeVM();
uint64_t inputs[] = {
0x0000000000000000, 0x000000000000ffff, 0x00000000ffffffff,
0x0000ffffffffffff, 0xffffffffffffffff, 0xffff000000000000,
0xffffffff00000000, 0xffffffffffff0000, 0xffff0000ffff0000,
0x0000ffffffff0000, 0x0000ffff0000ffff,
};
size_t nr_test_cases = sizeof(inputs) / sizeof(inputs[0]);
for (size_t i = 0; i < nr_test_cases; ++i) {
uint64_t res = run_li_macro(inputs[i], OPTIMIZE_SIZE);
CHECK_EQ(inputs[i], res);
res = run_li_macro(inputs[i], CONSTANT_SIZE);
CHECK_EQ(inputs[i], res);
if (is_int48(inputs[i])) {
res = run_li_macro(inputs[i], ADDRESS_LOAD);
CHECK_EQ(inputs[i], res);
}
}
}
uint64_t run_lwpc(int offset) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);