Commit b92aca8e authored by Zhao Jiazhong's avatar Zhao Jiazhong Committed by Commit Bot

[mips][wasm-simd] Implement load splat and load extend

Port 72b68dee https://crrev.com/c/1928150

Change-Id: Ic5d195046839bc83148d759225bc5330ce66a53b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2004139Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Auto-Submit: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Cr-Commit-Position: refs/heads/master@{#65938}
parent 8b5480b2
......@@ -1716,6 +1716,117 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ByteSwapSigned(i.OutputRegister(0), i.InputRegister(0), 4);
break;
}
case kMipsS8x16LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ lb(kScratchReg, i.MemoryOperand());
__ fill_b(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMipsS16x8LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ lh(kScratchReg, i.MemoryOperand());
__ fill_h(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMipsS32x4LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ Lw(kScratchReg, i.MemoryOperand());
__ fill_w(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMipsS64x2LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
break;
}
case kMipsI16x8Load8x8S: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
__ clti_s_b(kSimd128ScratchReg, dst, 0);
__ ilvr_b(dst, kSimd128ScratchReg, dst);
break;
}
case kMipsI16x8Load8x8U: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
__ ilvr_b(dst, kSimd128RegZero, dst);
break;
}
case kMipsI32x4Load16x4S: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
__ clti_s_h(kSimd128ScratchReg, dst, 0);
__ ilvr_h(dst, kSimd128ScratchReg, dst);
break;
}
case kMipsI32x4Load16x4U: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
__ ilvr_h(dst, kSimd128RegZero, dst);
break;
}
case kMipsI64x2Load32x2S: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
__ clti_s_w(kSimd128ScratchReg, dst, 0);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
break;
}
case kMipsI64x2Load32x2U: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
MemOperand memLow = i.MemoryOperand();
MemOperand memHigh = MemOperand(memLow.rm(), memLow.offset() + 4);
__ Lw(kScratchReg, memLow);
__ fill_w(dst, kScratchReg);
__ Lw(kScratchReg, memHigh);
__ fill_w(kSimd128ScratchReg, kScratchReg);
__ ilvr_w(dst, kSimd128ScratchReg, dst);
__ ilvr_w(dst, kSimd128RegZero, dst);
break;
}
case kWord32AtomicLoadInt8:
ASSEMBLE_ATOMIC_LOAD_INTEGER(lb);
break;
......
......@@ -294,6 +294,16 @@ namespace compiler {
V(MipsS8x8Reverse) \
V(MipsS8x4Reverse) \
V(MipsS8x2Reverse) \
V(MipsS8x16LoadSplat) \
V(MipsS16x8LoadSplat) \
V(MipsS32x4LoadSplat) \
V(MipsS64x2LoadSplat) \
V(MipsI16x8Load8x8S) \
V(MipsI16x8Load8x8U) \
V(MipsI32x4Load16x4S) \
V(MipsI32x4Load16x4U) \
V(MipsI64x2Load32x2S) \
V(MipsI64x2Load32x2U) \
V(MipsMsaLd) \
V(MipsMsaSt) \
V(MipsI32x4SConvertI16x8Low) \
......
......@@ -296,6 +296,16 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kMipsUlhu:
case kMipsUlw:
case kMipsUlwc1:
case kMipsS8x16LoadSplat:
case kMipsS16x8LoadSplat:
case kMipsS32x4LoadSplat:
case kMipsS64x2LoadSplat:
case kMipsI16x8Load8x8S:
case kMipsI16x8Load8x8U:
case kMipsI32x4Load16x4S:
case kMipsI32x4Load16x4U:
case kMipsI64x2Load32x2S:
case kMipsI64x2Load32x2U:
case kMipsWord32AtomicPairLoad:
return kIsLoadOperation;
......
......@@ -278,6 +278,61 @@ void InstructionSelector::VisitAbortCSAAssert(Node* node) {
Emit(kArchAbortCSAAssert, g.NoOutput(), g.UseFixed(node->InputAt(0), a0));
}
void InstructionSelector::VisitLoadTransform(Node* node) {
LoadTransformParameters params = LoadTransformParametersOf(node->op());
MipsOperandGenerator g(this);
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
InstructionCode opcode = kArchNop;
switch (params.transformation) {
case LoadTransformation::kS8x16LoadSplat:
opcode = kMipsS8x16LoadSplat;
break;
case LoadTransformation::kS16x8LoadSplat:
opcode = kMipsS16x8LoadSplat;
break;
case LoadTransformation::kS32x4LoadSplat:
opcode = kMipsS32x4LoadSplat;
break;
case LoadTransformation::kS64x2LoadSplat:
opcode = kMipsS64x2LoadSplat;
break;
case LoadTransformation::kI16x8Load8x8S:
opcode = kMipsI16x8Load8x8S;
break;
case LoadTransformation::kI16x8Load8x8U:
opcode = kMipsI16x8Load8x8U;
break;
case LoadTransformation::kI32x4Load16x4S:
opcode = kMipsI32x4Load16x4S;
break;
case LoadTransformation::kI32x4Load16x4U:
opcode = kMipsI32x4Load16x4U;
break;
case LoadTransformation::kI64x2Load32x2S:
opcode = kMipsI64x2Load32x2S;
break;
case LoadTransformation::kI64x2Load32x2U:
opcode = kMipsI64x2Load32x2U;
break;
default:
UNIMPLEMENTED();
}
if (g.CanBeImmediate(index, opcode)) {
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
} else {
InstructionOperand addr_reg = g.TempRegister();
Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
g.UseRegister(index), g.UseRegister(base));
// Emit desired load opcode, using temp addr_reg.
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
}
}
void InstructionSelector::VisitLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
MipsOperandGenerator g(this);
......
......@@ -1858,6 +1858,84 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ ByteSwapSigned(i.OutputRegister(0), i.InputRegister(0), 4);
break;
}
case kMips64S8x16LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ Lb(kScratchReg, i.MemoryOperand());
__ fill_b(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMips64S16x8LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ Lh(kScratchReg, i.MemoryOperand());
__ fill_h(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMips64S32x4LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ Lw(kScratchReg, i.MemoryOperand());
__ fill_w(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMips64S64x2LoadSplat: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(i.OutputSimd128Register(), kScratchReg);
break;
}
case kMips64I16x8Load8x8S: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
Simd128Register scratch = kSimd128ScratchReg;
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(dst, kScratchReg);
__ clti_s_b(scratch, dst, 0);
__ ilvr_b(dst, scratch, dst);
break;
}
case kMips64I16x8Load8x8U: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(dst, kScratchReg);
__ ilvr_b(dst, kSimd128RegZero, dst);
break;
}
case kMips64I32x4Load16x4S: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
Simd128Register scratch = kSimd128ScratchReg;
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(dst, kScratchReg);
__ clti_s_h(scratch, dst, 0);
__ ilvr_h(dst, scratch, dst);
break;
}
case kMips64I32x4Load16x4U: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(dst, kScratchReg);
__ ilvr_h(dst, kSimd128RegZero, dst);
break;
}
case kMips64I64x2Load32x2S: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
Simd128Register scratch = kSimd128ScratchReg;
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(dst, kScratchReg);
__ clti_s_w(scratch, dst, 0);
__ ilvr_w(dst, scratch, dst);
break;
}
case kMips64I64x2Load32x2U: {
CpuFeatureScope msa_scope(tasm(), MIPS_SIMD);
Simd128Register dst = i.OutputSimd128Register();
__ Ld(kScratchReg, i.MemoryOperand());
__ fill_d(dst, kScratchReg);
__ ilvr_w(dst, kSimd128RegZero, dst);
break;
}
case kWord32AtomicLoadInt8:
ASSEMBLE_ATOMIC_LOAD_INTEGER(Lb);
break;
......
......@@ -324,6 +324,16 @@ namespace compiler {
V(Mips64S8x8Reverse) \
V(Mips64S8x4Reverse) \
V(Mips64S8x2Reverse) \
V(Mips64S8x16LoadSplat) \
V(Mips64S16x8LoadSplat) \
V(Mips64S32x4LoadSplat) \
V(Mips64S64x2LoadSplat) \
V(Mips64I16x8Load8x8S) \
V(Mips64I16x8Load8x8U) \
V(Mips64I32x4Load16x4S) \
V(Mips64I32x4Load16x4U) \
V(Mips64I64x2Load32x2S) \
V(Mips64I64x2Load32x2U) \
V(Mips64MsaLd) \
V(Mips64MsaSt) \
V(Mips64I32x4SConvertI16x8Low) \
......
......@@ -324,6 +324,16 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kMips64Ulw:
case kMips64Ulwu:
case kMips64Ulwc1:
case kMips64S8x16LoadSplat:
case kMips64S16x8LoadSplat:
case kMips64S32x4LoadSplat:
case kMips64S64x2LoadSplat:
case kMips64I16x8Load8x8S:
case kMips64I16x8Load8x8U:
case kMips64I32x4Load16x4S:
case kMips64I32x4Load16x4U:
case kMips64I64x2Load32x2S:
case kMips64I64x2Load32x2U:
case kMips64Word64AtomicLoadUint8:
case kMips64Word64AtomicLoadUint16:
case kMips64Word64AtomicLoadUint32:
......
......@@ -359,6 +359,48 @@ void EmitLoad(InstructionSelector* selector, Node* node, InstructionCode opcode,
}
}
void InstructionSelector::VisitLoadTransform(Node* node) {
LoadTransformParameters params = LoadTransformParametersOf(node->op());
InstructionCode opcode = kArchNop;
switch (params.transformation) {
case LoadTransformation::kS8x16LoadSplat:
opcode = kMips64S8x16LoadSplat;
break;
case LoadTransformation::kS16x8LoadSplat:
opcode = kMips64S16x8LoadSplat;
break;
case LoadTransformation::kS32x4LoadSplat:
opcode = kMips64S32x4LoadSplat;
break;
case LoadTransformation::kS64x2LoadSplat:
opcode = kMips64S64x2LoadSplat;
break;
case LoadTransformation::kI16x8Load8x8S:
opcode = kMips64I16x8Load8x8S;
break;
case LoadTransformation::kI16x8Load8x8U:
opcode = kMips64I16x8Load8x8U;
break;
case LoadTransformation::kI32x4Load16x4S:
opcode = kMips64I32x4Load16x4S;
break;
case LoadTransformation::kI32x4Load16x4U:
opcode = kMips64I32x4Load16x4U;
break;
case LoadTransformation::kI64x2Load32x2S:
opcode = kMips64I64x2Load32x2S;
break;
case LoadTransformation::kI64x2Load32x2U:
opcode = kMips64I64x2Load32x2U;
break;
default:
UNIMPLEMENTED();
}
EmitLoad(this, node, opcode);
}
void InstructionSelector::VisitLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
......
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