Index: llvm/trunk/lib/Target/ARM/ARM.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARM.td +++ llvm/trunk/lib/Target/ARM/ARM.td @@ -363,6 +363,11 @@ def FeatureUseAA : SubtargetFeature<"use-aa", "UseAA", "true", "Use alias analysis during codegen">; +// Armv8.5-A extensions + +def FeatureSpecCtrl : SubtargetFeature<"specctrl", "HasSpecCtrl", "true", + "Enable speculation control barrier" >; + //===----------------------------------------------------------------------===// // ARM architecture class // @@ -454,7 +459,7 @@ def HasV8_5aOps : SubtargetFeature<"v8.5a", "HasV8_5aOps", "true", "Support ARM v8.5a instructions", - [HasV8_4aOps]>; + [HasV8_4aOps, FeatureSpecCtrl]>; //===----------------------------------------------------------------------===// // ARM Processor subtarget features. Index: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td +++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td @@ -391,6 +391,10 @@ def GenExecuteOnly : Predicate<"Subtarget->genExecuteOnly()">; +// Armv8.5-A extensions +def HasSpecCtrl : Predicate<"Subtarget->hasSpecCtrl()">, + AssemblerPredicate<"FeatureSpecCtrl", "specctrl">; + //===----------------------------------------------------------------------===// // ARM Flag Definitions. @@ -4875,6 +4879,14 @@ } +// Armv8.5-A speculation barrier +def SB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "sb", "", []>, + Requires<[IsARM, HasSpecCtrl]>, Sched<[]> { + let Inst{31-0} = 0xf57ff070; + let Unpredictable = 0x000fff0f; + let hasSideEffects = 1; +} + let usesCustomInserter = 1, Defs = [CPSR] in { // Pseudo instruction that combines movs + predicated rsbmi Index: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td @@ -3231,6 +3231,14 @@ } } +// Armv8.5-A speculation barrier +def t2SB : Thumb2XI<(outs), (ins), AddrModeNone, 4, NoItinerary, "sb", "", []>, + Requires<[IsThumb2, HasSpecCtrl]>, Sched<[]> { + let Inst{31-0} = 0xf3bf8f70; + let Unpredictable = 0x000f2f0f; + let hasSideEffects = 1; +} + class T2I_ldrex opcod, dag oops, dag iops, AddrMode am, int sz, InstrItinClass itin, string opc, string asm, string cstr, list pattern, bits<4> rt2 = 0b1111> Index: llvm/trunk/lib/Target/ARM/ARMSubtarget.h =================================================================== --- llvm/trunk/lib/Target/ARM/ARMSubtarget.h +++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h @@ -416,6 +416,9 @@ /// UseSjLjEH - If true, the target uses SjLj exception handling (e.g. iOS). bool UseSjLjEH = false; + /// Has speculation barrier + bool HasSpecCtrl = false; + /// Implicitly convert an instruction to a different one if its immediates /// cannot be encoded. For example, ADD r0, r1, #FFFFFFFF -> SUB r0, r1, #1. bool NegativeImmediates = true; @@ -625,6 +628,7 @@ bool hasDSP() const { return HasDSP; } bool useNaClTrap() const { return UseNaClTrap; } bool useSjLjEH() const { return UseSjLjEH; } + bool hasSpecCtrl() const { return HasSpecCtrl; } bool genLongCalls() const { return GenLongCalls; } bool genExecuteOnly() const { return GenExecuteOnly; } Index: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5720,7 +5720,8 @@ Mnemonic == "vmovx" || Mnemonic == "vins" || Mnemonic == "vudot" || Mnemonic == "vsdot" || Mnemonic == "vcmla" || Mnemonic == "vcadd" || - Mnemonic == "vfmal" || Mnemonic == "vfmsl") { + Mnemonic == "vfmal" || Mnemonic == "vfmsl" || + Mnemonic == "sb") { // These mnemonics are never predicable CanAcceptPredicationCode = false; } else if (!isThumb()) { Index: llvm/trunk/test/MC/ARM/armv8.5a-specctrl-error-thumb.s =================================================================== --- llvm/trunk/test/MC/ARM/armv8.5a-specctrl-error-thumb.s +++ llvm/trunk/test/MC/ARM/armv8.5a-specctrl-error-thumb.s @@ -0,0 +1,6 @@ +// RUN: not llvm-mc -triple thumbv8 -show-encoding -mattr=+specctrl < %s 2>&1 | FileCheck %s + +it eq +sbeq + +// CHECK: instruction 'sb' is not predicable, but condition code specified Index: llvm/trunk/test/MC/ARM/armv8.5a-specctrl-error.s =================================================================== --- llvm/trunk/test/MC/ARM/armv8.5a-specctrl-error.s +++ llvm/trunk/test/MC/ARM/armv8.5a-specctrl-error.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple armv8 -show-encoding -mattr=+specctrl < %s 2>&1 | FileCheck %s + +sbeq + +// CHECK: instruction 'sb' is not predicable Index: llvm/trunk/test/MC/ARM/armv8.5a-specctrl.s =================================================================== --- llvm/trunk/test/MC/ARM/armv8.5a-specctrl.s +++ llvm/trunk/test/MC/ARM/armv8.5a-specctrl.s @@ -0,0 +1,15 @@ +// RUN: llvm-mc -triple armv8 -show-encoding -mattr=+specctrl < %s | FileCheck %s +// RUN: llvm-mc -triple armv8 -show-encoding -mattr=+v8.5a < %s | FileCheck %s +// RUN: not llvm-mc -triple armv8 -show-encoding -mattr=-specctrl < %s 2>&1 | FileCheck %s --check-prefix=NOSB +// RUN: llvm-mc -triple thumbv8 -show-encoding -mattr=+specctrl < %s | FileCheck %s --check-prefix=THUMB +// RUN: llvm-mc -triple thumbv8 -show-encoding -mattr=+v8.5a < %s | FileCheck %s --check-prefix=THUMB +// RUN: not llvm-mc -triple thumbv8 -show-encoding -mattr=-specctrl < %s 2>&1 | FileCheck %s --check-prefix=NOSB + +// Flag manipulation +sb + +// CHECK: sb @ encoding: [0x70,0xf0,0x7f,0xf5] +// THUMB: sb @ encoding: [0xbf,0xf3,0x70,0x8f] + +// NOSB: instruction requires: specctrl +// NOSB-NEXT: sb Index: llvm/trunk/test/MC/Disassembler/ARM/armv8.5a-specctrl-thumb.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/armv8.5a-specctrl-thumb.txt +++ llvm/trunk/test/MC/Disassembler/ARM/armv8.5a-specctrl-thumb.txt @@ -0,0 +1,9 @@ +# RUN: llvm-mc -triple=thumbv8 -mattr=+specctrl -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=thumbv8 -mattr=+v8.5a -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=thumbv8 -mattr=-specctrl -disassemble < %s 2>&1 | FileCheck %s --check-prefix=NOSB + +0xbf 0xf3 0x70 0x8f + +# CHECK: sb +# NOSB: invalid instruction encoding +# NOSB-NEXT: 0xbf 0xf3 0x70 0x8f Index: llvm/trunk/test/MC/Disassembler/ARM/armv8.5a-specctrl.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/armv8.5a-specctrl.txt +++ llvm/trunk/test/MC/Disassembler/ARM/armv8.5a-specctrl.txt @@ -0,0 +1,9 @@ +# RUN: llvm-mc -triple=armv8 -mattr=+specctrl -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=armv8 -mattr=+v8.5a -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=armv8 -mattr=-specctrl -disassemble < %s 2>&1 | FileCheck %s --check-prefix=NOSB + +0x70 0xf0 0x7f 0xf5 + +# CHECK: sb +# NOSB: invalid instruction encoding +# NOSB-NEXT: 0x70 0xf0 0x7f 0xf5