[llvm] r237255 - [mips] [IAS] Unify common functionality of LA and LI.
Toma Tabacu
toma.tabacu at imgtec.com
Wed May 13 06:56:18 PDT 2015
Author: tomatabacu
Date: Wed May 13 08:56:16 2015
New Revision: 237255
URL: http://llvm.org/viewvc/llvm-project?rev=237255&view=rev
Log:
[mips] [IAS] Unify common functionality of LA and LI.
Summary: A side-effect of this is that LA gains proper handling of unsigned and positive signed 16-bit immediates and more accurate error messages.
Reviewers: dsanders
Reviewed By: dsanders
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D9290
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/trunk/test/MC/Mips/micromips-expansions.s
llvm/trunk/test/MC/Mips/mips-expansions-bad.s
llvm/trunk/test/MC/Mips/mips-expansions.s
Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=237255&r1=237254&r2=237255&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Wed May 13 08:56:16 2015
@@ -179,13 +179,17 @@ class MipsAsmParser : public MCTargetAsm
bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
+ bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
+ bool Is32BitImm, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+
bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
- bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
+ bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
- bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
+ bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
@@ -203,6 +207,9 @@ class MipsAsmParser : public MCTargetAsm
void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
+ void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
+ SmallVectorImpl<MCInst> &Instructions);
+
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
@@ -1615,9 +1622,9 @@ bool MipsAsmParser::expandInstruction(MC
case Mips::LoadImm64:
return expandLoadImm(Inst, false, IDLoc, Instructions);
case Mips::LoadAddrImm32:
- return expandLoadAddressImm(Inst, IDLoc, Instructions);
+ return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
case Mips::LoadAddrReg32:
- return expandLoadAddressReg(Inst, IDLoc, Instructions);
+ return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
case Mips::B_MM_Pseudo:
return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
case Mips::SWM_MM:
@@ -1713,21 +1720,20 @@ bool MipsAsmParser::expandJalWithRegs(MC
return false;
}
-bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
+bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
+ unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
if (!Is32BitImm && !isGP64bit()) {
Error(IDLoc, "instruction requires a 64-bit architecture");
return true;
}
+ bool UseSrcReg = false;
+ if (SrcReg != Mips::NoRegister)
+ UseSrcReg = true;
+
MCInst tmpInst;
- const MCOperand &ImmOp = Inst.getOperand(1);
- assert(ImmOp.isImm() && "expected immediate operand kind");
- const MCOperand &RegOp = Inst.getOperand(0);
- assert(RegOp.isReg() && "expected register operand kind");
- int64_t ImmValue = ImmOp.getImm();
- unsigned Reg = RegOp.getReg();
tmpInst.setLoc(IDLoc);
// FIXME: gas has a special case for values that are 000...1111, which
// becomes a li -1 and then a dsrl
@@ -1735,16 +1741,17 @@ bool MipsAsmParser::expandLoadImm(MCInst
// For unsigned and positive signed 16-bit values (0 <= j <= 65535):
// li d,j => ori d,$zero,j
tmpInst.setOpcode(Mips::ORi);
- tmpInst.addOperand(MCOperand::CreateReg(Reg));
- tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
+ tmpInst.addOperand(MCOperand::CreateReg(DstReg));
+ tmpInst.addOperand(MCOperand::CreateReg(
+ UseSrcReg ? SrcReg : (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO)));
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Instructions.push_back(tmpInst);
} else if (ImmValue < 0 && ImmValue >= -32768) {
// For negative signed 16-bit values (-32768 <= j < 0):
// li d,j => addiu d,$zero,j
tmpInst.setOpcode(Mips::ADDiu);
- tmpInst.addOperand(MCOperand::CreateReg(Reg));
- tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
+ tmpInst.addOperand(MCOperand::CreateReg(DstReg));
+ tmpInst.addOperand(MCOperand::CreateReg(UseSrcReg ? SrcReg : Mips::ZERO));
tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
Instructions.push_back(tmpInst);
} else if ((ImmValue & 0xffffffff) == ImmValue) {
@@ -1755,10 +1762,14 @@ bool MipsAsmParser::expandLoadImm(MCInst
uint16_t Bits15To0 = ImmValue & 0xffff;
tmpInst.setOpcode(Mips::LUi);
- tmpInst.addOperand(MCOperand::CreateReg(Reg));
+ tmpInst.addOperand(MCOperand::CreateReg(DstReg));
tmpInst.addOperand(MCOperand::CreateImm(Bits31To16));
Instructions.push_back(tmpInst);
- createLShiftOri<0>(Bits15To0, Reg, IDLoc, Instructions);
+ createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
+
+ if (UseSrcReg)
+ createAddu(DstReg, DstReg, SrcReg, Instructions);
+
} else if ((ImmValue & (0xffffLL << 48)) == 0) {
if (Is32BitImm) {
Error(IDLoc, "instruction requires a 32-bit immediate");
@@ -1783,11 +1794,15 @@ bool MipsAsmParser::expandLoadImm(MCInst
uint16_t Bits15To0 = ImmValue & 0xffff;
tmpInst.setOpcode(Mips::LUi);
- tmpInst.addOperand(MCOperand::CreateReg(Reg));
+ tmpInst.addOperand(MCOperand::CreateReg(DstReg));
tmpInst.addOperand(MCOperand::CreateImm(Bits47To32));
Instructions.push_back(tmpInst);
- createLShiftOri<0>(Bits31To16, Reg, IDLoc, Instructions);
- createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
+ createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
+ createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
+
+ if (UseSrcReg)
+ createAddu(DstReg, DstReg, SrcReg, Instructions);
+
} else {
if (Is32BitImm) {
Error(IDLoc, "instruction requires a 32-bit immediate");
@@ -1814,27 +1829,43 @@ bool MipsAsmParser::expandLoadImm(MCInst
uint16_t Bits15To0 = ImmValue & 0xffff;
tmpInst.setOpcode(Mips::LUi);
- tmpInst.addOperand(MCOperand::CreateReg(Reg));
+ tmpInst.addOperand(MCOperand::CreateReg(DstReg));
tmpInst.addOperand(MCOperand::CreateImm(Bits63To48));
Instructions.push_back(tmpInst);
- createLShiftOri<0>(Bits47To32, Reg, IDLoc, Instructions);
+ createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
// When Bits31To16 is 0, do a left shift of 32 bits instead of doing
// two left shifts of 16 bits.
if (Bits31To16 == 0) {
- createLShiftOri<32>(Bits15To0, Reg, IDLoc, Instructions);
+ createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
} else {
- createLShiftOri<16>(Bits31To16, Reg, IDLoc, Instructions);
- createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
+ createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
+ createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
}
+
+ if (UseSrcReg)
+ createAddu(DstReg, DstReg, SrcReg, Instructions);
}
return false;
}
+bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions) {
+ const MCOperand &ImmOp = Inst.getOperand(1);
+ assert(ImmOp.isImm() && "expected immediate operand kind");
+ const MCOperand &DstRegOp = Inst.getOperand(0);
+ assert(DstRegOp.isReg() && "expected register operand kind");
+
+ if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
+ Is32BitImm, IDLoc, Instructions))
+ return true;
+
+ return false;
+}
+
bool
-MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
+MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
- MCInst tmpInst;
const MCOperand &ImmOp = Inst.getOperand(2);
assert((ImmOp.isImm() || ImmOp.isExpr()) &&
"expected immediate operand kind");
@@ -1846,44 +1877,17 @@ MipsAsmParser::expandLoadAddressReg(MCIn
assert(SrcRegOp.isReg() && "expected register operand kind");
const MCOperand &DstRegOp = Inst.getOperand(0);
assert(DstRegOp.isReg() && "expected register operand kind");
- int ImmValue = ImmOp.getImm();
- if (-32768 <= ImmValue && ImmValue <= 65535) {
- // For -32768 <= j <= 65535.
- // la d,j(s) => addiu d,s,j
- tmpInst.setOpcode(Mips::ADDiu);
- tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
- Instructions.push_back(tmpInst);
- } else {
- // For any other value of j that is representable as a 32-bit integer.
- // la d,j(s) => lui d,hi16(j)
- // ori d,d,lo16(j)
- // addu d,d,s
- tmpInst.setOpcode(Mips::LUi);
- tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
- Instructions.push_back(tmpInst);
- tmpInst.clear();
- tmpInst.setOpcode(Mips::ORi);
- tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
- Instructions.push_back(tmpInst);
- tmpInst.clear();
- tmpInst.setOpcode(Mips::ADDu);
- tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
- Instructions.push_back(tmpInst);
- }
+
+ if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
+ Is32BitImm, IDLoc, Instructions))
+ return true;
+
return false;
}
bool
-MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
+MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
- MCInst tmpInst;
const MCOperand &ImmOp = Inst.getOperand(1);
assert((ImmOp.isImm() || ImmOp.isExpr()) &&
"expected immediate operand kind");
@@ -1891,32 +1895,13 @@ MipsAsmParser::expandLoadAddressImm(MCIn
expandLoadAddressSym(Inst, IDLoc, Instructions);
return false;
}
- const MCOperand &RegOp = Inst.getOperand(0);
- assert(RegOp.isReg() && "expected register operand kind");
- int ImmValue = ImmOp.getImm();
- if (-32768 <= ImmValue && ImmValue <= 65535) {
- // For -32768 <= j <= 65535.
- // la d,j => addiu d,$zero,j
- tmpInst.setOpcode(Mips::ADDiu);
- tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
- tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
- Instructions.push_back(tmpInst);
- } else {
- // For any other value of j that is representable as a 32-bit integer.
- // la d,j => lui d,hi16(j)
- // ori d,d,lo16(j)
- tmpInst.setOpcode(Mips::LUi);
- tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
- Instructions.push_back(tmpInst);
- tmpInst.clear();
- tmpInst.setOpcode(Mips::ORi);
- tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
- tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
- Instructions.push_back(tmpInst);
- }
+ const MCOperand &DstRegOp = Inst.getOperand(0);
+ assert(DstRegOp.isReg() && "expected register operand kind");
+
+ if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
+ Is32BitImm, IDLoc, Instructions))
+ return true;
+
return false;
}
@@ -2179,6 +2164,17 @@ void MipsAsmParser::createNop(bool hasSh
Instructions.push_back(NopInst);
}
+void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
+ unsigned TrgReg,
+ SmallVectorImpl<MCInst> &Instructions) {
+ MCInst AdduInst;
+ AdduInst.setOpcode(Mips::ADDu);
+ AdduInst.addOperand(MCOperand::CreateReg(DstReg));
+ AdduInst.addOperand(MCOperand::CreateReg(SrcReg));
+ AdduInst.addOperand(MCOperand::CreateReg(TrgReg));
+ Instructions.push_back(AdduInst);
+}
+
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// As described by the Mips32r2 spec, the registers Rd and Rs for
// jalr.hb must be different.
Modified: llvm/trunk/test/MC/Mips/micromips-expansions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/micromips-expansions.s?rev=237255&r1=237254&r2=237255&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/micromips-expansions.s (original)
+++ llvm/trunk/test/MC/Mips/micromips-expansions.s Wed May 13 08:56:16 2015
@@ -9,10 +9,10 @@
# CHECK: addiu $6, $zero, -2345 # encoding: [0xc0,0x30,0xd7,0xf6]
# CHECK: lui $7, 1 # encoding: [0xa7,0x41,0x01,0x00]
# CHECK: ori $7, $7, 2 # encoding: [0xe7,0x50,0x02,0x00]
-# CHECK: addiu $4, $zero, 20 # encoding: [0x80,0x30,0x14,0x00]
+# CHECK: ori $4, $zero, 20 # encoding: [0x80,0x50,0x14,0x00]
# CHECK: lui $7, 1 # encoding: [0xa7,0x41,0x01,0x00]
# CHECK: ori $7, $7, 2 # encoding: [0xe7,0x50,0x02,0x00]
-# CHECK: addiu $4, $5, 20 # encoding: [0x85,0x30,0x14,0x00]
+# CHECK: ori $4, $5, 20 # encoding: [0x85,0x50,0x14,0x00]
# CHECK: lui $7, 1 # encoding: [0xa7,0x41,0x01,0x00]
# CHECK: ori $7, $7, 2 # encoding: [0xe7,0x50,0x02,0x00]
# CHECK: addu $7, $7, $8 # encoding: [0x07,0x01,0x50,0x39]
Modified: llvm/trunk/test/MC/Mips/mips-expansions-bad.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-expansions-bad.s?rev=237255&r1=237254&r2=237255&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips-expansions-bad.s (original)
+++ llvm/trunk/test/MC/Mips/mips-expansions-bad.s Wed May 13 08:56:16 2015
@@ -7,5 +7,11 @@
li $5, 0x100000000
# 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate
# 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 32-bit immediate
+ la $5, 0x100000000
+ # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate
+ # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 32-bit immediate
+ la $5, 0x100000000($6)
+ # 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 32-bit immediate
+ # 64-BIT: :[[@LINE-2]]:3: error: instruction requires a 32-bit immediate
dli $5, 1
# 32-BIT: :[[@LINE-1]]:3: error: instruction requires a 64-bit architecture
Modified: llvm/trunk/test/MC/Mips/mips-expansions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/mips-expansions.s?rev=237255&r1=237254&r2=237255&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/mips-expansions.s (original)
+++ llvm/trunk/test/MC/Mips/mips-expansions.s Wed May 13 08:56:16 2015
@@ -12,10 +12,10 @@
# CHECK: lui $9, 1 # encoding: [0x01,0x00,0x09,0x3c]
# CHECK-NOT: ori $9, $9, 0 # encoding: [0x00,0x00,0x29,0x35]
-# CHECK: addiu $4, $zero, 20 # encoding: [0x14,0x00,0x04,0x24]
+# CHECK: ori $4, $zero, 20 # encoding: [0x14,0x00,0x04,0x34]
# CHECK: lui $7, 1 # encoding: [0x01,0x00,0x07,0x3c]
# CHECK: ori $7, $7, 2 # encoding: [0x02,0x00,0xe7,0x34]
-# CHECK: addiu $4, $5, 20 # encoding: [0x14,0x00,0xa4,0x24]
+# CHECK: ori $4, $5, 20 # encoding: [0x14,0x00,0xa4,0x34]
# CHECK: lui $7, 1 # encoding: [0x01,0x00,0x07,0x3c]
# CHECK: ori $7, $7, 2 # encoding: [0x02,0x00,0xe7,0x34]
# CHECK: addu $7, $7, $8 # encoding: [0x21,0x38,0xe8,0x00]
More information about the llvm-commits
mailing list