diff options
| author | Toma Tabacu <toma.tabacu@imgtec.com> | 2015-01-30 11:18:50 +0000 |
|---|---|---|
| committer | Toma Tabacu <toma.tabacu@imgtec.com> | 2015-01-30 11:18:50 +0000 |
| commit | 8f6603a2dc0f9aad72757f24febdcbbc75470b34 (patch) | |
| tree | 7917d06e5b27485ab96d60e6d8495c3a84d79ec5 /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | |
| parent | c9c4025c8a8eed871c88d79d9d801ce11fd10cd1 (diff) | |
| download | bcm5719-llvm-8f6603a2dc0f9aad72757f24febdcbbc75470b34.tar.gz bcm5719-llvm-8f6603a2dc0f9aad72757f24febdcbbc75470b34.zip | |
[mips] Manually replace JAL pseudo-instructions with their JALR equivalent, instead of using InstAlias.
Summary:
This is needed by the .cprestore assembler directive.
This directive needs to be able to insert an LW instruction after every JALR replacement of a JAL pseudo-instruction
(and never after a JALR which has NOT been a result of a pseudo-instruction replacement).
The problem with using InstAlias for these is that after it replaces the pseudo-instruction, we can't find out if the resulting JALR instruction
was generated by an InstAlias or not, so we don't know whether or not to insert our LW instruction.
By replacing it manually, we know when the pseudo-instruction replacement happens and we can insert the LW instruction correctly.
Reviewers: dsanders
Reviewed By: dsanders
Subscribers: emaste, llvm-commits
Differential Revision: http://reviews.llvm.org/D5601
llvm-svn: 227568
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index af9a731e606..09ed44fa8a4 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -165,6 +165,9 @@ class MipsAsmParser : public MCTargetAsmParser { bool expandInstruction(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions); + bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl<MCInst> &Instructions); + bool expandLoadImm(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions); @@ -1538,6 +1541,8 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) { case Mips::B_MM_Pseudo: case Mips::LWM_MM: case Mips::SWM_MM: + case Mips::JalOneReg: + case Mips::JalTwoReg: return true; default: return false; @@ -1565,6 +1570,9 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, case Mips::SWM_MM: case Mips::LWM_MM: return expandLoadStoreMultiple(Inst, IDLoc, Instructions); + case Mips::JalOneReg: + case Mips::JalTwoReg: + return expandJalWithRegs(Inst, IDLoc, Instructions); } } @@ -1599,6 +1607,48 @@ void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc, } } +bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, + SmallVectorImpl<MCInst> &Instructions) { + // Create a JALR instruction which is going to replace the pseudo-JAL. + MCInst JalrInst; + JalrInst.setLoc(IDLoc); + const MCOperand FirstRegOp = Inst.getOperand(0); + const unsigned Opcode = Inst.getOpcode(); + + if (Opcode == Mips::JalOneReg) { + // jal $rs => jalr $rs + if (inMicroMipsMode()) { + JalrInst.setOpcode(Mips::JALR16_MM); + JalrInst.addOperand(FirstRegOp); + } else { + JalrInst.setOpcode(Mips::JALR); + JalrInst.addOperand(MCOperand::CreateReg(Mips::RA)); + JalrInst.addOperand(FirstRegOp); + } + } else if (Opcode == Mips::JalTwoReg) { + // jal $rd, $rs => jalr $rd, $rs + JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR); + JalrInst.addOperand(FirstRegOp); + const MCOperand SecondRegOp = Inst.getOperand(1); + JalrInst.addOperand(SecondRegOp); + } + Instructions.push_back(JalrInst); + + // If .set reorder is active, emit a NOP after it. + if (AssemblerOptions.back()->isReorder()) { + // This is a 32-bit NOP because these 2 pseudo-instructions + // do not have a short delay slot. + MCInst NopInst; + NopInst.setOpcode(Mips::SLL); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); + NopInst.addOperand(MCOperand::CreateImm(0)); + Instructions.push_back(NopInst); + } + + return false; +} + bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) { MCInst tmpInst; |

