summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2013-12-09 11:50:16 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2013-12-09 11:50:16 +0000
commit897268d931a84872d88ad05b18027b6b9723e03e (patch)
tree5ee17d0f78f0abb1c8c9173f31d96805453da865 /lib
parent84744f691666de0e9da311ad668e4d1f93c5efe9 (diff)
downloadllvm-897268d931a84872d88ad05b18027b6b9723e03e.tar.gz
llvm-897268d931a84872d88ad05b18027b6b9723e03e.tar.bz2
llvm-897268d931a84872d88ad05b18027b6b9723e03e.tar.xz
[mips][msa] Fix suboptimal FrameIndex lowering for ld.[hwd] and st.[hwd]
Summary: The immediate in these instructions is scaled before use as an offset. They therefore have a wider reach than ld.b/st.b. Reviewers: matheusalmeida Reviewed By: matheusalmeida Differential Revision: http://llvm-reviews.chandlerc.com/D2338 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196775 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Mips/MipsSERegisterInfo.cpp35
1 files changed, 20 insertions, 15 deletions
diff --git a/lib/Target/Mips/MipsSERegisterInfo.cpp b/lib/Target/Mips/MipsSERegisterInfo.cpp
index 2d440840aa..cf408a1c09 100644
--- a/lib/Target/Mips/MipsSERegisterInfo.cpp
+++ b/lib/Target/Mips/MipsSERegisterInfo.cpp
@@ -62,21 +62,25 @@ MipsSERegisterInfo::intRegClass(unsigned Size) const {
return &Mips::GPR64RegClass;
}
-/// Determine whether a given opcode is an MSA load/store (supporting 10-bit
-/// offsets) or a non-MSA load/store (supporting 16-bit offsets).
-static inline bool isMSALoadOrStore(const unsigned Opcode) {
+/// Get the size of the offset supported by the given load/store.
+/// The result includes the effects of any scale factors applied to the
+/// instruction immediate.
+static inline unsigned getLoadStoreOffsetSizeInBits(const unsigned Opcode) {
switch (Opcode) {
case Mips::LD_B:
- case Mips::LD_H:
- case Mips::LD_W:
- case Mips::LD_D:
case Mips::ST_B:
+ return 10;
+ case Mips::LD_H:
case Mips::ST_H:
+ return 10 + 1 /* scale factor */;
+ case Mips::LD_W:
case Mips::ST_W:
+ return 10 + 2 /* scale factor */;
+ case Mips::LD_D:
case Mips::ST_D:
- return true;
+ return 10 + 3 /* scale factor */;
default:
- return false;
+ return 16;
}
}
@@ -131,13 +135,14 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
if (!MI.isDebugValue()) {
// Make sure Offset fits within the field available.
- // For MSA instructions, this is a 10-bit signed immediate, otherwise it is
- // a 16-bit signed immediate.
- unsigned OffsetBitSize = isMSALoadOrStore(MI.getOpcode()) ? 10 : 16;
-
- if (OffsetBitSize == 10 && !isInt<10>(Offset) && isInt<16>(Offset)) {
- // If we have an offset that needs to fit into a signed 10-bit immediate
- // and doesn't, but does fit into 16-bits then use an ADDiu
+ // For MSA instructions, this is a 10-bit signed immediate (scaled by
+ // element size), otherwise it is a 16-bit signed immediate.
+ unsigned OffsetBitSize = getLoadStoreOffsetSizeInBits(MI.getOpcode());
+
+ if (OffsetBitSize < 16 && !isIntN(OffsetBitSize, Offset) &&
+ isInt<16>(Offset)) {
+ // If we have an offset that needs to fit into a signed n-bit immediate
+ // (where n < 16) and doesn't, but does fit into 16-bits then use an ADDiu
MachineBasicBlock &MBB = *MI.getParent();
DebugLoc DL = II->getDebugLoc();
unsigned ADDiu = Subtarget.isABI_N64() ? Mips::DADDiu : Mips::ADDiu;