diff options
| -rw-r--r-- | llvm/lib/Target/ARM/ARM.h | 27 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 61 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/MC/Disassembler/arm-tests.txt | 6 | ||||
| -rw-r--r-- | llvm/utils/TableGen/EDEmitter.cpp | 1 | 
8 files changed, 74 insertions, 48 deletions
diff --git a/llvm/lib/Target/ARM/ARM.h b/llvm/lib/Target/ARM/ARM.h index 233706735e3..e76791921ee 100644 --- a/llvm/lib/Target/ARM/ARM.h +++ b/llvm/lib/Target/ARM/ARM.h @@ -90,6 +90,33 @@ inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {    }  } +namespace ARM_MB { +  // The Memory Barrier Option constants map directly to the 4-bit encoding of +  // the option field for memory barrier operations. +  enum MemBOpt { +    ST    = 14, +    ISH   = 11, +    ISHST = 10, +    NSH   = 7, +    NSHST = 6, +    OSH   = 3, +    OSHST = 2 +  }; + +  inline static const char *MemBOptToString(unsigned val) { +    switch (val) { +    default: llvm_unreachable("Unknown memory opetion"); +    case ST:    return "st"; +    case ISH:   return "ish"; +    case ISHST: return "ishst"; +    case NSH:   return "nsh"; +    case NSHST: return "nshst"; +    case OSH:   return "osh"; +    case OSHST: return "oshst"; +    } +  } +} // namespace ARM_MB +  FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM,                                 CodeGenOpt::Level OptLevel); diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index b09cd73176d..ded9800052e 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -122,6 +122,8 @@ namespace {                                  const char *Modifier = 0);      void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,                                          raw_ostream &O); +    void printMemBOption(const MachineInstr *MI, int OpNum, +                         raw_ostream &O);      void printSatShiftOperand(const MachineInstr *MI, int OpNum,                                raw_ostream &O); @@ -671,6 +673,13 @@ ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,    O << "#" << lsb << ", #" << width;  } +void +ARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum, +                               raw_ostream &O) { +  unsigned val = MI->getOperand(OpNum).getImm(); +  O << ARM_MB::MemBOptToString(val); +} +  void ARMAsmPrinter::printSatShiftOperand(const MachineInstr *MI, int OpNum,                                           raw_ostream &O) {    unsigned ShiftOp = MI->getOperand(OpNum).getImm(); diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index f058ee195f2..2e7757b0969 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -2389,61 +2389,30 @@ def DSB_MCR : AInoP<(outs), (ins GPR:$zero), MiscFrm, NoItinerary,  }  } -// Helper class for multiclass MemB -- for disassembly only -class AMBI<string opc, string asm> -  : AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm, -          [/* For disassembly only; pattern left blank */]>, -    Requires<[IsARM, HasV7]> { -  let Inst{31-20} = 0xf57; -} - -multiclass MemB<bits<4> op7_4, string opc> { - -  def st : AMBI<opc, "\tst"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b1110; -  } - -  def ish : AMBI<opc, "\tish"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b1011; -  } - -  def ishst : AMBI<opc, "\tishst"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b1010; -  } +// Memory Barrier Operations Variants -- for disassembly only -  def nsh : AMBI<opc, "\tnsh"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b0111; -  } - -  def nshst : AMBI<opc, "\tnshst"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b0110; -  } - -  def osh : AMBI<opc, "\tosh"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b0011; -  } +def memb_opt : Operand<i32> { +  let PrintMethod = "printMemBOption"; +} -  def oshst : AMBI<opc, "\toshst"> { -    let Inst{7-4} = op7_4; -    let Inst{3-0} = 0b0010; -  } +class AMBI<bits<4> op7_4, string opc> +  : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, opc, "\t$opt", +          [/* For disassembly only; pattern left blank */]>, +    Requires<[IsARM, HasDB]> { +  let Inst{31-8} = 0xf57ff0; +  let Inst{7-4} = op7_4;  }  // These DMB variants are for disassembly only. -defm DMB : MemB<0b0101, "dmb">; +def DMBvar : AMBI<0b0101, "dmb">;  // These DSB variants are for disassembly only. -defm DSB : MemB<0b0100, "dsb">; +def DSBvar : AMBI<0b0100, "dsb">;  // ISB has only full system option -- for disassembly only -def ISBsy : AMBI<"isb", ""> { -  let Inst{7-4} = 0b0110; +def ISBsy : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>, +            Requires<[IsARM, HasDB]> { +  let Inst{31-4} = 0xf57ff06;    let Inst{3-0} = 0b1111;  } diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp index f40da955041..b662289cd50 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp @@ -472,6 +472,12 @@ void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,    O << '#' << lsb << ", #" << width;  } +void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, +                                     raw_ostream &O) { +  unsigned val = MI->getOperand(OpNum).getImm(); +  O << ARM_MB::MemBOptToString(val); +} +  void ARMInstPrinter::printSatShiftOperand(const MCInst *MI, unsigned OpNum,                                            raw_ostream &O) {    unsigned ShiftOp = MI->getOperand(OpNum).getImm(); diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h index 14d7ec93087..3eaa6f78823 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMInstPrinter.h @@ -57,6 +57,7 @@ public:    void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,                                        raw_ostream &O); +  void printMemBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O);    void printSatShiftOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);    void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index cb15cff734b..9637caaa578 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -2935,7 +2935,7 @@ static bool DisassembleNDupFrm(MCInst &MI, unsigned Opcode, uint32_t insn,  // A8.6.49 ISB  static inline bool MemBarrierInstr(uint32_t insn) {    unsigned op7_4 = slice(insn, 7, 4); -  if (slice(insn, 31, 20) == 0xf57 && (op7_4 >= 4 && op7_4 <= 6)) +  if (slice(insn, 31, 8) == 0xf57ff0 && (op7_4 >= 4 && op7_4 <= 6))      return true;    return false; @@ -2992,8 +2992,15 @@ static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn,  static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,      unsigned short NumOps, unsigned &NumOpsAdded, BO B) { -  if (MemBarrierInstr(insn)) +  if (MemBarrierInstr(insn)) { +    // DMBsy, DSBsy, and ISBsy instructions have zero operand and are taken care +    // of within the generic ARMBasicMCBuilder::BuildIt() method. +    // +    // Inst{3-0} encodes the memory barrier option for the variants. +    MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0))); +    NumOpsAdded = 1;      return true; +  }    switch (Opcode) {    case ARM::CLREX: diff --git a/llvm/test/MC/Disassembler/arm-tests.txt b/llvm/test/MC/Disassembler/arm-tests.txt index bb5875d2f34..cca4f32a20c 100644 --- a/llvm/test/MC/Disassembler/arm-tests.txt +++ b/llvm/test/MC/Disassembler/arm-tests.txt @@ -21,6 +21,12 @@  # CHECK:	dsb  0x4f 0xf0 0x7f 0xf5 +# CHECK:	dsb	st +0x4e 0xf0 0x7f 0xf5 + +# CHECK:	isb +0x6f 0xf0 0x7f 0xf5 +  # CHECK:	ldclvc	p5, cr15, [r8], #-0  0x00 0xf5 0x78 0x7c diff --git a/llvm/utils/TableGen/EDEmitter.cpp b/llvm/utils/TableGen/EDEmitter.cpp index a640a74d216..8706ed5426e 100644 --- a/llvm/utils/TableGen/EDEmitter.cpp +++ b/llvm/utils/TableGen/EDEmitter.cpp @@ -599,6 +599,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,    IMM("cps_opt");    IMM("vfp_f64imm");    IMM("vfp_f32imm"); +  IMM("memb_opt");    IMM("msr_mask");    IMM("neg_zero");    IMM("imm0_31");  | 

