OSDN Git Service

PLD, PLDW, PLI encodings, plus refactor their use of addrmode2.
authorJim Grosbach <grosbach@apple.com>
Thu, 28 Oct 2010 18:34:10 +0000 (18:34 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 28 Oct 2010 18:34:10 +0000 (18:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117571 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMMCCodeEmitter.cpp
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp

index ffd4962..dd38119 100644 (file)
@@ -398,6 +398,9 @@ def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
 //
 def addrmode_imm12 : Operand<i32>,
                      ComplexPattern<i32, 2, "SelectAddrModeImm12", []> {
+  // 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<bit data, bit read, string opc> {
 
-  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)>;
 
index 1259672..122aadf 100644 (file)
@@ -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;
index 3c909ec..be66112 100644 (file)
@@ -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,
index 892558e..21b3e1c 100644 (file)
@@ -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;