[llvm] r288029 - [SystemZ] Add remaining branch instructions

Ulrich Weigand via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 28 05:40:09 PST 2016


Author: uweigand
Date: Mon Nov 28 07:40:08 2016
New Revision: 288029

URL: http://llvm.org/viewvc/llvm-project?rev=288029&view=rev
Log:
[SystemZ] Add remaining branch instructions

This patch adds assembler support for the remaining branch instructions:
the non-relative branch on count variants, and all variants of branch
on index.

The only one of those that can be readily exploited for code generation
is BRCTH (branch on count using a high 32-bit register as count).  Do
use it, however, it is necessary to also introduce a hew CHIMux pseudo
to allow comparisons of a 32-bit value agains a short immediate to go
into a high register as well (implemented via CHI/CIH).

This causes a bit of codegen changes overall, but those have proven to
be neutral (or even beneficial) in performance measurements.


Added:
    llvm/trunk/test/CodeGen/SystemZ/loop-02.ll
Modified:
    llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
    llvm/trunk/lib/Target/SystemZ/SystemZLongBranch.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ13.td
    llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ196.td
    llvm/trunk/lib/Target/SystemZ/SystemZScheduleZEC12.td
    llvm/trunk/test/MC/Disassembler/SystemZ/insns-pcrel.txt
    llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt
    llvm/trunk/test/MC/SystemZ/insn-bad-z196.s
    llvm/trunk/test/MC/SystemZ/insn-bad.s
    llvm/trunk/test/MC/SystemZ/insn-good-z196.s
    llvm/trunk/test/MC/SystemZ/insn-good.s

Modified: llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZElimCompare.cpp Mon Nov 28 07:40:08 2016
@@ -171,7 +171,7 @@ static unsigned getCompareSourceReg(Mach
 
 // Compare compares the result of MI against zero.  If MI is an addition
 // of -1 and if CCUsers is a single branch on nonzero, eliminate the addition
-// and convert the branch to a BRCT(G).  Return true on success.
+// and convert the branch to a BRCT(G) or BRCTH.  Return true on success.
 bool SystemZElimCompare::convertToBRCT(
     MachineInstr &MI, MachineInstr &Compare,
     SmallVectorImpl<MachineInstr *> &CCUsers) {
@@ -182,6 +182,8 @@ bool SystemZElimCompare::convertToBRCT(
     BRCT = SystemZ::BRCT;
   else if (Opcode == SystemZ::AGHI)
     BRCT = SystemZ::BRCTG;
+  else if (Opcode == SystemZ::AIH)
+    BRCT = SystemZ::BRCTH;
   else
     return false;
   if (MI.getOperand(2).getImm() != -1)
@@ -205,16 +207,20 @@ bool SystemZElimCompare::convertToBRCT(
     if (getRegReferences(*MBBI, SrcReg))
       return false;
 
-  // The transformation is OK.  Rebuild Branch as a BRCT(G).
+  // The transformation is OK.  Rebuild Branch as a BRCT(G) or BRCTH.
   MachineOperand Target(Branch->getOperand(2));
   while (Branch->getNumOperands())
     Branch->RemoveOperand(0);
   Branch->setDesc(TII->get(BRCT));
-  MachineInstrBuilder(*Branch->getParent()->getParent(), Branch)
-      .addOperand(MI.getOperand(0))
-      .addOperand(MI.getOperand(1))
-      .addOperand(Target)
-      .addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
+  MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch);
+  MIB.addOperand(MI.getOperand(0))
+     .addOperand(MI.getOperand(1))
+     .addOperand(Target);
+  // Add a CC def to BRCT(G), since we may have to split them again if the
+  // branch displacement overflows.  BRCTH has a 32-bit displacement, so
+  // this is not necessary there.
+  if (BRCT != SystemZ::BRCTH)
+    MIB.addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
   MI.eraseFromParent();
   return true;
 }

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrFormats.td Mon Nov 28 07:40:08 2016
@@ -291,6 +291,23 @@ class InstRIEd<bits<16> op, dag outs, da
   let Inst{7-0}   = op{7-0};
 }
 
+class InstRIEe<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
+  : InstSystemZ<6, outs, ins, asmstr, pattern> {
+  field bits<48> Inst;
+  field bits<48> SoftFail = 0;
+
+  bits<4> R1;
+  bits<4> R3;
+  bits<16> RI2;
+
+  let Inst{47-40} = op{15-8};
+  let Inst{39-36} = R1;
+  let Inst{35-32} = R3;
+  let Inst{31-16} = RI2;
+  let Inst{15-8}  = 0;
+  let Inst{7-0}   = op{7-0};
+}
+
 class InstRIEf<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
   : InstSystemZ<6, outs, ins, asmstr, pattern> {
   field bits<48> Inst;
@@ -1506,15 +1523,14 @@ class ICV<string name>
 //     compares the two input operands and branches or traps on the result.
 //
 //   BranchUnary:
-//     One register output operand, one register input operand and
-//     one branch displacement.  The instructions stores a modified
-//     form of the source register in the destination register and
-//     branches on the result.
+//     One register output operand, one register input operand and one branch
+//     target.  The instructions stores a modified form of the source register
+//     in the destination register and branches on the result.
 //
 //   BranchBinary:
 //     One register output operand, two register input operands and one branch
-//     displacement. The instructions stores a modified form of one of the
-//     source registers in the destination register and branches on the result.
+//     target. The instructions stores a modified form of one of the source
+//     registers in the destination register and branches on the result.
 //
 //   LoadMultiple:
 //     One address input operand and two explicit output operands.
@@ -1911,6 +1927,41 @@ class BranchUnaryRI<string mnemonic, bit
   let DisableEncoding = "$R1src";
 }
 
+class BranchUnaryRIL<string mnemonic, bits<12> opcode, RegisterOperand cls>
+  : InstRILb<opcode, (outs cls:$R1), (ins cls:$R1src, brtarget32:$RI2),
+             mnemonic##"\t$R1, $RI2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
+class BranchUnaryRR<string mnemonic, bits<8> opcode, RegisterOperand cls>
+  : InstRR<opcode, (outs cls:$R1), (ins cls:$R1src, GR64:$R2),
+           mnemonic##"\t$R1, $R2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
+class BranchUnaryRRE<string mnemonic, bits<16> opcode, RegisterOperand cls>
+  : InstRRE<opcode, (outs cls:$R1), (ins cls:$R1src, GR64:$R2),
+            mnemonic##"\t$R1, $R2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
+class BranchUnaryRX<string mnemonic, bits<8> opcode, RegisterOperand cls>
+  : InstRXa<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr12only:$XBD2),
+            mnemonic##"\t$R1, $XBD2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
+class BranchUnaryRXY<string mnemonic, bits<16> opcode, RegisterOperand cls>
+  : InstRXYa<opcode, (outs cls:$R1), (ins cls:$R1src, bdxaddr20only:$XBD2),
+             mnemonic##"\t$R1, $XBD2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
 class BranchBinaryRSI<string mnemonic, bits<8> opcode, RegisterOperand cls>
   : InstRSI<opcode, (outs cls:$R1), (ins cls:$R1src, cls:$R3, brtarget16:$RI2),
             mnemonic##"\t$R1, $R3, $RI2", []> {
@@ -1918,6 +1969,30 @@ class BranchBinaryRSI<string mnemonic, b
   let DisableEncoding = "$R1src";
 }
 
+class BranchBinaryRIEe<string mnemonic, bits<16> opcode, RegisterOperand cls>
+  : InstRIEe<opcode, (outs cls:$R1),
+             (ins cls:$R1src, cls:$R3, brtarget16:$RI2),
+             mnemonic##"\t$R1, $R3, $RI2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
+class BranchBinaryRS<string mnemonic, bits<8> opcode, RegisterOperand cls>
+  : InstRSa<opcode, (outs cls:$R1),
+            (ins cls:$R1src, cls:$R3, bdaddr12only:$BD2),
+            mnemonic##"\t$R1, $R3, $BD2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
+class BranchBinaryRSY<string mnemonic, bits<16> opcode, RegisterOperand cls>
+  : InstRSYa<opcode,
+             (outs cls:$R1), (ins cls:$R1src, cls:$R3, bdaddr20only:$BD2),
+             mnemonic##"\t$R1, $R3, $BD2", []> {
+  let Constraints = "$R1 = $R1src";
+  let DisableEncoding = "$R1src";
+}
+
 class LoadMultipleRS<string mnemonic, bits<8> opcode, RegisterOperand cls,
                      AddressingMode mode = bdaddr12only>
   : InstRSa<opcode, (outs cls:$R1, cls:$R3), (ins mode:$BD2),
@@ -3639,7 +3714,9 @@ multiclass BinaryRIAndKPseudo<string key
 // Like CompareRI, but expanded after RA depending on the choice of register.
 class CompareRIPseudo<SDPatternOperator operator, RegisterOperand cls,
                       Immediate imm>
-  : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]>;
+  : Pseudo<(outs), (ins cls:$R1, imm:$I2), [(operator cls:$R1, imm:$I2)]> {
+  let isCompare = 1;
+}
 
 // Like CompareRXY, but expanded after RA depending on the choice of register.
 class CompareRXYPseudo<SDPatternOperator operator, RegisterOperand cls,

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.cpp Mon Nov 28 07:40:08 2016
@@ -1321,6 +1321,10 @@ bool SystemZInstrInfo::expandPostRAPseud
     expandRIPseudo(MI, SystemZ::AFI, SystemZ::AIH, false);
     return true;
 
+  case SystemZ::CHIMux:
+    expandRIPseudo(MI, SystemZ::CHI, SystemZ::CIH, false);
+    return true;
+
   case SystemZ::CFIMux:
     expandRIPseudo(MI, SystemZ::CFI, SystemZ::CIH, false);
     return true;
@@ -1386,6 +1390,7 @@ SystemZInstrInfo::getBranchInfo(const Ma
                              MI.getOperand(1).getImm(), &MI.getOperand(2));
 
   case SystemZ::BRCT:
+  case SystemZ::BRCTH:
     return SystemZII::Branch(SystemZII::BranchCT, SystemZ::CCMASK_ICMP,
                              SystemZ::CCMASK_CMP_NE, &MI.getOperand(2));
 

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Mon Nov 28 07:40:08 2016
@@ -155,15 +155,33 @@ let isBranch = 1, isTerminator = 1 in {
 }
 
 // Decrement a register and branch if it is nonzero.  These don't clobber CC,
-// but we might need to split long branches into sequences that do.
-let isBranch = 1, isTerminator = 1, Defs = [CC] in {
-  def BRCT  : BranchUnaryRI<"brct",  0xA76, GR32>;
-  def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>;
-}
+// but we might need to split long relative branches into sequences that do.
+let isBranch = 1, isTerminator = 1 in {
+  let Defs = [CC] in {
+    def BRCT  : BranchUnaryRI<"brct",  0xA76, GR32>;
+    def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>;
+  }
+  // This doesn't need to clobber CC since we never need to split it.
+  def BRCTH : BranchUnaryRIL<"brcth", 0xCC6, GRH32>,
+              Requires<[FeatureHighWord]>;
 
-let isBranch = 1, isTerminator = 1, Defs = [CC] in {
-  def BRXH  : BranchBinaryRSI<"brxh",  0x84, GR32>;
-  def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR32>;
+  def BCT   : BranchUnaryRX<"bct",  0x46,GR32>;
+  def BCTR  : BranchUnaryRR<"bctr", 0x06, GR32>;
+  def BCTG  : BranchUnaryRXY<"bctg",  0xE346, GR64>;
+  def BCTGR : BranchUnaryRRE<"bctgr", 0xB946, GR64>;
+}
+
+let isBranch = 1, isTerminator = 1 in {
+  let Defs = [CC] in {
+    def BRXH  : BranchBinaryRSI<"brxh",  0x84, GR32>;
+    def BRXLE : BranchBinaryRSI<"brxle", 0x85, GR32>;
+    def BRXHG : BranchBinaryRIEe<"brxhg", 0xEC44, GR64>;
+    def BRXLG : BranchBinaryRIEe<"brxlg", 0xEC45, GR64>;
+  }
+  def BXH   : BranchBinaryRS<"bxh",  0x86, GR32>;
+  def BXLE  : BranchBinaryRS<"bxle", 0x87, GR32>;
+  def BXHG  : BranchBinaryRSY<"bxhg",  0xEB44, GR64>;
+  def BXLEG : BranchBinaryRSY<"bxleg", 0xEB45, GR64>;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1235,7 +1253,10 @@ let Defs = [CC], CCValues = 0xE in {
   def CGFR : CompareRRE<"cgfr", 0xB930, null_frag, GR64, GR32>;
   def CGR  : CompareRRE<"cgr",  0xB920, z_scmp,    GR64, GR64>;
 
-  // Comparison with a signed 16-bit immediate.
+  // Comparison with a signed 16-bit immediate.  CHIMux expands to CHI or CIH,
+  // depending on the choice of register.
+  def CHIMux : CompareRIPseudo<z_scmp, GRX32, imm32sx16>,
+               Requires<[FeatureHighWord]>;
   def CHI  : CompareRI<"chi",  0xA7E, z_scmp, GR32, imm32sx16>;
   def CGHI : CompareRI<"cghi", 0xA7F, z_scmp, GR64, imm64sx16>;
 

Modified: llvm/trunk/lib/Target/SystemZ/SystemZLongBranch.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZLongBranch.cpp?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZLongBranch.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZLongBranch.cpp Mon Nov 28 07:40:08 2016
@@ -226,6 +226,10 @@ TerminatorInfo SystemZLongBranch::descri
       // Relaxes to A(G)HI and BRCL, which is 6 bytes longer.
       Terminator.ExtraRelaxSize = 6;
       break;
+    case SystemZ::BRCTH:
+      // Never needs to be relaxed.
+      Terminator.ExtraRelaxSize = 0;
+      break;
     case SystemZ::CRJ:
     case SystemZ::CLRJ:
       // Relaxes to a C(L)R/BRCL sequence, which is 2 bytes longer.

Modified: llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ13.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ13.td?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ13.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ13.td Mon Nov 28 07:40:08 2016
@@ -116,7 +116,10 @@ def : InstRW<[VBU], (instregex "(Call)?J
 def : InstRW<[FXb], (instregex "(Call)?BC(R)?(Asm.*)?$")>;
 def : InstRW<[FXb], (instregex "(Call)?B(R)?(Asm.*)?$")>;
 def : InstRW<[FXa, EndGroup], (instregex "BRCT(G)?$")>;
-def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone], (instregex "BRX(H|LE)$")>;
+def : InstRW<[FXb, FXa, Lat2, GroupAlone], (instregex "BRCTH$")>;
+def : InstRW<[FXb, FXa, Lat2, GroupAlone], (instregex "BCT(G)?(R)?$")>;
+def : InstRW<[FXa, FXa, FXb, FXb, Lat4, GroupAlone],
+             (instregex "B(R)?X(H|L).*$")>;
 
 // Compare and branch
 def : InstRW<[FXb], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>;
@@ -466,11 +469,11 @@ def : InstRW<[FXa, FXa, Lat3, BeginGroup
 //===----------------------------------------------------------------------===//
 
 def : InstRW<[FXb, LSU, Lat5], (instregex "C(G|Y|Mux|RL)?$")>;
-def : InstRW<[FXb], (instregex "CFI(Mux)?$")>;
+def : InstRW<[FXb], (instregex "C(F|H)I(Mux)?$")>;
 def : InstRW<[FXb], (instregex "CG(F|H)I$")>;
 def : InstRW<[FXb, LSU, Lat5], (instregex "CG(HSI|RL)$")>;
 def : InstRW<[FXb], (instregex "C(G)?R$")>;
-def : InstRW<[FXb], (instregex "C(HI|IH)$")>;
+def : InstRW<[FXb], (instregex "CIH$")>;
 def : InstRW<[FXb, LSU, Lat5], (instregex "CH(F|SI)$")>;
 def : InstRW<[FXb, LSU, Lat5], (instregex "CL(Y|Mux|FHSI)?$")>;
 def : InstRW<[FXb], (instregex "CLFI(Mux)?$")>;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ196.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ196.td?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ196.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZScheduleZ196.td Mon Nov 28 07:40:08 2016
@@ -90,8 +90,10 @@ def : InstRW<[LSU, EndGroup], (instregex
 def : InstRW<[LSU, EndGroup], (instregex "(Call)?J(G)?(Asm.*)?$")>;
 def : InstRW<[LSU, EndGroup], (instregex "(Call)?BC(R)?(Asm.*)?$")>;
 def : InstRW<[LSU, EndGroup], (instregex "(Call)?B(R)?(Asm.*)?$")>;
-def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCT(G)?$")>;
-def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>;
+def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCT(G|H)?$")>;
+def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BCT(G)?(R)?$")>;
+def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone],
+             (instregex "B(R)?X(H|L).*$")>;
 
 // Compare and branch
 def : InstRW<[FXU, LSU, Lat5, GroupAlone],
@@ -433,11 +435,11 @@ def : InstRW<[FXU, FXU, Lat3, GroupAlone
 //===----------------------------------------------------------------------===//
 
 def : InstRW<[FXU, LSU, Lat5], (instregex "C(G|Y|Mux|RL)?$")>;
-def : InstRW<[FXU], (instregex "CFI(Mux)?$")>;
+def : InstRW<[FXU], (instregex "C(F|H)I(Mux)?$")>;
 def : InstRW<[FXU], (instregex "CG(F|H)I$")>;
 def : InstRW<[FXU, LSU, Lat5], (instregex "CG(HSI|RL)$")>;
 def : InstRW<[FXU], (instregex "C(G)?R$")>;
-def : InstRW<[FXU], (instregex "C(HI|IH)$")>;
+def : InstRW<[FXU], (instregex "CIH$")>;
 def : InstRW<[FXU, LSU, Lat5], (instregex "CH(F|SI)$")>;
 def : InstRW<[FXU, LSU, Lat5], (instregex "CL(Y|Mux|FHSI)?$")>;
 def : InstRW<[FXU], (instregex "CLFI(Mux)?$")>;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZScheduleZEC12.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZScheduleZEC12.td?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZScheduleZEC12.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZScheduleZEC12.td Mon Nov 28 07:40:08 2016
@@ -93,7 +93,10 @@ def : InstRW<[VBU], (instregex "(Call)?J
 def : InstRW<[LSU, Lat4], (instregex "(Call)?BC(R)?(Asm.*)?$")>;
 def : InstRW<[LSU, Lat4], (instregex "(Call)?B(R)?(Asm.*)?$")>;
 def : InstRW<[FXU, EndGroup], (instregex "BRCT(G)?$")>;
-def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone], (instregex "BRX(H|LE)$")>;
+def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BRCTH$")>;
+def : InstRW<[FXU, LSU, Lat5, GroupAlone], (instregex "BCT(G)?(R)?$")>;
+def : InstRW<[FXU, FXU, FXU, LSU, Lat7, GroupAlone],
+             (instregex "B(R)?X(H|L).*$")>;
 
 // Compare and branch
 def : InstRW<[FXU], (instregex "C(L)?(G)?(I|R)J(Asm.*)?$")>;
@@ -436,11 +439,11 @@ def : InstRW<[FXU, FXU, Lat3, GroupAlone
 //===----------------------------------------------------------------------===//
 
 def : InstRW<[FXU, LSU, Lat5], (instregex "C(G|Y|Mux|RL)?$")>;
-def : InstRW<[FXU], (instregex "CFI(Mux)?$")>;
+def : InstRW<[FXU], (instregex "C(F|H)I(Mux)?$")>;
 def : InstRW<[FXU], (instregex "CG(F|H)I$")>;
 def : InstRW<[FXU, LSU, Lat5], (instregex "CG(HSI|RL)$")>;
 def : InstRW<[FXU], (instregex "C(G)?R$")>;
-def : InstRW<[FXU], (instregex "C(HI|IH)$")>;
+def : InstRW<[FXU], (instregex "CIH$")>;
 def : InstRW<[FXU, LSU, Lat5], (instregex "CH(F|SI)$")>;
 def : InstRW<[FXU, LSU, Lat5], (instregex "CL(Y|Mux|FHSI)?$")>;
 def : InstRW<[FXU], (instregex "CLFI(Mux)?$")>;

Added: llvm/trunk/test/CodeGen/SystemZ/loop-02.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/loop-02.ll?rev=288029&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/loop-02.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/loop-02.ll Mon Nov 28 07:40:08 2016
@@ -0,0 +1,38 @@
+; Test BRCTH.
+
+; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z196 \
+; RUN:   -no-integrated-as | FileCheck %s
+
+; Test a loop that should be converted into dbr form and then use BRCTH.
+define void @f2(i32 *%src, i32 *%dest) {
+; CHECK-LABEL: f2:
+; CHECK: blah [[REG:%r[0-5]]]
+; CHECK: [[LABEL:\.[^:]*]]:{{.*}} %loop
+; CHECK: brcth [[REG]], [[LABEL]]
+; CHECK: br %r14
+entry:
+  ; Force upper bound into a high register in order to encourage the
+  ; register allocator to use a high register for the count variable.
+  %top = call i32 asm sideeffect "blah $0", "=h"()
+  br label %loop
+
+loop:
+  %count = phi i32 [ 0, %entry ], [ %next, %loop.next ]
+  %next = add i32 %count, 1
+  %val = load volatile i32 , i32 *%src
+  %cmp = icmp eq i32 %val, 0
+  br i1 %cmp, label %loop.next, label %loop.store
+
+loop.store:
+  %add = add i32 %val, 1
+  store volatile i32 %add, i32 *%dest
+  br label %loop.next
+
+loop.next:
+  %cont = icmp ne i32 %next, %top
+  br i1 %cont, label %loop, label %exit
+
+exit:
+  ret void
+}
+

Modified: llvm/trunk/test/MC/Disassembler/SystemZ/insns-pcrel.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/SystemZ/insns-pcrel.txt?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/SystemZ/insns-pcrel.txt (original)
+++ llvm/trunk/test/MC/Disassembler/SystemZ/insns-pcrel.txt Mon Nov 28 07:40:08 2016
@@ -1,7 +1,7 @@
 # Test instructions that have PC-relative operands.  There is no attempt
 # to keep the instructions in alphabetical order, since adding new instructions
 # in the middle would mean updating all later offsets.
-# RUN: llvm-mc --disassemble %s -triple=s390x-linux-gnu | FileCheck %s
+# RUN: llvm-mc --disassemble %s -triple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
 
 # 0x00000000:
 # CHECK: brasl %r0, 0x0
@@ -1810,3 +1810,76 @@
 # 0x00000a34:
 # CHECK: brxle %r15, %r1, 0x10a32
 0x85 0xf1 0x7f 0xff
+
+# 0x00000a38:
+# CHECK: brxhg %r0, %r1, 0xa38
+0xec 0x01 0x00 0x00 0x00 0x44
+
+# 0x00000a3e:
+# CHECK: brxhg %r14, %r1, 0xa3e
+0xec 0xe1 0x00 0x00 0x00 0x44
+
+# 0x00000a44:
+# CHECK: brxhg %r15, %r1, 0xa44
+0xec 0xf1 0x00 0x00 0x00 0x44
+
+# 0x00000a4a:
+# CHECK: brxhg %r0, %r1, 0xa48
+0xec 0x01 0xff 0xff 0x00 0x44
+
+# 0x00000a50:
+# CHECK: brxhg %r14, %r1, 0xffffffffffff0a50
+0xec 0xe1 0x80 0x00 0x00 0x44
+
+# 0x00000a56:
+# CHECK: brxhg %r15, %r1, 0x10a54
+0xec 0xf1 0x7f 0xff 0x00 0x44
+
+# 0x00000a5c:
+# CHECK: brxlg %r0, %r1, 0xa5c
+0xec 0x01 0x00 0x00 0x00 0x45
+
+# 0x00000a62:
+# CHECK: brxlg %r14, %r1, 0xa62
+0xec 0xe1 0x00 0x00 0x00 0x45
+
+# 0x00000a68:
+# CHECK: brxlg %r15, %r1, 0xa68
+0xec 0xf1 0x00 0x00 0x00 0x45
+
+# 0x00000a6e:
+# CHECK: brxlg %r0, %r1, 0xa6c
+0xec 0x01 0xff 0xff 0x00 0x45
+
+# 0x00000a74:
+# CHECK: brxlg %r14, %r1, 0xffffffffffff0a74
+0xec 0xe1 0x80 0x00 0x00 0x45
+
+# 0x00000a7a:
+# CHECK: brxlg %r15, %r1, 0x10a78
+0xec 0xf1 0x7f 0xff 0x00 0x45
+
+# 0x00000a80:
+# CHECK: brcth %r0, 0xa80
+0xcc 0x06 0x00 0x00 0x00 0x00
+
+# 0x00000a86:
+# CHECK: brcth %r14, 0xa86
+0xcc 0xe6 0x00 0x00 0x00 0x00
+
+# 0x00000a8c:
+# CHECK: brcth %r15, 0xa8c
+0xcc 0xf6 0x00 0x00 0x00 0x00
+
+# 0x00000a92:
+# CHECK: brcth %r0, 0xa90
+0xcc 0x06 0xff 0xff 0xff 0xff
+
+# 0x00000a98:
+# CHECK: brcth %r14, 0xffffffff00000a98
+0xcc 0xe6 0x80 0x00 0x00 0x00
+
+# 0x00000a9e:
+# CHECK: brcth %r15, 0x100000a9c
+0xcc 0xf6 0x7f 0xff 0xff 0xff
+

Modified: llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt (original)
+++ llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt Mon Nov 28 07:40:08 2016
@@ -994,6 +994,219 @@
 # CHECK: br %r15
 0x07 0xff
 
+# CHECK: bct %r0, 0
+0x46 0x00 0x00 0x00
+
+# CHECK: bct %r0, 4095
+0x46 0x00 0x0f 0xff
+
+# CHECK: bct %r0, 0(%r1)
+0x46 0x00 0x10 0x00
+
+# CHECK: bct %r0, 0(%r15)
+0x46 0x00 0xf0 0x00
+
+# CHECK: bct %r0, 4095(%r1,%r15)
+0x46 0x01 0xff 0xff
+
+# CHECK: bct %r0, 4095(%r15,%r1)
+0x46 0x0f 0x1f 0xff
+
+# CHECK: bct %r15, 0
+0x46 0xf0 0x00 0x00
+
+# CHECK: bctr %r0, %r9
+0x06 0x09
+
+# CHECK: bctr %r0, %r15
+0x06 0x0f
+
+# CHECK: bctr %r15, %r0
+0x06 0xf0
+
+# CHECK: bctr %r15, %r9
+0x06 0xf9
+
+# CHECK: bctg %r0, -524288
+0xe3 0x00 0x00 0x00 0x80 0x46
+
+# CHECK: bctg %r0, -1
+0xe3 0x00 0x0f 0xff 0xff 0x46
+
+# CHECK: bctg %r0, 0
+0xe3 0x00 0x00 0x00 0x00 0x46
+
+# CHECK: bctg %r0, 1
+0xe3 0x00 0x00 0x01 0x00 0x46
+
+# CHECK: bctg %r0, 524287
+0xe3 0x00 0x0f 0xff 0x7f 0x46
+
+# CHECK: bctg %r0, 0(%r1)
+0xe3 0x00 0x10 0x00 0x00 0x46
+
+# CHECK: bctg %r0, 0(%r15)
+0xe3 0x00 0xf0 0x00 0x00 0x46
+
+# CHECK: bctg %r0, 524287(%r1,%r15)
+0xe3 0x01 0xff 0xff 0x7f 0x46
+
+# CHECK: bctg %r0, 524287(%r15,%r1)
+0xe3 0x0f 0x1f 0xff 0x7f 0x46
+
+# CHECK: bctg %r15, 0
+0xe3 0xf0 0x00 0x00 0x00 0x46
+
+# CHECK: bctgr %r0, %r9
+0xb9 0x46 0x00 0x09
+
+# CHECK: bctgr %r0, %r15
+0xb9 0x46 0x00 0x0f
+
+# CHECK: bctgr %r15, %r0
+0xb9 0x46 0x00 0xf0
+
+# CHECK: bctgr %r15, %r9
+0xb9 0x46 0x00 0xf9
+
+# CHECK: bxh %r0, %r0, 0
+0x86 0x00 0x00 0x00
+
+# CHECK: bxh %r0, %r15, 0
+0x86 0x0f 0x00 0x00
+
+# CHECK: bxh %r14, %r15, 0
+0x86 0xef 0x00 0x00
+
+# CHECK: bxh %r15, %r15, 0
+0x86 0xff 0x00 0x00
+
+# CHECK: bxh %r0, %r0, 4095
+0x86 0x00 0x0f 0xff
+
+# CHECK: bxh %r0, %r0, 1
+0x86 0x00 0x00 0x01
+
+# CHECK: bxh %r0, %r0, 0(%r1)
+0x86 0x00 0x10 0x00
+
+# CHECK: bxh %r0, %r0, 0(%r15)
+0x86 0x00 0xf0 0x00
+
+# CHECK: bxh %r0, %r0, 4095(%r1)
+0x86 0x00 0x1f 0xff
+
+# CHECK: bxh %r0, %r0, 4095(%r15)
+0x86 0x00 0xff 0xff
+
+# CHECK: bxhg %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0x44
+
+# CHECK: bxhg %r0, %r15, 0
+0xeb 0x0f 0x00 0x00 0x00 0x44
+
+# CHECK: bxhg %r14, %r15, 0
+0xeb 0xef 0x00 0x00 0x00 0x44
+
+# CHECK: bxhg %r15, %r15, 0
+0xeb 0xff 0x00 0x00 0x00 0x44
+
+# CHECK: bxhg %r0, %r0, -524288
+0xeb 0x00 0x00 0x00 0x80 0x44
+
+# CHECK: bxhg %r0, %r0, -1
+0xeb 0x00 0x0f 0xff 0xff 0x44
+
+# CHECK: bxhg %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0x44
+
+# CHECK: bxhg %r0, %r0, 1
+0xeb 0x00 0x00 0x01 0x00 0x44
+
+# CHECK: bxhg %r0, %r0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0x44
+
+# CHECK: bxhg %r0, %r0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0x44
+
+# CHECK: bxhg %r0, %r0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0x44
+
+# CHECK: bxhg %r0, %r0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0x44
+
+# CHECK: bxhg %r0, %r0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0x44
+
+# CHECK: bxle %r0, %r0, 0
+0x87 0x00 0x00 0x00
+
+# CHECK: bxle %r0, %r15, 0
+0x87 0x0f 0x00 0x00
+
+# CHECK: bxle %r14, %r15, 0
+0x87 0xef 0x00 0x00
+
+# CHECK: bxle %r15, %r15, 0
+0x87 0xff 0x00 0x00
+
+# CHECK: bxle %r0, %r0, 4095
+0x87 0x00 0x0f 0xff
+
+# CHECK: bxle %r0, %r0, 1
+0x87 0x00 0x00 0x01
+
+# CHECK: bxle %r0, %r0, 0(%r1)
+0x87 0x00 0x10 0x00
+
+# CHECK: bxle %r0, %r0, 0(%r15)
+0x87 0x00 0xf0 0x00
+
+# CHECK: bxle %r0, %r0, 4095(%r1)
+0x87 0x00 0x1f 0xff
+
+# CHECK: bxle %r0, %r0, 4095(%r15)
+0x87 0x00 0xff 0xff
+
+# CHECK: bxleg %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0x45
+
+# CHECK: bxleg %r0, %r15, 0
+0xeb 0x0f 0x00 0x00 0x00 0x45
+
+# CHECK: bxleg %r14, %r15, 0
+0xeb 0xef 0x00 0x00 0x00 0x45
+
+# CHECK: bxleg   %r15, %r15, 0
+0xeb 0xff 0x00 0x00 0x00 0x45
+
+# CHECK: bxleg %r0, %r0, -524288
+0xeb 0x00 0x00 0x00 0x80 0x45
+
+# CHECK: bxleg %r0, %r0, -1
+0xeb 0x00 0x0f 0xff 0xff 0x45
+
+# CHECK: bxleg %r0, %r0, 0
+0xeb 0x00 0x00 0x00 0x00 0x45
+
+# CHECK: bxleg %r0, %r0, 1
+0xeb 0x00 0x00 0x01 0x00 0x45
+
+# CHECK: bxleg %r0, %r0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0x45
+
+# CHECK: bxleg %r0, %r0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0x45
+
+# CHECK: bxleg %r0, %r0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0x45
+
+# CHECK: bxleg %r0, %r0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0x45
+
+# CHECK: bxleg %r0, %r0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0x45
+
 # CHECK: cdbr %f0, %f0
 0xb3 0x19 0x00 0x00
 

Modified: llvm/trunk/test/MC/SystemZ/insn-bad-z196.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/SystemZ/insn-bad-z196.s?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/test/MC/SystemZ/insn-bad-z196.s (original)
+++ llvm/trunk/test/MC/SystemZ/insn-bad-z196.s Mon Nov 28 07:40:08 2016
@@ -34,6 +34,20 @@
 	aih	%r0, (-1 << 31) - 1
 	aih	%r0, (1 << 31)
 
+#CHECK: error: offset out of range
+#CHECK: brcth   %r0, -0x1000000002
+#CHECK: error: offset out of range
+#CHECK: brcth   %r0, -1
+#CHECK: error: offset out of range
+#CHECK: brcth   %r0, 1
+#CHECK: error: offset out of range
+#CHECK: brcth   %r0, 0x100000000
+
+        brcth   %r0, -0x1000000002
+        brcth   %r0, -1
+        brcth   %r0, 1
+        brcth   %r0, 0x100000000
+
 #CHECK: error: invalid operand
 #CHECK: cdfbra	%f0, 0, %r0, -1
 #CHECK: error: invalid operand

Modified: llvm/trunk/test/MC/SystemZ/insn-bad.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/SystemZ/insn-bad.s?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/test/MC/SystemZ/insn-bad.s (original)
+++ llvm/trunk/test/MC/SystemZ/insn-bad.s Mon Nov 28 07:40:08 2016
@@ -374,6 +374,22 @@
 	brcl	-1, bar
 	brcl	16, bar
 
+#CHECK: error: invalid operand
+#CHECK: bct	%r0, -1
+#CHECK: error: invalid operand
+#CHECK: bct	%r0, 4096
+
+	bct	%r0, -1
+	bct	%r0, 4096
+
+#CHECK: error: invalid operand
+#CHECK: bctg	%r0, -524289
+#CHECK: error: invalid operand
+#CHECK: bctg	%r0, 524288
+
+	bctg	%r0, -524289
+	bctg	%r0, 524288
+
 #CHECK: error: offset out of range
 #CHECK: brct	%r0, -0x100002
 #CHECK: error: offset out of range
@@ -402,6 +418,30 @@
 	brctg	%r0, 1
 	brctg	%r0, 0x10000
 
+#CHECK: error: instruction requires: high-word
+#CHECK: brcth	%r0, 0
+
+	brcth	%r0, 0
+
+#CHECK: error: invalid operand
+#CHECK: bxh	%r0, %r0, 4096
+#CHECK: error: invalid use of indexed addressing
+#CHECK: bxh	%r0, %r0, 0(%r1,%r2)
+
+	bxh	%r0, %r0, 4096
+	bxh	%r0, %r0, 0(%r1,%r2)
+
+#CHECK: error: invalid operand
+#CHECK: bxhg	%r0, %r0, -524289
+#CHECK: error: invalid operand
+#CHECK: bxhg	%r0, %r0, 524288
+#CHECK: error: invalid use of indexed addressing
+#CHECK: bxhg	%r0, %r0, 0(%r1,%r2)
+
+	bxhg	%r0, %r0, -524289
+	bxhg	%r0, %r0, 524288
+	bxhg	%r0, %r0, 0(%r1,%r2)
+
 #CHECK: error: offset out of range
 #CHECK: brxh	%r0, %r2, -0x100002
 #CHECK: error: offset out of range
@@ -417,6 +457,39 @@
 	brxh	%r0, %r2, 0x10000
 
 #CHECK: error: offset out of range
+#CHECK: brxhg	%r0, %r2, -0x100002
+#CHECK: error: offset out of range
+#CHECK: brxhg	%r0, %r2, -1
+#CHECK: error: offset out of range
+#CHECK: brxhg	%r0, %r2, 1
+#CHECK: error: offset out of range
+#CHECK: brxhg	%r0, %r2, 0x10000
+
+	brxhg	%r0, %r2, -0x100002
+	brxhg	%r0, %r2, -1
+	brxhg	%r0, %r2, 1
+	brxhg	%r0, %r2, 0x10000
+
+#CHECK: error: invalid operand
+#CHECK: bxle	%r0, %r0, 4096
+#CHECK: error: invalid use of indexed addressing
+#CHECK: bxle	%r0, %r0, 0(%r1,%r2)
+
+	bxle	%r0, %r0, 4096
+	bxle	%r0, %r0, 0(%r1,%r2)
+
+#CHECK: error: invalid operand
+#CHECK: bxhg	%r0, %r0, -524289
+#CHECK: error: invalid operand
+#CHECK: bxhg	%r0, %r0, 524288
+#CHECK: error: invalid use of indexed addressing
+#CHECK: bxhg	%r0, %r0, 0(%r1,%r2)
+
+	bxhg	%r0, %r0, -524289
+	bxhg	%r0, %r0, 524288
+	bxhg	%r0, %r0, 0(%r1,%r2)
+
+#CHECK: error: offset out of range
 #CHECK: brxle	%r0, %r2, -0x100002
 #CHECK: error: offset out of range
 #CHECK: brxle	%r0, %r2, -1
@@ -430,6 +503,20 @@
 	brxle	%r0, %r2, 1
 	brxle	%r0, %r2, 0x10000
 
+#CHECK: error: offset out of range
+#CHECK: brxlg	%r0, %r2, -0x100002
+#CHECK: error: offset out of range
+#CHECK: brxlg	%r0, %r2, -1
+#CHECK: error: offset out of range
+#CHECK: brxlg	%r0, %r2, 1
+#CHECK: error: offset out of range
+#CHECK: brxlg	%r0, %r2, 0x10000
+
+	brxlg	%r0, %r2, -0x100002
+	brxlg	%r0, %r2, -1
+	brxlg	%r0, %r2, 1
+	brxlg	%r0, %r2, 0x10000
+
 #CHECK: error: invalid operand
 #CHECK: c	%r0, -1
 #CHECK: error: invalid operand

Modified: llvm/trunk/test/MC/SystemZ/insn-good-z196.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/SystemZ/insn-good-z196.s?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/test/MC/SystemZ/insn-good-z196.s (original)
+++ llvm/trunk/test/MC/SystemZ/insn-good-z196.s Mon Nov 28 07:40:08 2016
@@ -164,6 +164,43 @@
 	cdgbra	%f4, 5, %r6, 7
 	cdgbra	%f15, 0, %r0, 0
 
+#CHECK: brcth	%r0, .[[LAB:L.*]]-4294967296 # encoding: [0xcc,0x06,A,A,A,A]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL
+	brcth	%r0, -0x100000000
+#CHECK: brcth	%r0, .[[LAB:L.*]]-2	# encoding: [0xcc,0x06,A,A,A,A]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC32DBL
+	brcth	%r0, -2
+#CHECK: brcth	%r0, .[[LAB:L.*]]	# encoding: [0xcc,0x06,A,A,A,A]
+#CHECK:  fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC32DBL
+	brcth	%r0, 0
+#CHECK: brcth	%r0, .[[LAB:L.*]]+4294967294 # encoding: [0xcc,0x06,A,A,A,A]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]+4294967294)+2, kind: FK_390_PC32DBL
+	brcth	%r0, 0xfffffffe
+
+#CHECK: brcth	%r0, foo                # encoding: [0xcc,0x06,A,A,A,A]
+# fixup A - offset: 2, value: foo+2, kind: FK_390_PC32DBL
+#CHECK: brcth	%r15, foo               # encoding: [0xcc,0xf6,A,A,A,A]
+# fixup A - offset: 2, value: foo+2, kind: FK_390_PC32DBL
+
+	brcth	%r0,foo
+	brcth	%r15,foo
+
+#CHECK: brcth	%r3, bar+100            # encoding: [0xcc,0x36,A,A,A,A]
+# fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC32DBL
+#CHECK: brcth	%r4, bar+100            # encoding: [0xcc,0x46,A,A,A,A]
+# fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC32DBL
+
+	brcth	%r3,bar+100
+	brcth	%r4,bar+100
+
+#CHECK: brcth	%r7, frob at PLT           # encoding: [0xcc,0x76,A,A,A,A]
+# fixup A - offset: 2, value: frob at PLT+2, kind: FK_390_PC32DBL
+#CHECK: brcth	%r8, frob at PLT           # encoding: [0xcc,0x86,A,A,A,A]
+# fixup A - offset: 2, value: frob at PLT+2, kind: FK_390_PC32DBL
+
+	brcth	%r7,frob at PLT
+	brcth	%r8,frob at PLT
+
 #CHECK: cdlfbr	%f0, 0, %r0, 0          # encoding: [0xb3,0x91,0x00,0x00]
 #CHECK: cdlfbr	%f0, 0, %r0, 15         # encoding: [0xb3,0x91,0x0f,0x00]
 #CHECK: cdlfbr	%f0, 0, %r15, 0         # encoding: [0xb3,0x91,0x00,0x0f]

Modified: llvm/trunk/test/MC/SystemZ/insn-good.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/SystemZ/insn-good.s?rev=288029&r1=288028&r2=288029&view=diff
==============================================================================
--- llvm/trunk/test/MC/SystemZ/insn-good.s (original)
+++ llvm/trunk/test/MC/SystemZ/insn-good.s Mon Nov 28 07:40:08 2016
@@ -1421,6 +1421,64 @@
 #CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC32DBL
 	jg	bar at PLT
 
+#CHECK: bct	%r0, 0                  # encoding: [0x46,0x00,0x00,0x00]
+#CHECK: bct	%r0, 4095               # encoding: [0x46,0x00,0x0f,0xff]
+#CHECK: bct	%r0, 0(%r1)             # encoding: [0x46,0x00,0x10,0x00]
+#CHECK: bct	%r0, 0(%r15)            # encoding: [0x46,0x00,0xf0,0x00]
+#CHECK: bct	%r0, 4095(%r1,%r15)     # encoding: [0x46,0x01,0xff,0xff]
+#CHECK: bct	%r0, 4095(%r15,%r1)     # encoding: [0x46,0x0f,0x1f,0xff]
+#CHECK: bct	%r15, 0                 # encoding: [0x46,0xf0,0x00,0x00]
+
+	bct	%r0, 0
+	bct	%r0, 4095
+	bct	%r0, 0(%r1)
+	bct	%r0, 0(%r15)
+	bct	%r0, 4095(%r1,%r15)
+	bct	%r0, 4095(%r15,%r1)
+	bct	%r15, 0
+
+#CHECK: bctr	%r0, %r9                # encoding: [0x06,0x09]
+#CHECK: bctr	%r0, %r15               # encoding: [0x06,0x0f]
+#CHECK: bctr	%r15, %r0               # encoding: [0x06,0xf0]
+#CHECK: bctr	%r15, %r9               # encoding: [0x06,0xf9]
+
+	bctr	%r0,%r9
+	bctr	%r0,%r15
+	bctr	%r15,%r0
+	bctr	%r15,%r9
+
+#CHECK: bctg	%r0, -524288            # encoding: [0xe3,0x00,0x00,0x00,0x80,0x46]
+#CHECK: bctg	%r0, -1                 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x46]
+#CHECK: bctg	%r0, 0                  # encoding: [0xe3,0x00,0x00,0x00,0x00,0x46]
+#CHECK: bctg	%r0, 1                  # encoding: [0xe3,0x00,0x00,0x01,0x00,0x46]
+#CHECK: bctg	%r0, 524287             # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x46]
+#CHECK: bctg	%r0, 0(%r1)             # encoding: [0xe3,0x00,0x10,0x00,0x00,0x46]
+#CHECK: bctg	%r0, 0(%r15)            # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x46]
+#CHECK: bctg	%r0, 524287(%r1,%r15)   # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x46]
+#CHECK: bctg	%r0, 524287(%r15,%r1)   # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x46]
+#CHECK: bctg	%r15, 0                 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x46]
+
+	bctg	%r0, -524288
+	bctg	%r0, -1
+	bctg	%r0, 0
+	bctg	%r0, 1
+	bctg	%r0, 524287
+	bctg	%r0, 0(%r1)
+	bctg	%r0, 0(%r15)
+	bctg	%r0, 524287(%r1,%r15)
+	bctg	%r0, 524287(%r15,%r1)
+	bctg	%r15, 0
+
+#CHECK: bctgr	%r0, %r9                # encoding: [0xb9,0x46,0x00,0x09]
+#CHECK: bctgr	%r0, %r15               # encoding: [0xb9,0x46,0x00,0x0f]
+#CHECK: bctgr	%r15, %r0               # encoding: [0xb9,0x46,0x00,0xf0]
+#CHECK: bctgr	%r15, %r9               # encoding: [0xb9,0x46,0x00,0xf9]
+
+	bctgr	%r0,%r9
+	bctgr	%r0,%r15
+	bctgr	%r15,%r0
+	bctgr	%r15,%r9
+
 #CHECK: brct	%r0, .[[LAB:L.*]]-65536	# encoding: [0xa7,0x06,A,A]
 #CHECK:  fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
 	brct	%r0, -0x10000
@@ -1453,6 +1511,56 @@
 #CHECK:  fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
 	brctg	%r15, 0
 
+#CHECK: bxh	%r0, %r0, 0             # encoding: [0x86,0x00,0x00,0x00]
+#CHECK: bxh	%r0, %r15, 0            # encoding: [0x86,0x0f,0x00,0x00]
+#CHECK: bxh	%r14, %r15, 0           # encoding: [0x86,0xef,0x00,0x00]
+#CHECK: bxh	%r15, %r15, 0           # encoding: [0x86,0xff,0x00,0x00]
+#CHECK: bxh	%r0, %r0, 4095          # encoding: [0x86,0x00,0x0f,0xff]
+#CHECK: bxh	%r0, %r0, 1             # encoding: [0x86,0x00,0x00,0x01]
+#CHECK: bxh	%r0, %r0, 0(%r1)        # encoding: [0x86,0x00,0x10,0x00]
+#CHECK: bxh	%r0, %r0, 0(%r15)       # encoding: [0x86,0x00,0xf0,0x00]
+#CHECK: bxh	%r0, %r0, 4095(%r1)     # encoding: [0x86,0x00,0x1f,0xff]
+#CHECK: bxh	%r0, %r0, 4095(%r15)    # encoding: [0x86,0x00,0xff,0xff]
+
+	bxh	%r0,%r0,0
+	bxh	%r0,%r15,0
+	bxh	%r14,%r15,0
+	bxh	%r15,%r15,0
+	bxh	%r0,%r0,4095
+	bxh	%r0,%r0,1
+	bxh	%r0,%r0,0(%r1)
+	bxh	%r0,%r0,0(%r15)
+	bxh	%r0,%r0,4095(%r1)
+	bxh	%r0,%r0,4095(%r15)
+
+#CHECK: bxhg	%r0, %r0, 0             # encoding: [0xeb,0x00,0x00,0x00,0x00,0x44]
+#CHECK: bxhg	%r0, %r15, 0            # encoding: [0xeb,0x0f,0x00,0x00,0x00,0x44]
+#CHECK: bxhg	%r14, %r15, 0           # encoding: [0xeb,0xef,0x00,0x00,0x00,0x44]
+#CHECK: bxhg	%r15, %r15, 0           # encoding: [0xeb,0xff,0x00,0x00,0x00,0x44]
+#CHECK: bxhg	%r0, %r0, -524288       # encoding: [0xeb,0x00,0x00,0x00,0x80,0x44]
+#CHECK: bxhg	%r0, %r0, -1            # encoding: [0xeb,0x00,0x0f,0xff,0xff,0x44]
+#CHECK: bxhg	%r0, %r0, 0             # encoding: [0xeb,0x00,0x00,0x00,0x00,0x44]
+#CHECK: bxhg	%r0, %r0, 1             # encoding: [0xeb,0x00,0x00,0x01,0x00,0x44]
+#CHECK: bxhg	%r0, %r0, 524287        # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0x44]
+#CHECK: bxhg	%r0, %r0, 0(%r1)        # encoding: [0xeb,0x00,0x10,0x00,0x00,0x44]
+#CHECK: bxhg	%r0, %r0, 0(%r15)       # encoding: [0xeb,0x00,0xf0,0x00,0x00,0x44]
+#CHECK: bxhg	%r0, %r0, 524287(%r1)   # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0x44]
+#CHECK: bxhg	%r0, %r0, 524287(%r15)  # encoding: [0xeb,0x00,0xff,0xff,0x7f,0x44]
+
+	bxhg	%r0,%r0,0
+	bxhg	%r0,%r15,0
+	bxhg	%r14,%r15,0
+	bxhg	%r15,%r15,0
+	bxhg	%r0,%r0,-524288
+	bxhg	%r0,%r0,-1
+	bxhg	%r0,%r0,0
+	bxhg	%r0,%r0,1
+	bxhg	%r0,%r0,524287
+	bxhg	%r0,%r0,0(%r1)
+	bxhg	%r0,%r0,0(%r15)
+	bxhg	%r0,%r0,524287(%r1)
+	bxhg	%r0,%r0,524287(%r15)
+
 #CHECK: brxh	%r0, %r2, .[[LAB:L.*]]-65536	# encoding: [0x84,0x02,A,A]
 #CHECK:  fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
 	brxh	%r0,%r2, -0x10000
@@ -1496,6 +1604,99 @@
 	brxh	%r14,%r2,bar at PLT
 	brxh	%r15,%r2,bar at PLT
 
+#CHECK: brxhg	%r0, %r2, .[[LAB:L.*]]-65536	# encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
+	brxhg	%r0,%r2, -0x10000
+#CHECK: brxhg	%r0, %r2, .[[LAB:L.*]]-2	# encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL
+	brxhg	%r0, %r2, -2
+#CHECK: brxhg	%r0, %r2, .[[LAB:L.*]]	        # encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
+	brxhg	%r0,%r2, 0
+#CHECK: brxhg	%r0, %r2, .[[LAB:L.*]]+65534	# encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL
+	brxhg	%r0,%r2, 0xfffe
+
+#CHECK: brxhg	%r0, %r2, foo                   # encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL
+#CHECK: brxhg	%r14, %r2, foo                  # encoding: [0xec,0xe2,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL
+#CHECK: brxhg	%r15, %r2, foo                  # encoding: [0xec,0xf2,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL
+	brxhg	%r0,%r2,foo
+	brxhg	%r14,%r2,foo
+	brxhg	%r15,%r2,foo
+
+#CHECK: brxhg	%r0, %r2, bar+100               # encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL
+#CHECK: brxhg	%r14, %r2, bar+100              # encoding: [0xec,0xe2,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL
+#CHECK: brxhg	%r15, %r2, bar+100              # encoding: [0xec,0xf2,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL
+	brxhg	%r0,%r2,bar+100
+	brxhg	%r14,%r2,bar+100
+	brxhg	%r15,%r2,bar+100
+
+#CHECK: brxhg	%r0, %r2, bar at PLT               # encoding: [0xec,0x02,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC16DBL
+#CHECK: brxhg	%r14, %r2, bar at PLT              # encoding: [0xec,0xe2,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC16DBL
+#CHECK: brxhg	%r15, %r2, bar at PLT              # encoding: [0xec,0xf2,A,A,0x00,0x44]
+#CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC16DBL
+	brxhg	%r0,%r2,bar at PLT
+	brxhg	%r14,%r2,bar at PLT
+	brxhg	%r15,%r2,bar at PLT
+
+#CHECK: bxle	%r0, %r0, 0             # encoding: [0x87,0x00,0x00,0x00]
+#CHECK: bxle	%r0, %r15, 0            # encoding: [0x87,0x0f,0x00,0x00]
+#CHECK: bxle	%r14, %r15, 0           # encoding: [0x87,0xef,0x00,0x00]
+#CHECK: bxle	%r15, %r15, 0           # encoding: [0x87,0xff,0x00,0x00]
+#CHECK: bxle	%r0, %r0, 4095          # encoding: [0x87,0x00,0x0f,0xff]
+#CHECK: bxle	%r0, %r0, 1             # encoding: [0x87,0x00,0x00,0x01]
+#CHECK: bxle	%r0, %r0, 0(%r1)        # encoding: [0x87,0x00,0x10,0x00]
+#CHECK: bxle	%r0, %r0, 0(%r15)       # encoding: [0x87,0x00,0xf0,0x00]
+#CHECK: bxle	%r0, %r0, 4095(%r1)     # encoding: [0x87,0x00,0x1f,0xff]
+#CHECK: bxle	%r0, %r0, 4095(%r15)    # encoding: [0x87,0x00,0xff,0xff]
+
+	bxle	%r0,%r0,0
+	bxle	%r0,%r15,0
+	bxle	%r14,%r15,0
+	bxle	%r15,%r15,0
+	bxle	%r0,%r0,4095
+	bxle	%r0,%r0,1
+	bxle	%r0,%r0,0(%r1)
+	bxle	%r0,%r0,0(%r15)
+	bxle	%r0,%r0,4095(%r1)
+	bxle	%r0,%r0,4095(%r15)
+
+#CHECK: bxleg	%r0, %r0, 0             # encoding: [0xeb,0x00,0x00,0x00,0x00,0x45]
+#CHECK: bxleg	%r0, %r15, 0            # encoding: [0xeb,0x0f,0x00,0x00,0x00,0x45]
+#CHECK: bxleg	%r14, %r15, 0           # encoding: [0xeb,0xef,0x00,0x00,0x00,0x45]
+#CHECK: bxleg	%r15, %r15, 0           # encoding: [0xeb,0xff,0x00,0x00,0x00,0x45]
+#CHECK: bxleg	%r0, %r0, -524288       # encoding: [0xeb,0x00,0x00,0x00,0x80,0x45]
+#CHECK: bxleg	%r0, %r0, -1            # encoding: [0xeb,0x00,0x0f,0xff,0xff,0x45]
+#CHECK: bxleg	%r0, %r0, 0             # encoding: [0xeb,0x00,0x00,0x00,0x00,0x45]
+#CHECK: bxleg	%r0, %r0, 1             # encoding: [0xeb,0x00,0x00,0x01,0x00,0x45]
+#CHECK: bxleg	%r0, %r0, 524287        # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0x45]
+#CHECK: bxleg	%r0, %r0, 0(%r1)        # encoding: [0xeb,0x00,0x10,0x00,0x00,0x45]
+#CHECK: bxleg	%r0, %r0, 0(%r15)       # encoding: [0xeb,0x00,0xf0,0x00,0x00,0x45]
+#CHECK: bxleg	%r0, %r0, 524287(%r1)   # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0x45]
+#CHECK: bxleg	%r0, %r0, 524287(%r15)  # encoding: [0xeb,0x00,0xff,0xff,0x7f,0x45]
+
+	bxleg	%r0,%r0,0
+	bxleg	%r0,%r15,0
+	bxleg	%r14,%r15,0
+	bxleg	%r15,%r15,0
+	bxleg	%r0,%r0,-524288
+	bxleg	%r0,%r0,-1
+	bxleg	%r0,%r0,0
+	bxleg	%r0,%r0,1
+	bxleg	%r0,%r0,524287
+	bxleg	%r0,%r0,0(%r1)
+	bxleg	%r0,%r0,0(%r15)
+	bxleg	%r0,%r0,524287(%r1)
+	bxleg	%r0,%r0,524287(%r15)
+
 #CHECK: brxle	%r0, %r2, .[[LAB:L.*]]-65536	# encoding: [0x85,0x02,A,A]
 #CHECK:  fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
 	brxle	%r0,%r2, -0x10000
@@ -1539,6 +1740,49 @@
 	brxle	%r14,%r2,bar at PLT
 	brxle	%r15,%r2,bar at PLT
 
+#CHECK: brxlg	%r0, %r2, .[[LAB:L.*]]-65536	# encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL
+	brxlg	%r0,%r2, -0x10000
+#CHECK: brxlg	%r0, %r2, .[[LAB:L.*]]-2	# encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL
+	brxlg	%r0, %r2, -2
+#CHECK: brxlg	%r0, %r2, .[[LAB:L.*]]	        # encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL
+	brxlg	%r0,%r2, 0
+#CHECK: brxlg	%r0, %r2, .[[LAB:L.*]]+65534	# encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL
+	brxlg	%r0,%r2, 0xfffe
+
+#CHECK: brxlg	%r0, %r2, foo                   # encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL
+#CHECK: brxlg	%r14, %r2, foo                  # encoding: [0xec,0xe2,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL
+#CHECK: brxlg	%r15, %r2, foo                  # encoding: [0xec,0xf2,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL
+	brxlg	%r0,%r2,foo
+	brxlg	%r14,%r2,foo
+	brxlg	%r15,%r2,foo
+
+#CHECK: brxlg	%r0, %r2, bar+100               # encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL
+#CHECK: brxlg	%r14, %r2, bar+100              # encoding: [0xec,0xe2,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL
+#CHECK: brxlg	%r15, %r2, bar+100              # encoding: [0xec,0xf2,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL
+	brxlg	%r0,%r2,bar+100
+	brxlg	%r14,%r2,bar+100
+	brxlg	%r15,%r2,bar+100
+
+#CHECK: brxlg	%r0, %r2, bar at PLT               # encoding: [0xec,0x02,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC16DBL
+#CHECK: brxlg	%r14, %r2, bar at PLT              # encoding: [0xec,0xe2,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC16DBL
+#CHECK: brxlg	%r15, %r2, bar at PLT              # encoding: [0xec,0xf2,A,A,0x00,0x45]
+#CHECK:  fixup A - offset: 2, value: bar at PLT+2, kind: FK_390_PC16DBL
+	brxlg	%r0,%r2,bar at PLT
+	brxlg	%r14,%r2,bar at PLT
+	brxlg	%r15,%r2,bar at PLT
+
 #CHECK: c	%r0, 0                  # encoding: [0x59,0x00,0x00,0x00]
 #CHECK: c	%r0, 4095               # encoding: [0x59,0x00,0x0f,0xff]
 #CHECK: c	%r0, 0(%r1)             # encoding: [0x59,0x00,0x10,0x00]




More information about the llvm-commits mailing list