From f990e4a4c7bcc3c3dec6ee8ffac39cc0a27e521a Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Tue, 13 Aug 2019 16:12:46 +0000 Subject: [PATCH] [ARM] Fix encoding of APSR in CLRM instruction The APSR is encoded by setting bit 15 in the register list of the CLRM instruction (cf. https://static.docs.arm.com/ddi0553/bh/DDI0553B_h_armv8m_arm.pdf). Differential Revision: https://reviews.llvm.org/D65873 llvm-svn: 368711 --- llvm/lib/Target/ARM/ARMRegisterInfo.td | 2 +- .../Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 21 ++++++--------------- llvm/test/MC/ARM/clrm-asm.s | 9 ++++++--- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.td b/llvm/lib/Target/ARM/ARMRegisterInfo.td index 92ae26b..4b9e562 100644 --- a/llvm/lib/Target/ARM/ARMRegisterInfo.td +++ b/llvm/lib/Target/ARM/ARMRegisterInfo.td @@ -180,7 +180,7 @@ def Q15 : ARMReg<15, "q15", [D30, D31]>; // models the APSR when it's accessed by some special instructions. In such cases // it has the same encoding as PC. def CPSR : ARMReg<0, "cpsr">; -def APSR : ARMReg<1, "apsr">; +def APSR : ARMReg<15, "apsr">; def APSR_NZCV : ARMReg<15, "apsr_nzcv">; def SPSR : ARMReg<2, "spsr">; def FPSCR : ARMReg<3, "fpscr">; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index dca6fe3..268fe7e 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -1720,7 +1720,6 @@ getRegisterListOpValue(const MCInst &MI, unsigned Op, unsigned Reg = MI.getOperand(Op).getReg(); bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg); bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg); - bool CLRMRegs = MI.getOpcode() == ARM::t2CLRM; unsigned Binary = 0; @@ -1739,21 +1738,13 @@ getRegisterListOpValue(const MCInst &MI, unsigned Op, Binary |= NumRegs * 2; } else { const MCRegisterInfo &MRI = *CTX.getRegisterInfo(); - if (!CLRMRegs) { - assert(std::is_sorted(MI.begin() + Op, MI.end(), - [&](const MCOperand &LHS, const MCOperand &RHS) { - return MRI.getEncodingValue(LHS.getReg()) < - MRI.getEncodingValue(RHS.getReg()); - })); - } - + assert(std::is_sorted(MI.begin() + Op, MI.end(), + [&](const MCOperand &LHS, const MCOperand &RHS) { + return MRI.getEncodingValue(LHS.getReg()) < + MRI.getEncodingValue(RHS.getReg()); + })); for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) { - unsigned RegNo; - if (CLRMRegs && MI.getOperand(I).getReg() == ARM::APSR) { - RegNo = 15; - } else { - RegNo = MRI.getEncodingValue(MI.getOperand(I).getReg()); - } + unsigned RegNo = MRI.getEncodingValue(MI.getOperand(I).getReg()); Binary |= 1 << RegNo; } } diff --git a/llvm/test/MC/ARM/clrm-asm.s b/llvm/test/MC/ARM/clrm-asm.s index 0ab7f36..88fd900 100644 --- a/llvm/test/MC/ARM/clrm-asm.s +++ b/llvm/test/MC/ARM/clrm-asm.s @@ -9,13 +9,16 @@ clrm {r0, r1, r2, r3} // ERROR-NOT: register list not in ascending order clrm {r3, r4, r1, r2} -// CHECK: clrm {r0, apsr, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} @ encoding: [0x9f,0xe8,0xff,0xdf] +// CHECK: clrm {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, lr, apsr} @ encoding: [0x9f,0xe8,0xff,0xdf] clrm {r0-r12, lr, apsr} -// CHECK: clrm {apsr, lr} @ encoding: [0x9f,0xe8,0x00,0xc0] +// CHECK: clrm {lr, apsr} @ encoding: [0x9f,0xe8,0x00,0xc0] clrm {apsr, lr} -// CHECK: clrm {r0, apsr, r1, r2, r3, r4, lr} @ encoding: [0x9f,0xe8,0x1f,0xc0] +// CHECK: clrm {r0, r1, apsr} @ encoding: [0x9f,0xe8,0x03,0x80] +clrm {apsr, r1, r0} + +// CHECK: clrm {r0, r1, r2, r3, r4, lr, apsr} @ encoding: [0x9f,0xe8,0x1f,0xc0] clrm {r0-r4, apsr, lr} // ERROR: invalid register in register list. Valid registers are r0-r12, lr/r14 and APSR. -- 2.7.4