diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index f575911fad1..03a6da6dc42 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1609,6 +1609,33 @@ static MachineBasicBlock *splitBlockAfter(MachineInstr *MI, return NewMBB; } +bool SystemZTargetLowering:: +convertPrevCompareToBranch(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned CCMask, MachineBasicBlock *Target) const { + MachineBasicBlock::iterator Compare = MBBI; + MachineBasicBlock::iterator Begin = MBB->begin(); + do + { + if (Compare == Begin) + return false; + --Compare; + } + while (Compare->isDebugValue()); + + const SystemZInstrInfo *TII = TM.getInstrInfo(); + unsigned FusedOpcode = TII->getCompareAndBranch(Compare->getOpcode()); + if (!FusedOpcode) + return false; + + DebugLoc DL = Compare->getDebugLoc(); + BuildMI(*MBB, MBBI, DL, TII->get(FusedOpcode)) + .addOperand(Compare->getOperand(0)).addOperand(Compare->getOperand(1)) + .addImm(CCMask).addMBB(Target); + Compare->removeFromParent(); + return true; +} + // Implement EmitInstrWithCustomInserter for pseudo Select* instruction MI. MachineBasicBlock * SystemZTargetLowering::emitSelect(MachineInstr *MI, @@ -1626,13 +1653,17 @@ SystemZTargetLowering::emitSelect(MachineInstr *MI, MachineBasicBlock *FalseMBB = emitBlockAfter(StartMBB); // StartMBB: - // ... - // TrueVal = ... - // cmpTY ccX, r1, r2 - // jCC JoinMBB + // BRC CCMask, JoinMBB // # fallthrough to FalseMBB + // + // The original DAG glues comparisons to their uses, both to ensure + // that no CC-clobbering instructions are inserted between them, and + // to ensure that comparison results are not reused. This means that + // this Select is the sole user of any preceding comparison instruction + // and that we can try to use a fused compare and branch instead. MBB = StartMBB; - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(CCMask).addMBB(JoinMBB); + if (!convertPrevCompareToBranch(MBB, MI, CCMask, JoinMBB)) + BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(CCMask).addMBB(JoinMBB); MBB->addSuccessor(JoinMBB); MBB->addSuccessor(FalseMBB); @@ -1854,10 +1885,17 @@ SystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI, if (IsSubWord) BuildMI(MBB, DL, TII->get(SystemZ::RLL), RotatedOldVal) .addReg(OldVal).addReg(BitShift).addImm(0); - BuildMI(MBB, DL, TII->get(CompareOpcode)) - .addReg(RotatedOldVal).addReg(Src2); - BuildMI(MBB, DL, TII->get(SystemZ::BRC)) - .addImm(KeepOldMask).addMBB(UpdateMBB); + unsigned FusedOpcode = TII->getCompareAndBranch(CompareOpcode); + if (FusedOpcode) + BuildMI(MBB, DL, TII->get(FusedOpcode)) + .addReg(RotatedOldVal).addReg(Src2) + .addImm(KeepOldMask).addMBB(UpdateMBB); + else { + BuildMI(MBB, DL, TII->get(CompareOpcode)) + .addReg(RotatedOldVal).addReg(Src2); + BuildMI(MBB, DL, TII->get(SystemZ::BRC)) + .addImm(KeepOldMask).addMBB(UpdateMBB); + } MBB->addSuccessor(UpdateMBB); MBB->addSuccessor(UseAltMBB); @@ -1959,8 +1997,7 @@ SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, // ^^ Replace the upper 32-BitSize bits of the // comparison value with those that we loaded, // so that we can use a full word comparison. - // CR %Dest, %RetryCmpVal - // JNE DoneMBB + // CRJNE %Dest, %RetryCmpVal, DoneMBB // # Fall through to SetMBB MBB = LoopMBB; BuildMI(MBB, DL, TII->get(SystemZ::PHI), OldVal) @@ -1976,9 +2013,9 @@ SystemZTargetLowering::emitAtomicCmpSwapW(MachineInstr *MI, .addReg(OldVal).addReg(BitShift).addImm(BitSize); BuildMI(MBB, DL, TII->get(SystemZ::RISBG32), RetryCmpVal) .addReg(CmpVal).addReg(Dest).addImm(32).addImm(63 - BitSize).addImm(0); - BuildMI(MBB, DL, TII->get(SystemZ::CR)) - .addReg(Dest).addReg(RetryCmpVal); - BuildMI(MBB, DL, TII->get(SystemZ::BRC)).addImm(MaskNE).addMBB(DoneMBB); + BuildMI(MBB, DL, TII->get(SystemZ::CRJ)) + .addReg(Dest).addReg(RetryCmpVal) + .addImm(MaskNE).addMBB(DoneMBB); MBB->addSuccessor(DoneMBB); MBB->addSuccessor(SetMBB); @@ -2227,6 +2264,16 @@ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const { case SystemZ::ATOMIC_CMP_SWAPW: return emitAtomicCmpSwapW(MI, MBB); + case SystemZ::BRC: + // The original DAG glues comparisons to their uses, both to ensure + // that no CC-clobbering instructions are inserted between them, and + // to ensure that comparison results are not reused. This means that + // a BRC is the sole user of a preceding comparison and that we can + // try to use a fused compare and branch instead. + if (convertPrevCompareToBranch(MBB, MI, MI->getOperand(0).getImm(), + MI->getOperand(1).getMBB())) + MI->eraseFromParent(); + return MBB; default: llvm_unreachable("Unexpected instr type to insert"); } diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index e408bd280aa..129165df6a8 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -16,6 +16,7 @@ #define LLVM_TARGET_SystemZ_ISELLOWERING_H #include "SystemZ.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Target/TargetLowering.h" @@ -189,6 +190,15 @@ private: SDValue lowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; + // If the last instruction before MBBI in MBB was some form of COMPARE, + // try to replace it with a COMPARE AND BRANCH just before MBBI. + // CCMask and Target are the BRC-like operands for the branch. + // Return true if the change was made. + bool convertPrevCompareToBranch(MachineBasicBlock *MBB, + MachineBasicBlock::iterator MBBI, + unsigned CCMask, + MachineBasicBlock *Target) const; + // Implement EmitInstrWithCustomInserter for individual operation types. MachineBasicBlock *emitSelect(MachineInstr *MI, MachineBasicBlock *BB) const; diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td index a9bc5629d0e..c52e2a29f3c 100644 --- a/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -110,6 +110,25 @@ class InstRI op, dag outs, dag ins, string asmstr, list pattern> let Inst{15-0} = I2; } +class InstRIEb op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<4> R1; + bits<4> R2; + bits<4> M3; + bits<16> RI4; + + let Inst{47-40} = op{15-8}; + let Inst{39-36} = R1; + let Inst{35-32} = R2; + let Inst{31-16} = RI4; + let Inst{15-12} = M3; + let Inst{11-8} = 0; + let Inst{7-0} = op{7-0}; +} + class InstRIEf op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp index 6296e4a4800..dcce5a7b7f7 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -132,6 +132,10 @@ bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, if (!Branch.Target->isMBB()) return true; + // Punt on compound branches. + if (Branch.Type != SystemZII::BranchNormal) + return true; + if (Branch.CCMask == SystemZ::CCMASK_ANY) { // Handle unconditional branches. if (!AllowModify) { @@ -361,11 +365,21 @@ SystemZInstrInfo::getBranchInfo(const MachineInstr *MI) const { case SystemZ::BR: case SystemZ::J: case SystemZ::JG: - return SystemZII::Branch(SystemZ::CCMASK_ANY, &MI->getOperand(0)); + return SystemZII::Branch(SystemZII::BranchNormal, SystemZ::CCMASK_ANY, + &MI->getOperand(0)); case SystemZ::BRC: case SystemZ::BRCL: - return SystemZII::Branch(MI->getOperand(0).getImm(), &MI->getOperand(1)); + return SystemZII::Branch(SystemZII::BranchNormal, + MI->getOperand(0).getImm(), &MI->getOperand(1)); + + case SystemZ::CRJ: + return SystemZII::Branch(SystemZII::BranchC, MI->getOperand(2).getImm(), + &MI->getOperand(3)); + + case SystemZ::CGRJ: + return SystemZII::Branch(SystemZII::BranchCG, MI->getOperand(2).getImm(), + &MI->getOperand(3)); default: llvm_unreachable("Unrecognized branch opcode"); @@ -426,6 +440,17 @@ unsigned SystemZInstrInfo::getOpcodeForOffset(unsigned Opcode, return 0; } +unsigned SystemZInstrInfo::getCompareAndBranch(unsigned Opcode) const { + switch (Opcode) { + case SystemZ::CR: + return SystemZ::CRJ; + case SystemZ::CGR: + return SystemZ::CGRJ; + default: + return 0; + } +} + void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned Reg, uint64_t Value) const { diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h index 322219c52f5..e4a984025f9 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.h +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -42,16 +42,32 @@ namespace SystemZII { // @GOT (aka @GOTENT) MO_GOT = (1 << 0) }; + // Classifies a branch. + enum BranchType { + // An instruction that branches on the current value of CC. + BranchNormal, + + // An instruction that peforms a 32-bit signed comparison and branches + // on the result. + BranchC, + + // An instruction that peforms a 64-bit signed comparison and branches + // on the result. + BranchCG + }; // Information about a branch instruction. struct Branch { + // The type of the branch. + BranchType Type; + // CCMASK_ is set if the branch should be taken when CC == N. unsigned CCMask; // The target of the branch. const MachineOperand *Target; - Branch(unsigned ccMask, const MachineOperand *target) - : CCMask(ccMask), Target(target) {} + Branch(BranchType type, unsigned ccMask, const MachineOperand *target) + : Type(type), CCMask(ccMask), Target(target) {} }; } @@ -125,6 +141,10 @@ public: // exists. unsigned getOpcodeForOffset(unsigned Opcode, int64_t Offset) const; + // If Opcode is a COMPARE opcode for which an associated COMPARE AND + // BRANCH exists, return the opcode for the latter, otherwise return 0. + unsigned getCompareAndBranch(unsigned Opcode) const; + // Emit code before MBBI in MI to move immediate value Value into // physical register Reg. void loadImmediate(MachineBasicBlock &MBB, diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index a27d62bcf4f..bc3997b857b 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -58,25 +58,52 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, R1 = 15 in { // in their raw BRC/BRCL form, with the 4-bit condition-code mask being // the first operand. It seems friendlier to use mnemonic forms like // JE and JLH when writing out the assembly though. -multiclass CondBranches { +// +// Using a custom inserter for BRC gives us a chance to convert the BRC +// and a preceding compare into a single compare-and-branch instruction. +// The inserter makes no change in cases where a separate branch really +// is needed. +multiclass CondBranches { let isBranch = 1, isTerminator = 1, Uses = [CC] in { - def "" : InstRI<0xA74, (outs), (ins imm:$R1, brtarget16:$I2), short, []>; - def L : InstRIL<0xC04, (outs), (ins imm:$R1, brtarget32:$I2), long, []>; + def "" : InstRI<0xA74, (outs), (ins ccmask:$R1, brtarget16:$I2), short, []>; + def L : InstRIL<0xC04, (outs), (ins ccmask:$R1, brtarget32:$I2), long, []>; } } -let isCodeGenOnly = 1 in +let isCodeGenOnly = 1, usesCustomInserter = 1 in defm BRC : CondBranches; defm AsmBRC : CondBranches; def : Pat<(z_br_ccmask cond4:$cond, bb:$dst), (BRC cond4:$cond, bb:$dst)>; -// Define AsmParser mnemonics for each condition code. -multiclass CondExtendedMnemonic Cond, string name> { - let R1 = Cond in { - def "" : InstRI<0xA74, (outs), (ins brtarget16:$I2), - "j"##name##"\t$I2", []>; +// Fused compare-and-branch instructions. As for normal branches, +// we handle these instructions internally in their raw CRJ-like form, +// but use assembly macros like CRJE when writing them out. +// +// These instructions do not use or clobber the condition codes. +// We nevertheless pretend that they clobber CC, so that we can lower +// them to separate comparisons and BRCLs if the branch ends up being +// out of range. +multiclass CompareBranches { + let isBranch = 1, isTerminator = 1, Defs = [CC] in { + def RJ : InstRIEb<0xEC76, (outs), (ins GR32:$R1, GR32:$R2, ccmask:$M3, + brtarget16:$RI4), + "crj"#pos1#"\t$R1, $R2, "#pos2#"$RI4", []>; + def GRJ : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, ccmask:$M3, + brtarget16:$RI4), + "cgrj"#pos1#"\t$R1, $R2, "#pos2#"$RI4", []>; + } +} +let isCodeGenOnly = 1 in + defm C : CompareBranches; +defm AsmC : CompareBranches; + +// Define AsmParser mnemonics for each general condition-code mask +// (integer or floating-point) +multiclass CondExtendedMnemonic ccmask, string name> { + let R1 = ccmask in { + def "" : InstRI<0xA74, (outs), (ins brtarget16:$I2), "j"#name#"\t$I2", []>; def L : InstRIL<0xC04, (outs), (ins brtarget32:$I2), - "jg"##name##"\t$I2", []>; + "jg"#name#"\t$I2", []>; } } defm AsmJO : CondExtendedMnemonic<1, "o">; @@ -94,6 +121,35 @@ defm AsmJLE : CondExtendedMnemonic<12, "le">; defm AsmJNH : CondExtendedMnemonic<13, "nh">; defm AsmJNO : CondExtendedMnemonic<14, "no">; +// Define AsmParser mnemonics for each integer condition-code mask. +// This is like the list above, except that condition 3 is not possible +// and that the low bit of the mask is therefore always 0. This means +// that each condition has two names. Conditions "o" and "no" are not used. +// +// We don't make one of the two names an alias of the other because +// we need the custom parsing routines to select the correct register class. +multiclass IntCondExtendedMnemonicA ccmask, string name> { + let M3 = ccmask in { + def CR : InstRIEb<0xEC76, (outs), (ins GR32:$R1, GR32:$R2, + brtarget16:$RI4), + "crj"##name##"\t$R1, $R2, $RI4", []>; + def CGR : InstRIEb<0xEC64, (outs), (ins GR64:$R1, GR64:$R2, + brtarget16:$RI4), + "cgrj"##name##"\t$R1, $R2, $RI4", []>; + } +} +multiclass IntCondExtendedMnemonic ccmask, string name1, string name2> + : IntCondExtendedMnemonicA { + let isAsmParserOnly = 1 in + defm Alt : IntCondExtendedMnemonicA; +} +defm AsmJH : IntCondExtendedMnemonic<2, "h", "nle">; +defm AsmJL : IntCondExtendedMnemonic<4, "l", "nhe">; +defm AsmJLH : IntCondExtendedMnemonic<6, "lh", "ne">; +defm AsmJE : IntCondExtendedMnemonic<8, "e", "nlh">; +defm AsmJHE : IntCondExtendedMnemonic<10, "he", "nl">; +defm AsmJLE : IntCondExtendedMnemonic<12, "le", "nh">; + def Select32 : SelectWrapper; def Select64 : SelectWrapper; diff --git a/lib/Target/SystemZ/SystemZLongBranch.cpp b/lib/Target/SystemZ/SystemZLongBranch.cpp index 9db4f2d6006..2fc85f50f0f 100644 --- a/lib/Target/SystemZ/SystemZLongBranch.cpp +++ b/lib/Target/SystemZ/SystemZLongBranch.cpp @@ -151,6 +151,7 @@ namespace { bool mustRelaxBranch(const TerminatorInfo &Terminator, uint64_t Address); bool mustRelaxABranch(); void setWorstCaseAddresses(); + void splitCompareBranch(MachineInstr *MI, unsigned CompareOpcode); void relaxBranch(TerminatorInfo &Terminator); void relaxBranches(); @@ -220,6 +221,14 @@ TerminatorInfo SystemZLongBranch::describeTerminator(MachineInstr *MI) { // Relaxes to BRCL, which is 2 bytes longer. Terminator.ExtraRelaxSize = 2; break; + case SystemZ::CRJ: + // Relaxes to a CR/BRCL sequence, which is 2 bytes longer. + Terminator.ExtraRelaxSize = 2; + break; + case SystemZ::CGRJ: + // Relaxes to a CGR/BRCL sequence, which is 4 bytes longer. + Terminator.ExtraRelaxSize = 4; + break; default: llvm_unreachable("Unrecognized branch instruction"); } @@ -319,6 +328,23 @@ void SystemZLongBranch::setWorstCaseAddresses() { } } +// Split MI into the comparison given by CompareOpcode followed +// a BRCL on the result. +void SystemZLongBranch::splitCompareBranch(MachineInstr *MI, + unsigned CompareOpcode) { + MachineBasicBlock *MBB = MI->getParent(); + DebugLoc DL = MI->getDebugLoc(); + BuildMI(*MBB, MI, DL, TII->get(CompareOpcode)) + .addOperand(MI->getOperand(0)) + .addOperand(MI->getOperand(1)); + MachineInstr *BRCL = BuildMI(*MBB, MI, DL, TII->get(SystemZ::BRCL)) + .addOperand(MI->getOperand(2)) + .addOperand(MI->getOperand(3)); + // The implicit use of CC is a killing use. + BRCL->getOperand(2).setIsKill(); + MI->eraseFromParent(); +} + // Relax the branch described by Terminator. void SystemZLongBranch::relaxBranch(TerminatorInfo &Terminator) { MachineInstr *Branch = Terminator.Branch; @@ -329,6 +355,12 @@ void SystemZLongBranch::relaxBranch(TerminatorInfo &Terminator) { case SystemZ::BRC: Branch->setDesc(TII->get(SystemZ::BRCL)); break; + case SystemZ::CRJ: + splitCompareBranch(Branch, SystemZ::CR); + break; + case SystemZ::CGRJ: + splitCompareBranch(Branch, SystemZ::CGR); + break; default: llvm_unreachable("Unrecognized branch"); } diff --git a/test/CodeGen/SystemZ/Large/branch-range-03.py b/test/CodeGen/SystemZ/Large/branch-range-03.py new file mode 100644 index 00000000000..75cdf247c6f --- /dev/null +++ b/test/CodeGen/SystemZ/Large/branch-range-03.py @@ -0,0 +1,107 @@ +# Test 32-bit COMPARE AND BRANCH in cases where the sheer number of +# instructions causes some branches to be out of range. +# RUN: python %s | llc -mtriple=s390x-linux-gnu | FileCheck %s + +# Construct: +# +# before0: +# conditional branch to after0 +# ... +# beforeN: +# conditional branch to after0 +# main: +# 0xffcc bytes, from MVIY instructions +# conditional branch to main +# after0: +# ... +# conditional branch to main +# afterN: +# +# Each conditional branch sequence occupies 12 bytes if it uses a short +# branch and 14 if it uses a long one. The ones before "main:" have to +# take the branch length into account, which is 6 for short branches, +# so the final (0x34 - 6) / 12 == 3 blocks can use short branches. +# The ones after "main:" do not, so the first 0x34 / 12 == 4 blocks +# can use short branches. +# +# CHECK: lb [[REG:%r[0-5]]], 0(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL:\.L[^ ]*]] +# CHECK: lb [[REG:%r[0-5]]], 1(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 2(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 3(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 4(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 5(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 6(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 7(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL]] +# ...main goes here... +# CHECK: lb [[REG:%r[0-5]]], 25(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL:\.L[^ ]*]] +# CHECK: lb [[REG:%r[0-5]]], 26(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 27(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 28(%r3) +# CHECK: crje %r4, [[REG]], [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 29(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 30(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 31(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lb [[REG:%r[0-5]]], 32(%r3) +# CHECK: cr %r4, [[REG]] +# CHECK: jge [[LABEL]] + +branch_blocks = 8 +main_size = 0xffcc + +print 'define void @f1(i8 *%base, i8 *%stop, i32 %limit) {' +print 'entry:' +print ' br label %before0' +print '' + +for i in xrange(branch_blocks): + next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main' + print 'before%d:' % i + print ' %%bstop%d = getelementptr i8 *%%stop, i64 %d' % (i, i) + print ' %%bcur%d = load volatile i8 *%%bstop%d' % (i, i) + print ' %%bext%d = sext i8 %%bcur%d to i32' % (i, i) + print ' %%btest%d = icmp eq i32 %%limit, %%bext%d' % (i, i) + print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next) + print '' + +print '%s:' % next +a, b = 1, 1 +for i in xrange(0, main_size, 6): + a, b = b, a + b + offset = 4096 + b % 500000 + value = a % 256 + print ' %%ptr%d = getelementptr i8 *%%base, i64 %d' % (i, offset) + print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i) + +for i in xrange(branch_blocks): + print ' %%astop%d = getelementptr i8 *%%stop, i64 %d' % (i, i + 25) + print ' %%acur%d = load volatile i8 *%%astop%d' % (i, i) + print ' %%aext%d = sext i8 %%acur%d to i32' % (i, i) + print ' %%atest%d = icmp eq i32 %%limit, %%aext%d' % (i, i) + print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i) + print '' + print 'after%d:' % i + +print ' ret void' +print '}' diff --git a/test/CodeGen/SystemZ/Large/branch-range-04.py b/test/CodeGen/SystemZ/Large/branch-range-04.py new file mode 100644 index 00000000000..3ae3ae9c37f --- /dev/null +++ b/test/CodeGen/SystemZ/Large/branch-range-04.py @@ -0,0 +1,111 @@ +# Test 64-bit COMPARE AND BRANCH in cases where the sheer number of +# instructions causes some branches to be out of range. +# RUN: python %s | llc -mtriple=s390x-linux-gnu | FileCheck %s + +# Construct: +# +# before0: +# conditional branch to after0 +# ... +# beforeN: +# conditional branch to after0 +# main: +# 0xffcc bytes, from MVIY instructions +# conditional branch to main +# after0: +# ... +# conditional branch to main +# afterN: +# +# Each conditional branch sequence occupies 12 bytes if it uses a short +# branch and 16 if it uses a long one. The ones before "main:" have to +# take the branch length into account, which is 6 for short branches, +# so the final (0x34 - 6) / 12 == 3 blocks can use short branches. +# The ones after "main:" do not, so the first 0x34 / 12 == 4 blocks +# can use short branches. The conservative algorithm we use makes +# one of the forward branches unnecessarily long, as noted in the +# check output below. +# +# CHECK: lgb [[REG:%r[0-5]]], 0(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL:\.L[^ ]*]] +# CHECK: lgb [[REG:%r[0-5]]], 1(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 2(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 3(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 4(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# ...as mentioned above, the next one could be a CGRJE instead... +# CHECK: lgb [[REG:%r[0-5]]], 5(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 6(%r3) +# CHECK: cgrje %r4, [[REG]], [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 7(%r3) +# CHECK: cgrje %r4, [[REG]], [[LABEL]] +# ...main goes here... +# CHECK: lgb [[REG:%r[0-5]]], 25(%r3) +# CHECK: cgrje %r4, [[REG]], [[LABEL:\.L[^ ]*]] +# CHECK: lgb [[REG:%r[0-5]]], 26(%r3) +# CHECK: cgrje %r4, [[REG]], [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 27(%r3) +# CHECK: cgrje %r4, [[REG]], [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 28(%r3) +# CHECK: cgrje %r4, [[REG]], [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 29(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 30(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 31(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] +# CHECK: lgb [[REG:%r[0-5]]], 32(%r3) +# CHECK: cgr %r4, [[REG]] +# CHECK: jge [[LABEL]] + +branch_blocks = 8 +main_size = 0xffcc + +print 'define void @f1(i8 *%base, i8 *%stop, i64 %limit) {' +print 'entry:' +print ' br label %before0' +print '' + +for i in xrange(branch_blocks): + next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main' + print 'before%d:' % i + print ' %%bstop%d = getelementptr i8 *%%stop, i64 %d' % (i, i) + print ' %%bcur%d = load volatile i8 *%%bstop%d' % (i, i) + print ' %%bext%d = sext i8 %%bcur%d to i64' % (i, i) + print ' %%btest%d = icmp eq i64 %%limit, %%bext%d' % (i, i) + print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next) + print '' + +print '%s:' % next +a, b = 1, 1 +for i in xrange(0, main_size, 6): + a, b = b, a + b + offset = 4096 + b % 500000 + value = a % 256 + print ' %%ptr%d = getelementptr i8 *%%base, i64 %d' % (i, offset) + print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i) + +for i in xrange(branch_blocks): + print ' %%astop%d = getelementptr i8 *%%stop, i64 %d' % (i, i + 25) + print ' %%acur%d = load volatile i8 *%%astop%d' % (i, i) + print ' %%aext%d = sext i8 %%acur%d to i64' % (i, i) + print ' %%atest%d = icmp eq i64 %%limit, %%aext%d' % (i, i) + print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i) + print '' + print 'after%d:' % i + +print ' ret void' +print '}' diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll index 83d6156c5db..bf490d89294 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-01.ll @@ -19,8 +19,7 @@ define i8 @f1(i8 *%src, i8 %b) { ; CHECK: l [[OLD:%r[0-9]+]], 0(%r2) ; CHECK: [[LOOP:\.[^:]*]]: ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]]) -; CHECK: cr [[ROT]], %r3 -; CHECK: jle [[KEEP:\..*]] +; CHECK: crjle [[ROT]], %r3, [[KEEP:\..*]] ; CHECK: risbg [[ROT]], %r3, 32, 39, 0 ; CHECK: [[KEEP]]: ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) @@ -40,7 +39,7 @@ define i8 @f1(i8 *%src, i8 %b) { ; CHECK-SHIFT2: f1: ; CHECK-SHIFT2: sll %r3, 24 ; CHECK-SHIFT2: rll -; CHECK-SHIFT2: cr {{%r[0-9]+}}, %r3 +; CHECK-SHIFT2: crjle {{%r[0-9]+}}, %r3 ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: br %r14 @@ -56,8 +55,7 @@ define i8 @f2(i8 *%src, i8 %b) { ; CHECK: l [[OLD:%r[0-9]+]], 0(%r2) ; CHECK: [[LOOP:\.[^:]*]]: ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]]) -; CHECK: cr [[ROT]], %r3 -; CHECK: jhe [[KEEP:\..*]] +; CHECK: crjhe [[ROT]], %r3, [[KEEP:\..*]] ; CHECK: risbg [[ROT]], %r3, 32, 39, 0 ; CHECK: [[KEEP]]: ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) @@ -77,7 +75,7 @@ define i8 @f2(i8 *%src, i8 %b) { ; CHECK-SHIFT2: f2: ; CHECK-SHIFT2: sll %r3, 24 ; CHECK-SHIFT2: rll -; CHECK-SHIFT2: cr {{%r[0-9]+}}, %r3 +; CHECK-SHIFT2: crjhe {{%r[0-9]+}}, %r3 ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: br %r14 @@ -164,7 +162,7 @@ define i8 @f4(i8 *%src, i8 %b) { define i8 @f5(i8 *%src) { ; CHECK: f5: ; CHECK: llilh [[SRC2:%r[0-9]+]], 33024 -; CHECK: cr [[ROT:%r[0-9]+]], [[SRC2]] +; CHECK: crjle [[ROT:%r[0-9]+]], [[SRC2]] ; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0 ; CHECK: br %r14 ; @@ -181,7 +179,7 @@ define i8 @f5(i8 *%src) { define i8 @f6(i8 *%src) { ; CHECK: f6: ; CHECK: llilh [[SRC2:%r[0-9]+]], 32256 -; CHECK: cr [[ROT:%r[0-9]+]], [[SRC2]] +; CHECK: crjhe [[ROT:%r[0-9]+]], [[SRC2]] ; CHECK: risbg [[ROT]], [[SRC2]], 32, 39, 0 ; CHECK: br %r14 ; diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll index 27dc3e925b3..b2c7bc90288 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-02.ll @@ -19,8 +19,7 @@ define i16 @f1(i16 *%src, i16 %b) { ; CHECK: l [[OLD:%r[0-9]+]], 0(%r2) ; CHECK: [[LOOP:\.[^:]*]]: ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]]) -; CHECK: cr [[ROT]], %r3 -; CHECK: jle [[KEEP:\..*]] +; CHECK: crjle [[ROT]], %r3, [[KEEP:\..*]] ; CHECK: risbg [[ROT]], %r3, 32, 47, 0 ; CHECK: [[KEEP]]: ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) @@ -40,7 +39,7 @@ define i16 @f1(i16 *%src, i16 %b) { ; CHECK-SHIFT2: f1: ; CHECK-SHIFT2: sll %r3, 16 ; CHECK-SHIFT2: rll -; CHECK-SHIFT2: cr {{%r[0-9]+}}, %r3 +; CHECK-SHIFT2: crjle {{%r[0-9]+}}, %r3 ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: br %r14 @@ -56,8 +55,7 @@ define i16 @f2(i16 *%src, i16 %b) { ; CHECK: l [[OLD:%r[0-9]+]], 0(%r2) ; CHECK: [[LOOP:\.[^:]*]]: ; CHECK: rll [[ROT:%r[0-9]+]], [[OLD]], 0([[SHIFT]]) -; CHECK: cr [[ROT]], %r3 -; CHECK: jhe [[KEEP:\..*]] +; CHECK: crjhe [[ROT]], %r3, [[KEEP:\..*]] ; CHECK: risbg [[ROT]], %r3, 32, 47, 0 ; CHECK: [[KEEP]]: ; CHECK: rll [[NEW:%r[0-9]+]], [[ROT]], 0({{%r[1-9]+}}) @@ -77,7 +75,7 @@ define i16 @f2(i16 *%src, i16 %b) { ; CHECK-SHIFT2: f2: ; CHECK-SHIFT2: sll %r3, 16 ; CHECK-SHIFT2: rll -; CHECK-SHIFT2: cr {{%r[0-9]+}}, %r3 +; CHECK-SHIFT2: crjhe {{%r[0-9]+}}, %r3 ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: rll ; CHECK-SHIFT2: br %r14 @@ -164,7 +162,7 @@ define i16 @f4(i16 *%src, i16 %b) { define i16 @f5(i16 *%src) { ; CHECK: f5: ; CHECK: llilh [[SRC2:%r[0-9]+]], 32769 -; CHECK: cr [[ROT:%r[0-9]+]], [[SRC2]] +; CHECK: crjle [[ROT:%r[0-9]+]], [[SRC2]] ; CHECK: risbg [[ROT]], [[SRC2]], 32, 47, 0 ; CHECK: br %r14 ; @@ -181,7 +179,7 @@ define i16 @f5(i16 *%src) { define i16 @f6(i16 *%src) { ; CHECK: f6: ; CHECK: llilh [[SRC2:%r[0-9]+]], 32766 -; CHECK: cr [[ROT:%r[0-9]+]], [[SRC2]] +; CHECK: crjhe [[ROT:%r[0-9]+]], [[SRC2]] ; CHECK: risbg [[ROT]], [[SRC2]], 32, 47, 0 ; CHECK: br %r14 ; diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll index 53d0e737e07..4f7d820adaf 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-03.ll @@ -7,9 +7,8 @@ define i32 @f1(i32 %dummy, i32 *%src, i32 %b) { ; CHECK: f1: ; CHECK: l %r2, 0(%r3) ; CHECK: [[LOOP:\.[^:]*]]: -; CHECK: cr %r2, %r4 ; CHECK: lr [[NEW:%r[0-9]+]], %r2 -; CHECK: jle [[KEEP:\..*]] +; CHECK: crjle %r2, %r4, [[KEEP:\..*]] ; CHECK: lr [[NEW]], %r4 ; CHECK: cs %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] @@ -23,9 +22,8 @@ define i32 @f2(i32 %dummy, i32 *%src, i32 %b) { ; CHECK: f2: ; CHECK: l %r2, 0(%r3) ; CHECK: [[LOOP:\.[^:]*]]: -; CHECK: cr %r2, %r4 ; CHECK: lr [[NEW:%r[0-9]+]], %r2 -; CHECK: jhe [[KEEP:\..*]] +; CHECK: crjhe %r2, %r4, [[KEEP:\..*]] ; CHECK: lr [[NEW]], %r4 ; CHECK: cs %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] @@ -164,9 +162,8 @@ define i32 @f13(i32 %dummy, i32 *%ptr) { ; CHECK: lhi [[LIMIT:%r[0-9]+]], 42 ; CHECK: l %r2, 0(%r3) ; CHECK: [[LOOP:\.[^:]*]]: -; CHECK: cr %r2, [[LIMIT]] ; CHECK: lr [[NEW:%r[0-9]+]], %r2 -; CHECK: jle [[KEEP:\..*]] +; CHECK: crjle %r2, [[LIMIT]], [[KEEP:\..*]] ; CHECK: lr [[NEW]], [[LIMIT]] ; CHECK: cs %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] diff --git a/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll b/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll index d7723314180..cd35ab019e0 100644 --- a/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll +++ b/test/CodeGen/SystemZ/atomicrmw-minmax-04.ll @@ -7,9 +7,8 @@ define i64 @f1(i64 %dummy, i64 *%src, i64 %b) { ; CHECK: f1: ; CHECK: lg %r2, 0(%r3) ; CHECK: [[LOOP:\.[^:]*]]: -; CHECK: cgr %r2, %r4 ; CHECK: lgr [[NEW:%r[0-9]+]], %r2 -; CHECK: jle [[KEEP:\..*]] +; CHECK: cgrjle %r2, %r4, [[KEEP:\..*]] ; CHECK: lgr [[NEW]], %r4 ; CHECK: csg %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] @@ -23,9 +22,8 @@ define i64 @f2(i64 %dummy, i64 *%src, i64 %b) { ; CHECK: f2: ; CHECK: lg %r2, 0(%r3) ; CHECK: [[LOOP:\.[^:]*]]: -; CHECK: cgr %r2, %r4 ; CHECK: lgr [[NEW:%r[0-9]+]], %r2 -; CHECK: jhe [[KEEP:\..*]] +; CHECK: cgrjhe %r2, %r4, [[KEEP:\..*]] ; CHECK: lgr [[NEW]], %r4 ; CHECK: csg %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] @@ -131,9 +129,8 @@ define i64 @f10(i64 %dummy, i64 *%ptr) { ; CHECK: lghi [[LIMIT:%r[0-9]+]], 42 ; CHECK: lg %r2, 0(%r3) ; CHECK: [[LOOP:\.[^:]*]]: -; CHECK: cgr %r2, [[LIMIT]] ; CHECK: lgr [[NEW:%r[0-9]+]], %r2 -; CHECK: jle [[KEEP:\..*]] +; CHECK: cgrjle %r2, [[LIMIT]], [[KEEP:\..*]] ; CHECK: lgr [[NEW]], [[LIMIT]] ; CHECK: csg %r2, [[NEW]], 0(%r3) ; CHECK: jlh [[LOOP]] diff --git a/test/CodeGen/SystemZ/branch-02.ll b/test/CodeGen/SystemZ/branch-02.ll index 9365f161430..9f71c053c7b 100644 --- a/test/CodeGen/SystemZ/branch-02.ll +++ b/test/CodeGen/SystemZ/branch-02.ll @@ -1,5 +1,6 @@ ; Test all condition-code masks that are relevant for signed integer -; comparisons. +; comparisons, in cases where a separate branch is better than COMPARE +; AND BRANCH. ; ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s diff --git a/test/CodeGen/SystemZ/branch-06.ll b/test/CodeGen/SystemZ/branch-06.ll new file mode 100644 index 00000000000..3854045e38f --- /dev/null +++ b/test/CodeGen/SystemZ/branch-06.ll @@ -0,0 +1,89 @@ +; Test all condition-code masks that are relevant for CRJ. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i32 @foo(); + +define void @f1(i32 %target) { +; CHECK: f1: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: crje %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i32 @foo() + %cond = icmp eq i32 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f2(i32 %target) { +; CHECK: f2: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: crjlh %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i32 @foo() + %cond = icmp ne i32 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f3(i32 %target) { +; CHECK: f3: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: crjle %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i32 @foo() + %cond = icmp sle i32 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f4(i32 %target) { +; CHECK: f4: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: crjl %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i32 @foo() + %cond = icmp slt i32 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f5(i32 %target) { +; CHECK: f5: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: crjh %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i32 @foo() + %cond = icmp sgt i32 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f6(i32 %target) { +; CHECK: f6: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: crjhe %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i32 @foo() + %cond = icmp sge i32 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} diff --git a/test/CodeGen/SystemZ/branch-07.ll b/test/CodeGen/SystemZ/branch-07.ll new file mode 100644 index 00000000000..1cab6ff28ed --- /dev/null +++ b/test/CodeGen/SystemZ/branch-07.ll @@ -0,0 +1,89 @@ +; Test all condition-code masks that are relevant for CGRJ. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i64 @foo(); + +define void @f1(i64 %target) { +; CHECK: f1: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: cgrje %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i64 @foo() + %cond = icmp eq i64 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f2(i64 %target) { +; CHECK: f2: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: cgrjlh %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i64 @foo() + %cond = icmp ne i64 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f3(i64 %target) { +; CHECK: f3: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: cgrjle %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i64 @foo() + %cond = icmp sle i64 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f4(i64 %target) { +; CHECK: f4: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: cgrjl %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i64 @foo() + %cond = icmp slt i64 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f5(i64 %target) { +; CHECK: f5: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: cgrjh %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i64 @foo() + %cond = icmp sgt i64 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} + +define void @f6(i64 %target) { +; CHECK: f6: +; CHECK: .cfi_def_cfa_offset +; CHECK: .L[[LABEL:.*]]: +; CHECK: cgrjhe %r2, {{%r[0-9]+}}, .L[[LABEL]] + br label %loop +loop: + %val = call i64 @foo() + %cond = icmp sge i64 %val, %target + br i1 %cond, label %loop, label %exit +exit: + ret void +} diff --git a/test/CodeGen/SystemZ/cmpxchg-01.ll b/test/CodeGen/SystemZ/cmpxchg-01.ll index e8488615bd1..03fabee1328 100644 --- a/test/CodeGen/SystemZ/cmpxchg-01.ll +++ b/test/CodeGen/SystemZ/cmpxchg-01.ll @@ -18,8 +18,7 @@ define i8 @f1(i8 %dummy, i8 *%src, i8 %cmp, i8 %swap) { ; CHECK-MAIN: [[LOOP:\.[^ ]*]]: ; CHECK-MAIN: rll %r2, [[OLD]], 8([[SHIFT]]) ; CHECK-MAIN: risbg %r4, %r2, 32, 55, 0 -; CHECK-MAIN: cr %r2, %r4 -; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]] +; CHECK-MAIN: crjlh %r2, %r4, [[EXIT:\.[^ ]*]] ; CHECK-MAIN: risbg %r5, %r2, 32, 55, 0 ; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r5, -8({{%r[1-9]+}}) ; CHECK-MAIN: cs [[OLD]], [[NEW]], 0(%r3) diff --git a/test/CodeGen/SystemZ/cmpxchg-02.ll b/test/CodeGen/SystemZ/cmpxchg-02.ll index 2c2f76cd7c1..b5005bb291e 100644 --- a/test/CodeGen/SystemZ/cmpxchg-02.ll +++ b/test/CodeGen/SystemZ/cmpxchg-02.ll @@ -18,8 +18,7 @@ define i16 @f1(i16 %dummy, i16 *%src, i16 %cmp, i16 %swap) { ; CHECK-MAIN: [[LOOP:\.[^ ]*]]: ; CHECK-MAIN: rll %r2, [[OLD]], 16([[SHIFT]]) ; CHECK-MAIN: risbg %r4, %r2, 32, 47, 0 -; CHECK-MAIN: cr %r2, %r4 -; CHECK-MAIN: jlh [[EXIT:\.[^ ]*]] +; CHECK-MAIN: crjlh %r2, %r4, [[EXIT:\.[^ ]*]] ; CHECK-MAIN: risbg %r5, %r2, 32, 47, 0 ; CHECK-MAIN: rll [[NEW:%r[0-9]+]], %r5, -16({{%r[1-9]+}}) ; CHECK-MAIN: cs [[OLD]], [[NEW]], 0(%r3) diff --git a/test/CodeGen/SystemZ/int-cmp-02.ll b/test/CodeGen/SystemZ/int-cmp-02.ll index 262ade0b99b..b98661ed4dd 100644 --- a/test/CodeGen/SystemZ/int-cmp-02.ll +++ b/test/CodeGen/SystemZ/int-cmp-02.ll @@ -5,8 +5,7 @@ ; Check register comparison. define double @f1(double %a, double %b, i32 %i1, i32 %i2) { ; CHECK: f1: -; CHECK: cr %r2, %r3 -; CHECK-NEXT: jl +; CHECK: crjl %r2, %r3 ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp slt i32 %i1, %i2 diff --git a/test/CodeGen/SystemZ/int-cmp-07.ll b/test/CodeGen/SystemZ/int-cmp-07.ll index 6e626bca7f1..48ccf5cb30b 100644 --- a/test/CodeGen/SystemZ/int-cmp-07.ll +++ b/test/CodeGen/SystemZ/int-cmp-07.ll @@ -5,8 +5,7 @@ ; Check CGR. define double @f1(double %a, double %b, i64 %i1, i64 %i2) { ; CHECK: f1: -; CHECK: cgr %r2, %r3 -; CHECK-NEXT: jl +; CHECK: cgrjl %r2, %r3 ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp slt i64 %i1, %i2 diff --git a/test/CodeGen/SystemZ/int-cmp-11.ll b/test/CodeGen/SystemZ/int-cmp-11.ll index 876882ea8f3..64386f05d1e 100644 --- a/test/CodeGen/SystemZ/int-cmp-11.ll +++ b/test/CodeGen/SystemZ/int-cmp-11.ll @@ -65,8 +65,7 @@ define double @f5(double %a, double %b, i64 %i1) { ; Check the next value up, which must use register comparison. define double @f6(double %a, double %b, i64 %i1) { ; CHECK: f6: -; CHECK: cgr -; CHECK-NEXT: jl +; CHECK: cgrjl ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp slt i64 %i1, 2147483648 @@ -125,8 +124,7 @@ define double @f10(double %a, double %b, i64 %i1) { ; Check the next value down, which must use register comparison. define double @f11(double %a, double %b, i64 %i1) { ; CHECK: f11: -; CHECK: cgr -; CHECK-NEXT: jl +; CHECK: cgrjl ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp slt i64 %i1, -2147483649 diff --git a/test/CodeGen/SystemZ/int-cmp-13.ll b/test/CodeGen/SystemZ/int-cmp-13.ll index 0eec8903056..aab95473a00 100644 --- a/test/CodeGen/SystemZ/int-cmp-13.ll +++ b/test/CodeGen/SystemZ/int-cmp-13.ll @@ -77,8 +77,7 @@ define double @f6(double %a, double %b, i64 %i1) { ; Check the next value up, which must use a register comparison. define double @f7(double %a, double %b, i64 %i1) { ; CHECK: f7: -; CHECK: cgr %r2, -; CHECK-NEXT: je +; CHECK: cgrje %r2, ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp eq i64 %i1, 4294967296 @@ -137,8 +136,7 @@ define double @f11(double %a, double %b, i64 %i1) { ; Check the next value down, which must use register comparison. define double @f12(double %a, double %b, i64 %i1) { ; CHECK: f12: -; CHECK: cgr -; CHECK-NEXT: je +; CHECK: cgrje ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp eq i64 %i1, -2147483649 diff --git a/test/CodeGen/SystemZ/int-cmp-14.ll b/test/CodeGen/SystemZ/int-cmp-14.ll index e3a561e38aa..28c325c005e 100644 --- a/test/CodeGen/SystemZ/int-cmp-14.ll +++ b/test/CodeGen/SystemZ/int-cmp-14.ll @@ -77,8 +77,7 @@ define double @f6(double %a, double %b, i64 %i1) { ; Check the next value up, which must use a register comparison. define double @f7(double %a, double %b, i64 %i1) { ; CHECK: f7: -; CHECK: cgr %r2, -; CHECK-NEXT: jlh +; CHECK: cgrjlh %r2, ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp ne i64 %i1, 4294967296 @@ -137,8 +136,7 @@ define double @f11(double %a, double %b, i64 %i1) { ; Check the next value down, which must use register comparison. define double @f12(double %a, double %b, i64 %i1) { ; CHECK: f12: -; CHECK: cgr -; CHECK-NEXT: jlh +; CHECK: cgrjlh ; CHECK: ldr %f0, %f2 ; CHECK: br %r14 %cond = icmp ne i64 %i1, -2147483649 diff --git a/test/MC/Disassembler/SystemZ/insns-pcrel.txt b/test/MC/Disassembler/SystemZ/insns-pcrel.txt index 1f2d8d0094d..0b135377f34 100644 --- a/test/MC/Disassembler/SystemZ/insns-pcrel.txt +++ b/test/MC/Disassembler/SystemZ/insns-pcrel.txt @@ -931,3 +931,178 @@ # CHECK: strl %r15, 0x100000530 0xc4 0xff 0x7f 0xff 0xff 0xff +# 0x00000538: +# CHECK: cgrj %r0, %r0, 0, 0x538 +0xec 0x00 0x00 0x00 0x00 0x64 + +# 0x0000053e: +# CHECK: cgrj %r0, %r15, 0, 0x53e +0xec 0x0f 0x00 0x00 0x00 0x64 + +# 0x00000544: +# CHECK: cgrj %r15, %r0, 0, 0x544 +0xec 0xf0 0x00 0x00 0x00 0x64 + +# 0x0000054a: +# CHECK: cgrj %r7, %r8, 0, 0x54a +0xec 0x78 0x00 0x00 0x00 0x64 + +# 0x00000550: +# CHECK: cgrj %r0, %r0, 0, 0x54e +0xec 0x00 0xff 0xff 0x00 0x64 + +# 0x00000556: +# CHECK: cgrj %r0, %r0, 0, 0xffffffffffff0556 +0xec 0x00 0x80 0x00 0x00 0x64 + +# 0x0000055c: +# CHECK: cgrj %r0, %r0, 0, 0x1055a +0xec 0x00 0x7f 0xff 0x00 0x64 + +# 0x00000562: +# CHECK: cgrj %r0, %r0, 1, 0x562 +0xec 0x00 0x00 0x00 0x10 0x64 + +# 0x00000568: +# CHECK: cgrjh %r0, %r0, 0x568 +0xec 0x00 0x00 0x00 0x20 0x64 + +# 0x0000056e: +# CHECK: cgrj %r0, %r0, 3, 0x56e +0xec 0x00 0x00 0x00 0x30 0x64 + +# 0x00000574: +# CHECK: cgrjl %r0, %r0, 0x574 +0xec 0x00 0x00 0x00 0x40 0x64 + +# 0x0000057a: +# CHECK: cgrj %r0, %r0, 5, 0x57a +0xec 0x00 0x00 0x00 0x50 0x64 + +# 0x00000580: +# CHECK: cgrjlh %r0, %r0, 0x580 +0xec 0x00 0x00 0x00 0x60 0x64 + +# 0x00000586: +# CHECK: cgrj %r0, %r0, 7, 0x586 +0xec 0x00 0x00 0x00 0x70 0x64 + +# 0x0000058c: +# CHECK: cgrje %r0, %r0, 0x58c +0xec 0x00 0x00 0x00 0x80 0x64 + +# 0x00000592: +# CHECK: cgrj %r0, %r0, 9, 0x592 +0xec 0x00 0x00 0x00 0x90 0x64 + +# 0x00000598: +# CHECK: cgrjhe %r0, %r0, 0x598 +0xec 0x00 0x00 0x00 0xa0 0x64 + +# 0x0000059e: +# CHECK: cgrj %r0, %r0, 11, 0x59e +0xec 0x00 0x00 0x00 0xb0 0x64 + +# 0x000005a4: +# CHECK: cgrjle %r0, %r0, 0x5a4 +0xec 0x00 0x00 0x00 0xc0 0x64 + +# 0x000005aa: +# CHECK: cgrj %r0, %r0, 13, 0x5aa +0xec 0x00 0x00 0x00 0xd0 0x64 + +# 0x000005b0: +# CHECK: cgrj %r0, %r0, 14, 0x5b0 +0xec 0x00 0x00 0x00 0xe0 0x64 + +# 0x000005b6: +# CHECK: cgrj %r0, %r0, 15, 0x5b6 +0xec 0x00 0x00 0x00 0xf0 0x64 + +# 0x000005bc: +# CHECK: crj %r0, %r0, 0, 0x5bc +0xec 0x00 0x00 0x00 0x00 0x76 + +# 0x000005c2: +# CHECK: crj %r0, %r15, 0, 0x5c2 +0xec 0x0f 0x00 0x00 0x00 0x76 + +# 0x000005c8: +# CHECK: crj %r15, %r0, 0, 0x5c8 +0xec 0xf0 0x00 0x00 0x00 0x76 + +# 0x000005ce: +# CHECK: crj %r7, %r8, 0, 0x5ce +0xec 0x78 0x00 0x00 0x00 0x76 + +# 0x000005d4: +# CHECK: crj %r0, %r0, 0, 0x5d2 +0xec 0x00 0xff 0xff 0x00 0x76 + +# 0x000005da: +# CHECK: crj %r0, %r0, 0, 0xffffffffffff05da +0xec 0x00 0x80 0x00 0x00 0x76 + +# 0x000005e0: +# CHECK: crj %r0, %r0, 0, 0x105de +0xec 0x00 0x7f 0xff 0x00 0x76 + +# 0x000005e6: +# CHECK: crj %r0, %r0, 1, 0x5e6 +0xec 0x00 0x00 0x00 0x10 0x76 + +# 0x000005ec: +# CHECK: crjh %r0, %r0, 0x5ec +0xec 0x00 0x00 0x00 0x20 0x76 + +# 0x000005f2: +# CHECK: crj %r0, %r0, 3, 0x5f2 +0xec 0x00 0x00 0x00 0x30 0x76 + +# 0x000005f8: +# CHECK: crjl %r0, %r0, 0x5f8 +0xec 0x00 0x00 0x00 0x40 0x76 + +# 0x000005fe: +# CHECK: crj %r0, %r0, 5, 0x5fe +0xec 0x00 0x00 0x00 0x50 0x76 + +# 0x00000604: +# CHECK: crjlh %r0, %r0, 0x604 +0xec 0x00 0x00 0x00 0x60 0x76 + +# 0x0000060a: +# CHECK: crj %r0, %r0, 7, 0x60a +0xec 0x00 0x00 0x00 0x70 0x76 + +# 0x00000610: +# CHECK: crje %r0, %r0, 0x610 +0xec 0x00 0x00 0x00 0x80 0x76 + +# 0x00000616: +# CHECK: crj %r0, %r0, 9, 0x616 +0xec 0x00 0x00 0x00 0x90 0x76 + +# 0x0000061c: +# CHECK: crjhe %r0, %r0, 0x61c +0xec 0x00 0x00 0x00 0xa0 0x76 + +# 0x00000622: +# CHECK: crj %r0, %r0, 11, 0x622 +0xec 0x00 0x00 0x00 0xb0 0x76 + +# 0x00000628: +# CHECK: crjle %r0, %r0, 0x628 +0xec 0x00 0x00 0x00 0xc0 0x76 + +# 0x0000062e: +# CHECK: crj %r0, %r0, 13, 0x62e +0xec 0x00 0x00 0x00 0xd0 0x76 + +# 0x00000634: +# CHECK: crj %r0, %r0, 14, 0x634 +0xec 0x00 0x00 0x00 0xe0 0x76 + +# 0x0000063a: +# CHECK: crj %r0, %r0, 15, 0x63a +0xec 0x00 0x00 0x00 0xf0 0x76 diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s index f1d86db437a..ea249119c79 100644 --- a/test/MC/SystemZ/insn-bad.s +++ b/test/MC/SystemZ/insn-bad.s @@ -452,6 +452,28 @@ cghsi 0, -32769 cghsi 0, 32768 +#CHECK: error: offset out of range +#CHECK: cgrj %r0, %r0, 0, -0x100002 +#CHECK: error: offset out of range +#CHECK: cgrj %r0, %r0, 0, -1 +#CHECK: error: offset out of range +#CHECK: cgrj %r0, %r0, 0, 1 +#CHECK: error: offset out of range +#CHECK: cgrj %r0, %r0, 0, 0x10000 + + cgrj %r0, %r0, 0, -0x100002 + cgrj %r0, %r0, 0, -1 + cgrj %r0, %r0, 0, 1 + cgrj %r0, %r0, 0, 0x10000 + +#CHECK: error: invalid instruction +#CHECK: cgrjo %r0, %r0, 0, 0 +#CHECK: error: invalid instruction +#CHECK: cgrjno %r0, %r0, 0, 0 + + cgrjo %r0, %r0, 0, 0 + cgrjno %r0, %r0, 0, 0 + #CHECK: error: offset out of range #CHECK: cgrl %r0, -0x1000000002 #CHECK: error: offset out of range @@ -756,6 +778,28 @@ cly %r0, -524289 cly %r0, 524288 +#CHECK: error: offset out of range +#CHECK: crj %r0, %r0, 0, -0x100002 +#CHECK: error: offset out of range +#CHECK: crj %r0, %r0, 0, -1 +#CHECK: error: offset out of range +#CHECK: crj %r0, %r0, 0, 1 +#CHECK: error: offset out of range +#CHECK: crj %r0, %r0, 0, 0x10000 + + crj %r0, %r0, 0, -0x100002 + crj %r0, %r0, 0, -1 + crj %r0, %r0, 0, 1 + crj %r0, %r0, 0, 0x10000 + +#CHECK: error: invalid instruction +#CHECK: crjo %r0, %r0, 0, 0 +#CHECK: error: invalid instruction +#CHECK: crjno %r0, %r0, 0, 0 + + crjo %r0, %r0, 0, 0 + crjno %r0, %r0, 0, 0 + #CHECK: error: offset out of range #CHECK: crl %r0, -0x1000000002 #CHECK: error: offset out of range diff --git a/test/MC/SystemZ/insn-good.s b/test/MC/SystemZ/insn-good.s index 99548ab362c..8188de3b563 100644 --- a/test/MC/SystemZ/insn-good.s +++ b/test/MC/SystemZ/insn-good.s @@ -1523,6 +1523,236 @@ cgr %r15,%r0 cgr %r7,%r8 +#CHECK: cgrj %r0, %r0, 0, .[[LAB:L.*]] # encoding: [0xec,0x00,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL +#CHECK: cgrj %r0, %r15, 0, .[[LAB:L.*]] # encoding: [0xec,0x0f,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL +#CHECK: cgrj %r15, %r0, 0, .[[LAB:L.*]] # encoding: [0xec,0xf0,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL +#CHECK: cgrj %r7, %r8, 0, .[[LAB:L.*]] # encoding: [0xec,0x78,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL + cgrj %r0,%r0,0,0 + cgrj %r0,%r15,0,0 + cgrj %r15,%r0,0,0 + cgrj %r7,%r8,0,0 + +#CHECK: cgrj %r1, %r2, 0, .[[LAB:L.*]]-65536 # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, -0x10000 +#CHECK: cgrj %r1, %r2, 0, .[[LAB:L.*]]-2 # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, -2 +#CHECK: cgrj %r1, %r2, 0, .[[LAB:L.*]] # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, 0 +#CHECK: cgrj %r1, %r2, 0, .[[LAB:L.*]]+65534 # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, 0xfffe + +#CHECK: cgrj %r1, %r2, 0, foo # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, foo + +#CHECK: cgrj %r1, %r2, 1, foo # encoding: [0xec,0x12,A,A,0x10,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 1, foo + +#CHECK: cgrj %r1, %r2, 2, foo # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjnle %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 2, foo + cgrjh %r1, %r2, foo + cgrjnle %r1, %r2, foo + +#CHECK: cgrj %r1, %r2, 3, foo # encoding: [0xec,0x12,A,A,0x30,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 3, foo + +#CHECK: cgrj %r1, %r2, 4, foo # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjl %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjnhe %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 4, foo + cgrjl %r1, %r2, foo + cgrjnhe %r1, %r2, foo + +#CHECK: cgrj %r1, %r2, 5, foo # encoding: [0xec,0x12,A,A,0x50,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 5, foo + +#CHECK: cgrj %r1, %r2, 6, foo # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjlh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjne %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 6, foo + cgrjlh %r1, %r2, foo + cgrjne %r1, %r2, foo + +#CHECK: cgrj %r1, %r2, 7, foo # encoding: [0xec,0x12,A,A,0x70,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 7, foo + +#CHECK: cgrj %r1, %r2, 8, foo # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrje %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjnlh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 8, foo + cgrje %r1, %r2, foo + cgrjnlh %r1, %r2, foo + +#CHECK: cgrj %r1, %r2, 9, foo # encoding: [0xec,0x12,A,A,0x90,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 9, foo + +#CHECK: cgrj %r1, %r2, 10, foo # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjhe %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjnl %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 10, foo + cgrjhe %r1, %r2, foo + cgrjnl %r1, %r2, foo + +#CHECK: cgrj %r1, %r2, 11, foo # encoding: [0xec,0x12,A,A,0xb0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 11, foo + +#CHECK: cgrj %r1, %r2, 12, foo # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjle %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: cgrjnh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 12, foo + cgrjle %r1, %r2, foo + cgrjnh %r1, %r2, foo + +#CHECK: cgrj %r1, %r2, 13, foo # encoding: [0xec,0x12,A,A,0xd0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 13, foo + +#CHECK: cgrj %r1, %r2, 14, foo # encoding: [0xec,0x12,A,A,0xe0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 14, foo + +#CHECK: cgrj %r1, %r2, 15, foo # encoding: [0xec,0x12,A,A,0xf0,0x64] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 15, foo + +#CHECK: cgrj %r1, %r2, 0, bar+100 # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, bar+100 + +#CHECK: cgrjh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjh %r1, %r2, bar+100 + +#CHECK: cgrjnle %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjnle %r1, %r2, bar+100 + +#CHECK: cgrjl %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjl %r1, %r2, bar+100 + +#CHECK: cgrjnhe %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjnhe %r1, %r2, bar+100 + +#CHECK: cgrjlh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjlh %r1, %r2, bar+100 + +#CHECK: cgrjne %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjne %r1, %r2, bar+100 + +#CHECK: cgrje %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrje %r1, %r2, bar+100 + +#CHECK: cgrjnlh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjnlh %r1, %r2, bar+100 + +#CHECK: cgrjhe %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjhe %r1, %r2, bar+100 + +#CHECK: cgrjnl %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjnl %r1, %r2, bar+100 + +#CHECK: cgrjle %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjle %r1, %r2, bar+100 + +#CHECK: cgrjnh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + cgrjnh %r1, %r2, bar+100 + +#CHECK: cgrj %r1, %r2, 0, bar@PLT # encoding: [0xec,0x12,A,A,0x00,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrj %r1, %r2, 0, bar@PLT + +#CHECK: cgrjh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjh %r1, %r2, bar@PLT + +#CHECK: cgrjnle %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x20,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjnle %r1, %r2, bar@PLT + +#CHECK: cgrjl %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjl %r1, %r2, bar@PLT + +#CHECK: cgrjnhe %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x40,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjnhe %r1, %r2, bar@PLT + +#CHECK: cgrjlh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjlh %r1, %r2, bar@PLT + +#CHECK: cgrjne %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x60,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjne %r1, %r2, bar@PLT + +#CHECK: cgrje %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrje %r1, %r2, bar@PLT + +#CHECK: cgrjnlh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x80,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjnlh %r1, %r2, bar@PLT + +#CHECK: cgrjhe %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjhe %r1, %r2, bar@PLT + +#CHECK: cgrjnl %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xa0,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjnl %r1, %r2, bar@PLT + +#CHECK: cgrjle %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjle %r1, %r2, bar@PLT + +#CHECK: cgrjnh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xc0,0x64] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + cgrjnh %r1, %r2, bar@PLT + #CHECK: cgrl %r0, .[[LAB:L.*]]-4294967296 # encoding: [0xc6,0x08,A,A,A,A] #CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL cgrl %r0, -0x100000000 @@ -2133,6 +2363,236 @@ cr %r15,%r0 cr %r7,%r8 +#CHECK: crj %r0, %r0, 0, .[[LAB:L.*]] # encoding: [0xec,0x00,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL +#CHECK: crj %r0, %r15, 0, .[[LAB:L.*]] # encoding: [0xec,0x0f,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL +#CHECK: crj %r15, %r0, 0, .[[LAB:L.*]] # encoding: [0xec,0xf0,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL +#CHECK: crj %r7, %r8, 0, .[[LAB:L.*]] # encoding: [0xec,0x78,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL + crj %r0,%r0,0,0 + crj %r0,%r15,0,0 + crj %r15,%r0,0,0 + crj %r7,%r8,0,0 + +#CHECK: crj %r1, %r2, 0, .[[LAB:L.*]]-65536 # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, -0x10000 +#CHECK: crj %r1, %r2, 0, .[[LAB:L.*]]-2 # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, -2 +#CHECK: crj %r1, %r2, 0, .[[LAB:L.*]] # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, 0 +#CHECK: crj %r1, %r2, 0, .[[LAB:L.*]]+65534 # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, 0xfffe + +#CHECK: crj %r1, %r2, 0, foo # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, foo + +#CHECK: crj %r1, %r2, 1, foo # encoding: [0xec,0x12,A,A,0x10,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 1, foo + +#CHECK: crj %r1, %r2, 2, foo # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjnle %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 2, foo + crjh %r1, %r2, foo + crjnle %r1, %r2, foo + +#CHECK: crj %r1, %r2, 3, foo # encoding: [0xec,0x12,A,A,0x30,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 3, foo + +#CHECK: crj %r1, %r2, 4, foo # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjl %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjnhe %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 4, foo + crjl %r1, %r2, foo + crjnhe %r1, %r2, foo + +#CHECK: crj %r1, %r2, 5, foo # encoding: [0xec,0x12,A,A,0x50,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 5, foo + +#CHECK: crj %r1, %r2, 6, foo # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjlh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjne %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 6, foo + crjlh %r1, %r2, foo + crjne %r1, %r2, foo + +#CHECK: crj %r1, %r2, 7, foo # encoding: [0xec,0x12,A,A,0x70,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 7, foo + +#CHECK: crj %r1, %r2, 8, foo # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crje %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjnlh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 8, foo + crje %r1, %r2, foo + crjnlh %r1, %r2, foo + +#CHECK: crj %r1, %r2, 9, foo # encoding: [0xec,0x12,A,A,0x90,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 9, foo + +#CHECK: crj %r1, %r2, 10, foo # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjhe %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjnl %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 10, foo + crjhe %r1, %r2, foo + crjnl %r1, %r2, foo + +#CHECK: crj %r1, %r2, 11, foo # encoding: [0xec,0x12,A,A,0xb0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 11, foo + +#CHECK: crj %r1, %r2, 12, foo # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjle %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: crjnh %r1, %r2, foo # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 12, foo + crjle %r1, %r2, foo + crjnh %r1, %r2, foo + +#CHECK: crj %r1, %r2, 13, foo # encoding: [0xec,0x12,A,A,0xd0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 13, foo + +#CHECK: crj %r1, %r2, 14, foo # encoding: [0xec,0x12,A,A,0xe0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 14, foo + +#CHECK: crj %r1, %r2, 15, foo # encoding: [0xec,0x12,A,A,0xf0,0x76] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + crj %r1, %r2, 15, foo + +#CHECK: crj %r1, %r2, 0, bar+100 # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, bar+100 + +#CHECK: crjh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjh %r1, %r2, bar+100 + +#CHECK: crjnle %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjnle %r1, %r2, bar+100 + +#CHECK: crjl %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjl %r1, %r2, bar+100 + +#CHECK: crjnhe %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjnhe %r1, %r2, bar+100 + +#CHECK: crjlh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjlh %r1, %r2, bar+100 + +#CHECK: crjne %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjne %r1, %r2, bar+100 + +#CHECK: crje %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crje %r1, %r2, bar+100 + +#CHECK: crjnlh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjnlh %r1, %r2, bar+100 + +#CHECK: crjhe %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjhe %r1, %r2, bar+100 + +#CHECK: crjnl %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjnl %r1, %r2, bar+100 + +#CHECK: crjle %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjle %r1, %r2, bar+100 + +#CHECK: crjnh %r1, %r2, bar+100 # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + crjnh %r1, %r2, bar+100 + +#CHECK: crj %r1, %r2, 0, bar@PLT # encoding: [0xec,0x12,A,A,0x00,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crj %r1, %r2, 0, bar@PLT + +#CHECK: crjh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjh %r1, %r2, bar@PLT + +#CHECK: crjnle %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x20,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjnle %r1, %r2, bar@PLT + +#CHECK: crjl %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjl %r1, %r2, bar@PLT + +#CHECK: crjnhe %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x40,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjnhe %r1, %r2, bar@PLT + +#CHECK: crjlh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjlh %r1, %r2, bar@PLT + +#CHECK: crjne %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x60,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjne %r1, %r2, bar@PLT + +#CHECK: crje %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crje %r1, %r2, bar@PLT + +#CHECK: crjnlh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0x80,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjnlh %r1, %r2, bar@PLT + +#CHECK: crjhe %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjhe %r1, %r2, bar@PLT + +#CHECK: crjnl %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xa0,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjnl %r1, %r2, bar@PLT + +#CHECK: crjle %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjle %r1, %r2, bar@PLT + +#CHECK: crjnh %r1, %r2, bar@PLT # encoding: [0xec,0x12,A,A,0xc0,0x76] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + crjnh %r1, %r2, bar@PLT + #CHECK: crl %r0, .[[LAB:L.*]]-4294967296 # encoding: [0xc6,0x0d,A,A,A,A] #CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL crl %r0, -0x100000000