summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-07-29 18:47:24 +0000
committerJim Grosbach <grosbach@apple.com>2011-07-29 18:47:24 +0000
commitc4dc52cd5262e5483efc6a382a0786b52092b447 (patch)
treef3ef96654d7135edf2182f9ade7aeea85b77d9c8 /llvm/lib
parentcb32ce26425632b3c91287375cc643e3aa5b01b7 (diff)
downloadbcm5719-llvm-c4dc52cd5262e5483efc6a382a0786b52092b447.tar.gz
bcm5719-llvm-c4dc52cd5262e5483efc6a382a0786b52092b447.zip
ARM assembly parsing and encoding for RFE instruction.
Fill in the missing fixed bits and the register operand bits of the instruction encoding. Refactor the definition to make the mode explicit, which is consistent with how loads and stores are normally represented and makes parsing much easier. Add parsing aliases for pseudo-instruction variants. Update the disassembler for the new representations. Add tests for parsing and encoding. llvm-svn: 136479
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td51
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp1
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp15
3 files changed, 54 insertions, 13 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index 351fcea6a60..b7c245fe1e7 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -1739,19 +1739,44 @@ def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode),
let Inst{7-5} = 0b000;
}
+
// Return From Exception
-def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
- NoItinerary, "rfe${amode}\t$base!", []> {
+class RFEI<bit wb, string asm>
+ : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm,
+ NoItinerary, asm, "", []> {
+ bits<4> Rn;
let Inst{31-28} = 0b1111;
- let Inst{22-20} = 0b011; // W = 1
- let Inst{15-0} = 0x0a00;
+ let Inst{27-25} = 0b100;
+ let Inst{22} = 0;
+ let Inst{21} = wb;
+ let Inst{20} = 1;
+ let Inst{19-16} = Rn;
+ let Inst{15-0} = 0xa00;
}
-def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base),
- NoItinerary, "rfe${amode}\t$base", []> {
- let Inst{31-28} = 0b1111;
- let Inst{22-20} = 0b001; // W = 0
- let Inst{15-0} = 0x0a00;
+def RFEDA : RFEI<0, "rfeda\t$Rn"> {
+ let Inst{24-23} = 0;
+}
+def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> {
+ let Inst{24-23} = 0;
+}
+def RFEDB : RFEI<0, "rfedb\t$Rn"> {
+ let Inst{24-23} = 0b10;
+}
+def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> {
+ let Inst{24-23} = 0b10;
+}
+def RFEIA : RFEI<0, "rfeia\t$Rn"> {
+ let Inst{24-23} = 0b01;
+}
+def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> {
+ let Inst{24-23} = 0b01;
+}
+def RFEIB : RFEI<0, "rfeib\t$Rn"> {
+ let Inst{24-23} = 0b11;
+}
+def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> {
+ let Inst{24-23} = 0b11;
}
//===----------------------------------------------------------------------===//
@@ -4421,3 +4446,11 @@ def : InstAlias<"uxtab16${p} $Rd, $Rn, $Rm",
def : InstAlias<"uxtb${p} $Rd, $Rm", (UXTB GPR:$Rd, GPR:$Rm, 0, pred:$p)>;
def : InstAlias<"uxtb16${p} $Rd, $Rm", (UXTB16 GPR:$Rd, GPR:$Rm, 0, pred:$p)>;
def : InstAlias<"uxth${p} $Rd, $Rm", (UXTH GPR:$Rd, GPR:$Rm, 0, pred:$p)>;
+
+
+// RFE aliases
+def : MnemonicAlias<"rfefa", "rfeda">;
+def : MnemonicAlias<"rfeea", "rfedb">;
+def : MnemonicAlias<"rfefd", "rfeia">;
+def : MnemonicAlias<"rfeed", "rfeib">;
+def : MnemonicAlias<"rfe", "rfeia">;
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 754c1bc883c..40c3097e130 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -2540,6 +2540,7 @@ getMnemonicAcceptInfo(StringRef Mnemonic, bool &CanAcceptCarrySet,
Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
Mnemonic == "setend" ||
((Mnemonic == "pld" || Mnemonic == "pli") && !isThumb()) ||
+ (Mnemonic.startswith("rfe") && !isThumb()) ||
Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
CanAcceptPredicationCode = false;
} else {
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index 1f3920bd8cf..983589f6983 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -799,7 +799,7 @@ static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, uint32_t insn,
// BXJ: Rm
// MSRi/MSRsysi: so_imm
// SRSW/SRS: ldstm_mode:$amode mode_imm
-// RFEW/RFE: ldstm_mode:$amode Rn
+// RFE: Rn
static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -858,19 +858,26 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
NumOpsAdded = 2;
return true;
}
- if (Opcode == ARM::SRSW || Opcode == ARM::SRS ||
- Opcode == ARM::RFEW || Opcode == ARM::RFE) {
+ if (Opcode == ARM::SRSW || Opcode == ARM::SRS) {
ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
if (Opcode == ARM::SRSW || Opcode == ARM::SRS)
MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
- else
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
NumOpsAdded = 3;
return true;
}
+ if (Opcode == ARM::RFEDA || Opcode == ARM::RFEDB ||
+ Opcode == ARM::RFEIA || Opcode == ARM::RFEIB ||
+ Opcode == ARM::RFEDA_UPD || Opcode == ARM::RFEDB_UPD ||
+ Opcode == ARM::RFEIA_UPD || Opcode == ARM::RFEIB_UPD) {
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ decodeRn(insn))));
+ NumOpsAdded = 1;
+ return true;
+ }
assert((Opcode == ARM::Bcc || Opcode == ARM::BL || Opcode == ARM::BL_pred
|| Opcode == ARM::SMC || Opcode == ARM::SVC) &&
OpenPOWER on IntegriCloud