summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc
diff options
context:
space:
mode:
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-03-01 22:03:07 +0000
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>2014-03-01 22:03:07 +0000
commitc86e0f38739eef5302e2c5d9dea16f4c4dca3134 (patch)
treeed0ab474e7b81e8fd24d75e125c973496b6467fe /llvm/lib/Target/Sparc
parent2430958182b84df0ebcb502e02bd6978cfecc55c (diff)
downloadbcm5719-llvm-c86e0f38739eef5302e2c5d9dea16f4c4dca3134.tar.gz
bcm5719-llvm-c86e0f38739eef5302e2c5d9dea16f4c4dca3134.zip
[SparcV9] Add support for parsing branch instructions with prediction.
llvm-svn: 202602
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r--llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp4
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp22
-rw-r--r--llvm/lib/Target/Sparc/SparcCodeEmitter.cpp8
-rw-r--r--llvm/lib/Target/Sparc/SparcInstr64Bit.td14
-rw-r--r--llvm/lib/Target/Sparc/SparcInstrAliases.td71
-rw-r--r--llvm/lib/Target/Sparc/SparcInstrFormats.td14
-rw-r--r--llvm/lib/Target/Sparc/SparcInstrInfo.td67
7 files changed, 156 insertions, 44 deletions
diff --git a/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
index 41db5798724..f887b945a36 100644
--- a/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
+++ b/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
@@ -118,6 +118,10 @@ void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum,
default: break;
case SP::FBCOND:
case SP::FBCONDA:
+ case SP::BPFCC:
+ case SP::BPFCCA:
+ case SP::BPFCCNT:
+ case SP::BPFCCANT:
case SP::MOVFCCrr:
case SP::MOVFCCri:
case SP::FMOVS_FCC:
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index 16310d50243..96665ef2454 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -61,7 +61,9 @@ public:
unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
-
+ unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
};
} // end anonymous namespace
@@ -173,13 +175,23 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
if (MO.isReg() || MO.isImm())
return getMachineOpValue(MI, MO, Fixups, STI);
- Sparc::Fixups fixup = Sparc::fixup_sparc_br22;
- if (MI.getOpcode() == SP::BPXCC)
- fixup = Sparc::fixup_sparc_br19;
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+ (MCFixupKind)Sparc::fixup_sparc_br22));
+ return 0;
+}
+
+unsigned SparcMCCodeEmitter::
+getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups, STI);
Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
- (MCFixupKind)fixup));
+ (MCFixupKind)Sparc::fixup_sparc_br19));
return 0;
}
+
#include "SparcGenMCCodeEmitter.inc"
diff --git a/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp b/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp
index b7b2182fc21..6b5e4bf0f5b 100644
--- a/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/SparcCodeEmitter.cpp
@@ -76,6 +76,8 @@ private:
unsigned) const;
unsigned getBranchTargetOpValue(const MachineInstr &MI,
unsigned) const;
+ unsigned getBranchPredTargetOpValue(const MachineInstr &MI,
+ unsigned) const;
void emitWord(unsigned Word);
@@ -198,6 +200,12 @@ unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
return getMachineOpValue(MI, MO);
}
+unsigned SparcCodeEmitter::getBranchPredTargetOpValue(const MachineInstr &MI,
+ unsigned opIdx) const {
+ const MachineOperand MO = MI.getOperand(opIdx);
+ return getMachineOpValue(MI, MO);
+}
+
unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI,
const MachineOperand &MO) const {
diff --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td
index 77b394dd7c9..9807c8d9217 100644
--- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td
+++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td
@@ -297,14 +297,6 @@ def : Pat<(store (i64 0), ADDRri:$dst), (STXri ADDRri:$dst, (i64 G0))>;
// 64-bit Conditionals.
//===----------------------------------------------------------------------===//
-// Conditional branch class on %xcc:
-class XBranchSP<dag ins, string asmstr, list<dag> pattern>
- : F2_3<0b001, 0b10, (outs), ins, asmstr, pattern> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
-}
-
//
// Flag-setting instructions like subcc and addcc set both icc and xcc flags.
// The icc flags correspond to the 32-bit result, and the xcc are for the
@@ -315,10 +307,8 @@ class XBranchSP<dag ins, string asmstr, list<dag> pattern>
let Predicates = [Is64Bit] in {
-let Uses = [ICC] in
-def BPXCC : XBranchSP<(ins brtarget:$imm19, CCOp:$cond),
- "b$cond %xcc, $imm19",
- [(SPbrxcc bb:$imm19, imm:$cond)]>;
+let Uses = [ICC], cc = 0b10 in
+ defm BPX : IPredBranch<"%xcc", [(SPbrxcc bb:$imm19, imm:$cond)]>;
// Conditional moves on %xcc.
let Uses = [ICC], Constraints = "$f = $rd" in {
diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index cee1c04a05c..2fc6b7120f8 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -50,10 +50,55 @@ multiclass int_cond_alias<string cond, int condVal> {
def : InstAlias<!strconcat(!strconcat("b", cond), ",a $imm"),
(BCONDA brtarget:$imm, condVal)>;
+ // b<cond> %icc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), " %icc, $imm"),
+ (BPICC brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // b<cond>,pt %icc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",pt %icc, $imm"),
+ (BPICC brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // b<cond>,a %icc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",a %icc, $imm"),
+ (BPICCA brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // b<cond>,a,pt %icc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pt %icc, $imm"),
+ (BPICCA brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // b<cond>,pn %icc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %icc, $imm"),
+ (BPICCNT brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // b<cond>,a,pn %icc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",a,pn %icc, $imm"),
+ (BPICCANT brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
// b<cond> %xcc, $imm
def : InstAlias<!strconcat(!strconcat("b", cond), " %xcc, $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]>;
+
+ // b<cond>,a %xcc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",a %xcc, $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]>;
+
+ // b<cond>,pn %xcc, $imm
+ def : InstAlias<!strconcat(!strconcat("b", cond), ",pn %xcc, $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]>;
+
+
defm : cond_mov_alias<cond, condVal, " %icc",
MOVICCrr, MOVICCri,
FMOVS_ICC, FMOVD_ICC>, Requires<[HasV9]>;
@@ -84,6 +129,30 @@ multiclass fp_cond_alias<string cond, int condVal> {
def : InstAlias<!strconcat(!strconcat("fb", cond), ",a $imm"),
(FBCONDA brtarget:$imm, condVal), 0>;
+ // fb<cond> %fcc0, $imm
+ def : InstAlias<!strconcat(!strconcat("fb", cond), " %fcc0, $imm"),
+ (BPFCC brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // fb<cond>,pt %fcc0, $imm
+ def : InstAlias<!strconcat(!strconcat("fb", cond), ",pt %fcc0, $imm"),
+ (BPFCC brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // fb<cond>,a %fcc0, $imm
+ def : InstAlias<!strconcat(!strconcat("fb", cond), ",a %fcc0, $imm"),
+ (BPFCCA brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // fb<cond>,a,pt %fcc0, $imm
+ def : InstAlias<!strconcat(!strconcat("fb", cond), ",a,pt %fcc0, $imm"),
+ (BPFCCA brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // fb<cond>,pn %fcc0, $imm
+ def : InstAlias<!strconcat(!strconcat("fb", cond), ",pn %fcc0, $imm"),
+ (BPFCCNT brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
+ // fb<cond>,a,pn %fcc0, $imm
+ def : InstAlias<!strconcat(!strconcat("fb", cond), ",a,pn %fcc0, $imm"),
+ (BPFCCANT brtarget:$imm, condVal)>, Requires<[HasV9]>;
+
defm : cond_mov_alias<cond, condVal, " %fcc0",
MOVFCCrr, MOVFCCri,
FMOVS_FCC, FMOVD_FCC>, Requires<[HasV9]>;
@@ -111,6 +180,8 @@ defm : int_cond_alias<"neg", 0b0110>;
defm : int_cond_alias<"vc", 0b1111>;
defm : int_cond_alias<"vs", 0b0111>;
+defm : fp_cond_alias<"a", 0b0000>;
+defm : fp_cond_alias<"n", 0b1000>;
defm : fp_cond_alias<"u", 0b0111>;
defm : fp_cond_alias<"g", 0b0110>;
defm : fp_cond_alias<"ug", 0b0101>;
diff --git a/llvm/lib/Target/Sparc/SparcInstrFormats.td b/llvm/lib/Target/Sparc/SparcInstrFormats.td
index 97b6498c947..761ff15d04f 100644
--- a/llvm/lib/Target/Sparc/SparcInstrFormats.td
+++ b/llvm/lib/Target/Sparc/SparcInstrFormats.td
@@ -60,23 +60,19 @@ class F2_2<bits<3> op2Val, bit annul, dag outs, dag ins, string asmstr,
let Inst{28-25} = cond;
}
-class F2_3<bits<3> op2Val, bits<2> ccVal, dag outs, dag ins, string asmstr,
- list<dag> pattern>
- : InstSP<outs, ins, asmstr, pattern> {
- bit annul;
+class F2_3<bits<3> op2Val, bit annul, bit pred,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : InstSP<outs, ins, asmstr, pattern> {
+ bits<2> cc;
bits<4> cond;
- bit pred;
bits<19> imm19;
let op = 0; // op = 0
- bit annul = 0; // currently unused
- let pred = 1; // default is predict taken
-
let Inst{29} = annul;
let Inst{28-25} = cond;
let Inst{24-22} = op2Val;
- let Inst{21-20} = ccVal;
+ let Inst{21-20} = cc;
let Inst{19} = pred;
let Inst{18-0} = imm19;
}
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index da1dfb5bde8..dec9c294766 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -105,6 +105,10 @@ def brtarget : Operand<OtherVT> {
let EncoderMethod = "getBranchTargetOpValue";
}
+def bprtarget : Operand<OtherVT> {
+ let EncoderMethod = "getBranchPredTargetOpValue";
+}
+
def calltarget : Operand<i32> {
let EncoderMethod = "getCallTargetOpValue";
let DecoderMethod = "DecodeCall";
@@ -562,22 +566,36 @@ class BranchAlways<dag ins, string asmstr, list<dag> pattern>
let cond = 8 in
def BA : BranchAlways<(ins brtarget:$imm22), "ba $imm22", [(br bb:$imm22)]>;
+
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in {
+
// conditional branch class:
class BranchSP<dag ins, string asmstr, list<dag> pattern>
- : F2_2<0b010, 0, (outs), ins, asmstr, pattern> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
-}
+ : F2_2<0b010, 0, (outs), ins, asmstr, pattern>;
// conditional branch with annul class:
class BranchSPA<dag ins, string asmstr, list<dag> pattern>
- : F2_2<0b010, 1, (outs), ins, asmstr, pattern> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
+ : F2_2<0b010, 1, (outs), ins, asmstr, pattern>;
+
+// Conditional branch class on %icc|%xcc with predication:
+multiclass IPredBranch<string regstr, list<dag> CCPattern> {
+ def CC : F2_3<0b001, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ !strconcat("b$cond ", !strconcat(regstr, ", $imm19")),
+ CCPattern>;
+ def CCA : F2_3<0b001, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ !strconcat("b$cond,a ", !strconcat(regstr, ", $imm19")),
+ []>;
+ def CCNT : F2_3<0b001, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ !strconcat("b$cond,pn ", !strconcat(regstr, ", $imm19")),
+ []>;
+ def CCANT : F2_3<0b001, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ !strconcat("b$cond,a,pn ", !strconcat(regstr, ", $imm19")),
+ []>;
}
+} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1
+
+
// Indirect branch instructions.
let isTerminator = 1, isBarrier = 1, hasDelaySlot = 1, isBranch =1,
isIndirectBranch = 1, rd = 0, isCodeGenOnly = 1 in {
@@ -597,25 +615,35 @@ let Uses = [ICC] in {
[(SPbricc bb:$imm22, imm:$cond)]>;
def BCONDA : BranchSPA<(ins brtarget:$imm22, CCOp:$cond),
"b$cond,a $imm22", []>;
+
+ let Predicates = [HasV9], cc = 0b00 in
+ defm BPI : IPredBranch<"%icc", []>;
}
// Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in {
+
// floating-point conditional branch class:
class FPBranchSP<dag ins, string asmstr, list<dag> pattern>
- : F2_2<0b110, 0, (outs), ins, asmstr, pattern> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
-}
+ : F2_2<0b110, 0, (outs), ins, asmstr, pattern>;
// floating-point conditional branch with annul class:
class FPBranchSPA<dag ins, string asmstr, list<dag> pattern>
- : F2_2<0b110, 1, (outs), ins, asmstr, pattern> {
- let isBranch = 1;
- let isTerminator = 1;
- let hasDelaySlot = 1;
+ : F2_2<0b110, 1, (outs), ins, asmstr, pattern>;
+
+// Conditional branch class on %fcc0-%fcc3 with predication:
+multiclass FPredBranch {
+ def CC : F2_3<0b101, 0, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ "fb$cond %fcc0, $imm19", []>;
+ def CCA : F2_3<0b101, 1, 1, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ "fb$cond,a %fcc0, $imm19", []>;
+ def CCNT : F2_3<0b101, 0, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ "fb$cond,pn %fcc0, $imm19", []>;
+ def CCANT : F2_3<0b101, 1, 0, (outs), (ins bprtarget:$imm19, CCOp:$cond),
+ "fb$cond,a,pn %fcc0, $imm19", []>;
}
+} // let isBranch = 1, isTerminator = 1, hasDelaySlot = 1
let Uses = [FCC] in {
def FBCOND : FPBranchSP<(ins brtarget:$imm22, CCOp:$cond),
@@ -623,6 +651,9 @@ let Uses = [FCC] in {
[(SPbrfcc bb:$imm22, imm:$cond)]>;
def FBCONDA : FPBranchSPA<(ins brtarget:$imm22, CCOp:$cond),
"fb$cond,a $imm22", []>;
+
+ let Predicates = [HasV9], cc = 0b00 in
+ defm BPF : FPredBranch;
}
// Section B.24 - Call and Link Instruction, p. 125
OpenPOWER on IntegriCloud