From 477168192c98e1f75a5bc6db3d34a177f327bd34 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 28 Aug 2013 10:31:43 +0000 Subject: [PATCH] [SystemZ] Add support for TMHH, TMHL, TMLH and TMLL For now just handles simple comparisons of an ANDed value with zero. The CC value provides enough information to do any comparison for a 2-bit mask, and some nonzero comparisons with more populated masks, but that's all future work. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189469 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZ.h | 7 + lib/Target/SystemZ/SystemZISelLowering.cpp | 61 +++++-- lib/Target/SystemZ/SystemZISelLowering.h | 4 + lib/Target/SystemZ/SystemZInstrInfo.td | 13 ++ lib/Target/SystemZ/SystemZOperators.td | 1 + test/CodeGen/SystemZ/int-cmp-44.ll | 4 +- test/CodeGen/SystemZ/int-cmp-46.ll | 99 +++++++++++ test/CodeGen/SystemZ/int-cmp-47.ll | 193 +++++++++++++++++++++ test/MC/Disassembler/SystemZ/insns.txt | 48 +++++ test/MC/SystemZ/insn-bad.s | 32 ++++ test/MC/SystemZ/insn-good.s | 40 +++++ 11 files changed, 490 insertions(+), 12 deletions(-) create mode 100644 test/CodeGen/SystemZ/int-cmp-46.ll create mode 100644 test/CodeGen/SystemZ/int-cmp-47.ll diff --git a/lib/Target/SystemZ/SystemZ.h b/lib/Target/SystemZ/SystemZ.h index ea6c7d17fa5..051ba1dcfb6 100644 --- a/lib/Target/SystemZ/SystemZ.h +++ b/lib/Target/SystemZ/SystemZ.h @@ -57,6 +57,13 @@ namespace llvm { const unsigned CCMASK_SRST_NOTFOUND = CCMASK_2; const unsigned CCMASK_SRST = CCMASK_1 | CCMASK_2; + // Condition-code mask assignments for TEST UNDER MASK. + const unsigned CCMASK_TM_ALL_0 = CCMASK_0; + const unsigned CCMASK_TM_MIXED_MSB_0 = CCMASK_1; + const unsigned CCMASK_TM_MIXED_MSB_1 = CCMASK_2; + const unsigned CCMASK_TM_ALL_1 = CCMASK_3; + const unsigned CCMASK_TM = CCMASK_ANY; + // Mask assignments for PFD. const unsigned PFD_READ = 1; const unsigned PFD_WRITE = 2; diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index dd230c62a5a..1ab1ef4acaf 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -1072,8 +1072,8 @@ static void adjustSubwordCmp(SelectionDAG &DAG, bool &IsUnsigned, // Return true if a comparison described by CCMask, CmpOp0 and CmpOp1 // is an equality comparison that is better implemented using unsigned // rather than signed comparison instructions. -static bool preferUnsignedComparison(SelectionDAG &DAG, SDValue CmpOp0, - SDValue CmpOp1, unsigned CCMask) { +static bool preferUnsignedComparison(SDValue CmpOp0, SDValue CmpOp1, + unsigned CCMask) { // The test must be for equality or inequality. if (CCMask != SystemZ::CCMASK_CMP_EQ && CCMask != SystemZ::CCMASK_CMP_NE) return false; @@ -1176,12 +1176,52 @@ static bool shouldSwapCmpOperands(SDValue Op0, SDValue Op1, return false; } +// See whether the comparison (Opcode CmpOp0, CmpOp1) can be implemented +// as a TEST UNDER MASK instruction when the condition being tested is +// as described by CCValid and CCMask. Update the arguments with the +// TM version if so. +static void adjustForTestUnderMask(unsigned &Opcode, SDValue &CmpOp0, + SDValue &CmpOp1, unsigned &CCValid, + unsigned &CCMask) { + // For now we just handle equality and inequality with zero. + if (CCMask != SystemZ::CCMASK_CMP_EQ && + (CCMask ^ CCValid) != SystemZ::CCMASK_CMP_EQ) + return; + ConstantSDNode *ConstCmpOp1 = dyn_cast(CmpOp1); + if (!ConstCmpOp1 || ConstCmpOp1->getZExtValue() != 0) + return; + + // Check whether the nonconstant input is an AND with a constant mask. + if (CmpOp0.getOpcode() != ISD::AND) + return; + SDValue AndOp0 = CmpOp0.getOperand(0); + SDValue AndOp1 = CmpOp0.getOperand(1); + ConstantSDNode *Mask = dyn_cast(AndOp1.getNode()); + if (!Mask) + return; + + // Check whether the mask is suitable for TMHH, TMHL, TMLH or TMLL. + uint64_t MaskVal = Mask->getZExtValue(); + if (!SystemZ::isImmLL(MaskVal) && !SystemZ::isImmLH(MaskVal) && + !SystemZ::isImmHL(MaskVal) && !SystemZ::isImmHH(MaskVal)) + return; + + // Go ahead and make the change. + Opcode = SystemZISD::TM; + CmpOp0 = AndOp0; + CmpOp1 = AndOp1; + CCValid = SystemZ::CCMASK_TM; + CCMask = (CCMask == SystemZ::CCMASK_CMP_EQ ? + SystemZ::CCMASK_TM_ALL_0 : + SystemZ::CCMASK_TM_ALL_0 ^ CCValid); +} + // Return a target node that compares CmpOp0 with CmpOp1 and stores a // 2-bit result in CC. Set CCValid to the CCMASK_* of all possible // 2-bit results and CCMask to the subset of those results that are // associated with Cond. -static SDValue emitCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, - ISD::CondCode Cond, unsigned &CCValid, +static SDValue emitCmp(SelectionDAG &DAG, SDLoc DL, SDValue CmpOp0, + SDValue CmpOp1, ISD::CondCode Cond, unsigned &CCValid, unsigned &CCMask) { bool IsUnsigned = false; CCMask = CCMaskForCondCode(Cond); @@ -1193,7 +1233,7 @@ static SDValue emitCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, CCMask &= CCValid; adjustZeroCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); adjustSubwordCmp(DAG, IsUnsigned, CmpOp0, CmpOp1, CCMask); - if (preferUnsignedComparison(DAG, CmpOp0, CmpOp1, CCMask)) + if (preferUnsignedComparison(CmpOp0, CmpOp1, CCMask)) IsUnsigned = true; } @@ -1205,9 +1245,9 @@ static SDValue emitCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, (CCMask & SystemZ::CCMASK_CMP_UO)); } - SDLoc DL(CmpOp0); - return DAG.getNode((IsUnsigned ? SystemZISD::UCMP : SystemZISD::CMP), - DL, MVT::Glue, CmpOp0, CmpOp1); + unsigned Opcode = (IsUnsigned ? SystemZISD::UCMP : SystemZISD::CMP); + adjustForTestUnderMask(Opcode, CmpOp0, CmpOp1, CCValid, CCMask); + return DAG.getNode(Opcode, DL, MVT::Glue, CmpOp0, CmpOp1); } // Implement a 32-bit *MUL_LOHI operation by extending both operands to @@ -1256,7 +1296,7 @@ SDValue SystemZTargetLowering::lowerBR_CC(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); unsigned CCValid, CCMask; - SDValue Flags = emitCmp(DAG, CmpOp0, CmpOp1, CC, CCValid, CCMask); + SDValue Flags = emitCmp(DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); return DAG.getNode(SystemZISD::BR_CCMASK, DL, Op.getValueType(), Chain, DAG.getConstant(CCValid, MVT::i32), DAG.getConstant(CCMask, MVT::i32), Dest, Flags); @@ -1272,7 +1312,7 @@ SDValue SystemZTargetLowering::lowerSELECT_CC(SDValue Op, SDLoc DL(Op); unsigned CCValid, CCMask; - SDValue Flags = emitCmp(DAG, CmpOp0, CmpOp1, CC, CCValid, CCMask); + SDValue Flags = emitCmp(DAG, DL, CmpOp0, CmpOp1, CC, CCValid, CCMask); SmallVector Ops; Ops.push_back(TrueOp); @@ -1908,6 +1948,7 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { OPCODE(PCREL_WRAPPER); OPCODE(CMP); OPCODE(UCMP); + OPCODE(TM); OPCODE(BR_CCMASK); OPCODE(SELECT_CCMASK); OPCODE(ADJDYNALLOC); diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index 9831777873a..ec5051f3e6e 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -45,6 +45,10 @@ namespace SystemZISD { // Likewise unsigned integer comparison. UCMP, + // Test under mask. The first operand is ANDed with the second operand + // and the condition codes are set on the result. + TM, + // Branches if a condition is true. Operand 0 is the chain operand; // operand 1 is the 4-bit condition-code mask, with bit N in // big-endian order meaning "branch if CC=N"; operand 2 is the diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 399b48a3368..7793818b796 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -1034,6 +1034,19 @@ let mayLoad = 1, Defs = [CC] in let mayLoad = 1, Defs = [CC], Uses = [R0W] in defm CLST : StringRRE<"clst", 0xB25D, z_strcmp>; +// Test under mask. +let Defs = [CC] in { + let isCodeGenOnly = 1 in { + def TMLL32 : CompareRI<"tmll", 0xA71, z_tm, GR32, imm32ll16>; + def TMLH32 : CompareRI<"tmlh", 0xA70, z_tm, GR32, imm32lh16>; + } + + def TMLL : CompareRI<"tmll", 0xA71, z_tm, GR64, imm64ll16>; + def TMLH : CompareRI<"tmlh", 0xA70, z_tm, GR64, imm64lh16>; + def TMHL : CompareRI<"tmhl", 0xA73, z_tm, GR64, imm64hl16>; + def TMHH : CompareRI<"tmhh", 0xA72, z_tm, GR64, imm64hh16>; +} + //===----------------------------------------------------------------------===// // Prefetch //===----------------------------------------------------------------------===// diff --git a/lib/Target/SystemZ/SystemZOperators.td b/lib/Target/SystemZ/SystemZOperators.td index ff64ea8fa0b..822195c02a5 100644 --- a/lib/Target/SystemZ/SystemZOperators.td +++ b/lib/Target/SystemZ/SystemZOperators.td @@ -96,6 +96,7 @@ def z_sibcall : SDNode<"SystemZISD::SIBCALL", SDT_ZCall, def z_pcrel_wrapper : SDNode<"SystemZISD::PCREL_WRAPPER", SDT_ZWrapPtr, []>; def z_cmp : SDNode<"SystemZISD::CMP", SDT_ZCmp, [SDNPOutGlue]>; def z_ucmp : SDNode<"SystemZISD::UCMP", SDT_ZCmp, [SDNPOutGlue]>; +def z_tm : SDNode<"SystemZISD::TM", SDT_ZCmp, [SDNPOutGlue]>; def z_br_ccmask : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask, [SDNPHasChain, SDNPInGlue]>; def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask, diff --git a/test/CodeGen/SystemZ/int-cmp-44.ll b/test/CodeGen/SystemZ/int-cmp-44.ll index b94f482f8b3..ae0133f1086 100644 --- a/test/CodeGen/SystemZ/int-cmp-44.ll +++ b/test/CodeGen/SystemZ/int-cmp-44.ll @@ -203,11 +203,11 @@ exit: ; comparisons with zero if the immediate covers the whole register. define i32 @f11(i32 %a, i32 %b, i32 *%dest) { ; CHECK-LABEL: f11: -; CHECK: nilf %r2, 100 +; CHECK: nilf %r2, 100000001 ; CHECK-NEXT: jl .L{{.*}} ; CHECK: br %r14 entry: - %res = and i32 %a, 100 + %res = and i32 %a, 100000001 %cmp = icmp ne i32 %res, 0 br i1 %cmp, label %exit, label %store diff --git a/test/CodeGen/SystemZ/int-cmp-46.ll b/test/CodeGen/SystemZ/int-cmp-46.ll new file mode 100644 index 00000000000..b46ca5e6d1f --- /dev/null +++ b/test/CodeGen/SystemZ/int-cmp-46.ll @@ -0,0 +1,99 @@ +; Test the use of TEST UNDER MASK for 32-bit operations. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s + +@g = global i32 0 + +; Check the lowest useful TMLL value. +define void @f1(i32 %a) { +; CHECK-LABEL: f1: +; CHECK: tmll %r2, 1 +; CHECK: je {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i32 %a, 1 + %cmp = icmp eq i32 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the high end of the TMLL range. +define void @f2(i32 %a) { +; CHECK-LABEL: f2: +; CHECK: tmll %r2, 65535 +; CHECK: jne {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i32 %a, 65535 + %cmp = icmp ne i32 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the lowest useful TMLH value, which is the next value up. +define void @f3(i32 %a) { +; CHECK-LABEL: f3: +; CHECK: tmlh %r2, 1 +; CHECK: jne {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i32 %a, 65536 + %cmp = icmp ne i32 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the next value up again, which cannot use TM. +define void @f4(i32 %a) { +; CHECK-LABEL: f4: +; CHECK-NOT: {{tm[lh].}} +; CHECK: br %r14 +entry: + %and = and i32 %a, 4294901759 + %cmp = icmp eq i32 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the high end of the TMLH range. +define void @f5(i32 %a) { +; CHECK-LABEL: f5: +; CHECK: tmlh %r2, 65535 +; CHECK: je {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i32 %a, 4294901760 + %cmp = icmp eq i32 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} diff --git a/test/CodeGen/SystemZ/int-cmp-47.ll b/test/CodeGen/SystemZ/int-cmp-47.ll new file mode 100644 index 00000000000..bf206ed9db6 --- /dev/null +++ b/test/CodeGen/SystemZ/int-cmp-47.ll @@ -0,0 +1,193 @@ +; Test the use of TEST UNDER MASK for 64-bit operations. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s + +@g = global i32 0 + +; Check the lowest useful TMLL value. +define void @f1(i64 %a) { +; CHECK-LABEL: f1: +; CHECK: tmll %r2, 1 +; CHECK: je {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 1 + %cmp = icmp eq i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the high end of the TMLL range. +define void @f2(i64 %a) { +; CHECK-LABEL: f2: +; CHECK: tmll %r2, 65535 +; CHECK: jne {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 65535 + %cmp = icmp ne i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the lowest useful TMLH value, which is the next value up. +define void @f3(i64 %a) { +; CHECK-LABEL: f3: +; CHECK: tmlh %r2, 1 +; CHECK: jne {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 65536 + %cmp = icmp ne i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the next value up again, which cannot use TM. +define void @f4(i64 %a) { +; CHECK-LABEL: f4: +; CHECK-NOT: {{tm[lh].}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 4294901759 + %cmp = icmp eq i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the high end of the TMLH range. +define void @f5(i64 %a) { +; CHECK-LABEL: f5: +; CHECK: tmlh %r2, 65535 +; CHECK: je {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 4294901760 + %cmp = icmp eq i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the lowest useful TMHL value. +define void @f6(i64 %a) { +; CHECK-LABEL: f6: +; CHECK: tmhl %r2, 1 +; CHECK: je {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 4294967296 + %cmp = icmp eq i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the next value up again, which cannot use TM. +define void @f7(i64 %a) { +; CHECK-LABEL: f7: +; CHECK-NOT: {{tm[lh].}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 4294967297 + %cmp = icmp ne i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the high end of the TMHL range. +define void @f8(i64 %a) { +; CHECK-LABEL: f8: +; CHECK: tmhl %r2, 65535 +; CHECK: jne {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 281470681743360 + %cmp = icmp ne i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the lowest useful TMHH value. +define void @f9(i64 %a) { +; CHECK-LABEL: f9: +; CHECK: tmhh %r2, 1 +; CHECK: jne {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 281474976710656 + %cmp = icmp ne i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} + +; Check the high end of the TMHH range. +define void @f10(i64 %a) { +; CHECK-LABEL: f10: +; CHECK: tmhh %r2, 65535 +; CHECK: je {{\.L.*}} +; CHECK: br %r14 +entry: + %and = and i64 %a, 18446462598732840960 + %cmp = icmp eq i64 %and, 0 + br i1 %cmp, label %exit, label %store + +store: + store i32 1, i32 *@g + br label %exit + +exit: + ret void +} diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt index 360785e94ba..912837c9a60 100644 --- a/test/MC/Disassembler/SystemZ/insns.txt +++ b/test/MC/Disassembler/SystemZ/insns.txt @@ -6964,6 +6964,54 @@ # CHECK: sy %r15, 0 0xe3 0xf0 0x00 0x00 0x00 0x5b +# CHECK: tmhh %r0, 0 +0xa7 0x02 0x00 0x00 + +# CHECK: tmhh %r0, 32768 +0xa7 0x02 0x80 0x00 + +# CHECK: tmhh %r0, 65535 +0xa7 0x02 0xff 0xff + +# CHECK: tmhh %r15, 0 +0xa7 0xf2 0x00 0x00 + +# CHECK: tmhl %r0, 0 +0xa7 0x03 0x00 0x00 + +# CHECK: tmhl %r0, 32768 +0xa7 0x03 0x80 0x00 + +# CHECK: tmhl %r0, 65535 +0xa7 0x03 0xff 0xff + +# CHECK: tmhl %r15, 0 +0xa7 0xf3 0x00 0x00 + +# CHECK: tmlh %r0, 0 +0xa7 0x00 0x00 0x00 + +# CHECK: tmlh %r0, 32768 +0xa7 0x00 0x80 0x00 + +# CHECK: tmlh %r0, 65535 +0xa7 0x00 0xff 0xff + +# CHECK: tmlh %r15, 0 +0xa7 0xf0 0x00 0x00 + +# CHECK: tmll %r0, 0 +0xa7 0x01 0x00 0x00 + +# CHECK: tmll %r0, 32768 +0xa7 0x01 0x80 0x00 + +# CHECK: tmll %r0, 65535 +0xa7 0x01 0xff 0xff + +# CHECK: tmll %r15, 0 +0xa7 0xf1 0x00 0x00 + # CHECK: xgr %r0, %r0 0xb9 0x82 0x00 0x00 diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s index 1c478caa037..54979fdaf91 100644 --- a/test/MC/SystemZ/insn-bad.s +++ b/test/MC/SystemZ/insn-bad.s @@ -2863,6 +2863,38 @@ sy %r0, -524289 sy %r0, 524288 +#CHECK: error: invalid operand +#CHECK: tmhh %r0, -1 +#CHECK: error: invalid operand +#CHECK: tmhh %r0, 0x10000 + + tmhh %r0, -1 + tmhh %r0, 0x10000 + +#CHECK: error: invalid operand +#CHECK: tmhl %r0, -1 +#CHECK: error: invalid operand +#CHECK: tmhl %r0, 0x10000 + + tmhl %r0, -1 + tmhl %r0, 0x10000 + +#CHECK: error: invalid operand +#CHECK: tmlh %r0, -1 +#CHECK: error: invalid operand +#CHECK: tmlh %r0, 0x10000 + + tmlh %r0, -1 + tmlh %r0, 0x10000 + +#CHECK: error: invalid operand +#CHECK: tmll %r0, -1 +#CHECK: error: invalid operand +#CHECK: tmll %r0, 0x10000 + + tmll %r0, -1 + tmll %r0, 0x10000 + #CHECK: error: invalid operand #CHECK: x %r0, -1 #CHECK: error: invalid operand diff --git a/test/MC/SystemZ/insn-good.s b/test/MC/SystemZ/insn-good.s index 9930d8ce6d1..be7e3085496 100644 --- a/test/MC/SystemZ/insn-good.s +++ b/test/MC/SystemZ/insn-good.s @@ -7284,6 +7284,46 @@ sy %r0, 524287(%r15,%r1) sy %r15, 0 +#CHECK: tmhh %r0, 0 # encoding: [0xa7,0x02,0x00,0x00] +#CHECK: tmhh %r0, 32768 # encoding: [0xa7,0x02,0x80,0x00] +#CHECK: tmhh %r0, 65535 # encoding: [0xa7,0x02,0xff,0xff] +#CHECK: tmhh %r15, 0 # encoding: [0xa7,0xf2,0x00,0x00] + + tmhh %r0, 0 + tmhh %r0, 0x8000 + tmhh %r0, 0xffff + tmhh %r15, 0 + +#CHECK: tmhl %r0, 0 # encoding: [0xa7,0x03,0x00,0x00] +#CHECK: tmhl %r0, 32768 # encoding: [0xa7,0x03,0x80,0x00] +#CHECK: tmhl %r0, 65535 # encoding: [0xa7,0x03,0xff,0xff] +#CHECK: tmhl %r15, 0 # encoding: [0xa7,0xf3,0x00,0x00] + + tmhl %r0, 0 + tmhl %r0, 0x8000 + tmhl %r0, 0xffff + tmhl %r15, 0 + +#CHECK: tmlh %r0, 0 # encoding: [0xa7,0x00,0x00,0x00] +#CHECK: tmlh %r0, 32768 # encoding: [0xa7,0x00,0x80,0x00] +#CHECK: tmlh %r0, 65535 # encoding: [0xa7,0x00,0xff,0xff] +#CHECK: tmlh %r15, 0 # encoding: [0xa7,0xf0,0x00,0x00] + + tmlh %r0, 0 + tmlh %r0, 0x8000 + tmlh %r0, 0xffff + tmlh %r15, 0 + +#CHECK: tmll %r0, 0 # encoding: [0xa7,0x01,0x00,0x00] +#CHECK: tmll %r0, 32768 # encoding: [0xa7,0x01,0x80,0x00] +#CHECK: tmll %r0, 65535 # encoding: [0xa7,0x01,0xff,0xff] +#CHECK: tmll %r15, 0 # encoding: [0xa7,0xf1,0x00,0x00] + + tmll %r0, 0 + tmll %r0, 0x8000 + tmll %r0, 0xffff + tmll %r15, 0 + #CHECK: x %r0, 0 # encoding: [0x57,0x00,0x00,0x00] #CHECK: x %r0, 4095 # encoding: [0x57,0x00,0x0f,0xff] #CHECK: x %r0, 0(%r1) # encoding: [0x57,0x00,0x10,0x00]