Commit c35cc141 authored by dusan.simicic's avatar dusan.simicic Committed by Commit bot

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}
parent a25e7688
......@@ -552,6 +552,17 @@ class Assembler : public AssemblerBase {
static const int kDebugBreakSlotLength =
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.
......@@ -1166,6 +1177,9 @@ class Assembler : public AssemblerBase {
}
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
static bool IsCompactBranchSupported() {
return IsMipsArchVariant(kMips32r6);
}
inline int UnboundLabelsCount() { return unbound_labels_count_; }
......@@ -1440,13 +1454,6 @@ class Assembler : public AssemblerBase {
// branch instruction generation, where we use jump instructions rather
// than regular branch instructions.
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;
// Internal reference positions, required for unbounded internal reference
......
......@@ -208,6 +208,12 @@ class MacroAssembler: public Assembler {
Heap::RootListIndex index,
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
// functor/function with 'Label *func(size_t index)' declaration.
template <typename Func>
......@@ -1832,13 +1838,13 @@ template <typename Func>
void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count,
Func GetLabelFunction) {
if (kArchVariant >= kMips32r6) {
BlockTrampolinePoolFor(case_count + 5);
BlockTrampolinePoolFor(case_count + kSwitchTablePrologueSize);
addiupc(at, 5);
Lsa(at, at, index, kPointerSizeLog2);
lw(at, MemOperand(at));
} else {
Label here;
BlockTrampolinePoolFor(case_count + 10);
BlockTrampolinePoolFor(case_count + kSwitchTablePrologueSize);
push(ra);
bal(&here);
sll(at, index, kPointerSizeLog2); // Branch delay slot.
......
......@@ -559,6 +559,13 @@ class Assembler : public AssemblerBase {
static const int kDebugBreakSlotLength =
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.
......@@ -1223,6 +1230,7 @@ class Assembler : public AssemblerBase {
}
bool IsPrevInstrCompactBranch() { return prev_instr_compact_branch_; }
static bool IsCompactBranchSupported() { return kArchVariant == kMips64r6; }
inline int UnboundLabelsCount() { return unbound_labels_count_; }
......@@ -1495,9 +1503,6 @@ class Assembler : public AssemblerBase {
// branch instruction generation, where we use jump instructions rather
// than regular branch instructions.
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;
// Internal reference positions, required for unbounded internal reference
......
......@@ -236,6 +236,13 @@ class MacroAssembler: public Assembler {
Heap::RootListIndex index,
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
// functor/function with 'Label *func(size_t index)' declaration.
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
// addresses.
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.
if ((pc_offset() & 7) == 0) {
nop();
......@@ -1984,7 +1992,8 @@ void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count,
ld(at, MemOperand(at));
} else {
Label here;
BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 11);
BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 +
kSwitchTablePrologueSize);
Align(8);
push(ra);
bal(&here);
......
......@@ -297,16 +297,21 @@ TEST(jump_tables6) {
v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
const int kNumCases = 40;
const int kFillInstr = 32551;
const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
const int kTrampolineSlotsSize = 4 * Instruction::kInstrSize;
const int kSwitchTableCases = 40;
const int kInstrSize = Assembler::kInstrSize;
const int kMaxBranchOffset = Assembler::kMaxBranchOffset;
const int kTrampolineSlotsSize = Assembler::kTrampolineSlotsSize;
const int kSwitchTablePrologueSize = MacroAssembler::kSwitchTablePrologueSize;
const int kMaxOffsetForTrampolineStart =
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));
Label labels[kNumCases];
Label labels[kSwitchTableCases];
Label near_start, end, done;
__ Push(ra);
......@@ -316,7 +321,7 @@ TEST(jump_tables6) {
int gen_insn = 0;
__ Branch(&end);
gen_insn += 2;
gen_insn += Assembler::IsCompactBranchSupported() ? 1 : 2;
__ bind(&near_start);
// Generate slightly less than 32K instructions, which will soon require
......@@ -326,23 +331,24 @@ TEST(jump_tables6) {
}
gen_insn += kFillInstr;
__ GenerateSwitchTable(a0, kNumCases,
__ GenerateSwitchTable(a0, kSwitchTableCases,
[&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]);
__ li(v0, values[i]);
__ 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
// offset for trampoline ...
CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
// ... number of generated instructions must be greater then "gen_insn",
// 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);
__ Pop(ra);
......@@ -360,7 +366,7 @@ TEST(jump_tables6) {
code->Print(std::cout);
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
for (int i = 0; i < kNumCases; ++i) {
for (int i = 0; i < kSwitchTableCases; ++i) {
int res =
reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
::printf("f(%d) = %d\n", i, res);
......
......@@ -365,16 +365,22 @@ TEST(jump_tables6) {
v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
const int kNumCases = 40;
const int kFillInstr = 32551;
const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
const int kTrampolineSlotsSize = 2 * Instruction::kInstrSize;
const int kSwitchTableCases = 40;
const int kInstrSize = Assembler::kInstrSize;
const int kMaxBranchOffset = Assembler::kMaxBranchOffset;
const int kTrampolineSlotsSize = Assembler::kTrampolineSlotsSize;
const int kSwitchTablePrologueSize = MacroAssembler::kSwitchTablePrologueSize;
const int kMaxOffsetForTrampolineStart =
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));
Label labels[kNumCases];
Label labels[kSwitchTableCases];
Label near_start, end, done;
__ Push(ra);
......@@ -384,7 +390,7 @@ TEST(jump_tables6) {
int gen_insn = 0;
__ Branch(&end);
gen_insn += 2;
gen_insn += Assembler::IsCompactBranchSupported() ? 1 : 2;
__ bind(&near_start);
// Generate slightly less than 32K instructions, which will soon require
......@@ -394,23 +400,24 @@ TEST(jump_tables6) {
}
gen_insn += kFillInstr;
__ GenerateSwitchTable(a0, kNumCases,
__ GenerateSwitchTable(a0, kSwitchTableCases,
[&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]);
__ li(v0, values[i]);
__ 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
// offset for trampoline ...
CHECK_LT(kMaxOffsetForTrampolineStart, masm->pc_offset() - offs1);
// ... number of generated instructions must be greater then "gen_insn",
// 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);
__ Pop(ra);
......@@ -428,7 +435,7 @@ TEST(jump_tables6) {
code->Print(std::cout);
#endif
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>(
CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
::printf("f(%d) = %" PRId64 "\n", i, res);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment