MIPS[64]: Fix jump_tables6 test for r6 architectures
This patch fixes jump_tables6 test for mips32r6 and mips64r6. This is regression from CL: https://crrev.com/d735f3ab12061f0a588b3f0538f9229cf747f818 BUG= Review-Url: https://codereview.chromium.org/2547033002 Cr-Commit-Position: refs/heads/master@{#41543}
This commit is contained in:
parent
a25e768864
commit
c35cc1419c
@ -552,6 +552,17 @@ class Assembler : public AssemblerBase {
|
|||||||
static const int kDebugBreakSlotLength =
|
static const int kDebugBreakSlotLength =
|
||||||
kDebugBreakSlotInstructions * kInstrSize;
|
kDebugBreakSlotInstructions * kInstrSize;
|
||||||
|
|
||||||
|
// Max offset for instructions with 16-bit offset field
|
||||||
|
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
||||||
|
|
||||||
|
// Max offset for compact branch instructions with 26-bit offset field
|
||||||
|
static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
|
||||||
|
|
||||||
|
#ifdef _MIPS_ARCH_MIPS32R6
|
||||||
|
static const int kTrampolineSlotsSize = 2 * kInstrSize;
|
||||||
|
#else
|
||||||
|
static const int kTrampolineSlotsSize = 4 * kInstrSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Code generation.
|
// Code generation.
|
||||||
@ -1166,6 +1177,9 @@ class Assembler : public AssemblerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
|
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
|
||||||
|
static bool IsCompactBranchSupported() {
|
||||||
|
return IsMipsArchVariant(kMips32r6);
|
||||||
|
}
|
||||||
|
|
||||||
inline int UnboundLabelsCount() { return unbound_labels_count_; }
|
inline int UnboundLabelsCount() { return unbound_labels_count_; }
|
||||||
|
|
||||||
@ -1440,13 +1454,6 @@ class Assembler : public AssemblerBase {
|
|||||||
// branch instruction generation, where we use jump instructions rather
|
// branch instruction generation, where we use jump instructions rather
|
||||||
// than regular branch instructions.
|
// than regular branch instructions.
|
||||||
bool trampoline_emitted_;
|
bool trampoline_emitted_;
|
||||||
#ifdef _MIPS_ARCH_MIPS32R6
|
|
||||||
static const int kTrampolineSlotsSize = 2 * kInstrSize;
|
|
||||||
#else
|
|
||||||
static const int kTrampolineSlotsSize = 4 * kInstrSize;
|
|
||||||
#endif
|
|
||||||
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
|
||||||
static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
|
|
||||||
static const int kInvalidSlotPos = -1;
|
static const int kInvalidSlotPos = -1;
|
||||||
|
|
||||||
// Internal reference positions, required for unbounded internal reference
|
// Internal reference positions, required for unbounded internal reference
|
||||||
|
@ -208,6 +208,12 @@ class MacroAssembler: public Assembler {
|
|||||||
Heap::RootListIndex index,
|
Heap::RootListIndex index,
|
||||||
BranchDelaySlot bdslot = PROTECT);
|
BranchDelaySlot bdslot = PROTECT);
|
||||||
|
|
||||||
|
// Number of instructions needed for calculation of switch table entry address
|
||||||
|
#ifdef _MIPS_ARCH_MIPS32R6
|
||||||
|
static const int kSwitchTablePrologueSize = 5;
|
||||||
|
#else
|
||||||
|
static const int kSwitchTablePrologueSize = 10;
|
||||||
|
#endif
|
||||||
// GetLabelFunction must be lambda '[](size_t index) -> Label*' or a
|
// GetLabelFunction must be lambda '[](size_t index) -> Label*' or a
|
||||||
// functor/function with 'Label *func(size_t index)' declaration.
|
// functor/function with 'Label *func(size_t index)' declaration.
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
@ -1832,13 +1838,13 @@ template <typename Func>
|
|||||||
void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count,
|
void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count,
|
||||||
Func GetLabelFunction) {
|
Func GetLabelFunction) {
|
||||||
if (kArchVariant >= kMips32r6) {
|
if (kArchVariant >= kMips32r6) {
|
||||||
BlockTrampolinePoolFor(case_count + 5);
|
BlockTrampolinePoolFor(case_count + kSwitchTablePrologueSize);
|
||||||
addiupc(at, 5);
|
addiupc(at, 5);
|
||||||
Lsa(at, at, index, kPointerSizeLog2);
|
Lsa(at, at, index, kPointerSizeLog2);
|
||||||
lw(at, MemOperand(at));
|
lw(at, MemOperand(at));
|
||||||
} else {
|
} else {
|
||||||
Label here;
|
Label here;
|
||||||
BlockTrampolinePoolFor(case_count + 10);
|
BlockTrampolinePoolFor(case_count + kSwitchTablePrologueSize);
|
||||||
push(ra);
|
push(ra);
|
||||||
bal(&here);
|
bal(&here);
|
||||||
sll(at, index, kPointerSizeLog2); // Branch delay slot.
|
sll(at, index, kPointerSizeLog2); // Branch delay slot.
|
||||||
|
@ -559,6 +559,13 @@ class Assembler : public AssemblerBase {
|
|||||||
static const int kDebugBreakSlotLength =
|
static const int kDebugBreakSlotLength =
|
||||||
kDebugBreakSlotInstructions * kInstrSize;
|
kDebugBreakSlotInstructions * kInstrSize;
|
||||||
|
|
||||||
|
// Max offset for instructions with 16-bit offset field
|
||||||
|
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
||||||
|
|
||||||
|
// Max offset for compact branch instructions with 26-bit offset field
|
||||||
|
static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
|
||||||
|
|
||||||
|
static const int kTrampolineSlotsSize = 2 * kInstrSize;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Code generation.
|
// Code generation.
|
||||||
@ -1223,6 +1230,7 @@ class Assembler : public AssemblerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
|
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
|
||||||
|
static bool IsCompactBranchSupported() { return kArchVariant == kMips64r6; }
|
||||||
|
|
||||||
inline int UnboundLabelsCount() { return unbound_labels_count_; }
|
inline int UnboundLabelsCount() { return unbound_labels_count_; }
|
||||||
|
|
||||||
@ -1495,9 +1503,6 @@ class Assembler : public AssemblerBase {
|
|||||||
// branch instruction generation, where we use jump instructions rather
|
// branch instruction generation, where we use jump instructions rather
|
||||||
// than regular branch instructions.
|
// than regular branch instructions.
|
||||||
bool trampoline_emitted_;
|
bool trampoline_emitted_;
|
||||||
static const int kTrampolineSlotsSize = 2 * kInstrSize;
|
|
||||||
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
|
||||||
static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
|
|
||||||
static const int kInvalidSlotPos = -1;
|
static const int kInvalidSlotPos = -1;
|
||||||
|
|
||||||
// Internal reference positions, required for unbounded internal reference
|
// Internal reference positions, required for unbounded internal reference
|
||||||
|
@ -236,6 +236,13 @@ class MacroAssembler: public Assembler {
|
|||||||
Heap::RootListIndex index,
|
Heap::RootListIndex index,
|
||||||
BranchDelaySlot bdslot = PROTECT);
|
BranchDelaySlot bdslot = PROTECT);
|
||||||
|
|
||||||
|
// Number of instructions needed for calculation of switch table entry address
|
||||||
|
#ifdef _MIPS_ARCH_MIPS64R6
|
||||||
|
static const int kSwitchTablePrologueSize = 6;
|
||||||
|
#else
|
||||||
|
static const int kSwitchTablePrologueSize = 11;
|
||||||
|
#endif
|
||||||
|
|
||||||
// GetLabelFunction must be lambda '[](size_t index) -> Label*' or a
|
// GetLabelFunction must be lambda '[](size_t index) -> Label*' or a
|
||||||
// functor/function with 'Label *func(size_t index)' declaration.
|
// functor/function with 'Label *func(size_t index)' declaration.
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
@ -1974,7 +1981,8 @@ void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count,
|
|||||||
// Ensure that dd-ed labels following this instruction use 8 bytes aligned
|
// Ensure that dd-ed labels following this instruction use 8 bytes aligned
|
||||||
// addresses.
|
// addresses.
|
||||||
if (kArchVariant >= kMips64r6) {
|
if (kArchVariant >= kMips64r6) {
|
||||||
BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 6);
|
BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 +
|
||||||
|
kSwitchTablePrologueSize);
|
||||||
// Opposite of Align(8) as we have odd number of instructions in this case.
|
// Opposite of Align(8) as we have odd number of instructions in this case.
|
||||||
if ((pc_offset() & 7) == 0) {
|
if ((pc_offset() & 7) == 0) {
|
||||||
nop();
|
nop();
|
||||||
@ -1984,7 +1992,8 @@ void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count,
|
|||||||
ld(at, MemOperand(at));
|
ld(at, MemOperand(at));
|
||||||
} else {
|
} else {
|
||||||
Label here;
|
Label here;
|
||||||
BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 11);
|
BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 +
|
||||||
|
kSwitchTablePrologueSize);
|
||||||
Align(8);
|
Align(8);
|
||||||
push(ra);
|
push(ra);
|
||||||
bal(&here);
|
bal(&here);
|
||||||
|
@ -297,16 +297,21 @@ TEST(jump_tables6) {
|
|||||||
v8::internal::CodeObjectRequired::kYes);
|
v8::internal::CodeObjectRequired::kYes);
|
||||||
MacroAssembler* masm = &assembler;
|
MacroAssembler* masm = &assembler;
|
||||||
|
|
||||||
const int kNumCases = 40;
|
const int kSwitchTableCases = 40;
|
||||||
const int kFillInstr = 32551;
|
|
||||||
const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
const int kInstrSize = Assembler::kInstrSize;
|
||||||
const int kTrampolineSlotsSize = 4 * Instruction::kInstrSize;
|
const int kMaxBranchOffset = Assembler::kMaxBranchOffset;
|
||||||
|
const int kTrampolineSlotsSize = Assembler::kTrampolineSlotsSize;
|
||||||
|
const int kSwitchTablePrologueSize = MacroAssembler::kSwitchTablePrologueSize;
|
||||||
|
|
||||||
const int kMaxOffsetForTrampolineStart =
|
const int kMaxOffsetForTrampolineStart =
|
||||||
kMaxBranchOffset - 16 * kTrampolineSlotsSize;
|
kMaxBranchOffset - 16 * kTrampolineSlotsSize;
|
||||||
|
const int kFillInstr = (kMaxOffsetForTrampolineStart / kInstrSize) -
|
||||||
|
(kSwitchTablePrologueSize + kSwitchTableCases) - 20;
|
||||||
|
|
||||||
int values[kNumCases];
|
int values[kSwitchTableCases];
|
||||||
isolate->random_number_generator()->NextBytes(values, sizeof(values));
|
isolate->random_number_generator()->NextBytes(values, sizeof(values));
|
||||||
Label labels[kNumCases];
|
Label labels[kSwitchTableCases];
|
||||||
Label near_start, end, done;
|
Label near_start, end, done;
|
||||||
|
|
||||||
__ Push(ra);
|
__ Push(ra);
|
||||||
@ -316,7 +321,7 @@ TEST(jump_tables6) {
|
|||||||
int gen_insn = 0;
|
int gen_insn = 0;
|
||||||
|
|
||||||
__ Branch(&end);
|
__ Branch(&end);
|
||||||
gen_insn += 2;
|
gen_insn += Assembler::IsCompactBranchSupported() ? 1 : 2;
|
||||||
__ bind(&near_start);
|
__ bind(&near_start);
|
||||||
|
|
||||||
// Generate slightly less than 32K instructions, which will soon require
|
// Generate slightly less than 32K instructions, which will soon require
|
||||||
@ -326,23 +331,24 @@ TEST(jump_tables6) {
|
|||||||
}
|
}
|
||||||
gen_insn += kFillInstr;
|
gen_insn += kFillInstr;
|
||||||
|
|
||||||
__ GenerateSwitchTable(a0, kNumCases,
|
__ GenerateSwitchTable(a0, kSwitchTableCases,
|
||||||
[&labels](size_t i) { return labels + i; });
|
[&labels](size_t i) { return labels + i; });
|
||||||
gen_insn += (10 + kNumCases);
|
gen_insn += (kSwitchTablePrologueSize + kSwitchTableCases);
|
||||||
|
|
||||||
for (int i = 0; i < kNumCases; ++i) {
|
for (int i = 0; i < kSwitchTableCases; ++i) {
|
||||||
__ bind(&labels[i]);
|
__ bind(&labels[i]);
|
||||||
__ li(v0, values[i]);
|
__ li(v0, values[i]);
|
||||||
__ Branch(&done);
|
__ Branch(&done);
|
||||||
}
|
}
|
||||||
gen_insn += (4 * kNumCases);
|
gen_insn +=
|
||||||
|
((Assembler::IsCompactBranchSupported() ? 3 : 4) * kSwitchTableCases);
|
||||||
|
|
||||||
// If offset from here to first branch instr is greater than max allowed
|
// If offset from here to first branch instr is greater than max allowed
|
||||||
// offset for trampoline ...
|
// offset for trampoline ...
|
||||||
CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
|
CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
|
||||||
// ... number of generated instructions must be greater then "gen_insn",
|
// ... number of generated instructions must be greater then "gen_insn",
|
||||||
// as we are expecting trampoline generation
|
// as we are expecting trampoline generation
|
||||||
CHECK_LT(gen_insn, (masm->pc_offset() - offs1) / Instruction::kInstrSize);
|
CHECK_LT(gen_insn, (masm->pc_offset() - offs1) / kInstrSize);
|
||||||
|
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
__ Pop(ra);
|
__ Pop(ra);
|
||||||
@ -360,7 +366,7 @@ TEST(jump_tables6) {
|
|||||||
code->Print(std::cout);
|
code->Print(std::cout);
|
||||||
#endif
|
#endif
|
||||||
F1 f = FUNCTION_CAST<F1>(code->entry());
|
F1 f = FUNCTION_CAST<F1>(code->entry());
|
||||||
for (int i = 0; i < kNumCases; ++i) {
|
for (int i = 0; i < kSwitchTableCases; ++i) {
|
||||||
int res =
|
int res =
|
||||||
reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
|
reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
|
||||||
::printf("f(%d) = %d\n", i, res);
|
::printf("f(%d) = %d\n", i, res);
|
||||||
|
@ -365,16 +365,22 @@ TEST(jump_tables6) {
|
|||||||
v8::internal::CodeObjectRequired::kYes);
|
v8::internal::CodeObjectRequired::kYes);
|
||||||
MacroAssembler* masm = &assembler;
|
MacroAssembler* masm = &assembler;
|
||||||
|
|
||||||
const int kNumCases = 40;
|
const int kSwitchTableCases = 40;
|
||||||
const int kFillInstr = 32551;
|
|
||||||
const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
|
const int kInstrSize = Assembler::kInstrSize;
|
||||||
const int kTrampolineSlotsSize = 2 * Instruction::kInstrSize;
|
const int kMaxBranchOffset = Assembler::kMaxBranchOffset;
|
||||||
|
const int kTrampolineSlotsSize = Assembler::kTrampolineSlotsSize;
|
||||||
|
const int kSwitchTablePrologueSize = MacroAssembler::kSwitchTablePrologueSize;
|
||||||
|
|
||||||
const int kMaxOffsetForTrampolineStart =
|
const int kMaxOffsetForTrampolineStart =
|
||||||
kMaxBranchOffset - 16 * kTrampolineSlotsSize;
|
kMaxBranchOffset - 16 * kTrampolineSlotsSize;
|
||||||
|
const int kFillInstr = (kMaxOffsetForTrampolineStart / kInstrSize) -
|
||||||
|
(kSwitchTablePrologueSize + 2 * kSwitchTableCases) -
|
||||||
|
20;
|
||||||
|
|
||||||
int values[kNumCases];
|
int values[kSwitchTableCases];
|
||||||
isolate->random_number_generator()->NextBytes(values, sizeof(values));
|
isolate->random_number_generator()->NextBytes(values, sizeof(values));
|
||||||
Label labels[kNumCases];
|
Label labels[kSwitchTableCases];
|
||||||
Label near_start, end, done;
|
Label near_start, end, done;
|
||||||
|
|
||||||
__ Push(ra);
|
__ Push(ra);
|
||||||
@ -384,7 +390,7 @@ TEST(jump_tables6) {
|
|||||||
int gen_insn = 0;
|
int gen_insn = 0;
|
||||||
|
|
||||||
__ Branch(&end);
|
__ Branch(&end);
|
||||||
gen_insn += 2;
|
gen_insn += Assembler::IsCompactBranchSupported() ? 1 : 2;
|
||||||
__ bind(&near_start);
|
__ bind(&near_start);
|
||||||
|
|
||||||
// Generate slightly less than 32K instructions, which will soon require
|
// Generate slightly less than 32K instructions, which will soon require
|
||||||
@ -394,23 +400,24 @@ TEST(jump_tables6) {
|
|||||||
}
|
}
|
||||||
gen_insn += kFillInstr;
|
gen_insn += kFillInstr;
|
||||||
|
|
||||||
__ GenerateSwitchTable(a0, kNumCases,
|
__ GenerateSwitchTable(a0, kSwitchTableCases,
|
||||||
[&labels](size_t i) { return labels + i; });
|
[&labels](size_t i) { return labels + i; });
|
||||||
gen_insn += (11 + 2 * kNumCases);
|
gen_insn += (kSwitchTablePrologueSize + 2 * kSwitchTableCases);
|
||||||
|
|
||||||
for (int i = 0; i < kNumCases; ++i) {
|
for (int i = 0; i < kSwitchTableCases; ++i) {
|
||||||
__ bind(&labels[i]);
|
__ bind(&labels[i]);
|
||||||
__ li(v0, values[i]);
|
__ li(v0, values[i]);
|
||||||
__ Branch(&done);
|
__ Branch(&done);
|
||||||
}
|
}
|
||||||
gen_insn += (4 * kNumCases);
|
gen_insn +=
|
||||||
|
((Assembler::IsCompactBranchSupported() ? 3 : 4) * kSwitchTableCases);
|
||||||
|
|
||||||
// If offset from here to first branch instr is greater than max allowed
|
// If offset from here to first branch instr is greater than max allowed
|
||||||
// offset for trampoline ...
|
// offset for trampoline ...
|
||||||
CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
|
CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
|
||||||
// ... number of generated instructions must be greater then "gen_insn",
|
// ... number of generated instructions must be greater then "gen_insn",
|
||||||
// as we are expecting trampoline generation
|
// as we are expecting trampoline generation
|
||||||
CHECK_LT(gen_insn, (masm->pc_offset() - offs1) / Instruction::kInstrSize);
|
CHECK_LT(gen_insn, (masm->pc_offset() - offs1) / kInstrSize);
|
||||||
|
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
__ Pop(ra);
|
__ Pop(ra);
|
||||||
@ -428,7 +435,7 @@ TEST(jump_tables6) {
|
|||||||
code->Print(std::cout);
|
code->Print(std::cout);
|
||||||
#endif
|
#endif
|
||||||
F1 f = FUNCTION_CAST<F1>(code->entry());
|
F1 f = FUNCTION_CAST<F1>(code->entry());
|
||||||
for (int i = 0; i < kNumCases; ++i) {
|
for (int i = 0; i < kSwitchTableCases; ++i) {
|
||||||
int64_t res = reinterpret_cast<int64_t>(
|
int64_t res = reinterpret_cast<int64_t>(
|
||||||
CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
|
CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
|
||||||
::printf("f(%d) = %" PRId64 "\n", i, res);
|
::printf("f(%d) = %" PRId64 "\n", i, res);
|
||||||
|
Loading…
Reference in New Issue
Block a user