diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp index 9fa60ee5229ba..3fac774f1fa60 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp @@ -85,10 +85,14 @@ createSparcMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { MCSubtargetInfo *STI = createSparcMCSubtargetInfoImpl(TT, CPU, /*TuneCPU=*/CPU, FS); + FeatureBitset Features = STI->getFeatureBits(); if (TT.isSPARC64() && !STI->hasFeature(Sparc::Feature64Bit)) { - FeatureBitset Features = STI->getFeatureBits(); STI->setFeatureBits(Features.set(Sparc::Feature64Bit)); + } else if (!TT.isSPARC64() && !STI->hasFeature(Sparc::Feature32Bit)) { + STI->setFeatureBits(Features.set(Sparc::Feature32Bit)); } + assert(Features.test(Sparc::Feature32Bit) != + Features.test(Sparc::Feature64Bit)); return STI; } diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td index ecf82fab5cc41..2ef8d7e57f398 100644 --- a/llvm/lib/Target/Sparc/Sparc.td +++ b/llvm/lib/Target/Sparc/Sparc.td @@ -23,20 +23,15 @@ include "llvm/TableGen/SearchableTable.td" def FeatureSoftMulDiv : SubtargetFeature<"soft-mul-div", "UseSoftMulDiv", "true", "Use software emulation for integer multiply and divide">; - def FeatureNoFSMULD : SubtargetFeature<"no-fsmuld", "HasNoFSMULD", "true", "Disable the fsmuld instruction.">; def FeatureNoFMULS : SubtargetFeature<"no-fmuls", "HasNoFMULS", "true", "Disable the fmuls instruction.">; - def FeatureV9 : SubtargetFeature<"v9", "IsV9", "true", "Enable SPARC-V9 instructions">; -def Feature64Bit : SubtargetFeature<"64bit", "Is64Bit", "true", - "Enable 64-bit mode", [FeatureV9]>; - def FeatureV8Plus : SubtargetFeature<"v8plus", "IsV8Plus", "true", "Enable V8+ mode, allowing use of 64-bit V9 instructions in 32-bit code">; @@ -77,17 +72,18 @@ def FeatureLeon def FeaturePWRPSR : SubtargetFeature<"leonpwrpsr", "HasPWRPSR", "true", "Enable the PWRPSR instruction">; - def FeatureHardQuad : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true", "Enable quad-word floating point instructions">; - def UsePopc : SubtargetFeature<"popc", "UsePopc", "true", "Use the popc (population count) instruction">; def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", "Use software emulation for floating point">; - +def Feature32Bit : SubtargetFeature<"32bit", "Is32Bit", "true", + "Enable 32-bit mode">; +def Feature64Bit : SubtargetFeature<"64bit", "Is64Bit", "true", + "Enable 64-bit mode", [FeatureV9]>; //===----------------------------------------------------------------------===// // SPARC Subtarget tuning features. // diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td index 459fd193db0ed..bc87ab2539e9c 100644 --- a/llvm/lib/Target/Sparc/SparcInstrAliases.td +++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td @@ -101,114 +101,168 @@ multiclass int_cond_alias { // b %icc, $imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9, Is32Bit]>; // b,pt %icc, $imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9, Is32Bit]>; // b,a %icc, $imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9, Is32Bit]>; // b,a,pt %icc, $imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9, Is32Bit]>; // b,pn %icc, $imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9, Is32Bit]>; // b,a,pn %icc, $imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, Requires<[HasV9, Is32Bit]>; // b %xcc, $imm def : InstAlias, Requires<[Is64Bit]>; + def : InstAlias, Requires<[Is64Bit]>; // b,pt %xcc, $imm def : InstAlias, Requires<[Is64Bit]>; + def : InstAlias, Requires<[Is64Bit]>; // b,a %xcc, $imm def : InstAlias, Requires<[Is64Bit]>; + def : InstAlias, Requires<[Is64Bit]>; // b,a,pt %xcc, $imm def : InstAlias, Requires<[Is64Bit]>; + def : InstAlias, Requires<[Is64Bit]>; // b,pn %xcc, $imm def : InstAlias, Requires<[Is64Bit]>; + def : InstAlias, Requires<[Is64Bit]>; // b,a,pn %xcc, $imm def : InstAlias, Requires<[Is64Bit]>; - + def : InstAlias, Requires<[Is64Bit]>; defm : intcond_mov_alias, Requires<[HasV9]>; + defm : intcond_mov_alias, Requires<[Is32Bit, HasV9]>; + defm : intcond_mov_alias, Requires<[Is64Bit]>; + defm : intcond_mov_alias, Requires<[Is64Bit]>; + // fmovq (%icc|%xcc), $rs2, $rd def : InstAlias, Requires<[HasV9, HasHardQuad]>; + def : InstAlias, + Requires<[HasV9, Is32Bit, HasHardQuad]>; def : InstAlias, Requires<[Is64Bit, HasHardQuad]>; + def : InstAlias, + Requires<[Is64Bit, HasHardQuad]>; // t %icc, rs => t %icc, G0 + rs def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is32Bit]>; + // t %icc, rs1 + rs2 def : InstAlias, Requires<[HasV9]>; - + def : InstAlias, + Requires<[HasV9, Is32Bit]>; // t %xcc, rs => t %xcc, G0 + rs def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is64Bit]>; + // t %xcc, rs1 + rs2 def : InstAlias, Requires<[HasV9]>; - - - // t rs=> t %icc, G0 + rs2 - //def : InstAlias, - // Requires<[HasV9]>; - - // t rs1 + rs2 => t %icc, rs1 + rs2 - //def : InstAlias, - // Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is64Bit]>; // t %icc, imm => t %icc, G0 + imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is32Bit]>; + // t %icc, rs1 + imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is32Bit]>; + // t %xcc, imm => t %xcc, G0 + imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is64Bit]>; + // t %xcc, rs1 + imm def : InstAlias, Requires<[HasV9]>; + def : InstAlias, + Requires<[HasV9, Is64Bit]>; // t imm => t G0 + imm def : InstAlias; def : InstAlias<"clrh [$addr]", (STHri MEMri:$addr, G0), 0>; def : InstAlias<"clr [$addr]", (STrr MEMrr:$addr, G0), 0>; def : InstAlias<"clr [$addr]", (STri MEMri:$addr, G0), 0>; - +def : InstAlias<"clrx [$addr]", (STXrr MEMrr:$addr, G0), 0>, Requires<[HasV9]>; +def : InstAlias<"clrx [$addr]", (STXri MEMri:$addr, G0), 0>, Requires<[HasV9]>; // mov reg_or_imm, rd -> or %g0, reg_or_imm, rd def : InstAlias<"mov $rs2, $rd", (ORrr IntRegs:$rd, G0, IntRegs:$rs2)>; @@ -701,6 +756,31 @@ def : MnemonicAlias<"addccc", "addxcc">, Requires<[HasV9]>; def : MnemonicAlias<"subc", "subx">, Requires<[HasV9]>; def : MnemonicAlias<"subccc", "subxcc">, Requires<[HasV9]>; +// Solaris Natural Instructions extension +// We match GCC's coverage of the extension; everything except setn & setnhi. +// See also: https://docs.oracle.com/cd/E53394_01/html/E54833/gmael.html +let Predicates = [Is32Bit] in { + def : MnemonicAlias<"ldn", "ld">; + def : MnemonicAlias<"stn", "st">; + def : MnemonicAlias<"ldna", "lda">; + def : MnemonicAlias<"stna", "sta">; + def : MnemonicAlias<"casn", "cas">; + def : MnemonicAlias<"slln", "sll">; + def : MnemonicAlias<"srln", "srl">; + def : MnemonicAlias<"sran", "sra">; + def : MnemonicAlias<"clrn", "clr">; +} +let Predicates = [Is64Bit] in { + def : MnemonicAlias<"ldn", "ldx">; + def : MnemonicAlias<"stn", "stx">; + def : MnemonicAlias<"ldna", "ldxa">; + def : MnemonicAlias<"stna", "stxa">; + def : MnemonicAlias<"casn", "casx">; + def : MnemonicAlias<"slln", "sllx">; + def : MnemonicAlias<"srln", "srlx">; + def : MnemonicAlias<"sran", "srax">; + def : MnemonicAlias<"clrn", "clrx">; +} def : InstAlias<"fcmps $rs1, $rs2", (V9FCMPS FCC0, FPRegs:$rs1, FPRegs:$rs2)>; def : InstAlias<"fcmpd $rs1, $rs2", (V9FCMPD FCC0, DFPRegs:$rs1, DFPRegs:$rs2)>; diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 107817fcab6df..2a02a10da21ec 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -21,11 +21,12 @@ include "SparcInstrFormats.td" //===----------------------------------------------------------------------===// // True when generating 32-bit code. -def Is32Bit : Predicate<"!Subtarget->is64Bit()">; +def Is32Bit : Predicate<"!Subtarget->is64Bit()">, + AssemblerPredicate<(all_of Feature32Bit)>; // True when generating 64-bit code. This also implies HasV9. def Is64Bit : Predicate<"Subtarget->is64Bit()">, - AssemblerPredicate<(all_of FeatureV9)>; + AssemblerPredicate<(all_of FeatureV9, Feature64Bit)>; def UseSoftMulDiv : Predicate<"Subtarget->useSoftMulDiv()">, AssemblerPredicate<(all_of FeatureSoftMulDiv)>; diff --git a/llvm/lib/Target/Sparc/SparcSubtarget.cpp b/llvm/lib/Target/Sparc/SparcSubtarget.cpp index 1d72d0bdada03..9d6473cc91684 100644 --- a/llvm/lib/Target/Sparc/SparcSubtarget.cpp +++ b/llvm/lib/Target/Sparc/SparcSubtarget.cpp @@ -40,11 +40,17 @@ SparcSubtarget &SparcSubtarget::initializeSubtargetDependencies( // Parse features string. ParseSubtargetFeatures(CPUName, TuneCPU, FS); + FeatureBitset Features = getFeatureBits(); if (!Is64Bit && TT.isSPARC64()) { - FeatureBitset Features = getFeatureBits(); setFeatureBits(Features.set(Sparc::Feature64Bit)); Is64Bit = true; + } else if (!Is32Bit && !TT.isSPARC64()) { + setFeatureBits(Features.set(Sparc::Feature32Bit)); + Is32Bit = true; } + assert(Features.test(Sparc::Feature32Bit) != + Features.test(Sparc::Feature64Bit)); + assert(Is32Bit != Is64Bit); // Popc is a v9-only instruction. if (!IsV9) diff --git a/llvm/test/MC/Sparc/sparc-natural-instructions.s b/llvm/test/MC/Sparc/sparc-natural-instructions.s new file mode 100644 index 0000000000000..4f223497b2556 --- /dev/null +++ b/llvm/test/MC/Sparc/sparc-natural-instructions.s @@ -0,0 +1,42 @@ +! RUN: llvm-mc %s -triple=sparc -mcpu=v9 -show-encoding | FileCheck %s --check-prefixes=SPARC32 +! RUN: llvm-mc %s -triple=sparcv9 -mcpu=v9 -show-encoding | FileCheck %s --check-prefixes=SPARC64 + +!! Solaris Natural Instructions. + +! SPARC32: .word 305419896 +! SPARC64: .xword 305419896 +.nword 0x12345678 + +! SPARC32: ld [%o0+8], %g1 ! encoding: [0xc2,0x02,0x20,0x08] +! SPARC64: ldx [%o0+8], %g1 ! encoding: [0xc2,0x5a,0x20,0x08] +ldn [%o0 + 8], %g1 +! SPARC32: st %g1, [%o0+8] ! encoding: [0xc2,0x22,0x20,0x08] +! SPARC64: stx %g1, [%o0+8] ! encoding: [0xc2,0x72,0x20,0x08] +stn %g1, [%o0 + 8] +! SPARC32: lda [%o0] #ASI_AIUP, %g1 ! encoding: [0xc2,0x82,0x02,0x00] +! SPARC64: ldxa [%o0] #ASI_AIUP, %g1 ! encoding: [0xc2,0xda,0x02,0x00] +ldna [%o0] 0x10, %g1 +! SPARC32: sta %g1, [%o0] #ASI_AIUP ! encoding: [0xc2,0xa2,0x02,0x00] +! SPARC64: stxa %g1, [%o0] #ASI_AIUP ! encoding: [0xc2,0xf2,0x02,0x00] +stna %g1, [%o0] 0x10 +! SPARC32: cas [%o0], %g0, %g1 ! encoding: [0xc3,0xe2,0x10,0x00] +! SPARC64: casx [%o0], %g0, %g1 ! encoding: [0xc3,0xf2,0x10,0x00] +casn [%o0], %g0, %g1 +! SPARC32: sll %g0, %g1, %g2 ! encoding: [0x85,0x28,0x00,0x01] +! SPARC64: sllx %g0, %g1, %g2 ! encoding: [0x85,0x28,0x10,0x01] +slln %g0, %g1, %g2 +! SPARC32: srl %g0, %g1, %g2 ! encoding: [0x85,0x30,0x00,0x01] +! SPARC64: srlx %g0, %g1, %g2 ! encoding: [0x85,0x30,0x10,0x01] +srln %g0, %g1, %g2 +! SPARC32: sra %g0, %g1, %g2 ! encoding: [0x85,0x38,0x00,0x01] +! SPARC64: srax %g0, %g1, %g2 ! encoding: [0x85,0x38,0x10,0x01] +sran %g0, %g1, %g2 +! SPARC32: st %g0, [%o0+8] ! encoding: [0xc0,0x22,0x20,0x08] +! SPARC64: stx %g0, [%o0+8] ! encoding: [0xc0,0x72,0x20,0x08] +clrn [%o0 + 8] + +ba %ncc, . +ta %ncc, 0x6d +move %ncc, %g1, %g2 +fmovse %ncc, %f0, %f1 +fmovse %ncc, %f0, %f2