Index: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp =================================================================== --- lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -772,7 +772,7 @@ 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; Index: lib/Target/Sparc/LeonFeatures.td =================================================================== --- lib/Target/Sparc/LeonFeatures.td +++ lib/Target/Sparc/LeonFeatures.td @@ -22,3 +22,18 @@ "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 CASASupport : SubtargetFeature< + "casasupport", + "CasaEnabled", + "true", + "Enable CASA instruction for relevant LEON3 and LEON4 processors" +>; + \ No newline at end of file Index: lib/Target/Sparc/Sparc.td =================================================================== --- lib/Target/Sparc/Sparc.td +++ lib/Target/Sparc/Sparc.td @@ -116,24 +116,22 @@ 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 full coverage of UT699 - covers all the erratum fixes for LEON3. No support for CASA 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 full coverage of GR712RC. Supports for CASA def : Processor<"gr712rc", LEON3Itineraries, - [FeatureLeon, UMACSMACSupport]>; + [FeatureLeon, UMACSMACSupport, CASASupport]>; // LEON 4 FT generic def : Processor<"leon4", LEON4Itineraries, - [FeatureLeon, UMACSMACSupport]>; + [FeatureLeon, UMACSMACSupport, CASASupport]>; // 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, CASASupport]>; //===----------------------------------------------------------------------===// // Declare the target which we are implementing Index: lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- lib/Target/Sparc/SparcISelLowering.cpp +++ lib/Target/Sparc/SparcISelLowering.cpp @@ -1798,6 +1798,12 @@ } } + if (Subtarget->isLeon()) { + setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, + Subtarget->casaEnabled() ? Legal: Expand); + } + + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); setMinFunctionAlignment(2); Index: lib/Target/Sparc/SparcInstrInfo.td =================================================================== --- lib/Target/Sparc/SparcInstrInfo.td +++ lib/Target/Sparc/SparcInstrInfo.td @@ -49,6 +49,10 @@ // point instructions. def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">; +// CASASupported - This is true when the target processor supports the CASA +// instruction +def CASASupported : Predicate<"Subtarget->casaEnabled()">; + // HasUMAC_SMAC - This is true when the target processor supports the // UMAC and SMAC instructions def HasUMAC_SMAC : Predicate<"Subtarget->hasUmacSmac()">; @@ -1492,12 +1496,9 @@ 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, @@ -1506,6 +1507,26 @@ [(set i32:$rd, (atomic_cmp_swap iPTR:$rs1, i32:$rs2, i32:$swap))]>; + +// CASA supported on some LEON3 and all LEON4 processors. +// This version can be automatically lowered from C code, selecting ASI 10 +let Predicates = [CASASupported], 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 = [CASASupported], 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 { Index: lib/Target/Sparc/SparcSubtarget.h =================================================================== --- lib/Target/Sparc/SparcSubtarget.h +++ lib/Target/Sparc/SparcSubtarget.h @@ -34,12 +34,16 @@ 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 CasaEnabled; + SparcInstrInfo InstrInfo; SparcTargetLowering TLInfo; SelectionDAGTargetInfo TSInfo; @@ -67,7 +71,6 @@ 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; } @@ -75,6 +78,10 @@ bool hasHardQuad() const { return HasHardQuad; } bool usePopc() const { return UsePopc; } + // Leon options + bool hasUmacSmac() const { return HasUmacSmac; } + bool casaEnabled() const { return CasaEnabled; } + /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef FS); Index: lib/Target/Sparc/SparcSubtarget.cpp =================================================================== --- lib/Target/Sparc/SparcSubtarget.cpp +++ lib/Target/Sparc/SparcSubtarget.cpp @@ -34,6 +34,9 @@ IsVIS = false; HasHardQuad = false; UsePopc = false; + + // Leon features + CasaEnabled = false; HasUmacSmac = false; // Determine default and user specified characteristics Index: test/MC/Sparc/leon-instructions.s =================================================================== --- test/MC/Sparc/leon-instructions.s +++ test/MC/Sparc/leon-instructions.s @@ -1,12 +1,20 @@ -! 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