const TargetRegisterClass *
getRegClassForTypeOnBank(unsigned OpSize, const RegisterBank &RB,
const RegisterBankInfo &RBI) const;
+ unsigned selectLoadStoreOpCode(MachineInstr &I,
+ MachineRegisterInfo &MRI) const;
const MipsTargetMachine &TM;
const MipsSubtarget &STI;
}
/// Returning Opc indicates that we failed to select MIPS instruction opcode.
-static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned MemSizeInBytes,
- unsigned RegBank, bool isFP64) {
- bool isStore = Opc == TargetOpcode::G_STORE;
+unsigned
+MipsInstructionSelector::selectLoadStoreOpCode(MachineInstr &I,
+ MachineRegisterInfo &MRI) const {
+ STI.getRegisterInfo();
+ const Register DestReg = I.getOperand(0).getReg();
+ const unsigned RegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
+ const unsigned MemSizeInBytes = (*I.memoperands_begin())->getSize();
+ unsigned Opc = I.getOpcode();
+ const bool isStore = Opc == TargetOpcode::G_STORE;
if (RegBank == Mips::GPRBRegBankID) {
if (isStore)
switch (MemSizeInBytes) {
case 4:
return isStore ? Mips::SWC1 : Mips::LWC1;
case 8:
- if (isFP64)
+ if (STI.isFP64bit())
return isStore ? Mips::SDC164 : Mips::LDC164;
else
return isStore ? Mips::SDC1 : Mips::LDC1;
+ case 16: {
+ assert(STI.hasMSA() && "Vector instructions require target with MSA.");
+ const unsigned VectorElementSizeInBytes =
+ MRI.getType(DestReg).getElementType().getSizeInBytes();
+ if (VectorElementSizeInBytes == 1)
+ return isStore ? Mips::ST_B : Mips::LD_B;
+ if (VectorElementSizeInBytes == 2)
+ return isStore ? Mips::ST_H : Mips::LD_H;
+ if (VectorElementSizeInBytes == 4)
+ return isStore ? Mips::ST_W : Mips::LD_W;
+ if (VectorElementSizeInBytes == 8)
+ return isStore ? Mips::ST_D : Mips::LD_D;
+ return Opc;
+ }
default:
return Opc;
}
case G_LOAD:
case G_ZEXTLOAD:
case G_SEXTLOAD: {
- const Register DestReg = I.getOperand(0).getReg();
- const unsigned DestRegBank = RBI.getRegBank(DestReg, MRI, TRI)->getID();
- const unsigned OpSize = MRI.getType(DestReg).getSizeInBits();
- const unsigned OpMemSizeInBytes = (*I.memoperands_begin())->getSize();
-
- if (DestRegBank == Mips::GPRBRegBankID && OpSize != 32)
- return false;
-
- if (DestRegBank == Mips::FPRBRegBankID && OpSize != 32 && OpSize != 64)
- return false;
-
- const unsigned NewOpc = selectLoadStoreOpCode(
- I.getOpcode(), OpMemSizeInBytes, DestRegBank, STI.isFP64bit());
+ const unsigned NewOpc = selectLoadStoreOpCode(I, MRI);
if (NewOpc == I.getOpcode())
return false;
using namespace llvm;
+struct TypesAndMemOps {
+ LLT ValTy;
+ LLT PtrTy;
+ unsigned MemSize;
+ bool MustBeNaturallyAligned;
+};
+
+static bool
+CheckTy0Ty1MemSizeAlign(const LegalityQuery &Query,
+ std::initializer_list<TypesAndMemOps> SupportedValues) {
+ for (auto &Val : SupportedValues) {
+ if (Val.ValTy != Query.Types[0])
+ continue;
+ if (Val.PtrTy != Query.Types[1])
+ continue;
+ if (Val.MemSize != Query.MMODescrs[0].SizeInBits)
+ continue;
+ if (Val.MustBeNaturallyAligned &&
+ Query.MMODescrs[0].SizeInBits % Query.MMODescrs[0].AlignInBits != 0)
+ continue;
+ return true;
+ }
+ return false;
+}
+
MipsLegalizerInfo::MipsLegalizerInfo(const MipsSubtarget &ST) {
using namespace TargetOpcode;
const LLT s1 = LLT::scalar(1);
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
+ const LLT v16s8 = LLT::vector(16, 8);
+ const LLT v8s16 = LLT::vector(8, 16);
+ const LLT v4s32 = LLT::vector(4, 32);
+ const LLT v2s64 = LLT::vector(2, 64);
const LLT p0 = LLT::pointer(0, 32);
getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL})
.maxScalar(0, s32);
getActionDefinitionsBuilder({G_LOAD, G_STORE})
- .legalForTypesWithMemDesc({{s32, p0, 8, 8},
- {s32, p0, 16, 8},
- {s32, p0, 32, 8},
- {s64, p0, 64, 8},
- {p0, p0, 32, 8}})
+ .legalIf([=, &ST](const LegalityQuery &Query) {
+ if (CheckTy0Ty1MemSizeAlign(Query, {{s32, p0, 8, ST.hasMips32r6()},
+ {s32, p0, 16, ST.hasMips32r6()},
+ {s32, p0, 32, ST.hasMips32r6()},
+ {p0, p0, 32, ST.hasMips32r6()},
+ {s64, p0, 64, ST.hasMips32r6()}}))
+ return true;
+ if (ST.hasMSA() &&
+ CheckTy0Ty1MemSizeAlign(Query, {{v16s8, p0, 128, false},
+ {v8s16, p0, 128, false},
+ {v4s32, p0, 128, false},
+ {v2s64, p0, 128, false}}))
+ return true;
+ return false;
+ })
.minScalar(0, s32);
getActionDefinitionsBuilder(G_IMPLICIT_DEF)
#include "MipsRegisterBankInfo.h"
#include "MipsInstrInfo.h"
+#include "MipsTargetMachine.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
PMI_GPR,
PMI_SPR,
PMI_DPR,
+ PMI_MSA,
PMI_Min = PMI_GPR,
};
RegisterBankInfo::PartialMapping PartMappings[]{
{0, 32, GPRBRegBank},
{0, 32, FPRBRegBank},
- {0, 64, FPRBRegBank}
+ {0, 64, FPRBRegBank},
+ {0, 128, FPRBRegBank}
};
enum ValueMappingIdx {
InvalidIdx = 0,
GPRIdx = 1,
SPRIdx = 4,
- DPRIdx = 7
+ DPRIdx = 7,
+ MSAIdx = 10
};
RegisterBankInfo::ValueMapping ValueMappings[] = {
// up to 3 operands in FPRs - double precission
{&PartMappings[PMI_DPR - PMI_Min], 1},
{&PartMappings[PMI_DPR - PMI_Min], 1},
- {&PartMappings[PMI_DPR - PMI_Min], 1}
+ {&PartMappings[PMI_DPR - PMI_Min], 1},
+ // up to 3 operands in FPRs - MSA
+ {&PartMappings[PMI_MSA - PMI_Min], 1},
+ {&PartMappings[PMI_MSA - PMI_Min], 1},
+ {&PartMappings[PMI_MSA - PMI_Min], 1}
};
} // end namespace Mips
case Mips::FGR32RegClassID:
case Mips::FGR64RegClassID:
case Mips::AFGR64RegClassID:
+ case Mips::MSA128BRegClassID:
+ case Mips::MSA128HRegClassID:
+ case Mips::MSA128WRegClassID:
+ case Mips::MSA128DRegClassID:
return getRegBank(Mips::FPRBRegBankID);
default:
llvm_unreachable("Register class not supported");
}
}
+static const MipsRegisterBankInfo::ValueMapping *
+getMSAMapping(const MachineFunction &MF) {
+ assert(static_cast<const MipsSubtarget &>(MF.getSubtarget()).hasMSA() &&
+ "MSA mapping not available on target without MSA.");
+ return &Mips::ValueMappings[Mips::MSAIdx];
+}
+
static const MipsRegisterBankInfo::ValueMapping *getFprbMapping(unsigned Size) {
return Size == 32 ? &Mips::ValueMappings[Mips::SPRIdx]
: &Mips::ValueMappings[Mips::DPRIdx];
if (RegTy.isScalar() &&
(RegTy.getSizeInBits() != 32 && RegTy.getSizeInBits() != 64))
return getInvalidInstructionMapping();
+
+ if (RegTy.isVector() && RegTy.getSizeInBits() != 128)
+ return getInvalidInstructionMapping();
}
}
break;
case G_STORE:
case G_LOAD:
+ if (Op0Size == 128) {
+ OperandsMapping = getOperandsMapping(
+ {getMSAMapping(MF), &Mips::ValueMappings[Mips::GPRIdx]});
+ break;
+ }
+
if (!Op0Ty.isPointer())
InstTy = TI.determineInstType(&MI);
def GPRBRegBank : RegisterBank<"GPRB", [GPR32]>;
-def FPRBRegBank : RegisterBank<"FPRB", [FGR64, AFGR64]>;
+def FPRBRegBank : RegisterBank<"FPRB", [FGR64, AFGR64, MSA128D]>;
--- /dev/null
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -mcpu=mips32r5 -mattr=msa,+fp64 -mattr=nan2008 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=P5600
+--- |
+
+ define void @load_store_v16i8(<16 x i8>* %a, <16 x i8>* %b) { entry: ret void }
+ define void @load_store_v8i16(<8 x i16>* %a, <8 x i16>* %b) { entry: ret void }
+ define void @load_store_v4i32(<4 x i32>* %a, <4 x i32>* %b) { entry: ret void }
+ define void @load_store_v2i64(<2 x i64>* %a, <2 x i64>* %b) { entry: ret void }
+ define void @load_store_v4f32(<4 x float>* %a, <4 x float>* %b) { entry: ret void }
+ define void @load_store_v2f64(<2 x double>* %a, <2 x double>* %b) { entry: ret void }
+
+...
+---
+name: load_store_v16i8
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v16i8
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; P5600: [[LD_B:%[0-9]+]]:msa128b = LD_B [[COPY1]], 0 :: (load 16 from %ir.b)
+ ; P5600: ST_B [[LD_B]], [[COPY]], 0 :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:gprb(p0) = COPY $a0
+ %1:gprb(p0) = COPY $a1
+ %2:fprb(<16 x s8>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<16 x s8>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v8i16
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v8i16
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; P5600: [[LD_H:%[0-9]+]]:msa128h = LD_H [[COPY1]], 0 :: (load 16 from %ir.b)
+ ; P5600: ST_H [[LD_H]], [[COPY]], 0 :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:gprb(p0) = COPY $a0
+ %1:gprb(p0) = COPY $a1
+ %2:fprb(<8 x s16>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<8 x s16>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v4i32
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v4i32
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; P5600: [[LD_W:%[0-9]+]]:msa128w = LD_W [[COPY1]], 0 :: (load 16 from %ir.b)
+ ; P5600: ST_W [[LD_W]], [[COPY]], 0 :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:gprb(p0) = COPY $a0
+ %1:gprb(p0) = COPY $a1
+ %2:fprb(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<4 x s32>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v2i64
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v2i64
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; P5600: [[LD_D:%[0-9]+]]:msa128d = LD_D [[COPY1]], 0 :: (load 16 from %ir.b)
+ ; P5600: ST_D [[LD_D]], [[COPY]], 0 :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:gprb(p0) = COPY $a0
+ %1:gprb(p0) = COPY $a1
+ %2:fprb(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<2 x s64>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v4f32
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v4f32
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; P5600: [[LD_W:%[0-9]+]]:msa128w = LD_W [[COPY1]], 0 :: (load 16 from %ir.b)
+ ; P5600: ST_W [[LD_W]], [[COPY]], 0 :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:gprb(p0) = COPY $a0
+ %1:gprb(p0) = COPY $a1
+ %2:fprb(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<4 x s32>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v2f64
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v2f64
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gpr32 = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gpr32 = COPY $a1
+ ; P5600: [[LD_D:%[0-9]+]]:msa128d = LD_D [[COPY1]], 0 :: (load 16 from %ir.b)
+ ; P5600: ST_D [[LD_D]], [[COPY]], 0 :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:gprb(p0) = COPY $a0
+ %1:gprb(p0) = COPY $a1
+ %2:fprb(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<2 x s64>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
--- /dev/null
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -mcpu=mips32r5 -mattr=msa,+fp64 -mattr=nan2008 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=P5600
+--- |
+
+ define void @load_store_v16i8(<16 x i8>* %a, <16 x i8>* %b) { entry: ret void }
+ define void @load_store_v8i16(<8 x i16>* %a, <8 x i16>* %b) { entry: ret void }
+ define void @load_store_v4i32(<4 x i32>* %a, <4 x i32>* %b) { entry: ret void }
+ define void @load_store_v2i64(<2 x i64>* %a, <2 x i64>* %b) { entry: ret void }
+ define void @load_store_v4f32(<4 x float>* %a, <4 x float>* %b) { entry: ret void }
+ define void @load_store_v2f64(<2 x double>* %a, <2 x double>* %b) { entry: ret void }
+
+...
+---
+name: load_store_v16i8
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v16i8
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:_(<16 x s8>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<16 x s8>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<16 x s8>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<16 x s8>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v8i16
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v8i16
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:_(<8 x s16>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<8 x s16>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<8 x s16>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<8 x s16>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v4i32
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v4i32
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:_(<4 x s32>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<4 x s32>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<4 x s32>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v2i64
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v2i64
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:_(<2 x s64>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<2 x s64>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<2 x s64>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v4f32
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v4f32
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:_(<4 x s32>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<4 x s32>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<4 x s32>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v2f64
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v2f64
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:_(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:_(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:_(<2 x s64>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<2 x s64>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<2 x s64>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -O0 -mtriple=mipsel-linux-gnu -global-isel -mcpu=mips32r5 -mattr=msa,+fp64 -mattr=nan2008 -verify-machineinstrs %s -o -| FileCheck %s -check-prefixes=P5600
+
+define void @load_store_v16i8(<16 x i8>* %a, <16 x i8>* %b) {
+; P5600-LABEL: load_store_v16i8:
+; P5600: # %bb.0: # %entry
+; P5600-NEXT: ld.b $w0, 0($5)
+; P5600-NEXT: st.b $w0, 0($4)
+; P5600-NEXT: jr $ra
+; P5600-NEXT: nop
+entry:
+ %0 = load <16 x i8>, <16 x i8>* %b, align 16
+ store <16 x i8> %0, <16 x i8>* %a, align 16
+ ret void
+}
+
+define void @load_store_v8i16(<8 x i16>* %a, <8 x i16>* %b) {
+; P5600-LABEL: load_store_v8i16:
+; P5600: # %bb.0: # %entry
+; P5600-NEXT: ld.h $w0, 0($5)
+; P5600-NEXT: st.h $w0, 0($4)
+; P5600-NEXT: jr $ra
+; P5600-NEXT: nop
+entry:
+ %0 = load <8 x i16>, <8 x i16>* %b, align 16
+ store <8 x i16> %0, <8 x i16>* %a, align 16
+ ret void
+}
+
+define void @load_store_v4i32(<4 x i32>* %a, <4 x i32>* %b) {
+; P5600-LABEL: load_store_v4i32:
+; P5600: # %bb.0: # %entry
+; P5600-NEXT: ld.w $w0, 0($5)
+; P5600-NEXT: st.w $w0, 0($4)
+; P5600-NEXT: jr $ra
+; P5600-NEXT: nop
+entry:
+ %0 = load <4 x i32>, <4 x i32>* %b, align 16
+ store <4 x i32> %0, <4 x i32>* %a, align 16
+ ret void
+}
+
+define void @load_store_v2i64(<2 x i64>* %a, <2 x i64>* %b) {
+; P5600-LABEL: load_store_v2i64:
+; P5600: # %bb.0: # %entry
+; P5600-NEXT: ld.d $w0, 0($5)
+; P5600-NEXT: st.d $w0, 0($4)
+; P5600-NEXT: jr $ra
+; P5600-NEXT: nop
+entry:
+ %0 = load <2 x i64>, <2 x i64>* %b, align 16
+ store <2 x i64> %0, <2 x i64>* %a, align 16
+ ret void
+}
+
+define void @load_store_v4f32(<4 x float>* %a, <4 x float>* %b) {
+; P5600-LABEL: load_store_v4f32:
+; P5600: # %bb.0: # %entry
+; P5600-NEXT: ld.w $w0, 0($5)
+; P5600-NEXT: st.w $w0, 0($4)
+; P5600-NEXT: jr $ra
+; P5600-NEXT: nop
+entry:
+ %0 = load <4 x float>, <4 x float>* %b, align 16
+ store <4 x float> %0, <4 x float>* %a, align 16
+ ret void
+}
+
+define void @load_store_v2f64(<2 x double>* %a, <2 x double>* %b) {
+; P5600-LABEL: load_store_v2f64:
+; P5600: # %bb.0: # %entry
+; P5600-NEXT: ld.d $w0, 0($5)
+; P5600-NEXT: st.d $w0, 0($4)
+; P5600-NEXT: jr $ra
+; P5600-NEXT: nop
+entry:
+ %0 = load <2 x double>, <2 x double>* %b, align 16
+ store <2 x double> %0, <2 x double>* %a, align 16
+ ret void
+}
--- /dev/null
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -O0 -mtriple=mipsel-linux-gnu -mcpu=mips32r5 -mattr=msa,+fp64 -mattr=nan2008 -run-pass=regbankselect -verify-machineinstrs %s -o - | FileCheck %s -check-prefixes=P5600
+--- |
+
+ define void @load_store_v16i8(<16 x i8>* %a, <16 x i8>* %b) { entry: ret void }
+ define void @load_store_v8i16(<8 x i16>* %a, <8 x i16>* %b) { entry: ret void }
+ define void @load_store_v4i32(<4 x i32>* %a, <4 x i32>* %b) { entry: ret void }
+ define void @load_store_v2i64(<2 x i64>* %a, <2 x i64>* %b) { entry: ret void }
+ define void @load_store_v4f32(<4 x float>* %a, <4 x float>* %b) { entry: ret void }
+ define void @load_store_v2f64(<2 x double>* %a, <2 x double>* %b) { entry: ret void }
+
+...
+---
+name: load_store_v16i8
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v16i8
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:fprb(<16 x s8>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<16 x s8>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<16 x s8>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<16 x s8>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v8i16
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v8i16
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:fprb(<8 x s16>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<8 x s16>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<8 x s16>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<8 x s16>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v4i32
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v4i32
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:fprb(<4 x s32>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<4 x s32>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<4 x s32>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v2i64
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v2i64
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:fprb(<2 x s64>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<2 x s64>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<2 x s64>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v4f32
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v4f32
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:fprb(<4 x s32>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<4 x s32>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<4 x s32>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<4 x s32>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...
+---
+name: load_store_v2f64
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.1.entry:
+ liveins: $a0, $a1
+
+ ; P5600-LABEL: name: load_store_v2f64
+ ; P5600: liveins: $a0, $a1
+ ; P5600: [[COPY:%[0-9]+]]:gprb(p0) = COPY $a0
+ ; P5600: [[COPY1:%[0-9]+]]:gprb(p0) = COPY $a1
+ ; P5600: [[LOAD:%[0-9]+]]:fprb(<2 x s64>) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.b)
+ ; P5600: G_STORE [[LOAD]](<2 x s64>), [[COPY]](p0) :: (store 16 into %ir.a)
+ ; P5600: RetRA
+ %0:_(p0) = COPY $a0
+ %1:_(p0) = COPY $a1
+ %2:_(<2 x s64>) = G_LOAD %1(p0) :: (load 16 from %ir.b)
+ G_STORE %2(<2 x s64>), %0(p0) :: (store 16 into %ir.a)
+ RetRA
+
+...