diff --git a/llvm/lib/Target/PowerPC/P10InstrResources.td b/llvm/lib/Target/PowerPC/P10InstrResources.td index 91c23622c99cd..d9eeb66d6c217 100644 --- a/llvm/lib/Target/PowerPC/P10InstrResources.td +++ b/llvm/lib/Target/PowerPC/P10InstrResources.td @@ -310,7 +310,7 @@ def : InstRW<[P10W_BF_7C, P10W_DISP_EVEN, P10W_FX_3C, P10W_DISP_ANY], // 2 Cycles Branch operations, 1 input operands def : InstRW<[P10W_BR_2C, P10W_DISP_ANY, P10BR_Read], (instrs - B, BCC, BCCA, BCCCTR, BCCCTR8, BCCCTRL, BCCCTRL8, BCCL, BCCLA, BCCLR, BCCLRL, CTRL_DEP, TAILB, TAILB8, + B, BCC, BCCA, BCCCTR, BCCCTR8, BCCCTRL, BCCCTRL8, BCCL, BCCLA, BCCLR, BCCLRL, BCCTAR, BCCTAR8, BCCTARL, BCCTARL8, gBCTAR, gBCTARL, CTRL_DEP, TAILB, TAILB8, BA, TAILBA, TAILBA8, BCCTR, BCCTR8, BCCTR8n, BCCTRn, gBCCTR, BCCTRL, BCCTRL8, BCCTRL8n, BCCTRLn, gBCCTRL, diff --git a/llvm/lib/Target/PowerPC/P9InstrResources.td b/llvm/lib/Target/PowerPC/P9InstrResources.td index b72671eefc7fd..1e84d5b490d0a 100644 --- a/llvm/lib/Target/PowerPC/P9InstrResources.td +++ b/llvm/lib/Target/PowerPC/P9InstrResources.td @@ -1311,6 +1311,8 @@ def : InstRW<[P9_BR_2C, DISP_BR_1C], (instregex "BCCCTR(L)?(8)?$"), (instregex "BCCL(A|R|RL)?$"), (instregex "BCCTR(L)?(8)?(n)?$"), + (instregex "BCCTAR(L)?(8)?$"), + (instregex "gBCTAR(L)?$"), (instregex "BD(N)?Z(8|A|Am|Ap|m|p)?$"), (instregex "BD(N)?ZL(A|Am|Ap|R|R8|RL|RLm|RLp|Rm|Rp|m|p)?$"), (instregex "BL(_TLS|_NOP)?(_RM)?$"), diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td index 8544f51f18756..e6b501508811f 100644 --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -154,6 +154,34 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR8], hasSideEffects = 0 in { } } +// bctar8 - Branch Conditional to Target Address Register (ISA 2.07 / POWER8) +// 64-bit variant, mirrors BCCTR/BCCTR8 split. +let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, hasSideEffects = 0 in { + let Predicates = [IsISA2_07] in { + let isBranch = 1, isIndirectBranch = 1 in { + let isCodeGenOnly = 1 in { + def BCCTAR8 : XLForm_2_br<19, 560, 0, (outs), (ins (pred $BIBO, $CR):$cond), + "b${cond:cc}tar${cond:pm} ${cond:reg}", IIC_BrB, + []>, Requires<[IsPPC64]>; + } + } + } +} + +// bctarl8 - Branch Conditional Link to Target Address Register (ISA 2.07 / POWER8) +// 64-bit variant with LR8 def, mirrors BCCTRL/BCCCTRL8 split. +let isCall = 1, PPC970_Unit = 7, Defs = [LR8], hasSideEffects = 0 in { + let Predicates = [IsISA2_07] in { + let Uses = [RM] in { + let isCodeGenOnly = 1 in { + def BCCTARL8 : XLForm_2_br<19, 560, 1, (outs), (ins (pred $BIBO, $CR):$cond), + "b${cond:cc}tarl${cond:pm} ${cond:reg}", IIC_BrB, + []>, Requires<[IsPPC64]>; + } + } + } +} + let isCall = 1, PPC970_Unit = 7, Defs = [LR8, RM], hasSideEffects = 0, isCodeGenOnly = 1, Uses = [RM] in { // Convenient aliases for call instructions diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index a67da9b85aa94..d14626f19d041 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -1610,6 +1610,24 @@ let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, hasSideEffects = 0 in { "bcctr 4, $BI, 0", IIC_BrB, []>; } } + + // bctar - Branch Conditional to TAR (ISA 2.07 / POWER8) + let Predicates = [IsISA2_07] in { + let isBranch = 1, isIndirectBranch = 1 in { + let isCodeGenOnly = 1 in { + def BCCTAR : XLForm_2_br<19, 560, 0, (outs), (ins (pred $BIBO, $CR):$cond), + "b${cond:cc}tar${cond:pm} ${cond:reg}", IIC_BrB, + []>; + } + } + let isCall = 1, Defs = [LR] in { + let isCodeGenOnly = 1 in { + def BCCTARL : XLForm_2_br<19, 560, 1, (outs), (ins (pred $BIBO, $CR):$cond), + "b${cond:cc}tarl${cond:pm} ${cond:reg}", IIC_BrB, + []>; + } + } + } } // Set the float rounding mode. @@ -5210,6 +5228,18 @@ let PPC970_Unit = 7, isBranch = 1, hasSideEffects = 0 in { def gBCCTRL : XLForm_2<19, 528, 1, (outs), (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH), "bcctrl $BO, $BI, $BH", IIC_BrB, []>; + + // bctar/bctarl - Branch Conditional to TAR (ISA 2.07 / POWER8) + let Predicates = [IsISA2_07] in { + let Uses = [RM] in + def gBCTAR : XLForm_2<19, 560, 0, (outs), + (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH), + "bctar $BO, $BI, $BH", IIC_BrB, []>; + let Defs = [LR], Uses = [RM] in + def gBCTARL : XLForm_2<19, 560, 1, (outs), + (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH), + "bctarl $BO, $BI, $BH", IIC_BrB, []>; + } } multiclass BranchSimpleMnemonicAT { @@ -5229,6 +5259,10 @@ 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)>; def : InstAlias<"bcctrl $bo, $bi", (gBCCTRL u5imm:$bo, crbitrc:$bi, 0)>; +let Predicates = [IsISA2_07] in { +def : InstAlias<"bctar $bo, $bi", (gBCTAR u5imm:$bo, crbitrc:$bi, 0)>; +def : InstAlias<"bctarl $bo, $bi", (gBCTARL u5imm:$bo, crbitrc:$bi, 0)>; +} multiclass BranchSimpleMnemonic1 { def : InstAlias<"b"#name#pm#" $bi, $dst", (gBC bo, crbitrc:$bi, condbrtarget:$dst)>; @@ -5242,6 +5276,10 @@ multiclass BranchSimpleMnemonic2 : BranchSimpleMnemonic1 { def : InstAlias<"b"#name#"ctr"#pm#" $bi", (gBCCTR bo, crbitrc:$bi, 0)>; def : InstAlias<"b"#name#"ctrl"#pm#" $bi", (gBCCTRL bo, crbitrc:$bi, 0)>; + let Predicates = [IsISA2_07] in { + def : InstAlias<"b"#name#"tar"#pm#" $bi", (gBCTAR bo, crbitrc:$bi, 0)>; + def : InstAlias<"b"#name#"tarl"#pm#" $bi", (gBCTARL bo, crbitrc:$bi, 0)>; + } } defm : BranchSimpleMnemonic2<"t", "", 12>; defm : BranchSimpleMnemonic2<"f", "", 4>; @@ -5254,6 +5292,22 @@ defm : BranchSimpleMnemonic1<"dnzf", "", 0>; defm : BranchSimpleMnemonic1<"dzt", "", 10>; defm : BranchSimpleMnemonic1<"dzf", "", 2>; +// bdnztar/bdztar - Branch Decrement CTR to TAR (ISA 2.07) +let Predicates = [IsISA2_07] in { +def : InstAlias<"bdnztar", (gBCTAR 16, CR0LT, 0)>; +def : InstAlias<"bdnztar+", (gBCTAR 25, CR0LT, 0)>; +def : InstAlias<"bdnztar-", (gBCTAR 24, CR0LT, 0)>; +def : InstAlias<"bdnztarl", (gBCTARL 16, CR0LT, 0)>; +def : InstAlias<"bdnztarl+", (gBCTARL 25, CR0LT, 0)>; +def : InstAlias<"bdnztarl-", (gBCTARL 24, CR0LT, 0)>; +def : InstAlias<"bdztar", (gBCTAR 18, CR0LT, 0)>; +def : InstAlias<"bdztar+", (gBCTAR 27, CR0LT, 0)>; +def : InstAlias<"bdztar-", (gBCTAR 26, CR0LT, 0)>; +def : InstAlias<"bdztarl", (gBCTARL 18, CR0LT, 0)>; +def : InstAlias<"bdztarl+", (gBCTARL 27, CR0LT, 0)>; +def : InstAlias<"bdztarl-", (gBCTARL 26, CR0LT, 0)>; +} + multiclass BranchExtendedMnemonicPM { def : InstAlias<"b"#name#pm#" $cc, $dst", (BCC (pred bibo, crrc:$cc), condbrtarget:$dst)>; @@ -5294,6 +5348,18 @@ multiclass BranchExtendedMnemonicPM { (BCCCTRL (pred bibo, crrc:$cc))>; def : InstAlias<"b"#name#"ctrl"#pm, (BCCCTRL (pred bibo, CR0))>; + + let Predicates = [IsISA2_07] in { + def : InstAlias<"b"#name#"tar"#pm#" $cc", + (BCCTAR (pred bibo, crrc:$cc))>; + def : InstAlias<"b"#name#"tar"#pm, + (BCCTAR (pred bibo, CR0))>; + + def : InstAlias<"b"#name#"tarl"#pm#" $cc", + (BCCTARL (pred bibo, crrc:$cc))>; + def : InstAlias<"b"#name#"tarl"#pm, + (BCCTARL (pred bibo, CR0))>; + } } multiclass BranchExtendedMnemonic { defm : BranchExtendedMnemonicPM; diff --git a/llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-bctar.txt b/llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-bctar.txt new file mode 100644 index 0000000000000..bcc23ca7ce7d5 --- /dev/null +++ b/llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-bctar.txt @@ -0,0 +1,62 @@ +# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-unknown -mcpu=pwr8 | FileCheck %s + +# ISA 2.07 (POWER8) Branch Conditional to Target Address Register. +# Paired with llvm/test/MC/PowerPC/ppc64-encoding-bctar.s +# +# The disassembler emits the generic bctar/bctarl form (BO, BI[, BH]); it does +# not reconstruct the simple or extended branch mnemonics. The BH operand is +# printed only when nonzero. Instruction bytes are in big-endian order. + +# Generic bctar / bctarl, 3-operand and 2-operand (BH == 0) forms. +# CHECK: bctar 4, 10, 3 +0x4c 0x8a 0x1c 0x60 +# CHECK: bctar 4, 10 +0x4c 0x8a 0x04 0x60 +# CHECK: bctarl 4, 10, 3 +0x4c 0x8a 0x1c 0x61 +# CHECK: bctarl 4, 10 +0x4c 0x8a 0x04 0x61 + +# BO encodings assembled from the bttar / bftar simple mnemonics. +# CHECK: bctar 12, 2 +0x4d 0x82 0x04 0x60 +# CHECK: bctar 4, 2 +0x4c 0x82 0x04 0x60 +# CHECK: bctarl 12, 2 +0x4d 0x82 0x04 0x61 +# CHECK: bctarl 4, 2 +0x4c 0x82 0x04 0x61 + +# Prediction-hint BO values decode to plain bctar BO, BI. +# CHECK: bctar 15, 2 +0x4d 0xe2 0x04 0x60 +# CHECK: bctar 14, 2 +0x4d 0xc2 0x04 0x60 +# CHECK: bctar 7, 2 +0x4c 0xe2 0x04 0x60 +# CHECK: bctar 6, 2 +0x4c 0xc2 0x04 0x60 + +# Condition-bit BI values assembled from blttar / bgttar / beqtar. +# CHECK: bctar 12, 0 +0x4d 0x80 0x04 0x60 +# CHECK: bctar 12, 8 +0x4d 0x88 0x04 0x60 +# CHECK: bctarl 12, 0 +0x4d 0x80 0x04 0x61 +# CHECK: bctarl 12, 8 +0x4d 0x88 0x04 0x61 +# CHECK: bctar 12, 9 +0x4d 0x89 0x04 0x60 +# CHECK: bctar 12, 10 +0x4d 0x8a 0x04 0x60 + +# bdnztar / bdztar decode as generic bctar/bctarl with BO={16,18}, BI=0. +# CHECK: bctar 16, 0 +0x4e 0x00 0x04 0x60 +# CHECK: bctar 18, 0 +0x4e 0x40 0x04 0x60 +# CHECK: bctarl 16, 0 +0x4e 0x00 0x04 0x61 +# CHECK: bctarl 18, 0 +0x4e 0x40 0x04 0x61 diff --git a/llvm/test/MC/PowerPC/ppc64-encoding-bctar.s b/llvm/test/MC/PowerPC/ppc64-encoding-bctar.s new file mode 100644 index 0000000000000..05117763be4ef --- /dev/null +++ b/llvm/test/MC/PowerPC/ppc64-encoding-bctar.s @@ -0,0 +1,111 @@ +# RUN: llvm-mc -triple powerpc64-unknown-linux-gnu -mcpu=pwr8 -show-encoding %s | \ +# RUN: FileCheck -check-prefix=CHECK-BE %s +# RUN: llvm-mc -triple powerpc64le-unknown-linux-gnu -mcpu=pwr8 -show-encoding %s | \ +# RUN: FileCheck -check-prefix=CHECK-LE %s + +# ISA 2.07 (POWER8) Branch Conditional to Target Address Register + +# bctar (generic form, 3-operand) +# CHECK-BE: bctar 4, 10, 3 # encoding: [0x4c,0x8a,0x1c,0x60] +# CHECK-LE: bctar 4, 10, 3 # encoding: [0x60,0x1c,0x8a,0x4c] + bctar 4, 10, 3 +# CHECK-BE: bctar 4, 10 # encoding: [0x4c,0x8a,0x04,0x60] +# CHECK-LE: bctar 4, 10 # encoding: [0x60,0x04,0x8a,0x4c] + bctar 4, 10 +# CHECK-BE: bctarl 4, 10, 3 # encoding: [0x4c,0x8a,0x1c,0x61] +# CHECK-LE: bctarl 4, 10, 3 # encoding: [0x61,0x1c,0x8a,0x4c] + bctarl 4, 10, 3 +# CHECK-BE: bctarl 4, 10 # encoding: [0x4c,0x8a,0x04,0x61] +# CHECK-LE: bctarl 4, 10 # encoding: [0x61,0x04,0x8a,0x4c] + bctarl 4, 10 + +# bttar/bftar (simple mnemonics print as generic bctar) +# CHECK-BE: bctar 12, 2 # encoding: [0x4d,0x82,0x04,0x60] +# CHECK-LE: bctar 12, 2 # encoding: [0x60,0x04,0x82,0x4d] + bttar 2 +# CHECK-BE: bctar 4, 2 # encoding: [0x4c,0x82,0x04,0x60] +# CHECK-LE: bctar 4, 2 # encoding: [0x60,0x04,0x82,0x4c] + bftar 2 +# CHECK-BE: bctarl 12, 2 # encoding: [0x4d,0x82,0x04,0x61] +# CHECK-LE: bctarl 12, 2 # encoding: [0x61,0x04,0x82,0x4d] + bttarl 2 +# CHECK-BE: bctarl 4, 2 # encoding: [0x4c,0x82,0x04,0x61] +# CHECK-LE: bctarl 4, 2 # encoding: [0x61,0x04,0x82,0x4c] + bftarl 2 + +# bttar/bftar with prediction hints +# CHECK-BE: bctar 15, 2 # encoding: [0x4d,0xe2,0x04,0x60] +# CHECK-LE: bctar 15, 2 # encoding: [0x60,0x04,0xe2,0x4d] + bttar+ 2 +# CHECK-BE: bctar 14, 2 # encoding: [0x4d,0xc2,0x04,0x60] +# CHECK-LE: bctar 14, 2 # encoding: [0x60,0x04,0xc2,0x4d] + bttar- 2 +# CHECK-BE: bctar 7, 2 # encoding: [0x4c,0xe2,0x04,0x60] +# CHECK-LE: bctar 7, 2 # encoding: [0x60,0x04,0xe2,0x4c] + bftar+ 2 +# CHECK-BE: bctar 6, 2 # encoding: [0x4c,0xc2,0x04,0x60] +# CHECK-LE: bctar 6, 2 # encoding: [0x60,0x04,0xc2,0x4c] + bftar- 2 + +# Extended mnemonics (blttar, bgttar, etc.) +# CHECK-BE: blttar 0 # encoding: [0x4d,0x80,0x04,0x60] +# CHECK-LE: blttar 0 # encoding: [0x60,0x04,0x80,0x4d] + blttar +# CHECK-BE: blttar 2 # encoding: [0x4d,0x88,0x04,0x60] +# CHECK-LE: blttar 2 # encoding: [0x60,0x04,0x88,0x4d] + blttar 2 +# CHECK-BE: blttarl 0 # encoding: [0x4d,0x80,0x04,0x61] +# CHECK-LE: blttarl 0 # encoding: [0x61,0x04,0x80,0x4d] + blttarl +# CHECK-BE: blttarl 2 # encoding: [0x4d,0x88,0x04,0x61] +# CHECK-LE: blttarl 2 # encoding: [0x61,0x04,0x88,0x4d] + blttarl 2 + +# CHECK-BE: bgttar 2 # encoding: [0x4d,0x89,0x04,0x60] +# CHECK-LE: bgttar 2 # encoding: [0x60,0x04,0x89,0x4d] + bgttar 2 +# CHECK-BE: beqtar 2 # encoding: [0x4d,0x8a,0x04,0x60] +# CHECK-LE: beqtar 2 # encoding: [0x60,0x04,0x8a,0x4d] + beqtar 2 + +# Extended mnemonics with prediction hints +# CHECK-BE: blttar+ 0 # encoding: [0x4d,0xe0,0x04,0x60] +# CHECK-LE: blttar+ 0 # encoding: [0x60,0x04,0xe0,0x4d] + blttar+ +# CHECK-BE: blttar- 0 # encoding: [0x4d,0xc0,0x04,0x60] +# CHECK-LE: blttar- 0 # encoding: [0x60,0x04,0xc0,0x4d] + blttar- +# CHECK-BE: blttarl+ 0 # encoding: [0x4d,0xe0,0x04,0x61] +# CHECK-LE: blttarl+ 0 # encoding: [0x61,0x04,0xe0,0x4d] + blttarl+ +# CHECK-BE: blttarl- 0 # encoding: [0x4d,0xc0,0x04,0x61] +# CHECK-LE: blttarl- 0 # encoding: [0x61,0x04,0xc0,0x4d] + blttarl- + +# bdnztar/bdztar +# CHECK-BE: bctar 16, 0 # encoding: [0x4e,0x00,0x04,0x60] +# CHECK-LE: bctar 16, 0 # encoding: [0x60,0x04,0x00,0x4e] + bdnztar +# CHECK-BE: bctar 18, 0 # encoding: [0x4e,0x40,0x04,0x60] +# CHECK-LE: bctar 18, 0 # encoding: [0x60,0x04,0x40,0x4e] + bdztar +# CHECK-BE: bctarl 16, 0 # encoding: [0x4e,0x00,0x04,0x61] +# CHECK-LE: bctarl 16, 0 # encoding: [0x61,0x04,0x00,0x4e] + bdnztarl +# CHECK-BE: bctarl 18, 0 # encoding: [0x4e,0x40,0x04,0x61] +# CHECK-LE: bctarl 18, 0 # encoding: [0x61,0x04,0x40,0x4e] + bdztarl + +# bdnztar/bdztar with prediction hints +# CHECK-BE: bctar 25, 0 # encoding: [0x4f,0x20,0x04,0x60] +# CHECK-LE: bctar 25, 0 # encoding: [0x60,0x04,0x20,0x4f] + bdnztar+ +# CHECK-BE: bctar 24, 0 # encoding: [0x4f,0x00,0x04,0x60] +# CHECK-LE: bctar 24, 0 # encoding: [0x60,0x04,0x00,0x4f] + bdnztar- +# CHECK-BE: bctar 27, 0 # encoding: [0x4f,0x60,0x04,0x60] +# CHECK-LE: bctar 27, 0 # encoding: [0x60,0x04,0x60,0x4f] + bdztar+ +# CHECK-BE: bctar 26, 0 # encoding: [0x4f,0x40,0x04,0x60] +# CHECK-LE: bctar 26, 0 # encoding: [0x60,0x04,0x40,0x4f] + bdztar-