[mips][microMIPS] Implement SWM and LWM aliases

Differential Revision: http://reviews.llvm.org/D5820


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227373 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zoran Jovanovic 2015-01-28 21:52:27 +00:00
parent b0f9090173
commit 7624914c14
3 changed files with 69 additions and 0 deletions

View File

@ -182,6 +182,10 @@ class MipsAsmParser : public MCTargetAsmParser {
void expandMemInst(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions, bool isLoad,
bool isImmOpnd);
bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
@ -1532,6 +1536,8 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) {
case Mips::LoadAddr32Reg:
case Mips::LoadImm64Reg:
case Mips::B_MM_Pseudo:
case Mips::LWM_MM:
case Mips::SWM_MM:
return true;
default:
return false;
@ -1556,6 +1562,9 @@ bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
return expandLoadAddressReg(Inst, IDLoc, Instructions);
case Mips::B_MM_Pseudo:
return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
case Mips::SWM_MM:
case Mips::LWM_MM:
return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
}
}
@ -2000,6 +2009,29 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
TempInst.clear();
}
bool
MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
unsigned OpNum = Inst.getNumOperands();
unsigned Opcode = Inst.getOpcode();
unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
assert (Inst.getOperand(OpNum - 1).isImm() &&
Inst.getOperand(OpNum - 2).isReg() &&
Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
Inst.getOperand(OpNum - 1).getImm() >= 0 &&
Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
// It can be implemented as SWM16 or LWM16 instruction.
NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
Inst.setOpcode(NewOpcode);
Instructions.push_back(Inst);
return false;
}
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
// As described by the Mips32r2 spec, the registers Rd and Rs for
// jalr.hb must be different.

View File

@ -697,6 +697,19 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
def SWP_MM : StorePairMM<"swp">, LWM_FM_MM<0x9>;
def LWP_MM : LoadPairMM<"lwp">, LWM_FM_MM<0x1>;
/// Load and Store multiple pseudo Instructions
class LoadWordMultMM<string instr_asm > :
MipsAsmPseudoInst<(outs reglist:$rt), (ins mem_mm_12:$addr),
!strconcat(instr_asm, "\t$rt, $addr")> ;
class StoreWordMultMM<string instr_asm > :
MipsAsmPseudoInst<(outs), (ins reglist:$rt, mem_mm_12:$addr),
!strconcat(instr_asm, "\t$rt, $addr")> ;
def SWM_MM : StoreWordMultMM<"swm">;
def LWM_MM : LoadWordMultMM<"lwm">;
/// Move Conditional
def MOVZ_I_MM : MMRel, CMov_I_I_FT<"movz", GPR32Opnd, GPR32Opnd,
NoItinerary>, ADD_FM_MM<0, 0x58>;

View File

@ -34,6 +34,14 @@
# CHECK-EL: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x84,0x20,0x08,0xd0]
# CHECK-EL: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x12,0x45]
# CHECK-EL: swm16 $16, $17, $ra, 8($sp) # encoding: [0x52,0x45]
# CHECK-EL: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x12,0x45]
# CHECK-EL: lwm32 $16, $17, $ra, 64($sp) # encoding: [0x5d,0x22,0x40,0x50]
# CHECK-EL: lwm32 $16, $17, $ra, 8($4) # encoding: [0x44,0x22,0x08,0x50]
# CHECK-EL: lwm32 $16, $17, 8($sp) # encoding: [0x5d,0x20,0x08,0x50]
# CHECK-EL: swm16 $16, $17, $ra, 8($sp) # encoding: [0x52,0x45]
# CHECK-EL: swm32 $16, $17, $ra, 64($sp) # encoding: [0x5d,0x22,0x40,0xd0]
# CHECK-EL: swm32 $16, $17, $ra, 8($4) # encoding: [0x44,0x22,0x08,0xd0]
# CHECK-EL: swm32 $16, $17, 8($sp) # encoding: [0x5d,0x20,0x08,0xd0]
# CHECK-EL: swp $16, 8($4) # encoding: [0x04,0x22,0x08,0x90]
# CHECK-EL: lwp $16, 8($4) # encoding: [0x04,0x22,0x08,0x10]
#------------------------------------------------------------------------------
@ -64,6 +72,14 @@
# CHECK-EB: swm32 $16, $17, $18, $19, 8($4) # encoding: [0x20,0x84,0xd0,0x08]
# CHECK-EB: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x12]
# CHECK-EB: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x52]
# CHECK-EB: lwm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x12]
# CHECK-EB: lwm32 $16, $17, $ra, 64($sp) # encoding: [0x22,0x5d,0x50,0x40]
# CHECK-EB: lwm32 $16, $17, $ra, 8($4) # encoding: [0x22,0x44,0x50,0x08]
# CHECK-EB: lwm32 $16, $17, 8($sp) # encoding: [0x20,0x5d,0x50,0x08]
# CHECK-EB: swm16 $16, $17, $ra, 8($sp) # encoding: [0x45,0x52]
# CHECK-EB: swm32 $16, $17, $ra, 64($sp) # encoding: [0x22,0x5d,0xd0,0x40]
# CHECK-EB: swm32 $16, $17, $ra, 8($4) # encoding: [0x22,0x44,0xd0,0x08]
# CHECK-EB: swm32 $16, $17, 8($sp) # encoding: [0x20,0x5d,0xd0,0x08]
# CHECK-EB: swp $16, 8($4) # encoding: [0x22,0x04,0x90,0x08]
# CHECK-EB: lwp $16, 8($4) # encoding: [0x22,0x04,0x10,0x08]
lb $5, 8($4)
@ -91,5 +107,13 @@
swm32 $16 - $19, 8($4)
lwm16 $16, $17, $ra, 8($sp)
swm16 $16, $17, $ra, 8($sp)
lwm $16, $17, $ra, 8($sp)
lwm $16, $17, $ra, 64($sp)
lwm $16, $17, $ra, 8($4)
lwm $16, $17, 8($sp)
swm $16, $17, $ra, 8($sp)
swm $16, $17, $ra, 64($sp)
swm $16, $17, $ra, 8($4)
swm $16, $17, 8($sp)
swp $16, 8($4)
lwp $16, 8($4)