aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Nacke <kai@redstar.de>2022-08-30 09:34:43 -0400
committerKai Nacke <kai@redstar.de>2022-11-13 11:07:55 -0500
commit67a418b5657de6712502cd50c4a12118debce25e (patch)
tree629f68548ff484cd794e06ffba57be928ad029c9
parent6d6a7320f73e25a73b292155e32dc36117111333 (diff)
downloadllvm-67a418b5657de6712502cd50c4a12118debce25e.zip
llvm-67a418b5657de6712502cd50c4a12118debce25e.tar.gz
llvm-67a418b5657de6712502cd50c4a12118debce25e.tar.bz2
[m88k] Implement add/sub with carry.
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def16
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp40
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp4
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kPostLegalizerLowering.cpp13
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp15
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h5
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kRegisterBanks.td1
7 files changed, 83 insertions, 11 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def b/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def
index bf8a220..8cd362a 100644
--- a/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def
+++ b/llvm/lib/Target/M88k/GISel/M88kGenRegisterBankInfo.def
@@ -23,6 +23,8 @@ RegisterBankInfo::PartialMapping M88kGenRegisterBankInfo::PartMappings[]{
{0, 32, M88k::GRRegBank},
// 4: GPR 64-bit value.
{0, 64, M88k::GRRegBank},
+ // 5: CR 32-bit value.
+ {0, 32, M88k::CRRegBank},
};
// ValueMappings.
@@ -48,20 +50,24 @@ RegisterBankInfo::ValueMapping M88kGenRegisterBankInfo::ValMappings[]{
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR32 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR32 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR32 - PMI_Min], 1},
- // 13: 2x GR 32-bit value. <-- This must match Last3OpsIdx.
+ // 13: 2x GR 32-bit value.
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR64 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR64 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR64 - PMI_Min], 1},
- // 16: GR 32-bit <- XR 32-bit copy. <-- This must match FirstCrossRegCpyIdx.
+ // 16: CR 32-bit value. <-- This must match Last3OpsIdx.
+ {&M88kGenRegisterBankInfo::PartMappings[PMI_CR - PMI_Min], 1},
+ {&M88kGenRegisterBankInfo::PartMappings[PMI_CR - PMI_Min], 1},
+ {&M88kGenRegisterBankInfo::PartMappings[PMI_CR - PMI_Min], 1},
+ // 19: GR 32-bit <- XR 32-bit copy. <-- This must match FirstCrossRegCpyIdx.
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR32 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_XR32 - PMI_Min], 1},
- // 18: XR 32-bit <- GR 32-bit copy.
+ // 21: XR 32-bit <- GR 32-bit copy.
{&M88kGenRegisterBankInfo::PartMappings[PMI_XR32 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR32 - PMI_Min], 1},
- // 20: 2x GR 32-bit <- XR 64-bit copy.
+ // 23: 2x GR 32-bit <- XR 64-bit copy.
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR64 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_XR64 - PMI_Min], 1},
- // 22: XR 64-bit <- 2x GR 32-bit copy. <-- This must match
+ // 25: XR 64-bit <- 2x GR 32-bit copy. <-- This must match
// LastCrossRegCpyIdx.
{&M88kGenRegisterBankInfo::PartMappings[PMI_XR64 - PMI_Min], 1},
{&M88kGenRegisterBankInfo::PartMappings[PMI_GR64 - PMI_Min], 1},
diff --git a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
index 175769c..dba84c0 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 selectAddSubWithCarry(MachineInstr &I, MachineBasicBlock &MBB,
+ MachineRegisterInfo &MRI) const;
bool selectMul(MachineInstr &I, MachineBasicBlock &MBB,
MachineRegisterInfo &MRI) const;
bool selectUDiv(MachineInstr &I, MachineBasicBlock &MBB,
@@ -608,6 +610,39 @@ bool M88kInstructionSelector::selectPtrAdd(MachineInstr &I,
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}
+bool M88kInstructionSelector::selectAddSubWithCarry(
+ MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const {
+ assert(I.getOpcode() == TargetOpcode::G_UADDO ||
+ I.getOpcode() == TargetOpcode::G_USUBO ||
+ I.getOpcode() == TargetOpcode::G_UADDE ||
+ I.getOpcode() == TargetOpcode::G_USUBE && "Unexpected G code");
+
+ static unsigned TargetOpc[] = {
+ M88k::ADDUrrco, M88k::ADDUrrci, M88k::ADDUrrcio, // Add
+ M88k::SUBUrrco, M88k::SUBUrrci, M88k::SUBUrrcio, // Sub
+ };
+ unsigned Opc = I.getOpcode();
+ bool HasCarryInOut =
+ Opc == TargetOpcode::G_UADDE || Opc == TargetOpcode::G_USUBE;
+ bool IsCarryOutUsed =
+ HasCarryInOut && MRI.use_begin(I.getOperand(1).getReg()) != MRI.use_end();
+ bool IsSub = Opc == TargetOpcode::G_USUBO || Opc == TargetOpcode::G_USUBE;
+ unsigned NewOpc =
+ TargetOpc[3 * IsSub + HasCarryInOut + IsCarryOutUsed];
+
+ MachineInstr *MI = nullptr;
+ Register DstReg = I.getOperand(0).getReg();
+ Register Src1Reg = I.getOperand(2).getReg();
+ Register Src2Reg = I.getOperand(3).getReg();
+
+ MI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc), DstReg)
+ .addReg(Src1Reg)
+ .addReg(Src2Reg);
+
+ I.eraseFromParent();
+ 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");
@@ -1131,6 +1166,11 @@ bool M88kInstructionSelector::select(MachineInstr &I) {
return selectBrJT(I, MBB, MRI);
case TargetOpcode::G_BRINDIRECT:
return selectBrIndirect(I, MBB, MRI);
+ case TargetOpcode::G_UADDO:
+ case TargetOpcode::G_USUBO:
+ case TargetOpcode::G_UADDE:
+ case TargetOpcode::G_USUBE:
+ return selectAddSubWithCarry(I, MBB, MRI);
case TargetOpcode::G_MUL:
return selectMul(I, MBB, MRI);
case TargetOpcode::G_UDIV:
diff --git a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp
index ea865ca..8533953 100644
--- a/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kLegalizerInfo.cpp
@@ -86,6 +86,10 @@ M88kLegalizerInfo::M88kLegalizerInfo(const M88kSubtarget &ST) {
.legalIf(
all(typeInSet(0, {V8S8, V4S16, V2S32}), LegalityPredicate(IsMC88110)))
.clampScalar(0, S32, S32);
+ getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE})
+ .legalFor({S32, S32})
+ .clampScalar(0, S32, S32)
+ .clampScalar(1, S32, S32);
getActionDefinitionsBuilder({G_MUL, G_UDIV})
.legalFor({S32})
.customIf(all(typeInSet(0, {S64}), LegalityPredicate(IsMC88110)))
diff --git a/llvm/lib/Target/M88k/GISel/M88kPostLegalizerLowering.cpp b/llvm/lib/Target/M88k/GISel/M88kPostLegalizerLowering.cpp
index aa29756..be20a0e 100644
--- a/llvm/lib/Target/M88k/GISel/M88kPostLegalizerLowering.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kPostLegalizerLowering.cpp
@@ -398,15 +398,20 @@ bool M88kPostLegalizerLoweringInfo::combine(GISelChangeObserver &Observer,
// swap the operands. The matcher generated from the SDAG patterns expects the
// constant always as the second operand, otherwise operand is not matched as
// immediate.
- if (MI.isCommutable()) {
- assert(MI.getNumExplicitOperands() == 3 && "Not a binary operation");
+ if (MI.isCommutable() && isPreISelGenericOpcode(MI.getOpcode())) {
+ assert(MI.getNumExplicitOperands() >= 3 && "Not a binary operation");
+ unsigned Opc = MI.getOpcode();
+ bool HasCarry =
+ Opc == TargetOpcode::G_UADDO || Opc == TargetOpcode::G_USUBO ||
+ Opc == TargetOpcode::G_UADDE || Opc == TargetOpcode::G_USUBE;
+ unsigned SrcIdx = HasCarry ? 2 : 1;
unsigned SrcOpc =
- getDefIgnoringCopies(MI.getOperand(1).getReg(), *B.getMRI())
+ getDefIgnoringCopies(MI.getOperand(SrcIdx).getReg(), *B.getMRI())
->getOpcode();
if (SrcOpc == TargetOpcode::G_CONSTANT ||
SrcOpc == TargetOpcode::G_FCONSTANT) {
Observer.changingInstr(MI);
- B.getTII().commuteInstruction(MI, false, 1, 2);
+ B.getTII().commuteInstruction(MI, false, SrcIdx, SrcIdx + 1);
Observer.changedInstr(MI);
}
}
diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
index 60cbfe7..c607087 100644
--- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
@@ -169,6 +169,21 @@ M88kRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
OperandsMapping = getValueMapping(RBIdx);
break;
}
+ // Integer arithmetic producing a carry.
+ case TargetOpcode::G_UADDO:
+ case TargetOpcode::G_USUBO:
+ OperandsMapping = getOperandsMapping(
+ {getValueMapping(PMI_GR32), getValueMapping(PMI_CR),
+ getValueMapping(PMI_GR32), getValueMapping(PMI_GR32)});
+ break;
+ // Integer arithmetic producing and consuming a carry.
+ case TargetOpcode::G_UADDE:
+ case TargetOpcode::G_USUBE:
+ OperandsMapping = getOperandsMapping(
+ {getValueMapping(PMI_GR32), getValueMapping(PMI_CR),
+ getValueMapping(PMI_GR32), getValueMapping(PMI_GR32),
+ getValueMapping(PMI_CR)});
+ break;
// Floating point ops.
case TargetOpcode::G_FADD:
case TargetOpcode::G_FSUB:
diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h
index ccba9aa..bf0ada2 100644
--- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h
+++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.h
@@ -31,6 +31,7 @@ protected:
PMI_XR80,
PMI_GR32,
PMI_GR64,
+ PMI_CR,
PMI_Min = PMI_XR32,
};
@@ -41,9 +42,9 @@ protected:
enum ValueMappingIdx {
InvalidIdx = 0,
First3OpsIdx = 1,
- Last3OpsIdx = 13,
+ Last3OpsIdx = 16,
DistanceBetweenRegBanks = 3,
- FirstCrossRegCpyIdx = 16,
+ FirstCrossRegCpyIdx = 19,
LastCrossRegCpyIdx = 22,
DistanceBetweenCrossRegCpy = 2,
};
diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBanks.td b/llvm/lib/Target/M88k/GISel/M88kRegisterBanks.td
index 391cc74..ef0a55e 100644
--- a/llvm/lib/Target/M88k/GISel/M88kRegisterBanks.td
+++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBanks.td
@@ -14,3 +14,4 @@
/// Register banks.
def GRRegBank : RegisterBank<"GR", [GPRRC, GPR64RC]>;
def XRRegBank : RegisterBank<"XR", [XRRC]>;
+def CRRegBank : RegisterBank<"CR", [CRRC]>;