Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
12 changes: 4 additions & 8 deletions llvm/lib/Target/Sparc/Sparc.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">;
Expand Down Expand Up @@ -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.
//
Expand Down
108 changes: 94 additions & 14 deletions llvm/lib/Target/Sparc/SparcInstrAliases.td
Original file line number Diff line number Diff line change
Expand Up @@ -101,114 +101,168 @@ multiclass int_cond_alias<string cond, int condVal> {
// b<cond> %icc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), " %icc, $imm"),
(BPICC brtarget:$imm, condVal)>, Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("b", cond), " %ncc, $imm"),
(BPICC brtarget:$imm, condVal)>, Requires<[HasV9, Is32Bit]>;

// b<cond>,pt %icc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %icc, $imm"),
(BPICC brtarget:$imm, condVal)>, Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %ncc, $imm"),
(BPICC brtarget:$imm, condVal)>, Requires<[HasV9, Is32Bit]>;

// b<cond>,a %icc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",a %icc, $imm"),
(BPICCA brtarget:$imm, condVal)>, Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",a %ncc, $imm"),
(BPICCA brtarget:$imm, condVal)>, Requires<[HasV9, Is32Bit]>;

// b<cond>,a,pt %icc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %icc, $imm"),
(BPICCA brtarget:$imm, condVal)>, Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %ncc, $imm"),
(BPICCA brtarget:$imm, condVal)>, Requires<[HasV9, Is32Bit]>;

// b<cond>,pn %icc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %icc, $imm"),
(BPICCNT brtarget:$imm, condVal)>, Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %ncc, $imm"),
(BPICCNT brtarget:$imm, condVal)>, Requires<[HasV9, Is32Bit]>;

// b<cond>,a,pn %icc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %icc, $imm"),
(BPICCANT brtarget:$imm, condVal)>, Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %ncc, $imm"),
(BPICCANT brtarget:$imm, condVal)>, Requires<[HasV9, Is32Bit]>;

// b<cond> %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), " %xcc, $imm"),
(BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
def : InstAlias<!strconcat(!strconcat("b", cond), " %ncc, $imm"),
(BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

// b<cond>,pt %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %xcc, $imm"),
(BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %ncc, $imm"),
(BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

// b<cond>,a %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",a %xcc, $imm"),
(BPXCCA brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",a %ncc, $imm"),
(BPXCCA brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

// b<cond>,a,pt %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %xcc, $imm"),
(BPXCCA brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %ncc, $imm"),
(BPXCCA brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

// b<cond>,pn %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %xcc, $imm"),
(BPXCCNT brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %ncc, $imm"),
(BPXCCNT brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

// b<cond>,a,pn %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %xcc, $imm"),
(BPXCCANT brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %ncc, $imm"),
(BPXCCANT brtarget:$imm, condVal)>, Requires<[Is64Bit]>;

defm : intcond_mov_alias<cond, condVal, " %icc",
MOVICCrr, MOVICCri,
FMOVS_ICC, FMOVD_ICC>, Requires<[HasV9]>;

defm : intcond_mov_alias<cond, condVal, " %ncc",
MOVICCrr, MOVICCri,
FMOVS_ICC, FMOVD_ICC>, Requires<[Is32Bit, HasV9]>;

defm : intcond_mov_alias<cond, condVal, " %xcc",
MOVXCCrr, MOVXCCri,
FMOVS_XCC, FMOVD_XCC>, Requires<[Is64Bit]>;

defm : intcond_mov_alias<cond, condVal, " %ncc",
MOVXCCrr, MOVXCCri,
FMOVS_XCC, FMOVD_XCC>, Requires<[Is64Bit]>;

// fmovq<cond> (%icc|%xcc), $rs2, $rd
def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %icc, $rs2, $rd"),
(FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
Requires<[HasV9, HasHardQuad]>;
def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %ncc, $rs2, $rd"),
(FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
Requires<[HasV9, Is32Bit, HasHardQuad]>;
def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %xcc, $rs2, $rd"),
(FMOVQ_XCC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
Requires<[Is64Bit, HasHardQuad]>;
def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %ncc, $rs2, $rd"),
(FMOVQ_XCC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
Requires<[Is64Bit, HasHardQuad]>;

// t<cond> %icc, rs => t<cond> %icc, G0 + rs
def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $rs2"),
(TICCrr G0, IntRegs:$rs2, condVal)>,
Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $rs2"),
(TICCrr G0, IntRegs:$rs2, condVal)>,
Requires<[HasV9, Is32Bit]>;

// t<cond> %icc, rs1 + rs2
def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $rs1 + $rs2"),
(TICCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>,
Requires<[HasV9]>;

def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $rs1 + $rs2"),
(TICCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>,
Requires<[HasV9, Is32Bit]>;

// t<cond> %xcc, rs => t<cond> %xcc, G0 + rs
def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $rs2"),
(TXCCrr G0, IntRegs:$rs2, condVal)>,
Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $rs2"),
(TXCCrr G0, IntRegs:$rs2, condVal)>,
Requires<[HasV9, Is64Bit]>;

// t<cond> %xcc, rs1 + rs2
def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $rs1 + $rs2"),
(TXCCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>,
Requires<[HasV9]>;


// t<cond> rs=> t<cond> %icc, G0 + rs2
//def : InstAlias<!strconcat(!strconcat("t", cond), " $rs2"),
// (TICCrr G0, IntRegs:$rs2, condVal)>,
// Requires<[HasV9]>;

// t<cond> rs1 + rs2 => t<cond> %icc, rs1 + rs2
//def : InstAlias<!strconcat(!strconcat("t", cond), " $rs1 + $rs2"),
// (TICCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>,
// Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $rs1 + $rs2"),
(TXCCrr IntRegs:$rs1, IntRegs:$rs2, condVal)>,
Requires<[HasV9, Is64Bit]>;

// t<cond> %icc, imm => t<cond> %icc, G0 + imm
def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $imm"),
(TICCri G0, i32imm:$imm, condVal)>,
Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $imm"),
(TICCri G0, i32imm:$imm, condVal)>,
Requires<[HasV9, Is32Bit]>;

// t<cond> %icc, rs1 + imm
def : InstAlias<!strconcat(!strconcat("t", cond), " %icc, $rs1 + $imm"),
(TICCri IntRegs:$rs1, i32imm:$imm, condVal)>,
Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $rs1 + $imm"),
(TICCri IntRegs:$rs1, i32imm:$imm, condVal)>,
Requires<[HasV9, Is32Bit]>;

// t<cond> %xcc, imm => t<cond> %xcc, G0 + imm
def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $imm"),
(TXCCri G0, i32imm:$imm, condVal)>,
Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $imm"),
(TXCCri G0, i32imm:$imm, condVal)>,
Requires<[HasV9, Is64Bit]>;

// t<cond> %xcc, rs1 + imm
def : InstAlias<!strconcat(!strconcat("t", cond), " %xcc, $rs1 + $imm"),
(TXCCri IntRegs:$rs1, i32imm:$imm, condVal)>,
Requires<[HasV9]>;
def : InstAlias<!strconcat(!strconcat("t", cond), " %ncc, $rs1 + $imm"),
(TXCCri IntRegs:$rs1, i32imm:$imm, condVal)>,
Requires<[HasV9, Is64Bit]>;

// t<cond> imm => t<cond> G0 + imm
def : InstAlias<!strconcat(!strconcat("t", cond), " $imm"),
Expand Down Expand Up @@ -599,7 +653,8 @@ def : InstAlias<"clrh [$addr]", (STHrr MEMrr:$addr, G0), 0>;
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)>;
Expand Down Expand Up @@ -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)>;
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/Sparc/SparcInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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)>;
Expand Down
8 changes: 7 additions & 1 deletion llvm/lib/Target/Sparc/SparcSubtarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
42 changes: 42 additions & 0 deletions llvm/test/MC/Sparc/sparc-natural-instructions.s
Original file line number Diff line number Diff line change
@@ -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
Comment on lines +38 to +42
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking as WIP because I'm kinda lost with how to implement %ncc handling.
I tried following the other conditional instructions parsing in SparcInstrAliases.td but seems like I can't get it to work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arsenm this is what makes it fail.
I tried adding the bits for %ncc in SparcInstrAliases.td (e.g here and here) but it seems to still not be able to recognize it. Any ideas how I should implement it?

Loading