aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Nacke <kai@redstar.de>2022-09-04 23:47:51 -0400
committerKai Nacke <kai@redstar.de>2022-11-13 11:07:56 -0500
commit8da87a791b4737220384b67859959bfad17d3b7f (patch)
treed26dc40ceddda1981f13048e83c317ebb37b0cb7
parentc84e7977c35ee139b39da9a5137f4d2e62914fd1 (diff)
downloadllvm-8da87a791b4737220384b67859959bfad17d3b7f.zip
llvm-8da87a791b4737220384b67859959bfad17d3b7f.tar.gz
llvm-8da87a791b4737220384b67859959bfad17d3b7f.tar.bz2
[m88k] Improve handling of carry.
- Add virtual carry register as implicit operand - Replace virtual carry register with physical carry register - Add more test cases
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp20
-rw-r--r--llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp2
-rw-r--r--llvm/test/CodeGen/M88k/add.ll35
3 files changed, 54 insertions, 3 deletions
diff --git a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
index dba84c0..fbf6394 100644
--- a/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kInstructionSelector.cpp
@@ -630,17 +630,31 @@ bool M88kInstructionSelector::selectAddSubWithCarry(
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)
+ auto &MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc), DstReg)
.addReg(Src1Reg)
.addReg(Src2Reg);
+ if (HasCarryInOut) {
+ MIB.addReg(I.getOperand(4).getReg(), RegState::Implicit);
+ if (IsCarryOutUsed) {
+ MIB.addReg(I.getOperand(1).getReg(), RegState::ImplicitDefine);
+ }
+ } else
+ MIB.addReg(I.getOperand(1).getReg(), RegState::ImplicitDefine);
+
+ // The carry bit aka cr1 is not an allocatable register class. Simply replace
+ // the use of the virtual register with the physical carry register.
+ for (auto &OP : MIB->implicit_operands()) {
+ if (Register::isVirtualRegister(OP.getReg())) {
+ MRI.replaceRegWith(OP.getReg(), M88k::CARRY);
+ }
+ }
I.eraseFromParent();
- return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);
}
bool M88kInstructionSelector::selectMul(MachineInstr &I, MachineBasicBlock &MBB,
diff --git a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
index c607087..36b2067 100644
--- a/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
+++ b/llvm/lib/Target/M88k/GISel/M88kRegisterBankInfo.cpp
@@ -39,6 +39,8 @@ M88kRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
return getRegBank(M88k::GRRegBankID);
case M88k::XRRCRegClassID:
return getRegBank(M88k::XRRegBankID);
+ case M88k::CRRCRegClassID:
+ return getRegBank(M88k::CRRegBankID);
default:
llvm_unreachable("Unexpected register class");
}
diff --git a/llvm/test/CodeGen/M88k/add.ll b/llvm/test/CodeGen/M88k/add.ll
index 3e15d9e..5f45d48 100644
--- a/llvm/test/CodeGen/M88k/add.ll
+++ b/llvm/test/CodeGen/M88k/add.ll
@@ -18,3 +18,38 @@ define i32 @f2(i32 %a) {
%sum = add i32 512, %a
ret i32 %sum
}
+
+define i32 @f3(i32 %a) {
+; CHECK-LABEL: f3:
+; CHECK: subu %r2, %r2, 512
+; CHECK-NEXT: jmp %r1
+ %sum = sub i32 %a, 512
+ ret i32 %sum
+}
+
+define i32 @f4(i32 %a) {
+; CHECK-LABEL: f4:
+; CHECK: or %r3, %r0, 512
+; CHECK-NEXT: subu %r2, %r3, %r2
+; CHECK-NEXT: jmp %r1
+ %sum = sub i32 512, %a
+ ret i32 %sum
+}
+
+define i64 @f5(i64 %a, i64 %b) {
+; CHECK-LABEL: f5:
+; CHECK: addu.co %r3, %r3, %r5
+; CHECK-NEXT: addu.ci %r2, %r2, %r4
+; CHECK-NEXT: jmp %r1
+ %sum = add i64 %a, %b
+ ret i64 %sum
+}
+
+define i64 @f6(i64 %a, i64 %b) {
+; CHECK-LABEL: f6:
+; CHECK: subu.co %r3, %r3, %r5
+; CHECK-NEXT: subu.ci %r2, %r2, %r4
+; CHECK-NEXT: jmp %r1
+ %sum = sub i64 %a, %b
+ ret i64 %sum
+}