aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorKai Nacke <kai@redstar.de>2022-08-01 23:35:55 -0400
committerKai Nacke <kai@redstar.de>2022-11-13 11:07:39 -0500
commitaf16dd4a0b0e2b10fa7149e81ec0d5839d2d103e (patch)
tree6dc2e21016b56880f0c12ec88330ff4ff8bd4f39 /llvm
parentb076c1b283b8d1ba262247dda505ebbce83f0fa3 (diff)
downloadllvm-af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e.zip
llvm-af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e.tar.gz
llvm-af16dd4a0b0e2b10fa7149e81ec0d5839d2d103e.tar.bz2
[m88k] Legalize & select G_MUL
With special check to generate mulu.d instruction from 88110.
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp40
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp46
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp11
3 files changed, 92 insertions, 5 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
index 2bc663f..1172343 100644
--- a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
@@ -82,6 +82,8 @@ private:
MachineRegisterInfo &MRI) const;
bool selectPtrAdd(MachineInstr &I, MachineBasicBlock &MBB,
MachineRegisterInfo &MRI) const;
+ bool selectMul(MachineInstr &I, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const;
bool selectExt(MachineInstr &I, MachineBasicBlock &MBB,
MachineRegisterInfo &MRI) const;
bool selectLoadStore(MachineInstr &I, MachineBasicBlock &MBB,
@@ -594,6 +596,38 @@ bool M88kInstructionSelector::selectPtrAdd(MachineInstr &I,
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}
+bool M88kInstructionSelector::selectMul(MachineInstr &I, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const {
+ assert(I.getOpcode() == TargetOpcode::G_MUL && "Unexpected G code");
+
+ // Only selects special mulu.d instruction, the other mul instructions are
+ // matched by the patterns from the target description.
+ if (!isMC88110())
+ return false;
+
+ MachineInstr *MI = nullptr;
+ Register DstReg = I.getOperand(0).getReg();
+ Register Src1Reg = I.getOperand(1).getReg();
+ Register Src2Reg = I.getOperand(2).getReg();
+
+ MachineInstr *Merge1MI =
+ getOpcodeDef(TargetOpcode::G_MERGE_VALUES, Src1Reg, MRI);
+ MachineInstr *Merge2MI =
+ getOpcodeDef(TargetOpcode::G_MERGE_VALUES, Src2Reg, MRI);
+ if (Merge1MI &&
+ mi_match(Merge1MI->getOperand(1).getReg(), MRI, m_ZeroInt()) &&
+ Merge2MI &&
+ mi_match(Merge2MI->getOperand(1).getReg(), MRI, m_ZeroInt())) {
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(M88k::MULUrrd), DstReg)
+ .addReg(Merge1MI->getOperand(2).getReg())
+ .addReg(Merge2MI->getOperand(2).getReg());
+ } else
+ return false;
+
+ I.eraseFromParent();
+ return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+}
+
bool M88kInstructionSelector::selectExt(MachineInstr &I, MachineBasicBlock &MBB,
MachineRegisterInfo &MRI) const {
assert(I.getOpcode() == TargetOpcode::G_ZEXT ||
@@ -832,14 +866,14 @@ bool M88kInstructionSelector::selectMergeUnmerge(
// Copy to dst.
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
I.getOperand(0).getReg())
- .addReg(SrcReg, 0, M88k::sub_hi);
+ .addReg(SrcReg, 0, M88k::sub_lo);
RBI.constrainGenericRegister(I.getOperand(0).getReg(), M88k::GPRRCRegClass,
MRI);
constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
I.getOperand(1).getReg())
- .addReg(SrcReg, 0, M88k::sub_lo);
+ .addReg(SrcReg, 0, M88k::sub_hi);
RBI.constrainGenericRegister(I.getOperand(1).getReg(), M88k::GPRRCRegClass,
MRI);
}
@@ -1064,6 +1098,8 @@ bool M88kInstructionSelector::select(MachineInstr &I) {
return selectBrJT(I, MBB, MRI);
case TargetOpcode::G_BRINDIRECT:
return selectBrIndirect(I, MBB, MRI);
+ case TargetOpcode::G_MUL:
+ return selectMul(I, MBB, MRI);
case TargetOpcode::G_ZEXT:
case TargetOpcode::G_SEXT:
case TargetOpcode::G_ANYEXT: // TODO Can G_ANYEXT end up here?
diff --git a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp
index 4f439a2..1d55cac 100644
--- a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp
@@ -35,6 +35,11 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) {
const LLT S64 = LLT::scalar(64);
const LLT S80 = LLT::scalar(80);
const LLT P0 = LLT::pointer(0, 32);
+
+ auto IsMC88110 = [=, &ST](const LegalityQuery &Query) {
+ return ST.isMC88110();
+ };
+
getActionDefinitionsBuilder(G_PHI).legalFor({S32, P0});
getActionDefinitionsBuilder(G_SELECT)
.customForCartesianProduct({S32, S64, P0}, {S1});
@@ -72,7 +77,11 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) {
.clampScalar(1, S32, S32);
getActionDefinitionsBuilder(G_ADD).legalFor({S32});
getActionDefinitionsBuilder(G_SUB).legalFor({S32});
- getActionDefinitionsBuilder(G_MUL).legalFor({S32});
+ getActionDefinitionsBuilder(G_MUL)
+ .legalFor({S32})
+ .customIf(all(typeInSet(0, {S64}), LegalityPredicate(IsMC88110)))
+ .libcallFor({S64})
+ .clampScalar(0, S32, S64);
getActionDefinitionsBuilder(G_UDIV).legalFor({S32}).libcallFor({S64});
getActionDefinitionsBuilder(G_SDIV)
#if 0
@@ -171,6 +180,41 @@ bool M88kLegalizerInfo::legalizeCustom(LegalizerHelper &Helper,
MI.eraseFromParent();
break;
}
+ case G_MUL: {
+ // MC88110 only: 32bit multiplication with 64bit result.
+ Register DstReg = MI.getOperand(0).getReg();
+ if (MRI.getType(DstReg) != S64)
+ return false;
+ MachineInstr *Src1I = getDefIgnoringCopies(MI.getOperand(1).getReg(), MRI);
+ MachineInstr *Src2I = getDefIgnoringCopies(MI.getOperand(2).getReg(), MRI);
+ unsigned Opc1 = Src1I->getOpcode();
+ unsigned Opc2 = Src2I->getOpcode();
+ // Check if the multiplicants are blown-up 32 bit values. If yes then the
+ // multiplication is legal.
+ if (Opc1 == G_MERGE_VALUES && Opc2 == G_MERGE_VALUES) {
+ auto C1 = getIConstantVRegValWithLookThrough(
+ Src1I->getOperand(1).getReg(), MRI);
+ auto C2 = getIConstantVRegValWithLookThrough(
+ Src1I->getOperand(1).getReg(), MRI);
+ return C1 && C1->Value.isZero() && C2 && C2->Value.isZero();
+ }
+
+ // Try to legalize the instruction.
+ if (!((Opc1 == G_ZEXT || Opc1 == G_SEXT) &&
+ (Opc2 == G_ZEXT || Opc2 == G_SEXT)))
+ return false;
+ if (MRI.getType(Src1I->getOperand(1).getReg()) != S32 ||
+ MRI.getType(Src2I->getOperand(1).getReg()) != S32)
+ return false;
+ auto Zero = MIRBuilder.buildConstant(S32, 0);
+ auto Mult1 = MIRBuilder.buildMerge(
+ S64, {Zero.getReg(0), Src1I->getOperand(1).getReg()});
+ auto Mult2 = MIRBuilder.buildMerge(
+ S64, {Zero.getReg(0), Src2I->getOperand(1).getReg()});
+ MIRBuilder.buildMul(DstReg, Mult1, Mult2, MI.getFlags());
+ MI.eraseFromParent();
+ break;
+ }
case G_SELECT: {
using namespace MIPatternMatch;
// The instruction
diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
index 7529d89..cfa198c 100644
--- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
@@ -147,9 +147,7 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_ADD:
case TargetOpcode::G_SUB:
case TargetOpcode::G_PTR_ADD:
- case TargetOpcode::G_MUL:
case TargetOpcode::G_SDIV:
- case TargetOpcode::G_UDIV:
// Bitwise ops.
case TargetOpcode::G_AND:
case TargetOpcode::G_OR:
@@ -162,6 +160,15 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
case TargetOpcode::G_LSHR:
OperandsMapping = getValueMapping(PMI_GR32);
break;
+ case TargetOpcode::G_MUL:
+ case TargetOpcode::G_UDIV: {
+ LLT Ty = MRI.getType(MI.getOperand(0).getReg());
+ if (Ty.getSizeInBits() != 64 && Ty.getSizeInBits() != 32)
+ return getInvalidInstructionMapping();
+ PartialMappingIdx RBIdx = (Ty.getSizeInBits() == 64) ? PMI_GR64 : PMI_GR32;
+ OperandsMapping = getValueMapping(RBIdx);
+ break;
+ }
// Floating point ops.
case TargetOpcode::G_FADD:
case TargetOpcode::G_FSUB: