aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/Thumb2InstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/Thumb2InstrInfo.cpp')
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp58
1 files changed, 48 insertions, 10 deletions
diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp
index d567d3339049..5a965f7a6b9b 100644
--- a/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -1,9 +1,8 @@
//===- Thumb2InstrInfo.cpp - Thumb-2 Instruction Information --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -162,7 +161,7 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
// otherwise).
if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
MachineRegisterInfo *MRI = &MF.getRegInfo();
- MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
+ MRI->constrainRegClass(SrcReg, &ARM::GPRPair_with_gsub_1_in_GPRwithAPSRnospRegClass);
}
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2STRDi8));
@@ -204,7 +203,7 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
if (TargetRegisterInfo::isVirtualRegister(DestReg)) {
MachineRegisterInfo *MRI = &MF.getRegInfo();
MRI->constrainRegClass(DestReg,
- &ARM::GPRPair_with_gsub_1_in_rGPRRegClass);
+ &ARM::GPRPair_with_gsub_1_in_GPRwithAPSRnospRegClass);
}
MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(ARM::t2LDRDi8));
@@ -478,7 +477,7 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
bool isSub = false;
// Memory operands in inline assembly always use AddrModeT2_i12.
- if (Opcode == ARM::INLINEASM)
+ if (Opcode == ARM::INLINEASM || Opcode == ARM::INLINEASM_BR)
AddrMode = ARMII::AddrModeT2_i12; // FIXME. mode for thumb2?
if (Opcode == ARM::t2ADDri || Opcode == ARM::t2ADDri12) {
@@ -611,9 +610,23 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
Offset = -Offset;
isSub = true;
}
+ } else if (AddrMode == ARMII::AddrModeT2_i7s4 ||
+ AddrMode == ARMII::AddrModeT2_i7s2 ||
+ AddrMode == ARMII::AddrModeT2_i7) {
+ Offset += MI.getOperand(FrameRegIdx + 1).getImm();
+ unsigned OffsetMask;
+ switch (AddrMode) {
+ case ARMII::AddrModeT2_i7s4: NumBits = 9; OffsetMask = 0x3; break;
+ case ARMII::AddrModeT2_i7s2: NumBits = 8; OffsetMask = 0x1; break;
+ default: NumBits = 7; OffsetMask = 0x0; break;
+ }
+ // MCInst operand expects already scaled value.
+ Scale = 1;
+ assert((Offset & OffsetMask) == 0 && "Can't encode this offset!");
+ (void)OffsetMask; // squash unused-variable warning at -NDEBUG
} else if (AddrMode == ARMII::AddrModeT2_i8s4) {
Offset += MI.getOperand(FrameRegIdx + 1).getImm() * 4;
- NumBits = 10; // 8 bits scaled by 4
+ NumBits = 8 + 2;
// MCInst operand expects already scaled value.
Scale = 1;
assert((Offset & 3) == 0 && "Can't encode this offset!");
@@ -639,7 +652,7 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
// Replace the FrameIndex with fp/sp
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
if (isSub) {
- if (AddrMode == ARMII::AddrMode5)
+ if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
// FIXME: Not consistent.
ImmedOffset |= 1 << NumBits;
else
@@ -653,7 +666,7 @@ bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
// Otherwise, offset doesn't fit. Pull in what we can to simplify
ImmedOffset = ImmedOffset & Mask;
if (isSub) {
- if (AddrMode == ARMII::AddrMode5)
+ if (AddrMode == ARMII::AddrMode5 || AddrMode == ARMII::AddrMode5FP16)
// FIXME: Not consistent.
ImmedOffset |= 1 << NumBits;
else {
@@ -678,3 +691,28 @@ ARMCC::CondCodes llvm::getITInstrPredicate(const MachineInstr &MI,
return ARMCC::AL;
return getInstrPredicate(MI, PredReg);
}
+
+int llvm::findFirstVPTPredOperandIdx(const MachineInstr &MI) {
+ const MCInstrDesc &MCID = MI.getDesc();
+
+ if (!MCID.OpInfo)
+ return -1;
+
+ for (unsigned i = 0, e = MCID.getNumOperands(); i != e; ++i)
+ if (ARM::isVpred(MCID.OpInfo[i].OperandType))
+ return i;
+
+ return -1;
+}
+
+ARMVCC::VPTCodes llvm::getVPTInstrPredicate(const MachineInstr &MI,
+ unsigned &PredReg) {
+ int PIdx = findFirstVPTPredOperandIdx(MI);
+ if (PIdx == -1) {
+ PredReg = 0;
+ return ARMVCC::None;
+ }
+
+ PredReg = MI.getOperand(PIdx+1).getReg();
+ return (ARMVCC::VPTCodes)MI.getOperand(PIdx).getImm();
+}