summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorToma Tabacu <toma.tabacu@imgtec.com>2015-05-15 09:42:11 +0000
committerToma Tabacu <toma.tabacu@imgtec.com>2015-05-15 09:42:11 +0000
commita3d056fd4cb8d587db98c158e78554620e68df0a (patch)
treee94f00cbbeb1342f49403935d082eb1f0ac7b60a /llvm/lib/Target
parent731dde91db80686eec141cc3ee0ef9594e1a85c6 (diff)
downloadbcm5719-llvm-a3d056fd4cb8d587db98c158e78554620e68df0a.tar.gz
bcm5719-llvm-a3d056fd4cb8d587db98c158e78554620e68df0a.zip
[mips] [IAS] Fix expansion of negative 32-bit immediates for LI/DLI.
Summary: To maintain compatibility with GAS, we need to stop treating negative 32-bit immediates as 64-bit values when expanding LI/DLI. This currently happens because of sign extension. To do this we need to choose the 32-bit value expansion for values which use their upper 33 bits only for sign extension (i.e. no 0's, only 1's). Reviewers: dsanders Reviewed By: dsanders Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8662 llvm-svn: 237428
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 6a006caffd8..99da61a558d 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -1758,7 +1758,7 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
tmpInst.addOperand(MCOperand::createReg(SrcReg));
tmpInst.addOperand(MCOperand::createImm(ImmValue));
Instructions.push_back(tmpInst);
- } else if ((ImmValue & 0xffffffff) == ImmValue) {
+ } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
if (!AssemblerOptions.back()->isMacro())
Warning(IDLoc, "macro instruction expanded into multiple instructions");
@@ -1768,10 +1768,23 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
uint16_t Bits15To0 = ImmValue & 0xffff;
- tmpInst.setOpcode(Mips::LUi);
- tmpInst.addOperand(MCOperand::createReg(DstReg));
- tmpInst.addOperand(MCOperand::createImm(Bits31To16));
- Instructions.push_back(tmpInst);
+ if (!Is32BitImm && !isInt<32>(ImmValue)) {
+ // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
+ // upper 32 bits.
+ tmpInst.setOpcode(Mips::ORi);
+ tmpInst.addOperand(MCOperand::createReg(DstReg));
+ tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
+ tmpInst.addOperand(MCOperand::createImm(Bits31To16));
+ tmpInst.setLoc(IDLoc);
+ Instructions.push_back(tmpInst);
+ // Move the value to the upper 16 bits by doing a 16-bit left shift.
+ createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
+ } else {
+ tmpInst.setOpcode(Mips::LUi);
+ tmpInst.addOperand(MCOperand::createReg(DstReg));
+ tmpInst.addOperand(MCOperand::createImm(Bits31To16));
+ Instructions.push_back(tmpInst);
+ }
createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
if (UseSrcReg)
OpenPOWER on IntegriCloud