summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--llvm/test/MC/ARM/basic-arm-instructions.s50
4 files changed, 104 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) &&
diff --git a/llvm/test/MC/ARM/basic-arm-instructions.s b/llvm/test/MC/ARM/basic-arm-instructions.s
index 872341ffe97..1a271986b34 100644
--- a/llvm/test/MC/ARM/basic-arm-instructions.s
+++ b/llvm/test/MC/ARM/basic-arm-instructions.s
@@ -1169,6 +1169,56 @@ Lforward:
@------------------------------------------------------------------------------
+@ RFE
+@------------------------------------------------------------------------------
+ rfeda r2
+ rfedb r3
+ rfeia r5
+ rfeib r6
+
+ rfeda r4!
+ rfedb r7!
+ rfeia r9!
+ rfeib r8!
+
+ rfefa r2
+ rfeea r3
+ rfefd r5
+ rfeed r6
+
+ rfefa r4!
+ rfeea r7!
+ rfefd r9!
+ rfeed r8!
+
+ rfe r1
+ rfe r1!
+
+@ CHECK: rfeda r2 @ encoding: [0x00,0x0a,0x12,0xf8]
+@ CHECK: rfedb r3 @ encoding: [0x00,0x0a,0x13,0xf9]
+@ CHECK: rfeia r5 @ encoding: [0x00,0x0a,0x95,0xf8]
+@ CHECK: rfeib r6 @ encoding: [0x00,0x0a,0x96,0xf9]
+
+@ CHECK: rfeda r4! @ encoding: [0x00,0x0a,0x34,0xf8]
+@ CHECK: rfedb r7! @ encoding: [0x00,0x0a,0x37,0xf9]
+@ CHECK: rfeia r9! @ encoding: [0x00,0x0a,0xb9,0xf8]
+@ CHECK: rfeib r8! @ encoding: [0x00,0x0a,0xb8,0xf9]
+
+@ CHECK: rfeda r2 @ encoding: [0x00,0x0a,0x12,0xf8]
+@ CHECK: rfedb r3 @ encoding: [0x00,0x0a,0x13,0xf9]
+@ CHECK: rfeia r5 @ encoding: [0x00,0x0a,0x95,0xf8]
+@ CHECK: rfeib r6 @ encoding: [0x00,0x0a,0x96,0xf9]
+
+@ CHECK: rfeda r4! @ encoding: [0x00,0x0a,0x34,0xf8]
+@ CHECK: rfedb r7! @ encoding: [0x00,0x0a,0x37,0xf9]
+@ CHECK: rfeia r9! @ encoding: [0x00,0x0a,0xb9,0xf8]
+@ CHECK: rfeib r8! @ encoding: [0x00,0x0a,0xb8,0xf9]
+
+@ CHECK: rfeia r1 @ encoding: [0x00,0x0a,0x91,0xf8]
+@ CHECK: rfeia r1! @ encoding: [0x00,0x0a,0xb1,0xf8]
+
+
+@------------------------------------------------------------------------------
@ RSB
@------------------------------------------------------------------------------
rsb r4, r5, #0xf000
OpenPOWER on IntegriCloud