Parser.getTok().getLoc()));
Parser.Lex(); // Eat the [
- if (Mnemonic == "cas" || Mnemonic == "casx") {
+ if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
SMLoc S = Parser.getTok().getLoc();
if (getLexer().getKind() != AsmToken::Percent)
return MatchOperand_NoMatch;
"true",
"Enable UMAC and SMAC for LEON3 and LEON4 processors"
>;
+
+
+//===----------------------------------------------------------------------===//
+// CASA Support differs between LEON3-FT GR712RC and LEON3-FT UT699
+// We need to have the option to switch this on and off.
+//===----------------------------------------------------------------------===//
+
+//support to casa instruction; for leon3 subtarget only
+def LeonCASA : SubtargetFeature<
+ "hasleoncasa",
+ "HasLeonCasa",
+ "true",
+ "Enable CASA instruction for LEON3 and LEON4 processors"
+>;
+
\ No newline at end of file
def : Processor<"leon3", LEON3Itineraries,
[FeatureLeon, UMACSMACSupport]>;
-// LEON 3 FT (UT699)
-// TO DO: Place-holder: Processor specific features will be added *very* soon here.
+// LEON 3 FT (UT699). Provides features for the UT699 processor
+// - covers all the erratum fixes for LEON3, but does not support the CASA instruction.
def : Processor<"ut699", LEON3Itineraries,
[FeatureLeon, UMACSMACSupport]>;
-// LEON3 FT (GR712RC)
-// TO DO: Place-holder: Processor specific features will be added *very* soon here.
+// LEON3 FT (GR712RC). Provides features for the GR712RC processor.
+// - covers all the erratum fixed for LEON3 and support for the CASA instruction.
def : Processor<"gr712rc", LEON3Itineraries,
- [FeatureLeon, UMACSMACSupport]>;
+ [FeatureLeon, UMACSMACSupport, LeonCASA]>;
// LEON 4 FT generic
def : Processor<"leon4", LEON4Itineraries,
- [FeatureLeon, UMACSMACSupport]>;
+ [FeatureLeon, UMACSMACSupport, LeonCASA]>;
// LEON 4 FT (GR740)
// TO DO: Place-holder: Processor specific features will be added *very* soon here.
def : Processor<"gr740", LEON4Itineraries,
- [FeatureLeon, UMACSMACSupport]>;
+ [FeatureLeon, UMACSMACSupport, LeonCASA]>;
//===----------------------------------------------------------------------===//
// Declare the target which we are implementing
}
// ATOMICs.
- // Atomics are only supported on Sparcv9. (32bit atomics are also
- // supported by the Leon sparcv8 variant, but we don't support that
- // yet.)
+ // Atomics are supported on SparcV9. 32-bit atomics are also
+ // supported by some Leon SparcV8 variants. Otherwise, atomics
+ // are unsupported.
if (Subtarget->isV9())
setMaxAtomicSizeInBitsSupported(64);
+ else if (false && Subtarget->hasLeonCasa())
+ // Test made to fail pending completion of AtomicExpandPass,
+ // as this will cause a regression until that work is completed.
+ setMaxAtomicSizeInBitsSupported(32);
else
setMaxAtomicSizeInBitsSupported(0);
setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Legal);
- setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32,
- (Subtarget->isV9() ? Legal: Expand));
-
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Legal);
// point instructions.
def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
+// HasLeonCASA - This is true when the target processor supports the CASA
+// instruction
+def HasLeonCASA : Predicate<"Subtarget->hasLeonCasa()">;
+
// HasUMAC_SMAC - This is true when the target processor supports the
// UMAC and SMAC instructions
def HasUMAC_SMAC : Predicate<"Subtarget->hasUmacSmac()">;
def MEMBARi : F3_2<2, 0b101000, (outs), (ins simm13Op:$simm13),
"membar $simm13", []>;
-// TODO: Should add a CASArr variant. In fact, the CAS instruction,
-// unlike other instructions, only comes in a form which requires an
-// ASI be provided. The ASI value hardcoded here is ASI_PRIMARY, the
-// default unprivileged ASI for SparcV9. (Also of note: some modern
-// SparcV8 implementations provide CASA as an extension, but require
-// the use of SparcV8's default ASI, 0xA ("User Data") instead.)
+// The CAS instruction, unlike other instructions, only comes in a
+// form which requires an ASI be provided. The ASI value hardcoded
+// here is ASI_PRIMARY, the default unprivileged ASI for SparcV9.
let Predicates = [HasV9], Constraints = "$swap = $rd", asi = 0b10000000 in
def CASrr: F3_1_asi<3, 0b111100,
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
[(set i32:$rd,
(atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>;
+
+// CASA is supported as an instruction on some LEON3 and all LEON4 processors.
+// This version can be automatically lowered from C code, selecting ASI 10
+let Predicates = [HasLeonCASA], Constraints = "$swap = $rd", asi = 0b00001010 in
+ def CASAasi10: F3_1_asi<3, 0b111100,
+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
+ IntRegs:$swap),
+ "casa [$rs1] 10, $rs2, $rd",
+ [(set i32:$rd,
+ (atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>;
+
+// CASA supported on some LEON3 and all LEON4 processors. Same pattern as
+// CASrr, above, but with a different ASI. This version is supported for
+// inline assembly lowering only.
+let Predicates = [HasLeonCASA], Constraints = "$swap = $rd" in
+ def CASArr: F3_1_asi<3, 0b111100,
+ (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
+ IntRegs:$swap, i8imm:$asi),
+ "casa [$rs1] $asi, $rs2, $rd", []>;
+
// TODO: Add DAG sequence to lower these instructions. Currently, only provided
// as inline assembler-supported instructions.
let Predicates = [HasUMAC_SMAC], Defs = [Y, ASR18], Uses = [Y, ASR18] in {
IsVIS = false;
HasHardQuad = false;
UsePopc = false;
+
+ // Leon features
+ HasLeonCasa = false;
HasUmacSmac = false;
// Determine default and user specified characteristics
virtual void anchor();
bool IsV9;
bool IsLeon;
- bool HasUmacSmac;
bool V8DeprecatedInsts;
bool IsVIS, IsVIS2, IsVIS3;
bool Is64Bit;
bool HasHardQuad;
bool UsePopc;
+
+ // LEON features
+ bool HasUmacSmac;
+ bool HasLeonCasa;
+
SparcInstrInfo InstrInfo;
SparcTargetLowering TLInfo;
SelectionDAGTargetInfo TSInfo;
bool isV9() const { return IsV9; }
bool isLeon() const { return IsLeon; }
- bool hasUmacSmac() const { return HasUmacSmac; }
bool isVIS() const { return IsVIS; }
bool isVIS2() const { return IsVIS2; }
bool isVIS3() const { return IsVIS3; }
bool hasHardQuad() const { return HasHardQuad; }
bool usePopc() const { return UsePopc; }
+ // Leon options
+ bool hasUmacSmac() const { return HasUmacSmac; }
+ bool hasLeonCasa() const { return HasLeonCasa; }
+
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
-! RUN: llvm-mc %s -arch=sparc -mcpu=leon3 -show-encoding | FileCheck %s
-! RUN: llvm-mc %s -arch=sparc -mcpu=ut699 -show-encoding | FileCheck %s
+! RUN: llvm-mc %s -arch=sparc -mcpu=leon3 -show-encoding | FileCheck %s -check-prefix=CHECK_NO_CASA
+! RUN: llvm-mc %s -arch=sparc -mcpu=ut699 -show-encoding | FileCheck %s -check-prefix=CHECK_NO_CASA
! RUN: llvm-mc %s -arch=sparc -mcpu=gr712rc -show-encoding | FileCheck %s
! RUN: llvm-mc %s -arch=sparc -mcpu=leon4 -show-encoding | FileCheck %s
! RUN: llvm-mc %s -arch=sparc -mcpu=gr740 -show-encoding | FileCheck %s
+ ! CHECK: casa [%i0] 10, %l6, %o2 ! encoding: [0xd5,0xe6,0x01,0x56]
+ casa [%i0] 10, %l6, %o2
+
+ ! CHECK: casa [%i0] 5, %l6, %o2 ! encoding: [0xd5,0xe6,0x00,0xb6]
+ casa [%i0] 5, %l6, %o2
+
! CHECK: umac %i0, %l6, %o2 ! encoding: [0x95,0xf6,0x00,0x16]
+ ! CHECK_NO_CASA: umac %i0, %l6, %o2 ! encoding: [0x95,0xf6,0x00,0x16]
umac %i0, %l6, %o2
! CHECK: smac %i0, %l6, %o2 ! encoding: [0x95,0xfe,0x00,0x16]
+ ! CHECK_NO_CASA: smac %i0, %l6, %o2 ! encoding: [0x95,0xfe,0x00,0x16]
smac %i0, %l6, %o2