From ab682a2090f795d0b67f29889622da0a74cd97c3 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Thu, 28 Oct 2010 18:34:10 +0000 Subject: [PATCH] PLD, PLDW, PLI encodings, plus refactor their use of addrmode2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117571 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrInfo.td | 24 ++++++++++++++----- lib/Target/ARM/ARMMCCodeEmitter.cpp | 12 +++++++--- .../ARM/Disassembler/ARMDisassemblerCore.cpp | 21 +++++++++------- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 7 ++++-- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index ffd49620683..dd38119c31e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -398,6 +398,9 @@ def imm0_31_m1 : Operand, PatLeaf<(imm), [{ // def addrmode_imm12 : Operand, ComplexPattern { + // 12-bit immediate operand. Note that instructions using this encode + // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other + // immediate values are as normal. string EncoderMethod = "getAddrModeImm12OpValue"; let PrintMethod = "printAddrModeImm12Operand"; @@ -988,23 +991,33 @@ def CPS : AXI<(outs), (ins cps_opt:$opt), MiscFrm, NoItinerary, "cps$opt", // The neg_zero operand translates -0 to -1, -1 to -2, ..., etc. multiclass APreLoad { - def i : AXI<(outs), (ins GPR:$base, neg_zero:$imm), MiscFrm, NoItinerary, - !strconcat(opc, "\t[$base, $imm]"), []> { + def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, NoItinerary, + !strconcat(opc, "\t$addr"), []> { + bits<4> Rt; + bits<17> addr; let Inst{31-26} = 0b111101; let Inst{25} = 0; // 0 for immediate form let Inst{24} = data; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) let Inst{22} = read; let Inst{21-20} = 0b01; + let Inst{19-16} = addr{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = addr{11-0}; // imm12 } - def r : AXI<(outs), (ins addrmode2:$addr), MiscFrm, NoItinerary, - !strconcat(opc, "\t$addr"), []> { + def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, NoItinerary, + !strconcat(opc, "\t$shift"), []> { + bits<4> Rt; + bits<17> shift; let Inst{31-26} = 0b111101; let Inst{25} = 1; // 1 for register form let Inst{24} = data; + let Inst{23} = shift{12}; // U (add = ('U' == 1)) let Inst{22} = read; let Inst{21-20} = 0b01; - let Inst{4} = 0; + let Inst{19-16} = shift{16-13}; // Rn + let Inst{11-0} = shift{11-0}; } } @@ -3199,7 +3212,6 @@ def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, Requires<[IsARM, IsDarwin]>; // zextload i1 -> zextload i8 -//def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 1259672b9b9..122aadf321a 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -190,9 +190,15 @@ unsigned ARMMCCodeEmitter::getAddrModeImm12OpValue(const MCInst &MI, const MCOperand &MO1 = MI.getOperand(OpIdx + 1); unsigned Reg = getARMRegisterNumbering(MO.getReg()); int32_t Imm12 = MO1.getImm(); - uint32_t Binary; - Binary = Imm12 & 0xfff; - if (Imm12 >= 0) + bool isAdd = Imm12 >= 0; + // Special value for #-0 + if (Imm12 == INT32_MIN) + Imm12 = 0; + // Immediate is always encoded as positive. The 'U' bit controls add vs sub. + if (Imm12 < 0) + Imm12 = -Imm12; + uint32_t Binary = Imm12 & 0xfff; + if (isAdd) Binary |= (1 << 12); Binary |= (Reg << 13); return Binary; diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 3c909ec72d2..be66112ba35 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -2931,9 +2931,9 @@ static inline bool MemBarrierInstr(uint32_t insn) { static inline bool PreLoadOpcode(unsigned Opcode) { switch(Opcode) { - case ARM::PLDi: case ARM::PLDr: - case ARM::PLDWi: case ARM::PLDWr: - case ARM::PLIi: case ARM::PLIr: + case ARM::PLDi12: case ARM::PLDrs: + case ARM::PLDWi12: case ARM::PLDWrs: + case ARM::PLIi12: case ARM::PLIrs: return true; default: return false; @@ -2943,18 +2943,21 @@ static inline bool PreLoadOpcode(unsigned Opcode) { static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) { - // Preload Data/Instruction requires either 2 or 4 operands. - // PLDi, PLDWi, PLIi: Rn [+/-]imm12 add = (U == '1') - // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: Rn Rm addrmode2_opc + // Preload Data/Instruction requires either 2 or 3 operands. + // PLDi, PLDWi, PLIi: addrmode_imm12 + // PLDr[a|m], PLDWr[a|m], PLIr[a|m]: ldst_so_reg MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn)))); - if (Opcode == ARM::PLDi || Opcode == ARM::PLDWi || Opcode == ARM::PLIi) { + if (Opcode == ARM::PLDi12 || Opcode == ARM::PLDWi12 + || Opcode == ARM::PLIi12) { unsigned Imm12 = slice(insn, 11, 0); bool Negative = getUBit(insn) == 0; - int Offset = Negative ? -1 - Imm12 : 1 * Imm12; - MI.addOperand(MCOperand::CreateImm(Offset)); + // -0 is represented specially. All other values are as normal. + if (Imm12 == 0 && Negative) + Imm12 = INT32_MIN; + MI.addOperand(MCOperand::CreateImm(Imm12)); NumOpsAdded = 2; } else { MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 892558eed39..21b3e1c32a2 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -613,8 +613,11 @@ void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum, O << "[" << getRegisterName(MO1.getReg()); int32_t OffImm = (int32_t)MO2.getImm(); - // Don't print +0. - if (OffImm < 0) + bool isSub = OffImm < 0; + // Special value for #-0. All others are normal. + if (OffImm == INT32_MIN) + OffImm = 0; + if (isSub) O << ", #-" << -OffImm; else if (OffImm > 0) O << ", #" << OffImm; -- 2.34.1