summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/mips
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/mips')
-rw-r--r--deps/v8/src/compiler/mips/code-generator-mips.cc1029
-rw-r--r--deps/v8/src/compiler/mips/instruction-codes-mips.h91
-rw-r--r--deps/v8/src/compiler/mips/instruction-selector-mips.cc641
3 files changed, 1234 insertions, 527 deletions
diff --git a/deps/v8/src/compiler/mips/code-generator-mips.cc b/deps/v8/src/compiler/mips/code-generator-mips.cc
index 5055735ba6..e87f210264 100644
--- a/deps/v8/src/compiler/mips/code-generator-mips.cc
+++ b/deps/v8/src/compiler/mips/code-generator-mips.cc
@@ -14,8 +14,7 @@ namespace v8 {
namespace internal {
namespace compiler {
-#define __ masm()->
-
+#define __ tasm()->
// TODO(plind): Possibly avoid using these lithium names.
#define kScratchReg kLithiumScratchReg
@@ -80,11 +79,9 @@ class MipsOperandConverter final : public InstructionOperandConverter {
case Constant::kInt32:
return Operand(constant.ToInt32());
case Constant::kFloat32:
- return Operand(
- isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
+ return Operand::EmbeddedNumber(constant.ToFloat32());
case Constant::kFloat64:
- return Operand(
- isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
+ return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kInt64:
case Constant::kExternalReference:
case Constant::kHeapObject:
@@ -96,7 +93,6 @@ class MipsOperandConverter final : public InstructionOperandConverter {
break;
}
UNREACHABLE();
- return Operand(zero_reg);
}
Operand InputOperand(size_t index) {
@@ -120,7 +116,6 @@ class MipsOperandConverter final : public InstructionOperandConverter {
UNREACHABLE();
}
UNREACHABLE();
- return MemOperand(no_reg);
}
MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); }
@@ -233,7 +228,8 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
- must_save_lr_(!gen->frame_access_state()->has_frame()) {}
+ must_save_lr_(!gen->frame_access_state()->has_frame()),
+ zone_(gen->zone()) {}
void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) {
@@ -251,10 +247,10 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore ra if the frame was elided.
__ Push(ra);
}
- RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
- remembered_set_action, save_fp_mode);
__ Addu(scratch1_, object_, index_);
- __ CallStub(&stub);
+ __ CallStubDelayed(
+ new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
+ remembered_set_action, save_fp_mode));
if (must_save_lr_) {
__ Pop(ra);
}
@@ -268,15 +264,16 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Register const scratch1_;
RecordWriteMode const mode_;
bool must_save_lr_;
+ Zone* zone_;
};
-#define CREATE_OOL_CLASS(ool_name, masm_ool_name, T) \
+#define CREATE_OOL_CLASS(ool_name, tasm_ool_name, T) \
class ool_name final : public OutOfLineCode { \
public: \
ool_name(CodeGenerator* gen, T dst, T src1, T src2) \
: OutOfLineCode(gen), dst_(dst), src1_(src1), src2_(src2) {} \
\
- void Generate() final { __ masm_ool_name(dst_, src1_, src2_); } \
+ void Generate() final { __ tasm_ool_name(dst_, src1_, src2_); } \
\
private: \
T const dst_; \
@@ -320,7 +317,6 @@ Condition FlagsConditionToConditionCmp(FlagsCondition condition) {
break;
}
UNREACHABLE();
- return kNoCondition;
}
@@ -334,7 +330,6 @@ Condition FlagsConditionToConditionTst(FlagsCondition condition) {
break;
}
UNREACHABLE();
- return kNoCondition;
}
@@ -368,7 +363,6 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
break;
}
UNREACHABLE();
- return kNoFPUCondition;
}
} // namespace
@@ -518,7 +512,7 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
#define ASSEMBLE_IEEE754_BINOP(name) \
do { \
- FrameScope scope(masm(), StackFrame::MANUAL); \
+ FrameScope scope(tasm(), StackFrame::MANUAL); \
__ PrepareCallCFunction(0, 2, kScratchReg); \
__ MovToFloatParameters(i.InputDoubleRegister(0), \
i.InputDoubleRegister(1)); \
@@ -530,7 +524,7 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
#define ASSEMBLE_IEEE754_UNOP(name) \
do { \
- FrameScope scope(masm(), StackFrame::MANUAL); \
+ FrameScope scope(tasm(), StackFrame::MANUAL); \
__ PrepareCallCFunction(0, 1, kScratchReg); \
__ MovToFloatParameter(i.InputDoubleRegister(0)); \
__ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
@@ -579,7 +573,7 @@ void CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
namespace {
-void AdjustStackPointerForTailCall(MacroAssembler* masm,
+void AdjustStackPointerForTailCall(TurboAssembler* tasm,
FrameAccessState* state,
int new_slot_above_sp,
bool allow_shrinkage = true) {
@@ -587,10 +581,10 @@ void AdjustStackPointerForTailCall(MacroAssembler* masm,
StandardFrameConstants::kFixedSlotCountAboveFp;
int stack_slot_delta = new_slot_above_sp - current_sp_offset;
if (stack_slot_delta > 0) {
- masm->Subu(sp, sp, stack_slot_delta * kPointerSize);
+ tasm->Subu(sp, sp, stack_slot_delta * kPointerSize);
state->IncreaseSPDelta(stack_slot_delta);
} else if (allow_shrinkage && stack_slot_delta < 0) {
- masm->Addu(sp, sp, -stack_slot_delta * kPointerSize);
+ tasm->Addu(sp, sp, -stack_slot_delta * kPointerSize);
state->IncreaseSPDelta(stack_slot_delta);
}
}
@@ -599,13 +593,13 @@ void AdjustStackPointerForTailCall(MacroAssembler* masm,
void CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
int first_unused_stack_slot) {
- AdjustStackPointerForTailCall(masm(), frame_access_state(),
+ AdjustStackPointerForTailCall(tasm(), frame_access_state(),
first_unused_stack_slot, false);
}
void CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
int first_unused_stack_slot) {
- AdjustStackPointerForTailCall(masm(), frame_access_state(),
+ AdjustStackPointerForTailCall(tasm(), frame_access_state(),
first_unused_stack_slot);
}
@@ -619,8 +613,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchCallCodeObject: {
EnsureSpaceForLazyDeopt();
if (instr->InputAt(0)->IsImmediate()) {
- __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
- RelocInfo::CODE_TARGET);
+ __ Call(i.InputCode(0), RelocInfo::CODE_TARGET);
} else {
__ Call(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
}
@@ -636,8 +629,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
i.TempRegister(2));
}
if (instr->InputAt(0)->IsImmediate()) {
- __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
- RelocInfo::CODE_TARGET);
+ __ Jump(i.InputCode(0), RelocInfo::CODE_TARGET);
} else {
__ Jump(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
}
@@ -752,7 +744,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
case kArchTruncateDoubleToI:
- __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+ __ TruncateDoubleToIDelayed(zone(), i.OutputRegister(),
+ i.InputDoubleRegister(0));
break;
case kArchStoreWithWriteBarrier: {
RecordWriteMode mode =
@@ -855,8 +848,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_IEEE754_UNOP(log2);
break;
case kIeee754Float64Pow: {
- MathPowStub stub(isolate(), MathPowStub::DOUBLE);
- __ CallStub(&stub);
+ __ CallStubDelayed(new (zone())
+ MathPowStub(nullptr, MathPowStub::DOUBLE));
break;
}
case kIeee754Float64Sin:
@@ -938,68 +931,75 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Clz(i.OutputRegister(), i.InputRegister(0));
break;
case kMipsCtz: {
- Register reg1 = kScratchReg;
- Register reg2 = kScratchReg2;
- Label skip_for_zero;
- Label end;
- // Branch if the operand is zero
- __ Branch(&skip_for_zero, eq, i.InputRegister(0), Operand(zero_reg));
- // Find the number of bits before the last bit set to 1.
- __ Subu(reg2, zero_reg, i.InputRegister(0));
- __ And(reg2, reg2, i.InputRegister(0));
- __ clz(reg2, reg2);
- // Get the number of bits after the last bit set to 1.
- __ li(reg1, 0x1F);
- __ Subu(i.OutputRegister(), reg1, reg2);
- __ Branch(&end);
- __ bind(&skip_for_zero);
- // If the operand is zero, return word length as the result.
- __ li(i.OutputRegister(), 0x20);
- __ bind(&end);
+ Register src = i.InputRegister(0);
+ Register dst = i.OutputRegister();
+ if (IsMipsArchVariant(kMips32r6)) {
+ // We don't have an instruction to count the number of trailing zeroes.
+ // Start by flipping the bits end-for-end so we can count the number of
+ // leading zeroes instead.
+ __ rotr(dst, src, 16);
+ __ wsbh(dst, dst);
+ __ bitswap(dst, dst);
+ __ Clz(dst, dst);
+ } else {
+ // Convert trailing zeroes to trailing ones, and bits to their left
+ // to zeroes.
+ __ Addu(kScratchReg, src, -1);
+ __ Xor(dst, kScratchReg, src);
+ __ And(dst, dst, kScratchReg);
+ // Count number of leading zeroes.
+ __ Clz(dst, dst);
+ // Subtract number of leading zeroes from 32 to get number of trailing
+ // ones. Remember that the trailing ones were formerly trailing zeroes.
+ __ li(kScratchReg, 32);
+ __ Subu(dst, kScratchReg, dst);
+ }
} break;
case kMipsPopcnt: {
- Register reg1 = kScratchReg;
- Register reg2 = kScratchReg2;
- uint32_t m1 = 0x55555555;
- uint32_t m2 = 0x33333333;
- uint32_t m4 = 0x0f0f0f0f;
- uint32_t m8 = 0x00ff00ff;
- uint32_t m16 = 0x0000ffff;
-
- // Put count of ones in every 2 bits into those 2 bits.
- __ li(at, m1);
- __ srl(reg1, i.InputRegister(0), 1);
- __ And(reg2, i.InputRegister(0), at);
- __ And(reg1, reg1, at);
- __ addu(reg1, reg1, reg2);
-
- // Put count of ones in every 4 bits into those 4 bits.
- __ li(at, m2);
- __ srl(reg2, reg1, 2);
- __ And(reg2, reg2, at);
- __ And(reg1, reg1, at);
- __ addu(reg1, reg1, reg2);
-
- // Put count of ones in every 8 bits into those 8 bits.
- __ li(at, m4);
- __ srl(reg2, reg1, 4);
- __ And(reg2, reg2, at);
- __ And(reg1, reg1, at);
- __ addu(reg1, reg1, reg2);
-
- // Put count of ones in every 16 bits into those 16 bits.
- __ li(at, m8);
- __ srl(reg2, reg1, 8);
- __ And(reg2, reg2, at);
- __ And(reg1, reg1, at);
- __ addu(reg1, reg1, reg2);
-
- // Calculate total number of ones.
- __ li(at, m16);
- __ srl(reg2, reg1, 16);
- __ And(reg2, reg2, at);
- __ And(reg1, reg1, at);
- __ addu(i.OutputRegister(), reg1, reg2);
+ // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ //
+ // A generalization of the best bit counting method to integers of
+ // bit-widths up to 128 (parameterized by type T) is this:
+ //
+ // v = v - ((v >> 1) & (T)~(T)0/3); // temp
+ // v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3); // temp
+ // v = (v + (v >> 4)) & (T)~(T)0/255*15; // temp
+ // c = (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * BITS_PER_BYTE; //count
+ //
+ // For comparison, for 32-bit quantities, this algorithm can be executed
+ // using 20 MIPS instructions (the calls to LoadConst32() generate two
+ // machine instructions each for the values being used in this algorithm).
+ // A(n unrolled) loop-based algorithm requires 25 instructions.
+ //
+ // For 64-bit quantities, this algorithm gets executed twice, (once
+ // for in_lo, and again for in_hi), but saves a few instructions
+ // because the mask values only have to be loaded once. Using this
+ // algorithm the count for a 64-bit operand can be performed in 29
+ // instructions compared to a loop-based algorithm which requires 47
+ // instructions.
+ Register src = i.InputRegister(0);
+ Register dst = i.OutputRegister();
+ uint32_t B0 = 0x55555555; // (T)~(T)0/3
+ uint32_t B1 = 0x33333333; // (T)~(T)0/15*3
+ uint32_t B2 = 0x0f0f0f0f; // (T)~(T)0/255*15
+ uint32_t value = 0x01010101; // (T)~(T)0/255
+ uint32_t shift = 24; // (sizeof(T) - 1) * BITS_PER_BYTE
+ __ srl(kScratchReg, src, 1);
+ __ li(kScratchReg2, B0);
+ __ And(kScratchReg, kScratchReg, kScratchReg2);
+ __ Subu(kScratchReg, src, kScratchReg);
+ __ li(kScratchReg2, B1);
+ __ And(dst, kScratchReg, kScratchReg2);
+ __ srl(kScratchReg, kScratchReg, 2);
+ __ And(kScratchReg, kScratchReg, kScratchReg2);
+ __ Addu(kScratchReg, dst, kScratchReg);
+ __ srl(dst, kScratchReg, 4);
+ __ Addu(dst, dst, kScratchReg);
+ __ li(kScratchReg2, B2);
+ __ And(dst, dst, kScratchReg2);
+ __ li(kScratchReg, value);
+ __ Mul(dst, dst, kScratchReg);
+ __ srl(dst, dst, shift);
} break;
case kMipsShl:
if (instr->InputAt(1)->IsRegister()) {
@@ -1120,7 +1120,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kMipsModS: {
// TODO(bmeurer): We should really get rid of this special instruction,
// and generate a CallAddress instruction instead.
- FrameScope scope(masm(), StackFrame::MANUAL);
+ FrameScope scope(tasm(), StackFrame::MANUAL);
__ PrepareCallCFunction(0, 2, kScratchReg);
__ MovToFloatParameters(i.InputDoubleRegister(0),
i.InputDoubleRegister(1));
@@ -1206,7 +1206,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kMipsModD: {
// TODO(bmeurer): We should really get rid of this special instruction,
// and generate a CallAddress instruction instead.
- FrameScope scope(masm(), StackFrame::MANUAL);
+ FrameScope scope(tasm(), StackFrame::MANUAL);
__ PrepareCallCFunction(0, 2, kScratchReg);
__ MovToFloatParameters(i.InputDoubleRegister(0),
i.InputDoubleRegister(1));
@@ -1653,24 +1653,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
UNREACHABLE();
break;
case kMipsS128Zero: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ xor_v(i.OutputSimd128Register(), i.OutputSimd128Register(),
i.OutputSimd128Register());
break;
}
case kMipsI32x4Splat: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fill_w(i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kMipsI32x4ExtractLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ copy_s_w(i.OutputRegister(), i.InputSimd128Register(0),
i.InputInt8(1));
break;
}
case kMipsI32x4ReplaceLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
if (!src.is(dst)) {
@@ -1680,31 +1680,31 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kMipsI32x4Add: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ addv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4Sub: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ subv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Splat: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ FmoveLow(kScratchReg, i.InputSingleRegister(0));
__ fill_w(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMipsF32x4ExtractLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ copy_u_w(kScratchReg, i.InputSimd128Register(0), i.InputInt8(1));
__ FmoveLow(i.OutputSingleRegister(), kScratchReg);
break;
}
case kMipsF32x4ReplaceLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
if (!src.is(dst)) {
@@ -1715,213 +1715,211 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kMipsF32x4SConvertI32x4: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ ffint_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsF32x4UConvertI32x4: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ ffint_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsI32x4Mul: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ mulv_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4MaxS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ max_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4MinS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ min_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4Eq: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ ceq_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4Ne: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ ceq_w(dst, i.InputSimd128Register(0), i.InputSimd128Register(1));
__ nor_v(dst, dst, dst);
break;
}
case kMipsI32x4Shl: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ slli_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMipsI32x4ShrS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ srai_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMipsI32x4ShrU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ srli_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1));
break;
}
case kMipsI32x4MaxU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ max_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4MinU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ min_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
- case kMipsS32x4Select:
- case kMipsS16x8Select:
- case kMipsS8x16Select: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ case kMipsS128Select: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
DCHECK(i.OutputSimd128Register().is(i.InputSimd128Register(0)));
__ bsel_v(i.OutputSimd128Register(), i.InputSimd128Register(2),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Abs: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ bclri_w(i.OutputSimd128Register(), i.InputSimd128Register(0), 31);
break;
}
case kMipsF32x4Neg: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ bnegi_w(i.OutputSimd128Register(), i.InputSimd128Register(0), 31);
break;
}
case kMipsF32x4RecipApprox: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ frcp_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsF32x4RecipSqrtApprox: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ frsqrt_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsF32x4Add: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fadd_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Sub: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fsub_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Mul: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fmul_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Max: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fmax_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Min: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fmin_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Eq: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fceq_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Ne: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fcne_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Lt: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fclt_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsF32x4Le: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fcle_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI32x4SConvertF32x4: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ ftrunc_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsI32x4UConvertF32x4: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ ftrunc_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0));
break;
}
case kMipsI32x4Neg: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
__ subv_w(i.OutputSimd128Register(), kSimd128RegZero,
i.InputSimd128Register(0));
break;
}
- case kMipsI32x4LtS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ clt_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI32x4GtS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ clt_s_w(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
- case kMipsI32x4LeS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ cle_s_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI32x4GeS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ cle_s_w(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
- case kMipsI32x4LtU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ clt_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI32x4GtU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ clt_u_w(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
- case kMipsI32x4LeU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ cle_u_w(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI32x4GeU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ cle_u_w(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
case kMipsI16x8Splat: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fill_h(i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kMipsI16x8ExtractLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ copy_s_h(i.OutputRegister(), i.InputSimd128Register(0),
i.InputInt8(1));
break;
}
case kMipsI16x8ReplaceLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
if (!src.is(dst)) {
@@ -1931,146 +1929,146 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kMipsI16x8Neg: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
__ subv_h(i.OutputSimd128Register(), kSimd128RegZero,
i.InputSimd128Register(0));
break;
}
case kMipsI16x8Shl: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ slli_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt4(1));
break;
}
case kMipsI16x8ShrS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ srai_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt4(1));
break;
}
case kMipsI16x8ShrU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ srli_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt4(1));
break;
}
case kMipsI16x8Add: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ addv_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8AddSaturateS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ adds_s_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8Sub: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ subv_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8SubSaturateS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ subs_s_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8Mul: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ mulv_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8MaxS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ max_s_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8MinS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ min_s_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8Eq: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ ceq_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8Ne: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ ceq_h(dst, i.InputSimd128Register(0), i.InputSimd128Register(1));
__ nor_v(dst, dst, dst);
break;
}
- case kMipsI16x8LtS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ clt_s_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI16x8GtS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ clt_s_h(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
- case kMipsI16x8LeS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ cle_s_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI16x8GeS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ cle_s_h(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
case kMipsI16x8AddSaturateU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ adds_u_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8SubSaturateU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ subs_u_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8MaxU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ max_u_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
case kMipsI16x8MinU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ min_u_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1));
break;
}
- case kMipsI16x8LtU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ clt_u_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI16x8GtU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ clt_u_h(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
- case kMipsI16x8LeU: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
- __ cle_u_h(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1));
+ case kMipsI16x8GeU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ cle_u_h(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
break;
}
case kMipsI8x16Splat: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ fill_b(i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kMipsI8x16ExtractLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ copy_s_b(i.OutputRegister(), i.InputSimd128Register(0),
i.InputInt8(1));
break;
}
case kMipsI8x16ReplaceLane: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register src = i.InputSimd128Register(0);
Simd128Register dst = i.OutputSimd128Register();
if (!src.is(dst)) {
@@ -2080,24 +2078,637 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kMipsI8x16Neg: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
__ subv_b(i.OutputSimd128Register(), kSimd128RegZero,
i.InputSimd128Register(0));
break;
}
case kMipsI8x16Shl: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ slli_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt3(1));
break;
}
case kMipsI8x16ShrS: {
- CpuFeatureScope msa_scope(masm(), MIPS_SIMD);
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ srai_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt3(1));
break;
}
+ case kMipsI8x16Add: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ addv_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16AddSaturateS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ adds_s_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16Sub: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ subv_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16SubSaturateS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ subs_s_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16Mul: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ mulv_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16MaxS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ max_s_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16MinS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ min_s_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16Eq: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ ceq_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16Ne: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ __ ceq_b(dst, i.InputSimd128Register(0), i.InputSimd128Register(1));
+ __ nor_v(dst, dst, dst);
+ break;
+ }
+ case kMipsI8x16GtS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ clt_s_b(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI8x16GeS: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ cle_s_b(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI8x16ShrU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ srli_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputInt3(1));
+ break;
+ }
+ case kMipsI8x16AddSaturateU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ adds_u_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16SubSaturateU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ subs_u_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16MaxU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ max_u_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16MinU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ min_u_b(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsI8x16GtU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ clt_u_b(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI8x16GeU: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ cle_u_b(i.OutputSimd128Register(), i.InputSimd128Register(1),
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsS128And: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ and_v(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsS128Or: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ or_v(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsS128Xor: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ xor_v(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(1));
+ break;
+ }
+ case kMipsS128Not: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ nor_v(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsS1x4AnyTrue:
+ case kMipsS1x8AnyTrue:
+ case kMipsS1x16AnyTrue: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Register dst = i.OutputRegister();
+ Label all_false;
+
+ __ BranchMSA(&all_false, MSA_BRANCH_V, all_zero,
+ i.InputSimd128Register(0), USE_DELAY_SLOT);
+ __ li(dst, 0); // branch delay slot
+ __ li(dst, -1);
+ __ bind(&all_false);
+ break;
+ }
+ case kMipsS1x4AllTrue: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Register dst = i.OutputRegister();
+ Label all_true;
+ __ BranchMSA(&all_true, MSA_BRANCH_W, all_not_zero,
+ i.InputSimd128Register(0), USE_DELAY_SLOT);
+ __ li(dst, -1); // branch delay slot
+ __ li(dst, 0);
+ __ bind(&all_true);
+ break;
+ }
+ case kMipsS1x8AllTrue: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Register dst = i.OutputRegister();
+ Label all_true;
+ __ BranchMSA(&all_true, MSA_BRANCH_H, all_not_zero,
+ i.InputSimd128Register(0), USE_DELAY_SLOT);
+ __ li(dst, -1); // branch delay slot
+ __ li(dst, 0);
+ __ bind(&all_true);
+ break;
+ }
+ case kMipsS1x16AllTrue: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Register dst = i.OutputRegister();
+ Label all_true;
+ __ BranchMSA(&all_true, MSA_BRANCH_B, all_not_zero,
+ i.InputSimd128Register(0), USE_DELAY_SLOT);
+ __ li(dst, -1); // branch delay slot
+ __ li(dst, 0);
+ __ bind(&all_true);
+ break;
+ }
+ case kMipsMsaLd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ ld_b(i.OutputSimd128Register(), i.MemoryOperand());
+ break;
+ }
+ case kMipsMsaSt: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ st_b(i.InputSimd128Register(2), i.MemoryOperand());
+ break;
+ }
+ case kMipsS32x4InterleaveRight: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [7, 6, 5, 4], src0 = [3, 2, 1, 0]
+ // dst = [5, 1, 4, 0]
+ __ ilvr_w(dst, src1, src0);
+ break;
+ }
+ case kMipsS32x4InterleaveLeft: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [7, 6, 5, 4], src0 = [3, 2, 1, 0]
+ // dst = [7, 3, 6, 2]
+ __ ilvl_w(dst, src1, src0);
+ break;
+ }
+ case kMipsS32x4PackEven: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [7, 6, 5, 4], src0 = [3, 2, 1, 0]
+ // dst = [6, 4, 2, 0]
+ __ pckev_w(dst, src1, src0);
+ break;
+ }
+ case kMipsS32x4PackOdd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [7, 6, 5, 4], src0 = [3, 2, 1, 0]
+ // dst = [7, 5, 3, 1]
+ __ pckod_w(dst, src1, src0);
+ break;
+ }
+ case kMipsS32x4InterleaveEven: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [7, 6, 5, 4], src0 = [3, 2, 1, 0]
+ // dst = [6, 2, 4, 0]
+ __ ilvev_w(dst, src1, src0);
+ break;
+ }
+ case kMipsS32x4InterleaveOdd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [7, 6, 5, 4], src0 = [3, 2, 1, 0]
+ // dst = [7, 3, 5, 1]
+ __ ilvod_w(dst, src1, src0);
+ break;
+ }
+ case kMipsS32x4Shuffle: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+
+ int32_t shuffle = i.InputInt32(2);
+
+ if (src0.is(src1)) {
+ // Unary S32x4 shuffles are handled with shf.w instruction
+ uint32_t i8 = 0;
+ for (int i = 0; i < 4; i++) {
+ int lane = shuffle & 0xff;
+ DCHECK(lane < 4);
+ i8 |= lane << (2 * i);
+ shuffle >>= 8;
+ }
+ __ shf_w(dst, src0, i8);
+ } else {
+ // For binary shuffles use vshf.w instruction
+ if (dst.is(src0)) {
+ __ move_v(kSimd128ScratchReg, src0);
+ src0 = kSimd128ScratchReg;
+ } else if (dst.is(src1)) {
+ __ move_v(kSimd128ScratchReg, src1);
+ src1 = kSimd128ScratchReg;
+ }
+
+ __ li(kScratchReg, i.InputInt32(2));
+ __ insert_w(dst, 0, kScratchReg);
+ __ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
+ __ ilvr_b(dst, kSimd128RegZero, dst);
+ __ ilvr_h(dst, kSimd128RegZero, dst);
+ __ vshf_w(dst, src1, src0);
+ }
+ break;
+ }
+ case kMipsS16x8InterleaveRight: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [15, ... 11, 10, 9, 8], src0 = [7, ... 3, 2, 1, 0]
+ // dst = [11, 3, 10, 2, 9, 1, 8, 0]
+ __ ilvr_h(dst, src1, src0);
+ break;
+ }
+ case kMipsS16x8InterleaveLeft: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [15, ... 11, 10, 9, 8], src0 = [7, ... 3, 2, 1, 0]
+ // dst = [15, 7, 14, 6, 13, 5, 12, 4]
+ __ ilvl_h(dst, src1, src0);
+ break;
+ }
+ case kMipsS16x8PackEven: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [15, ... 11, 10, 9, 8], src0 = [7, ... 3, 2, 1, 0]
+ // dst = [14, 12, 10, 8, 6, 4, 2, 0]
+ __ pckev_h(dst, src1, src0);
+ break;
+ }
+ case kMipsS16x8PackOdd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [15, ... 11, 10, 9, 8], src0 = [7, ... 3, 2, 1, 0]
+ // dst = [15, 13, 11, 9, 7, 5, 3, 1]
+ __ pckod_h(dst, src1, src0);
+ break;
+ }
+ case kMipsS16x8InterleaveEven: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [15, ... 11, 10, 9, 8], src0 = [7, ... 3, 2, 1, 0]
+ // dst = [14, 6, 12, 4, 10, 2, 8, 0]
+ __ ilvev_h(dst, src1, src0);
+ break;
+ }
+ case kMipsS16x8InterleaveOdd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [15, ... 11, 10, 9, 8], src0 = [7, ... 3, 2, 1, 0]
+ // dst = [15, 7, ... 11, 3, 9, 1]
+ __ ilvod_h(dst, src1, src0);
+ break;
+ }
+ case kMipsS16x4Reverse: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ // src = [7, 6, 5, 4, 3, 2, 1, 0], dst = [4, 5, 6, 7, 0, 1, 2, 3]
+ // shf.df imm field: 0 1 2 3 = 00011011 = 0x1B
+ __ shf_h(i.OutputSimd128Register(), i.InputSimd128Register(0), 0x1B);
+ break;
+ }
+ case kMipsS16x2Reverse: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ // src = [7, 6, 5, 4, 3, 2, 1, 0], dst = [6, 7, 4, 5, 3, 2, 0, 1]
+ // shf.df imm field: 2 3 0 1 = 10110001 = 0xB1
+ __ shf_h(i.OutputSimd128Register(), i.InputSimd128Register(0), 0xB1);
+ break;
+ }
+ case kMipsS8x16InterleaveRight: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [31, ... 19, 18, 17, 16], src0 = [15, ... 3, 2, 1, 0]
+ // dst = [23, 7, ... 17, 1, 16, 0]
+ __ ilvr_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x16InterleaveLeft: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [31, ... 19, 18, 17, 16], src0 = [15, ... 3, 2, 1, 0]
+ // dst = [31, 15, ... 25, 9, 24, 8]
+ __ ilvl_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x16PackEven: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [31, ... 19, 18, 17, 16], src0 = [15, ... 3, 2, 1, 0]
+ // dst = [30, 28, ... 6, 4, 2, 0]
+ __ pckev_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x16PackOdd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [31, ... 19, 18, 17, 16], src0 = [15, ... 3, 2, 1, 0]
+ // dst = [31, 29, ... 7, 5, 3, 1]
+ __ pckod_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x16InterleaveEven: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [31, ... 19, 18, 17, 16], src0 = [15, ... 3, 2, 1, 0]
+ // dst = [30, 14, ... 18, 2, 16, 0]
+ __ ilvev_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x16InterleaveOdd: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+ // src1 = [31, ... 19, 18, 17, 16], src0 = [15, ... 3, 2, 1, 0]
+ // dst = [31, 15, ... 19, 3, 17, 1]
+ __ ilvod_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x16Concat: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ DCHECK(dst.is(i.InputSimd128Register(0)));
+ __ sldi_b(dst, i.InputSimd128Register(1), i.InputInt4(2));
+ break;
+ }
+ case kMipsS8x16Shuffle: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register(),
+ src0 = i.InputSimd128Register(0),
+ src1 = i.InputSimd128Register(1);
+
+ if (dst.is(src0)) {
+ __ move_v(kSimd128ScratchReg, src0);
+ src0 = kSimd128ScratchReg;
+ } else if (dst.is(src1)) {
+ __ move_v(kSimd128ScratchReg, src1);
+ src1 = kSimd128ScratchReg;
+ }
+
+ __ li(kScratchReg, i.InputInt32(2));
+ __ insert_w(dst, 0, kScratchReg);
+ __ li(kScratchReg, i.InputInt32(3));
+ __ insert_w(dst, 1, kScratchReg);
+ __ li(kScratchReg, i.InputInt32(4));
+ __ insert_w(dst, 2, kScratchReg);
+ __ li(kScratchReg, i.InputInt32(5));
+ __ insert_w(dst, 3, kScratchReg);
+ __ vshf_b(dst, src1, src0);
+ break;
+ }
+ case kMipsS8x8Reverse: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ // src = [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
+ // dst = [8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7]
+ // [A B C D] => [B A D C]: shf.w imm: 2 3 0 1 = 10110001 = 0xB1
+ // C: [7, 6, 5, 4] => A': [4, 5, 6, 7]: shf.b imm: 00011011 = 0x1B
+ __ shf_w(kSimd128ScratchReg, i.InputSimd128Register(0), 0xB1);
+ __ shf_b(i.OutputSimd128Register(), kSimd128ScratchReg, 0x1B);
+ break;
+ }
+ case kMipsS8x4Reverse: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ // src = [15, 14, ... 3, 2, 1, 0], dst = [12, 13, 14, 15, ... 0, 1, 2, 3]
+ // shf.df imm field: 0 1 2 3 = 00011011 = 0x1B
+ __ shf_b(i.OutputSimd128Register(), i.InputSimd128Register(0), 0x1B);
+ break;
+ }
+ case kMipsS8x2Reverse: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ // src = [15, 14, ... 3, 2, 1, 0], dst = [14, 15, 12, 13, ... 2, 3, 0, 1]
+ // shf.df imm field: 2 3 0 1 = 10110001 = 0xB1
+ __ shf_b(i.OutputSimd128Register(), i.InputSimd128Register(0), 0xB1);
+ break;
+ }
+ case kMipsI32x4SConvertI16x8Low: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src = i.InputSimd128Register(0);
+ __ ilvr_h(kSimd128ScratchReg, src, src);
+ __ slli_w(dst, kSimd128ScratchReg, 16);
+ __ srai_w(dst, dst, 16);
+ break;
+ }
+ case kMipsI32x4SConvertI16x8High: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src = i.InputSimd128Register(0);
+ __ ilvl_h(kSimd128ScratchReg, src, src);
+ __ slli_w(dst, kSimd128ScratchReg, 16);
+ __ srai_w(dst, dst, 16);
+ break;
+ }
+ case kMipsI32x4UConvertI16x8Low: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
+ __ ilvr_h(i.OutputSimd128Register(), kSimd128RegZero,
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI32x4UConvertI16x8High: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
+ __ ilvl_h(i.OutputSimd128Register(), kSimd128RegZero,
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI16x8SConvertI8x16Low: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src = i.InputSimd128Register(0);
+ __ ilvr_b(kSimd128ScratchReg, src, src);
+ __ slli_h(dst, kSimd128ScratchReg, 8);
+ __ srai_h(dst, dst, 8);
+ break;
+ }
+ case kMipsI16x8SConvertI8x16High: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src = i.InputSimd128Register(0);
+ __ ilvl_b(kSimd128ScratchReg, src, src);
+ __ slli_h(dst, kSimd128ScratchReg, 8);
+ __ srai_h(dst, dst, 8);
+ break;
+ }
+ case kMipsI16x8SConvertI32x4: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ __ sat_s_w(kSimd128ScratchReg, src0, 15);
+ __ sat_s_w(kSimd128RegZero, src1, 15); // kSimd128RegZero as scratch
+ __ pckev_h(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
+ case kMipsI16x8UConvertI32x4: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ __ sat_u_w(kSimd128ScratchReg, src0, 15);
+ __ sat_u_w(kSimd128RegZero, src1, 15); // kSimd128RegZero as scratch
+ __ pckev_h(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
+ case kMipsI16x8UConvertI8x16Low: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
+ __ ilvr_b(i.OutputSimd128Register(), kSimd128RegZero,
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI16x8UConvertI8x16High: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ __ xor_v(kSimd128RegZero, kSimd128RegZero, kSimd128RegZero);
+ __ ilvl_b(i.OutputSimd128Register(), kSimd128RegZero,
+ i.InputSimd128Register(0));
+ break;
+ }
+ case kMipsI8x16SConvertI16x8: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ __ sat_s_h(kSimd128ScratchReg, src0, 7);
+ __ sat_s_h(kSimd128RegZero, src1, 7); // kSimd128RegZero as scratch
+ __ pckev_b(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
+ case kMipsI8x16UConvertI16x8: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register dst = i.OutputSimd128Register();
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ __ sat_u_h(kSimd128ScratchReg, src0, 7);
+ __ sat_u_h(kSimd128RegZero, src1, 7); // kSimd128RegZero as scratch
+ __ pckev_b(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
+ case kMipsF32x4AddHoriz: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ Simd128Register dst = i.OutputSimd128Register();
+ __ shf_w(kSimd128ScratchReg, src0, 0xB1); // 2 3 0 1 : 10110001 : 0xB1
+ __ shf_w(kSimd128RegZero, src1, 0xB1); // kSimd128RegZero as scratch
+ __ fadd_w(kSimd128ScratchReg, kSimd128ScratchReg, src0);
+ __ fadd_w(kSimd128RegZero, kSimd128RegZero, src1);
+ __ pckev_w(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
+ case kMipsI32x4AddHoriz: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ Simd128Register dst = i.OutputSimd128Register();
+ __ hadd_s_d(kSimd128ScratchReg, src0, src0);
+ __ hadd_s_d(kSimd128RegZero, src1, src1); // kSimd128RegZero as scratch
+ __ pckev_w(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
+ case kMipsI16x8AddHoriz: {
+ CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
+ Simd128Register src0 = i.InputSimd128Register(0);
+ Simd128Register src1 = i.InputSimd128Register(1);
+ Simd128Register dst = i.OutputSimd128Register();
+ __ hadd_s_w(kSimd128ScratchReg, src0, src0);
+ __ hadd_s_w(kSimd128RegZero, src1, src1); // kSimd128RegZero as scratch
+ __ pckev_h(dst, kSimd128RegZero, kSimd128ScratchReg);
+ break;
+ }
}
return kSuccess;
} // NOLINT(readability/fn_size)
@@ -2134,11 +2745,11 @@ static bool convertCondition(FlagsCondition condition, Condition& cc) {
return false;
}
-void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
+void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
Instruction* instr, FlagsCondition condition,
Label* tlabel, Label* flabel, bool fallthru) {
#undef __
-#define __ masm->
+#define __ tasm->
Condition cc = kNoCondition;
// MIPS does not have condition code flags, so compare and branch are
@@ -2227,14 +2838,14 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
}
if (!fallthru) __ Branch(flabel); // no fallthru to flabel.
#undef __
-#define __ masm()->
+#define __ tasm()->
}
// Assembles branches after an instruction.
void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
Label* tlabel = branch->true_label;
Label* flabel = branch->false_label;
- AssembleBranchToLabels(this, masm(), instr, branch->condition, tlabel, flabel,
+ AssembleBranchToLabels(this, tasm(), instr, branch->condition, tlabel, flabel,
branch->fallthru);
}
@@ -2277,14 +2888,14 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
// We use the context register as the scratch register, because we do
// not have a context here.
__ PrepareCallCFunction(0, 0, cp);
- __ CallCFunction(
- ExternalReference::wasm_call_trap_callback_for_testing(isolate()),
- 0);
+ __ CallCFunction(ExternalReference::wasm_call_trap_callback_for_testing(
+ tasm()->isolate()),
+ 0);
__ LeaveFrame(StackFrame::WASM_COMPILED);
__ Ret();
} else {
gen_->AssembleSourcePosition(instr_);
- __ Call(handle(isolate()->builtins()->builtin(trap_id), isolate()),
+ __ Call(tasm()->isolate()->builtins()->builtin_handle(trap_id),
RelocInfo::CODE_TARGET);
ReferenceMap* reference_map =
new (gen_->zone()) ReferenceMap(gen_->zone());
@@ -2303,7 +2914,7 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
bool frame_elided = !frame_access_state()->has_frame();
auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
Label* tlabel = ool->entry();
- AssembleBranchToLabels(this, masm(), instr, condition, tlabel, nullptr, true);
+ AssembleBranchToLabels(this, tasm(), instr, condition, tlabel, nullptr, true);
}
// Assembles boolean materializations after an instruction.
@@ -2325,7 +2936,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
if (instr->arch_opcode() == kMipsTst) {
cc = FlagsConditionToConditionTst(condition);
if (instr->InputAt(1)->IsImmediate() &&
- base::bits::IsPowerOfTwo32(i.InputOperand(1).immediate())) {
+ base::bits::IsPowerOfTwo(i.InputOperand(1).immediate())) {
uint16_t pos =
base::bits::CountTrailingZeros32(i.InputOperand(1).immediate());
__ Ext(result, i.InputRegister(0), pos, 1);
@@ -2504,7 +3115,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
isolate(), deoptimization_id, bailout_type);
if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
- if (isolate()->NeedsSourcePositionsForProfiling()) {
+ if (info()->is_source_positions_enabled()) {
__ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id);
}
__ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
@@ -2563,7 +3174,7 @@ void CodeGenerator::AssembleConstructFrame() {
// remaining stack slots.
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
osr_pc_offset_ = __ pc_offset();
- shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+ shrink_slots -= osr_helper()->UnoptimizedFrameSlots();
}
const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
@@ -2672,13 +3283,13 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
case Constant::kFloat32:
- __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
+ __ li(dst, Operand::EmbeddedNumber(src.ToFloat32()));
break;
case Constant::kInt64:
UNREACHABLE();
break;
case Constant::kFloat64:
- __ li(dst, isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
+ __ li(dst, Operand::EmbeddedNumber(src.ToFloat64().value()));
break;
case Constant::kExternalReference:
__ li(dst, Operand(src.ToExternalReference()));
@@ -2717,7 +3328,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DoubleRegister dst = destination->IsFPRegister()
? g.ToDoubleRegister(destination)
: kScratchDoubleReg;
- __ Move(dst, src.ToFloat64());
+ __ Move(dst, src.ToFloat64().value());
if (destination->IsFPStackSlot()) {
__ Sdc1(dst, g.ToMemOperand(destination));
}
@@ -2875,11 +3486,11 @@ void CodeGenerator::EnsureSpaceForLazyDeopt() {
int space_needed = Deoptimizer::patch_size();
// Ensure that we have enough space after the previous lazy-bailout
// instruction for patching the code here.
- int current_pc = masm()->pc_offset();
+ int current_pc = tasm()->pc_offset();
if (current_pc < last_lazy_deopt_pc_ + space_needed) {
// Block tramoline pool emission for duration of padding.
v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
- masm());
+ tasm());
int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
while (padding_size > 0) {
diff --git a/deps/v8/src/compiler/mips/instruction-codes-mips.h b/deps/v8/src/compiler/mips/instruction-codes-mips.h
index f80fae9340..3a2a873e48 100644
--- a/deps/v8/src/compiler/mips/instruction-codes-mips.h
+++ b/deps/v8/src/compiler/mips/instruction-codes-mips.h
@@ -138,6 +138,7 @@ namespace compiler {
V(MipsI32x4ExtractLane) \
V(MipsI32x4ReplaceLane) \
V(MipsI32x4Add) \
+ V(MipsI32x4AddHoriz) \
V(MipsI32x4Sub) \
V(MipsF32x4Splat) \
V(MipsF32x4ExtractLane) \
@@ -154,12 +155,12 @@ namespace compiler {
V(MipsI32x4ShrU) \
V(MipsI32x4MaxU) \
V(MipsI32x4MinU) \
- V(MipsS32x4Select) \
V(MipsF32x4Abs) \
V(MipsF32x4Neg) \
V(MipsF32x4RecipApprox) \
V(MipsF32x4RecipSqrtApprox) \
V(MipsF32x4Add) \
+ V(MipsF32x4AddHoriz) \
V(MipsF32x4Sub) \
V(MipsF32x4Mul) \
V(MipsF32x4Max) \
@@ -171,10 +172,10 @@ namespace compiler {
V(MipsI32x4SConvertF32x4) \
V(MipsI32x4UConvertF32x4) \
V(MipsI32x4Neg) \
- V(MipsI32x4LtS) \
- V(MipsI32x4LeS) \
- V(MipsI32x4LtU) \
- V(MipsI32x4LeU) \
+ V(MipsI32x4GtS) \
+ V(MipsI32x4GeS) \
+ V(MipsI32x4GtU) \
+ V(MipsI32x4GeU) \
V(MipsI16x8Splat) \
V(MipsI16x8ExtractLane) \
V(MipsI16x8ReplaceLane) \
@@ -184,6 +185,7 @@ namespace compiler {
V(MipsI16x8ShrU) \
V(MipsI16x8Add) \
V(MipsI16x8AddSaturateS) \
+ V(MipsI16x8AddHoriz) \
V(MipsI16x8Sub) \
V(MipsI16x8SubSaturateS) \
V(MipsI16x8Mul) \
@@ -191,22 +193,89 @@ namespace compiler {
V(MipsI16x8MinS) \
V(MipsI16x8Eq) \
V(MipsI16x8Ne) \
- V(MipsI16x8LtS) \
- V(MipsI16x8LeS) \
+ V(MipsI16x8GtS) \
+ V(MipsI16x8GeS) \
V(MipsI16x8AddSaturateU) \
V(MipsI16x8SubSaturateU) \
V(MipsI16x8MaxU) \
V(MipsI16x8MinU) \
- V(MipsI16x8LtU) \
- V(MipsI16x8LeU) \
+ V(MipsI16x8GtU) \
+ V(MipsI16x8GeU) \
V(MipsI8x16Splat) \
V(MipsI8x16ExtractLane) \
V(MipsI8x16ReplaceLane) \
V(MipsI8x16Neg) \
V(MipsI8x16Shl) \
V(MipsI8x16ShrS) \
- V(MipsS16x8Select) \
- V(MipsS8x16Select)
+ V(MipsI8x16Add) \
+ V(MipsI8x16AddSaturateS) \
+ V(MipsI8x16Sub) \
+ V(MipsI8x16SubSaturateS) \
+ V(MipsI8x16Mul) \
+ V(MipsI8x16MaxS) \
+ V(MipsI8x16MinS) \
+ V(MipsI8x16Eq) \
+ V(MipsI8x16Ne) \
+ V(MipsI8x16GtS) \
+ V(MipsI8x16GeS) \
+ V(MipsI8x16ShrU) \
+ V(MipsI8x16AddSaturateU) \
+ V(MipsI8x16SubSaturateU) \
+ V(MipsI8x16MaxU) \
+ V(MipsI8x16MinU) \
+ V(MipsI8x16GtU) \
+ V(MipsI8x16GeU) \
+ V(MipsS128And) \
+ V(MipsS128Or) \
+ V(MipsS128Xor) \
+ V(MipsS128Not) \
+ V(MipsS128Select) \
+ V(MipsS1x4AnyTrue) \
+ V(MipsS1x4AllTrue) \
+ V(MipsS1x8AnyTrue) \
+ V(MipsS1x8AllTrue) \
+ V(MipsS1x16AnyTrue) \
+ V(MipsS1x16AllTrue) \
+ V(MipsS32x4InterleaveRight) \
+ V(MipsS32x4InterleaveLeft) \
+ V(MipsS32x4PackEven) \
+ V(MipsS32x4PackOdd) \
+ V(MipsS32x4InterleaveEven) \
+ V(MipsS32x4InterleaveOdd) \
+ V(MipsS32x4Shuffle) \
+ V(MipsS16x8InterleaveRight) \
+ V(MipsS16x8InterleaveLeft) \
+ V(MipsS16x8PackEven) \
+ V(MipsS16x8PackOdd) \
+ V(MipsS16x8InterleaveEven) \
+ V(MipsS16x8InterleaveOdd) \
+ V(MipsS16x4Reverse) \
+ V(MipsS16x2Reverse) \
+ V(MipsS8x16InterleaveRight) \
+ V(MipsS8x16InterleaveLeft) \
+ V(MipsS8x16PackEven) \
+ V(MipsS8x16PackOdd) \
+ V(MipsS8x16InterleaveEven) \
+ V(MipsS8x16InterleaveOdd) \
+ V(MipsS8x16Shuffle) \
+ V(MipsS8x16Concat) \
+ V(MipsS8x8Reverse) \
+ V(MipsS8x4Reverse) \
+ V(MipsS8x2Reverse) \
+ V(MipsMsaLd) \
+ V(MipsMsaSt) \
+ V(MipsI32x4SConvertI16x8Low) \
+ V(MipsI32x4SConvertI16x8High) \
+ V(MipsI32x4UConvertI16x8Low) \
+ V(MipsI32x4UConvertI16x8High) \
+ V(MipsI16x8SConvertI8x16Low) \
+ V(MipsI16x8SConvertI8x16High) \
+ V(MipsI16x8SConvertI32x4) \
+ V(MipsI16x8UConvertI32x4) \
+ V(MipsI16x8UConvertI8x16Low) \
+ V(MipsI16x8UConvertI8x16High) \
+ V(MipsI8x16SConvertI16x8) \
+ V(MipsI8x16UConvertI16x8)
// Addressing modes represent the "shape" of inputs to an instruction.
// Many instructions support multiple addressing modes. Addressing modes
diff --git a/deps/v8/src/compiler/mips/instruction-selector-mips.cc b/deps/v8/src/compiler/mips/instruction-selector-mips.cc
index 1058833a43..9d5a2d95a1 100644
--- a/deps/v8/src/compiler/mips/instruction-selector-mips.cc
+++ b/deps/v8/src/compiler/mips/instruction-selector-mips.cc
@@ -294,11 +294,10 @@ void InstructionSelector::VisitLoad(Node* node) {
case MachineRepresentation::kWord32:
opcode = kMipsLw;
break;
+ case MachineRepresentation::kSimd128:
+ opcode = kMipsMsaLd;
+ break;
case MachineRepresentation::kWord64: // Fall through.
- case MachineRepresentation::kSimd128: // Fall through.
- case MachineRepresentation::kSimd1x4: // Fall through.
- case MachineRepresentation::kSimd1x8: // Fall through.
- case MachineRepresentation::kSimd1x16: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -382,11 +381,10 @@ void InstructionSelector::VisitStore(Node* node) {
case MachineRepresentation::kWord32:
opcode = kMipsSw;
break;
+ case MachineRepresentation::kSimd128:
+ opcode = kMipsMsaSt;
+ break;
case MachineRepresentation::kWord64: // Fall through.
- case MachineRepresentation::kSimd128: // Fall through.
- case MachineRepresentation::kSimd1x4: // Fall through.
- case MachineRepresentation::kSimd1x8: // Fall through.
- case MachineRepresentation::kSimd1x16: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -732,20 +730,20 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
MipsOperandGenerator g(this);
Int32BinopMatcher m(node);
if (m.right().HasValue() && m.right().Value() > 0) {
- int32_t value = m.right().Value();
- if (base::bits::IsPowerOfTwo32(value)) {
+ uint32_t value = static_cast<uint32_t>(m.right().Value());
+ if (base::bits::IsPowerOfTwo(value)) {
Emit(kMipsShl | AddressingModeField::encode(kMode_None),
g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value)));
return;
}
- if (base::bits::IsPowerOfTwo32(value - 1)) {
+ if (base::bits::IsPowerOfTwo(value - 1)) {
Emit(kMipsLsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
g.UseRegister(m.left().node()),
g.TempImmediate(WhichPowerOf2(value - 1)));
return;
}
- if (base::bits::IsPowerOfTwo32(value + 1)) {
+ if (base::bits::IsPowerOfTwo(value + 1)) {
InstructionOperand temp = g.TempRegister();
Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
g.UseRegister(m.left().node()),
@@ -1234,11 +1232,10 @@ void InstructionSelector::VisitUnalignedLoad(Node* node) {
case MachineRepresentation::kFloat64:
opcode = kMipsUldc1;
break;
+ case MachineRepresentation::kSimd128:
+ opcode = kMipsMsaLd;
+ break;
case MachineRepresentation::kWord64: // Fall through.
- case MachineRepresentation::kSimd128: // Fall through.
- case MachineRepresentation::kSimd1x4: // Fall through.
- case MachineRepresentation::kSimd1x8: // Fall through.
- case MachineRepresentation::kSimd1x16: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -1287,11 +1284,10 @@ void InstructionSelector::VisitUnalignedStore(Node* node) {
case MachineRepresentation::kWord32:
opcode = kMipsUsw;
break;
+ case MachineRepresentation::kSimd128:
+ opcode = kMipsMsaSt;
+ break;
case MachineRepresentation::kWord64: // Fall through.
- case MachineRepresentation::kSimd128: // Fall through.
- case MachineRepresentation::kSimd1x4: // Fall through.
- case MachineRepresentation::kSimd1x8: // Fall through.
- case MachineRepresentation::kSimd1x16: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -1340,9 +1336,6 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
case MachineRepresentation::kTagged: // Fall through.
case MachineRepresentation::kWord64: // Fall through.
case MachineRepresentation::kSimd128: // Fall through.
- case MachineRepresentation::kSimd1x4: // Fall through.
- case MachineRepresentation::kSimd1x8: // Fall through.
- case MachineRepresentation::kSimd1x16: // Fall through.
case MachineRepresentation::kNone:
UNREACHABLE();
return;
@@ -1683,6 +1676,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
// Emit either ArchTableSwitch or ArchLookupSwitch.
+ static const size_t kMaxTableSwitchValueRange = 2 << 16;
size_t table_space_cost = 9 + sw.value_range;
size_t table_time_cost = 3;
size_t lookup_space_cost = 2 + 2 * sw.case_count;
@@ -1690,7 +1684,8 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
if (sw.case_count > 0 &&
table_space_cost + 3 * table_time_cost <=
lookup_space_cost + 3 * lookup_time_cost &&
- sw.min_value > std::numeric_limits<int32_t>::min()) {
+ sw.min_value > std::numeric_limits<int32_t>::min() &&
+ sw.value_range <= kMaxTableSwitchValueRange) {
InstructionOperand index_operand = value_operand;
if (sw.min_value) {
index_operand = g.TempRegister();
@@ -1941,316 +1936,348 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
UNREACHABLE();
}
-void InstructionSelector::VisitI32x4Splat(Node* node) {
- VisitRR(this, kMipsI32x4Splat, node);
-}
-
-void InstructionSelector::VisitI32x4ExtractLane(Node* node) {
- VisitRRI(this, kMipsI32x4ExtractLane, node);
-}
-
-void InstructionSelector::VisitI32x4ReplaceLane(Node* node) {
- VisitRRIR(this, kMipsI32x4ReplaceLane, node);
-}
-
-void InstructionSelector::VisitI32x4Add(Node* node) {
- VisitRRR(this, kMipsI32x4Add, node);
-}
-
-void InstructionSelector::VisitI32x4Sub(Node* node) {
- VisitRRR(this, kMipsI32x4Sub, node);
-}
+#define SIMD_TYPE_LIST(V) \
+ V(F32x4) \
+ V(I32x4) \
+ V(I16x8) \
+ V(I8x16)
+
+#define SIMD_FORMAT_LIST(V) \
+ V(32x4) \
+ V(16x8) \
+ V(8x16)
+
+#define SIMD_UNOP_LIST(V) \
+ V(F32x4SConvertI32x4, kMipsF32x4SConvertI32x4) \
+ V(F32x4UConvertI32x4, kMipsF32x4UConvertI32x4) \
+ V(F32x4Abs, kMipsF32x4Abs) \
+ V(F32x4Neg, kMipsF32x4Neg) \
+ V(F32x4RecipApprox, kMipsF32x4RecipApprox) \
+ V(F32x4RecipSqrtApprox, kMipsF32x4RecipSqrtApprox) \
+ V(I32x4SConvertF32x4, kMipsI32x4SConvertF32x4) \
+ V(I32x4UConvertF32x4, kMipsI32x4UConvertF32x4) \
+ V(I32x4Neg, kMipsI32x4Neg) \
+ V(I32x4SConvertI16x8Low, kMipsI32x4SConvertI16x8Low) \
+ V(I32x4SConvertI16x8High, kMipsI32x4SConvertI16x8High) \
+ V(I32x4UConvertI16x8Low, kMipsI32x4UConvertI16x8Low) \
+ V(I32x4UConvertI16x8High, kMipsI32x4UConvertI16x8High) \
+ V(I16x8Neg, kMipsI16x8Neg) \
+ V(I16x8SConvertI8x16Low, kMipsI16x8SConvertI8x16Low) \
+ V(I16x8SConvertI8x16High, kMipsI16x8SConvertI8x16High) \
+ V(I16x8UConvertI8x16Low, kMipsI16x8UConvertI8x16Low) \
+ V(I16x8UConvertI8x16High, kMipsI16x8UConvertI8x16High) \
+ V(I8x16Neg, kMipsI8x16Neg) \
+ V(S128Not, kMipsS128Not) \
+ V(S1x4AnyTrue, kMipsS1x4AnyTrue) \
+ V(S1x4AllTrue, kMipsS1x4AllTrue) \
+ V(S1x8AnyTrue, kMipsS1x8AnyTrue) \
+ V(S1x8AllTrue, kMipsS1x8AllTrue) \
+ V(S1x16AnyTrue, kMipsS1x16AnyTrue) \
+ V(S1x16AllTrue, kMipsS1x16AllTrue)
+
+#define SIMD_SHIFT_OP_LIST(V) \
+ V(I32x4Shl) \
+ V(I32x4ShrS) \
+ V(I32x4ShrU) \
+ V(I16x8Shl) \
+ V(I16x8ShrS) \
+ V(I16x8ShrU) \
+ V(I8x16Shl) \
+ V(I8x16ShrS) \
+ V(I8x16ShrU)
+
+#define SIMD_BINOP_LIST(V) \
+ V(F32x4Add, kMipsF32x4Add) \
+ V(F32x4AddHoriz, kMipsF32x4AddHoriz) \
+ V(F32x4Sub, kMipsF32x4Sub) \
+ V(F32x4Mul, kMipsF32x4Mul) \
+ V(F32x4Max, kMipsF32x4Max) \
+ V(F32x4Min, kMipsF32x4Min) \
+ V(F32x4Eq, kMipsF32x4Eq) \
+ V(F32x4Ne, kMipsF32x4Ne) \
+ V(F32x4Lt, kMipsF32x4Lt) \
+ V(F32x4Le, kMipsF32x4Le) \
+ V(I32x4Add, kMipsI32x4Add) \
+ V(I32x4AddHoriz, kMipsI32x4AddHoriz) \
+ V(I32x4Sub, kMipsI32x4Sub) \
+ V(I32x4Mul, kMipsI32x4Mul) \
+ V(I32x4MaxS, kMipsI32x4MaxS) \
+ V(I32x4MinS, kMipsI32x4MinS) \
+ V(I32x4MaxU, kMipsI32x4MaxU) \
+ V(I32x4MinU, kMipsI32x4MinU) \
+ V(I32x4Eq, kMipsI32x4Eq) \
+ V(I32x4Ne, kMipsI32x4Ne) \
+ V(I32x4GtS, kMipsI32x4GtS) \
+ V(I32x4GeS, kMipsI32x4GeS) \
+ V(I32x4GtU, kMipsI32x4GtU) \
+ V(I32x4GeU, kMipsI32x4GeU) \
+ V(I16x8Add, kMipsI16x8Add) \
+ V(I16x8AddSaturateS, kMipsI16x8AddSaturateS) \
+ V(I16x8AddSaturateU, kMipsI16x8AddSaturateU) \
+ V(I16x8AddHoriz, kMipsI16x8AddHoriz) \
+ V(I16x8Sub, kMipsI16x8Sub) \
+ V(I16x8SubSaturateS, kMipsI16x8SubSaturateS) \
+ V(I16x8SubSaturateU, kMipsI16x8SubSaturateU) \
+ V(I16x8Mul, kMipsI16x8Mul) \
+ V(I16x8MaxS, kMipsI16x8MaxS) \
+ V(I16x8MinS, kMipsI16x8MinS) \
+ V(I16x8MaxU, kMipsI16x8MaxU) \
+ V(I16x8MinU, kMipsI16x8MinU) \
+ V(I16x8Eq, kMipsI16x8Eq) \
+ V(I16x8Ne, kMipsI16x8Ne) \
+ V(I16x8GtS, kMipsI16x8GtS) \
+ V(I16x8GeS, kMipsI16x8GeS) \
+ V(I16x8GtU, kMipsI16x8GtU) \
+ V(I16x8GeU, kMipsI16x8GeU) \
+ V(I16x8SConvertI32x4, kMipsI16x8SConvertI32x4) \
+ V(I16x8UConvertI32x4, kMipsI16x8UConvertI32x4) \
+ V(I8x16Add, kMipsI8x16Add) \
+ V(I8x16AddSaturateS, kMipsI8x16AddSaturateS) \
+ V(I8x16AddSaturateU, kMipsI8x16AddSaturateU) \
+ V(I8x16Sub, kMipsI8x16Sub) \
+ V(I8x16SubSaturateS, kMipsI8x16SubSaturateS) \
+ V(I8x16SubSaturateU, kMipsI8x16SubSaturateU) \
+ V(I8x16Mul, kMipsI8x16Mul) \
+ V(I8x16MaxS, kMipsI8x16MaxS) \
+ V(I8x16MinS, kMipsI8x16MinS) \
+ V(I8x16MaxU, kMipsI8x16MaxU) \
+ V(I8x16MinU, kMipsI8x16MinU) \
+ V(I8x16Eq, kMipsI8x16Eq) \
+ V(I8x16Ne, kMipsI8x16Ne) \
+ V(I8x16GtS, kMipsI8x16GtS) \
+ V(I8x16GeS, kMipsI8x16GeS) \
+ V(I8x16GtU, kMipsI8x16GtU) \
+ V(I8x16GeU, kMipsI8x16GeU) \
+ V(I8x16SConvertI16x8, kMipsI8x16SConvertI16x8) \
+ V(I8x16UConvertI16x8, kMipsI8x16UConvertI16x8) \
+ V(S128And, kMipsS128And) \
+ V(S128Or, kMipsS128Or) \
+ V(S128Xor, kMipsS128Xor)
void InstructionSelector::VisitS128Zero(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
}
-void InstructionSelector::VisitS1x4Zero(Node* node) {
- MipsOperandGenerator g(this);
- Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
-}
-
-void InstructionSelector::VisitS1x8Zero(Node* node) {
- MipsOperandGenerator g(this);
- Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
-}
-
-void InstructionSelector::VisitS1x16Zero(Node* node) {
- MipsOperandGenerator g(this);
- Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
-}
-
-void InstructionSelector::VisitF32x4Splat(Node* node) {
- VisitRR(this, kMipsF32x4Splat, node);
-}
-
-void InstructionSelector::VisitF32x4ExtractLane(Node* node) {
- VisitRRI(this, kMipsF32x4ExtractLane, node);
-}
-
-void InstructionSelector::VisitF32x4ReplaceLane(Node* node) {
- VisitRRIR(this, kMipsF32x4ReplaceLane, node);
-}
-
-void InstructionSelector::VisitF32x4SConvertI32x4(Node* node) {
- VisitRR(this, kMipsF32x4SConvertI32x4, node);
-}
-
-void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
- VisitRR(this, kMipsF32x4UConvertI32x4, node);
-}
-
-void InstructionSelector::VisitI32x4Mul(Node* node) {
- VisitRRR(this, kMipsI32x4Mul, node);
-}
-
-void InstructionSelector::VisitI32x4MaxS(Node* node) {
- VisitRRR(this, kMipsI32x4MaxS, node);
-}
-
-void InstructionSelector::VisitI32x4MinS(Node* node) {
- VisitRRR(this, kMipsI32x4MinS, node);
-}
-
-void InstructionSelector::VisitI32x4Eq(Node* node) {
- VisitRRR(this, kMipsI32x4Eq, node);
-}
-
-void InstructionSelector::VisitI32x4Ne(Node* node) {
- VisitRRR(this, kMipsI32x4Ne, node);
-}
-
-void InstructionSelector::VisitI32x4Shl(Node* node) {
- VisitRRI(this, kMipsI32x4Shl, node);
-}
-
-void InstructionSelector::VisitI32x4ShrS(Node* node) {
- VisitRRI(this, kMipsI32x4ShrS, node);
-}
-
-void InstructionSelector::VisitI32x4ShrU(Node* node) {
- VisitRRI(this, kMipsI32x4ShrU, node);
-}
-
-void InstructionSelector::VisitI32x4MaxU(Node* node) {
- VisitRRR(this, kMipsI32x4MaxU, node);
-}
-
-void InstructionSelector::VisitI32x4MinU(Node* node) {
- VisitRRR(this, kMipsI32x4MinU, node);
-}
-
-void InstructionSelector::VisitS32x4Select(Node* node) {
- VisitRRRR(this, kMipsS32x4Select, node);
-}
-
-void InstructionSelector::VisitF32x4Abs(Node* node) {
- VisitRR(this, kMipsF32x4Abs, node);
-}
-
-void InstructionSelector::VisitF32x4Neg(Node* node) {
- VisitRR(this, kMipsF32x4Neg, node);
-}
-
-void InstructionSelector::VisitF32x4RecipApprox(Node* node) {
- VisitRR(this, kMipsF32x4RecipApprox, node);
-}
-
-void InstructionSelector::VisitF32x4RecipSqrtApprox(Node* node) {
- VisitRR(this, kMipsF32x4RecipSqrtApprox, node);
-}
-
-void InstructionSelector::VisitF32x4Add(Node* node) {
- VisitRRR(this, kMipsF32x4Add, node);
-}
-
-void InstructionSelector::VisitF32x4Sub(Node* node) {
- VisitRRR(this, kMipsF32x4Sub, node);
-}
-
-void InstructionSelector::VisitF32x4Mul(Node* node) {
- VisitRRR(this, kMipsF32x4Mul, node);
-}
-
-void InstructionSelector::VisitF32x4Max(Node* node) {
- VisitRRR(this, kMipsF32x4Max, node);
-}
-
-void InstructionSelector::VisitF32x4Min(Node* node) {
- VisitRRR(this, kMipsF32x4Min, node);
-}
-
-void InstructionSelector::VisitF32x4Eq(Node* node) {
- VisitRRR(this, kMipsF32x4Eq, node);
-}
-
-void InstructionSelector::VisitF32x4Ne(Node* node) {
- VisitRRR(this, kMipsF32x4Ne, node);
-}
-
-void InstructionSelector::VisitF32x4Lt(Node* node) {
- VisitRRR(this, kMipsF32x4Lt, node);
-}
-
-void InstructionSelector::VisitF32x4Le(Node* node) {
- VisitRRR(this, kMipsF32x4Le, node);
-}
-
-void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
- VisitRR(this, kMipsI32x4SConvertF32x4, node);
-}
-
-void InstructionSelector::VisitI32x4UConvertF32x4(Node* node) {
- VisitRR(this, kMipsI32x4UConvertF32x4, node);
-}
-
-void InstructionSelector::VisitI32x4Neg(Node* node) {
- VisitRR(this, kMipsI32x4Neg, node);
-}
-
-void InstructionSelector::VisitI32x4LtS(Node* node) {
- VisitRRR(this, kMipsI32x4LtS, node);
-}
-
-void InstructionSelector::VisitI32x4LeS(Node* node) {
- VisitRRR(this, kMipsI32x4LeS, node);
-}
-
-void InstructionSelector::VisitI32x4LtU(Node* node) {
- VisitRRR(this, kMipsI32x4LtU, node);
-}
-
-void InstructionSelector::VisitI32x4LeU(Node* node) {
- VisitRRR(this, kMipsI32x4LeU, node);
-}
-
-void InstructionSelector::VisitI16x8Splat(Node* node) {
- VisitRR(this, kMipsI16x8Splat, node);
-}
-
-void InstructionSelector::VisitI16x8ExtractLane(Node* node) {
- VisitRRI(this, kMipsI16x8ExtractLane, node);
-}
-
-void InstructionSelector::VisitI16x8ReplaceLane(Node* node) {
- VisitRRIR(this, kMipsI16x8ReplaceLane, node);
-}
-
-void InstructionSelector::VisitI16x8Neg(Node* node) {
- VisitRR(this, kMipsI16x8Neg, node);
-}
-
-void InstructionSelector::VisitI16x8Shl(Node* node) {
- VisitRRI(this, kMipsI16x8Shl, node);
-}
-
-void InstructionSelector::VisitI16x8ShrS(Node* node) {
- VisitRRI(this, kMipsI16x8ShrS, node);
-}
-
-void InstructionSelector::VisitI16x8ShrU(Node* node) {
- VisitRRI(this, kMipsI16x8ShrU, node);
-}
-
-void InstructionSelector::VisitI16x8Add(Node* node) {
- VisitRRR(this, kMipsI16x8Add, node);
-}
-
-void InstructionSelector::VisitI16x8AddSaturateS(Node* node) {
- VisitRRR(this, kMipsI16x8AddSaturateS, node);
-}
-
-void InstructionSelector::VisitI16x8Sub(Node* node) {
- VisitRRR(this, kMipsI16x8Sub, node);
-}
-
-void InstructionSelector::VisitI16x8SubSaturateS(Node* node) {
- VisitRRR(this, kMipsI16x8SubSaturateS, node);
-}
-
-void InstructionSelector::VisitI16x8Mul(Node* node) {
- VisitRRR(this, kMipsI16x8Mul, node);
-}
-
-void InstructionSelector::VisitI16x8MaxS(Node* node) {
- VisitRRR(this, kMipsI16x8MaxS, node);
-}
-
-void InstructionSelector::VisitI16x8MinS(Node* node) {
- VisitRRR(this, kMipsI16x8MinS, node);
-}
-
-void InstructionSelector::VisitI16x8Eq(Node* node) {
- VisitRRR(this, kMipsI16x8Eq, node);
-}
-
-void InstructionSelector::VisitI16x8Ne(Node* node) {
- VisitRRR(this, kMipsI16x8Ne, node);
-}
-
-void InstructionSelector::VisitI16x8LtS(Node* node) {
- VisitRRR(this, kMipsI16x8LtS, node);
-}
+#define SIMD_VISIT_SPLAT(Type) \
+ void InstructionSelector::Visit##Type##Splat(Node* node) { \
+ VisitRR(this, kMips##Type##Splat, node); \
+ }
+SIMD_TYPE_LIST(SIMD_VISIT_SPLAT)
+#undef SIMD_VISIT_SPLAT
-void InstructionSelector::VisitI16x8LeS(Node* node) {
- VisitRRR(this, kMipsI16x8LeS, node);
-}
+#define SIMD_VISIT_EXTRACT_LANE(Type) \
+ void InstructionSelector::Visit##Type##ExtractLane(Node* node) { \
+ VisitRRI(this, kMips##Type##ExtractLane, node); \
+ }
+SIMD_TYPE_LIST(SIMD_VISIT_EXTRACT_LANE)
+#undef SIMD_VISIT_EXTRACT_LANE
-void InstructionSelector::VisitI16x8AddSaturateU(Node* node) {
- VisitRRR(this, kMipsI16x8AddSaturateU, node);
-}
+#define SIMD_VISIT_REPLACE_LANE(Type) \
+ void InstructionSelector::Visit##Type##ReplaceLane(Node* node) { \
+ VisitRRIR(this, kMips##Type##ReplaceLane, node); \
+ }
+SIMD_TYPE_LIST(SIMD_VISIT_REPLACE_LANE)
+#undef SIMD_VISIT_REPLACE_LANE
-void InstructionSelector::VisitI16x8SubSaturateU(Node* node) {
- VisitRRR(this, kMipsI16x8SubSaturateU, node);
-}
+#define SIMD_VISIT_UNOP(Name, instruction) \
+ void InstructionSelector::Visit##Name(Node* node) { \
+ VisitRR(this, instruction, node); \
+ }
+SIMD_UNOP_LIST(SIMD_VISIT_UNOP)
+#undef SIMD_VISIT_UNOP
-void InstructionSelector::VisitI16x8MaxU(Node* node) {
- VisitRRR(this, kMipsI16x8MaxU, node);
-}
+#define SIMD_VISIT_SHIFT_OP(Name) \
+ void InstructionSelector::Visit##Name(Node* node) { \
+ VisitRRI(this, kMips##Name, node); \
+ }
+SIMD_SHIFT_OP_LIST(SIMD_VISIT_SHIFT_OP)
+#undef SIMD_VISIT_SHIFT_OP
-void InstructionSelector::VisitI16x8MinU(Node* node) {
- VisitRRR(this, kMipsI16x8MinU, node);
-}
+#define SIMD_VISIT_BINOP(Name, instruction) \
+ void InstructionSelector::Visit##Name(Node* node) { \
+ VisitRRR(this, instruction, node); \
+ }
+SIMD_BINOP_LIST(SIMD_VISIT_BINOP)
+#undef SIMD_VISIT_BINOP
-void InstructionSelector::VisitI16x8LtU(Node* node) {
- VisitRRR(this, kMipsI16x8LtU, node);
+void InstructionSelector::VisitS128Select(Node* node) {
+ VisitRRRR(this, kMipsS128Select, node);
}
-void InstructionSelector::VisitI16x8LeU(Node* node) {
- VisitRRR(this, kMipsI16x8LeU, node);
-}
+namespace {
-void InstructionSelector::VisitI8x16Splat(Node* node) {
- VisitRR(this, kMipsI8x16Splat, node);
+// Tries to match 8x16 byte shuffle to equivalent 32x4 word shuffle.
+bool TryMatch32x4Shuffle(const uint8_t* shuffle, uint8_t* shuffle32x4) {
+ static const int kLanes = 4;
+ static const int kLaneSize = 4;
+ for (int i = 0; i < kLanes; ++i) {
+ if (shuffle[i * kLaneSize] % kLaneSize != 0) return false;
+ for (int j = 1; j < kLaneSize; ++j) {
+ if (shuffle[i * kLaneSize + j] - shuffle[i * kLaneSize + j - 1] != 1)
+ return false;
+ }
+ shuffle32x4[i] = shuffle[i * kLaneSize] / kLaneSize;
+ }
+ return true;
}
-void InstructionSelector::VisitI8x16ExtractLane(Node* node) {
- VisitRRI(this, kMipsI8x16ExtractLane, node);
+// Tries to match byte shuffle to concatenate (sldi) operation.
+bool TryMatchConcat(const uint8_t* shuffle, uint8_t mask, uint8_t* offset) {
+ uint8_t start = shuffle[0];
+ for (int i = 1; i < kSimd128Size - start; ++i) {
+ if ((shuffle[i] & mask) != ((shuffle[i - 1] + 1) & mask)) return false;
+ }
+ uint8_t wrap = kSimd128Size;
+ for (int i = kSimd128Size - start; i < kSimd128Size; ++i, ++wrap) {
+ if ((shuffle[i] & mask) != (wrap & mask)) return false;
+ }
+ *offset = start;
+ return true;
}
-void InstructionSelector::VisitI8x16ReplaceLane(Node* node) {
- VisitRRIR(this, kMipsI8x16ReplaceLane, node);
-}
+struct ShuffleEntry {
+ uint8_t shuffle[kSimd128Size];
+ ArchOpcode opcode;
+};
-void InstructionSelector::VisitI8x16Neg(Node* node) {
- VisitRR(this, kMipsI8x16Neg, node);
+static const ShuffleEntry arch_shuffles[] = {
+ {{0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23},
+ kMipsS32x4InterleaveRight},
+ {{8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31},
+ kMipsS32x4InterleaveLeft},
+ {{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27},
+ kMipsS32x4PackEven},
+ {{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31},
+ kMipsS32x4PackOdd},
+ {{0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 24, 25, 26, 27},
+ kMipsS32x4InterleaveEven},
+ {{4, 5, 6, 7, 20, 21, 22, 23, 12, 13, 14, 15, 28, 29, 30, 31},
+ kMipsS32x4InterleaveOdd},
+
+ {{0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23},
+ kMipsS16x8InterleaveRight},
+ {{8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31},
+ kMipsS16x8InterleaveLeft},
+ {{0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29},
+ kMipsS16x8PackEven},
+ {{2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31},
+ kMipsS16x8PackOdd},
+ {{0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29},
+ kMipsS16x8InterleaveEven},
+ {{2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31},
+ kMipsS16x8InterleaveOdd},
+ {{6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9}, kMipsS16x4Reverse},
+ {{2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13}, kMipsS16x2Reverse},
+
+ {{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23},
+ kMipsS8x16InterleaveRight},
+ {{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31},
+ kMipsS8x16InterleaveLeft},
+ {{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30},
+ kMipsS8x16PackEven},
+ {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
+ kMipsS8x16PackOdd},
+ {{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30},
+ kMipsS8x16InterleaveEven},
+ {{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31},
+ kMipsS8x16InterleaveOdd},
+ {{7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8}, kMipsS8x8Reverse},
+ {{3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12}, kMipsS8x4Reverse},
+ {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14}, kMipsS8x2Reverse}};
+
+bool TryMatchArchShuffle(const uint8_t* shuffle, const ShuffleEntry* table,
+ size_t num_entries, uint8_t mask, ArchOpcode* opcode) {
+ for (size_t i = 0; i < num_entries; ++i) {
+ const ShuffleEntry& entry = table[i];
+ int j = 0;
+ for (; j < kSimd128Size; ++j) {
+ if ((entry.shuffle[j] & mask) != (shuffle[j] & mask)) {
+ break;
+ }
+ }
+ if (j == kSimd128Size) {
+ *opcode = entry.opcode;
+ return true;
+ }
+ }
+ return false;
}
-void InstructionSelector::VisitI8x16Shl(Node* node) {
- VisitRRI(this, kMipsI8x16Shl, node);
+// Canonicalize shuffles to make pattern matching simpler. Returns a mask that
+// will ignore the high bit of indices in some cases.
+uint8_t CanonicalizeShuffle(InstructionSelector* selector, Node* node) {
+ static const int kUnaryShuffleMask = kSimd128Size - 1;
+ const uint8_t* shuffle = OpParameter<uint8_t*>(node);
+ uint8_t mask = 0xff;
+ // If shuffle is unary, set 'mask' to ignore the high bit of the indices.
+ // Replace any unused source with the other.
+ if (selector->GetVirtualRegister(node->InputAt(0)) ==
+ selector->GetVirtualRegister(node->InputAt(1))) {
+ // unary, src0 == src1.
+ mask = kUnaryShuffleMask;
+ } else {
+ bool src0_is_used = false;
+ bool src1_is_used = false;
+ for (int i = 0; i < kSimd128Size; i++) {
+ if (shuffle[i] < kSimd128Size) {
+ src0_is_used = true;
+ } else {
+ src1_is_used = true;
+ }
+ }
+ if (src0_is_used && !src1_is_used) {
+ node->ReplaceInput(1, node->InputAt(0));
+ mask = kUnaryShuffleMask;
+ } else if (src1_is_used && !src0_is_used) {
+ node->ReplaceInput(0, node->InputAt(1));
+ mask = kUnaryShuffleMask;
+ }
+ }
+ return mask;
}
-void InstructionSelector::VisitI8x16ShrS(Node* node) {
- VisitRRI(this, kMipsI8x16ShrS, node);
+int32_t Pack4Lanes(const uint8_t* shuffle, uint8_t mask) {
+ int32_t result = 0;
+ for (int i = 3; i >= 0; --i) {
+ result <<= 8;
+ result |= shuffle[i] & mask;
+ }
+ return result;
}
-void InstructionSelector::VisitS16x8Select(Node* node) {
- VisitRRRR(this, kMipsS16x8Select, node);
-}
+} // namespace
-void InstructionSelector::VisitS8x16Select(Node* node) {
- VisitRRRR(this, kMipsS8x16Select, node);
+void InstructionSelector::VisitS8x16Shuffle(Node* node) {
+ const uint8_t* shuffle = OpParameter<uint8_t*>(node);
+ uint8_t mask = CanonicalizeShuffle(this, node);
+ uint8_t shuffle32x4[4];
+ ArchOpcode opcode;
+ if (TryMatchArchShuffle(shuffle, arch_shuffles, arraysize(arch_shuffles),
+ mask, &opcode)) {
+ VisitRRR(this, opcode, node);
+ return;
+ }
+ uint8_t offset;
+ MipsOperandGenerator g(this);
+ if (TryMatchConcat(shuffle, mask, &offset)) {
+ Emit(kMipsS8x16Concat, g.DefineSameAsFirst(node),
+ g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)),
+ g.UseImmediate(offset));
+ return;
+ }
+ if (TryMatch32x4Shuffle(shuffle, shuffle32x4)) {
+ Emit(kMipsS32x4Shuffle, g.DefineAsRegister(node),
+ g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)),
+ g.UseImmediate(Pack4Lanes(shuffle32x4, mask)));
+ return;
+ }
+ Emit(kMipsS8x16Shuffle, g.DefineAsRegister(node),
+ g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)),
+ g.UseImmediate(Pack4Lanes(shuffle, mask)),
+ g.UseImmediate(Pack4Lanes(shuffle + 4, mask)),
+ g.UseImmediate(Pack4Lanes(shuffle + 8, mask)),
+ g.UseImmediate(Pack4Lanes(shuffle + 12, mask)));
}
// static