summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ/SystemZOperators.td
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-09-10 10:20:32 +0000
committerRichard Sandiford <rsandifo@linux.vnet.ibm.com>2013-09-10 10:20:32 +0000
commita9eb9972e4183bc859d6daf16ab32b855c196f4e (patch)
treed04a77f7029614549d28bccb30ede9ca2282f039 /llvm/lib/Target/SystemZ/SystemZOperators.td
parent3615c45d764d8c34720725e1870b94326de5797a (diff)
downloadbcm5719-llvm-a9eb9972e4183bc859d6daf16ab32b855c196f4e.tar.gz
bcm5719-llvm-a9eb9972e4183bc859d6daf16ab32b855c196f4e.zip
[SystemZ] Add TM and TMY
The main complication here is that TM and TMY (the memory forms) set CC differently from the register forms. When the tested bits contain some 0s and some 1s, the register forms set CC to 1 or 2 based on the value the uppermost bit. The memory forms instead set CC to 1 regardless of the uppermost bit. Until now, I've tried to make it so that a branch never tests for an impossible CC value. E.g. NR only sets CC to 0 or 1, so branches on the result will only test for 0 or 1. Originally I'd tried to do the same thing for TM and TMY by using custom matching code in ISelDAGToDAG. That ended up being very ugly though, and would have meant duplicating some of the chain checks that the common isel code does. I've therefore gone for the simpler alternative of adding an extra operand to the TM DAG opcode to say whether a memory form would be OK. This means that the inverse of a "TM;JE" is "TM;JNE" rather than the more precise "TM;JNLE", just like the inverse of "TMLL;JE" is "TMLL;JNE". I suppose that's arguably less confusing though... llvm-svn: 190400
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZOperators.td')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZOperators.td6
1 files changed, 5 insertions, 1 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZOperators.td b/llvm/lib/Target/SystemZ/SystemZOperators.td
index c135b3b82b0..4a6b665a11d 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperators.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperators.td
@@ -99,7 +99,7 @@ def z_sibcall : SDNode<"SystemZISD::SIBCALL", SDT_ZCall,
def z_pcrel_wrapper : SDNode<"SystemZISD::PCREL_WRAPPER", SDT_ZWrapPtr, []>;
def z_icmp : SDNode<"SystemZISD::ICMP", SDT_ZICmp, [SDNPOutGlue]>;
def z_fcmp : SDNode<"SystemZISD::FCMP", SDT_ZCmp, [SDNPOutGlue]>;
-def z_tm : SDNode<"SystemZISD::TM", SDT_ZCmp, [SDNPOutGlue]>;
+def z_tm : SDNode<"SystemZISD::TM", SDT_ZICmp, [SDNPOutGlue]>;
def z_br_ccmask : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask,
[SDNPHasChain, SDNPInGlue]>;
def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask,
@@ -176,6 +176,10 @@ def z_ucmp : PatFrag<(ops node:$a, node:$b), (z_icmp node:$a, node:$b, imm), [{
return Type != SystemZICMP::SignedOnly;
}]>;
+// Register- and memory-based TEST UNDER MASK.
+def z_tm_reg : PatFrag<(ops node:$a, node:$b), (z_tm node:$a, node:$b, imm)>;
+def z_tm_mem : PatFrag<(ops node:$a, node:$b), (z_tm node:$a, node:$b, 0)>;
+
// Register sign-extend operations. Sub-32-bit values are represented as i32s.
def sext8 : PatFrag<(ops node:$src), (sext_inreg node:$src, i8)>;
def sext16 : PatFrag<(ops node:$src), (sext_inreg node:$src, i16)>;
OpenPOWER on IntegriCloud