summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp1
-rw-r--r--llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp9
-rw-r--r--llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h1
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrFormats.td16
-rw-r--r--llvm/lib/Target/PowerPC/PPCInstrInfo.td43
-rw-r--r--llvm/test/MC/PowerPC/ppc64-encoding.s41
6 files changed, 111 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index c7a871dd791..1bd4c27302a 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -545,6 +545,7 @@ public:
&& isUInt<5>(getImm())); }
bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
isPowerOf2_32(getImm()); }
+ bool isATBitsAsHint() const { return false; }
bool isMem() const override { return false; }
bool isReg() const override { return false; }
diff --git a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
index d1c4b59e559..61ad5705329 100644
--- a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp
@@ -258,6 +258,15 @@ void PPCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
printOperand(MI, OpNo+1, O);
}
+void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
+ raw_ostream &O) {
+ unsigned Code = MI->getOperand(OpNo).getImm();
+ if (Code == 2)
+ O << "-";
+ else if (Code == 3)
+ O << "+";
+}
+
void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
diff --git a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
index d0ffeff0247..9c79ffb1176 100644
--- a/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
+++ b/llvm/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.h
@@ -45,6 +45,7 @@ public:
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printPredicateOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier = nullptr);
+ void printATBitsAsHint(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printU1ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printU2ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFormats.td b/llvm/lib/Target/PowerPC/PPCInstrFormats.td
index dfbf80690d2..163c5d0eb87 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFormats.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFormats.td
@@ -163,6 +163,22 @@ class BForm_3<bits<6> opcode, bit aa, bit lk,
let Inst{31} = lk;
}
+class BForm_3_at<bits<6> opcode, bit aa, bit lk,
+ dag OOL, dag IOL, string asmstr>
+ : I<opcode, OOL, IOL, asmstr, IIC_BrB> {
+ bits<5> BO;
+ bits<2> at;
+ bits<5> BI;
+ bits<14> BD;
+
+ let Inst{6-8} = BO{4-2};
+ let Inst{9-10} = at;
+ let Inst{11-15} = BI;
+ let Inst{16-29} = BD;
+ let Inst{30} = aa;
+ let Inst{31} = lk;
+}
+
class BForm_4<bits<6> opcode, bits<5> bo, bit aa, bit lk,
dag OOL, dag IOL, string asmstr>
: I<opcode, OOL, IOL, asmstr, IIC_BrB> {
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 4edfe943df3..7939bc8482f 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -478,6 +478,15 @@ def u2imm : Operand<i32> {
let ParserMatchClass = PPCU2ImmAsmOperand;
}
+def PPCATBitsAsHintAsmOperand : AsmOperandClass {
+ let Name = "ATBitsAsHint"; let PredicateMethod = "isATBitsAsHint";
+ let RenderMethod = "addImmOperands"; // Irrelevant, predicate always fails.
+}
+def atimm : Operand<i32> {
+ let PrintMethod = "printATBitsAsHint";
+ let ParserMatchClass = PPCATBitsAsHintAsmOperand;
+}
+
def PPCU3ImmAsmOperand : AsmOperandClass {
let Name = "U3Imm"; let PredicateMethod = "isU3Imm";
let RenderMethod = "addImmOperands";
@@ -4134,6 +4143,16 @@ let PPC970_Unit = 7 in {
def gBCA : BForm_3<16, 1, 0, (outs),
(ins u5imm:$bo, crbitrc:$bi, abscondbrtarget:$dst),
"bca $bo, $bi, $dst">;
+ let isAsmParserOnly = 1 in {
+ def gBCat : BForm_3_at<16, 0, 0, (outs),
+ (ins u5imm:$bo, atimm:$at, crbitrc:$bi,
+ condbrtarget:$dst),
+ "bc$at $bo, $bi, $dst">;
+ def gBCAat : BForm_3_at<16, 1, 0, (outs),
+ (ins u5imm:$bo, atimm:$at, crbitrc:$bi,
+ abscondbrtarget:$dst),
+ "bca$at $bo, $bi, $dst">;
+ } // isAsmParserOnly = 1
}
let Defs = [LR, CTR], Uses = [CTR, RM] in {
def gBCL : BForm_3<16, 0, 1, (outs),
@@ -4142,6 +4161,16 @@ let PPC970_Unit = 7 in {
def gBCLA : BForm_3<16, 1, 1, (outs),
(ins u5imm:$bo, crbitrc:$bi, abscondbrtarget:$dst),
"bcla $bo, $bi, $dst">;
+ let isAsmParserOnly = 1 in {
+ def gBCLat : BForm_3_at<16, 0, 1, (outs),
+ (ins u5imm:$bo, atimm:$at, crbitrc:$bi,
+ condbrtarget:$dst),
+ "bcl$at $bo, $bi, $dst">;
+ def gBCLAat : BForm_3_at<16, 1, 1, (outs),
+ (ins u5imm:$bo, atimm:$at, crbitrc:$bi,
+ abscondbrtarget:$dst),
+ "bcla$at $bo, $bi, $dst">;
+ } // // isAsmParserOnly = 1
}
let Defs = [CTR], Uses = [CTR, LR, RM] in
def gBCLR : XLForm_2<19, 16, 0, (outs),
@@ -4160,6 +4189,20 @@ let PPC970_Unit = 7 in {
(ins u5imm:$bo, crbitrc:$bi, i32imm:$bh),
"bcctrl $bo, $bi, $bh", IIC_BrB, []>;
}
+
+multiclass BranchSimpleMnemonicAT<string pm, int at> {
+ def : InstAlias<"bc"#pm#" $bo, $bi, $dst", (gBCat u5imm:$bo, at, crbitrc:$bi,
+ condbrtarget:$dst)>;
+ def : InstAlias<"bca"#pm#" $bo, $bi, $dst", (gBCAat u5imm:$bo, at, crbitrc:$bi,
+ condbrtarget:$dst)>;
+ def : InstAlias<"bcl"#pm#" $bo, $bi, $dst", (gBCLat u5imm:$bo, at, crbitrc:$bi,
+ condbrtarget:$dst)>;
+ def : InstAlias<"bcla"#pm#" $bo, $bi, $dst", (gBCLAat u5imm:$bo, at, crbitrc:$bi,
+ condbrtarget:$dst)>;
+}
+defm : BranchSimpleMnemonicAT<"+", 3>;
+defm : BranchSimpleMnemonicAT<"-", 2>;
+
def : InstAlias<"bclr $bo, $bi", (gBCLR u5imm:$bo, crbitrc:$bi, 0)>;
def : InstAlias<"bclrl $bo, $bi", (gBCLRL u5imm:$bo, crbitrc:$bi, 0)>;
def : InstAlias<"bcctr $bo, $bi", (gBCCTR u5imm:$bo, crbitrc:$bi, 0)>;
diff --git a/llvm/test/MC/PowerPC/ppc64-encoding.s b/llvm/test/MC/PowerPC/ppc64-encoding.s
index 70c2e949deb..a772ca44986 100644
--- a/llvm/test/MC/PowerPC/ppc64-encoding.s
+++ b/llvm/test/MC/PowerPC/ppc64-encoding.s
@@ -48,6 +48,47 @@
# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
bcla 4, 10, target
+# CHECK-BE: bc+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA00]
+# CHECK-LE: bc+ 12, 28, target # encoding: [0bAAAAAA00,A,0xfc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+ bc+ 12, 28, target
+# CHECK-BE: bc- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA00]
+# CHECK-LE: bc- 12, 28, target # encoding: [0bAAAAAA00,A,0xdc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+ bc- 12, 28, target
+# CHECK-BE: bca+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA10]
+# CHECK-LE: bca+ 12, 28, target # encoding: [0bAAAAAA10,A,0xfc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+ bca+ 12, 28, target
+# CHECK-BE: bca- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA10]
+# CHECK-LE: bca- 12, 28, target # encoding: [0bAAAAAA10,A,0xdc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+ bca- 12, 28, target
+# CHECK-BE: bcl+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA01]
+# CHECK-LE: bcl+ 12, 28, target # encoding: [0bAAAAAA01,A,0xfc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+ bcl+ 12, 28, target
+# CHECK-BE: bcl- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA01]
+# CHECK-LE: bcl- 12, 28, target # encoding: [0bAAAAAA01,A,0xdc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14
+ bcl- 12, 28, target
+# CHECK-BE: bcla+ 12, 28, target # encoding: [0x41,0xfc,A,0bAAAAAA11]
+# CHECK-LE: bcla+ 12, 28, target # encoding: [0bAAAAAA11,A,0xfc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+ bcla+ 12, 28, target
+# CHECK-BE: bcla- 12, 28, target # encoding: [0x41,0xdc,A,0bAAAAAA11]
+# CHECK-LE: bcla- 12, 28, target # encoding: [0bAAAAAA11,A,0xdc,0x41]
+# CHECK-BE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+# CHECK-LE-NEXT: # fixup A - offset: 0, value: target, kind: fixup_ppc_brcond14abs
+ bcla- 12, 28, target
+
# CHECK-BE: bclr 4, 10, 3 # encoding: [0x4c,0x8a,0x18,0x20]
# CHECK-LE: bclr 4, 10, 3 # encoding: [0x20,0x18,0x8a,0x4c]
bclr 4, 10, 3
OpenPOWER on IntegriCloud