Commit 126881bb authored by Zhao Jiazhong's avatar Zhao Jiazhong Committed by Commit Bot

[mips][wasm-simd][liftoff] Implement v128.const

Port d0e6ff15
https://crrev.com/c/2285149

Port 34871edd
https://crrev.com/c/2284212

Port dc82799d
https://crrev.com/c/2290623

Change-Id: I8cceface23368dafc6a029edaa7c6a125a0760ed
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2291306
Commit-Queue: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68856}
parent bd964935
......@@ -2243,6 +2243,8 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
V(S128Xor, kMipsS128Xor) \
V(S128AndNot, kMipsS128AndNot)
void InstructionSelector::VisitS128Const(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS128Zero(Node* node) {
MipsOperandGenerator g(this);
Emit(kMipsS128Zero, g.DefineSameAsFirst(node));
......
......@@ -2085,10 +2085,27 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Assert(eq, static_cast<AbortReason>(i.InputOperand(2).immediate()),
i.InputRegister(0), Operand(i.InputRegister(1)));
break;
case kMips64S128Const: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
uint64_t imm1 = make_uint64(i.InputUint32(1), i.InputUint32(0));
uint64_t imm2 = make_uint64(i.InputUint32(3), i.InputUint32(2));
__ li(kScratchReg, imm1);
__ insert_d(dst, 0, kScratchReg);
__ li(kScratchReg, imm2);
__ insert_d(dst, 1, kScratchReg);
break;
}
case kMips64S128Zero: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ xor_v(i.OutputSimd128Register(), i.OutputSimd128Register(),
i.OutputSimd128Register());
Simd128Register dst = i.OutputSimd128Register();
__ xor_v(dst, dst, dst);
break;
}
case kMips64S128AllOnes: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ ceq_d(dst, dst, dst);
break;
}
case kMips64I32x4Splat: {
......
......@@ -165,7 +165,9 @@ namespace compiler {
V(Mips64Seh) \
V(Mips64Sync) \
V(Mips64AssertEqual) \
V(Mips64S128Const) \
V(Mips64S128Zero) \
V(Mips64S128AllOnes) \
V(Mips64I32x4Splat) \
V(Mips64I32x4ExtractLane) \
V(Mips64I32x4ReplaceLane) \
......
......@@ -271,7 +271,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kMips64S128Select:
case kMips64S128AndNot:
case kMips64S128Xor:
case kMips64S128Const:
case kMips64S128Zero:
case kMips64S128AllOnes:
case kMips64S16x8InterleaveEven:
case kMips64S16x8InterleaveOdd:
case kMips64S16x8InterleaveLeft:
......
......@@ -2916,6 +2916,26 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
V(S128Xor, kMips64S128Xor) \
V(S128AndNot, kMips64S128AndNot)
void InstructionSelector::VisitS128Const(Node* node) {
Mips64OperandGenerator g(this);
static const int kUint32Immediates = kSimd128Size / sizeof(uint32_t);
uint32_t val[kUint32Immediates];
memcpy(val, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
val[2] == UINT32_MAX && val[3] == UINT32_MAX;
InstructionOperand dst = g.DefineAsRegister(node);
if (all_zeros) {
Emit(kMips64S128Zero, dst);
} else if (all_ones) {
Emit(kMips64S128AllOnes, dst);
} else {
Emit(kMips64S128Const, dst, g.UseImmediate(val[0]), g.UseImmediate(val[1]),
g.UseImmediate(val[2]), g.UseImmediate(val[3]));
}
}
void InstructionSelector::VisitS128Zero(Node* node) {
Mips64OperandGenerator g(this);
Emit(kMips64S128Zero, g.DefineAsRegister(node));
......
......@@ -1750,6 +1750,11 @@ void LiftoffAssembler::emit_f64x2_le(LiftoffRegister dst, LiftoffRegister lhs,
bailout(kSimd, "emit_f64x2_le");
}
void LiftoffAssembler::emit_s128_const(LiftoffRegister dst,
const uint8_t imms[16]) {
bailout(kSimd, "emit_s128_const");
}
void LiftoffAssembler::emit_s128_not(LiftoffRegister dst, LiftoffRegister src) {
bailout(kSimd, "emit_s128_not");
}
......
......@@ -1675,6 +1675,17 @@ void LiftoffAssembler::emit_f64x2_le(LiftoffRegister dst, LiftoffRegister lhs,
fcle_d(dst.fp().toW(), lhs.fp().toW(), rhs.fp().toW());
}
void LiftoffAssembler::emit_s128_const(LiftoffRegister dst,
const uint8_t imms[16]) {
MSARegister dst_msa = dst.fp().toW();
uint64_t vals[2];
memcpy(vals, imms, sizeof(vals));
li(kScratchReg, vals[0]);
insert_d(dst_msa, 0, kScratchReg);
li(kScratchReg, vals[1]);
insert_d(dst_msa, 1, kScratchReg);
}
void LiftoffAssembler::emit_s128_not(LiftoffRegister dst, LiftoffRegister src) {
nor_v(dst.fp().toW(), src.fp().toW(), src.fp().toW());
}
......
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