Index: include/llvm/IR/IntrinsicsARM.td =================================================================== --- include/llvm/IR/IntrinsicsARM.td +++ include/llvm/IR/IntrinsicsARM.td @@ -45,6 +45,11 @@ def int_arm_ldrexd : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_ptr_ty]>; //===----------------------------------------------------------------------===// +// Data barrier instructions +def int_arm_dmb : Intrinsic<[], [llvm_i32_ty]>; +def int_arm_dsb : Intrinsic<[], [llvm_i32_ty]>; + +//===----------------------------------------------------------------------===// // VFP def int_arm_get_fpscr : GCCBuiltin<"__builtin_arm_get_fpscr">, Index: lib/Target/ARM/ARMInstrInfo.td =================================================================== --- lib/Target/ARM/ARMInstrInfo.td +++ lib/Target/ARM/ARMInstrInfo.td @@ -4263,6 +4263,8 @@ } } +def : Pat<(int_arm_dmb (i32 imm:$opt)), (DMB (i32 imm:$opt))>; + def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, "dsb", "\t$opt", []>, Requires<[IsARM, HasDB]> { @@ -4271,6 +4273,8 @@ let Inst{3-0} = opt; } +def : Pat<(int_arm_dsb (i32 imm:$opt)), (DSB (i32 imm:$opt))>; + // ISB has only full system option def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary, "isb", "\t$opt", []>, Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -339,6 +339,7 @@ struct MBOptOp { ARM_MB::MemBOpt Val; + bool HasV8; }; struct ISBOptOp { @@ -2452,9 +2453,11 @@ return Op; } - static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S) { + static ARMOperand *CreateMemBarrierOpt(ARM_MB::MemBOpt Opt, SMLoc S, + bool HasV8) { ARMOperand *Op = new ARMOperand(k_MemBarrierOpt); Op->MBOpt.Val = Opt; + Op->MBOpt.HasV8 = HasV8; Op->StartLoc = S; Op->EndLoc = S; return Op; @@ -2521,7 +2524,8 @@ getImm()->print(OS); break; case k_MemBarrierOpt: - OS << ""; + OS << ""; break; case k_InstSyncBarrierOpt: OS << ""; @@ -3466,18 +3470,27 @@ Opt = StringSwitch(OptStr.slice(0, OptStr.size()).lower()) .Case("sy", ARM_MB::SY) .Case("st", ARM_MB::ST) + .Case("ld", ARM_MB::LD) .Case("sh", ARM_MB::ISH) .Case("ish", ARM_MB::ISH) .Case("shst", ARM_MB::ISHST) .Case("ishst", ARM_MB::ISHST) + .Case("ishld", ARM_MB::ISHLD) .Case("nsh", ARM_MB::NSH) .Case("un", ARM_MB::NSH) .Case("nshst", ARM_MB::NSHST) + .Case("nshld", ARM_MB::NSHLD) .Case("unst", ARM_MB::NSHST) .Case("osh", ARM_MB::OSH) .Case("oshst", ARM_MB::OSHST) + .Case("oshld", ARM_MB::OSHLD) .Default(~0U); + // ishld, oshld, nshld and ld are only available from ARMv8. + if (!hasV8Ops() && (Opt == ARM_MB::ISHLD || Opt == ARM_MB::OSHLD || + Opt == ARM_MB::NSHLD || Opt == ARM_MB::LD)) + Opt = ~0U; + if (Opt == ~0U) return MatchOperand_NoMatch; @@ -3511,7 +3524,8 @@ } else return MatchOperand_ParseFail; - Operands.push_back(ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S)); + Operands.push_back( + ARMOperand::CreateMemBarrierOpt((ARM_MB::MemBOpt)Opt, S, hasV8Ops())); return MatchOperand_Success; } Index: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp =================================================================== --- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -677,7 +677,7 @@ void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O) { unsigned val = MI->getOperand(OpNum).getImm(); - O << ARM_MB::MemBOptToString(val); + O << ARM_MB::MemBOptToString(val, (getAvailableFeatures() & ARM::HasV8Ops)); } void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum, Index: lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -121,41 +121,41 @@ // the option field for memory barrier operations. enum MemBOpt { RESERVED_0 = 0, - RESERVED_1 = 1, + OSHLD = 1, OSHST = 2, OSH = 3, RESERVED_4 = 4, - RESERVED_5 = 5, + NSHLD = 5, NSHST = 6, NSH = 7, RESERVED_8 = 8, - RESERVED_9 = 9, + ISHLD = 9, ISHST = 10, ISH = 11, RESERVED_12 = 12, - RESERVED_13 = 13, + LD = 13, ST = 14, SY = 15 }; - inline static const char *MemBOptToString(unsigned val) { + inline static const char *MemBOptToString(unsigned val, bool HasV8) { switch (val) { default: llvm_unreachable("Unknown memory operation"); case SY: return "sy"; case ST: return "st"; - case RESERVED_13: return "#0xd"; + case LD: return HasV8 ? "ld" : "#0xd"; case RESERVED_12: return "#0xc"; case ISH: return "ish"; case ISHST: return "ishst"; - case RESERVED_9: return "#0x9"; + case ISHLD: return HasV8 ? "ishld" : "#0x9"; case RESERVED_8: return "#0x8"; case NSH: return "nsh"; case NSHST: return "nshst"; - case RESERVED_5: return "#0x5"; + case NSHLD: return HasV8 ? "nshld" : "#0x5"; case RESERVED_4: return "#0x4"; case OSH: return "osh"; case OSHST: return "oshst"; - case RESERVED_1: return "#0x1"; + case OSHLD: return HasV8 ? "oshld" : "#0x1"; case RESERVED_0: return "#0x0"; } } Index: test/MC/ARM/basic-arm-instructions-v8.s =================================================================== --- /dev/null +++ test/MC/ARM/basic-arm-instructions-v8.s @@ -0,0 +1,36 @@ +@ RUN: llvm-mc -triple=armv8 -mattr=+db -show-encoding < %s | FileCheck %s +@ RUN: not llvm-mc -triple=armv7 -mattr=+db -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V7 + +@------------------------------------------------------------------------------ +@ DMB (v8 barriers) +@------------------------------------------------------------------------------ + dmb ishld + dmb oshld + dmb nshld + dmb ld + +@ CHECK: dmb ishld @ encoding: [0x59,0xf0,0x7f,0xf5] +@ CHECK: dmb oshld @ encoding: [0x51,0xf0,0x7f,0xf5] +@ CHECK: dmb nshld @ encoding: [0x55,0xf0,0x7f,0xf5] +@ CHECK: dmb ld @ encoding: [0x5d,0xf0,0x7f,0xf5] +@ CHECK-V7: error: invalid operand for instruction +@ CHECK-V7: error: invalid operand for instruction +@ CHECK-V7: error: invalid operand for instruction +@ CHECK-V7: error: invalid operand for instruction + +@------------------------------------------------------------------------------ +@ DSB (v8 barriers) +@------------------------------------------------------------------------------ + dsb ishld + dsb oshld + dsb nshld + dsb ld + +@ CHECK: dsb ishld @ encoding: [0x49,0xf0,0x7f,0xf5] +@ CHECK: dsb oshld @ encoding: [0x41,0xf0,0x7f,0xf5] +@ CHECK: dsb nshld @ encoding: [0x45,0xf0,0x7f,0xf5] +@ CHECK: dsb ld @ encoding: [0x4d,0xf0,0x7f,0xf5] +@ CHECK-V7: error: invalid operand for instruction +@ CHECK-V7: error: invalid operand for instruction +@ CHECK-V7: error: invalid operand for instruction +@ CHECK-V7: error: invalid operand for instruction