xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.td (revision 6c4b055cfb6bf549e9145dde6454cc6b178c35e4)
10b57cec5SDimitry Andric//===-- PPCInstrInfo.td - The PowerPC Instruction Set ------*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This file describes the subset of the 32-bit PowerPC instruction set, as used
100b57cec5SDimitry Andric// by the PowerPC instruction selector.
110b57cec5SDimitry Andric//
120b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andricinclude "PPCInstrFormats.td"
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
170b57cec5SDimitry Andric// PowerPC specific type constraints.
180b57cec5SDimitry Andric//
190b57cec5SDimitry Andricdef SDT_PPCstfiwx : SDTypeProfile<0, 2, [ // stfiwx
200b57cec5SDimitry Andric  SDTCisVT<0, f64>, SDTCisPtrTy<1>
210b57cec5SDimitry Andric]>;
220b57cec5SDimitry Andricdef SDT_PPClfiwx : SDTypeProfile<1, 1, [ // lfiw[az]x
230b57cec5SDimitry Andric  SDTCisVT<0, f64>, SDTCisPtrTy<1>
240b57cec5SDimitry Andric]>;
250b57cec5SDimitry Andricdef SDT_PPCLxsizx : SDTypeProfile<1, 2, [
260b57cec5SDimitry Andric  SDTCisVT<0, f64>, SDTCisPtrTy<1>, SDTCisPtrTy<2>
270b57cec5SDimitry Andric]>;
280b57cec5SDimitry Andricdef SDT_PPCstxsix : SDTypeProfile<0, 3, [
290b57cec5SDimitry Andric  SDTCisVT<0, f64>, SDTCisPtrTy<1>, SDTCisPtrTy<2>
300b57cec5SDimitry Andric]>;
310b57cec5SDimitry Andricdef SDT_PPCcv_fp_to_int  : SDTypeProfile<1, 1, [
320b57cec5SDimitry Andric  SDTCisFP<0>, SDTCisFP<1>
330b57cec5SDimitry Andric  ]>;
340b57cec5SDimitry Andricdef SDT_PPCstore_scal_int_from_vsr : SDTypeProfile<0, 3, [
3506c3fb27SDimitry Andric  SDTCisFP<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>
360b57cec5SDimitry Andric]>;
370b57cec5SDimitry Andricdef SDT_PPCVexts  : SDTypeProfile<1, 2, [
380b57cec5SDimitry Andric  SDTCisVT<0, f64>, SDTCisVT<1, f64>, SDTCisPtrTy<2>
390b57cec5SDimitry Andric]>;
400b57cec5SDimitry Andric
410b57cec5SDimitry Andricdef SDT_PPCCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32>,
420b57cec5SDimitry Andric                                           SDTCisVT<1, i32> ]>;
430b57cec5SDimitry Andricdef SDT_PPCCallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>,
440b57cec5SDimitry Andric                                         SDTCisVT<1, i32> ]>;
450b57cec5SDimitry Andricdef SDT_PPCvperm   : SDTypeProfile<1, 3, [
460b57cec5SDimitry Andric  SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>
470b57cec5SDimitry Andric]>;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andricdef SDT_PPCVecSplat : SDTypeProfile<1, 2, [ SDTCisVec<0>,
500b57cec5SDimitry Andric  SDTCisVec<1>, SDTCisInt<2>
510b57cec5SDimitry Andric]>;
520b57cec5SDimitry Andric
535ffd83dbSDimitry Andricdef SDT_PPCSpToDp : SDTypeProfile<1, 1, [ SDTCisVT<0, v2f64>,
545ffd83dbSDimitry Andric  SDTCisInt<1>
555ffd83dbSDimitry Andric]>;
565ffd83dbSDimitry Andric
570b57cec5SDimitry Andricdef SDT_PPCVecShift : SDTypeProfile<1, 3, [ SDTCisVec<0>,
580b57cec5SDimitry Andric  SDTCisVec<1>, SDTCisVec<2>, SDTCisPtrTy<3>
590b57cec5SDimitry Andric]>;
600b57cec5SDimitry Andric
610b57cec5SDimitry Andricdef SDT_PPCVecInsert : SDTypeProfile<1, 3, [ SDTCisVec<0>,
620b57cec5SDimitry Andric  SDTCisVec<1>, SDTCisVec<2>, SDTCisInt<3>
630b57cec5SDimitry Andric]>;
640b57cec5SDimitry Andric
650b57cec5SDimitry Andricdef SDT_PPCxxpermdi: SDTypeProfile<1, 3, [ SDTCisVec<0>,
660b57cec5SDimitry Andric  SDTCisVec<1>, SDTCisVec<2>, SDTCisInt<3>
670b57cec5SDimitry Andric]>;
680b57cec5SDimitry Andric
690b57cec5SDimitry Andricdef SDT_PPCvcmp : SDTypeProfile<1, 3, [
700b57cec5SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>
710b57cec5SDimitry Andric]>;
720b57cec5SDimitry Andric
730b57cec5SDimitry Andricdef SDT_PPCcondbr : SDTypeProfile<0, 3, [
740b57cec5SDimitry Andric  SDTCisVT<0, i32>, SDTCisVT<2, OtherVT>
750b57cec5SDimitry Andric]>;
760b57cec5SDimitry Andric
77e8d8bef9SDimitry Andricdef SDT_PPCFtsqrt : SDTypeProfile<1, 1, [
78e8d8bef9SDimitry Andric  SDTCisVT<0, i32>]>;
79e8d8bef9SDimitry Andric
800b57cec5SDimitry Andricdef SDT_PPClbrx : SDTypeProfile<1, 2, [
810b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>
820b57cec5SDimitry Andric]>;
830b57cec5SDimitry Andricdef SDT_PPCstbrx : SDTypeProfile<0, 3, [
840b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>
850b57cec5SDimitry Andric]>;
86bdd1243dSDimitry Andricdef SDT_StoreCond : SDTypeProfile<0, 3, [
87bdd1243dSDimitry Andric  SDTCisPtrTy<0>, SDTCisInt<1>, SDTCisPtrTy<2>
88bdd1243dSDimitry Andric]>;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andricdef SDT_PPCTC_ret : SDTypeProfile<0, 2, [
910b57cec5SDimitry Andric  SDTCisPtrTy<0>, SDTCisVT<1, i32>
920b57cec5SDimitry Andric]>;
930b57cec5SDimitry Andric
940b57cec5SDimitry Andricdef tocentry32 : Operand<iPTR> {
950b57cec5SDimitry Andric  let MIOperandInfo = (ops i32imm:$imm);
960b57cec5SDimitry Andric}
970b57cec5SDimitry Andric
980b57cec5SDimitry Andricdef SDT_PPCqvfperm   : SDTypeProfile<1, 3, [
990b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVec<3>
1000b57cec5SDimitry Andric]>;
1010b57cec5SDimitry Andricdef SDT_PPCqvgpci   : SDTypeProfile<1, 1, [
1020b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisInt<1>
1030b57cec5SDimitry Andric]>;
1040b57cec5SDimitry Andricdef SDT_PPCqvaligni   : SDTypeProfile<1, 3, [
1050b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<3>
1060b57cec5SDimitry Andric]>;
1070b57cec5SDimitry Andricdef SDT_PPCqvesplati   : SDTypeProfile<1, 2, [
1080b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>
1090b57cec5SDimitry Andric]>;
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andricdef SDT_PPCqbflt : SDTypeProfile<1, 1, [
1120b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisVec<1>
1130b57cec5SDimitry Andric]>;
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andricdef SDT_PPCqvlfsb : SDTypeProfile<1, 1, [
1160b57cec5SDimitry Andric  SDTCisVec<0>, SDTCisPtrTy<1>
1170b57cec5SDimitry Andric]>;
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andricdef SDT_PPCextswsli : SDTypeProfile<1, 2, [  // extswsli
1200b57cec5SDimitry Andric  SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisInt<2>
1210b57cec5SDimitry Andric]>;
1220b57cec5SDimitry Andric
123480093f4SDimitry Andricdef SDT_PPCFPMinMax : SDTypeProfile<1, 2, [
124480093f4SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0>
125480093f4SDimitry Andric]>;
126480093f4SDimitry Andric
1270b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1280b57cec5SDimitry Andric// PowerPC specific DAG Nodes.
1290b57cec5SDimitry Andric//
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andricdef PPCfre    : SDNode<"PPCISD::FRE",     SDTFPUnaryOp, []>;
1320b57cec5SDimitry Andricdef PPCfrsqrte: SDNode<"PPCISD::FRSQRTE", SDTFPUnaryOp, []>;
133e8d8bef9SDimitry Andricdef PPCfsqrt  : SDNode<"PPCISD::FSQRT",   SDTFPUnaryOp, []>;
134e8d8bef9SDimitry Andricdef PPCftsqrt : SDNode<"PPCISD::FTSQRT",  SDT_PPCFtsqrt,[]>;
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andricdef PPCfcfid  : SDNode<"PPCISD::FCFID",   SDTFPUnaryOp, []>;
1370b57cec5SDimitry Andricdef PPCfcfidu : SDNode<"PPCISD::FCFIDU",  SDTFPUnaryOp, []>;
1380b57cec5SDimitry Andricdef PPCfcfids : SDNode<"PPCISD::FCFIDS",  SDTFPRoundOp, []>;
1390b57cec5SDimitry Andricdef PPCfcfidus: SDNode<"PPCISD::FCFIDUS", SDTFPRoundOp, []>;
1400b57cec5SDimitry Andricdef PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>;
1410b57cec5SDimitry Andricdef PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
1420b57cec5SDimitry Andricdef PPCfctiduz: SDNode<"PPCISD::FCTIDUZ",SDTFPUnaryOp, []>;
1430b57cec5SDimitry Andricdef PPCfctiwuz: SDNode<"PPCISD::FCTIWUZ",SDTFPUnaryOp, []>;
1440b57cec5SDimitry Andric
145e8d8bef9SDimitry Andricdef PPCstrict_fcfid : SDNode<"PPCISD::STRICT_FCFID",
146e8d8bef9SDimitry Andric                             SDTFPUnaryOp, [SDNPHasChain]>;
147e8d8bef9SDimitry Andricdef PPCstrict_fcfidu : SDNode<"PPCISD::STRICT_FCFIDU",
148e8d8bef9SDimitry Andric                              SDTFPUnaryOp, [SDNPHasChain]>;
149e8d8bef9SDimitry Andricdef PPCstrict_fcfids : SDNode<"PPCISD::STRICT_FCFIDS",
150e8d8bef9SDimitry Andric                             SDTFPRoundOp, [SDNPHasChain]>;
151e8d8bef9SDimitry Andricdef PPCstrict_fcfidus : SDNode<"PPCISD::STRICT_FCFIDUS",
152e8d8bef9SDimitry Andric                              SDTFPRoundOp, [SDNPHasChain]>;
153e8d8bef9SDimitry Andric
154e8d8bef9SDimitry Andricdef PPCany_fcfid : PatFrags<(ops node:$op),
155e8d8bef9SDimitry Andric                             [(PPCfcfid node:$op),
156e8d8bef9SDimitry Andric                              (PPCstrict_fcfid node:$op)]>;
157e8d8bef9SDimitry Andricdef PPCany_fcfidu : PatFrags<(ops node:$op),
158e8d8bef9SDimitry Andric                             [(PPCfcfidu node:$op),
159e8d8bef9SDimitry Andric                              (PPCstrict_fcfidu node:$op)]>;
160e8d8bef9SDimitry Andricdef PPCany_fcfids : PatFrags<(ops node:$op),
161e8d8bef9SDimitry Andric                              [(PPCfcfids node:$op),
162e8d8bef9SDimitry Andric                               (PPCstrict_fcfids node:$op)]>;
163e8d8bef9SDimitry Andricdef PPCany_fcfidus : PatFrags<(ops node:$op),
164e8d8bef9SDimitry Andric                              [(PPCfcfidus node:$op),
165e8d8bef9SDimitry Andric                               (PPCstrict_fcfidus node:$op)]>;
166e8d8bef9SDimitry Andric
1670b57cec5SDimitry Andricdef PPCstore_scal_int_from_vsr:
1680b57cec5SDimitry Andric   SDNode<"PPCISD::ST_VSR_SCAL_INT", SDT_PPCstore_scal_int_from_vsr,
1690b57cec5SDimitry Andric           [SDNPHasChain, SDNPMayStore]>;
1700b57cec5SDimitry Andricdef PPCstfiwx : SDNode<"PPCISD::STFIWX", SDT_PPCstfiwx,
1710b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayStore]>;
1720b57cec5SDimitry Andricdef PPClfiwax : SDNode<"PPCISD::LFIWAX", SDT_PPClfiwx,
1730b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1740b57cec5SDimitry Andricdef PPClfiwzx : SDNode<"PPCISD::LFIWZX", SDT_PPClfiwx,
1750b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
1760b57cec5SDimitry Andricdef PPClxsizx : SDNode<"PPCISD::LXSIZX", SDT_PPCLxsizx,
1770b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayLoad]>;
1780b57cec5SDimitry Andricdef PPCstxsix : SDNode<"PPCISD::STXSIX", SDT_PPCstxsix,
1790b57cec5SDimitry Andric                       [SDNPHasChain, SDNPMayStore]>;
1800b57cec5SDimitry Andricdef PPCVexts  : SDNode<"PPCISD::VEXTS", SDT_PPCVexts, []>;
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andric// Extract FPSCR (not modeled at the DAG level).
1830b57cec5SDimitry Andricdef PPCmffs   : SDNode<"PPCISD::MFFS",
1845ffd83dbSDimitry Andric                       SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>,
1855ffd83dbSDimitry Andric                       [SDNPHasChain]>;
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andric// Perform FADD in round-to-zero mode.
1880b57cec5SDimitry Andricdef PPCfaddrtz: SDNode<"PPCISD::FADDRTZ", SDTFPBinOp, []>;
189e8d8bef9SDimitry Andricdef PPCstrict_faddrtz: SDNode<"PPCISD::STRICT_FADDRTZ", SDTFPBinOp,
190e8d8bef9SDimitry Andric                              [SDNPHasChain]>;
1910b57cec5SDimitry Andric
192e8d8bef9SDimitry Andricdef PPCany_faddrtz: PatFrags<(ops node:$lhs, node:$rhs),
193e8d8bef9SDimitry Andric                             [(PPCfaddrtz node:$lhs, node:$rhs),
194e8d8bef9SDimitry Andric                              (PPCstrict_faddrtz node:$lhs, node:$rhs)]>;
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andricdef PPCfsel   : SDNode<"PPCISD::FSEL",
1970b57cec5SDimitry Andric   // Type constraint for fsel.
1980b57cec5SDimitry Andric   SDTypeProfile<1, 3, [SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,
1990b57cec5SDimitry Andric                        SDTCisFP<0>, SDTCisVT<1, f64>]>, []>;
20081ad6265SDimitry Andricdef PPCxsmaxc : SDNode<"PPCISD::XSMAXC", SDT_PPCFPMinMax, []>;
20181ad6265SDimitry Andricdef PPCxsminc : SDNode<"PPCISD::XSMINC", SDT_PPCFPMinMax, []>;
2020b57cec5SDimitry Andricdef PPChi       : SDNode<"PPCISD::Hi", SDTIntBinOp, []>;
2030b57cec5SDimitry Andricdef PPClo       : SDNode<"PPCISD::Lo", SDTIntBinOp, []>;
2040b57cec5SDimitry Andricdef PPCtoc_entry: SDNode<"PPCISD::TOC_ENTRY", SDTIntBinOp,
2050b57cec5SDimitry Andric                         [SDNPMayLoad, SDNPMemOperand]>;
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andricdef PPCppc32GOT : SDNode<"PPCISD::PPC32_GOT", SDTIntLeaf, []>;
2080b57cec5SDimitry Andric
2090b57cec5SDimitry Andricdef PPCaddisGotTprelHA : SDNode<"PPCISD::ADDIS_GOT_TPREL_HA", SDTIntBinOp>;
2100b57cec5SDimitry Andricdef PPCldGotTprelL : SDNode<"PPCISD::LD_GOT_TPREL_L", SDTIntBinOp,
2110b57cec5SDimitry Andric                            [SDNPMayLoad]>;
2120b57cec5SDimitry Andricdef PPCaddTls     : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>;
2130b57cec5SDimitry Andricdef PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>;
2140b57cec5SDimitry Andricdef PPCaddiTlsgdL   : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>;
2150b57cec5SDimitry Andricdef PPCgetTlsAddr   : SDNode<"PPCISD::GET_TLS_ADDR", SDTIntBinOp>;
2160fca6ea1SDimitry Andricdef PPCgetTlsMod   : SDNode<"PPCISD::GET_TLS_MOD_AIX", SDTIntUnaryOp>;
21706c3fb27SDimitry Andricdef PPCgetTpointer : SDNode<"PPCISD::GET_TPOINTER", SDTIntLeaf, []>;
2180b57cec5SDimitry Andricdef PPCaddiTlsgdLAddr : SDNode<"PPCISD::ADDI_TLSGD_L_ADDR",
2190b57cec5SDimitry Andric                               SDTypeProfile<1, 3, [
2200b57cec5SDimitry Andric                                 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2210b57cec5SDimitry Andric                                 SDTCisSameAs<0, 3>, SDTCisInt<0> ]>>;
222fe6060f1SDimitry Andricdef PPCTlsgdAIX     : SDNode<"PPCISD::TLSGD_AIX", SDTIntBinOp>;
2230fca6ea1SDimitry Andricdef PPCTlsldAIX     : SDNode<"PPCISD::TLSLD_AIX", SDTIntUnaryOp>;
2240b57cec5SDimitry Andricdef PPCaddisTlsldHA : SDNode<"PPCISD::ADDIS_TLSLD_HA", SDTIntBinOp>;
2250b57cec5SDimitry Andricdef PPCaddiTlsldL   : SDNode<"PPCISD::ADDI_TLSLD_L", SDTIntBinOp>;
2260b57cec5SDimitry Andricdef PPCgetTlsldAddr : SDNode<"PPCISD::GET_TLSLD_ADDR", SDTIntBinOp>;
2270b57cec5SDimitry Andricdef PPCaddiTlsldLAddr : SDNode<"PPCISD::ADDI_TLSLD_L_ADDR",
2280b57cec5SDimitry Andric                               SDTypeProfile<1, 3, [
2290b57cec5SDimitry Andric                                 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2300b57cec5SDimitry Andric                                 SDTCisSameAs<0, 3>, SDTCisInt<0> ]>>;
2310b57cec5SDimitry Andricdef PPCaddisDtprelHA : SDNode<"PPCISD::ADDIS_DTPREL_HA", SDTIntBinOp>;
2320b57cec5SDimitry Andricdef PPCaddiDtprelL   : SDNode<"PPCISD::ADDI_DTPREL_L", SDTIntBinOp>;
233e8d8bef9SDimitry Andricdef PPCpaddiDtprel   : SDNode<"PPCISD::PADDI_DTPREL", SDTIntBinOp>;
2340b57cec5SDimitry Andric
2350b57cec5SDimitry Andricdef PPCvperm     : SDNode<"PPCISD::VPERM", SDT_PPCvperm, []>;
2360b57cec5SDimitry Andricdef PPCxxsplt    : SDNode<"PPCISD::XXSPLT", SDT_PPCVecSplat, []>;
2375ffd83dbSDimitry Andricdef PPCxxspltidp : SDNode<"PPCISD::XXSPLTI_SP_TO_DP", SDT_PPCSpToDp, []>;
2380b57cec5SDimitry Andricdef PPCvecinsert : SDNode<"PPCISD::VECINSERT", SDT_PPCVecInsert, []>;
2390b57cec5SDimitry Andricdef PPCxxpermdi  : SDNode<"PPCISD::XXPERMDI", SDT_PPCxxpermdi, []>;
2400b57cec5SDimitry Andricdef PPCvecshl    : SDNode<"PPCISD::VECSHL", SDT_PPCVecShift, []>;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andricdef PPCcmpb     : SDNode<"PPCISD::CMPB", SDTIntBinOp, []>;
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric// These nodes represent the 32-bit PPC shifts that operate on 6-bit shift
2450b57cec5SDimitry Andric// amounts.  These nodes are generated by the multi-precision shift code.
2460b57cec5SDimitry Andricdef PPCsrl        : SDNode<"PPCISD::SRL"       , SDTIntShiftOp>;
2470b57cec5SDimitry Andricdef PPCsra        : SDNode<"PPCISD::SRA"       , SDTIntShiftOp>;
2480b57cec5SDimitry Andricdef PPCshl        : SDNode<"PPCISD::SHL"       , SDTIntShiftOp>;
2490b57cec5SDimitry Andric
2505ffd83dbSDimitry Andricdef PPCfnmsub     : SDNode<"PPCISD::FNMSUB"    , SDTFPTernaryOp>;
2515ffd83dbSDimitry Andric
2520b57cec5SDimitry Andricdef PPCextswsli : SDNode<"PPCISD::EXTSWSLI" , SDT_PPCextswsli>;
2530b57cec5SDimitry Andric
254e8d8bef9SDimitry Andricdef PPCstrict_fctidz : SDNode<"PPCISD::STRICT_FCTIDZ",
255e8d8bef9SDimitry Andric                              SDTFPUnaryOp, [SDNPHasChain]>;
256e8d8bef9SDimitry Andricdef PPCstrict_fctiwz : SDNode<"PPCISD::STRICT_FCTIWZ",
257e8d8bef9SDimitry Andric                              SDTFPUnaryOp, [SDNPHasChain]>;
258e8d8bef9SDimitry Andricdef PPCstrict_fctiduz : SDNode<"PPCISD::STRICT_FCTIDUZ",
259e8d8bef9SDimitry Andric                               SDTFPUnaryOp, [SDNPHasChain]>;
260e8d8bef9SDimitry Andricdef PPCstrict_fctiwuz : SDNode<"PPCISD::STRICT_FCTIWUZ",
261e8d8bef9SDimitry Andric                                SDTFPUnaryOp, [SDNPHasChain]>;
262e8d8bef9SDimitry Andric
263e8d8bef9SDimitry Andricdef PPCany_fctidz : PatFrags<(ops node:$op),
264e8d8bef9SDimitry Andric                             [(PPCstrict_fctidz node:$op),
265e8d8bef9SDimitry Andric                              (PPCfctidz node:$op)]>;
266e8d8bef9SDimitry Andricdef PPCany_fctiwz : PatFrags<(ops node:$op),
267e8d8bef9SDimitry Andric                             [(PPCstrict_fctiwz node:$op),
268e8d8bef9SDimitry Andric                              (PPCfctiwz node:$op)]>;
269e8d8bef9SDimitry Andricdef PPCany_fctiduz : PatFrags<(ops node:$op),
270e8d8bef9SDimitry Andric                              [(PPCstrict_fctiduz node:$op),
271e8d8bef9SDimitry Andric                               (PPCfctiduz node:$op)]>;
272e8d8bef9SDimitry Andricdef PPCany_fctiwuz : PatFrags<(ops node:$op),
273e8d8bef9SDimitry Andric                              [(PPCstrict_fctiwuz node:$op),
274e8d8bef9SDimitry Andric                               (PPCfctiwuz node:$op)]>;
275e8d8bef9SDimitry Andric
2760b57cec5SDimitry Andric// Move 2 i64 values into a VSX register
2770b57cec5SDimitry Andricdef PPCbuild_fp128: SDNode<"PPCISD::BUILD_FP128",
2780b57cec5SDimitry Andric                           SDTypeProfile<1, 2,
2790b57cec5SDimitry Andric                             [SDTCisFP<0>, SDTCisSameSizeAs<1,2>,
2800b57cec5SDimitry Andric                              SDTCisSameAs<1,2>]>,
2810b57cec5SDimitry Andric                           []>;
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andricdef PPCbuild_spe64: SDNode<"PPCISD::BUILD_SPE64",
2840b57cec5SDimitry Andric                           SDTypeProfile<1, 2,
2850b57cec5SDimitry Andric                             [SDTCisVT<0, f64>, SDTCisVT<1,i32>,
2860b57cec5SDimitry Andric                             SDTCisVT<1,i32>]>,
2870b57cec5SDimitry Andric                           []>;
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andricdef PPCextract_spe : SDNode<"PPCISD::EXTRACT_SPE",
2900b57cec5SDimitry Andric                            SDTypeProfile<1, 2,
2910b57cec5SDimitry Andric                              [SDTCisVT<0, i32>, SDTCisVT<1, f64>,
2920b57cec5SDimitry Andric                              SDTCisPtrTy<2>]>,
2930b57cec5SDimitry Andric                              []>;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric// These are target-independent nodes, but have target-specific formats.
2960b57cec5SDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_PPCCallSeqStart,
2970b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOutGlue]>;
2980b57cec5SDimitry Andricdef callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_PPCCallSeqEnd,
2990b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andricdef SDT_PPCCall   : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
3020b57cec5SDimitry Andricdef PPCcall  : SDNode<"PPCISD::CALL", SDT_PPCCall,
3030b57cec5SDimitry Andric                      [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3040b57cec5SDimitry Andric                       SDNPVariadic]>;
3050b57cec5SDimitry Andricdef PPCcall_nop  : SDNode<"PPCISD::CALL_NOP", SDT_PPCCall,
3060b57cec5SDimitry Andric                          [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3070b57cec5SDimitry Andric                           SDNPVariadic]>;
3085ffd83dbSDimitry Andricdef PPCcall_notoc : SDNode<"PPCISD::CALL_NOTOC", SDT_PPCCall,
3095ffd83dbSDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3105ffd83dbSDimitry Andric                            SDNPVariadic]>;
3110b57cec5SDimitry Andricdef PPCmtctr      : SDNode<"PPCISD::MTCTR", SDT_PPCCall,
3120b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
3130b57cec5SDimitry Andricdef PPCbctrl : SDNode<"PPCISD::BCTRL", SDTNone,
3140b57cec5SDimitry Andric                      [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3150b57cec5SDimitry Andric                       SDNPVariadic]>;
3160b57cec5SDimitry Andricdef PPCbctrl_load_toc : SDNode<"PPCISD::BCTRL_LOAD_TOC",
3170b57cec5SDimitry Andric                               SDTypeProfile<0, 1, []>,
3180b57cec5SDimitry Andric                               [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
3190b57cec5SDimitry Andric                                SDNPVariadic]>;
3200b57cec5SDimitry Andric
321349cc55cSDimitry Andric// Call nodes for strictfp calls (that define RM).
322349cc55cSDimitry Andricdef PPCcall_rm  : SDNode<"PPCISD::CALL_RM", SDT_PPCCall,
323349cc55cSDimitry Andric                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
324349cc55cSDimitry Andric                          SDNPVariadic]>;
325349cc55cSDimitry Andricdef PPCcall_nop_rm  : SDNode<"PPCISD::CALL_NOP_RM", SDT_PPCCall,
326349cc55cSDimitry Andric                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
327349cc55cSDimitry Andric                              SDNPVariadic]>;
328349cc55cSDimitry Andricdef PPCcall_notoc_rm : SDNode<"PPCISD::CALL_NOTOC_RM", SDT_PPCCall,
329349cc55cSDimitry Andric                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
330349cc55cSDimitry Andric                               SDNPVariadic]>;
331349cc55cSDimitry Andricdef PPCbctrl_rm : SDNode<"PPCISD::BCTRL_RM", SDTNone,
332349cc55cSDimitry Andric                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
333349cc55cSDimitry Andric                          SDNPVariadic]>;
334349cc55cSDimitry Andricdef PPCbctrl_load_toc_rm : SDNode<"PPCISD::BCTRL_LOAD_TOC_RM",
335349cc55cSDimitry Andric                                  SDTypeProfile<0, 1, []>,
336349cc55cSDimitry Andric                                  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
337349cc55cSDimitry Andric                                   SDNPVariadic]>;
338349cc55cSDimitry Andric
3390fca6ea1SDimitry Andricdef PPCretglue   : SDNode<"PPCISD::RET_GLUE", SDTNone,
3400b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
3410b57cec5SDimitry Andric
3420b57cec5SDimitry Andricdef PPCtc_return : SDNode<"PPCISD::TC_RETURN", SDT_PPCTC_ret,
3430b57cec5SDimitry Andric                        [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;
3440b57cec5SDimitry Andric
3450b57cec5SDimitry Andricdef PPCeh_sjlj_setjmp  : SDNode<"PPCISD::EH_SJLJ_SETJMP",
3460b57cec5SDimitry Andric                                SDTypeProfile<1, 1, [SDTCisInt<0>,
3470b57cec5SDimitry Andric                                                     SDTCisPtrTy<1>]>,
3480b57cec5SDimitry Andric                                [SDNPHasChain, SDNPSideEffect]>;
3490b57cec5SDimitry Andricdef PPCeh_sjlj_longjmp : SDNode<"PPCISD::EH_SJLJ_LONGJMP",
3500b57cec5SDimitry Andric                                SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
3510b57cec5SDimitry Andric                                [SDNPHasChain, SDNPSideEffect]>;
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andricdef SDT_PPCsc     : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
3540b57cec5SDimitry Andricdef PPCsc         : SDNode<"PPCISD::SC", SDT_PPCsc,
3550b57cec5SDimitry Andric                           [SDNPHasChain, SDNPSideEffect]>;
3560b57cec5SDimitry Andric
3570b57cec5SDimitry Andricdef PPCclrbhrb    : SDNode<"PPCISD::CLRBHRB", SDTNone,
3580b57cec5SDimitry Andric                           [SDNPHasChain, SDNPSideEffect]>;
3590b57cec5SDimitry Andricdef PPCmfbhrbe    : SDNode<"PPCISD::MFBHRBE", SDTIntBinOp, [SDNPHasChain]>;
3600b57cec5SDimitry Andricdef PPCrfebb      : SDNode<"PPCISD::RFEBB", SDT_PPCsc,
3610b57cec5SDimitry Andric                           [SDNPHasChain, SDNPSideEffect]>;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andricdef PPCvcmp       : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>;
364e8d8bef9SDimitry Andricdef PPCvcmp_rec   : SDNode<"PPCISD::VCMP_rec", SDT_PPCvcmp, [SDNPOutGlue]>;
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andricdef PPCcondbranch : SDNode<"PPCISD::COND_BRANCH", SDT_PPCcondbr,
3670b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue]>;
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric// PPC-specific atomic operations.
3700b57cec5SDimitry Andricdef PPCatomicCmpSwap_8 :
3710b57cec5SDimitry Andric  SDNode<"PPCISD::ATOMIC_CMP_SWAP_8", SDTAtomic3,
3720b57cec5SDimitry Andric         [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
3730b57cec5SDimitry Andricdef PPCatomicCmpSwap_16 :
3740b57cec5SDimitry Andric  SDNode<"PPCISD::ATOMIC_CMP_SWAP_16", SDTAtomic3,
3750b57cec5SDimitry Andric         [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
3760b57cec5SDimitry Andricdef PPClbrx       : SDNode<"PPCISD::LBRX", SDT_PPClbrx,
3770b57cec5SDimitry Andric                           [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
3780b57cec5SDimitry Andricdef PPCstbrx      : SDNode<"PPCISD::STBRX", SDT_PPCstbrx,
3790b57cec5SDimitry Andric                           [SDNPHasChain, SDNPMayStore]>;
380bdd1243dSDimitry Andricdef PPCStoreCond  : SDNode<"PPCISD::STORE_COND", SDT_StoreCond,
381bdd1243dSDimitry Andric                           [SDNPHasChain, SDNPMayStore,
382bdd1243dSDimitry Andric                            SDNPMemOperand, SDNPOutGlue]>;
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric// Instructions to set/unset CR bit 6 for SVR4 vararg calls
3850b57cec5SDimitry Andricdef PPCcr6set   : SDNode<"PPCISD::CR6SET", SDTNone,
3860b57cec5SDimitry Andric                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
3870b57cec5SDimitry Andricdef PPCcr6unset : SDNode<"PPCISD::CR6UNSET", SDTNone,
3880b57cec5SDimitry Andric                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric// Instructions to support dynamic alloca.
3910b57cec5SDimitry Andricdef SDTDynOp  : SDTypeProfile<1, 2, []>;
3920b57cec5SDimitry Andricdef SDTDynAreaOp  : SDTypeProfile<1, 1, []>;
3930b57cec5SDimitry Andricdef PPCdynalloc   : SDNode<"PPCISD::DYNALLOC", SDTDynOp, [SDNPHasChain]>;
3940b57cec5SDimitry Andricdef PPCdynareaoffset   : SDNode<"PPCISD::DYNAREAOFFSET", SDTDynAreaOp, [SDNPHasChain]>;
3955ffd83dbSDimitry Andricdef PPCprobedalloca : SDNode<"PPCISD::PROBED_ALLOCA", SDTDynOp, [SDNPHasChain]>;
3965ffd83dbSDimitry Andric
3975ffd83dbSDimitry Andric// PC Relative Specific Nodes
3985ffd83dbSDimitry Andricdef PPCmatpcreladdr : SDNode<"PPCISD::MAT_PCREL_ADDR", SDTIntUnaryOp, []>;
399e8d8bef9SDimitry Andricdef PPCtlsdynamatpcreladdr : SDNode<"PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR",
400e8d8bef9SDimitry Andric                                    SDTIntUnaryOp, []>;
401e8d8bef9SDimitry Andricdef PPCtlslocalexecmataddr : SDNode<"PPCISD::TLS_LOCAL_EXEC_MAT_ADDR",
402e8d8bef9SDimitry Andric                                    SDTIntUnaryOp, []>;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4050b57cec5SDimitry Andric// PowerPC specific transformation functions and pattern fragments.
4060b57cec5SDimitry Andric//
4070b57cec5SDimitry Andric
4085ffd83dbSDimitry Andric// A floating point immediate that is not a positive zero and can be converted
4095ffd83dbSDimitry Andric// to a single precision floating point non-denormal immediate without loss of
4105ffd83dbSDimitry Andric// information.
4115ffd83dbSDimitry Andricdef nzFPImmAsi32 : PatLeaf<(fpimm), [{
4125ffd83dbSDimitry Andric  APFloat APFloatOfN = N->getValueAPF();
4135ffd83dbSDimitry Andric  return convertToNonDenormSingle(APFloatOfN) && !N->isExactlyValue(+0.0);
4145ffd83dbSDimitry Andric}]>;
4155ffd83dbSDimitry Andric
416bdd1243dSDimitry Andric// A floating point immediate that is exactly an integer (for example 3.0, -5.0)
417bdd1243dSDimitry Andric// and can be represented in 5 bits (range of [-16, 15]).
418bdd1243dSDimitry Andricdef nzFPImmExactInti5 : PatLeaf<(fpimm), [{
419bdd1243dSDimitry Andric  APFloat FloatValue = N->getValueAPF();
420bdd1243dSDimitry Andric  bool IsExact;
421bdd1243dSDimitry Andric  APSInt IntResult(16, false);
422bdd1243dSDimitry Andric  FloatValue.convertToInteger(IntResult, APFloat::rmTowardZero, &IsExact);
423bdd1243dSDimitry Andric  return IsExact && IntResult <= 15 && IntResult >= -16 && !FloatValue.isZero();
424bdd1243dSDimitry Andric}]>;
425bdd1243dSDimitry Andric
426bdd1243dSDimitry Andricdef getFPAs5BitExactInt : SDNodeXForm<fpimm, [{
427bdd1243dSDimitry Andric  APFloat FloatValue = N->getValueAPF();
428bdd1243dSDimitry Andric  bool IsExact;
429bdd1243dSDimitry Andric  APSInt IntResult(32, false);
430bdd1243dSDimitry Andric  FloatValue.convertToInteger(IntResult, APFloat::rmTowardZero, &IsExact);
431bdd1243dSDimitry Andric  return CurDAG->getTargetConstant(IntResult, SDLoc(N), MVT::i32);
432bdd1243dSDimitry Andric}]>;
433bdd1243dSDimitry Andric
4345ffd83dbSDimitry Andric// Convert the floating point immediate into a 32 bit floating point immediate
4355ffd83dbSDimitry Andric// and get a i32 with the resulting bits.
4365ffd83dbSDimitry Andricdef getFPAs32BitInt : SDNodeXForm<fpimm, [{
4375ffd83dbSDimitry Andric  APFloat APFloatOfN = N->getValueAPF();
4385ffd83dbSDimitry Andric  convertToNonDenormSingle(APFloatOfN);
4395ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(APFloatOfN.bitcastToAPInt().getZExtValue(),
4405ffd83dbSDimitry Andric                                   SDLoc(N), MVT::i32);
4415ffd83dbSDimitry Andric}]>;
4425ffd83dbSDimitry Andric
443fe6060f1SDimitry Andric// Check if the value can be converted to be single precision immediate, which
444fe6060f1SDimitry Andric// can be exploited by XXSPLTIDP. Ensure that it cannot be converted to single
445fe6060f1SDimitry Andric// precision before exploiting with XXSPLTI32DX.
446fe6060f1SDimitry Andricdef nzFPImmAsi64 : PatLeaf<(fpimm), [{
447fe6060f1SDimitry Andric  APFloat APFloatOfN = N->getValueAPF();
448fe6060f1SDimitry Andric  return !N->isExactlyValue(+0.0) && !checkConvertToNonDenormSingle(APFloatOfN);
449fe6060f1SDimitry Andric}]>;
450fe6060f1SDimitry Andric
451fe6060f1SDimitry Andric// Get the Hi bits of a 64 bit immediate.
452fe6060f1SDimitry Andricdef getFPAs64BitIntHi : SDNodeXForm<fpimm, [{
453fe6060f1SDimitry Andric  APFloat APFloatOfN = N->getValueAPF();
454fe6060f1SDimitry Andric  bool Unused;
455fe6060f1SDimitry Andric  APFloatOfN.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
456fe6060f1SDimitry Andric                     &Unused);
457fe6060f1SDimitry Andric  uint32_t Hi = (uint32_t)((APFloatOfN.bitcastToAPInt().getZExtValue() &
458fe6060f1SDimitry Andric                            0xFFFFFFFF00000000LL) >> 32);
459fe6060f1SDimitry Andric  return CurDAG->getTargetConstant(Hi, SDLoc(N), MVT::i32);
460fe6060f1SDimitry Andric}]>;
461fe6060f1SDimitry Andric
462fe6060f1SDimitry Andric// Get the Lo bits of a 64 bit immediate.
463fe6060f1SDimitry Andricdef getFPAs64BitIntLo : SDNodeXForm<fpimm, [{
464fe6060f1SDimitry Andric  APFloat APFloatOfN = N->getValueAPF();
465fe6060f1SDimitry Andric  bool Unused;
466fe6060f1SDimitry Andric  APFloatOfN.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
467fe6060f1SDimitry Andric                     &Unused);
468fe6060f1SDimitry Andric  uint32_t Lo = (uint32_t)(APFloatOfN.bitcastToAPInt().getZExtValue() &
469fe6060f1SDimitry Andric                           0xFFFFFFFF);
470fe6060f1SDimitry Andric  return CurDAG->getTargetConstant(Lo, SDLoc(N), MVT::i32);
471fe6060f1SDimitry Andric}]>;
472fe6060f1SDimitry Andric
473fe6060f1SDimitry Andricdef imm34 : PatLeaf<(imm), [{
474fe6060f1SDimitry Andric  return isInt<34>(N->getSExtValue());
475fe6060f1SDimitry Andric}]>;
476fe6060f1SDimitry Andric
477fe6060f1SDimitry Andricdef getImmAs64BitInt : SDNodeXForm<imm, [{
478fe6060f1SDimitry Andric  return getI64Imm(N->getSExtValue(), SDLoc(N));
479fe6060f1SDimitry Andric}]>;
480fe6060f1SDimitry Andric
4810b57cec5SDimitry Andricdef SHL32 : SDNodeXForm<imm, [{
4820b57cec5SDimitry Andric  // Transformation function: 31 - imm
4830b57cec5SDimitry Andric  return getI32Imm(31 - N->getZExtValue(), SDLoc(N));
4840b57cec5SDimitry Andric}]>;
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andricdef SRL32 : SDNodeXForm<imm, [{
4870b57cec5SDimitry Andric  // Transformation function: 32 - imm
4880b57cec5SDimitry Andric  return N->getZExtValue() ? getI32Imm(32 - N->getZExtValue(), SDLoc(N))
4890b57cec5SDimitry Andric                           : getI32Imm(0, SDLoc(N));
4900b57cec5SDimitry Andric}]>;
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andricdef LO16 : SDNodeXForm<imm, [{
4930b57cec5SDimitry Andric  // Transformation function: get the low 16 bits.
4940b57cec5SDimitry Andric  return getI32Imm((unsigned short)N->getZExtValue(), SDLoc(N));
4950b57cec5SDimitry Andric}]>;
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andricdef HI16 : SDNodeXForm<imm, [{
4980b57cec5SDimitry Andric  // Transformation function: shift the immediate value down into the low bits.
4990b57cec5SDimitry Andric  return getI32Imm((unsigned)N->getZExtValue() >> 16, SDLoc(N));
5000b57cec5SDimitry Andric}]>;
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andricdef HA16 : SDNodeXForm<imm, [{
5030b57cec5SDimitry Andric  // Transformation function: shift the immediate value down into the low bits.
504bdd1243dSDimitry Andric  int64_t Val = N->getZExtValue();
5050b57cec5SDimitry Andric  return getI32Imm((Val - (signed short)Val) >> 16, SDLoc(N));
5060b57cec5SDimitry Andric}]>;
5070b57cec5SDimitry Andricdef MB : SDNodeXForm<imm, [{
5080b57cec5SDimitry Andric  // Transformation function: get the start bit of a mask
5090b57cec5SDimitry Andric  unsigned mb = 0, me;
5100b57cec5SDimitry Andric  (void)isRunOfOnes((unsigned)N->getZExtValue(), mb, me);
5110b57cec5SDimitry Andric  return getI32Imm(mb, SDLoc(N));
5120b57cec5SDimitry Andric}]>;
5130b57cec5SDimitry Andric
5140b57cec5SDimitry Andricdef ME : SDNodeXForm<imm, [{
5150b57cec5SDimitry Andric  // Transformation function: get the end bit of a mask
5160b57cec5SDimitry Andric  unsigned mb, me = 0;
5170b57cec5SDimitry Andric  (void)isRunOfOnes((unsigned)N->getZExtValue(), mb, me);
5180b57cec5SDimitry Andric  return getI32Imm(me, SDLoc(N));
5190b57cec5SDimitry Andric}]>;
5200b57cec5SDimitry Andricdef maskimm32 : PatLeaf<(imm), [{
5210b57cec5SDimitry Andric  // maskImm predicate - True if immediate is a run of ones.
5220b57cec5SDimitry Andric  unsigned mb, me;
5230b57cec5SDimitry Andric  if (N->getValueType(0) == MVT::i32)
5240b57cec5SDimitry Andric    return isRunOfOnes((unsigned)N->getZExtValue(), mb, me);
5250b57cec5SDimitry Andric  else
5260b57cec5SDimitry Andric    return false;
5270b57cec5SDimitry Andric}]>;
5280b57cec5SDimitry Andric
5290b57cec5SDimitry Andricdef imm32SExt16  : Operand<i32>, ImmLeaf<i32, [{
5300b57cec5SDimitry Andric  // imm32SExt16 predicate - True if the i32 immediate fits in a 16-bit
5310b57cec5SDimitry Andric  // sign extended field.  Used by instructions like 'addi'.
5320b57cec5SDimitry Andric  return (int32_t)Imm == (short)Imm;
5330b57cec5SDimitry Andric}]>;
5340b57cec5SDimitry Andricdef imm64SExt16  : Operand<i64>, ImmLeaf<i64, [{
5350b57cec5SDimitry Andric  // imm64SExt16 predicate - True if the i64 immediate fits in a 16-bit
5360b57cec5SDimitry Andric  // sign extended field.  Used by instructions like 'addi'.
5370b57cec5SDimitry Andric  return (int64_t)Imm == (short)Imm;
5380b57cec5SDimitry Andric}]>;
5390b57cec5SDimitry Andricdef immZExt16  : PatLeaf<(imm), [{
5400b57cec5SDimitry Andric  // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended
5410b57cec5SDimitry Andric  // field.  Used by instructions like 'ori'.
5420b57cec5SDimitry Andric  return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
5430b57cec5SDimitry Andric}], LO16>;
5448bcb0991SDimitry Andricdef immNonAllOneAnyExt8 : ImmLeaf<i32, [{
5458bcb0991SDimitry Andric  return (isInt<8>(Imm) && (Imm != -1)) || (isUInt<8>(Imm) && (Imm != 0xFF));
5468bcb0991SDimitry Andric}]>;
5475ffd83dbSDimitry Andricdef i32immNonAllOneNonZero : ImmLeaf<i32, [{ return Imm && (Imm != -1); }]>;
5480b57cec5SDimitry Andricdef immSExt5NonZero : ImmLeaf<i32, [{ return Imm && isInt<5>(Imm); }]>;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric// imm16Shifted* - These match immediates where the low 16-bits are zero.  There
5510b57cec5SDimitry Andric// are two forms: imm16ShiftedSExt and imm16ShiftedZExt.  These two forms are
5520b57cec5SDimitry Andric// identical in 32-bit mode, but in 64-bit mode, they return true if the
5530b57cec5SDimitry Andric// immediate fits into a sign/zero extended 32-bit immediate (with the low bits
5540b57cec5SDimitry Andric// clear).
5550b57cec5SDimitry Andricdef imm16ShiftedZExt : PatLeaf<(imm), [{
5560b57cec5SDimitry Andric  // imm16ShiftedZExt predicate - True if only bits in the top 16-bits of the
5570b57cec5SDimitry Andric  // immediate are set.  Used by instructions like 'xoris'.
5580b57cec5SDimitry Andric  return (N->getZExtValue() & ~uint64_t(0xFFFF0000)) == 0;
5590b57cec5SDimitry Andric}], HI16>;
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andricdef imm16ShiftedSExt : PatLeaf<(imm), [{
5620b57cec5SDimitry Andric  // imm16ShiftedSExt predicate - True if only bits in the top 16-bits of the
5630b57cec5SDimitry Andric  // immediate are set.  Used by instructions like 'addis'.  Identical to
5640b57cec5SDimitry Andric  // imm16ShiftedZExt in 32-bit mode.
5650b57cec5SDimitry Andric  if (N->getZExtValue() & 0xFFFF) return false;
5660b57cec5SDimitry Andric  if (N->getValueType(0) == MVT::i32)
5670b57cec5SDimitry Andric    return true;
5680b57cec5SDimitry Andric  // For 64-bit, make sure it is sext right.
5690b57cec5SDimitry Andric  return N->getZExtValue() == (uint64_t)(int)N->getZExtValue();
5700b57cec5SDimitry Andric}], HI16>;
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andricdef imm64ZExt32  : Operand<i64>, ImmLeaf<i64, [{
5730b57cec5SDimitry Andric  // imm64ZExt32 predicate - True if the i64 immediate fits in a 32-bit
5740b57cec5SDimitry Andric  // zero extended field.
5750b57cec5SDimitry Andric  return isUInt<32>(Imm);
5760b57cec5SDimitry Andric}]>;
5770b57cec5SDimitry Andric
578e8d8bef9SDimitry Andric// This is a somewhat weaker condition than actually checking for 4-byte
579e8d8bef9SDimitry Andric// alignment. It is simply checking that the displacement can be represented
580e8d8bef9SDimitry Andric// as an immediate that is a multiple of 4 (i.e. the requirements for DS-Form
581e8d8bef9SDimitry Andric// instructions).
582e8d8bef9SDimitry Andric// But some r+i load/store instructions (such as LD, STD, LDU, etc.) that require
5830b57cec5SDimitry Andric// restricted memrix (4-aligned) constants are alignment sensitive. If these
5840b57cec5SDimitry Andric// offsets are hidden behind TOC entries than the values of the lower-order
5850b57cec5SDimitry Andric// bits cannot be checked directly. As a result, we need to also incorporate
5860b57cec5SDimitry Andric// an alignment check into the relevant patterns.
5870b57cec5SDimitry Andric
588e8d8bef9SDimitry Andricdef DSFormLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
589bdd1243dSDimitry Andric  return isOffsetMultipleOf(N, 4) || cast<LoadSDNode>(N)->getAlign() >= 4;
5900b57cec5SDimitry Andric}]>;
591e8d8bef9SDimitry Andricdef DSFormStore : PatFrag<(ops node:$val, node:$ptr),
5920b57cec5SDimitry Andric                            (store node:$val, node:$ptr), [{
593bdd1243dSDimitry Andric  return isOffsetMultipleOf(N, 4) || cast<StoreSDNode>(N)->getAlign() >= 4;
5940b57cec5SDimitry Andric}]>;
595e8d8bef9SDimitry Andricdef DSFormSextLoadi32 : PatFrag<(ops node:$ptr), (sextloadi32 node:$ptr), [{
596bdd1243dSDimitry Andric  return isOffsetMultipleOf(N, 4) || cast<LoadSDNode>(N)->getAlign() >= 4;
5970b57cec5SDimitry Andric}]>;
598e8d8bef9SDimitry Andricdef DSFormPreStore : PatFrag<
5990b57cec5SDimitry Andric                          (ops node:$val, node:$base, node:$offset),
6000b57cec5SDimitry Andric                          (pre_store node:$val, node:$base, node:$offset), [{
601bdd1243dSDimitry Andric  return isOffsetMultipleOf(N, 4) || cast<StoreSDNode>(N)->getAlign() >= 4;
6020b57cec5SDimitry Andric}]>;
6030b57cec5SDimitry Andric
604e8d8bef9SDimitry Andricdef NonDSFormLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
605bdd1243dSDimitry Andric  return cast<LoadSDNode>(N)->getAlign() < 4 && !isOffsetMultipleOf(N, 4);
6060b57cec5SDimitry Andric}]>;
607e8d8bef9SDimitry Andricdef NonDSFormStore : PatFrag<(ops node:$val, node:$ptr),
6080b57cec5SDimitry Andric                              (store node:$val, node:$ptr), [{
609bdd1243dSDimitry Andric  return cast<StoreSDNode>(N)->getAlign() < 4 && !isOffsetMultipleOf(N, 4);
6100b57cec5SDimitry Andric}]>;
611e8d8bef9SDimitry Andricdef NonDSFormSextLoadi32 : PatFrag<(ops node:$ptr), (sextloadi32 node:$ptr), [{
612bdd1243dSDimitry Andric  return cast<LoadSDNode>(N)->getAlign() < 4 && !isOffsetMultipleOf(N, 4);
6130b57cec5SDimitry Andric}]>;
6140b57cec5SDimitry Andric
6150b57cec5SDimitry Andric// This is a somewhat weaker condition than actually checking for 16-byte
6160b57cec5SDimitry Andric// alignment. It is simply checking that the displacement can be represented
6170b57cec5SDimitry Andric// as an immediate that is a multiple of 16 (i.e. the requirements for DQ-Form
6180b57cec5SDimitry Andric// instructions).
6190b57cec5SDimitry Andricdef quadwOffsetLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
6200b57cec5SDimitry Andric  return isOffsetMultipleOf(N, 16);
6210b57cec5SDimitry Andric}]>;
6220b57cec5SDimitry Andricdef quadwOffsetStore : PatFrag<(ops node:$val, node:$ptr),
6230b57cec5SDimitry Andric                               (store node:$val, node:$ptr), [{
6240b57cec5SDimitry Andric  return isOffsetMultipleOf(N, 16);
6250b57cec5SDimitry Andric}]>;
6260b57cec5SDimitry Andricdef nonQuadwOffsetLoad : PatFrag<(ops node:$ptr), (load node:$ptr), [{
6270b57cec5SDimitry Andric  return !isOffsetMultipleOf(N, 16);
6280b57cec5SDimitry Andric}]>;
6290b57cec5SDimitry Andricdef nonQuadwOffsetStore : PatFrag<(ops node:$val, node:$ptr),
6300b57cec5SDimitry Andric                                  (store node:$val, node:$ptr), [{
6310b57cec5SDimitry Andric  return !isOffsetMultipleOf(N, 16);
6320b57cec5SDimitry Andric}]>;
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andric// PatFrag for binary operation whose operands are both non-constant
6350b57cec5SDimitry Andricclass BinOpWithoutSImm16Operand<SDNode opcode> :
6360b57cec5SDimitry Andric  PatFrag<(ops node:$left, node:$right), (opcode node:$left, node:$right), [{
6370b57cec5SDimitry Andric    int16_t Imm;
6380b57cec5SDimitry Andric    return !isIntS16Immediate(N->getOperand(0), Imm)
6390b57cec5SDimitry Andric             && !isIntS16Immediate(N->getOperand(1), Imm);
6400b57cec5SDimitry Andric}]>;
6410b57cec5SDimitry Andric
6420b57cec5SDimitry Andricdef add_without_simm16 : BinOpWithoutSImm16Operand<add>;
6430b57cec5SDimitry Andricdef mul_without_simm16 : BinOpWithoutSImm16Operand<mul>;
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6460b57cec5SDimitry Andric// PowerPC Flag Definitions.
6470b57cec5SDimitry Andric
6480b57cec5SDimitry Andricclass isPPC64 { bit PPC64 = 1; }
649480093f4SDimitry Andricclass isRecordForm   { bit RC = 1; }
6500b57cec5SDimitry Andric
6510b57cec5SDimitry Andricclass RegConstraint<string C> {
6520b57cec5SDimitry Andric  string Constraints = C;
6530b57cec5SDimitry Andric}
6540b57cec5SDimitry Andricclass NoEncode<string E> {
6550b57cec5SDimitry Andric  string DisableEncoding = E;
6560b57cec5SDimitry Andric}
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andric
6590b57cec5SDimitry Andric// Define PowerPC specific addressing mode.
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andric// d-form
6620b57cec5SDimitry Andricdef iaddr    : ComplexPattern<iPTR, 2, "SelectAddrImm",     [], []>; // "stb"
6630b57cec5SDimitry Andric// ds-form
6640b57cec5SDimitry Andricdef iaddrX4  : ComplexPattern<iPTR, 2, "SelectAddrImmX4",   [], []>; // "std"
6650b57cec5SDimitry Andric// dq-form
6660b57cec5SDimitry Andricdef iaddrX16 : ComplexPattern<iPTR, 2, "SelectAddrImmX16",  [], []>; // "stxv"
667e8d8bef9SDimitry Andric// 8LS:d-form
668e8d8bef9SDimitry Andricdef iaddrX34 : ComplexPattern<iPTR, 2, "SelectAddrImmX34",  [], []>; // "pstxvp"
6690b57cec5SDimitry Andric
6700b57cec5SDimitry Andric// Below forms are all x-form addressing mode, use three different ones so we
6710b57cec5SDimitry Andric// can make a accurate check for x-form instructions in ISEL.
6725ffd83dbSDimitry Andric// x-form addressing mode whose associated displacement form is D.
6730b57cec5SDimitry Andricdef xaddr  : ComplexPattern<iPTR, 2, "SelectAddrIdx",     [], []>;    // "stbx"
6745ffd83dbSDimitry Andric// x-form addressing mode whose associated displacement form is DS.
6750b57cec5SDimitry Andricdef xaddrX4 : ComplexPattern<iPTR, 2, "SelectAddrIdxX4",    [], []>;  // "stdx"
6765ffd83dbSDimitry Andric// x-form addressing mode whose associated displacement form is DQ.
6770b57cec5SDimitry Andricdef xaddrX16 : ComplexPattern<iPTR, 2, "SelectAddrIdxX16",   [], []>; // "stxvx"
6780b57cec5SDimitry Andric
6790b57cec5SDimitry Andricdef xoaddr : ComplexPattern<iPTR, 2, "SelectAddrIdxOnly",[], []>;
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andric// The address in a single register. This is used with the SjLj
6820b57cec5SDimitry Andric// pseudo-instructions.
6830b57cec5SDimitry Andricdef addr   : ComplexPattern<iPTR, 1, "SelectAddr",[], []>;
6840b57cec5SDimitry Andric
6850b57cec5SDimitry Andric/// This is just the offset part of iaddr, used for preinc.
6860b57cec5SDimitry Andricdef iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>;
6870b57cec5SDimitry Andric
688fe6060f1SDimitry Andric// Load and Store Instruction Selection addressing modes.
689fe6060f1SDimitry Andricdef DForm  : ComplexPattern<iPTR, 2, "SelectDForm",    [], [SDNPWantParent]>;
690fe6060f1SDimitry Andricdef DSForm : ComplexPattern<iPTR, 2, "SelectDSForm",   [], [SDNPWantParent]>;
691fe6060f1SDimitry Andricdef DQForm : ComplexPattern<iPTR, 2, "SelectDQForm",   [], [SDNPWantParent]>;
692fe6060f1SDimitry Andricdef XForm  : ComplexPattern<iPTR, 2, "SelectXForm",    [], [SDNPWantParent]>;
693fe6060f1SDimitry Andricdef ForceXForm : ComplexPattern<iPTR, 2, "SelectForceXForm", [], [SDNPWantParent]>;
694349cc55cSDimitry Andricdef PCRelForm : ComplexPattern<iPTR, 2, "SelectPCRelForm", [], [SDNPWantParent]>;
695349cc55cSDimitry Andricdef PDForm : ComplexPattern<iPTR, 2, "SelectPDForm",   [], [SDNPWantParent]>;
696fe6060f1SDimitry Andric
6970b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6980b57cec5SDimitry Andric// PowerPC Instruction Predicate Definitions.
6995ffd83dbSDimitry Andricdef In32BitMode  : Predicate<"!Subtarget->isPPC64()">;
7005ffd83dbSDimitry Andricdef In64BitMode  : Predicate<"Subtarget->isPPC64()">;
7015ffd83dbSDimitry Andricdef IsBookE  : Predicate<"Subtarget->isBookE()">;
7025ffd83dbSDimitry Andricdef IsNotBookE  : Predicate<"!Subtarget->isBookE()">;
7035ffd83dbSDimitry Andricdef HasOnlyMSYNC : Predicate<"Subtarget->hasOnlyMSYNC()">;
7045ffd83dbSDimitry Andricdef HasSYNC   : Predicate<"!Subtarget->hasOnlyMSYNC()">;
7055ffd83dbSDimitry Andricdef IsPPC4xx  : Predicate<"Subtarget->isPPC4xx()">;
7065ffd83dbSDimitry Andricdef IsPPC6xx  : Predicate<"Subtarget->isPPC6xx()">;
7075ffd83dbSDimitry Andricdef IsE500  : Predicate<"Subtarget->isE500()">;
7085ffd83dbSDimitry Andricdef HasSPE  : Predicate<"Subtarget->hasSPE()">;
7095ffd83dbSDimitry Andricdef HasICBT : Predicate<"Subtarget->hasICBT()">;
7105ffd83dbSDimitry Andricdef HasPartwordAtomics : Predicate<"Subtarget->hasPartwordAtomics()">;
711fe6060f1SDimitry Andricdef HasQuadwordAtomics : Predicate<"Subtarget->hasQuadwordAtomics()">;
7125ffd83dbSDimitry Andricdef NoNaNsFPMath
7135ffd83dbSDimitry Andric    : Predicate<"Subtarget->getTargetMachine().Options.NoNaNsFPMath">;
7145ffd83dbSDimitry Andricdef NaNsFPMath
7155ffd83dbSDimitry Andric    : Predicate<"!Subtarget->getTargetMachine().Options.NoNaNsFPMath">;
7165ffd83dbSDimitry Andricdef HasBPERMD : Predicate<"Subtarget->hasBPERMD()">;
7175ffd83dbSDimitry Andricdef HasExtDiv : Predicate<"Subtarget->hasExtDiv()">;
718349cc55cSDimitry Andricdef IsISA2_06 : Predicate<"Subtarget->isISA2_06()">;
719fe6060f1SDimitry Andricdef IsISA2_07 : Predicate<"Subtarget->isISA2_07()">;
7205ffd83dbSDimitry Andricdef IsISA3_0 : Predicate<"Subtarget->isISA3_0()">;
7215ffd83dbSDimitry Andricdef HasFPU : Predicate<"Subtarget->hasFPU()">;
7225ffd83dbSDimitry Andricdef PCRelativeMemops : Predicate<"Subtarget->hasPCRelativeMemops()">;
723e8d8bef9SDimitry Andricdef IsNotISA3_1 : Predicate<"!Subtarget->isISA3_1()">;
724e8d8bef9SDimitry Andric
725e8d8bef9SDimitry Andric// AIX assembler may not be modern enough to support some extended mne.
726e8d8bef9SDimitry Andricdef ModernAs: Predicate<"!Subtarget->isAIXABI() || Subtarget->HasModernAIXAs">,
727e8d8bef9SDimitry Andric                 AssemblerPredicate<(any_of (not AIXOS), FeatureModernAIXAs)>;
728fe6060f1SDimitry Andricdef IsAIX : Predicate<"Subtarget->isAIXABI()">;
729fe6060f1SDimitry Andricdef NotAIX : Predicate<"!Subtarget->isAIXABI()">;
73081ad6265SDimitry Andricdef IsISAFuture : Predicate<"Subtarget->isISAFuture()">;
731bdd1243dSDimitry Andricdef IsNotISAFuture : Predicate<"!Subtarget->isISAFuture()">;
7320b57cec5SDimitry Andric
7330b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7340b57cec5SDimitry Andric// PowerPC Multiclass Definitions.
73506c3fb27SDimitry Andricmulticlass XForm_base_r3xo_r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
73606c3fb27SDimitry Andric                      string asmbase, string asmstr, list<dag> pattern> {
73706c3fb27SDimitry Andric  let BaseName = asmbase in {
73806c3fb27SDimitry Andric    def NAME : XForm_base_r3xo<opcode, xo, OOL, IOL,
73906c3fb27SDimitry Andric                                !strconcat(asmbase, !strconcat(" ", asmstr)),
74006c3fb27SDimitry Andric                                NoItinerary, pattern>, RecFormRel;
74106c3fb27SDimitry Andric    let Defs = [CR1] in
74206c3fb27SDimitry Andric    def _rec : XForm_base_r3xo<opcode, xo, OOL, IOL,
74306c3fb27SDimitry Andric                               !strconcat(asmbase, !strconcat(". ", asmstr)),
74406c3fb27SDimitry Andric                               NoItinerary, []>, isRecordForm, RecFormRel;
74506c3fb27SDimitry Andric  }
74606c3fb27SDimitry Andric}
7470b57cec5SDimitry Andric
7480b57cec5SDimitry Andricmulticlass XForm_6r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
7490b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
7500b57cec5SDimitry Andric                    list<dag> pattern> {
7510b57cec5SDimitry Andric  let BaseName = asmbase in {
7520b57cec5SDimitry Andric    def NAME : XForm_6<opcode, xo, OOL, IOL,
7530b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
7540b57cec5SDimitry Andric                       pattern>, RecFormRel;
7550b57cec5SDimitry Andric    let Defs = [CR0] in
756480093f4SDimitry Andric    def _rec    : XForm_6<opcode, xo, OOL, IOL,
7570b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
758480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
7590b57cec5SDimitry Andric  }
7600b57cec5SDimitry Andric}
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andricmulticlass XForm_6rc<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
7630b57cec5SDimitry Andric                     string asmbase, string asmstr, InstrItinClass itin,
7640b57cec5SDimitry Andric                     list<dag> pattern> {
7650b57cec5SDimitry Andric  let BaseName = asmbase in {
7660b57cec5SDimitry Andric    let Defs = [CARRY] in
7670b57cec5SDimitry Andric    def NAME : XForm_6<opcode, xo, OOL, IOL,
7680b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
7690b57cec5SDimitry Andric                       pattern>, RecFormRel;
7700b57cec5SDimitry Andric    let Defs = [CARRY, CR0] in
771480093f4SDimitry Andric    def _rec    : XForm_6<opcode, xo, OOL, IOL,
7720b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
773480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
7740b57cec5SDimitry Andric  }
7750b57cec5SDimitry Andric}
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andricmulticlass XForm_10rc<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
7780b57cec5SDimitry Andric                      string asmbase, string asmstr, InstrItinClass itin,
7790b57cec5SDimitry Andric                      list<dag> pattern> {
7800b57cec5SDimitry Andric  let BaseName = asmbase in {
7810b57cec5SDimitry Andric    let Defs = [CARRY] in
7820b57cec5SDimitry Andric    def NAME : XForm_10<opcode, xo, OOL, IOL,
7830b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
7840b57cec5SDimitry Andric                       pattern>, RecFormRel;
7850b57cec5SDimitry Andric    let Defs = [CARRY, CR0] in
786480093f4SDimitry Andric    def _rec    : XForm_10<opcode, xo, OOL, IOL,
7870b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
788480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
7890b57cec5SDimitry Andric  }
7900b57cec5SDimitry Andric}
7910b57cec5SDimitry Andric
7920b57cec5SDimitry Andricmulticlass XForm_11r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
7930b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
7940b57cec5SDimitry Andric                    list<dag> pattern> {
7950b57cec5SDimitry Andric  let BaseName = asmbase in {
7960b57cec5SDimitry Andric    def NAME : XForm_11<opcode, xo, OOL, IOL,
7970b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
7980b57cec5SDimitry Andric                       pattern>, RecFormRel;
7990b57cec5SDimitry Andric    let Defs = [CR0] in
800480093f4SDimitry Andric    def _rec    : XForm_11<opcode, xo, OOL, IOL,
8010b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
802480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
8030b57cec5SDimitry Andric  }
8040b57cec5SDimitry Andric}
8050b57cec5SDimitry Andric
8060b57cec5SDimitry Andricmulticlass XOForm_1r<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
8070b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
8080b57cec5SDimitry Andric                    list<dag> pattern> {
8090b57cec5SDimitry Andric  let BaseName = asmbase in {
8100b57cec5SDimitry Andric    def NAME : XOForm_1<opcode, xo, oe, OOL, IOL,
8110b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
8120b57cec5SDimitry Andric                       pattern>, RecFormRel;
8130b57cec5SDimitry Andric    let Defs = [CR0] in
814480093f4SDimitry Andric    def _rec    : XOForm_1<opcode, xo, oe, OOL, IOL,
8150b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
816480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
8170b57cec5SDimitry Andric  }
8180b57cec5SDimitry Andric}
8190b57cec5SDimitry Andric
820c14a5a88SDimitry Andric// Multiclass for instructions which have a record overflow form as well
821c14a5a88SDimitry Andric// as a record form but no carry (i.e. mulld, mulldo, subf, subfo, etc.)
822349cc55cSDimitry Andricmulticlass XOForm_1rx<bits<6> opcode, bits<9> xo, dag OOL, dag IOL,
823c14a5a88SDimitry Andric                      string asmbase, string asmstr, InstrItinClass itin,
824c14a5a88SDimitry Andric                      list<dag> pattern> {
825c14a5a88SDimitry Andric  let BaseName = asmbase in {
826c14a5a88SDimitry Andric    def NAME : XOForm_1<opcode, xo, 0, OOL, IOL,
827c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
828c14a5a88SDimitry Andric                        pattern>, RecFormRel;
829c14a5a88SDimitry Andric    let Defs = [CR0] in
830480093f4SDimitry Andric    def _rec    : XOForm_1<opcode, xo, 0, OOL, IOL,
831c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
832480093f4SDimitry Andric                        []>, isRecordForm, RecFormRel;
833c14a5a88SDimitry Andric  }
834c14a5a88SDimitry Andric  let BaseName = !strconcat(asmbase, "O") in {
835c14a5a88SDimitry Andric    let Defs = [XER] in
836c14a5a88SDimitry Andric    def O    : XOForm_1<opcode, xo, 1, OOL, IOL,
837c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o ", asmstr)), itin,
838c14a5a88SDimitry Andric                        []>, RecFormRel;
839c14a5a88SDimitry Andric    let Defs = [XER, CR0] in
840480093f4SDimitry Andric    def O_rec    : XOForm_1<opcode, xo, 1, OOL, IOL,
841c14a5a88SDimitry Andric                         !strconcat(asmbase, !strconcat("o. ", asmstr)), itin,
842480093f4SDimitry Andric                         []>, isRecordForm, RecFormRel;
843c14a5a88SDimitry Andric  }
844c14a5a88SDimitry Andric}
845c14a5a88SDimitry Andric
8460b57cec5SDimitry Andric// Multiclass for instructions for which the non record form is not cracked
8470b57cec5SDimitry Andric// and the record form is cracked (i.e. divw, mullw, etc.)
8480b57cec5SDimitry Andricmulticlass XOForm_1rcr<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
8490b57cec5SDimitry Andric                      string asmbase, string asmstr, InstrItinClass itin,
8500b57cec5SDimitry Andric                      list<dag> pattern> {
8510b57cec5SDimitry Andric  let BaseName = asmbase in {
8520b57cec5SDimitry Andric    def NAME : XOForm_1<opcode, xo, oe, OOL, IOL,
8530b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
8540b57cec5SDimitry Andric                       pattern>, RecFormRel;
8550b57cec5SDimitry Andric    let Defs = [CR0] in
856480093f4SDimitry Andric    def _rec    : XOForm_1<opcode, xo, oe, OOL, IOL,
8570b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
858480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel, PPC970_DGroup_First,
8590b57cec5SDimitry Andric                       PPC970_DGroup_Cracked;
8600b57cec5SDimitry Andric  }
861c14a5a88SDimitry Andric  let BaseName = !strconcat(asmbase, "O") in {
862c14a5a88SDimitry Andric    let Defs = [XER] in
863c14a5a88SDimitry Andric    def O    : XOForm_1<opcode, xo, 1, OOL, IOL,
864c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o ", asmstr)), itin,
865c14a5a88SDimitry Andric                        []>, RecFormRel;
866c14a5a88SDimitry Andric    let Defs = [XER, CR0] in
867480093f4SDimitry Andric    def O_rec   : XOForm_1<opcode, xo, 1, OOL, IOL,
868c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o. ", asmstr)), itin,
869480093f4SDimitry Andric                        []>, isRecordForm, RecFormRel;
870c14a5a88SDimitry Andric  }
8710b57cec5SDimitry Andric}
8720b57cec5SDimitry Andric
8730b57cec5SDimitry Andricmulticlass XOForm_1rc<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
8740b57cec5SDimitry Andric                      string asmbase, string asmstr, InstrItinClass itin,
8750b57cec5SDimitry Andric                      list<dag> pattern> {
8760b57cec5SDimitry Andric  let BaseName = asmbase in {
8770b57cec5SDimitry Andric    let Defs = [CARRY] in
8780b57cec5SDimitry Andric    def NAME : XOForm_1<opcode, xo, oe, OOL, IOL,
8790b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
8800b57cec5SDimitry Andric                       pattern>, RecFormRel;
8810b57cec5SDimitry Andric    let Defs = [CARRY, CR0] in
882480093f4SDimitry Andric    def _rec    : XOForm_1<opcode, xo, oe, OOL, IOL,
8830b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
884480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
8850b57cec5SDimitry Andric  }
886c14a5a88SDimitry Andric  let BaseName = !strconcat(asmbase, "O") in {
887c14a5a88SDimitry Andric    let Defs = [CARRY, XER] in
888c14a5a88SDimitry Andric    def O    : XOForm_1<opcode, xo, 1, OOL, IOL,
889c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o ", asmstr)), itin,
890c14a5a88SDimitry Andric                        []>, RecFormRel;
891c14a5a88SDimitry Andric    let Defs = [CARRY, XER, CR0] in
892480093f4SDimitry Andric    def O_rec   : XOForm_1<opcode, xo, 1, OOL, IOL,
893c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o. ", asmstr)), itin,
894480093f4SDimitry Andric                        []>, isRecordForm, RecFormRel;
895c14a5a88SDimitry Andric  }
8960b57cec5SDimitry Andric}
8970b57cec5SDimitry Andric
8980b57cec5SDimitry Andricmulticlass XOForm_3r<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
8990b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
9000b57cec5SDimitry Andric                    list<dag> pattern> {
9010b57cec5SDimitry Andric  let BaseName = asmbase in {
9020b57cec5SDimitry Andric    def NAME : XOForm_3<opcode, xo, oe, OOL, IOL,
9030b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
9040b57cec5SDimitry Andric                       pattern>, RecFormRel;
9050b57cec5SDimitry Andric    let Defs = [CR0] in
906480093f4SDimitry Andric    def _rec    : XOForm_3<opcode, xo, oe, OOL, IOL,
9070b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
908480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
9090b57cec5SDimitry Andric  }
910c14a5a88SDimitry Andric  let BaseName = !strconcat(asmbase, "O") in {
911c14a5a88SDimitry Andric    let Defs = [XER] in
912c14a5a88SDimitry Andric    def O    : XOForm_3<opcode, xo, 1, OOL, IOL,
913c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o ", asmstr)), itin,
914c14a5a88SDimitry Andric                        []>, RecFormRel;
915c14a5a88SDimitry Andric    let Defs = [XER, CR0] in
916480093f4SDimitry Andric    def O_rec   : XOForm_3<opcode, xo, 1, OOL, IOL,
917c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o. ", asmstr)), itin,
918480093f4SDimitry Andric                        []>, isRecordForm, RecFormRel;
919c14a5a88SDimitry Andric  }
9200b57cec5SDimitry Andric}
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andricmulticlass XOForm_3rc<bits<6> opcode, bits<9> xo, bit oe, dag OOL, dag IOL,
9230b57cec5SDimitry Andric                      string asmbase, string asmstr, InstrItinClass itin,
9240b57cec5SDimitry Andric                      list<dag> pattern> {
9250b57cec5SDimitry Andric  let BaseName = asmbase in {
9260b57cec5SDimitry Andric    let Defs = [CARRY] in
9270b57cec5SDimitry Andric    def NAME : XOForm_3<opcode, xo, oe, OOL, IOL,
9280b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
9290b57cec5SDimitry Andric                       pattern>, RecFormRel;
9300b57cec5SDimitry Andric    let Defs = [CARRY, CR0] in
931480093f4SDimitry Andric    def _rec    : XOForm_3<opcode, xo, oe, OOL, IOL,
9320b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
933480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
9340b57cec5SDimitry Andric  }
935c14a5a88SDimitry Andric  let BaseName = !strconcat(asmbase, "O") in {
936c14a5a88SDimitry Andric    let Defs = [CARRY, XER] in
937c14a5a88SDimitry Andric    def O    : XOForm_3<opcode, xo, 1, OOL, IOL,
938c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o ", asmstr)), itin,
939c14a5a88SDimitry Andric                        []>, RecFormRel;
940c14a5a88SDimitry Andric    let Defs = [CARRY, XER, CR0] in
941480093f4SDimitry Andric    def O_rec   : XOForm_3<opcode, xo, 1, OOL, IOL,
942c14a5a88SDimitry Andric                        !strconcat(asmbase, !strconcat("o. ", asmstr)), itin,
943480093f4SDimitry Andric                        []>, isRecordForm, RecFormRel;
944c14a5a88SDimitry Andric  }
9450b57cec5SDimitry Andric}
9460b57cec5SDimitry Andric
94706c3fb27SDimitry Andricmulticlass MForm_1r<bits<6> opcode, dag OOL, dag IOL,
94806c3fb27SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
94906c3fb27SDimitry Andric                    list<dag> pattern> {
95006c3fb27SDimitry Andric  let BaseName = asmbase in {
95106c3fb27SDimitry Andric    def NAME : MForm_1<opcode, OOL, IOL,
95206c3fb27SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
95306c3fb27SDimitry Andric                       pattern>, RecFormRel;
95406c3fb27SDimitry Andric    let Defs = [CR0] in
95506c3fb27SDimitry Andric    def _rec    : MForm_1<opcode, OOL, IOL,
95606c3fb27SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
95706c3fb27SDimitry Andric                       []>, isRecordForm, RecFormRel;
95806c3fb27SDimitry Andric  }
95906c3fb27SDimitry Andric}
96006c3fb27SDimitry Andric
9610b57cec5SDimitry Andricmulticlass MForm_2r<bits<6> opcode, dag OOL, dag IOL,
9620b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
9630b57cec5SDimitry Andric                    list<dag> pattern> {
9640b57cec5SDimitry Andric  let BaseName = asmbase in {
9650b57cec5SDimitry Andric    def NAME : MForm_2<opcode, OOL, IOL,
9660b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
9670b57cec5SDimitry Andric                       pattern>, RecFormRel;
9680b57cec5SDimitry Andric    let Defs = [CR0] in
969480093f4SDimitry Andric    def _rec    : MForm_2<opcode, OOL, IOL,
9700b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
971480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
9720b57cec5SDimitry Andric  }
9730b57cec5SDimitry Andric}
9740b57cec5SDimitry Andric
9750b57cec5SDimitry Andricmulticlass MDForm_1r<bits<6> opcode, bits<3> xo, dag OOL, dag IOL,
9760b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
9770b57cec5SDimitry Andric                    list<dag> pattern> {
9780b57cec5SDimitry Andric  let BaseName = asmbase in {
9790b57cec5SDimitry Andric    def NAME : MDForm_1<opcode, xo, OOL, IOL,
9800b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
9810b57cec5SDimitry Andric                       pattern>, RecFormRel;
9820b57cec5SDimitry Andric    let Defs = [CR0] in
983480093f4SDimitry Andric    def _rec    : MDForm_1<opcode, xo, OOL, IOL,
9840b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
985480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
9860b57cec5SDimitry Andric  }
9870b57cec5SDimitry Andric}
9880b57cec5SDimitry Andric
9890b57cec5SDimitry Andricmulticlass MDSForm_1r<bits<6> opcode, bits<4> xo, dag OOL, dag IOL,
9900b57cec5SDimitry Andric                     string asmbase, string asmstr, InstrItinClass itin,
9910b57cec5SDimitry Andric                     list<dag> pattern> {
9920b57cec5SDimitry Andric  let BaseName = asmbase in {
9930b57cec5SDimitry Andric    def NAME : MDSForm_1<opcode, xo, OOL, IOL,
9940b57cec5SDimitry Andric                        !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
9950b57cec5SDimitry Andric                        pattern>, RecFormRel;
9960b57cec5SDimitry Andric    let Defs = [CR0] in
997480093f4SDimitry Andric    def _rec    : MDSForm_1<opcode, xo, OOL, IOL,
9980b57cec5SDimitry Andric                        !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
999480093f4SDimitry Andric                        []>, isRecordForm, RecFormRel;
10000b57cec5SDimitry Andric  }
10010b57cec5SDimitry Andric}
10020b57cec5SDimitry Andric
10030b57cec5SDimitry Andricmulticlass XSForm_1rc<bits<6> opcode, bits<9> xo, dag OOL, dag IOL,
10040b57cec5SDimitry Andric                      string asmbase, string asmstr, InstrItinClass itin,
10050b57cec5SDimitry Andric                      list<dag> pattern> {
10060b57cec5SDimitry Andric  let BaseName = asmbase in {
10070b57cec5SDimitry Andric    let Defs = [CARRY] in
10080b57cec5SDimitry Andric    def NAME : XSForm_1<opcode, xo, OOL, IOL,
10090b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
10100b57cec5SDimitry Andric                       pattern>, RecFormRel;
10110b57cec5SDimitry Andric    let Defs = [CARRY, CR0] in
1012480093f4SDimitry Andric    def _rec    : XSForm_1<opcode, xo, OOL, IOL,
10130b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1014480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
10150b57cec5SDimitry Andric  }
10160b57cec5SDimitry Andric}
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andricmulticlass XSForm_1r<bits<6> opcode, bits<9> xo, dag OOL, dag IOL,
10190b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
10200b57cec5SDimitry Andric                    list<dag> pattern> {
10210b57cec5SDimitry Andric  let BaseName = asmbase in {
10220b57cec5SDimitry Andric    def NAME : XSForm_1<opcode, xo, OOL, IOL,
10230b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
10240b57cec5SDimitry Andric                       pattern>, RecFormRel;
10250b57cec5SDimitry Andric    let Defs = [CR0] in
1026480093f4SDimitry Andric    def _rec    : XSForm_1<opcode, xo, OOL, IOL,
10270b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1028480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
10290b57cec5SDimitry Andric  }
10300b57cec5SDimitry Andric}
10310b57cec5SDimitry Andric
10320b57cec5SDimitry Andricmulticlass XForm_26r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
10330b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
10340b57cec5SDimitry Andric                    list<dag> pattern> {
10350b57cec5SDimitry Andric  let BaseName = asmbase in {
10360b57cec5SDimitry Andric    def NAME : XForm_26<opcode, xo, OOL, IOL,
10370b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
10380b57cec5SDimitry Andric                       pattern>, RecFormRel;
10390b57cec5SDimitry Andric    let Defs = [CR1] in
1040480093f4SDimitry Andric    def _rec    : XForm_26<opcode, xo, OOL, IOL,
10410b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1042480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
10430b57cec5SDimitry Andric  }
10440b57cec5SDimitry Andric}
10450b57cec5SDimitry Andric
10460b57cec5SDimitry Andricmulticlass XForm_28r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
10470b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
10480b57cec5SDimitry Andric                    list<dag> pattern> {
10490b57cec5SDimitry Andric  let BaseName = asmbase in {
10500b57cec5SDimitry Andric    def NAME : XForm_28<opcode, xo, OOL, IOL,
10510b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
10520b57cec5SDimitry Andric                       pattern>, RecFormRel;
10530b57cec5SDimitry Andric    let Defs = [CR1] in
1054480093f4SDimitry Andric    def _rec    : XForm_28<opcode, xo, OOL, IOL,
10550b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1056480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
10570b57cec5SDimitry Andric  }
10580b57cec5SDimitry Andric}
10590b57cec5SDimitry Andric
106006c3fb27SDimitry Andricmulticlass XForm_SP2_FRTB5r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
106106c3fb27SDimitry Andric                        string asmbase, string asmstr, list<dag> pattern> {
106206c3fb27SDimitry Andric  let BaseName = asmbase in {
106306c3fb27SDimitry Andric    def NAME : XForm_SP2_FRTB5<opcode, xo, OOL, IOL,
106406c3fb27SDimitry Andric                               !strconcat(asmbase, !strconcat(" ", asmstr)),
106506c3fb27SDimitry Andric                               pattern, NoItinerary>, RecFormRel;
106606c3fb27SDimitry Andric    let Defs = [CR1] in
106706c3fb27SDimitry Andric    def _rec : XForm_SP2_FRTB5<opcode, xo, OOL, IOL,
106806c3fb27SDimitry Andric                               !strconcat(asmbase, !strconcat(". ", asmstr)),
106906c3fb27SDimitry Andric                               [], NoItinerary>, isRecordForm, RecFormRel;
107006c3fb27SDimitry Andric  }
107106c3fb27SDimitry Andric}
107206c3fb27SDimitry Andric
107306c3fb27SDimitry Andricmulticlass XForm_S1_FRTB5r<bits<6> opcode, bits<10> xo, dag OOL, dag IOL,
107406c3fb27SDimitry Andric                      string asmbase, string asmstr, list<dag> pattern> {
107506c3fb27SDimitry Andric  let BaseName = asmbase in {
107606c3fb27SDimitry Andric    def NAME : XForm_S1_FRTB5<opcode, xo, OOL, IOL,
107706c3fb27SDimitry Andric                              !strconcat(asmbase, !strconcat(" ", asmstr)),
107806c3fb27SDimitry Andric                              pattern, NoItinerary>, RecFormRel;
107906c3fb27SDimitry Andric    let Defs = [CR1] in
108006c3fb27SDimitry Andric    def _rec : XForm_S1_FRTB5<opcode, xo, OOL, IOL,
108106c3fb27SDimitry Andric                              !strconcat(asmbase, !strconcat(". ", asmstr)), [],
108206c3fb27SDimitry Andric                              NoItinerary>, isRecordForm, RecFormRel;
108306c3fb27SDimitry Andric  }
108406c3fb27SDimitry Andric}
108506c3fb27SDimitry Andric
10860b57cec5SDimitry Andricmulticlass AForm_1r<bits<6> opcode, bits<5> xo, dag OOL, dag IOL,
10870b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
10880b57cec5SDimitry Andric                    list<dag> pattern> {
10890b57cec5SDimitry Andric  let BaseName = asmbase in {
10900b57cec5SDimitry Andric    def NAME : AForm_1<opcode, xo, OOL, IOL,
10910b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
10920b57cec5SDimitry Andric                       pattern>, RecFormRel;
10930b57cec5SDimitry Andric    let Defs = [CR1] in
1094480093f4SDimitry Andric    def _rec    : AForm_1<opcode, xo, OOL, IOL,
10950b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1096480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
10970b57cec5SDimitry Andric  }
10980b57cec5SDimitry Andric}
10990b57cec5SDimitry Andric
11000b57cec5SDimitry Andricmulticlass AForm_2r<bits<6> opcode, bits<5> xo, dag OOL, dag IOL,
11010b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
11020b57cec5SDimitry Andric                    list<dag> pattern> {
11030b57cec5SDimitry Andric  let BaseName = asmbase in {
11040b57cec5SDimitry Andric    def NAME : AForm_2<opcode, xo, OOL, IOL,
11050b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
11060b57cec5SDimitry Andric                       pattern>, RecFormRel;
11070b57cec5SDimitry Andric    let Defs = [CR1] in
1108480093f4SDimitry Andric    def _rec    : AForm_2<opcode, xo, OOL, IOL,
11090b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1110480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
11110b57cec5SDimitry Andric  }
11120b57cec5SDimitry Andric}
11130b57cec5SDimitry Andric
11140b57cec5SDimitry Andricmulticlass AForm_3r<bits<6> opcode, bits<5> xo, dag OOL, dag IOL,
11150b57cec5SDimitry Andric                    string asmbase, string asmstr, InstrItinClass itin,
11160b57cec5SDimitry Andric                    list<dag> pattern> {
11170b57cec5SDimitry Andric  let BaseName = asmbase in {
11180b57cec5SDimitry Andric    def NAME : AForm_3<opcode, xo, OOL, IOL,
11190b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(" ", asmstr)), itin,
11200b57cec5SDimitry Andric                       pattern>, RecFormRel;
11210b57cec5SDimitry Andric    let Defs = [CR1] in
1122480093f4SDimitry Andric    def _rec    : AForm_3<opcode, xo, OOL, IOL,
11230b57cec5SDimitry Andric                       !strconcat(asmbase, !strconcat(". ", asmstr)), itin,
1124480093f4SDimitry Andric                       []>, isRecordForm, RecFormRel;
11250b57cec5SDimitry Andric  }
11260b57cec5SDimitry Andric}
11270b57cec5SDimitry Andric
112806c3fb27SDimitry Andricmulticlass
112906c3fb27SDimitry Andric    Z23Form_TE5_FRTB5_RMC2r<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
113006c3fb27SDimitry Andric                            string asmbase, string asmstr, list<dag> pattern> {
113106c3fb27SDimitry Andric  let BaseName = asmbase in {
113206c3fb27SDimitry Andric    def NAME
113306c3fb27SDimitry Andric        : Z23Form_TE5_FRTB5_RMC2<opcode, xo, OOL, IOL,
113406c3fb27SDimitry Andric                                 !strconcat(asmbase, !strconcat(" ", asmstr)),
113506c3fb27SDimitry Andric                                 pattern>, RecFormRel;
113606c3fb27SDimitry Andric    let Defs = [CR0] in
113706c3fb27SDimitry Andric    def _rec : Z23Form_TE5_FRTB5_RMC2<opcode, xo, OOL, IOL,
113806c3fb27SDimitry Andric                                 !strconcat(asmbase, !strconcat(". ", asmstr)),
113906c3fb27SDimitry Andric                                 []>, isRecordForm, RecFormRel;
114006c3fb27SDimitry Andric  }
114106c3fb27SDimitry Andric}
114206c3fb27SDimitry Andric
114306c3fb27SDimitry Andricmulticlass
114406c3fb27SDimitry Andric    Z23Form_FRTAB5_RMC2r<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
114506c3fb27SDimitry Andric                         string asmbase, string asmstr, list<dag> pattern> {
114606c3fb27SDimitry Andric  let BaseName = asmbase in {
114706c3fb27SDimitry Andric    def NAME : Z23Form_FRTAB5_RMC2<opcode, xo, OOL, IOL,
114806c3fb27SDimitry Andric                                   !strconcat(asmbase, !strconcat(" ", asmstr)),
114906c3fb27SDimitry Andric                                   pattern>, RecFormRel;
115006c3fb27SDimitry Andric    let Defs = [CR1] in
115106c3fb27SDimitry Andric    def _rec : Z23Form_FRTAB5_RMC2<opcode, xo, OOL, IOL,
115206c3fb27SDimitry Andric                              !strconcat(asmbase, !strconcat(". ", asmstr)),
115306c3fb27SDimitry Andric                              []>, isRecordForm, RecFormRel;
115406c3fb27SDimitry Andric  }
115506c3fb27SDimitry Andric}
115606c3fb27SDimitry Andric
115706c3fb27SDimitry Andricmulticlass
115806c3fb27SDimitry Andric    Z23Form_FRTB5_R1_RMC2r<bits<6> opcode, bits<8> xo, dag OOL, dag IOL,
115906c3fb27SDimitry Andric                           string asmbase, string asmstr, list<dag> pattern> {
116006c3fb27SDimitry Andric  let BaseName = asmbase in {
116106c3fb27SDimitry Andric    def NAME : Z23Form_FRTB5_R1_RMC2<opcode, xo, OOL, IOL,
116206c3fb27SDimitry Andric                               !strconcat(asmbase, !strconcat(" ", asmstr)),
116306c3fb27SDimitry Andric                               pattern>, RecFormRel;
116406c3fb27SDimitry Andric    let Defs = [CR1] in
116506c3fb27SDimitry Andric    def _rec : Z23Form_FRTB5_R1_RMC2<opcode, xo, OOL, IOL,
116606c3fb27SDimitry Andric                               !strconcat(asmbase, !strconcat(". ", asmstr)),
116706c3fb27SDimitry Andric                               []>, isRecordForm, RecFormRel;
116806c3fb27SDimitry Andric  }
116906c3fb27SDimitry Andric}
117006c3fb27SDimitry Andric
117106c3fb27SDimitry Andricmulticlass Z22Form_FRTA5_SH6r<bits<6> opcode, bits<9> xo, dag OOL, dag IOL,
117206c3fb27SDimitry Andric                      string asmbase, string asmstr, list<dag> pattern> {
117306c3fb27SDimitry Andric  let BaseName = asmbase in {
117406c3fb27SDimitry Andric    def NAME : Z22Form_FRTA5_SH6<opcode, xo, OOL, IOL,
117506c3fb27SDimitry Andric                                 !strconcat(asmbase, !strconcat(" ", asmstr)),
117606c3fb27SDimitry Andric                                 pattern, NoItinerary>, RecFormRel;
117706c3fb27SDimitry Andric    let Defs = [CR1] in
117806c3fb27SDimitry Andric    def _rec : Z22Form_FRTA5_SH6<opcode, xo, OOL, IOL,
117906c3fb27SDimitry Andric                                 !strconcat(asmbase, !strconcat(". ", asmstr)),
118006c3fb27SDimitry Andric                                 [], NoItinerary>, isRecordForm, RecFormRel;
118106c3fb27SDimitry Andric  }
118206c3fb27SDimitry Andric}
118306c3fb27SDimitry Andric
118406c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
118506c3fb27SDimitry Andric// END OF MULTICLASS DEFINITIONS
118606c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
118706c3fb27SDimitry Andric
11880b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
11890b57cec5SDimitry Andric// PowerPC Instruction Definitions.
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andric// Pseudo instructions:
11920b57cec5SDimitry Andric
11930b57cec5SDimitry Andriclet hasCtrlDep = 1 in {
11940b57cec5SDimitry Andriclet Defs = [R1], Uses = [R1] in {
11950b57cec5SDimitry Andricdef ADJCALLSTACKDOWN : PPCEmitTimePseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2),
11960b57cec5SDimitry Andric                              "#ADJCALLSTACKDOWN $amt1 $amt2",
11970b57cec5SDimitry Andric                              [(callseq_start timm:$amt1, timm:$amt2)]>;
11980b57cec5SDimitry Andricdef ADJCALLSTACKUP   : PPCEmitTimePseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2),
11990b57cec5SDimitry Andric                              "#ADJCALLSTACKUP $amt1 $amt2",
12000b57cec5SDimitry Andric                              [(callseq_end timm:$amt1, timm:$amt2)]>;
12010b57cec5SDimitry Andric}
1202e8d8bef9SDimitry Andric} // hasCtrlDep
12030b57cec5SDimitry Andric
12040b57cec5SDimitry Andriclet Defs = [R1], Uses = [R1] in
12050b57cec5SDimitry Andricdef DYNALLOC : PPCEmitTimePseudo<(outs gprc:$result), (ins gprc:$negsize, memri:$fpsi), "#DYNALLOC",
12060b57cec5SDimitry Andric                       [(set i32:$result,
12070b57cec5SDimitry Andric                             (PPCdynalloc i32:$negsize, iaddr:$fpsi))]>;
12080b57cec5SDimitry Andricdef DYNAREAOFFSET : PPCEmitTimePseudo<(outs i32imm:$result), (ins memri:$fpsi), "#DYNAREAOFFSET",
12090b57cec5SDimitry Andric                       [(set i32:$result, (PPCdynareaoffset iaddr:$fpsi))]>;
12105ffd83dbSDimitry Andric// Probed alloca to support stack clash protection.
12115ffd83dbSDimitry Andriclet Defs = [R1], Uses = [R1], hasNoSchedulingInfo = 1 in {
12125ffd83dbSDimitry Andricdef PROBED_ALLOCA_32 : PPCCustomInserterPseudo<(outs gprc:$result),
12135ffd83dbSDimitry Andric                         (ins gprc:$negsize, memri:$fpsi), "#PROBED_ALLOCA_32",
12145ffd83dbSDimitry Andric                           [(set i32:$result,
12155ffd83dbSDimitry Andric                             (PPCprobedalloca i32:$negsize, iaddr:$fpsi))]>;
1216590d96feSDimitry Andricdef PREPARE_PROBED_ALLOCA_32 : PPCEmitTimePseudo<(outs
1217590d96feSDimitry Andric    gprc:$fp, gprc:$actual_negsize),
12185ffd83dbSDimitry Andric    (ins gprc:$negsize, memri:$fpsi), "#PREPARE_PROBED_ALLOCA_32", []>;
1219590d96feSDimitry Andricdef PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32 : PPCEmitTimePseudo<(outs
1220590d96feSDimitry Andric    gprc:$fp, gprc:$actual_negsize),
1221590d96feSDimitry Andric    (ins gprc:$negsize, memri:$fpsi),
1222590d96feSDimitry Andric    "#PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32", []>,
1223590d96feSDimitry Andric    RegConstraint<"$actual_negsize = $negsize">;
12245ffd83dbSDimitry Andricdef PROBED_STACKALLOC_32 : PPCEmitTimePseudo<(outs gprc:$scratch, gprc:$temp),
12255ffd83dbSDimitry Andric    (ins i64imm:$stacksize),
12265ffd83dbSDimitry Andric    "#PROBED_STACKALLOC_32", []>;
12275ffd83dbSDimitry Andric}
12280b57cec5SDimitry Andric
12290b57cec5SDimitry Andric// SELECT_CC_* - Used to implement the SELECT_CC DAG operation.  Expanded after
12300b57cec5SDimitry Andric// instruction selection into a branch sequence.
12310b57cec5SDimitry Andriclet PPC970_Single = 1 in {
12320b57cec5SDimitry Andric  // Note that SELECT_CC_I4 and SELECT_CC_I8 use the no-r0 register classes
12330b57cec5SDimitry Andric  // because either operand might become the first operand in an isel, and
12340b57cec5SDimitry Andric  // that operand cannot be r0.
12350b57cec5SDimitry Andric  def SELECT_CC_I4 : PPCCustomInserterPseudo<(outs gprc:$dst), (ins crrc:$cond,
12360b57cec5SDimitry Andric                              gprc_nor0:$T, gprc_nor0:$F,
12370b57cec5SDimitry Andric                              i32imm:$BROPC), "#SELECT_CC_I4",
12380b57cec5SDimitry Andric                              []>;
12390b57cec5SDimitry Andric  def SELECT_CC_I8 : PPCCustomInserterPseudo<(outs g8rc:$dst), (ins crrc:$cond,
12400b57cec5SDimitry Andric                              g8rc_nox0:$T, g8rc_nox0:$F,
12410b57cec5SDimitry Andric                              i32imm:$BROPC), "#SELECT_CC_I8",
12420b57cec5SDimitry Andric                              []>;
12430b57cec5SDimitry Andric  def SELECT_CC_F4  : PPCCustomInserterPseudo<(outs f4rc:$dst), (ins crrc:$cond, f4rc:$T, f4rc:$F,
12440b57cec5SDimitry Andric                              i32imm:$BROPC), "#SELECT_CC_F4",
12450b57cec5SDimitry Andric                              []>;
12460b57cec5SDimitry Andric  def SELECT_CC_F8  : PPCCustomInserterPseudo<(outs f8rc:$dst), (ins crrc:$cond, f8rc:$T, f8rc:$F,
12470b57cec5SDimitry Andric                              i32imm:$BROPC), "#SELECT_CC_F8",
12480b57cec5SDimitry Andric                              []>;
12490b57cec5SDimitry Andric  def SELECT_CC_F16  : PPCCustomInserterPseudo<(outs vrrc:$dst), (ins crrc:$cond, vrrc:$T, vrrc:$F,
12500b57cec5SDimitry Andric                              i32imm:$BROPC), "#SELECT_CC_F16",
12510b57cec5SDimitry Andric                              []>;
12520b57cec5SDimitry Andric  def SELECT_CC_VRRC: PPCCustomInserterPseudo<(outs vrrc:$dst), (ins crrc:$cond, vrrc:$T, vrrc:$F,
12530b57cec5SDimitry Andric                              i32imm:$BROPC), "#SELECT_CC_VRRC",
12540b57cec5SDimitry Andric                              []>;
12550b57cec5SDimitry Andric
12560b57cec5SDimitry Andric  // SELECT_* pseudo instructions, like SELECT_CC_* but taking condition
12570b57cec5SDimitry Andric  // register bit directly.
12580b57cec5SDimitry Andric  def SELECT_I4 : PPCCustomInserterPseudo<(outs gprc:$dst), (ins crbitrc:$cond,
12590b57cec5SDimitry Andric                          gprc_nor0:$T, gprc_nor0:$F), "#SELECT_I4",
12600b57cec5SDimitry Andric                          [(set i32:$dst, (select i1:$cond, i32:$T, i32:$F))]>;
12610b57cec5SDimitry Andric  def SELECT_I8 : PPCCustomInserterPseudo<(outs g8rc:$dst), (ins crbitrc:$cond,
12620b57cec5SDimitry Andric                          g8rc_nox0:$T, g8rc_nox0:$F), "#SELECT_I8",
12630b57cec5SDimitry Andric                          [(set i64:$dst, (select i1:$cond, i64:$T, i64:$F))]>;
12640b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
12650b57cec5SDimitry Andric  def SELECT_F4  : PPCCustomInserterPseudo<(outs f4rc:$dst), (ins crbitrc:$cond,
12660b57cec5SDimitry Andric                          f4rc:$T, f4rc:$F), "#SELECT_F4",
12670b57cec5SDimitry Andric                          [(set f32:$dst, (select i1:$cond, f32:$T, f32:$F))]>;
12680b57cec5SDimitry Andric  def SELECT_F8  : PPCCustomInserterPseudo<(outs f8rc:$dst), (ins crbitrc:$cond,
12690b57cec5SDimitry Andric                          f8rc:$T, f8rc:$F), "#SELECT_F8",
12700b57cec5SDimitry Andric                          [(set f64:$dst, (select i1:$cond, f64:$T, f64:$F))]>;
12710b57cec5SDimitry Andric  def SELECT_F16  : PPCCustomInserterPseudo<(outs vrrc:$dst), (ins crbitrc:$cond,
12720b57cec5SDimitry Andric                          vrrc:$T, vrrc:$F), "#SELECT_F16",
12730b57cec5SDimitry Andric                          [(set f128:$dst, (select i1:$cond, f128:$T, f128:$F))]>;
12740b57cec5SDimitry Andric}
12750b57cec5SDimitry Andric  def SELECT_VRRC: PPCCustomInserterPseudo<(outs vrrc:$dst), (ins crbitrc:$cond,
12760b57cec5SDimitry Andric                          vrrc:$T, vrrc:$F), "#SELECT_VRRC",
12770b57cec5SDimitry Andric                          [(set v4i32:$dst,
12780b57cec5SDimitry Andric                                (select i1:$cond, v4i32:$T, v4i32:$F))]>;
12790b57cec5SDimitry Andric}
12800b57cec5SDimitry Andric
12810b57cec5SDimitry Andric// SPILL_CR - Indicate that we're dumping the CR register, so we'll need to
12820b57cec5SDimitry Andric// scavenge a register for it.
12830b57cec5SDimitry Andriclet mayStore = 1 in {
12840b57cec5SDimitry Andricdef SPILL_CR : PPCEmitTimePseudo<(outs), (ins crrc:$cond, memri:$F),
12850b57cec5SDimitry Andric                     "#SPILL_CR", []>;
12860b57cec5SDimitry Andricdef SPILL_CRBIT : PPCEmitTimePseudo<(outs), (ins crbitrc:$cond, memri:$F),
12870b57cec5SDimitry Andric                         "#SPILL_CRBIT", []>;
12880b57cec5SDimitry Andric}
12890b57cec5SDimitry Andric
12900b57cec5SDimitry Andric// RESTORE_CR - Indicate that we're restoring the CR register (previously
12910b57cec5SDimitry Andric// spilled), so we'll need to scavenge a register for it.
12920b57cec5SDimitry Andriclet mayLoad = 1 in {
12930b57cec5SDimitry Andricdef RESTORE_CR : PPCEmitTimePseudo<(outs crrc:$cond), (ins memri:$F),
12940b57cec5SDimitry Andric                     "#RESTORE_CR", []>;
12950b57cec5SDimitry Andricdef RESTORE_CRBIT : PPCEmitTimePseudo<(outs crbitrc:$cond), (ins memri:$F),
12960b57cec5SDimitry Andric                           "#RESTORE_CRBIT", []>;
12970b57cec5SDimitry Andric}
12980b57cec5SDimitry Andric
1299349cc55cSDimitry Andriclet isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, hasSideEffects = 0 in {
1300480093f4SDimitry Andric  let isPredicable = 1, isReturn = 1, Uses = [LR, RM] in
13010b57cec5SDimitry Andric    def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (outs), (ins), "blr", IIC_BrB,
13020fca6ea1SDimitry Andric                           [(PPCretglue)]>, Requires<[In32BitMode]>;
13030b57cec5SDimitry Andric  let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in {
1304480093f4SDimitry Andric    let isPredicable = 1 in
13050b57cec5SDimitry Andric      def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", IIC_BrB,
13060b57cec5SDimitry Andric                              []>;
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andric    let isCodeGenOnly = 1 in {
130906c3fb27SDimitry Andric      def BCCCTR : XLForm_2_br<19, 528, 0, (outs), (ins (pred $BIBO, $CR):$cond),
13100b57cec5SDimitry Andric                               "b${cond:cc}ctr${cond:pm} ${cond:reg}", IIC_BrB,
13110b57cec5SDimitry Andric                               []>;
13120b57cec5SDimitry Andric
131306c3fb27SDimitry Andric      def BCCTR :  XLForm_2_br2<19, 528, 12, 0, (outs), (ins crbitrc:$BI),
131406c3fb27SDimitry Andric                                "bcctr 12, $BI, 0", IIC_BrB, []>;
131506c3fb27SDimitry Andric      def BCCTRn : XLForm_2_br2<19, 528, 4, 0, (outs), (ins crbitrc:$BI),
131606c3fb27SDimitry Andric                                "bcctr 4, $BI, 0", IIC_BrB, []>;
13170b57cec5SDimitry Andric    }
13180b57cec5SDimitry Andric  }
13190b57cec5SDimitry Andric}
13200b57cec5SDimitry Andric
13210b57cec5SDimitry Andric// Set the float rounding mode.
13220b57cec5SDimitry Andriclet Uses = [RM], Defs = [RM] in {
13230b57cec5SDimitry Andricdef SETRNDi : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins u2imm:$RND),
13240b57cec5SDimitry Andric                    "#SETRNDi", [(set f64:$FRT, (int_ppc_setrnd (i32 imm:$RND)))]>;
13250b57cec5SDimitry Andric
13260b57cec5SDimitry Andricdef SETRND : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins gprc:$in),
13270b57cec5SDimitry Andric                    "#SETRND", [(set f64:$FRT, (int_ppc_setrnd gprc :$in))]>;
1328e8d8bef9SDimitry Andric
1329e8d8bef9SDimitry Andricdef SETFLM : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins f8rc:$FLM),
1330e8d8bef9SDimitry Andric                    "#SETFLM", [(set f64:$FRT, (int_ppc_setflm f8rc:$FLM))]>;
13310b57cec5SDimitry Andric}
13320b57cec5SDimitry Andric
13337a6dacacSDimitry Andriclet isBarrier = 1, hasSideEffects = 1, Defs = [RM] in
13347a6dacacSDimitry Andricdef FENCE : PPCEmitTimePseudo<(outs), (ins), "#FENCE", []>;
13357a6dacacSDimitry Andric
13360b57cec5SDimitry Andriclet Defs = [LR] in
13370b57cec5SDimitry Andric  def MovePCtoLR : PPCEmitTimePseudo<(outs), (ins), "#MovePCtoLR", []>,
13380b57cec5SDimitry Andric                   PPC970_Unit_BRU;
13390b57cec5SDimitry Andriclet Defs = [LR] in
13400b57cec5SDimitry Andric  def MoveGOTtoLR : PPCEmitTimePseudo<(outs), (ins), "#MoveGOTtoLR", []>,
13410b57cec5SDimitry Andric                    PPC970_Unit_BRU;
13420b57cec5SDimitry Andric
1343349cc55cSDimitry Andriclet isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
1344349cc55cSDimitry Andric    hasSideEffects = 0 in {
13450b57cec5SDimitry Andric  let isBarrier = 1 in {
1346480093f4SDimitry Andric    let isPredicable = 1 in
134706c3fb27SDimitry Andric      def B : IForm<18, 0, 0, (outs), (ins directbrtarget:$LI),
134806c3fb27SDimitry Andric                    "b $LI", IIC_BrB,
134906c3fb27SDimitry Andric                    [(br bb:$LI)]>;
135006c3fb27SDimitry Andric  def BA  : IForm<18, 1, 0, (outs), (ins absdirectbrtarget:$LI),
135106c3fb27SDimitry Andric                  "ba $LI", IIC_BrB, []>;
13520b57cec5SDimitry Andric  }
13530b57cec5SDimitry Andric
13540b57cec5SDimitry Andric  // BCC represents an arbitrary conditional branch on a predicate.
13550b57cec5SDimitry Andric  // FIXME: should be able to write a pattern for PPCcondbranch, but can't use
13560b57cec5SDimitry Andric  // a two-value operand where a dag node expects two operands. :(
13570b57cec5SDimitry Andric  let isCodeGenOnly = 1 in {
135806c3fb27SDimitry Andric    class BCC_class : BForm<16, 0, 0, (outs), (ins (pred $BIBO, $CR):$cond, condbrtarget:$BD),
135906c3fb27SDimitry Andric                            "b${cond:cc}${cond:pm} ${cond:reg}, $BD"
136006c3fb27SDimitry Andric                            /*[(PPCcondbranch crrc:$crS, imm:$opc, bb:$BD)]*/>;
13610b57cec5SDimitry Andric    def BCC : BCC_class;
13620b57cec5SDimitry Andric
13630b57cec5SDimitry Andric    // The same as BCC, except that it's not a terminator. Used for introducing
13640b57cec5SDimitry Andric    // control flow dependency without creating new blocks.
13650b57cec5SDimitry Andric    let isTerminator = 0 in def CTRL_DEP : BCC_class;
13660b57cec5SDimitry Andric
136706c3fb27SDimitry Andric    def BCCA : BForm<16, 1, 0, (outs), (ins (pred $BIBO, $CR):$cond, abscondbrtarget:$BD),
136806c3fb27SDimitry Andric                     "b${cond:cc}a${cond:pm} ${cond:reg}, $BD">;
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andric    let isReturn = 1, Uses = [LR, RM] in
137106c3fb27SDimitry Andric    def BCCLR : XLForm_2_br<19, 16, 0, (outs), (ins (pred $BIBO, $CR):$cond),
13720b57cec5SDimitry Andric                           "b${cond:cc}lr${cond:pm} ${cond:reg}", IIC_BrB, []>;
13730b57cec5SDimitry Andric  }
13740b57cec5SDimitry Andric
13750b57cec5SDimitry Andric  let isCodeGenOnly = 1 in {
137606c3fb27SDimitry Andric    let Pattern = [(brcond i1:$BI, bb:$BD)] in
137706c3fb27SDimitry Andric    def BC  : BForm_4<16, 12, 0, 0, (outs), (ins crbitrc:$BI, condbrtarget:$BD),
137806c3fb27SDimitry Andric             "bc 12, $BI, $BD">;
13790b57cec5SDimitry Andric
138006c3fb27SDimitry Andric    let Pattern = [(brcond (not i1:$BI), bb:$BD)] in
138106c3fb27SDimitry Andric    def BCn : BForm_4<16, 4, 0, 0, (outs), (ins crbitrc:$BI, condbrtarget:$BD),
138206c3fb27SDimitry Andric             "bc 4, $BI, $BD">;
13830b57cec5SDimitry Andric
1384e8d8bef9SDimitry Andric    let isReturn = 1, Uses = [LR, RM] in {
138506c3fb27SDimitry Andric    def BCLR  : XLForm_2_br2<19, 16, 12, 0, (outs), (ins crbitrc:$BI),
138606c3fb27SDimitry Andric                             "bclr 12, $BI, 0", IIC_BrB, []>;
138706c3fb27SDimitry Andric    def BCLRn : XLForm_2_br2<19, 16, 4, 0, (outs), (ins crbitrc:$BI),
138806c3fb27SDimitry Andric                             "bclr 4, $BI, 0", IIC_BrB, []>;
13890b57cec5SDimitry Andric    }
1390e8d8bef9SDimitry Andric  }
13910b57cec5SDimitry Andric
13920b57cec5SDimitry Andric  let isReturn = 1, Defs = [CTR], Uses = [CTR, LR, RM] in {
13930b57cec5SDimitry Andric   def BDZLR  : XLForm_2_ext<19, 16, 18, 0, 0, (outs), (ins),
13940b57cec5SDimitry Andric                             "bdzlr", IIC_BrB, []>;
13950b57cec5SDimitry Andric   def BDNZLR : XLForm_2_ext<19, 16, 16, 0, 0, (outs), (ins),
13960b57cec5SDimitry Andric                             "bdnzlr", IIC_BrB, []>;
13970b57cec5SDimitry Andric   def BDZLRp : XLForm_2_ext<19, 16, 27, 0, 0, (outs), (ins),
13980b57cec5SDimitry Andric                             "bdzlr+", IIC_BrB, []>;
13990b57cec5SDimitry Andric   def BDNZLRp: XLForm_2_ext<19, 16, 25, 0, 0, (outs), (ins),
14000b57cec5SDimitry Andric                             "bdnzlr+", IIC_BrB, []>;
14010b57cec5SDimitry Andric   def BDZLRm : XLForm_2_ext<19, 16, 26, 0, 0, (outs), (ins),
14020b57cec5SDimitry Andric                             "bdzlr-", IIC_BrB, []>;
14030b57cec5SDimitry Andric   def BDNZLRm: XLForm_2_ext<19, 16, 24, 0, 0, (outs), (ins),
14040b57cec5SDimitry Andric                             "bdnzlr-", IIC_BrB, []>;
14050b57cec5SDimitry Andric  }
14060b57cec5SDimitry Andric
14070b57cec5SDimitry Andric  let Defs = [CTR], Uses = [CTR] in {
140806c3fb27SDimitry Andric    def BDZ  : BForm_1<16, 18, 0, 0, (outs), (ins condbrtarget:$BD),
140906c3fb27SDimitry Andric                       "bdz $BD">;
141006c3fb27SDimitry Andric    def BDNZ : BForm_1<16, 16, 0, 0, (outs), (ins condbrtarget:$BD),
141106c3fb27SDimitry Andric                       "bdnz $BD">;
141206c3fb27SDimitry Andric    def BDZA  : BForm_1<16, 18, 1, 0, (outs), (ins abscondbrtarget:$BD),
141306c3fb27SDimitry Andric                        "bdza $BD">;
141406c3fb27SDimitry Andric    def BDNZA : BForm_1<16, 16, 1, 0, (outs), (ins abscondbrtarget:$BD),
141506c3fb27SDimitry Andric                        "bdnza $BD">;
141606c3fb27SDimitry Andric    def BDZp : BForm_1<16, 27, 0, 0, (outs), (ins condbrtarget:$BD),
141706c3fb27SDimitry Andric                       "bdz+ $BD">;
141806c3fb27SDimitry Andric    def BDNZp: BForm_1<16, 25, 0, 0, (outs), (ins condbrtarget:$BD),
141906c3fb27SDimitry Andric                       "bdnz+ $BD">;
142006c3fb27SDimitry Andric    def BDZAp : BForm_1<16, 27, 1, 0, (outs), (ins abscondbrtarget:$BD),
142106c3fb27SDimitry Andric                        "bdza+ $BD">;
142206c3fb27SDimitry Andric    def BDNZAp: BForm_1<16, 25, 1, 0, (outs), (ins abscondbrtarget:$BD),
142306c3fb27SDimitry Andric                        "bdnza+ $BD">;
142406c3fb27SDimitry Andric    def BDZm : BForm_1<16, 26, 0, 0, (outs), (ins condbrtarget:$BD),
142506c3fb27SDimitry Andric                       "bdz- $BD">;
142606c3fb27SDimitry Andric    def BDNZm: BForm_1<16, 24, 0, 0, (outs), (ins condbrtarget:$BD),
142706c3fb27SDimitry Andric                       "bdnz- $BD">;
142806c3fb27SDimitry Andric    def BDZAm : BForm_1<16, 26, 1, 0, (outs), (ins abscondbrtarget:$BD),
142906c3fb27SDimitry Andric                        "bdza- $BD">;
143006c3fb27SDimitry Andric    def BDNZAm: BForm_1<16, 24, 1, 0, (outs), (ins abscondbrtarget:$BD),
143106c3fb27SDimitry Andric                        "bdnza- $BD">;
14320b57cec5SDimitry Andric  }
14330b57cec5SDimitry Andric}
14340b57cec5SDimitry Andric
14350b57cec5SDimitry Andric// The unconditional BCL used by the SjLj setjmp code.
1436349cc55cSDimitry Andriclet isCall = 1, hasCtrlDep = 1, isCodeGenOnly = 1, PPC970_Unit = 7,
1437349cc55cSDimitry Andric    hasSideEffects = 0 in {
14380b57cec5SDimitry Andric  let Defs = [LR], Uses = [RM] in {
143906c3fb27SDimitry Andric    def BCLalways  : BForm_2<16, 20, 31, 0, 1, (outs), (ins condbrtarget:$BD),
144006c3fb27SDimitry Andric                            "bcl 20, 31, $BD">;
14410b57cec5SDimitry Andric  }
14420b57cec5SDimitry Andric}
14430b57cec5SDimitry Andric
14440b57cec5SDimitry Andriclet isCall = 1, PPC970_Unit = 7, Defs = [LR] in {
14450b57cec5SDimitry Andric  // Convenient aliases for call instructions
14460b57cec5SDimitry Andric  let Uses = [RM] in {
144706c3fb27SDimitry Andric    def BL  : IForm<18, 0, 1, (outs), (ins calltarget:$LI),
144806c3fb27SDimitry Andric                    "bl $LI", IIC_BrB, []>;  // See Pat patterns below.
144906c3fb27SDimitry Andric    def BLA : IForm<18, 1, 1, (outs), (ins abscalltarget:$LI),
145006c3fb27SDimitry Andric                    "bla $LI", IIC_BrB, [(PPCcall (i32 imm:$LI))]>;
14510b57cec5SDimitry Andric
14520b57cec5SDimitry Andric    let isCodeGenOnly = 1 in {
145306c3fb27SDimitry Andric      def BL_TLS  : IForm<18, 0, 1, (outs), (ins tlscall32:$LI),
145406c3fb27SDimitry Andric                          "bl $LI", IIC_BrB, []>;
145506c3fb27SDimitry Andric      def BCCL : BForm<16, 0, 1, (outs), (ins (pred $BIBO, $CR):$cond, condbrtarget:$BD),
145606c3fb27SDimitry Andric                       "b${cond:cc}l${cond:pm} ${cond:reg}, $BD">;
145706c3fb27SDimitry Andric      def BCCLA : BForm<16, 1, 1, (outs), (ins (pred $BIBO, $CR):$cond, abscondbrtarget:$BD),
145806c3fb27SDimitry Andric                        "b${cond:cc}la${cond:pm} ${cond:reg}, $BD">;
14590b57cec5SDimitry Andric
14600b57cec5SDimitry Andric      def BCL  : BForm_4<16, 12, 0, 1, (outs),
146106c3fb27SDimitry Andric                         (ins crbitrc:$BI, condbrtarget:$BD),
146206c3fb27SDimitry Andric                         "bcl 12, $BI, $BD">;
14630b57cec5SDimitry Andric      def BCLn : BForm_4<16, 4, 0, 1, (outs),
146406c3fb27SDimitry Andric                         (ins crbitrc:$BI, condbrtarget:$BD),
146506c3fb27SDimitry Andric                         "bcl 4, $BI, $BD">;
14660b57cec5SDimitry Andric      def BL_NOP  : IForm_and_DForm_4_zero<18, 0, 1, 24,
146706c3fb27SDimitry Andric                                           (outs), (ins calltarget:$LI),
146806c3fb27SDimitry Andric                                           "bl $LI\n\tnop", IIC_BrB, []>;
14690b57cec5SDimitry Andric    }
14700b57cec5SDimitry Andric  }
14710b57cec5SDimitry Andric  let Uses = [CTR, RM] in {
1472480093f4SDimitry Andric    let isPredicable = 1 in
14730b57cec5SDimitry Andric      def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
14740b57cec5SDimitry Andric                              "bctrl", IIC_BrB, [(PPCbctrl)]>,
14750b57cec5SDimitry Andric                  Requires<[In32BitMode]>;
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andric    let isCodeGenOnly = 1 in {
147806c3fb27SDimitry Andric      def BCCCTRL : XLForm_2_br<19, 528, 1, (outs), (ins (pred $BIBO, $CR):$cond),
14790b57cec5SDimitry Andric                                "b${cond:cc}ctrl${cond:pm} ${cond:reg}", IIC_BrB,
14800b57cec5SDimitry Andric                                []>;
14810b57cec5SDimitry Andric
148206c3fb27SDimitry Andric      def BCCTRL  : XLForm_2_br2<19, 528, 12, 1, (outs), (ins crbitrc:$BI),
148306c3fb27SDimitry Andric                                 "bcctrl 12, $BI, 0", IIC_BrB, []>;
148406c3fb27SDimitry Andric      def BCCTRLn : XLForm_2_br2<19, 528, 4, 1, (outs), (ins crbitrc:$BI),
148506c3fb27SDimitry Andric                                 "bcctrl 4, $BI, 0", IIC_BrB, []>;
14860b57cec5SDimitry Andric    }
14870b57cec5SDimitry Andric  }
14880b57cec5SDimitry Andric  let Uses = [LR, RM] in {
14890b57cec5SDimitry Andric    def BLRL : XLForm_2_ext<19, 16, 20, 0, 1, (outs), (ins),
14900b57cec5SDimitry Andric                            "blrl", IIC_BrB, []>;
14910b57cec5SDimitry Andric
14920b57cec5SDimitry Andric    let isCodeGenOnly = 1 in {
149306c3fb27SDimitry Andric      def BCCLRL : XLForm_2_br<19, 16, 1, (outs), (ins (pred $BIBO, $CR):$cond),
14940b57cec5SDimitry Andric                              "b${cond:cc}lrl${cond:pm} ${cond:reg}", IIC_BrB,
14950b57cec5SDimitry Andric                              []>;
14960b57cec5SDimitry Andric
149706c3fb27SDimitry Andric      def BCLRL  : XLForm_2_br2<19, 16, 12, 1, (outs), (ins crbitrc:$BI),
149806c3fb27SDimitry Andric                                "bclrl 12, $BI, 0", IIC_BrB, []>;
149906c3fb27SDimitry Andric      def BCLRLn : XLForm_2_br2<19, 16, 4, 1, (outs), (ins crbitrc:$BI),
150006c3fb27SDimitry Andric                                "bclrl 4, $BI, 0", IIC_BrB, []>;
15010b57cec5SDimitry Andric    }
15020b57cec5SDimitry Andric  }
15030b57cec5SDimitry Andric  let Defs = [CTR], Uses = [CTR, RM] in {
150406c3fb27SDimitry Andric    def BDZL  : BForm_1<16, 18, 0, 1, (outs), (ins condbrtarget:$BD),
150506c3fb27SDimitry Andric                        "bdzl $BD">;
150606c3fb27SDimitry Andric    def BDNZL : BForm_1<16, 16, 0, 1, (outs), (ins condbrtarget:$BD),
150706c3fb27SDimitry Andric                        "bdnzl $BD">;
150806c3fb27SDimitry Andric    def BDZLA  : BForm_1<16, 18, 1, 1, (outs), (ins abscondbrtarget:$BD),
150906c3fb27SDimitry Andric                         "bdzla $BD">;
151006c3fb27SDimitry Andric    def BDNZLA : BForm_1<16, 16, 1, 1, (outs), (ins abscondbrtarget:$BD),
151106c3fb27SDimitry Andric                         "bdnzla $BD">;
151206c3fb27SDimitry Andric    def BDZLp : BForm_1<16, 27, 0, 1, (outs), (ins condbrtarget:$BD),
151306c3fb27SDimitry Andric                        "bdzl+ $BD">;
151406c3fb27SDimitry Andric    def BDNZLp: BForm_1<16, 25, 0, 1, (outs), (ins condbrtarget:$BD),
151506c3fb27SDimitry Andric                        "bdnzl+ $BD">;
151606c3fb27SDimitry Andric    def BDZLAp : BForm_1<16, 27, 1, 1, (outs), (ins abscondbrtarget:$BD),
151706c3fb27SDimitry Andric                         "bdzla+ $BD">;
151806c3fb27SDimitry Andric    def BDNZLAp: BForm_1<16, 25, 1, 1, (outs), (ins abscondbrtarget:$BD),
151906c3fb27SDimitry Andric                         "bdnzla+ $BD">;
152006c3fb27SDimitry Andric    def BDZLm : BForm_1<16, 26, 0, 1, (outs), (ins condbrtarget:$BD),
152106c3fb27SDimitry Andric                        "bdzl- $BD">;
152206c3fb27SDimitry Andric    def BDNZLm: BForm_1<16, 24, 0, 1, (outs), (ins condbrtarget:$BD),
152306c3fb27SDimitry Andric                        "bdnzl- $BD">;
152406c3fb27SDimitry Andric    def BDZLAm : BForm_1<16, 26, 1, 1, (outs), (ins abscondbrtarget:$BD),
152506c3fb27SDimitry Andric                         "bdzla- $BD">;
152606c3fb27SDimitry Andric    def BDNZLAm: BForm_1<16, 24, 1, 1, (outs), (ins abscondbrtarget:$BD),
152706c3fb27SDimitry Andric                         "bdnzla- $BD">;
15280b57cec5SDimitry Andric  }
15290b57cec5SDimitry Andric  let Defs = [CTR], Uses = [CTR, LR, RM] in {
15300b57cec5SDimitry Andric    def BDZLRL  : XLForm_2_ext<19, 16, 18, 0, 1, (outs), (ins),
15310b57cec5SDimitry Andric                               "bdzlrl", IIC_BrB, []>;
15320b57cec5SDimitry Andric    def BDNZLRL : XLForm_2_ext<19, 16, 16, 0, 1, (outs), (ins),
15330b57cec5SDimitry Andric                               "bdnzlrl", IIC_BrB, []>;
15340b57cec5SDimitry Andric    def BDZLRLp : XLForm_2_ext<19, 16, 27, 0, 1, (outs), (ins),
15350b57cec5SDimitry Andric                               "bdzlrl+", IIC_BrB, []>;
15360b57cec5SDimitry Andric    def BDNZLRLp: XLForm_2_ext<19, 16, 25, 0, 1, (outs), (ins),
15370b57cec5SDimitry Andric                               "bdnzlrl+", IIC_BrB, []>;
15380b57cec5SDimitry Andric    def BDZLRLm : XLForm_2_ext<19, 16, 26, 0, 1, (outs), (ins),
15390b57cec5SDimitry Andric                               "bdzlrl-", IIC_BrB, []>;
15400b57cec5SDimitry Andric    def BDNZLRLm: XLForm_2_ext<19, 16, 24, 0, 1, (outs), (ins),
15410b57cec5SDimitry Andric                               "bdnzlrl-", IIC_BrB, []>;
15420b57cec5SDimitry Andric  }
15430b57cec5SDimitry Andric}
15440b57cec5SDimitry Andric
1545349cc55cSDimitry Andriclet isCall = 1, PPC970_Unit = 7, Defs = [LR, RM], isCodeGenOnly = 1 in {
1546349cc55cSDimitry Andric  // Convenient aliases for call instructions
1547349cc55cSDimitry Andric  let Uses = [RM] in {
154806c3fb27SDimitry Andric    def BL_RM  : IForm<18, 0, 1, (outs), (ins calltarget:$LI),
154906c3fb27SDimitry Andric                       "bl $LI", IIC_BrB, []>;  // See Pat patterns below.
155006c3fb27SDimitry Andric    def BLA_RM : IForm<18, 1, 1, (outs), (ins abscalltarget:$LI),
155106c3fb27SDimitry Andric                       "bla $LI", IIC_BrB, [(PPCcall_rm (i32 imm:$LI))]>;
1552349cc55cSDimitry Andric
1553349cc55cSDimitry Andric    def BL_NOP_RM  : IForm_and_DForm_4_zero<18, 0, 1, 24,
155406c3fb27SDimitry Andric                                            (outs), (ins calltarget:$LI),
155506c3fb27SDimitry Andric                                            "bl $LI\n\tnop", IIC_BrB, []>;
1556349cc55cSDimitry Andric  }
1557349cc55cSDimitry Andric  let Uses = [CTR, RM] in {
1558349cc55cSDimitry Andric    let isPredicable = 1 in
1559349cc55cSDimitry Andric      def BCTRL_RM : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins),
1560349cc55cSDimitry Andric                                  "bctrl", IIC_BrB, [(PPCbctrl_rm)]>,
1561349cc55cSDimitry Andric                  Requires<[In32BitMode]>;
1562349cc55cSDimitry Andric  }
1563349cc55cSDimitry Andric}
1564349cc55cSDimitry Andric
15650b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
15660b57cec5SDimitry Andricdef TCRETURNdi :PPCEmitTimePseudo< (outs),
15670b57cec5SDimitry Andric                        (ins calltarget:$dst, i32imm:$offset),
15680b57cec5SDimitry Andric                 "#TC_RETURNd $dst $offset",
15690b57cec5SDimitry Andric                 []>;
15700b57cec5SDimitry Andric
15710b57cec5SDimitry Andric
15720b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
15730b57cec5SDimitry Andricdef TCRETURNai :PPCEmitTimePseudo<(outs), (ins abscalltarget:$func, i32imm:$offset),
15740b57cec5SDimitry Andric                 "#TC_RETURNa $func $offset",
15750b57cec5SDimitry Andric                 [(PPCtc_return (i32 imm:$func), imm:$offset)]>;
15760b57cec5SDimitry Andric
15770b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [RM] in
15780b57cec5SDimitry Andricdef TCRETURNri : PPCEmitTimePseudo<(outs), (ins CTRRC:$dst, i32imm:$offset),
15790b57cec5SDimitry Andric                 "#TC_RETURNr $dst $offset",
15800b57cec5SDimitry Andric                 []>;
15810b57cec5SDimitry Andric
1582480093f4SDimitry Andriclet isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
1583480093f4SDimitry Andric    Defs = [LR, R2], Uses = [CTR, RM], RST = 2 in {
1584480093f4SDimitry Andric  def BCTRL_LWZinto_toc:
1585480093f4SDimitry Andric    XLForm_2_ext_and_DForm_1<19, 528, 20, 0, 1, 32, (outs),
158606c3fb27SDimitry Andric     (ins (memri $D, $RA):$addr), "bctrl\n\tlwz 2, $addr", IIC_BrB,
158706c3fb27SDimitry Andric     [(PPCbctrl_load_toc iaddr:$addr)]>, Requires<[In32BitMode]>;
1588480093f4SDimitry Andric
1589480093f4SDimitry Andric}
1590480093f4SDimitry Andric
1591349cc55cSDimitry Andriclet isCall = 1, PPC970_Unit = 7, isCodeGenOnly = 1,
1592349cc55cSDimitry Andric    Defs = [LR, R2, RM], Uses = [CTR, RM], RST = 2 in {
1593349cc55cSDimitry Andric  def BCTRL_LWZinto_toc_RM:
1594349cc55cSDimitry Andric    XLForm_2_ext_and_DForm_1<19, 528, 20, 0, 1, 32, (outs),
159506c3fb27SDimitry Andric     (ins (memri $D, $RA):$addr), "bctrl\n\tlwz 2, $addr", IIC_BrB,
159606c3fb27SDimitry Andric     [(PPCbctrl_load_toc_rm iaddr:$addr)]>, Requires<[In32BitMode]>;
15970b57cec5SDimitry Andric
1598349cc55cSDimitry Andric}
1599349cc55cSDimitry Andric
1600349cc55cSDimitry Andriclet isCodeGenOnly = 1, hasSideEffects = 0 in {
16010b57cec5SDimitry Andric
16020b57cec5SDimitry Andriclet isTerminator = 1, isBarrier = 1, PPC970_Unit = 7, isBranch = 1,
16030b57cec5SDimitry Andric    isIndirectBranch = 1, isCall = 1, isReturn = 1, Uses = [CTR, RM]  in
16040b57cec5SDimitry Andricdef TAILBCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", IIC_BrB,
16050b57cec5SDimitry Andric                            []>, Requires<[In32BitMode]>;
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
16080b57cec5SDimitry Andric    isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
160906c3fb27SDimitry Andricdef TAILB   : IForm<18, 0, 0, (outs), (ins calltarget:$LI),
161006c3fb27SDimitry Andric                  "b $LI", IIC_BrB,
16110b57cec5SDimitry Andric                  []>;
16120b57cec5SDimitry Andric
16130b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, hasCtrlDep = 1, PPC970_Unit = 7,
16140b57cec5SDimitry Andric    isBarrier = 1, isCall = 1, isReturn = 1, Uses = [RM] in
161506c3fb27SDimitry Andricdef TAILBA   : IForm<18, 0, 0, (outs), (ins abscalltarget:$LI),
161606c3fb27SDimitry Andric                  "ba $LI", IIC_BrB,
16170b57cec5SDimitry Andric                  []>;
16180b57cec5SDimitry Andric
16190b57cec5SDimitry Andric}
16200b57cec5SDimitry Andric
16210b57cec5SDimitry Andric// While longjmp is a control-flow barrier (fallthrough isn't allowed), setjmp
16220b57cec5SDimitry Andric// is not.
16230b57cec5SDimitry Andriclet hasSideEffects = 1 in {
16240b57cec5SDimitry Andric  let Defs = [CTR] in
16250b57cec5SDimitry Andric  def EH_SjLj_SetJmp32  : PPCCustomInserterPseudo<(outs gprc:$dst), (ins memr:$buf),
16260b57cec5SDimitry Andric                            "#EH_SJLJ_SETJMP32",
16270b57cec5SDimitry Andric                            [(set i32:$dst, (PPCeh_sjlj_setjmp addr:$buf))]>,
16280b57cec5SDimitry Andric                          Requires<[In32BitMode]>;
16290b57cec5SDimitry Andric}
16300b57cec5SDimitry Andric
16310b57cec5SDimitry Andriclet hasSideEffects = 1, isBarrier = 1 in {
16320b57cec5SDimitry Andric  let isTerminator = 1 in
16330b57cec5SDimitry Andric  def EH_SjLj_LongJmp32 : PPCCustomInserterPseudo<(outs), (ins memr:$buf),
16340b57cec5SDimitry Andric                            "#EH_SJLJ_LONGJMP32",
16350b57cec5SDimitry Andric                            [(PPCeh_sjlj_longjmp addr:$buf)]>,
16360b57cec5SDimitry Andric                          Requires<[In32BitMode]>;
16370b57cec5SDimitry Andric}
16380b57cec5SDimitry Andric
16390b57cec5SDimitry Andric// This pseudo is never removed from the function, as it serves as
16400b57cec5SDimitry Andric// a terminator.  Size is set to 0 to prevent the builtin assembler
16410b57cec5SDimitry Andric// from emitting it.
16420b57cec5SDimitry Andriclet isBranch = 1, isTerminator = 1, Size = 0 in {
16430b57cec5SDimitry Andric  def EH_SjLj_Setup : PPCEmitTimePseudo<(outs), (ins directbrtarget:$dst),
16440b57cec5SDimitry Andric                        "#EH_SjLj_Setup\t$dst", []>;
16450b57cec5SDimitry Andric}
16460b57cec5SDimitry Andric
16470b57cec5SDimitry Andric// System call.
16480b57cec5SDimitry Andriclet PPC970_Unit = 7 in {
16495f757f3fSDimitry Andric  def SC     : SCForm<17, 1, 0, (outs), (ins i32imm:$LEV),
165006c3fb27SDimitry Andric                      "sc $LEV", IIC_BrB, [(PPCsc (i32 imm:$LEV))]>;
16510b57cec5SDimitry Andric}
16520b57cec5SDimitry Andric
16535f757f3fSDimitry Andric// We mark SCV as having no scheduling model since it is only meant to be used
16545f757f3fSDimitry Andric// as inline assembly. If we implement a builtin pattern for it we will need to
16555f757f3fSDimitry Andric// add it to the P9 and P10 scheduling models.
16565f757f3fSDimitry Andriclet Predicates = [IsISA3_0], hasNoSchedulingInfo = 1 in {
16575f757f3fSDimitry Andric  def SCV : SCForm<17, 0, 1, (outs), (ins i32imm:$LEV),
16585f757f3fSDimitry Andric                   "scv $LEV", IIC_BrB, []>;
16595f757f3fSDimitry Andric}
16605f757f3fSDimitry Andric
16610b57cec5SDimitry Andric// Branch history rolling buffer.
16620b57cec5SDimitry Andricdef CLRBHRB : XForm_0<31, 430, (outs), (ins), "clrbhrb", IIC_BrB,
16630b57cec5SDimitry Andric                      [(PPCclrbhrb)]>,
16640b57cec5SDimitry Andric                      PPC970_DGroup_Single;
16650b57cec5SDimitry Andric// The $dmy argument used for MFBHRBE is not needed; however, including
16660b57cec5SDimitry Andric// it avoids automatic generation of PPCFastISel::fastEmit_i(), which
16670b57cec5SDimitry Andric// interferes with necessary special handling (see PPCFastISel.cpp).
166806c3fb27SDimitry Andricdef MFBHRBE : XFXForm_3p<31, 302, (outs gprc:$RT),
16690b57cec5SDimitry Andric                         (ins u10imm:$imm, u10imm:$dmy),
167006c3fb27SDimitry Andric                         "mfbhrbe $RT, $imm", IIC_BrB,
167106c3fb27SDimitry Andric                         [(set i32:$RT,
16720b57cec5SDimitry Andric                               (PPCmfbhrbe imm:$imm, imm:$dmy))]>,
16730b57cec5SDimitry Andric                         PPC970_DGroup_First;
16740b57cec5SDimitry Andric
167506c3fb27SDimitry Andricdef RFEBB : XLForm_S<19, 146, (outs), (ins u1imm:$S), "rfebb $S",
167606c3fb27SDimitry Andric                     IIC_BrB, [(PPCrfebb (i32 imm:$S))]>,
16770b57cec5SDimitry Andric                     PPC970_DGroup_Single;
16780b57cec5SDimitry Andric
16795ffd83dbSDimitry Andricdef : InstAlias<"rfebb", (RFEBB 1)>;
16805ffd83dbSDimitry Andric
16810b57cec5SDimitry Andric// DCB* instructions.
168206c3fb27SDimitry Andricdef DCBA   : DCB_Form<758, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcba $addr",
168306c3fb27SDimitry Andric                      IIC_LdStDCBF, [(int_ppc_dcba xoaddr:$addr)]>,
16840b57cec5SDimitry Andric                      PPC970_DGroup_Single;
168506c3fb27SDimitry Andricdef DCBI   : DCB_Form<470, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcbi $addr",
168606c3fb27SDimitry Andric                      IIC_LdStDCBF, [(int_ppc_dcbi xoaddr:$addr)]>,
16870b57cec5SDimitry Andric                      PPC970_DGroup_Single;
168806c3fb27SDimitry Andricdef DCBST  : DCB_Form<54, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcbst $addr",
168906c3fb27SDimitry Andric                      IIC_LdStDCBF, [(int_ppc_dcbst xoaddr:$addr)]>,
16900b57cec5SDimitry Andric                      PPC970_DGroup_Single;
169106c3fb27SDimitry Andricdef DCBZ   : DCB_Form<1014, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcbz $addr",
169206c3fb27SDimitry Andric                      IIC_LdStDCBF, [(int_ppc_dcbz xoaddr:$addr)]>,
16930b57cec5SDimitry Andric                      PPC970_DGroup_Single;
169406c3fb27SDimitry Andricdef DCBZL  : DCB_Form<1014, 1, (outs), (ins (memrr $RA, $RB):$addr), "dcbzl $addr",
169506c3fb27SDimitry Andric                      IIC_LdStDCBF, [(int_ppc_dcbzl xoaddr:$addr)]>,
16960b57cec5SDimitry Andric                      PPC970_DGroup_Single;
16970b57cec5SDimitry Andric
169806c3fb27SDimitry Andricdef DCBF   : DCB_Form_hint<86, (outs), (ins u3imm:$TH, (memrr $RA, $RB):$addr),
169906c3fb27SDimitry Andric                      "dcbf $addr, $TH", IIC_LdStDCBF, []>,
17000b57cec5SDimitry Andric                      PPC970_DGroup_Single;
17010b57cec5SDimitry Andric
17020b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1 in {
170306c3fb27SDimitry Andricdef DCBT   : DCB_Form_hint<278, (outs), (ins u5imm:$TH, (memrr $RA, $RB):$addr),
170406c3fb27SDimitry Andric                      "dcbt $addr, $TH", IIC_LdStDCBF, []>,
17050b57cec5SDimitry Andric                      PPC970_DGroup_Single;
170606c3fb27SDimitry Andricdef DCBTST : DCB_Form_hint<246, (outs), (ins u5imm:$TH, (memrr $RA, $RB):$addr),
170706c3fb27SDimitry Andric                      "dcbtst $addr, $TH", IIC_LdStDCBF, []>,
17080b57cec5SDimitry Andric                      PPC970_DGroup_Single;
17090b57cec5SDimitry Andric} // hasSideEffects = 0
17100b57cec5SDimitry Andric
171106c3fb27SDimitry Andricdef ICBLC  : XForm_icbt<31, 230, (outs), (ins u4imm:$CT, (memrr $RA, $RB):$addr),
171206c3fb27SDimitry Andric                       "icblc $CT, $addr", IIC_LdStStore>, Requires<[HasICBT]>;
171306c3fb27SDimitry Andricdef ICBLQ  : XForm_icbt<31, 198, (outs), (ins u4imm:$CT, (memrr $RA, $RB):$addr),
171406c3fb27SDimitry Andric                       "icblq. $CT, $addr", IIC_LdStLoad>, Requires<[HasICBT]>;
171506c3fb27SDimitry Andricdef ICBT  : XForm_icbt<31, 22, (outs), (ins u4imm:$CT, (memrr $RA, $RB):$addr),
171606c3fb27SDimitry Andric                       "icbt $CT, $addr", IIC_LdStLoad>, Requires<[HasICBT]>;
171706c3fb27SDimitry Andricdef ICBTLS : XForm_icbt<31, 486, (outs), (ins u4imm:$CT, (memrr $RA, $RB):$addr),
171806c3fb27SDimitry Andric                       "icbtls $CT, $addr", IIC_LdStLoad>, Requires<[HasICBT]>;
17190b57cec5SDimitry Andric
17200b57cec5SDimitry Andricdef : Pat<(int_ppc_dcbt xoaddr:$dst),
17210b57cec5SDimitry Andric          (DCBT 0, xoaddr:$dst)>;
17220b57cec5SDimitry Andricdef : Pat<(int_ppc_dcbtst xoaddr:$dst),
17230b57cec5SDimitry Andric          (DCBTST 0, xoaddr:$dst)>;
17240b57cec5SDimitry Andricdef : Pat<(int_ppc_dcbf xoaddr:$dst),
17250b57cec5SDimitry Andric          (DCBF 0, xoaddr:$dst)>;
1726fe6060f1SDimitry Andricdef : Pat<(int_ppc_icbt xoaddr:$dst),
1727fe6060f1SDimitry Andric          (ICBT 0, xoaddr:$dst)>;
17280b57cec5SDimitry Andric
17295f757f3fSDimitry Andricdef : Pat<(prefetch xoaddr:$dst, (i32 0), timm, (i32 1)),
17300b57cec5SDimitry Andric          (DCBT 0, xoaddr:$dst)>;   // data prefetch for loads
17315f757f3fSDimitry Andricdef : Pat<(prefetch xoaddr:$dst, (i32 1), timm, (i32 1)),
17320b57cec5SDimitry Andric          (DCBTST 0, xoaddr:$dst)>; // data prefetch for stores
17335f757f3fSDimitry Andricdef : Pat<(prefetch xoaddr:$dst, (i32 0), timm, (i32 0)),
17340b57cec5SDimitry Andric          (ICBT 0, xoaddr:$dst)>, Requires<[HasICBT]>; // inst prefetch (for read)
17350b57cec5SDimitry Andric
17365ffd83dbSDimitry Andricdef : Pat<(int_ppc_dcbt_with_hint xoaddr:$dst, i32:$TH),
17375ffd83dbSDimitry Andric          (DCBT i32:$TH, xoaddr:$dst)>;
17385ffd83dbSDimitry Andricdef : Pat<(int_ppc_dcbtst_with_hint xoaddr:$dst, i32:$TH),
17395ffd83dbSDimitry Andric          (DCBTST i32:$TH, xoaddr:$dst)>;
17405ffd83dbSDimitry Andric
17410b57cec5SDimitry Andric// Atomic operations
17420b57cec5SDimitry Andric// FIXME: some of these might be used with constant operands. This will result
17430b57cec5SDimitry Andric// in constant materialization instructions that may be redundant. We currently
17440b57cec5SDimitry Andric// clean this up in PPCMIPeephole with calls to
17450b57cec5SDimitry Andric// PPCInstrInfo::convertToImmediateForm() but we should probably not emit them
17460b57cec5SDimitry Andric// in the first place.
17470b57cec5SDimitry Andriclet Defs = [CR0] in {
17480b57cec5SDimitry Andric  def ATOMIC_LOAD_ADD_I8 : PPCCustomInserterPseudo<
17490b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I8",
17500fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_add_i8 ForceXForm:$ptr, i32:$incr))]>;
17510b57cec5SDimitry Andric  def ATOMIC_LOAD_SUB_I8 : PPCCustomInserterPseudo<
17520b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_SUB_I8",
17530fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_sub_i8 ForceXForm:$ptr, i32:$incr))]>;
17540b57cec5SDimitry Andric  def ATOMIC_LOAD_AND_I8 : PPCCustomInserterPseudo<
17550b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_AND_I8",
17560fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_and_i8 ForceXForm:$ptr, i32:$incr))]>;
17570b57cec5SDimitry Andric  def ATOMIC_LOAD_OR_I8 : PPCCustomInserterPseudo<
17580b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_OR_I8",
17590fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_or_i8 ForceXForm:$ptr, i32:$incr))]>;
17600b57cec5SDimitry Andric  def ATOMIC_LOAD_XOR_I8 : PPCCustomInserterPseudo<
17610b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "ATOMIC_LOAD_XOR_I8",
17620fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_xor_i8 ForceXForm:$ptr, i32:$incr))]>;
17630b57cec5SDimitry Andric  def ATOMIC_LOAD_NAND_I8 : PPCCustomInserterPseudo<
17640b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I8",
17650fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_nand_i8 ForceXForm:$ptr, i32:$incr))]>;
17660b57cec5SDimitry Andric  def ATOMIC_LOAD_MIN_I8 : PPCCustomInserterPseudo<
17670b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MIN_I8",
17680fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_min_i8 ForceXForm:$ptr, i32:$incr))]>;
17690b57cec5SDimitry Andric  def ATOMIC_LOAD_MAX_I8 : PPCCustomInserterPseudo<
17700b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MAX_I8",
17710fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_max_i8 ForceXForm:$ptr, i32:$incr))]>;
17720b57cec5SDimitry Andric  def ATOMIC_LOAD_UMIN_I8 : PPCCustomInserterPseudo<
17730b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMIN_I8",
17740fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_umin_i8 ForceXForm:$ptr, i32:$incr))]>;
17750b57cec5SDimitry Andric  def ATOMIC_LOAD_UMAX_I8 : PPCCustomInserterPseudo<
17760b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMAX_I8",
17770fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_umax_i8 ForceXForm:$ptr, i32:$incr))]>;
17780b57cec5SDimitry Andric  def ATOMIC_LOAD_ADD_I16 : PPCCustomInserterPseudo<
17790b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I16",
17800fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_add_i16 ForceXForm:$ptr, i32:$incr))]>;
17810b57cec5SDimitry Andric  def ATOMIC_LOAD_SUB_I16 : PPCCustomInserterPseudo<
17820b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_SUB_I16",
17830fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_sub_i16 ForceXForm:$ptr, i32:$incr))]>;
17840b57cec5SDimitry Andric  def ATOMIC_LOAD_AND_I16 : PPCCustomInserterPseudo<
17850b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_AND_I16",
17860fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_and_i16 ForceXForm:$ptr, i32:$incr))]>;
17870b57cec5SDimitry Andric  def ATOMIC_LOAD_OR_I16 : PPCCustomInserterPseudo<
17880b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_OR_I16",
17890fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_or_i16 ForceXForm:$ptr, i32:$incr))]>;
17900b57cec5SDimitry Andric  def ATOMIC_LOAD_XOR_I16 : PPCCustomInserterPseudo<
17910b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_XOR_I16",
17920fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_xor_i16 ForceXForm:$ptr, i32:$incr))]>;
17930b57cec5SDimitry Andric  def ATOMIC_LOAD_NAND_I16 : PPCCustomInserterPseudo<
17940b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I16",
17950fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_nand_i16 ForceXForm:$ptr, i32:$incr))]>;
17960b57cec5SDimitry Andric  def ATOMIC_LOAD_MIN_I16 : PPCCustomInserterPseudo<
17970b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MIN_I16",
17980fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_min_i16 ForceXForm:$ptr, i32:$incr))]>;
17990b57cec5SDimitry Andric  def ATOMIC_LOAD_MAX_I16 : PPCCustomInserterPseudo<
18000b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MAX_I16",
18010fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_max_i16 ForceXForm:$ptr, i32:$incr))]>;
18020b57cec5SDimitry Andric  def ATOMIC_LOAD_UMIN_I16 : PPCCustomInserterPseudo<
18030b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMIN_I16",
18040fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_umin_i16 ForceXForm:$ptr, i32:$incr))]>;
18050b57cec5SDimitry Andric  def ATOMIC_LOAD_UMAX_I16 : PPCCustomInserterPseudo<
18060b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMAX_I16",
18070fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_umax_i16 ForceXForm:$ptr, i32:$incr))]>;
18080b57cec5SDimitry Andric  def ATOMIC_LOAD_ADD_I32 : PPCCustomInserterPseudo<
18090b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_ADD_I32",
18100fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_add_i32 ForceXForm:$ptr, i32:$incr))]>;
18110b57cec5SDimitry Andric  def ATOMIC_LOAD_SUB_I32 : PPCCustomInserterPseudo<
18120b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_SUB_I32",
18130fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_sub_i32 ForceXForm:$ptr, i32:$incr))]>;
18140b57cec5SDimitry Andric  def ATOMIC_LOAD_AND_I32 : PPCCustomInserterPseudo<
18150b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_AND_I32",
18160fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_and_i32 ForceXForm:$ptr, i32:$incr))]>;
18170b57cec5SDimitry Andric  def ATOMIC_LOAD_OR_I32 : PPCCustomInserterPseudo<
18180b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_OR_I32",
18190fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_or_i32 ForceXForm:$ptr, i32:$incr))]>;
18200b57cec5SDimitry Andric  def ATOMIC_LOAD_XOR_I32 : PPCCustomInserterPseudo<
18210b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_XOR_I32",
18220fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_xor_i32 ForceXForm:$ptr, i32:$incr))]>;
18230b57cec5SDimitry Andric  def ATOMIC_LOAD_NAND_I32 : PPCCustomInserterPseudo<
18240b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_NAND_I32",
18250fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_nand_i32 ForceXForm:$ptr, i32:$incr))]>;
18260b57cec5SDimitry Andric  def ATOMIC_LOAD_MIN_I32 : PPCCustomInserterPseudo<
18270b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MIN_I32",
18280fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_min_i32 ForceXForm:$ptr, i32:$incr))]>;
18290b57cec5SDimitry Andric  def ATOMIC_LOAD_MAX_I32 : PPCCustomInserterPseudo<
18300b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_MAX_I32",
18310fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_max_i32 ForceXForm:$ptr, i32:$incr))]>;
18320b57cec5SDimitry Andric  def ATOMIC_LOAD_UMIN_I32 : PPCCustomInserterPseudo<
18330b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMIN_I32",
18340fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_umin_i32 ForceXForm:$ptr, i32:$incr))]>;
18350b57cec5SDimitry Andric  def ATOMIC_LOAD_UMAX_I32 : PPCCustomInserterPseudo<
18360b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$incr), "#ATOMIC_LOAD_UMAX_I32",
18370fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_load_umax_i32 ForceXForm:$ptr, i32:$incr))]>;
18380b57cec5SDimitry Andric
18390b57cec5SDimitry Andric  def ATOMIC_CMP_SWAP_I8 : PPCCustomInserterPseudo<
18400b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I8",
18410fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_cmp_swap_i8 ForceXForm:$ptr, i32:$old, i32:$new))]>;
18420b57cec5SDimitry Andric  def ATOMIC_CMP_SWAP_I16 : PPCCustomInserterPseudo<
18430b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I16 $dst $ptr $old $new",
18440fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_cmp_swap_i16 ForceXForm:$ptr, i32:$old, i32:$new))]>;
18450b57cec5SDimitry Andric  def ATOMIC_CMP_SWAP_I32 : PPCCustomInserterPseudo<
18460b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$old, gprc:$new), "#ATOMIC_CMP_SWAP_I32 $dst $ptr $old $new",
18470fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_cmp_swap_i32 ForceXForm:$ptr, i32:$old, i32:$new))]>;
18480b57cec5SDimitry Andric
18490b57cec5SDimitry Andric  def ATOMIC_SWAP_I8 : PPCCustomInserterPseudo<
18500b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$new), "#ATOMIC_SWAP_i8",
18510fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_swap_i8 ForceXForm:$ptr, i32:$new))]>;
18520b57cec5SDimitry Andric  def ATOMIC_SWAP_I16 : PPCCustomInserterPseudo<
18530b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$new), "#ATOMIC_SWAP_I16",
18540fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_swap_i16 ForceXForm:$ptr, i32:$new))]>;
18550b57cec5SDimitry Andric  def ATOMIC_SWAP_I32 : PPCCustomInserterPseudo<
18560b57cec5SDimitry Andric    (outs gprc:$dst), (ins memrr:$ptr, gprc:$new), "#ATOMIC_SWAP_I32",
18570fca6ea1SDimitry Andric    [(set i32:$dst, (atomic_swap_i32 ForceXForm:$ptr, i32:$new))]>;
18580b57cec5SDimitry Andric}
18590b57cec5SDimitry Andric
1860fe6060f1SDimitry Andricdef : Pat<(PPCatomicCmpSwap_8 ForceXForm:$ptr, i32:$old, i32:$new),
1861fe6060f1SDimitry Andric        (ATOMIC_CMP_SWAP_I8 ForceXForm:$ptr, i32:$old, i32:$new)>;
1862fe6060f1SDimitry Andricdef : Pat<(PPCatomicCmpSwap_16 ForceXForm:$ptr, i32:$old, i32:$new),
1863fe6060f1SDimitry Andric        (ATOMIC_CMP_SWAP_I16 ForceXForm:$ptr, i32:$old, i32:$new)>;
18640b57cec5SDimitry Andric
18650b57cec5SDimitry Andric// Instructions to support atomic operations
18660b57cec5SDimitry Andriclet mayLoad = 1, mayStore = 0, hasSideEffects = 0 in {
186706c3fb27SDimitry Andricdef LBARX : XForm_1_memOp<31,  52, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
186806c3fb27SDimitry Andric                    "lbarx $RST, $addr", IIC_LdStLWARX, []>,
18690b57cec5SDimitry Andric                    Requires<[HasPartwordAtomics]>;
18700b57cec5SDimitry Andric
187106c3fb27SDimitry Andricdef LHARX : XForm_1_memOp<31,  116, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
187206c3fb27SDimitry Andric                    "lharx $RST, $addr", IIC_LdStLWARX, []>,
18730b57cec5SDimitry Andric                    Requires<[HasPartwordAtomics]>;
18740b57cec5SDimitry Andric
187506c3fb27SDimitry Andricdef LWARX : XForm_1_memOp<31,  20, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
187606c3fb27SDimitry Andric                    "lwarx $RST, $addr", IIC_LdStLWARX, []>;
18770b57cec5SDimitry Andric
18780b57cec5SDimitry Andric// Instructions to support lock versions of atomics
18790b57cec5SDimitry Andric// (EH=1 - see Power ISA 2.07 Book II 4.4.2)
188006c3fb27SDimitry Andricdef LBARXL : XForm_1_memOp<31,  52, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
188106c3fb27SDimitry Andric                     "lbarx $RST, $addr, 1", IIC_LdStLWARX, []>, isRecordForm,
18820b57cec5SDimitry Andric                     Requires<[HasPartwordAtomics]>;
18830b57cec5SDimitry Andric
188406c3fb27SDimitry Andricdef LHARXL : XForm_1_memOp<31,  116, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
188506c3fb27SDimitry Andric                     "lharx $RST, $addr, 1", IIC_LdStLWARX, []>, isRecordForm,
18860b57cec5SDimitry Andric                     Requires<[HasPartwordAtomics]>;
18870b57cec5SDimitry Andric
188806c3fb27SDimitry Andricdef LWARXL : XForm_1_memOp<31,  20, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
188906c3fb27SDimitry Andric                     "lwarx $RST, $addr, 1", IIC_LdStLWARX, []>, isRecordForm;
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andric// The atomic instructions use the destination register as well as the next one
18920b57cec5SDimitry Andric// or two registers in order (modulo 31).
18930b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1 in
189406c3fb27SDimitry Andricdef LWAT : X_RD5_RS5_IM5<31, 582, (outs gprc:$RST), (ins gprc:$RA, u5imm:$RB),
189506c3fb27SDimitry Andric                         "lwat $RST, $RA, $RB", IIC_LdStLoad>,
18960b57cec5SDimitry Andric           Requires<[IsISA3_0]>;
18970b57cec5SDimitry Andric}
18980b57cec5SDimitry Andric
18990b57cec5SDimitry Andriclet Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
190006c3fb27SDimitry Andricdef STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
190106c3fb27SDimitry Andric                    "stbcx. $RST, $addr", IIC_LdStSTWCX, []>,
1902480093f4SDimitry Andric                    isRecordForm, Requires<[HasPartwordAtomics]>;
19030b57cec5SDimitry Andric
190406c3fb27SDimitry Andricdef STHCX : XForm_1_memOp<31, 726, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
190506c3fb27SDimitry Andric                    "sthcx. $RST, $addr", IIC_LdStSTWCX, []>,
1906480093f4SDimitry Andric                    isRecordForm, Requires<[HasPartwordAtomics]>;
19070b57cec5SDimitry Andric
190806c3fb27SDimitry Andricdef STWCX : XForm_1_memOp<31, 150, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
190906c3fb27SDimitry Andric                    "stwcx. $RST, $addr", IIC_LdStSTWCX, []>, isRecordForm;
19100b57cec5SDimitry Andric}
19110b57cec5SDimitry Andric
19120b57cec5SDimitry Andriclet mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
191306c3fb27SDimitry Andricdef STWAT : X_RD5_RS5_IM5<31, 710, (outs), (ins gprc:$RST, gprc:$RA, u5imm:$RB),
191406c3fb27SDimitry Andric                          "stwat $RST, $RA, $RB", IIC_LdStStore>,
19150b57cec5SDimitry Andric            Requires<[IsISA3_0]>;
19160b57cec5SDimitry Andric
1917297eecfbSDimitry Andriclet isTrap = 1, hasCtrlDep = 1 in
19180b57cec5SDimitry Andricdef TRAP  : XForm_24<31, 4, (outs), (ins), "trap", IIC_LdStLoad, [(trap)]>;
19190b57cec5SDimitry Andric
192006c3fb27SDimitry Andricdef TWI : DForm_base<3, (outs), (ins u5imm:$RST, gprc:$RA, s16imm:$D, variable_ops),
192106c3fb27SDimitry Andric                     "twi $RST, $RA, $D", IIC_IntTrapW, []>;
192206c3fb27SDimitry Andricdef TW : XForm_1<31, 4, (outs), (ins u5imm:$RST, gprc:$RA, gprc:$RB, variable_ops),
192306c3fb27SDimitry Andric                 "tw $RST, $RA, $RB", IIC_IntTrapW, []>;
192406c3fb27SDimitry Andricdef TDI : DForm_base<2, (outs), (ins u5imm:$RST, g8rc:$RA, s16imm:$D, variable_ops),
192506c3fb27SDimitry Andric                     "tdi $RST, $RA, $D", IIC_IntTrapD, []>;
192606c3fb27SDimitry Andricdef TD : XForm_1<31, 68, (outs), (ins u5imm:$RST, g8rc:$RA, g8rc:$RB, variable_ops),
192706c3fb27SDimitry Andric                 "td $RST, $RA, $RB", IIC_IntTrapD, []>;
19280b57cec5SDimitry Andric
192906c3fb27SDimitry Andricdef POPCNTB : XForm_11<31, 122, (outs gprc:$RA), (ins gprc:$RST),
193006c3fb27SDimitry Andric                       "popcntb $RA, $RST", IIC_IntGeneral,
193106c3fb27SDimitry Andric                       [(set i32:$RA, (int_ppc_popcntb i32:$RST))]>;
193206c3fb27SDimitry Andric
193306c3fb27SDimitry Andricdef CDTBCD : XForm_11<31, 282, (outs gprc:$RA), (ins gprc:$RST),
193406c3fb27SDimitry Andric                      "cdtbcd $RA, $RST", IIC_IntGeneral, []>;
193506c3fb27SDimitry Andricdef CBCDTD : XForm_11<31, 314, (outs gprc:$RA), (ins gprc:$RST),
193606c3fb27SDimitry Andric                      "cbcdtd $RA, $RST", IIC_IntGeneral, []>;
193706c3fb27SDimitry Andric
193806c3fb27SDimitry Andricdef ADDG6S : XOForm_1<31, 74, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
193906c3fb27SDimitry Andric                      "addg6s $RT, $RA, $RB", IIC_IntGeneral, []>;
1940fe6060f1SDimitry Andric
19410b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
19420b57cec5SDimitry Andric// PPC32 Load Instructions.
19430b57cec5SDimitry Andric//
19440b57cec5SDimitry Andric
19450b57cec5SDimitry Andric// Unindexed (r+i) Loads.
19460b57cec5SDimitry Andriclet PPC970_Unit = 2 in {
194706c3fb27SDimitry Andricdef LBZ : DForm_1<34, (outs gprc:$RST), (ins (memri $D, $RA):$addr),
194806c3fb27SDimitry Andric                  "lbz $RST, $addr", IIC_LdStLoad,
194906c3fb27SDimitry Andric                  [(set i32:$RST, (zextloadi8 DForm:$addr))]>, ZExt32To64,
1950bdd1243dSDimitry Andric                  SExt32To64;
195106c3fb27SDimitry Andricdef LHA : DForm_1<42, (outs gprc:$RST), (ins (memri $D, $RA):$addr),
195206c3fb27SDimitry Andric                  "lha $RST, $addr", IIC_LdStLHA,
195306c3fb27SDimitry Andric                  [(set i32:$RST, (sextloadi16 DForm:$addr))]>,
1954bdd1243dSDimitry Andric                  PPC970_DGroup_Cracked, SExt32To64;
195506c3fb27SDimitry Andricdef LHZ : DForm_1<40, (outs gprc:$RST), (ins (memri $D, $RA):$addr),
195606c3fb27SDimitry Andric                  "lhz $RST, $addr", IIC_LdStLoad,
195706c3fb27SDimitry Andric                  [(set i32:$RST, (zextloadi16 DForm:$addr))]>, ZExt32To64,
1958bdd1243dSDimitry Andric                  SExt32To64;
195906c3fb27SDimitry Andricdef LWZ : DForm_1<32, (outs gprc:$RST), (ins (memri $D, $RA):$addr),
196006c3fb27SDimitry Andric                  "lwz $RST, $addr", IIC_LdStLoad,
196106c3fb27SDimitry Andric                  [(set i32:$RST, (load DForm:$addr))]>, ZExt32To64;
19620b57cec5SDimitry Andric
19630b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
196406c3fb27SDimitry Andricdef LFS : DForm_1<48, (outs f4rc:$RST), (ins (memri $D, $RA):$addr),
196506c3fb27SDimitry Andric                  "lfs $RST, $addr", IIC_LdStLFD,
196606c3fb27SDimitry Andric                  [(set f32:$RST, (load DForm:$addr))]>;
196706c3fb27SDimitry Andricdef LFD : DForm_1<50, (outs f8rc:$RST), (ins (memri $D, $RA):$addr),
196806c3fb27SDimitry Andric                  "lfd $RST, $addr", IIC_LdStLFD,
196906c3fb27SDimitry Andric                  [(set f64:$RST, (load DForm:$addr))]>;
19700b57cec5SDimitry Andric}
19710b57cec5SDimitry Andric
19720b57cec5SDimitry Andric
19730b57cec5SDimitry Andric// Unindexed (r+i) Loads with Update (preinc).
19740b57cec5SDimitry Andriclet mayLoad = 1, mayStore = 0, hasSideEffects = 0 in {
197506c3fb27SDimitry Andricdef LBZU : DForm_1<35, (outs gprc:$RST, ptr_rc_nor0:$ea_result), (ins (memri $D, $RA):$addr),
197606c3fb27SDimitry Andric                   "lbzu $RST, $addr", IIC_LdStLoadUpd,
197706c3fb27SDimitry Andric                   []>, RegConstraint<"$RA = $ea_result">;
197806c3fb27SDimitry Andric
197906c3fb27SDimitry Andricdef LHAU : DForm_1<43, (outs gprc:$RST, ptr_rc_nor0:$ea_result), (ins (memri $D, $RA):$addr),
198006c3fb27SDimitry Andric                   "lhau $RST, $addr", IIC_LdStLHAU,
19810b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.reg = $ea_result">,
19820b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
19830b57cec5SDimitry Andric
198406c3fb27SDimitry Andricdef LHZU : DForm_1<41, (outs gprc:$RST, ptr_rc_nor0:$ea_result), (ins (memri $D, $RA):$addr),
198506c3fb27SDimitry Andric                   "lhzu $RST, $addr", IIC_LdStLoadUpd,
19860b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.reg = $ea_result">,
19870b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
19880b57cec5SDimitry Andric
198906c3fb27SDimitry Andricdef LWZU : DForm_1<33, (outs gprc:$RST, ptr_rc_nor0:$ea_result), (ins (memri $D, $RA):$addr),
199006c3fb27SDimitry Andric                   "lwzu $RST, $addr", IIC_LdStLoadUpd,
19910b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.reg = $ea_result">,
19920b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
199506c3fb27SDimitry Andricdef LFSU : DForm_1<49, (outs f4rc:$RST, ptr_rc_nor0:$ea_result), (ins (memri $D, $RA):$addr),
199606c3fb27SDimitry Andric                  "lfsu $RST, $addr", IIC_LdStLFDU,
19970b57cec5SDimitry Andric                  []>, RegConstraint<"$addr.reg = $ea_result">,
19980b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
19990b57cec5SDimitry Andric
200006c3fb27SDimitry Andricdef LFDU : DForm_1<51, (outs f8rc:$RST, ptr_rc_nor0:$ea_result), (ins (memri $D, $RA):$addr),
200106c3fb27SDimitry Andric                  "lfdu $RST, $addr", IIC_LdStLFDU,
20020b57cec5SDimitry Andric                  []>, RegConstraint<"$addr.reg = $ea_result">,
20030b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20040b57cec5SDimitry Andric}
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andric// Indexed (r+r) Loads with Update (preinc).
200806c3fb27SDimitry Andricdef LBZUX : XForm_1_memOp<31, 119, (outs gprc:$RST, ptr_rc_nor0:$ea_result),
200906c3fb27SDimitry Andric                   (ins (memrr $RA, $RB):$addr),
201006c3fb27SDimitry Andric                   "lbzux $RST, $addr", IIC_LdStLoadUpdX,
20110b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.ptrreg = $ea_result">,
20120b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20130b57cec5SDimitry Andric
201406c3fb27SDimitry Andricdef LHAUX : XForm_1_memOp<31, 375, (outs gprc:$RST, ptr_rc_nor0:$ea_result),
201506c3fb27SDimitry Andric                   (ins (memrr $RA, $RB):$addr),
201606c3fb27SDimitry Andric                   "lhaux $RST, $addr", IIC_LdStLHAUX,
20170b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.ptrreg = $ea_result">,
20180b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20190b57cec5SDimitry Andric
202006c3fb27SDimitry Andricdef LHZUX : XForm_1_memOp<31, 311, (outs gprc:$RST, ptr_rc_nor0:$ea_result),
202106c3fb27SDimitry Andric                   (ins (memrr $RA, $RB):$addr),
202206c3fb27SDimitry Andric                   "lhzux $RST, $addr", IIC_LdStLoadUpdX,
20230b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.ptrreg = $ea_result">,
20240b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20250b57cec5SDimitry Andric
202606c3fb27SDimitry Andricdef LWZUX : XForm_1_memOp<31, 55, (outs gprc:$RST, ptr_rc_nor0:$ea_result),
202706c3fb27SDimitry Andric                   (ins (memrr $RA, $RB):$addr),
202806c3fb27SDimitry Andric                   "lwzux $RST, $addr", IIC_LdStLoadUpdX,
20290b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.ptrreg = $ea_result">,
20300b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20310b57cec5SDimitry Andric
20320b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
203306c3fb27SDimitry Andricdef LFSUX : XForm_1_memOp<31, 567, (outs f4rc:$RST, ptr_rc_nor0:$ea_result),
203406c3fb27SDimitry Andric                   (ins (memrr $RA, $RB):$addr),
203506c3fb27SDimitry Andric                   "lfsux $RST, $addr", IIC_LdStLFDUX,
20360b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.ptrreg = $ea_result">,
20370b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20380b57cec5SDimitry Andric
203906c3fb27SDimitry Andricdef LFDUX : XForm_1_memOp<31, 631, (outs f8rc:$RST, ptr_rc_nor0:$ea_result),
204006c3fb27SDimitry Andric                   (ins (memrr $RA, $RB):$addr),
204106c3fb27SDimitry Andric                   "lfdux $RST, $addr", IIC_LdStLFDUX,
20420b57cec5SDimitry Andric                   []>, RegConstraint<"$addr.ptrreg = $ea_result">,
20430b57cec5SDimitry Andric                   NoEncode<"$ea_result">;
20440b57cec5SDimitry Andric}
20450b57cec5SDimitry Andric}
20460b57cec5SDimitry Andric}
20470b57cec5SDimitry Andric
20480b57cec5SDimitry Andric// Indexed (r+r) Loads.
20490b57cec5SDimitry Andric//
20500b57cec5SDimitry Andriclet PPC970_Unit = 2, mayLoad = 1, mayStore = 0 in {
205106c3fb27SDimitry Andricdef LBZX : XForm_1_memOp<31,  87, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
205206c3fb27SDimitry Andric                   "lbzx $RST, $addr", IIC_LdStLoad,
205306c3fb27SDimitry Andric                   [(set i32:$RST, (zextloadi8 XForm:$addr))]>, ZExt32To64,
2054bdd1243dSDimitry Andric                   SExt32To64;
205506c3fb27SDimitry Andricdef LHAX : XForm_1_memOp<31, 343, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
205606c3fb27SDimitry Andric                   "lhax $RST, $addr", IIC_LdStLHA,
205706c3fb27SDimitry Andric                   [(set i32:$RST, (sextloadi16 XForm:$addr))]>,
2058bdd1243dSDimitry Andric                   PPC970_DGroup_Cracked, SExt32To64;
205906c3fb27SDimitry Andricdef LHZX : XForm_1_memOp<31, 279, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
206006c3fb27SDimitry Andric                   "lhzx $RST, $addr", IIC_LdStLoad,
206106c3fb27SDimitry Andric                   [(set i32:$RST, (zextloadi16 XForm:$addr))]>, ZExt32To64,
2062bdd1243dSDimitry Andric                   SExt32To64;
206306c3fb27SDimitry Andricdef LWZX : XForm_1_memOp<31,  23, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
206406c3fb27SDimitry Andric                   "lwzx $RST, $addr", IIC_LdStLoad,
206506c3fb27SDimitry Andric                   [(set i32:$RST, (load XForm:$addr))]>, ZExt32To64;
206606c3fb27SDimitry Andricdef LHBRX : XForm_1_memOp<31, 790, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
206706c3fb27SDimitry Andric                   "lhbrx $RST, $addr", IIC_LdStLoad,
206806c3fb27SDimitry Andric                   [(set i32:$RST, (PPClbrx ForceXForm:$addr, i16))]>, ZExt32To64;
206906c3fb27SDimitry Andricdef LWBRX : XForm_1_memOp<31,  534, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
207006c3fb27SDimitry Andric                   "lwbrx $RST, $addr", IIC_LdStLoad,
207106c3fb27SDimitry Andric                   [(set i32:$RST, (PPClbrx ForceXForm:$addr, i32))]>, ZExt32To64;
20720b57cec5SDimitry Andric
20730b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
207406c3fb27SDimitry Andricdef LFSX   : XForm_25_memOp<31, 535, (outs f4rc:$RST), (ins (memrr $RA, $RB):$addr),
207506c3fb27SDimitry Andric                      "lfsx $RST, $addr", IIC_LdStLFD,
207606c3fb27SDimitry Andric                      [(set f32:$RST, (load XForm:$addr))]>;
207706c3fb27SDimitry Andricdef LFDX   : XForm_25_memOp<31, 599, (outs f8rc:$RST), (ins (memrr $RA, $RB):$addr),
207806c3fb27SDimitry Andric                      "lfdx $RST, $addr", IIC_LdStLFD,
207906c3fb27SDimitry Andric                      [(set f64:$RST, (load XForm:$addr))]>;
20800b57cec5SDimitry Andric
208106c3fb27SDimitry Andricdef LFIWAX : XForm_25_memOp<31, 855, (outs f8rc:$RST), (ins (memrr $RA, $RB):$addr),
208206c3fb27SDimitry Andric                      "lfiwax $RST, $addr", IIC_LdStLFD,
208306c3fb27SDimitry Andric                      [(set f64:$RST, (PPClfiwax ForceXForm:$addr))]>;
208406c3fb27SDimitry Andricdef LFIWZX : XForm_25_memOp<31, 887, (outs f8rc:$RST), (ins (memrr $RA, $RB):$addr),
208506c3fb27SDimitry Andric                      "lfiwzx $RST, $addr", IIC_LdStLFD,
208606c3fb27SDimitry Andric                      [(set f64:$RST, (PPClfiwzx ForceXForm:$addr))]>;
20870b57cec5SDimitry Andric}
20880b57cec5SDimitry Andric}
20890b57cec5SDimitry Andric
20900b57cec5SDimitry Andric// Load Multiple
2091480093f4SDimitry Andriclet mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
209206c3fb27SDimitry Andricdef LMW : DForm_1<46, (outs gprc:$RST), (ins (memri $D, $RA):$src),
209306c3fb27SDimitry Andric                  "lmw $RST, $src", IIC_LdStLMW, []>;
20940b57cec5SDimitry Andric
20950b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
20960b57cec5SDimitry Andric// PPC32 Store Instructions.
20970b57cec5SDimitry Andric//
20980b57cec5SDimitry Andric
20990b57cec5SDimitry Andric// Unindexed (r+i) Stores.
21000b57cec5SDimitry Andriclet PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in {
210106c3fb27SDimitry Andricdef STB  : DForm_1<38, (outs), (ins gprc:$RST, (memri $D, $RA):$dst),
210206c3fb27SDimitry Andric                   "stb $RST, $dst", IIC_LdStStore,
210306c3fb27SDimitry Andric                   [(truncstorei8 i32:$RST, DForm:$dst)]>;
210406c3fb27SDimitry Andricdef STH  : DForm_1<44, (outs), (ins gprc:$RST, (memri $D, $RA):$dst),
210506c3fb27SDimitry Andric                   "sth $RST, $dst", IIC_LdStStore,
210606c3fb27SDimitry Andric                   [(truncstorei16 i32:$RST, DForm:$dst)]>;
210706c3fb27SDimitry Andricdef STW  : DForm_1<36, (outs), (ins gprc:$RST, (memri $D, $RA):$dst),
210806c3fb27SDimitry Andric                   "stw $RST, $dst", IIC_LdStStore,
210906c3fb27SDimitry Andric                   [(store i32:$RST, DForm:$dst)]>;
21100b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
211106c3fb27SDimitry Andricdef STFS : DForm_1<52, (outs), (ins f4rc:$RST, (memri $D, $RA):$dst),
211206c3fb27SDimitry Andric                   "stfs $RST, $dst", IIC_LdStSTFD,
211306c3fb27SDimitry Andric                   [(store f32:$RST, DForm:$dst)]>;
211406c3fb27SDimitry Andricdef STFD : DForm_1<54, (outs), (ins f8rc:$RST, (memri $D, $RA):$dst),
211506c3fb27SDimitry Andric                   "stfd $RST, $dst", IIC_LdStSTFD,
211606c3fb27SDimitry Andric                   [(store f64:$RST, DForm:$dst)]>;
21170b57cec5SDimitry Andric}
21180b57cec5SDimitry Andric}
21190b57cec5SDimitry Andric
21200b57cec5SDimitry Andric// Unindexed (r+i) Stores with Update (preinc).
21210b57cec5SDimitry Andriclet PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in {
212206c3fb27SDimitry Andricdef STBU  : DForm_1<39, (outs ptr_rc_nor0:$ea_res), (ins gprc:$RST, (memri $D, $RA):$dst),
212306c3fb27SDimitry Andric                    "stbu $RST, $dst", IIC_LdStSTU, []>,
21240b57cec5SDimitry Andric                    RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
212506c3fb27SDimitry Andricdef STHU  : DForm_1<45, (outs ptr_rc_nor0:$ea_res), (ins gprc:$RST, (memri $D, $RA):$dst),
212606c3fb27SDimitry Andric                    "sthu $RST, $dst", IIC_LdStSTU, []>,
21270b57cec5SDimitry Andric                    RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
212806c3fb27SDimitry Andricdef STWU  : DForm_1<37, (outs ptr_rc_nor0:$ea_res), (ins gprc:$RST, (memri $D, $RA):$dst),
212906c3fb27SDimitry Andric                    "stwu $RST, $dst", IIC_LdStSTU, []>,
21300b57cec5SDimitry Andric                    RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
21310b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
213206c3fb27SDimitry Andricdef STFSU : DForm_1<53, (outs ptr_rc_nor0:$ea_res), (ins f4rc:$RST, (memri $D, $RA):$dst),
213306c3fb27SDimitry Andric                    "stfsu $RST, $dst", IIC_LdStSTFDU, []>,
21340b57cec5SDimitry Andric                    RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
213506c3fb27SDimitry Andricdef STFDU : DForm_1<55, (outs ptr_rc_nor0:$ea_res), (ins f8rc:$RST, (memri $D, $RA):$dst),
213606c3fb27SDimitry Andric                    "stfdu $RST, $dst", IIC_LdStSTFDU, []>,
21370b57cec5SDimitry Andric                    RegConstraint<"$dst.reg = $ea_res">, NoEncode<"$ea_res">;
21380b57cec5SDimitry Andric}
21390b57cec5SDimitry Andric}
21400b57cec5SDimitry Andric
21410b57cec5SDimitry Andric// Patterns to match the pre-inc stores.  We can't put the patterns on
21420b57cec5SDimitry Andric// the instruction definitions directly as ISel wants the address base
21430b57cec5SDimitry Andric// and offset to be separate operands, not a single complex operand.
21440b57cec5SDimitry Andricdef : Pat<(pre_truncsti8 i32:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
21450b57cec5SDimitry Andric          (STBU $rS, iaddroff:$ptroff, $ptrreg)>;
21460b57cec5SDimitry Andricdef : Pat<(pre_truncsti16 i32:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
21470b57cec5SDimitry Andric          (STHU $rS, iaddroff:$ptroff, $ptrreg)>;
21480b57cec5SDimitry Andricdef : Pat<(pre_store i32:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
21490b57cec5SDimitry Andric          (STWU $rS, iaddroff:$ptroff, $ptrreg)>;
21500b57cec5SDimitry Andricdef : Pat<(pre_store f32:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
21510b57cec5SDimitry Andric          (STFSU $rS, iaddroff:$ptroff, $ptrreg)>;
21520b57cec5SDimitry Andricdef : Pat<(pre_store f64:$rS, iPTR:$ptrreg, iaddroff:$ptroff),
21530b57cec5SDimitry Andric          (STFDU $rS, iaddroff:$ptroff, $ptrreg)>;
21540b57cec5SDimitry Andric
21550b57cec5SDimitry Andric// Indexed (r+r) Stores.
21560b57cec5SDimitry Andriclet PPC970_Unit = 2 in {
215706c3fb27SDimitry Andricdef STBX  : XForm_8_memOp<31, 215, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
215806c3fb27SDimitry Andric                   "stbx $RST, $addr", IIC_LdStStore,
215906c3fb27SDimitry Andric                   [(truncstorei8 i32:$RST, XForm:$addr)]>,
21600b57cec5SDimitry Andric                   PPC970_DGroup_Cracked;
216106c3fb27SDimitry Andricdef STHX  : XForm_8_memOp<31, 407, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
216206c3fb27SDimitry Andric                   "sthx $RST, $addr", IIC_LdStStore,
216306c3fb27SDimitry Andric                   [(truncstorei16 i32:$RST, XForm:$addr)]>,
21640b57cec5SDimitry Andric                   PPC970_DGroup_Cracked;
216506c3fb27SDimitry Andricdef STWX  : XForm_8_memOp<31, 151, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
216606c3fb27SDimitry Andric                   "stwx $RST, $addr", IIC_LdStStore,
216706c3fb27SDimitry Andric                   [(store i32:$RST, XForm:$addr)]>,
21680b57cec5SDimitry Andric                   PPC970_DGroup_Cracked;
21690b57cec5SDimitry Andric
217006c3fb27SDimitry Andricdef STHBRX: XForm_8_memOp<31, 918, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
217106c3fb27SDimitry Andric                   "sthbrx $RST, $addr", IIC_LdStStore,
217206c3fb27SDimitry Andric                   [(PPCstbrx i32:$RST, ForceXForm:$addr, i16)]>,
21730b57cec5SDimitry Andric                   PPC970_DGroup_Cracked;
217406c3fb27SDimitry Andricdef STWBRX: XForm_8_memOp<31, 662, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
217506c3fb27SDimitry Andric                   "stwbrx $RST, $addr", IIC_LdStStore,
217606c3fb27SDimitry Andric                   [(PPCstbrx i32:$RST, ForceXForm:$addr, i32)]>,
21770b57cec5SDimitry Andric                   PPC970_DGroup_Cracked;
21780b57cec5SDimitry Andric
21790b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
218006c3fb27SDimitry Andricdef STFIWX: XForm_28_memOp<31, 983, (outs), (ins f8rc:$RST, (memrr $RA, $RB):$addr),
218106c3fb27SDimitry Andric                     "stfiwx $RST, $addr", IIC_LdStSTFD,
218206c3fb27SDimitry Andric                     [(PPCstfiwx f64:$RST, ForceXForm:$addr)]>;
21830b57cec5SDimitry Andric
218406c3fb27SDimitry Andricdef STFSX : XForm_28_memOp<31, 663, (outs), (ins f4rc:$RST, (memrr $RA, $RB):$addr),
218506c3fb27SDimitry Andric                     "stfsx $RST, $addr", IIC_LdStSTFD,
218606c3fb27SDimitry Andric                     [(store f32:$RST, XForm:$addr)]>;
218706c3fb27SDimitry Andricdef STFDX : XForm_28_memOp<31, 727, (outs), (ins f8rc:$RST, (memrr $RA, $RB):$addr),
218806c3fb27SDimitry Andric                     "stfdx $RST, $addr", IIC_LdStSTFD,
218906c3fb27SDimitry Andric                     [(store f64:$RST, XForm:$addr)]>;
21900b57cec5SDimitry Andric}
21910b57cec5SDimitry Andric}
21920b57cec5SDimitry Andric
21930b57cec5SDimitry Andric// Indexed (r+r) Stores with Update (preinc).
21940b57cec5SDimitry Andriclet PPC970_Unit = 2, mayStore = 1, mayLoad = 0 in {
21950b57cec5SDimitry Andricdef STBUX : XForm_8_memOp<31, 247, (outs ptr_rc_nor0:$ea_res),
219606c3fb27SDimitry Andric                          (ins gprc:$RST, (memrr $RA, $RB):$addr),
219706c3fb27SDimitry Andric                          "stbux $RST, $addr", IIC_LdStSTUX, []>,
219806c3fb27SDimitry Andric                          RegConstraint<"$addr.ptrreg = $ea_res">,
21990b57cec5SDimitry Andric                          NoEncode<"$ea_res">,
22000b57cec5SDimitry Andric                          PPC970_DGroup_Cracked;
22010b57cec5SDimitry Andricdef STHUX : XForm_8_memOp<31, 439, (outs ptr_rc_nor0:$ea_res),
220206c3fb27SDimitry Andric                          (ins gprc:$RST, (memrr $RA, $RB):$addr),
220306c3fb27SDimitry Andric                          "sthux $RST, $addr", IIC_LdStSTUX, []>,
220406c3fb27SDimitry Andric                          RegConstraint<"$addr.ptrreg = $ea_res">,
22050b57cec5SDimitry Andric                          NoEncode<"$ea_res">,
22060b57cec5SDimitry Andric                          PPC970_DGroup_Cracked;
22070b57cec5SDimitry Andricdef STWUX : XForm_8_memOp<31, 183, (outs ptr_rc_nor0:$ea_res),
220806c3fb27SDimitry Andric                          (ins gprc:$RST, (memrr $RA, $RB):$addr),
220906c3fb27SDimitry Andric                          "stwux $RST, $addr", IIC_LdStSTUX, []>,
221006c3fb27SDimitry Andric                          RegConstraint<"$addr.ptrreg = $ea_res">,
22110b57cec5SDimitry Andric                          NoEncode<"$ea_res">,
22120b57cec5SDimitry Andric                          PPC970_DGroup_Cracked;
22130b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
22140b57cec5SDimitry Andricdef STFSUX: XForm_8_memOp<31, 695, (outs ptr_rc_nor0:$ea_res),
221506c3fb27SDimitry Andric                          (ins f4rc:$RST, (memrr $RA, $RB):$addr),
221606c3fb27SDimitry Andric                          "stfsux $RST, $addr", IIC_LdStSTFDU, []>,
221706c3fb27SDimitry Andric                          RegConstraint<"$addr.ptrreg = $ea_res">,
22180b57cec5SDimitry Andric                          NoEncode<"$ea_res">,
22190b57cec5SDimitry Andric                          PPC970_DGroup_Cracked;
22200b57cec5SDimitry Andricdef STFDUX: XForm_8_memOp<31, 759, (outs ptr_rc_nor0:$ea_res),
222106c3fb27SDimitry Andric                          (ins f8rc:$RST, (memrr $RA, $RB):$addr),
222206c3fb27SDimitry Andric                          "stfdux $RST, $addr", IIC_LdStSTFDU, []>,
222306c3fb27SDimitry Andric                          RegConstraint<"$addr.ptrreg = $ea_res">,
22240b57cec5SDimitry Andric                          NoEncode<"$ea_res">,
22250b57cec5SDimitry Andric                          PPC970_DGroup_Cracked;
22260b57cec5SDimitry Andric}
22270b57cec5SDimitry Andric}
22280b57cec5SDimitry Andric
22290b57cec5SDimitry Andric// Patterns to match the pre-inc stores.  We can't put the patterns on
22300b57cec5SDimitry Andric// the instruction definitions directly as ISel wants the address base
22310b57cec5SDimitry Andric// and offset to be separate operands, not a single complex operand.
22320b57cec5SDimitry Andricdef : Pat<(pre_truncsti8 i32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
22330b57cec5SDimitry Andric          (STBUX $rS, $ptrreg, $ptroff)>;
22340b57cec5SDimitry Andricdef : Pat<(pre_truncsti16 i32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
22350b57cec5SDimitry Andric          (STHUX $rS, $ptrreg, $ptroff)>;
22360b57cec5SDimitry Andricdef : Pat<(pre_store i32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
22370b57cec5SDimitry Andric          (STWUX $rS, $ptrreg, $ptroff)>;
22380b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
22390b57cec5SDimitry Andricdef : Pat<(pre_store f32:$rS, iPTR:$ptrreg, iPTR:$ptroff),
22400b57cec5SDimitry Andric          (STFSUX $rS, $ptrreg, $ptroff)>;
22410b57cec5SDimitry Andricdef : Pat<(pre_store f64:$rS, iPTR:$ptrreg, iPTR:$ptroff),
22420b57cec5SDimitry Andric          (STFDUX $rS, $ptrreg, $ptroff)>;
22430b57cec5SDimitry Andric}
22440b57cec5SDimitry Andric
22450b57cec5SDimitry Andric// Store Multiple
2246480093f4SDimitry Andriclet mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
224706c3fb27SDimitry Andricdef STMW : DForm_1<47, (outs), (ins gprc:$RST, (memri $D, $RA):$dst),
224806c3fb27SDimitry Andric                   "stmw $RST, $dst", IIC_LdStLMW, []>;
22490b57cec5SDimitry Andric
2250e8d8bef9SDimitry Andricdef SYNC : XForm_24_sync<31, 598, (outs), (ins u2imm:$L),
22510b57cec5SDimitry Andric                        "sync $L", IIC_LdStSync, []>;
22520b57cec5SDimitry Andric
22530b57cec5SDimitry Andriclet isCodeGenOnly = 1 in {
22540b57cec5SDimitry Andric  def MSYNC : XForm_24_sync<31, 598, (outs), (ins),
22550b57cec5SDimitry Andric                           "msync", IIC_LdStSync, []> {
22560b57cec5SDimitry Andric    let L = 0;
22570b57cec5SDimitry Andric  }
22580b57cec5SDimitry Andric}
22590b57cec5SDimitry Andric
22605ffd83dbSDimitry Andric// We used to have EIEIO as value but E[0-9A-Z] is a reserved name
22615ffd83dbSDimitry Andricdef EnforceIEIO : XForm_24_eieio<31, 854, (outs), (ins),
22625ffd83dbSDimitry Andric                                 "eieio", IIC_LdStLoad, []>;
22635ffd83dbSDimitry Andric
2264fe6060f1SDimitry Andricdef PseudoEIEIO : PPCEmitTimePseudo<(outs), (ins), "#PPCEIEIO",
2265fe6060f1SDimitry Andric                  [(int_ppc_eieio)]>;
2266fe6060f1SDimitry Andric
22670b57cec5SDimitry Andricdef : Pat<(int_ppc_sync),   (SYNC 0)>, Requires<[HasSYNC]>;
2268fe6060f1SDimitry Andricdef : Pat<(int_ppc_iospace_sync),   (SYNC 0)>, Requires<[HasSYNC]>;
22690b57cec5SDimitry Andricdef : Pat<(int_ppc_lwsync), (SYNC 1)>, Requires<[HasSYNC]>;
2270fe6060f1SDimitry Andricdef : Pat<(int_ppc_iospace_lwsync), (SYNC 1)>, Requires<[HasSYNC]>;
22710b57cec5SDimitry Andricdef : Pat<(int_ppc_sync),   (MSYNC)>, Requires<[HasOnlyMSYNC]>;
2272fe6060f1SDimitry Andricdef : Pat<(int_ppc_iospace_sync),   (MSYNC)>, Requires<[HasOnlyMSYNC]>;
22730b57cec5SDimitry Andricdef : Pat<(int_ppc_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>;
2274fe6060f1SDimitry Andricdef : Pat<(int_ppc_iospace_lwsync), (MSYNC)>, Requires<[HasOnlyMSYNC]>;
2275fe6060f1SDimitry Andricdef : Pat<(int_ppc_eieio),  (PseudoEIEIO)>;
2276fe6060f1SDimitry Andricdef : Pat<(int_ppc_iospace_eieio),  (PseudoEIEIO)>;
22770b57cec5SDimitry Andric
22780b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
22790b57cec5SDimitry Andric// PPC32 Arithmetic Instructions.
22800b57cec5SDimitry Andric//
22810b57cec5SDimitry Andric
22820b57cec5SDimitry Andriclet PPC970_Unit = 1 in {  // FXU Operations.
228306c3fb27SDimitry Andricdef ADDI   : DForm_2<14, (outs gprc:$RST), (ins gprc_nor0:$RA, s16imm:$D),
228406c3fb27SDimitry Andric                     "addi $RST, $RA, $D", IIC_IntSimple,
228506c3fb27SDimitry Andric                     [(set i32:$RST, (add i32:$RA, imm32SExt16:$D))]>;
22860b57cec5SDimitry Andriclet BaseName = "addic" in {
22870b57cec5SDimitry Andriclet Defs = [CARRY] in
228806c3fb27SDimitry Andricdef ADDIC  : DForm_2<12, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
228906c3fb27SDimitry Andric                     "addic $RST, $RA, $D", IIC_IntGeneral,
229006c3fb27SDimitry Andric                     [(set i32:$RST, (addc i32:$RA, imm32SExt16:$D))]>,
22910b57cec5SDimitry Andric                     RecFormRel, PPC970_DGroup_Cracked;
22920b57cec5SDimitry Andriclet Defs = [CARRY, CR0] in
229306c3fb27SDimitry Andricdef ADDIC_rec : DForm_2<13, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
229406c3fb27SDimitry Andric                     "addic. $RST, $RA, $D", IIC_IntGeneral,
2295480093f4SDimitry Andric                     []>, isRecordForm, RecFormRel;
22960b57cec5SDimitry Andric}
229706c3fb27SDimitry Andricdef ADDIS  : DForm_2<15, (outs gprc:$RST), (ins gprc_nor0:$RA, s17imm:$D),
229806c3fb27SDimitry Andric                     "addis $RST, $RA, $D", IIC_IntSimple,
229906c3fb27SDimitry Andric                     [(set i32:$RST, (add i32:$RA, imm16ShiftedSExt:$D))]>;
23000b57cec5SDimitry Andriclet isCodeGenOnly = 1 in
230106c3fb27SDimitry Andricdef LA     : DForm_2<14, (outs gprc:$RST), (ins gprc_nor0:$RA, s16imm:$D),
230206c3fb27SDimitry Andric                     "la $RST, $D($RA)", IIC_IntGeneral,
230306c3fb27SDimitry Andric                     [(set i32:$RST, (add i32:$RA,
230406c3fb27SDimitry Andric                                          (PPClo tglobaladdr:$D, 0)))]>;
230506c3fb27SDimitry Andricdef MULLI  : DForm_2< 7, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
230606c3fb27SDimitry Andric                     "mulli $RST, $RA, $D", IIC_IntMulLI,
230706c3fb27SDimitry Andric                     [(set i32:$RST, (mul i32:$RA, imm32SExt16:$D))]>;
23080b57cec5SDimitry Andriclet Defs = [CARRY] in
230906c3fb27SDimitry Andricdef SUBFIC : DForm_2< 8, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
231006c3fb27SDimitry Andric                     "subfic $RST, $RA, $D", IIC_IntGeneral,
231106c3fb27SDimitry Andric                     [(set i32:$RST, (subc imm32SExt16:$D, i32:$RA))]>;
23120b57cec5SDimitry Andric
23130b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
231406c3fb27SDimitry Andric  def LI  : DForm_2_r0<14, (outs gprc:$RST), (ins s16imm:$D),
231506c3fb27SDimitry Andric                       "li $RST, $D", IIC_IntSimple,
231606c3fb27SDimitry Andric                       [(set i32:$RST, imm32SExt16:$D)]>, SExt32To64;
231706c3fb27SDimitry Andric  def LIS : DForm_2_r0<15, (outs gprc:$RST), (ins s17imm:$D),
231806c3fb27SDimitry Andric                       "lis $RST, $D", IIC_IntSimple,
231906c3fb27SDimitry Andric                       [(set i32:$RST, imm16ShiftedSExt:$D)]>, SExt32To64;
23200b57cec5SDimitry Andric}
23210b57cec5SDimitry Andric}
23220b57cec5SDimitry Andric
23235ffd83dbSDimitry Andricdef : InstAlias<"li $rD, $imm", (ADDI gprc:$rD, ZERO, s16imm:$imm)>;
23245ffd83dbSDimitry Andricdef : InstAlias<"lis $rD, $imm", (ADDIS gprc:$rD, ZERO, s17imm:$imm)>;
23255ffd83dbSDimitry Andric
23260b57cec5SDimitry Andriclet PPC970_Unit = 1 in {  // FXU Operations.
23270b57cec5SDimitry Andriclet Defs = [CR0] in {
232806c3fb27SDimitry Andricdef ANDI_rec : DForm_4<28, (outs gprc:$RA), (ins gprc:$RST, u16imm:$D),
232906c3fb27SDimitry Andric                    "andi. $RA, $RST, $D", IIC_IntGeneral,
233006c3fb27SDimitry Andric                    [(set i32:$RA, (and i32:$RST, immZExt16:$D))]>,
2331bdd1243dSDimitry Andric                    isRecordForm, ZExt32To64, SExt32To64;
233206c3fb27SDimitry Andricdef ANDIS_rec : DForm_4<29, (outs gprc:$RA), (ins gprc:$RST, u16imm:$D),
233306c3fb27SDimitry Andric                    "andis. $RA, $RST, $D", IIC_IntGeneral,
233406c3fb27SDimitry Andric                    [(set i32:$RA, (and i32:$RST, imm16ShiftedZExt:$D))]>,
2335bdd1243dSDimitry Andric                    isRecordForm, ZExt32To64;
23360b57cec5SDimitry Andric}
233706c3fb27SDimitry Andricdef ORI   : DForm_4<24, (outs gprc:$RA), (ins gprc:$RST, u16imm:$D),
233806c3fb27SDimitry Andric                    "ori $RA, $RST, $D", IIC_IntSimple,
233906c3fb27SDimitry Andric                    [(set i32:$RA, (or i32:$RST, immZExt16:$D))]>;
234006c3fb27SDimitry Andricdef ORIS  : DForm_4<25, (outs gprc:$RA), (ins gprc:$RST, u16imm:$D),
234106c3fb27SDimitry Andric                    "oris $RA, $RST, $D", IIC_IntSimple,
234206c3fb27SDimitry Andric                    [(set i32:$RA, (or i32:$RST, imm16ShiftedZExt:$D))]>;
234306c3fb27SDimitry Andricdef XORI  : DForm_4<26, (outs gprc:$RA), (ins gprc:$RST, u16imm:$D),
234406c3fb27SDimitry Andric                    "xori $RA, $RST, $D", IIC_IntSimple,
234506c3fb27SDimitry Andric                    [(set i32:$RA, (xor i32:$RST, immZExt16:$D))]>;
234606c3fb27SDimitry Andricdef XORIS : DForm_4<27, (outs gprc:$RA), (ins gprc:$RST, u16imm:$D),
234706c3fb27SDimitry Andric                    "xoris $RA, $RST, $D", IIC_IntSimple,
234806c3fb27SDimitry Andric                    [(set i32:$RA, (xor i32:$RST, imm16ShiftedZExt:$D))]>;
23490b57cec5SDimitry Andric
23500b57cec5SDimitry Andricdef NOP   : DForm_4_zero<24, (outs), (ins), "nop", IIC_IntSimple,
23510b57cec5SDimitry Andric                         []>;
23520b57cec5SDimitry Andriclet isCodeGenOnly = 1 in {
23530b57cec5SDimitry Andric// The POWER6 and POWER7 have special group-terminating nops.
23540b57cec5SDimitry Andricdef NOP_GT_PWR6 : DForm_4_fixedreg_zero<24, 1, (outs), (ins),
23550b57cec5SDimitry Andric                                        "ori 1, 1, 0", IIC_IntSimple, []>;
23560b57cec5SDimitry Andricdef NOP_GT_PWR7 : DForm_4_fixedreg_zero<24, 2, (outs), (ins),
23570b57cec5SDimitry Andric                                        "ori 2, 2, 0", IIC_IntSimple, []>;
23580b57cec5SDimitry Andric}
23590b57cec5SDimitry Andric
23600b57cec5SDimitry Andriclet isCompare = 1, hasSideEffects = 0 in {
236106c3fb27SDimitry Andric  def CMPWI : DForm_5_ext<11, (outs crrc:$BF), (ins gprc:$RA, s16imm:$D),
236206c3fb27SDimitry Andric                          "cmpwi $BF, $RA, $D", IIC_IntCompare>;
236306c3fb27SDimitry Andric  def CMPLWI : DForm_6_ext<10, (outs crrc:$BF), (ins gprc:$RA, u16imm:$D),
236406c3fb27SDimitry Andric                           "cmplwi $BF, $RA, $D", IIC_IntCompare>;
2365fe6060f1SDimitry Andric  def CMPRB  : X_BF3_L1_RS5_RS5<31, 192, (outs crrc:$BF),
236606c3fb27SDimitry Andric                                (ins u1imm:$L, gprc:$RA, gprc:$RB),
236706c3fb27SDimitry Andric                                "cmprb $BF, $L, $RA, $RB", IIC_IntCompare, []>,
23680b57cec5SDimitry Andric               Requires<[IsISA3_0]>;
23690b57cec5SDimitry Andric}
23700b57cec5SDimitry Andric}
23710b57cec5SDimitry Andric
23720b57cec5SDimitry Andriclet PPC970_Unit = 1, hasSideEffects = 0 in {  // FXU Operations.
23730b57cec5SDimitry Andriclet isCommutable = 1 in {
237406c3fb27SDimitry Andricdefm NAND : XForm_6r<31, 476, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
237506c3fb27SDimitry Andric                     "nand", "$RA, $RST, $RB", IIC_IntSimple,
237606c3fb27SDimitry Andric                     [(set i32:$RA, (not (and i32:$RST, i32:$RB)))]>;
237706c3fb27SDimitry Andricdefm AND  : XForm_6r<31,  28, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
237806c3fb27SDimitry Andric                     "and", "$RA, $RST, $RB", IIC_IntSimple,
237906c3fb27SDimitry Andric                     [(set i32:$RA, (and i32:$RST, i32:$RB))]>;
23800b57cec5SDimitry Andric} // isCommutable
238106c3fb27SDimitry Andricdefm ANDC : XForm_6r<31,  60, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
238206c3fb27SDimitry Andric                     "andc", "$RA, $RST, $RB", IIC_IntSimple,
238306c3fb27SDimitry Andric                     [(set i32:$RA, (and i32:$RST, (not i32:$RB)))]>;
23840b57cec5SDimitry Andriclet isCommutable = 1 in {
238506c3fb27SDimitry Andricdefm OR   : XForm_6r<31, 444, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
238606c3fb27SDimitry Andric                     "or", "$RA, $RST, $RB", IIC_IntSimple,
238706c3fb27SDimitry Andric                     [(set i32:$RA, (or i32:$RST, i32:$RB))]>;
238806c3fb27SDimitry Andricdefm NOR  : XForm_6r<31, 124, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
238906c3fb27SDimitry Andric                     "nor", "$RA, $RST, $RB", IIC_IntSimple,
239006c3fb27SDimitry Andric                     [(set i32:$RA, (not (or i32:$RST, i32:$RB)))]>;
23910b57cec5SDimitry Andric} // isCommutable
239206c3fb27SDimitry Andricdefm ORC  : XForm_6r<31, 412, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
239306c3fb27SDimitry Andric                     "orc", "$RA, $RST, $RB", IIC_IntSimple,
239406c3fb27SDimitry Andric                     [(set i32:$RA, (or i32:$RST, (not i32:$RB)))]>;
23950b57cec5SDimitry Andriclet isCommutable = 1 in {
239606c3fb27SDimitry Andricdefm EQV  : XForm_6r<31, 284, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
239706c3fb27SDimitry Andric                     "eqv", "$RA, $RST, $RB", IIC_IntSimple,
239806c3fb27SDimitry Andric                     [(set i32:$RA, (not (xor i32:$RST, i32:$RB)))]>;
239906c3fb27SDimitry Andricdefm XOR  : XForm_6r<31, 316, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
240006c3fb27SDimitry Andric                     "xor", "$RA, $RST, $RB", IIC_IntSimple,
240106c3fb27SDimitry Andric                     [(set i32:$RA, (xor i32:$RST, i32:$RB))]>;
24020b57cec5SDimitry Andric} // isCommutable
240306c3fb27SDimitry Andricdefm SLW  : XForm_6r<31,  24, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
240406c3fb27SDimitry Andric                     "slw", "$RA, $RST, $RB", IIC_IntGeneral,
240506c3fb27SDimitry Andric                     [(set i32:$RA, (PPCshl i32:$RST, i32:$RB))]>, ZExt32To64;
240606c3fb27SDimitry Andricdefm SRW  : XForm_6r<31, 536, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
240706c3fb27SDimitry Andric                     "srw", "$RA, $RST, $RB", IIC_IntGeneral,
240806c3fb27SDimitry Andric                     [(set i32:$RA, (PPCsrl i32:$RST, i32:$RB))]>, ZExt32To64;
240906c3fb27SDimitry Andricdefm SRAW : XForm_6rc<31, 792, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
241006c3fb27SDimitry Andric                      "sraw", "$RA, $RST, $RB", IIC_IntShift,
241106c3fb27SDimitry Andric                      [(set i32:$RA, (PPCsra i32:$RST, i32:$RB))]>, SExt32To64;
24120b57cec5SDimitry Andric}
24130b57cec5SDimitry Andric
24145ffd83dbSDimitry Andricdef : InstAlias<"mr $rA, $rB", (OR gprc:$rA, gprc:$rB, gprc:$rB)>;
24155ffd83dbSDimitry Andricdef : InstAlias<"mr. $rA, $rB", (OR_rec gprc:$rA, gprc:$rB, gprc:$rB)>;
24165ffd83dbSDimitry Andric
24175ffd83dbSDimitry Andricdef : InstAlias<"not $rA, $rS", (NOR gprc:$rA, gprc:$rS, gprc:$rS)>;
24185ffd83dbSDimitry Andricdef : InstAlias<"not. $rA, $rS", (NOR_rec gprc:$rA, gprc:$rS, gprc:$rS)>;
24195ffd83dbSDimitry Andric
24205ffd83dbSDimitry Andricdef : InstAlias<"nop", (ORI R0, R0, 0)>;
24215ffd83dbSDimitry Andric
24220b57cec5SDimitry Andriclet PPC970_Unit = 1 in {  // FXU Operations.
24230b57cec5SDimitry Andriclet hasSideEffects = 0 in {
242406c3fb27SDimitry Andricdefm SRAWI : XForm_10rc<31, 824, (outs gprc:$RA), (ins gprc:$RST, u5imm:$RB),
242506c3fb27SDimitry Andric                        "srawi", "$RA, $RST, $RB", IIC_IntShift,
242606c3fb27SDimitry Andric                        [(set i32:$RA, (sra i32:$RST, (i32 imm:$RB)))]>,
2427bdd1243dSDimitry Andric                        SExt32To64;
242806c3fb27SDimitry Andricdefm CNTLZW : XForm_11r<31,  26, (outs gprc:$RA), (ins gprc:$RST),
242906c3fb27SDimitry Andric                        "cntlzw", "$RA, $RST", IIC_IntGeneral,
243006c3fb27SDimitry Andric                        [(set i32:$RA, (ctlz i32:$RST))]>, ZExt32To64;
243106c3fb27SDimitry Andricdefm CNTTZW : XForm_11r<31, 538, (outs gprc:$RA), (ins gprc:$RST),
243206c3fb27SDimitry Andric                        "cnttzw", "$RA, $RST", IIC_IntGeneral,
243306c3fb27SDimitry Andric                        [(set i32:$RA, (cttz i32:$RST))]>, Requires<[IsISA3_0]>,
2434bdd1243dSDimitry Andric                        ZExt32To64;
243506c3fb27SDimitry Andricdefm EXTSB  : XForm_11r<31, 954, (outs gprc:$RA), (ins gprc:$RST),
243606c3fb27SDimitry Andric                        "extsb", "$RA, $RST", IIC_IntSimple,
243706c3fb27SDimitry Andric                        [(set i32:$RA, (sext_inreg i32:$RST, i8))]>, SExt32To64;
243806c3fb27SDimitry Andricdefm EXTSH  : XForm_11r<31, 922, (outs gprc:$RA), (ins gprc:$RST),
243906c3fb27SDimitry Andric                        "extsh", "$RA, $RST", IIC_IntSimple,
244006c3fb27SDimitry Andric                        [(set i32:$RA, (sext_inreg i32:$RST, i16))]>, SExt32To64;
24410b57cec5SDimitry Andric
24420b57cec5SDimitry Andriclet isCommutable = 1 in
244306c3fb27SDimitry Andricdef CMPB : XForm_6<31, 508, (outs gprc:$RA), (ins gprc:$RST, gprc:$RB),
244406c3fb27SDimitry Andric                   "cmpb $RA, $RST, $RB", IIC_IntGeneral,
244506c3fb27SDimitry Andric                   [(set i32:$RA, (PPCcmpb i32:$RST, i32:$RB))]>;
24460b57cec5SDimitry Andric}
24470b57cec5SDimitry Andriclet isCompare = 1, hasSideEffects = 0 in {
244806c3fb27SDimitry Andric  def CMPW   : XForm_16_ext<31, 0, (outs crrc:$BF), (ins gprc:$RA, gprc:$RB),
244906c3fb27SDimitry Andric                            "cmpw $BF, $RA, $RB", IIC_IntCompare>;
245006c3fb27SDimitry Andric  def CMPLW  : XForm_16_ext<31, 32, (outs crrc:$BF), (ins gprc:$RA, gprc:$RB),
245106c3fb27SDimitry Andric                            "cmplw $BF, $RA, $RB", IIC_IntCompare>;
24520b57cec5SDimitry Andric}
24530b57cec5SDimitry Andric}
24540b57cec5SDimitry Andriclet PPC970_Unit = 3, Predicates = [HasFPU] in {  // FPU Operations.
2455e8d8bef9SDimitry Andriclet isCompare = 1, mayRaiseFPException = 1, hasSideEffects = 0 in {
245606c3fb27SDimitry Andric  def FCMPUS : XForm_17<63, 0, (outs crrc:$BF), (ins f4rc:$RA, f4rc:$RB),
245706c3fb27SDimitry Andric                        "fcmpu $BF, $RA, $RB", IIC_FPCompare>;
245806c3fb27SDimitry Andric  def FCMPOS : XForm_17<63, 32, (outs crrc:$BF), (ins f4rc:$RA, f4rc:$RB),
245906c3fb27SDimitry Andric                        "fcmpo $BF, $RA, $RB", IIC_FPCompare>;
2460e8d8bef9SDimitry Andric  let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
246106c3fb27SDimitry Andric    def FCMPUD : XForm_17<63, 0, (outs crrc:$BF), (ins f8rc:$RA, f8rc:$RB),
246206c3fb27SDimitry Andric                          "fcmpu $BF, $RA, $RB", IIC_FPCompare>;
246306c3fb27SDimitry Andric    def FCMPOD : XForm_17<63, 32, (outs crrc:$BF), (ins f8rc:$RA, f8rc:$RB),
246406c3fb27SDimitry Andric                          "fcmpo $BF, $RA, $RB", IIC_FPCompare>;
2465e8d8bef9SDimitry Andric  }
24660b57cec5SDimitry Andric}
24670b57cec5SDimitry Andric
246806c3fb27SDimitry Andricdef FTDIV: XForm_17<63, 128, (outs crrc:$BF), (ins f8rc:$RA, f8rc:$RB),
246906c3fb27SDimitry Andric                      "ftdiv $BF, $RA, $RB", IIC_FPCompare>;
247006c3fb27SDimitry Andricdef FTSQRT: XForm_17a<63, 160, (outs crrc:$BF), (ins f8rc:$RB),
247106c3fb27SDimitry Andric                      "ftsqrt $BF, $RB", IIC_FPCompare,
247206c3fb27SDimitry Andric                      [(set i32:$BF, (PPCftsqrt f64:$RB))]>;
24730b57cec5SDimitry Andric
2474e8d8bef9SDimitry Andriclet mayRaiseFPException = 1, hasSideEffects = 0 in {
24750b57cec5SDimitry Andric  let Interpretation64Bit = 1, isCodeGenOnly = 1 in
247606c3fb27SDimitry Andric  defm FRIND  : XForm_26r<63, 392, (outs f8rc:$RST), (ins f8rc:$RB),
247706c3fb27SDimitry Andric                          "frin", "$RST, $RB", IIC_FPGeneral,
247806c3fb27SDimitry Andric                          [(set f64:$RST, (any_fround f64:$RB))]>;
247906c3fb27SDimitry Andric  defm FRINS  : XForm_26r<63, 392, (outs f4rc:$RST), (ins f4rc:$RB),
248006c3fb27SDimitry Andric                          "frin", "$RST, $RB", IIC_FPGeneral,
248106c3fb27SDimitry Andric                          [(set f32:$RST, (any_fround f32:$RB))]>;
24820b57cec5SDimitry Andric
24830b57cec5SDimitry Andric  let Interpretation64Bit = 1, isCodeGenOnly = 1 in
248406c3fb27SDimitry Andric  defm FRIPD  : XForm_26r<63, 456, (outs f8rc:$RST), (ins f8rc:$RB),
248506c3fb27SDimitry Andric                          "frip", "$RST, $RB", IIC_FPGeneral,
248606c3fb27SDimitry Andric                          [(set f64:$RST, (any_fceil f64:$RB))]>;
248706c3fb27SDimitry Andric  defm FRIPS  : XForm_26r<63, 456, (outs f4rc:$RST), (ins f4rc:$RB),
248806c3fb27SDimitry Andric                          "frip", "$RST, $RB", IIC_FPGeneral,
248906c3fb27SDimitry Andric                          [(set f32:$RST, (any_fceil f32:$RB))]>;
24900b57cec5SDimitry Andric  let Interpretation64Bit = 1, isCodeGenOnly = 1 in
249106c3fb27SDimitry Andric  defm FRIZD  : XForm_26r<63, 424, (outs f8rc:$RST), (ins f8rc:$RB),
249206c3fb27SDimitry Andric                          "friz", "$RST, $RB", IIC_FPGeneral,
249306c3fb27SDimitry Andric                          [(set f64:$RST, (any_ftrunc f64:$RB))]>;
249406c3fb27SDimitry Andric  defm FRIZS  : XForm_26r<63, 424, (outs f4rc:$RST), (ins f4rc:$RB),
249506c3fb27SDimitry Andric                          "friz", "$RST, $RB", IIC_FPGeneral,
249606c3fb27SDimitry Andric                          [(set f32:$RST, (any_ftrunc f32:$RB))]>;
24970b57cec5SDimitry Andric  let Interpretation64Bit = 1, isCodeGenOnly = 1 in
249806c3fb27SDimitry Andric  defm FRIMD  : XForm_26r<63, 488, (outs f8rc:$RST), (ins f8rc:$RB),
249906c3fb27SDimitry Andric                          "frim", "$RST, $RB", IIC_FPGeneral,
250006c3fb27SDimitry Andric                          [(set f64:$RST, (any_ffloor f64:$RB))]>;
250106c3fb27SDimitry Andric  defm FRIMS  : XForm_26r<63, 488, (outs f4rc:$RST), (ins f4rc:$RB),
250206c3fb27SDimitry Andric                          "frim", "$RST, $RB", IIC_FPGeneral,
250306c3fb27SDimitry Andric                          [(set f32:$RST, (any_ffloor f32:$RB))]>;
2504e8d8bef9SDimitry Andric}
2505e8d8bef9SDimitry Andric
2506e8d8bef9SDimitry Andriclet Uses = [RM], mayRaiseFPException = 1, hasSideEffects = 0 in {
250706c3fb27SDimitry Andric  defm FCTIW  : XForm_26r<63, 14, (outs f8rc:$RST), (ins f8rc:$RB),
250806c3fb27SDimitry Andric                          "fctiw", "$RST, $RB", IIC_FPGeneral,
2509e8d8bef9SDimitry Andric                          []>;
251006c3fb27SDimitry Andric  defm FCTIWU  : XForm_26r<63, 142, (outs f8rc:$RST), (ins f8rc:$RB),
251106c3fb27SDimitry Andric                          "fctiwu", "$RST, $RB", IIC_FPGeneral,
2512e8d8bef9SDimitry Andric                          []>;
251306c3fb27SDimitry Andric  defm FCTIWZ : XForm_26r<63, 15, (outs f8rc:$RST), (ins f8rc:$RB),
251406c3fb27SDimitry Andric                          "fctiwz", "$RST, $RB", IIC_FPGeneral,
251506c3fb27SDimitry Andric                          [(set f64:$RST, (PPCany_fctiwz f64:$RB))]>;
2516e8d8bef9SDimitry Andric
251706c3fb27SDimitry Andric  defm FRSP   : XForm_26r<63, 12, (outs f4rc:$RST), (ins f8rc:$RB),
251806c3fb27SDimitry Andric                          "frsp", "$RST, $RB", IIC_FPGeneral,
251906c3fb27SDimitry Andric                          [(set f32:$RST, (any_fpround f64:$RB))]>;
25200b57cec5SDimitry Andric
252106c3fb27SDimitry Andric  defm FSQRT  : XForm_26r<63, 22, (outs f8rc:$RST), (ins f8rc:$RB),
252206c3fb27SDimitry Andric                          "fsqrt", "$RST, $RB", IIC_FPSqrtD,
252306c3fb27SDimitry Andric                          [(set f64:$RST, (any_fsqrt f64:$RB))]>;
252406c3fb27SDimitry Andric  defm FSQRTS : XForm_26r<59, 22, (outs f4rc:$RST), (ins f4rc:$RB),
252506c3fb27SDimitry Andric                          "fsqrts", "$RST, $RB", IIC_FPSqrtS,
252606c3fb27SDimitry Andric                          [(set f32:$RST, (any_fsqrt f32:$RB))]>;
25270b57cec5SDimitry Andric}
25280b57cec5SDimitry Andric}
2529e8d8bef9SDimitry Andric
2530e8d8bef9SDimitry Andricdef : Pat<(PPCfsqrt f64:$frA), (FSQRT $frA)>;
25310b57cec5SDimitry Andric
25320b57cec5SDimitry Andric/// Note that FMR is defined as pseudo-ops on the PPC970 because they are
25330b57cec5SDimitry Andric/// often coalesced away and we don't want the dispatch group builder to think
25340b57cec5SDimitry Andric/// that they will fill slots (which could cause the load of a LSU reject to
25350b57cec5SDimitry Andric/// sneak into a d-group with a store).
25360b57cec5SDimitry Andriclet hasSideEffects = 0, Predicates = [HasFPU] in
253706c3fb27SDimitry Andricdefm FMR   : XForm_26r<63, 72, (outs f4rc:$RST), (ins f4rc:$RB),
253806c3fb27SDimitry Andric                       "fmr", "$RST, $RB", IIC_FPGeneral,
253906c3fb27SDimitry Andric                       []>,  // (set f32:$RST, f32:$RB)
25400b57cec5SDimitry Andric                       PPC970_Unit_Pseudo;
25410b57cec5SDimitry Andric
25420b57cec5SDimitry Andriclet PPC970_Unit = 3, hasSideEffects = 0, Predicates = [HasFPU] in {  // FPU Operations.
25430b57cec5SDimitry Andric// These are artificially split into two different forms, for 4/8 byte FP.
254406c3fb27SDimitry Andricdefm FABSS  : XForm_26r<63, 264, (outs f4rc:$RST), (ins f4rc:$RB),
254506c3fb27SDimitry Andric                        "fabs", "$RST, $RB", IIC_FPGeneral,
254606c3fb27SDimitry Andric                        [(set f32:$RST, (fabs f32:$RB))]>;
25470b57cec5SDimitry Andriclet Interpretation64Bit = 1, isCodeGenOnly = 1 in
254806c3fb27SDimitry Andricdefm FABSD  : XForm_26r<63, 264, (outs f8rc:$RST), (ins f8rc:$RB),
254906c3fb27SDimitry Andric                        "fabs", "$RST, $RB", IIC_FPGeneral,
255006c3fb27SDimitry Andric                        [(set f64:$RST, (fabs f64:$RB))]>;
255106c3fb27SDimitry Andricdefm FNABSS : XForm_26r<63, 136, (outs f4rc:$RST), (ins f4rc:$RB),
255206c3fb27SDimitry Andric                        "fnabs", "$RST, $RB", IIC_FPGeneral,
255306c3fb27SDimitry Andric                        [(set f32:$RST, (fneg (fabs f32:$RB)))]>;
25540b57cec5SDimitry Andriclet Interpretation64Bit = 1, isCodeGenOnly = 1 in
255506c3fb27SDimitry Andricdefm FNABSD : XForm_26r<63, 136, (outs f8rc:$RST), (ins f8rc:$RB),
255606c3fb27SDimitry Andric                        "fnabs", "$RST, $RB", IIC_FPGeneral,
255706c3fb27SDimitry Andric                        [(set f64:$RST, (fneg (fabs f64:$RB)))]>;
255806c3fb27SDimitry Andricdefm FNEGS  : XForm_26r<63, 40, (outs f4rc:$RST), (ins f4rc:$RB),
255906c3fb27SDimitry Andric                        "fneg", "$RST, $RB", IIC_FPGeneral,
256006c3fb27SDimitry Andric                        [(set f32:$RST, (fneg f32:$RB))]>;
25610b57cec5SDimitry Andriclet Interpretation64Bit = 1, isCodeGenOnly = 1 in
256206c3fb27SDimitry Andricdefm FNEGD  : XForm_26r<63, 40, (outs f8rc:$RST), (ins f8rc:$RB),
256306c3fb27SDimitry Andric                        "fneg", "$RST, $RB", IIC_FPGeneral,
256406c3fb27SDimitry Andric                        [(set f64:$RST, (fneg f64:$RB))]>;
25650b57cec5SDimitry Andric
256606c3fb27SDimitry Andricdefm FCPSGNS : XForm_28r<63, 8, (outs f4rc:$RST), (ins f4rc:$RA, f4rc:$RB),
256706c3fb27SDimitry Andric                        "fcpsgn", "$RST, $RA, $RB", IIC_FPGeneral,
256806c3fb27SDimitry Andric                        [(set f32:$RST, (fcopysign f32:$RB, f32:$RA))]>;
25690b57cec5SDimitry Andriclet Interpretation64Bit = 1, isCodeGenOnly = 1 in
257006c3fb27SDimitry Andricdefm FCPSGND : XForm_28r<63, 8, (outs f8rc:$RST), (ins f8rc:$RA, f8rc:$RB),
257106c3fb27SDimitry Andric                        "fcpsgn", "$RST, $RA, $RB", IIC_FPGeneral,
257206c3fb27SDimitry Andric                        [(set f64:$RST, (fcopysign f64:$RB, f64:$RA))]>;
25730b57cec5SDimitry Andric
25740b57cec5SDimitry Andric// Reciprocal estimates.
2575e8d8bef9SDimitry Andriclet mayRaiseFPException = 1 in {
257606c3fb27SDimitry Andricdefm FRE      : XForm_26r<63, 24, (outs f8rc:$RST), (ins f8rc:$RB),
257706c3fb27SDimitry Andric                          "fre", "$RST, $RB", IIC_FPGeneral,
257806c3fb27SDimitry Andric                          [(set f64:$RST, (PPCfre f64:$RB))]>;
257906c3fb27SDimitry Andricdefm FRES     : XForm_26r<59, 24, (outs f4rc:$RST), (ins f4rc:$RB),
258006c3fb27SDimitry Andric                          "fres", "$RST, $RB", IIC_FPGeneral,
258106c3fb27SDimitry Andric                          [(set f32:$RST, (PPCfre f32:$RB))]>;
258206c3fb27SDimitry Andricdefm FRSQRTE  : XForm_26r<63, 26, (outs f8rc:$RST), (ins f8rc:$RB),
258306c3fb27SDimitry Andric                          "frsqrte", "$RST, $RB", IIC_FPGeneral,
258406c3fb27SDimitry Andric                          [(set f64:$RST, (PPCfrsqrte f64:$RB))]>;
258506c3fb27SDimitry Andricdefm FRSQRTES : XForm_26r<59, 26, (outs f4rc:$RST), (ins f4rc:$RB),
258606c3fb27SDimitry Andric                          "frsqrtes", "$RST, $RB", IIC_FPGeneral,
258706c3fb27SDimitry Andric                          [(set f32:$RST, (PPCfrsqrte f32:$RB))]>;
25880b57cec5SDimitry Andric}
2589e8d8bef9SDimitry Andric}
25900b57cec5SDimitry Andric
25910b57cec5SDimitry Andric// XL-Form instructions.  condition register logical ops.
25920b57cec5SDimitry Andric//
25930b57cec5SDimitry Andriclet hasSideEffects = 0 in
25940b57cec5SDimitry Andricdef MCRF   : XLForm_3<19, 0, (outs crrc:$BF), (ins crrc:$BFA),
25950b57cec5SDimitry Andric                      "mcrf $BF, $BFA", IIC_BrMCR>,
25960b57cec5SDimitry Andric             PPC970_DGroup_First, PPC970_Unit_CRU;
25970b57cec5SDimitry Andric
25980b57cec5SDimitry Andric// FIXME: According to the ISA (section 2.5.1 of version 2.06), the
25990b57cec5SDimitry Andric// condition-register logical instructions have preferred forms. Specifically,
26000b57cec5SDimitry Andric// it is preferred that the bit specified by the BT field be in the same
26010b57cec5SDimitry Andric// condition register as that specified by the bit BB. We might want to account
26020b57cec5SDimitry Andric// for this via hinting the register allocator and anti-dep breakers, or we
26030b57cec5SDimitry Andric// could constrain the register class to force this constraint and then loosen
26040b57cec5SDimitry Andric// it during register allocation via convertToThreeAddress or some similar
26050b57cec5SDimitry Andric// mechanism.
26060b57cec5SDimitry Andric
26070b57cec5SDimitry Andriclet isCommutable = 1 in {
26080b57cec5SDimitry Andricdef CRAND  : XLForm_1<19, 257, (outs crbitrc:$CRD),
26090b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26100b57cec5SDimitry Andric                      "crand $CRD, $CRA, $CRB", IIC_BrCR,
26110b57cec5SDimitry Andric                      [(set i1:$CRD, (and i1:$CRA, i1:$CRB))]>;
26120b57cec5SDimitry Andric
26130b57cec5SDimitry Andricdef CRNAND : XLForm_1<19, 225, (outs crbitrc:$CRD),
26140b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26150b57cec5SDimitry Andric                      "crnand $CRD, $CRA, $CRB", IIC_BrCR,
26160b57cec5SDimitry Andric                      [(set i1:$CRD, (not (and i1:$CRA, i1:$CRB)))]>;
26170b57cec5SDimitry Andric
26180b57cec5SDimitry Andricdef CROR   : XLForm_1<19, 449, (outs crbitrc:$CRD),
26190b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26200b57cec5SDimitry Andric                      "cror $CRD, $CRA, $CRB", IIC_BrCR,
26210b57cec5SDimitry Andric                      [(set i1:$CRD, (or i1:$CRA, i1:$CRB))]>;
26220b57cec5SDimitry Andric
26230b57cec5SDimitry Andricdef CRXOR  : XLForm_1<19, 193, (outs crbitrc:$CRD),
26240b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26250b57cec5SDimitry Andric                      "crxor $CRD, $CRA, $CRB", IIC_BrCR,
26260b57cec5SDimitry Andric                      [(set i1:$CRD, (xor i1:$CRA, i1:$CRB))]>;
26270b57cec5SDimitry Andric
26280b57cec5SDimitry Andricdef CRNOR  : XLForm_1<19, 33, (outs crbitrc:$CRD),
26290b57cec5SDimitry Andric                              (ins crbitrc:$CRA, crbitrc:$CRB),
26300b57cec5SDimitry Andric                      "crnor $CRD, $CRA, $CRB", IIC_BrCR,
26310b57cec5SDimitry Andric                      [(set i1:$CRD, (not (or i1:$CRA, i1:$CRB)))]>;
26320b57cec5SDimitry Andricdef CREQV  : XLForm_1<19, 289, (outs crbitrc:$CRD),
26330b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26340b57cec5SDimitry Andric                      "creqv $CRD, $CRA, $CRB", IIC_BrCR,
26350b57cec5SDimitry Andric                      [(set i1:$CRD, (not (xor i1:$CRA, i1:$CRB)))]>;
26360b57cec5SDimitry Andric} // isCommutable
26370b57cec5SDimitry Andric
2638bdd1243dSDimitry Andriclet isCodeGenOnly = 1 in
2639bdd1243dSDimitry Andricdef CRNOT  : XLForm_1s<19, 33, (outs crbitrc:$CRD), (ins crbitrc:$CRA),
2640bdd1243dSDimitry Andric                       "crnot $CRD, $CRA", IIC_BrCR,
2641bdd1243dSDimitry Andric                       [(set i1:$CRD, (not i1:$CRA))]>;
2642bdd1243dSDimitry Andric
26430b57cec5SDimitry Andricdef CRANDC : XLForm_1<19, 129, (outs crbitrc:$CRD),
26440b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26450b57cec5SDimitry Andric                      "crandc $CRD, $CRA, $CRB", IIC_BrCR,
26460b57cec5SDimitry Andric                      [(set i1:$CRD, (and i1:$CRA, (not i1:$CRB)))]>;
26470b57cec5SDimitry Andric
26480b57cec5SDimitry Andricdef CRORC  : XLForm_1<19, 417, (outs crbitrc:$CRD),
26490b57cec5SDimitry Andric                               (ins crbitrc:$CRA, crbitrc:$CRB),
26500b57cec5SDimitry Andric                      "crorc $CRD, $CRA, $CRB", IIC_BrCR,
26510b57cec5SDimitry Andric                      [(set i1:$CRD, (or i1:$CRA, (not i1:$CRB)))]>;
26520b57cec5SDimitry Andric
26530b57cec5SDimitry Andriclet isCodeGenOnly = 1 in {
26540b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in {
265506c3fb27SDimitry Andricdef CRSET  : XLForm_1_ext<19, 289, (outs crbitrc:$CRD), (ins),
265606c3fb27SDimitry Andric              "creqv $CRD, $CRD, $CRD", IIC_BrCR,
265706c3fb27SDimitry Andric              [(set i1:$CRD, 1)]>;
26580b57cec5SDimitry Andric
265906c3fb27SDimitry Andricdef CRUNSET: XLForm_1_ext<19, 193, (outs crbitrc:$CRD), (ins),
266006c3fb27SDimitry Andric              "crxor $CRD, $CRD, $CRD", IIC_BrCR,
266106c3fb27SDimitry Andric              [(set i1:$CRD, 0)]>;
26620b57cec5SDimitry Andric}
26630b57cec5SDimitry Andric
26640b57cec5SDimitry Andriclet Defs = [CR1EQ], CRD = 6 in {
26650b57cec5SDimitry Andricdef CR6SET  : XLForm_1_ext<19, 289, (outs), (ins),
26660b57cec5SDimitry Andric              "creqv 6, 6, 6", IIC_BrCR,
26670b57cec5SDimitry Andric              [(PPCcr6set)]>;
26680b57cec5SDimitry Andric
26690b57cec5SDimitry Andricdef CR6UNSET: XLForm_1_ext<19, 193, (outs), (ins),
26700b57cec5SDimitry Andric              "crxor 6, 6, 6", IIC_BrCR,
26710b57cec5SDimitry Andric              [(PPCcr6unset)]>;
26720b57cec5SDimitry Andric}
26730b57cec5SDimitry Andric}
26740b57cec5SDimitry Andric
26750b57cec5SDimitry Andric// XFX-Form instructions.  Instructions that deal with SPRs.
26760b57cec5SDimitry Andric//
26770b57cec5SDimitry Andric
267806c3fb27SDimitry Andricdef MFSPR : XFXForm_1<31, 339, (outs gprc:$RST), (ins i32imm:$SPR),
267906c3fb27SDimitry Andric                      "mfspr $RST, $SPR", IIC_SprMFSPR>;
268006c3fb27SDimitry Andricdef MTSPR : XFXForm_1<31, 467, (outs), (ins i32imm:$SPR, gprc:$RST),
268106c3fb27SDimitry Andric                      "mtspr $SPR, $RST", IIC_SprMTSPR>;
26820b57cec5SDimitry Andric
268306c3fb27SDimitry Andricdef MFTB : XFXForm_1<31, 371, (outs gprc:$RST), (ins i32imm:$SPR),
268406c3fb27SDimitry Andric                     "mftb $RST, $SPR", IIC_SprMFTB>;
26850b57cec5SDimitry Andric
268606c3fb27SDimitry Andricdef MFPMR : XFXForm_1<31, 334, (outs gprc:$RST), (ins i32imm:$SPR),
268706c3fb27SDimitry Andric                     "mfpmr $RST, $SPR", IIC_SprMFPMR>;
26880b57cec5SDimitry Andric
268906c3fb27SDimitry Andricdef MTPMR : XFXForm_1<31, 462, (outs), (ins i32imm:$SPR, gprc:$RST),
269006c3fb27SDimitry Andric                     "mtpmr $SPR, $RST", IIC_SprMTPMR>;
26910b57cec5SDimitry Andric
26920b57cec5SDimitry Andric
26930b57cec5SDimitry Andric// A pseudo-instruction used to implement the read of the 64-bit cycle counter
26940b57cec5SDimitry Andric// on a 32-bit target.
26950b57cec5SDimitry Andriclet hasSideEffects = 1 in
26960b57cec5SDimitry Andricdef ReadTB : PPCCustomInserterPseudo<(outs gprc:$lo, gprc:$hi), (ins),
26970b57cec5SDimitry Andric                    "#ReadTB", []>;
26980b57cec5SDimitry Andric
26990b57cec5SDimitry Andriclet Uses = [CTR] in {
270006c3fb27SDimitry Andricdef MFCTR : XFXForm_1_ext<31, 339, 9, (outs gprc:$RST), (ins),
270106c3fb27SDimitry Andric                          "mfctr $RST", IIC_SprMFSPR>,
27020b57cec5SDimitry Andric            PPC970_DGroup_First, PPC970_Unit_FXU;
27030b57cec5SDimitry Andric}
270406c3fb27SDimitry Andriclet Defs = [CTR], Pattern = [(PPCmtctr i32:$RST)] in {
270506c3fb27SDimitry Andricdef MTCTR : XFXForm_1_ext<31, 467, 9, (outs), (ins gprc:$RST),
270606c3fb27SDimitry Andric                          "mtctr $RST", IIC_SprMTSPR>,
27070b57cec5SDimitry Andric            PPC970_DGroup_First, PPC970_Unit_FXU;
27080b57cec5SDimitry Andric}
2709bdd1243dSDimitry Andriclet hasSideEffects = 1, isCodeGenOnly = 1, isNotDuplicable = 1, Defs = [CTR] in {
271006c3fb27SDimitry Andriclet Pattern = [(int_set_loop_iterations i32:$RST)] in
271106c3fb27SDimitry Andricdef MTCTRloop : XFXForm_1_ext<31, 467, 9, (outs), (ins gprc:$RST),
271206c3fb27SDimitry Andric                              "mtctr $RST", IIC_SprMTSPR>,
27130b57cec5SDimitry Andric                PPC970_DGroup_First, PPC970_Unit_FXU;
27140b57cec5SDimitry Andric}
27150b57cec5SDimitry Andric
2716bdd1243dSDimitry Andriclet hasSideEffects = 1, hasNoSchedulingInfo = 1, isNotDuplicable = 1, Uses = [CTR], Defs = [CTR] in
2717bdd1243dSDimitry Andricdef DecreaseCTRloop : PPCEmitTimePseudo<(outs crbitrc:$rT), (ins i32imm:$stride),
2718bdd1243dSDimitry Andric                                       "#DecreaseCTRloop", [(set i1:$rT, (int_loop_decrement (i32 imm:$stride)))]>;
271981ad6265SDimitry Andric
2720480093f4SDimitry Andriclet hasSideEffects = 0 in {
27210b57cec5SDimitry Andriclet Defs = [LR] in {
272206c3fb27SDimitry Andricdef MTLR  : XFXForm_1_ext<31, 467, 8, (outs), (ins gprc:$RST),
272306c3fb27SDimitry Andric                          "mtlr $RST", IIC_SprMTSPR>,
27240b57cec5SDimitry Andric            PPC970_DGroup_First, PPC970_Unit_FXU;
27250b57cec5SDimitry Andric}
27260b57cec5SDimitry Andriclet Uses = [LR] in {
272706c3fb27SDimitry Andricdef MFLR  : XFXForm_1_ext<31, 339, 8, (outs gprc:$RST), (ins),
272806c3fb27SDimitry Andric                          "mflr $RST", IIC_SprMFSPR>,
27290b57cec5SDimitry Andric            PPC970_DGroup_First, PPC970_Unit_FXU;
27300b57cec5SDimitry Andric}
2731480093f4SDimitry Andric}
27320b57cec5SDimitry Andric
273381ad6265SDimitry Andriclet hasSideEffects = 1 in {
273406c3fb27SDimitry Andric  def MTUDSCR : XFXForm_1_ext<31, 467, 3, (outs), (ins gprc:$RST),
273506c3fb27SDimitry Andric                              "mtspr 3, $RST", IIC_SprMTSPR>,
273681ad6265SDimitry Andric                PPC970_DGroup_Single, PPC970_Unit_FXU;
273706c3fb27SDimitry Andric  def MFUDSCR : XFXForm_1_ext<31, 339, 3, (outs gprc:$RST), (ins),
273806c3fb27SDimitry Andric                              "mfspr $RST, 3", IIC_SprMFSPR>,
273981ad6265SDimitry Andric                PPC970_DGroup_First, PPC970_Unit_FXU;
274081ad6265SDimitry Andric}
274181ad6265SDimitry Andric
274281ad6265SDimitry Andric// Disable these alias on AIX since they are not supported.
274381ad6265SDimitry Andriclet Predicates = [ModernAs] in {
274481ad6265SDimitry Andric// Aliases for moving to/from dscr to mtspr/mfspr
274581ad6265SDimitry Andricdef : InstAlias<"mtudscr $Rx", (MTUDSCR gprc:$Rx)>;
274681ad6265SDimitry Andricdef : InstAlias<"mfudscr $Rx", (MFUDSCR gprc:$Rx)>;
274781ad6265SDimitry Andric}
274881ad6265SDimitry Andric
27490b57cec5SDimitry Andriclet isCodeGenOnly = 1 in {
27500b57cec5SDimitry Andric  // Move to/from VRSAVE: despite being a SPR, the VRSAVE register is renamed
27510b57cec5SDimitry Andric  // like a GPR on the PPC970.  As such, copies in and out have the same
27520b57cec5SDimitry Andric  // performance characteristics as an OR instruction.
275306c3fb27SDimitry Andric  def MTVRSAVE : XFXForm_1_ext<31, 467, 256, (outs), (ins gprc:$RST),
275406c3fb27SDimitry Andric                               "mtspr 256, $RST", IIC_IntGeneral>,
27550b57cec5SDimitry Andric                 PPC970_DGroup_Single, PPC970_Unit_FXU;
275606c3fb27SDimitry Andric  def MFVRSAVE : XFXForm_1_ext<31, 339, 256, (outs gprc:$RST), (ins),
275706c3fb27SDimitry Andric                               "mfspr $RST, 256", IIC_IntGeneral>,
27580b57cec5SDimitry Andric                 PPC970_DGroup_First, PPC970_Unit_FXU;
27590b57cec5SDimitry Andric
276006c3fb27SDimitry Andric  def MTVRSAVEv : XFXForm_1_ext<31, 467, 256,
276106c3fb27SDimitry Andric                                (outs VRSAVERC:$SPR), (ins gprc:$RST),
276206c3fb27SDimitry Andric                                "mtspr 256, $RST", IIC_IntGeneral>,
27630b57cec5SDimitry Andric                  PPC970_DGroup_Single, PPC970_Unit_FXU;
276406c3fb27SDimitry Andric  def MFVRSAVEv : XFXForm_1_ext<31, 339, 256, (outs gprc:$RST),
276506c3fb27SDimitry Andric                                (ins VRSAVERC:$SPR),
276606c3fb27SDimitry Andric                                "mfspr $RST, 256", IIC_IntGeneral>,
27670b57cec5SDimitry Andric                  PPC970_DGroup_First, PPC970_Unit_FXU;
27680b57cec5SDimitry Andric}
27690b57cec5SDimitry Andric
27700b57cec5SDimitry Andric// Aliases for mtvrsave/mfvrsave to mfspr/mtspr.
27710b57cec5SDimitry Andricdef : InstAlias<"mtvrsave $rS", (MTVRSAVE gprc:$rS)>;
27720b57cec5SDimitry Andricdef : InstAlias<"mfvrsave $rS", (MFVRSAVE gprc:$rS)>;
27730b57cec5SDimitry Andric
27740b57cec5SDimitry Andriclet hasSideEffects = 0 in {
27750b57cec5SDimitry Andric// mtocrf's input needs to be prepared by shifting by an amount dependent
27760b57cec5SDimitry Andric// on the cr register selected. Thus, post-ra anti-dep breaking must not
27770b57cec5SDimitry Andric// later change that register assignment.
27780b57cec5SDimitry Andriclet hasExtraDefRegAllocReq = 1 in {
277906c3fb27SDimitry Andricdef MTOCRF: XFXForm_5a<31, 144, (outs crbitm:$FXM), (ins gprc:$RST),
278006c3fb27SDimitry Andric                       "mtocrf $FXM, $RST", IIC_BrMCRX>,
27810b57cec5SDimitry Andric            PPC970_DGroup_First, PPC970_Unit_CRU;
27820b57cec5SDimitry Andric
27830b57cec5SDimitry Andric// Similarly to mtocrf, the mask for mtcrf must be prepared in a way that
27840b57cec5SDimitry Andric// is dependent on the cr fields being set.
278506c3fb27SDimitry Andricdef MTCRF : XFXForm_5<31, 144, (outs), (ins i32imm:$FXM, gprc:$RST),
278606c3fb27SDimitry Andric                      "mtcrf $FXM, $RST", IIC_BrMCRX>,
27870b57cec5SDimitry Andric            PPC970_MicroCode, PPC970_Unit_CRU;
27880b57cec5SDimitry Andric} // hasExtraDefRegAllocReq = 1
27890b57cec5SDimitry Andric
27900b57cec5SDimitry Andric// mfocrf's input needs to be prepared by shifting by an amount dependent
27910b57cec5SDimitry Andric// on the cr register selected. Thus, post-ra anti-dep breaking must not
27920b57cec5SDimitry Andric// later change that register assignment.
27930b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1 in {
279406c3fb27SDimitry Andricdef MFOCRF: XFXForm_5a<31, 19, (outs gprc:$RST), (ins crbitm:$FXM),
279506c3fb27SDimitry Andric                       "mfocrf $RST, $FXM", IIC_SprMFCRF>,
27960b57cec5SDimitry Andric            PPC970_DGroup_First, PPC970_Unit_CRU;
27970b57cec5SDimitry Andric
27980b57cec5SDimitry Andric// Similarly to mfocrf, the mask for mfcrf must be prepared in a way that
27990b57cec5SDimitry Andric// is dependent on the cr fields being copied.
280006c3fb27SDimitry Andricdef MFCR : XFXForm_3<31, 19, (outs gprc:$RT), (ins),
280106c3fb27SDimitry Andric                     "mfcr $RT", IIC_SprMFCR>,
28020b57cec5SDimitry Andric                     PPC970_MicroCode, PPC970_Unit_CRU;
28030b57cec5SDimitry Andric} // hasExtraSrcRegAllocReq = 1
28040b57cec5SDimitry Andric
28050b57cec5SDimitry Andricdef MCRXRX : X_BF3<31, 576, (outs crrc:$BF), (ins),
28060b57cec5SDimitry Andric                   "mcrxrx $BF", IIC_BrMCRX>, Requires<[IsISA3_0]>;
28070b57cec5SDimitry Andric} // hasSideEffects = 0
28080b57cec5SDimitry Andric
28095ffd83dbSDimitry Andricdef : InstAlias<"mtcr $rA", (MTCRF 255, gprc:$rA)>;
28105ffd83dbSDimitry Andric
28110b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
28120b57cec5SDimitry Andric// Custom inserter instruction to perform FADD in round-to-zero mode.
2813e8d8bef9SDimitry Andriclet Uses = [RM], mayRaiseFPException = 1 in {
28140b57cec5SDimitry Andric  def FADDrtz: PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB), "",
2815e8d8bef9SDimitry Andric                      [(set f64:$FRT, (PPCany_faddrtz f64:$FRA, f64:$FRB))]>;
28160b57cec5SDimitry Andric}
28170b57cec5SDimitry Andric
28180b57cec5SDimitry Andric// The above pseudo gets expanded to make use of the following instructions
28190b57cec5SDimitry Andric// to manipulate FPSCR.  Note that FPSCR is not modeled at the DAG level.
2820e8d8bef9SDimitry Andric
2821e8d8bef9SDimitry Andric// When FM is 30/31, we are setting the 62/63 bit of FPSCR, the implicit-def
2822e8d8bef9SDimitry Andric// RM should be set.
2823fe6060f1SDimitry Andriclet hasSideEffects = 1, Defs = [RM] in {
28240b57cec5SDimitry Andricdef MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
2825fe6060f1SDimitry Andric                      "mtfsb0 $FM", IIC_IntMTFSB0,
2826fe6060f1SDimitry Andric                      [(int_ppc_mtfsb0 timm:$FM)]>,
28270b57cec5SDimitry Andric             PPC970_DGroup_Single, PPC970_Unit_FPU;
28280b57cec5SDimitry Andricdef MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
2829fe6060f1SDimitry Andric                      "mtfsb1 $FM", IIC_IntMTFSB0,
2830fe6060f1SDimitry Andric                      [(int_ppc_mtfsb1 timm:$FM)]>,
28310b57cec5SDimitry Andric             PPC970_DGroup_Single, PPC970_Unit_FPU;
2832fe6060f1SDimitry Andric}
2833e8d8bef9SDimitry Andric
2834349cc55cSDimitry Andriclet Defs = [RM], hasSideEffects = 1 in {
28350b57cec5SDimitry Andric  let isCodeGenOnly = 1 in
283606c3fb27SDimitry Andric  def MTFSFb  : XFLForm<63, 711, (outs), (ins i32imm:$FM, f8rc:$RT),
283706c3fb27SDimitry Andric                        "mtfsf $FM, $RT", IIC_IntMTFSB0,
283806c3fb27SDimitry Andric                        [(int_ppc_mtfsf timm:$FM, f64:$RT)]>,
28390b57cec5SDimitry Andric                PPC970_DGroup_Single, PPC970_Unit_FPU;
28400b57cec5SDimitry Andric}
2841349cc55cSDimitry Andriclet Uses = [RM], hasSideEffects = 1 in {
284206c3fb27SDimitry Andric  def MFFS   : XForm_42<63, 583, (outs f8rc:$RST), (ins),
284306c3fb27SDimitry Andric                         "mffs $RST", IIC_IntMFFS,
284406c3fb27SDimitry Andric                         [(set f64:$RST, (PPCmffs))]>,
28450b57cec5SDimitry Andric               PPC970_DGroup_Single, PPC970_Unit_FPU;
28460b57cec5SDimitry Andric
28470b57cec5SDimitry Andric  let Defs = [CR1] in
284806c3fb27SDimitry Andric  def MFFS_rec : XForm_42<63, 583, (outs f8rc:$RST), (ins),
284906c3fb27SDimitry Andric                      "mffs. $RST", IIC_IntMFFS, []>, isRecordForm;
28500b57cec5SDimitry Andric
285106c3fb27SDimitry Andric  def MFFSCE : X_FRT5_XO2_XO3_XO10<63, 0, 1, 583, (outs f8rc:$RST), (ins),
285206c3fb27SDimitry Andric                                  "mffsce $RST", IIC_IntMFFS, []>,
28530b57cec5SDimitry Andric               PPC970_DGroup_Single, PPC970_Unit_FPU;
28540b57cec5SDimitry Andric
285506c3fb27SDimitry Andric  def MFFSCDRN : X_FRT5_XO2_XO3_FRB5_XO10<63, 2, 4, 583, (outs f8rc:$RST),
285606c3fb27SDimitry Andric                                         (ins f8rc:$FRB), "mffscdrn $RST, $FRB",
28570b57cec5SDimitry Andric                                         IIC_IntMFFS, []>,
28580b57cec5SDimitry Andric                 PPC970_DGroup_Single, PPC970_Unit_FPU;
28590b57cec5SDimitry Andric
286006c3fb27SDimitry Andric  def MFFSCDRNI : X_FRT5_XO2_XO3_DRM3_XO10<63, 2, 5, 583, (outs f8rc:$RST),
28610b57cec5SDimitry Andric                                          (ins u3imm:$DRM),
286206c3fb27SDimitry Andric                                          "mffscdrni $RST, $DRM",
28630b57cec5SDimitry Andric                                          IIC_IntMFFS, []>,
28640b57cec5SDimitry Andric                  PPC970_DGroup_Single, PPC970_Unit_FPU;
28650b57cec5SDimitry Andric
286606c3fb27SDimitry Andric  def MFFSCRN : X_FRT5_XO2_XO3_FRB5_XO10<63, 2, 6, 583, (outs f8rc:$RST),
286706c3fb27SDimitry Andric                                        (ins f8rc:$FRB), "mffscrn $RST, $FRB",
28680b57cec5SDimitry Andric                                        IIC_IntMFFS, []>,
28690b57cec5SDimitry Andric                PPC970_DGroup_Single, PPC970_Unit_FPU;
28700b57cec5SDimitry Andric
287106c3fb27SDimitry Andric  def MFFSCRNI : X_FRT5_XO2_XO3_RM2_X10<63, 2, 7, 583, (outs f8rc:$RST),
287206c3fb27SDimitry Andric                                       (ins u2imm:$RM), "mffscrni $RST, $RM",
28730b57cec5SDimitry Andric                                       IIC_IntMFFS, []>,
28740b57cec5SDimitry Andric                 PPC970_DGroup_Single, PPC970_Unit_FPU;
28750b57cec5SDimitry Andric
287606c3fb27SDimitry Andric  def MFFSL  : X_FRT5_XO2_XO3_XO10<63, 3, 0, 583, (outs f8rc:$RST), (ins),
287706c3fb27SDimitry Andric                                  "mffsl $RST", IIC_IntMFFS, []>,
28780b57cec5SDimitry Andric               PPC970_DGroup_Single, PPC970_Unit_FPU;
28790b57cec5SDimitry Andric}
28800b57cec5SDimitry Andric}
28810b57cec5SDimitry Andric
28820b57cec5SDimitry Andriclet Predicates = [IsISA3_0] in {
288306c3fb27SDimitry Andricdef MODSW : XForm_8<31, 779, (outs gprc:$RST), (ins gprc:$RA, gprc:$RB),
288406c3fb27SDimitry Andric                        "modsw $RST, $RA, $RB", IIC_IntDivW,
288506c3fb27SDimitry Andric                        [(set i32:$RST, (srem i32:$RA, i32:$RB))]>;
288606c3fb27SDimitry Andricdef MODUW : XForm_8<31, 267, (outs gprc:$RST), (ins gprc:$RA, gprc:$RB),
288706c3fb27SDimitry Andric                        "moduw $RST, $RA, $RB", IIC_IntDivW,
288806c3fb27SDimitry Andric                        [(set i32:$RST, (urem i32:$RA, i32:$RB))]>;
2889fe6060f1SDimitry Andriclet hasSideEffects = 1 in
289006c3fb27SDimitry Andricdef ADDEX : Z23Form_RTAB5_CY2<31, 170, (outs gprc:$RT),
289106c3fb27SDimitry Andric                              (ins gprc:$RA, gprc:$RB, u2imm:$CY),
289206c3fb27SDimitry Andric                              "addex $RT, $RA, $RB, $CY", IIC_IntGeneral, []>;
28930b57cec5SDimitry Andric}
28940b57cec5SDimitry Andric
28950b57cec5SDimitry Andriclet PPC970_Unit = 1, hasSideEffects = 0 in {  // FXU Operations.
28960b57cec5SDimitry Andric// XO-Form instructions.  Arithmetic instructions that can set overflow bit
28970b57cec5SDimitry Andriclet isCommutable = 1 in
289806c3fb27SDimitry Andricdefm ADD4  : XOForm_1rx<31, 266, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
289906c3fb27SDimitry Andric                        "add", "$RT, $RA, $RB", IIC_IntSimple,
290006c3fb27SDimitry Andric                        [(set i32:$RT, (add i32:$RA, i32:$RB))]>;
29010b57cec5SDimitry Andriclet isCodeGenOnly = 1 in
290206c3fb27SDimitry Andricdef ADD4TLS  : XOForm_1<31, 266, 0, (outs gprc:$RT), (ins gprc:$RA, tlsreg32:$RB),
290306c3fb27SDimitry Andric                       "add $RT, $RA, $RB", IIC_IntSimple,
290406c3fb27SDimitry Andric                       [(set i32:$RT, (add i32:$RA, tglobaltlsaddr:$RB))]>;
29050b57cec5SDimitry Andriclet isCommutable = 1 in
290606c3fb27SDimitry Andricdefm ADDC  : XOForm_1rc<31, 10, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
290706c3fb27SDimitry Andric                        "addc", "$RT, $RA, $RB", IIC_IntGeneral,
290806c3fb27SDimitry Andric                        [(set i32:$RT, (addc i32:$RA, i32:$RB))]>,
29090b57cec5SDimitry Andric                        PPC970_DGroup_Cracked;
29100b57cec5SDimitry Andric
291106c3fb27SDimitry Andricdefm DIVW  : XOForm_1rcr<31, 491, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
291206c3fb27SDimitry Andric                          "divw", "$RT, $RA, $RB", IIC_IntDivW,
291306c3fb27SDimitry Andric                          [(set i32:$RT, (sdiv i32:$RA, i32:$RB))]>;
291406c3fb27SDimitry Andricdefm DIVWU : XOForm_1rcr<31, 459, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
291506c3fb27SDimitry Andric                          "divwu", "$RT, $RA, $RB", IIC_IntDivW,
291606c3fb27SDimitry Andric                          [(set i32:$RT, (udiv i32:$RA, i32:$RB))]>;
291706c3fb27SDimitry Andricdefm DIVWE : XOForm_1rcr<31, 427, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
291806c3fb27SDimitry Andric                         "divwe", "$RT, $RA, $RB", IIC_IntDivW,
291906c3fb27SDimitry Andric                         [(set i32:$RT, (int_ppc_divwe gprc:$RA, gprc:$RB))]>,
29200b57cec5SDimitry Andric                         Requires<[HasExtDiv]>;
292106c3fb27SDimitry Andricdefm DIVWEU : XOForm_1rcr<31, 395, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
292206c3fb27SDimitry Andric                          "divweu", "$RT, $RA, $RB", IIC_IntDivW,
292306c3fb27SDimitry Andric                          [(set i32:$RT, (int_ppc_divweu gprc:$RA, gprc:$RB))]>,
29240b57cec5SDimitry Andric                          Requires<[HasExtDiv]>;
29250b57cec5SDimitry Andriclet isCommutable = 1 in {
292606c3fb27SDimitry Andricdefm MULHW : XOForm_1r<31, 75, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
292706c3fb27SDimitry Andric                       "mulhw", "$RT, $RA, $RB", IIC_IntMulHW,
292806c3fb27SDimitry Andric                       [(set i32:$RT, (mulhs i32:$RA, i32:$RB))]>;
292906c3fb27SDimitry Andricdefm MULHWU : XOForm_1r<31, 11, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
293006c3fb27SDimitry Andric                       "mulhwu", "$RT, $RA, $RB", IIC_IntMulHWU,
293106c3fb27SDimitry Andric                       [(set i32:$RT, (mulhu i32:$RA, i32:$RB))]>;
293206c3fb27SDimitry Andricdefm MULLW : XOForm_1rx<31, 235, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
293306c3fb27SDimitry Andric                        "mullw", "$RT, $RA, $RB", IIC_IntMulHW,
293406c3fb27SDimitry Andric                        [(set i32:$RT, (mul i32:$RA, i32:$RB))]>;
29350b57cec5SDimitry Andric} // isCommutable
293606c3fb27SDimitry Andricdefm SUBF  : XOForm_1rx<31, 40, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
293706c3fb27SDimitry Andric                        "subf", "$RT, $RA, $RB", IIC_IntGeneral,
293806c3fb27SDimitry Andric                        [(set i32:$RT, (sub i32:$RB, i32:$RA))]>;
293906c3fb27SDimitry Andricdefm SUBFC : XOForm_1rc<31, 8, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
294006c3fb27SDimitry Andric                        "subfc", "$RT, $RA, $RB", IIC_IntGeneral,
294106c3fb27SDimitry Andric                        [(set i32:$RT, (subc i32:$RB, i32:$RA))]>,
29420b57cec5SDimitry Andric                        PPC970_DGroup_Cracked;
294306c3fb27SDimitry Andricdefm NEG    : XOForm_3r<31, 104, 0, (outs gprc:$RT), (ins gprc:$RA),
294406c3fb27SDimitry Andric                        "neg", "$RT, $RA", IIC_IntSimple,
294506c3fb27SDimitry Andric                        [(set i32:$RT, (ineg i32:$RA))]>;
29460b57cec5SDimitry Andriclet Uses = [CARRY] in {
29470b57cec5SDimitry Andriclet isCommutable = 1 in
294806c3fb27SDimitry Andricdefm ADDE  : XOForm_1rc<31, 138, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
294906c3fb27SDimitry Andric                        "adde", "$RT, $RA, $RB", IIC_IntGeneral,
295006c3fb27SDimitry Andric                        [(set i32:$RT, (adde i32:$RA, i32:$RB))]>;
295106c3fb27SDimitry Andricdefm ADDME  : XOForm_3rc<31, 234, 0, (outs gprc:$RT), (ins gprc:$RA),
295206c3fb27SDimitry Andric                         "addme", "$RT, $RA", IIC_IntGeneral,
295306c3fb27SDimitry Andric                         [(set i32:$RT, (adde i32:$RA, -1))]>;
295406c3fb27SDimitry Andricdefm ADDZE  : XOForm_3rc<31, 202, 0, (outs gprc:$RT), (ins gprc:$RA),
295506c3fb27SDimitry Andric                         "addze", "$RT, $RA", IIC_IntGeneral,
295606c3fb27SDimitry Andric                         [(set i32:$RT, (adde i32:$RA, 0))]>;
295706c3fb27SDimitry Andricdefm SUBFE : XOForm_1rc<31, 136, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
295806c3fb27SDimitry Andric                        "subfe", "$RT, $RA, $RB", IIC_IntGeneral,
295906c3fb27SDimitry Andric                        [(set i32:$RT, (sube i32:$RB, i32:$RA))]>;
296006c3fb27SDimitry Andricdefm SUBFME : XOForm_3rc<31, 232, 0, (outs gprc:$RT), (ins gprc:$RA),
296106c3fb27SDimitry Andric                         "subfme", "$RT, $RA", IIC_IntGeneral,
296206c3fb27SDimitry Andric                         [(set i32:$RT, (sube -1, i32:$RA))]>;
296306c3fb27SDimitry Andricdefm SUBFZE : XOForm_3rc<31, 200, 0, (outs gprc:$RT), (ins gprc:$RA),
296406c3fb27SDimitry Andric                         "subfze", "$RT, $RA", IIC_IntGeneral,
296506c3fb27SDimitry Andric                         [(set i32:$RT, (sube 0, i32:$RA))]>;
29660b57cec5SDimitry Andric}
29670b57cec5SDimitry Andric}
29680b57cec5SDimitry Andric
29695ffd83dbSDimitry Andricdef : InstAlias<"sub $rA, $rB, $rC", (SUBF gprc:$rA, gprc:$rC, gprc:$rB)>;
29705ffd83dbSDimitry Andricdef : InstAlias<"sub. $rA, $rB, $rC", (SUBF_rec gprc:$rA, gprc:$rC, gprc:$rB)>;
29715ffd83dbSDimitry Andricdef : InstAlias<"subc $rA, $rB, $rC", (SUBFC gprc:$rA, gprc:$rC, gprc:$rB)>;
29725ffd83dbSDimitry Andricdef : InstAlias<"subc. $rA, $rB, $rC", (SUBFC_rec gprc:$rA, gprc:$rC, gprc:$rB)>;
29735ffd83dbSDimitry Andric
29740b57cec5SDimitry Andric// A-Form instructions.  Most of the instructions executed in the FPU are of
29750b57cec5SDimitry Andric// this type.
29760b57cec5SDimitry Andric//
29770b57cec5SDimitry Andriclet PPC970_Unit = 3, hasSideEffects = 0, Predicates = [HasFPU] in {  // FPU Operations.
2978e8d8bef9SDimitry Andriclet mayRaiseFPException = 1, Uses = [RM] in {
29790b57cec5SDimitry Andriclet isCommutable = 1 in {
29800b57cec5SDimitry Andric  defm FMADD : AForm_1r<63, 29,
29810b57cec5SDimitry Andric                      (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB),
29820b57cec5SDimitry Andric                      "fmadd", "$FRT, $FRA, $FRC, $FRB", IIC_FPFused,
29835ffd83dbSDimitry Andric                      [(set f64:$FRT, (any_fma f64:$FRA, f64:$FRC, f64:$FRB))]>;
29840b57cec5SDimitry Andric  defm FMADDS : AForm_1r<59, 29,
29850b57cec5SDimitry Andric                      (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB),
29860b57cec5SDimitry Andric                      "fmadds", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral,
29875ffd83dbSDimitry Andric                      [(set f32:$FRT, (any_fma f32:$FRA, f32:$FRC, f32:$FRB))]>;
29880b57cec5SDimitry Andric  defm FMSUB : AForm_1r<63, 28,
29890b57cec5SDimitry Andric                      (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB),
29900b57cec5SDimitry Andric                      "fmsub", "$FRT, $FRA, $FRC, $FRB", IIC_FPFused,
29910b57cec5SDimitry Andric                      [(set f64:$FRT,
29925ffd83dbSDimitry Andric                            (any_fma f64:$FRA, f64:$FRC, (fneg f64:$FRB)))]>;
29930b57cec5SDimitry Andric  defm FMSUBS : AForm_1r<59, 28,
29940b57cec5SDimitry Andric                      (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB),
29950b57cec5SDimitry Andric                      "fmsubs", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral,
29960b57cec5SDimitry Andric                      [(set f32:$FRT,
29975ffd83dbSDimitry Andric                            (any_fma f32:$FRA, f32:$FRC, (fneg f32:$FRB)))]>;
29980b57cec5SDimitry Andric  defm FNMADD : AForm_1r<63, 31,
29990b57cec5SDimitry Andric                      (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB),
30000b57cec5SDimitry Andric                      "fnmadd", "$FRT, $FRA, $FRC, $FRB", IIC_FPFused,
30010b57cec5SDimitry Andric                      [(set f64:$FRT,
30025ffd83dbSDimitry Andric                            (fneg (any_fma f64:$FRA, f64:$FRC, f64:$FRB)))]>;
30030b57cec5SDimitry Andric  defm FNMADDS : AForm_1r<59, 31,
30040b57cec5SDimitry Andric                      (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB),
30050b57cec5SDimitry Andric                      "fnmadds", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral,
30060b57cec5SDimitry Andric                      [(set f32:$FRT,
30075ffd83dbSDimitry Andric                            (fneg (any_fma f32:$FRA, f32:$FRC, f32:$FRB)))]>;
30080b57cec5SDimitry Andric  defm FNMSUB : AForm_1r<63, 30,
30090b57cec5SDimitry Andric                      (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB),
30100b57cec5SDimitry Andric                      "fnmsub", "$FRT, $FRA, $FRC, $FRB", IIC_FPFused,
30115ffd83dbSDimitry Andric                      [(set f64:$FRT, (fneg (any_fma f64:$FRA, f64:$FRC,
30120b57cec5SDimitry Andric                                                 (fneg f64:$FRB))))]>;
30130b57cec5SDimitry Andric  defm FNMSUBS : AForm_1r<59, 30,
30140b57cec5SDimitry Andric                      (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC, f4rc:$FRB),
30150b57cec5SDimitry Andric                      "fnmsubs", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral,
30165ffd83dbSDimitry Andric                      [(set f32:$FRT, (fneg (any_fma f32:$FRA, f32:$FRC,
30170b57cec5SDimitry Andric                                                 (fneg f32:$FRB))))]>;
30180b57cec5SDimitry Andric} // isCommutable
30190b57cec5SDimitry Andric}
30200b57cec5SDimitry Andric// FSEL is artificially split into 4 and 8-byte forms for the result.  To avoid
30210b57cec5SDimitry Andric// having 4 of these, force the comparison to always be an 8-byte double (code
30220b57cec5SDimitry Andric// should use an FMRSD if the input comparison value really wants to be a float)
30230b57cec5SDimitry Andric// and 4/8 byte forms for the result and operand type..
30240b57cec5SDimitry Andriclet Interpretation64Bit = 1, isCodeGenOnly = 1 in
30250b57cec5SDimitry Andricdefm FSELD : AForm_1r<63, 23,
30260b57cec5SDimitry Andric                      (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC, f8rc:$FRB),
30270b57cec5SDimitry Andric                      "fsel", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral,
30280b57cec5SDimitry Andric                      [(set f64:$FRT, (PPCfsel f64:$FRA, f64:$FRC, f64:$FRB))]>;
30290b57cec5SDimitry Andricdefm FSELS : AForm_1r<63, 23,
30300b57cec5SDimitry Andric                      (outs f4rc:$FRT), (ins f8rc:$FRA, f4rc:$FRC, f4rc:$FRB),
30310b57cec5SDimitry Andric                      "fsel", "$FRT, $FRA, $FRC, $FRB", IIC_FPGeneral,
30320b57cec5SDimitry Andric                      [(set f32:$FRT, (PPCfsel f64:$FRA, f32:$FRC, f32:$FRB))]>;
30335ffd83dbSDimitry Andriclet Uses = [RM], mayRaiseFPException = 1 in {
30340b57cec5SDimitry Andric  let isCommutable = 1 in {
30350b57cec5SDimitry Andric  defm FADD  : AForm_2r<63, 21,
30360b57cec5SDimitry Andric                        (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB),
30370b57cec5SDimitry Andric                        "fadd", "$FRT, $FRA, $FRB", IIC_FPAddSub,
30385ffd83dbSDimitry Andric                        [(set f64:$FRT, (any_fadd f64:$FRA, f64:$FRB))]>;
30390b57cec5SDimitry Andric  defm FADDS : AForm_2r<59, 21,
30400b57cec5SDimitry Andric                        (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB),
30410b57cec5SDimitry Andric                        "fadds", "$FRT, $FRA, $FRB", IIC_FPGeneral,
30425ffd83dbSDimitry Andric                        [(set f32:$FRT, (any_fadd f32:$FRA, f32:$FRB))]>;
30430b57cec5SDimitry Andric  } // isCommutable
30440b57cec5SDimitry Andric  defm FDIV  : AForm_2r<63, 18,
30450b57cec5SDimitry Andric                        (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB),
30460b57cec5SDimitry Andric                        "fdiv", "$FRT, $FRA, $FRB", IIC_FPDivD,
30475ffd83dbSDimitry Andric                        [(set f64:$FRT, (any_fdiv f64:$FRA, f64:$FRB))]>;
30480b57cec5SDimitry Andric  defm FDIVS : AForm_2r<59, 18,
30490b57cec5SDimitry Andric                        (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB),
30500b57cec5SDimitry Andric                        "fdivs", "$FRT, $FRA, $FRB", IIC_FPDivS,
30515ffd83dbSDimitry Andric                        [(set f32:$FRT, (any_fdiv f32:$FRA, f32:$FRB))]>;
30520b57cec5SDimitry Andric  let isCommutable = 1 in {
30530b57cec5SDimitry Andric  defm FMUL  : AForm_3r<63, 25,
30540b57cec5SDimitry Andric                        (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRC),
30550b57cec5SDimitry Andric                        "fmul", "$FRT, $FRA, $FRC", IIC_FPFused,
30565ffd83dbSDimitry Andric                        [(set f64:$FRT, (any_fmul f64:$FRA, f64:$FRC))]>;
30570b57cec5SDimitry Andric  defm FMULS : AForm_3r<59, 25,
30580b57cec5SDimitry Andric                        (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRC),
30590b57cec5SDimitry Andric                        "fmuls", "$FRT, $FRA, $FRC", IIC_FPGeneral,
30605ffd83dbSDimitry Andric                        [(set f32:$FRT, (any_fmul f32:$FRA, f32:$FRC))]>;
30610b57cec5SDimitry Andric  } // isCommutable
30620b57cec5SDimitry Andric  defm FSUB  : AForm_2r<63, 20,
30630b57cec5SDimitry Andric                        (outs f8rc:$FRT), (ins f8rc:$FRA, f8rc:$FRB),
30640b57cec5SDimitry Andric                        "fsub", "$FRT, $FRA, $FRB", IIC_FPAddSub,
30655ffd83dbSDimitry Andric                        [(set f64:$FRT, (any_fsub f64:$FRA, f64:$FRB))]>;
30660b57cec5SDimitry Andric  defm FSUBS : AForm_2r<59, 20,
30670b57cec5SDimitry Andric                        (outs f4rc:$FRT), (ins f4rc:$FRA, f4rc:$FRB),
30680b57cec5SDimitry Andric                        "fsubs", "$FRT, $FRA, $FRB", IIC_FPGeneral,
30695ffd83dbSDimitry Andric                        [(set f32:$FRT, (any_fsub f32:$FRA, f32:$FRB))]>;
30700b57cec5SDimitry Andric  }
30710b57cec5SDimitry Andric}
30720b57cec5SDimitry Andric
30730b57cec5SDimitry Andriclet hasSideEffects = 0 in {
30740b57cec5SDimitry Andriclet PPC970_Unit = 1 in {  // FXU Operations.
30750b57cec5SDimitry Andric  let isSelect = 1 in
30760b57cec5SDimitry Andric  def ISEL  : AForm_4<31, 15,
307706c3fb27SDimitry Andric                     (outs gprc:$RT), (ins gprc_nor0:$RA, gprc:$RB, crbitrc:$COND),
307806c3fb27SDimitry Andric                     "isel $RT, $RA, $RB, $COND", IIC_IntISEL,
30790b57cec5SDimitry Andric                     []>;
30800b57cec5SDimitry Andric}
30810b57cec5SDimitry Andric
30820b57cec5SDimitry Andriclet PPC970_Unit = 1 in {  // FXU Operations.
30830b57cec5SDimitry Andric// M-Form instructions.  rotate and mask instructions.
30840b57cec5SDimitry Andric//
30850b57cec5SDimitry Andriclet isCommutable = 1 in {
30860b57cec5SDimitry Andric// RLWIMI can be commuted if the rotate amount is zero.
308706c3fb27SDimitry Andricdefm RLWIMI : MForm_2r<20, (outs gprc:$RA),
308806c3fb27SDimitry Andric                       (ins gprc:$RAi, gprc:$RS, u5imm:$SH, u5imm:$MB,
308906c3fb27SDimitry Andric                       u5imm:$ME), "rlwimi", "$RA, $RS, $SH, $MB, $ME",
30900b57cec5SDimitry Andric                       IIC_IntRotate, []>, PPC970_DGroup_Cracked,
309106c3fb27SDimitry Andric                       RegConstraint<"$RAi = $RA">, NoEncode<"$RAi">;
30920b57cec5SDimitry Andric}
30930b57cec5SDimitry Andriclet BaseName = "rlwinm" in {
30940b57cec5SDimitry Andricdef RLWINM : MForm_2<21,
309506c3fb27SDimitry Andric                     (outs gprc:$RA), (ins gprc:$RS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
309606c3fb27SDimitry Andric                     "rlwinm $RA, $RS, $SH, $MB, $ME", IIC_IntGeneral,
30970b57cec5SDimitry Andric                     []>, RecFormRel;
30980b57cec5SDimitry Andriclet Defs = [CR0] in
3099480093f4SDimitry Andricdef RLWINM_rec : MForm_2<21,
310006c3fb27SDimitry Andric                      (outs gprc:$RA), (ins gprc:$RS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
310106c3fb27SDimitry Andric                      "rlwinm. $RA, $RS, $SH, $MB, $ME", IIC_IntGeneral,
3102480093f4SDimitry Andric                      []>, isRecordForm, RecFormRel, PPC970_DGroup_Cracked;
31030b57cec5SDimitry Andric}
310406c3fb27SDimitry Andricdefm RLWNM  : MForm_1r<23, (outs gprc:$RA),
310506c3fb27SDimitry Andric                       (ins gprc:$RS, gprc:$RB, u5imm:$MB, u5imm:$ME),
310606c3fb27SDimitry Andric                       "rlwnm", "$RA, $RS, $RB, $MB, $ME", IIC_IntGeneral,
31070b57cec5SDimitry Andric                       []>;
31080b57cec5SDimitry Andric}
31090b57cec5SDimitry Andric} // hasSideEffects = 0
31100b57cec5SDimitry Andric
31110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
31120b57cec5SDimitry Andric// PowerPC Instruction Patterns
31130b57cec5SDimitry Andric//
31140b57cec5SDimitry Andric
31150b57cec5SDimitry Andric// Arbitrary immediate support.  Implement in terms of LIS/ORI.
31160b57cec5SDimitry Andricdef : Pat<(i32 imm:$imm),
31170b57cec5SDimitry Andric          (ORI (LIS (HI16 imm:$imm)), (LO16 imm:$imm))>;
31180b57cec5SDimitry Andric
31190b57cec5SDimitry Andric// Implement the 'not' operation with the NOR instruction.
31200b57cec5SDimitry Andricdef i32not : OutPatFrag<(ops node:$in),
31210b57cec5SDimitry Andric                        (NOR $in, $in)>;
31220b57cec5SDimitry Andricdef        : Pat<(not i32:$in),
31230b57cec5SDimitry Andric                 (i32not $in)>;
31240b57cec5SDimitry Andric
31250b57cec5SDimitry Andric// ADD an arbitrary immediate.
31260b57cec5SDimitry Andricdef : Pat<(add i32:$in, imm:$imm),
31270b57cec5SDimitry Andric          (ADDIS (ADDI $in, (LO16 imm:$imm)), (HA16 imm:$imm))>;
31280b57cec5SDimitry Andric// OR an arbitrary immediate.
31290b57cec5SDimitry Andricdef : Pat<(or i32:$in, imm:$imm),
31300b57cec5SDimitry Andric          (ORIS (ORI $in, (LO16 imm:$imm)), (HI16 imm:$imm))>;
31310b57cec5SDimitry Andric// XOR an arbitrary immediate.
31320b57cec5SDimitry Andricdef : Pat<(xor i32:$in, imm:$imm),
31330b57cec5SDimitry Andric          (XORIS (XORI $in, (LO16 imm:$imm)), (HI16 imm:$imm))>;
31340b57cec5SDimitry Andric// SUBFIC
31350b57cec5SDimitry Andricdef : Pat<(sub imm32SExt16:$imm, i32:$in),
31360b57cec5SDimitry Andric          (SUBFIC $in, imm:$imm)>;
31370b57cec5SDimitry Andric
31380b57cec5SDimitry Andric// SHL/SRL
31390b57cec5SDimitry Andricdef : Pat<(shl i32:$in, (i32 imm:$imm)),
31400b57cec5SDimitry Andric          (RLWINM $in, imm:$imm, 0, (SHL32 imm:$imm))>;
31410b57cec5SDimitry Andricdef : Pat<(srl i32:$in, (i32 imm:$imm)),
31420b57cec5SDimitry Andric          (RLWINM $in, (SRL32 imm:$imm), imm:$imm, 31)>;
31430b57cec5SDimitry Andric
31440b57cec5SDimitry Andric// ROTL
31450b57cec5SDimitry Andricdef : Pat<(rotl i32:$in, i32:$sh),
31460b57cec5SDimitry Andric          (RLWNM $in, $sh, 0, 31)>;
31470b57cec5SDimitry Andricdef : Pat<(rotl i32:$in, (i32 imm:$imm)),
31480b57cec5SDimitry Andric          (RLWINM $in, imm:$imm, 0, 31)>;
31490b57cec5SDimitry Andric
31500b57cec5SDimitry Andric// RLWNM
31510b57cec5SDimitry Andricdef : Pat<(and (rotl i32:$in, i32:$sh), maskimm32:$imm),
31520b57cec5SDimitry Andric          (RLWNM $in, $sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
31530b57cec5SDimitry Andric
31540b57cec5SDimitry Andric// Calls
31550b57cec5SDimitry Andricdef : Pat<(PPCcall (i32 tglobaladdr:$dst)),
31560b57cec5SDimitry Andric          (BL tglobaladdr:$dst)>;
31570b57cec5SDimitry Andric
31580b57cec5SDimitry Andricdef : Pat<(PPCcall (i32 texternalsym:$dst)),
31590b57cec5SDimitry Andric          (BL texternalsym:$dst)>;
31600b57cec5SDimitry Andric
3161349cc55cSDimitry Andricdef : Pat<(PPCcall_rm (i32 tglobaladdr:$dst)),
3162349cc55cSDimitry Andric          (BL_RM tglobaladdr:$dst)>;
3163349cc55cSDimitry Andric
3164349cc55cSDimitry Andricdef : Pat<(PPCcall_rm (i32 texternalsym:$dst)),
3165349cc55cSDimitry Andric          (BL_RM texternalsym:$dst)>;
3166349cc55cSDimitry Andric
31670b57cec5SDimitry Andric// Calls for AIX only
31680b57cec5SDimitry Andricdef : Pat<(PPCcall (i32 mcsym:$dst)),
31690b57cec5SDimitry Andric          (BL mcsym:$dst)>;
3170e8d8bef9SDimitry Andric
31710b57cec5SDimitry Andricdef : Pat<(PPCcall_nop (i32 mcsym:$dst)),
31720b57cec5SDimitry Andric          (BL_NOP mcsym:$dst)>;
31730b57cec5SDimitry Andric
3174e8d8bef9SDimitry Andricdef : Pat<(PPCcall_nop (i32 texternalsym:$dst)),
3175e8d8bef9SDimitry Andric          (BL_NOP texternalsym:$dst)>;
3176e8d8bef9SDimitry Andric
3177349cc55cSDimitry Andricdef : Pat<(PPCcall_rm (i32 mcsym:$dst)),
3178349cc55cSDimitry Andric          (BL_RM mcsym:$dst)>;
3179349cc55cSDimitry Andric
3180349cc55cSDimitry Andricdef : Pat<(PPCcall_nop_rm (i32 mcsym:$dst)),
3181349cc55cSDimitry Andric          (BL_NOP_RM mcsym:$dst)>;
3182349cc55cSDimitry Andric
3183349cc55cSDimitry Andricdef : Pat<(PPCcall_nop_rm (i32 texternalsym:$dst)),
3184349cc55cSDimitry Andric          (BL_NOP_RM texternalsym:$dst)>;
3185349cc55cSDimitry Andric
31860b57cec5SDimitry Andricdef : Pat<(PPCtc_return (i32 tglobaladdr:$dst),  imm:$imm),
31870b57cec5SDimitry Andric          (TCRETURNdi tglobaladdr:$dst, imm:$imm)>;
31880b57cec5SDimitry Andric
31890b57cec5SDimitry Andricdef : Pat<(PPCtc_return (i32 texternalsym:$dst), imm:$imm),
31900b57cec5SDimitry Andric          (TCRETURNdi texternalsym:$dst, imm:$imm)>;
31910b57cec5SDimitry Andric
31920b57cec5SDimitry Andricdef : Pat<(PPCtc_return CTRRC:$dst, imm:$imm),
31930b57cec5SDimitry Andric          (TCRETURNri CTRRC:$dst, imm:$imm)>;
31940b57cec5SDimitry Andric
31957a6dacacSDimitry Andricdef : Pat<(int_ppc_fence), (FENCE)>;
3196e8d8bef9SDimitry Andricdef : Pat<(int_ppc_readflm), (MFFS)>;
31975f757f3fSDimitry Andricdef : Pat<(int_ppc_mffsl), (MFFSL)>;
31980b57cec5SDimitry Andric
31990b57cec5SDimitry Andric// Hi and Lo for Darwin Global Addresses.
32000b57cec5SDimitry Andricdef : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>;
32010b57cec5SDimitry Andricdef : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>;
32020b57cec5SDimitry Andricdef : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>;
32030b57cec5SDimitry Andricdef : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>;
32040b57cec5SDimitry Andricdef : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>;
32050b57cec5SDimitry Andricdef : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>;
32060b57cec5SDimitry Andricdef : Pat<(PPChi tblockaddress:$in, 0), (LIS tblockaddress:$in)>;
32070b57cec5SDimitry Andricdef : Pat<(PPClo tblockaddress:$in, 0), (LI tblockaddress:$in)>;
32080b57cec5SDimitry Andricdef : Pat<(PPChi tglobaltlsaddr:$g, i32:$in),
32090b57cec5SDimitry Andric          (ADDIS $in, tglobaltlsaddr:$g)>;
32100b57cec5SDimitry Andricdef : Pat<(PPClo tglobaltlsaddr:$g, i32:$in),
32110b57cec5SDimitry Andric          (ADDI $in, tglobaltlsaddr:$g)>;
32120b57cec5SDimitry Andricdef : Pat<(add i32:$in, (PPChi tglobaladdr:$g, 0)),
32130b57cec5SDimitry Andric          (ADDIS $in, tglobaladdr:$g)>;
32140b57cec5SDimitry Andricdef : Pat<(add i32:$in, (PPChi tconstpool:$g, 0)),
32150b57cec5SDimitry Andric          (ADDIS $in, tconstpool:$g)>;
32160b57cec5SDimitry Andricdef : Pat<(add i32:$in, (PPChi tjumptable:$g, 0)),
32170b57cec5SDimitry Andric          (ADDIS $in, tjumptable:$g)>;
32180b57cec5SDimitry Andricdef : Pat<(add i32:$in, (PPChi tblockaddress:$g, 0)),
32190b57cec5SDimitry Andric          (ADDIS $in, tblockaddress:$g)>;
32200b57cec5SDimitry Andric
32210b57cec5SDimitry Andric// Support for thread-local storage.
32220b57cec5SDimitry Andricdef PPC32GOT: PPCEmitTimePseudo<(outs gprc:$rD), (ins), "#PPC32GOT",
32230b57cec5SDimitry Andric                [(set i32:$rD, (PPCppc32GOT))]>;
32240b57cec5SDimitry Andric
32250b57cec5SDimitry Andric// Get the _GLOBAL_OFFSET_TABLE_ in PIC mode.
32260b57cec5SDimitry Andric// This uses two output registers, the first as the real output, the second as a
32270b57cec5SDimitry Andric// temporary register, used internally in code generation.
32280b57cec5SDimitry Andricdef PPC32PICGOT: PPCEmitTimePseudo<(outs gprc:$rD, gprc:$rT), (ins), "#PPC32PICGOT",
32290b57cec5SDimitry Andric                []>, NoEncode<"$rT">;
32300b57cec5SDimitry Andric
32316dce2be1SDimitry Andricdef LDgotTprelL32: PPCEmitTimePseudo<(outs gprc_nor0:$rD), (ins s16imm:$disp, gprc_nor0:$reg),
32320b57cec5SDimitry Andric                           "#LDgotTprelL32",
32330b57cec5SDimitry Andric                           [(set i32:$rD,
32340b57cec5SDimitry Andric                             (PPCldGotTprelL tglobaltlsaddr:$disp, i32:$reg))]>;
32350b57cec5SDimitry Andricdef : Pat<(PPCaddTls i32:$in, tglobaltlsaddr:$g),
32360b57cec5SDimitry Andric          (ADD4TLS $in, tglobaltlsaddr:$g)>;
32370b57cec5SDimitry Andric
32380b57cec5SDimitry Andricdef ADDItlsgdL32 : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
32390b57cec5SDimitry Andric                         "#ADDItlsgdL32",
32400b57cec5SDimitry Andric                         [(set i32:$rD,
32410b57cec5SDimitry Andric                           (PPCaddiTlsgdL i32:$reg, tglobaltlsaddr:$disp))]>;
32420b57cec5SDimitry Andric// LR is a true define, while the rest of the Defs are clobbers.  R3 is
32430b57cec5SDimitry Andric// explicitly defined when this op is created, so not mentioned here.
32440b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
32450b57cec5SDimitry Andric    Defs = [R0,R4,R5,R6,R7,R8,R9,R10,R11,R12,LR,CTR,CR0,CR1,CR5,CR6,CR7] in
32460b57cec5SDimitry Andricdef GETtlsADDR32 : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
32470b57cec5SDimitry Andric                          "GETtlsADDR32",
32480b57cec5SDimitry Andric                          [(set i32:$rD,
32490b57cec5SDimitry Andric                            (PPCgetTlsAddr i32:$reg, tglobaltlsaddr:$sym))]>;
3250fe6060f1SDimitry Andric// R3 is explicitly defined when this op is created, so not mentioned here.
3251fe6060f1SDimitry Andric// The rest of the Defs are the exact set of registers that will be clobbered by
3252fe6060f1SDimitry Andric// the call.
3253fe6060f1SDimitry Andriclet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
32540fca6ea1SDimitry Andric    Defs = [R0,R4,R5,R11,LR,CR0] in {
3255fe6060f1SDimitry Andricdef GETtlsADDR32AIX : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$offset, gprc:$handle),
3256fe6060f1SDimitry Andric                          "GETtlsADDR32AIX",
3257fe6060f1SDimitry Andric                          [(set i32:$rD,
3258fe6060f1SDimitry Andric                            (PPCgetTlsAddr i32:$offset, i32:$handle))]>;
32590fca6ea1SDimitry Andricdef GETtlsMOD32AIX : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$handle),
32600fca6ea1SDimitry Andric                          "GETtlsMOD32AIX",
32610fca6ea1SDimitry Andric                          [(set i32:$rD,
32620fca6ea1SDimitry Andric                            (PPCgetTlsMod i32:$handle))]>;
32630fca6ea1SDimitry Andric}
326406c3fb27SDimitry Andric
326506c3fb27SDimitry Andric// For local-exec accesses on 32-bit AIX, a call to .__get_tpointer is
326606c3fb27SDimitry Andric// generated to retrieve the thread pointer. GETtlsTpointer32AIX clobbers both
326706c3fb27SDimitry Andric// R3 and the LR (link register).
326806c3fb27SDimitry Andriclet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
326906c3fb27SDimitry Andric    Defs = [R3,LR] in
327006c3fb27SDimitry Andricdef GETtlsTpointer32AIX : PPCEmitTimePseudo<(outs gprc:$rD), (ins),
327106c3fb27SDimitry Andric                          "GETtlsTpointer32AIX",
327206c3fb27SDimitry Andric                          [(set i32:$rD, (PPCgetTpointer))]>;
327306c3fb27SDimitry Andric
32745f757f3fSDimitry Andric// The following pattern matches local- and initial-exec TLS accesses on 32-bit AIX.
32755f757f3fSDimitry Andric// PPCaddTls is used in local- and initial-exec accesses in order to:
327606c3fb27SDimitry Andric//   - Get the address of a variable (add the variable offset to the thread
327706c3fb27SDimitry Andric//     pointer, retrieved by calling .__get_tpointer).
327806c3fb27SDimitry Andric//   - Create an opportunity to optimize the user of the loaded address.
327906c3fb27SDimitry Andricdef : Pat<(PPCaddTls i32:$in, i32:$addr),
328006c3fb27SDimitry Andric          (ADD4TLS $in, $addr)>;
328106c3fb27SDimitry Andric
32820b57cec5SDimitry Andric// Combined op for ADDItlsgdL32 and GETtlsADDR32, late expanded.  R3 and LR
32830b57cec5SDimitry Andric// are true defines while the rest of the Defs are clobbers.
32840b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
32850b57cec5SDimitry Andric    Defs = [R0,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,LR,CTR,CR0,CR1,CR5,CR6,CR7] in
32860b57cec5SDimitry Andricdef ADDItlsgdLADDR32 : PPCEmitTimePseudo<(outs gprc:$rD),
32870b57cec5SDimitry Andric                              (ins gprc_nor0:$reg, s16imm:$disp, tlsgd32:$sym),
32880b57cec5SDimitry Andric                              "#ADDItlsgdLADDR32",
32890b57cec5SDimitry Andric                              [(set i32:$rD,
32900b57cec5SDimitry Andric                                (PPCaddiTlsgdLAddr i32:$reg,
32910b57cec5SDimitry Andric                                                   tglobaltlsaddr:$disp,
32920b57cec5SDimitry Andric                                                   tglobaltlsaddr:$sym))]>;
32930b57cec5SDimitry Andricdef ADDItlsldL32 : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
32940b57cec5SDimitry Andric                          "#ADDItlsldL32",
32950b57cec5SDimitry Andric                          [(set i32:$rD,
32960b57cec5SDimitry Andric                            (PPCaddiTlsldL i32:$reg, tglobaltlsaddr:$disp))]>;
3297fe6060f1SDimitry Andric// This pseudo is expanded to two copies to put the variable offset in R4 and
3298fe6060f1SDimitry Andric// the region handle in R3 and GETtlsADDR32AIX.
3299fe6060f1SDimitry Andricdef TLSGDAIX : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$offset, gprc:$handle),
3300fe6060f1SDimitry Andric                          "#TLSGDAIX",
3301fe6060f1SDimitry Andric                          [(set i32:$rD,
3302fe6060f1SDimitry Andric                            (PPCTlsgdAIX i32:$offset, i32:$handle))]>;
33030fca6ea1SDimitry Andric// This pseudo is expanded to the call to GETtlsMOD32AIX.
33040fca6ea1SDimitry Andricdef TLSLDAIX : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$handle),
33050fca6ea1SDimitry Andric                          "#TLSLDAIX", [(set i32:$rD, (PPCTlsldAIX i32:$handle))]>;
33060b57cec5SDimitry Andric// LR is a true define, while the rest of the Defs are clobbers.  R3 is
33070b57cec5SDimitry Andric// explicitly defined when this op is created, so not mentioned here.
33080b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
33090b57cec5SDimitry Andric    Defs = [R0,R4,R5,R6,R7,R8,R9,R10,R11,R12,LR,CTR,CR0,CR1,CR5,CR6,CR7] in
33100b57cec5SDimitry Andricdef GETtlsldADDR32 : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
33110b57cec5SDimitry Andric                            "GETtlsldADDR32",
33120b57cec5SDimitry Andric                            [(set i32:$rD,
33130b57cec5SDimitry Andric                              (PPCgetTlsldAddr i32:$reg,
33140b57cec5SDimitry Andric                                               tglobaltlsaddr:$sym))]>;
33150b57cec5SDimitry Andric// Combined op for ADDItlsldL32 and GETtlsADDR32, late expanded.  R3 and LR
33160b57cec5SDimitry Andric// are true defines while the rest of the Defs are clobbers.
33170b57cec5SDimitry Andriclet hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1,
33180b57cec5SDimitry Andric    Defs = [R0,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12,LR,CTR,CR0,CR1,CR5,CR6,CR7] in
33190b57cec5SDimitry Andricdef ADDItlsldLADDR32 : PPCEmitTimePseudo<(outs gprc:$rD),
33200b57cec5SDimitry Andric                              (ins gprc_nor0:$reg, s16imm:$disp, tlsgd32:$sym),
33210b57cec5SDimitry Andric                              "#ADDItlsldLADDR32",
33220b57cec5SDimitry Andric                              [(set i32:$rD,
33230b57cec5SDimitry Andric                                (PPCaddiTlsldLAddr i32:$reg,
33240b57cec5SDimitry Andric                                                   tglobaltlsaddr:$disp,
33250b57cec5SDimitry Andric                                                   tglobaltlsaddr:$sym))]>;
33260b57cec5SDimitry Andricdef ADDIdtprelL32 : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
33270b57cec5SDimitry Andric                           "#ADDIdtprelL32",
33280b57cec5SDimitry Andric                           [(set i32:$rD,
33290b57cec5SDimitry Andric                             (PPCaddiDtprelL i32:$reg, tglobaltlsaddr:$disp))]>;
33300b57cec5SDimitry Andricdef ADDISdtprelHA32 : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
33310b57cec5SDimitry Andric                            "#ADDISdtprelHA32",
33320b57cec5SDimitry Andric                            [(set i32:$rD,
33330b57cec5SDimitry Andric                              (PPCaddisDtprelHA i32:$reg,
33340b57cec5SDimitry Andric                                                tglobaltlsaddr:$disp))]>;
33350b57cec5SDimitry Andric
33360b57cec5SDimitry Andric// Support for Position-independent code
33370b57cec5SDimitry Andricdef LWZtoc : PPCEmitTimePseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc:$reg),
33380b57cec5SDimitry Andric                   "#LWZtoc",
33390b57cec5SDimitry Andric                   [(set i32:$rD,
33400b57cec5SDimitry Andric                     (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
33418bcb0991SDimitry Andricdef LWZtocL : PPCEmitTimePseudo<(outs gprc:$rD), (ins tocentry32:$disp, gprc_nor0:$reg),
33428bcb0991SDimitry Andric                    "#LWZtocL",
33438bcb0991SDimitry Andric                    [(set i32:$rD,
33448bcb0991SDimitry Andric                      (PPCtoc_entry tglobaladdr:$disp, i32:$reg))]>;
33458bcb0991SDimitry Andricdef ADDIStocHA : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentry32:$disp),
33460fca6ea1SDimitry Andric                       "#ADDIStocHA", []>;
33470fca6ea1SDimitry Andric// TOC Data Transform on AIX
33480fca6ea1SDimitry Andricdef ADDItoc : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc:$reg, tocentry32:$disp),
33490fca6ea1SDimitry Andric                   "#ADDItoc", []>;
33500fca6ea1SDimitry Andricdef ADDItocL : PPCEmitTimePseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, tocentry32:$disp),
33510fca6ea1SDimitry Andric                   "#ADDItocL", []>;
33528bcb0991SDimitry Andric
33530b57cec5SDimitry Andric// Get Global (GOT) Base Register offset, from the word immediately preceding
33540b57cec5SDimitry Andric// the function label.
33550b57cec5SDimitry Andricdef UpdateGBR : PPCEmitTimePseudo<(outs gprc:$rD, gprc:$rT), (ins gprc:$rI), "#UpdateGBR", []>;
33560b57cec5SDimitry Andric
3357480093f4SDimitry Andric// Pseudo-instruction marked for deletion. When deleting the instruction would
3358480093f4SDimitry Andric// cause iterator invalidation in MIR transformation passes, this pseudo can be
3359480093f4SDimitry Andric// used instead. It will be removed unconditionally at pre-emit time (prior to
3360480093f4SDimitry Andric// branch selection).
3361480093f4SDimitry Andricdef UNENCODED_NOP: PPCEmitTimePseudo<(outs), (ins), "#UNENCODED_NOP", []>;
33620b57cec5SDimitry Andric
33630b57cec5SDimitry Andric// Standard shifts.  These are represented separately from the real shifts above
33640b57cec5SDimitry Andric// so that we can distinguish between shifts that allow 5-bit and 6-bit shift
33650b57cec5SDimitry Andric// amounts.
33660b57cec5SDimitry Andricdef : Pat<(sra i32:$rS, i32:$rB),
33670b57cec5SDimitry Andric          (SRAW $rS, $rB)>;
33680b57cec5SDimitry Andricdef : Pat<(srl i32:$rS, i32:$rB),
33690b57cec5SDimitry Andric          (SRW $rS, $rB)>;
33700b57cec5SDimitry Andricdef : Pat<(shl i32:$rS, i32:$rB),
33710b57cec5SDimitry Andric          (SLW $rS, $rB)>;
33720b57cec5SDimitry Andric
3373fe6060f1SDimitry Andricdef : Pat<(i32 (zextloadi1 DForm:$src)),
3374fe6060f1SDimitry Andric          (LBZ DForm:$src)>;
3375fe6060f1SDimitry Andricdef : Pat<(i32 (zextloadi1 XForm:$src)),
3376fe6060f1SDimitry Andric          (LBZX XForm:$src)>;
3377fe6060f1SDimitry Andricdef : Pat<(i32 (extloadi1 DForm:$src)),
3378fe6060f1SDimitry Andric          (LBZ DForm:$src)>;
3379fe6060f1SDimitry Andricdef : Pat<(i32 (extloadi1 XForm:$src)),
3380fe6060f1SDimitry Andric          (LBZX XForm:$src)>;
3381fe6060f1SDimitry Andricdef : Pat<(i32 (extloadi8 DForm:$src)),
3382fe6060f1SDimitry Andric          (LBZ DForm:$src)>;
3383fe6060f1SDimitry Andricdef : Pat<(i32 (extloadi8 XForm:$src)),
3384fe6060f1SDimitry Andric          (LBZX XForm:$src)>;
3385fe6060f1SDimitry Andricdef : Pat<(i32 (extloadi16 DForm:$src)),
3386fe6060f1SDimitry Andric          (LHZ DForm:$src)>;
3387fe6060f1SDimitry Andricdef : Pat<(i32 (extloadi16 XForm:$src)),
3388fe6060f1SDimitry Andric          (LHZX XForm:$src)>;
33890b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
3390fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 DForm:$src)),
3391fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LFS DForm:$src), F8RC)>;
3392fe6060f1SDimitry Andricdef : Pat<(f64 (extloadf32 XForm:$src)),
3393fe6060f1SDimitry Andric          (COPY_TO_REGCLASS (LFSX XForm:$src), F8RC)>;
33940b57cec5SDimitry Andric
3395e8d8bef9SDimitry Andricdef : Pat<(f64 (any_fpextend f32:$src)),
33960b57cec5SDimitry Andric          (COPY_TO_REGCLASS $src, F8RC)>;
33970b57cec5SDimitry Andric}
33980b57cec5SDimitry Andric
33990b57cec5SDimitry Andric// Only seq_cst fences require the heavyweight sync (SYNC 0).
34000b57cec5SDimitry Andric// All others can use the lightweight sync (SYNC 1).
34010b57cec5SDimitry Andric// source: http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
34020b57cec5SDimitry Andric// The rule for seq_cst is duplicated to work with both 64 bits and 32 bits
34030b57cec5SDimitry Andric// versions of Power.
3404480093f4SDimitry Andricdef : Pat<(atomic_fence (i64 7), (timm)), (SYNC 0)>, Requires<[HasSYNC]>;
3405480093f4SDimitry Andricdef : Pat<(atomic_fence (i32 7), (timm)), (SYNC 0)>, Requires<[HasSYNC]>;
3406480093f4SDimitry Andricdef : Pat<(atomic_fence (timm), (timm)), (SYNC 1)>, Requires<[HasSYNC]>;
3407480093f4SDimitry Andricdef : Pat<(atomic_fence (timm), (timm)), (MSYNC)>, Requires<[HasOnlyMSYNC]>;
34080b57cec5SDimitry Andric
34090b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
34105ffd83dbSDimitry Andric// Additional fnmsub patterns for custom node
34115ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, f64:$C),
34125ffd83dbSDimitry Andric          (FNMSUB $A, $B, $C)>;
34135ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, f32:$C),
34145ffd83dbSDimitry Andric          (FNMSUBS $A, $B, $C)>;
34155ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f64:$A, f64:$B, f64:$C)),
34165ffd83dbSDimitry Andric          (FMSUB $A, $B, $C)>;
34175ffd83dbSDimitry Andricdef : Pat<(fneg (PPCfnmsub f32:$A, f32:$B, f32:$C)),
34185ffd83dbSDimitry Andric          (FMSUBS $A, $B, $C)>;
34195ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f64:$A, f64:$B, (fneg f64:$C)),
34205ffd83dbSDimitry Andric          (FNMADD $A, $B, $C)>;
34215ffd83dbSDimitry Andricdef : Pat<(PPCfnmsub f32:$A, f32:$B, (fneg f32:$C)),
34225ffd83dbSDimitry Andric          (FNMADDS $A, $B, $C)>;
34230b57cec5SDimitry Andric
34240b57cec5SDimitry Andric// FCOPYSIGN's operand types need not agree.
34250b57cec5SDimitry Andricdef : Pat<(fcopysign f64:$frB, f32:$frA),
34260b57cec5SDimitry Andric          (FCPSGND (COPY_TO_REGCLASS $frA, F8RC), $frB)>;
34270b57cec5SDimitry Andricdef : Pat<(fcopysign f32:$frB, f64:$frA),
34280b57cec5SDimitry Andric          (FCPSGNS (COPY_TO_REGCLASS $frA, F4RC), $frB)>;
34290b57cec5SDimitry Andric}
34300b57cec5SDimitry Andric
3431fe6060f1SDimitry Andric// XL Compat intrinsics.
3432fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsub f64:$A, f64:$B, f64:$C), (FMSUB $A, $B, $C)>;
3433fe6060f1SDimitry Andricdef : Pat<(int_ppc_fmsubs f32:$A, f32:$B, f32:$C), (FMSUBS $A, $B, $C)>;
3434fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadd f64:$A, f64:$B, f64:$C), (FNMADD $A, $B, $C)>;
3435fe6060f1SDimitry Andricdef : Pat<(int_ppc_fnmadds f32:$A, f32:$B, f32:$C), (FNMADDS $A, $B, $C)>;
3436fe6060f1SDimitry Andricdef : Pat<(int_ppc_fre f64:$A), (FRE $A)>;
3437fe6060f1SDimitry Andricdef : Pat<(int_ppc_fres f32:$A), (FRES $A)>;
343881ad6265SDimitry Andricdef : Pat<(int_ppc_fnabs f64:$A), (FNABSD $A)>;
343981ad6265SDimitry Andricdef : Pat<(int_ppc_fnabss f32:$A), (FNABSS $A)>;
3440fe6060f1SDimitry Andric
34410b57cec5SDimitry Andricinclude "PPCInstrAltivec.td"
34420b57cec5SDimitry Andricinclude "PPCInstrSPE.td"
34430b57cec5SDimitry Andricinclude "PPCInstr64Bit.td"
34440b57cec5SDimitry Andricinclude "PPCInstrVSX.td"
34450b57cec5SDimitry Andricinclude "PPCInstrHTM.td"
34460b57cec5SDimitry Andric
34470b57cec5SDimitry Andricdef crnot : OutPatFrag<(ops node:$in),
3448bdd1243dSDimitry Andric                       (CRNOT $in)>;
34490b57cec5SDimitry Andricdef       : Pat<(not i1:$in),
34500b57cec5SDimitry Andric                (crnot $in)>;
34510b57cec5SDimitry Andric
34525f757f3fSDimitry Andric// Pseudo-instructions for alternate assembly syntax (never used by codegen).
34535f757f3fSDimitry Andric// These are aliases that require C++ handling to convert to the target
34545f757f3fSDimitry Andric// instruction, while InstAliases can be handled directly by tblgen.
34555f757f3fSDimitry Andricclass PPCAsmPseudo<string asm, dag iops>
34565f757f3fSDimitry Andric  : Instruction {
34575f757f3fSDimitry Andric  let Namespace = "PPC";
34585f757f3fSDimitry Andric  bit PPC64 = 0;  // Default value, override with isPPC64
34595f757f3fSDimitry Andric
34605f757f3fSDimitry Andric  let OutOperandList = (outs);
34615f757f3fSDimitry Andric  let InOperandList = iops;
34625f757f3fSDimitry Andric  let Pattern = [];
34635f757f3fSDimitry Andric  let AsmString = asm;
34645f757f3fSDimitry Andric  let isAsmParserOnly = 1;
34655f757f3fSDimitry Andric  let isPseudo = 1;
34665f757f3fSDimitry Andric  let hasNoSchedulingInfo = 1;
34675f757f3fSDimitry Andric}
34685f757f3fSDimitry Andric
34695ffd83dbSDimitry Andric// Prefixed instructions may require access to the above defs at a later
34705ffd83dbSDimitry Andric// time so we include this after the def.
347181ad6265SDimitry Andricinclude "PPCInstrP10.td"
3472bdd1243dSDimitry Andricinclude "PPCInstrFutureMMA.td"
3473bdd1243dSDimitry Andricinclude "PPCInstrFuture.td"
347481ad6265SDimitry Andricinclude "PPCInstrMMA.td"
347506c3fb27SDimitry Andricinclude "PPCInstrDFP.td"
34765ffd83dbSDimitry Andric
34770b57cec5SDimitry Andric// Patterns for arithmetic i1 operations.
34780b57cec5SDimitry Andricdef : Pat<(add i1:$a, i1:$b),
34790b57cec5SDimitry Andric          (CRXOR $a, $b)>;
34800b57cec5SDimitry Andricdef : Pat<(sub i1:$a, i1:$b),
34810b57cec5SDimitry Andric          (CRXOR $a, $b)>;
34820b57cec5SDimitry Andricdef : Pat<(mul i1:$a, i1:$b),
34830b57cec5SDimitry Andric          (CRAND $a, $b)>;
34840b57cec5SDimitry Andric
34850b57cec5SDimitry Andric// We're sometimes asked to materialize i1 -1, which is just 1 in this case
34860b57cec5SDimitry Andric// (-1 is used to mean all bits set).
34870b57cec5SDimitry Andricdef : Pat<(i1 -1), (CRSET)>;
34880b57cec5SDimitry Andric
34890b57cec5SDimitry Andric// i1 extensions, implemented in terms of isel.
34900b57cec5SDimitry Andricdef : Pat<(i32 (zext i1:$in)),
34910b57cec5SDimitry Andric          (SELECT_I4 $in, (LI 1), (LI 0))>;
34920b57cec5SDimitry Andricdef : Pat<(i32 (sext i1:$in)),
34930b57cec5SDimitry Andric          (SELECT_I4 $in, (LI -1), (LI 0))>;
34940b57cec5SDimitry Andric
34950b57cec5SDimitry Andricdef : Pat<(i64 (zext i1:$in)),
34960b57cec5SDimitry Andric          (SELECT_I8 $in, (LI8 1), (LI8 0))>;
34970b57cec5SDimitry Andricdef : Pat<(i64 (sext i1:$in)),
34980b57cec5SDimitry Andric          (SELECT_I8 $in, (LI8 -1), (LI8 0))>;
34990b57cec5SDimitry Andric
35000b57cec5SDimitry Andric// FIXME: We should choose either a zext or a sext based on other constants
35010b57cec5SDimitry Andric// already around.
35020b57cec5SDimitry Andricdef : Pat<(i32 (anyext i1:$in)),
350306c3fb27SDimitry Andric          (SELECT_I4 $in, (LI 1), (LI 0))>;
35040b57cec5SDimitry Andricdef : Pat<(i64 (anyext i1:$in)),
350506c3fb27SDimitry Andric          (SELECT_I8 $in, (LI8 1), (LI8 0))>;
35060b57cec5SDimitry Andric
35070b57cec5SDimitry Andric// match setcc on i1 variables.
35080b57cec5SDimitry Andric// CRANDC is:
35090b57cec5SDimitry Andric//   1 1 : F
35100b57cec5SDimitry Andric//   1 0 : T
35110b57cec5SDimitry Andric//   0 1 : F
35120b57cec5SDimitry Andric//   0 0 : F
35130b57cec5SDimitry Andric//
35140b57cec5SDimitry Andric// LT is:
35150b57cec5SDimitry Andric//  -1 -1  : F
35160b57cec5SDimitry Andric//  -1  0  : T
35170b57cec5SDimitry Andric//   0 -1  : F
35180b57cec5SDimitry Andric//   0  0  : F
35190b57cec5SDimitry Andric//
35200b57cec5SDimitry Andric// ULT is:
35210b57cec5SDimitry Andric//   1 1 : F
35220b57cec5SDimitry Andric//   1 0 : F
35230b57cec5SDimitry Andric//   0 1 : T
35240b57cec5SDimitry Andric//   0 0 : F
35250b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETLT)),
35260b57cec5SDimitry Andric          (CRANDC $s1, $s2)>;
35270b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETULT)),
35280b57cec5SDimitry Andric          (CRANDC $s2, $s1)>;
35290b57cec5SDimitry Andric// CRORC is:
35300b57cec5SDimitry Andric//   1 1 : T
35310b57cec5SDimitry Andric//   1 0 : T
35320b57cec5SDimitry Andric//   0 1 : F
35330b57cec5SDimitry Andric//   0 0 : T
35340b57cec5SDimitry Andric//
35350b57cec5SDimitry Andric// LE is:
35360b57cec5SDimitry Andric//  -1 -1 : T
35370b57cec5SDimitry Andric//  -1  0 : T
35380b57cec5SDimitry Andric//   0 -1 : F
35390b57cec5SDimitry Andric//   0  0 : T
35400b57cec5SDimitry Andric//
35410b57cec5SDimitry Andric// ULE is:
35420b57cec5SDimitry Andric//   1 1 : T
35430b57cec5SDimitry Andric//   1 0 : F
35440b57cec5SDimitry Andric//   0 1 : T
35450b57cec5SDimitry Andric//   0 0 : T
35460b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETLE)),
35470b57cec5SDimitry Andric          (CRORC $s1, $s2)>;
35480b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETULE)),
35490b57cec5SDimitry Andric          (CRORC $s2, $s1)>;
35500b57cec5SDimitry Andric
35510b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETEQ)),
35520b57cec5SDimitry Andric          (CREQV $s1, $s2)>;
35530b57cec5SDimitry Andric
35540b57cec5SDimitry Andric// GE is:
35550b57cec5SDimitry Andric//  -1 -1 : T
35560b57cec5SDimitry Andric//  -1  0 : F
35570b57cec5SDimitry Andric//   0 -1 : T
35580b57cec5SDimitry Andric//   0  0 : T
35590b57cec5SDimitry Andric//
35600b57cec5SDimitry Andric// UGE is:
35610b57cec5SDimitry Andric//   1 1 : T
35620b57cec5SDimitry Andric//   1 0 : T
35630b57cec5SDimitry Andric//   0 1 : F
35640b57cec5SDimitry Andric//   0 0 : T
35650b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETGE)),
35660b57cec5SDimitry Andric          (CRORC $s2, $s1)>;
35670b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETUGE)),
35680b57cec5SDimitry Andric          (CRORC $s1, $s2)>;
35690b57cec5SDimitry Andric
35700b57cec5SDimitry Andric// GT is:
35710b57cec5SDimitry Andric//  -1 -1 : F
35720b57cec5SDimitry Andric//  -1  0 : F
35730b57cec5SDimitry Andric//   0 -1 : T
35740b57cec5SDimitry Andric//   0  0 : F
35750b57cec5SDimitry Andric//
35760b57cec5SDimitry Andric// UGT is:
35770b57cec5SDimitry Andric//  1 1 : F
35780b57cec5SDimitry Andric//  1 0 : T
35790b57cec5SDimitry Andric//  0 1 : F
35800b57cec5SDimitry Andric//  0 0 : F
35810b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETGT)),
35820b57cec5SDimitry Andric          (CRANDC $s2, $s1)>;
35830b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETUGT)),
35840b57cec5SDimitry Andric          (CRANDC $s1, $s2)>;
35850b57cec5SDimitry Andric
35860b57cec5SDimitry Andricdef : Pat<(i1 (setcc i1:$s1, i1:$s2, SETNE)),
35870b57cec5SDimitry Andric          (CRXOR $s1, $s2)>;
35880b57cec5SDimitry Andric
35890b57cec5SDimitry Andric// match setcc on non-i1 (non-vector) variables. Note that SETUEQ, SETOGE,
35900b57cec5SDimitry Andric// SETOLE, SETONE, SETULT and SETUGT should be expanded by legalize for
35910b57cec5SDimitry Andric// floating-point types.
35920b57cec5SDimitry Andric
35930b57cec5SDimitry Andricmulticlass CRNotPat<dag pattern, dag result> {
35940b57cec5SDimitry Andric  def : Pat<pattern, (crnot result)>;
35950b57cec5SDimitry Andric  def : Pat<(not pattern), result>;
35960b57cec5SDimitry Andric
35970b57cec5SDimitry Andric  // We can also fold the crnot into an extension:
35980b57cec5SDimitry Andric  def : Pat<(i32 (zext pattern)),
35990b57cec5SDimitry Andric            (SELECT_I4 result, (LI 0), (LI 1))>;
36000b57cec5SDimitry Andric  def : Pat<(i32 (sext pattern)),
36010b57cec5SDimitry Andric            (SELECT_I4 result, (LI 0), (LI -1))>;
36020b57cec5SDimitry Andric
36030b57cec5SDimitry Andric  // We can also fold the crnot into an extension:
36040b57cec5SDimitry Andric  def : Pat<(i64 (zext pattern)),
36050b57cec5SDimitry Andric            (SELECT_I8 result, (LI8 0), (LI8 1))>;
36060b57cec5SDimitry Andric  def : Pat<(i64 (sext pattern)),
36070b57cec5SDimitry Andric            (SELECT_I8 result, (LI8 0), (LI8 -1))>;
36080b57cec5SDimitry Andric
36090b57cec5SDimitry Andric  // FIXME: We should choose either a zext or a sext based on other constants
36100b57cec5SDimitry Andric  // already around.
36110b57cec5SDimitry Andric  def : Pat<(i32 (anyext pattern)),
36120b57cec5SDimitry Andric            (SELECT_I4 result, (LI 0), (LI 1))>;
36130b57cec5SDimitry Andric
36140b57cec5SDimitry Andric  def : Pat<(i64 (anyext pattern)),
36150b57cec5SDimitry Andric            (SELECT_I8 result, (LI8 0), (LI8 1))>;
36160b57cec5SDimitry Andric}
36170b57cec5SDimitry Andric
36180b57cec5SDimitry Andric// FIXME: Because of what seems like a bug in TableGen's type-inference code,
36190b57cec5SDimitry Andric// we need to write imm:$imm in the output patterns below, not just $imm, or
36200b57cec5SDimitry Andric// else the resulting matcher will not correctly add the immediate operand
36210b57cec5SDimitry Andric// (making it a register operand instead).
36220b57cec5SDimitry Andric
36230b57cec5SDimitry Andric// extended SETCC.
36240b57cec5SDimitry Andricmulticlass ExtSetCCPat<CondCode cc, PatFrag pfrag,
36250b57cec5SDimitry Andric                       OutPatFrag rfrag, OutPatFrag rfrag8> {
36260b57cec5SDimitry Andric  def : Pat<(i32 (zext (i1 (pfrag i32:$s1, cc)))),
36270b57cec5SDimitry Andric            (rfrag $s1)>;
36280b57cec5SDimitry Andric  def : Pat<(i64 (zext (i1 (pfrag i64:$s1, cc)))),
36290b57cec5SDimitry Andric            (rfrag8 $s1)>;
36300b57cec5SDimitry Andric  def : Pat<(i64 (zext (i1 (pfrag i32:$s1, cc)))),
36310b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (rfrag $s1), sub_32)>;
36320b57cec5SDimitry Andric  def : Pat<(i32 (zext (i1 (pfrag i64:$s1, cc)))),
36330b57cec5SDimitry Andric            (EXTRACT_SUBREG (rfrag8 $s1), sub_32)>;
36340b57cec5SDimitry Andric
36350b57cec5SDimitry Andric  def : Pat<(i32 (anyext (i1 (pfrag i32:$s1, cc)))),
36360b57cec5SDimitry Andric            (rfrag $s1)>;
36370b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i1 (pfrag i64:$s1, cc)))),
36380b57cec5SDimitry Andric            (rfrag8 $s1)>;
36390b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i1 (pfrag i32:$s1, cc)))),
36400b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (rfrag $s1), sub_32)>;
36410b57cec5SDimitry Andric  def : Pat<(i32 (anyext (i1 (pfrag i64:$s1, cc)))),
36420b57cec5SDimitry Andric            (EXTRACT_SUBREG (rfrag8 $s1), sub_32)>;
36430b57cec5SDimitry Andric}
36440b57cec5SDimitry Andric
36450b57cec5SDimitry Andric// Note that we do all inversions below with i(32|64)not, instead of using
36460b57cec5SDimitry Andric// (xori x, 1) because on the A2 nor has single-cycle latency while xori
36470b57cec5SDimitry Andric// has 2-cycle latency.
36480b57cec5SDimitry Andric
36490b57cec5SDimitry Andricdefm : ExtSetCCPat<SETEQ,
36500b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36510b57cec5SDimitry Andric                           (setcc $in, 0, $cc)>,
36520b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36530b57cec5SDimitry Andric                              (RLWINM (CNTLZW $in), 27, 31, 31)>,
36540b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36550b57cec5SDimitry Andric                              (RLDICL (CNTLZD $in), 58, 63)> >;
36560b57cec5SDimitry Andric
36570b57cec5SDimitry Andricdefm : ExtSetCCPat<SETNE,
36580b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36590b57cec5SDimitry Andric                           (setcc $in, 0, $cc)>,
36600b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36610b57cec5SDimitry Andric                              (RLWINM (i32not (CNTLZW $in)), 27, 31, 31)>,
36620b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36630b57cec5SDimitry Andric                              (RLDICL (i64not (CNTLZD $in)), 58, 63)> >;
36640b57cec5SDimitry Andric
36650b57cec5SDimitry Andricdefm : ExtSetCCPat<SETLT,
36660b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36670b57cec5SDimitry Andric                           (setcc $in, 0, $cc)>,
36680b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36690b57cec5SDimitry Andric                              (RLWINM $in, 1, 31, 31)>,
36700b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36710b57cec5SDimitry Andric                              (RLDICL $in, 1, 63)> >;
36720b57cec5SDimitry Andric
36730b57cec5SDimitry Andricdefm : ExtSetCCPat<SETGE,
36740b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36750b57cec5SDimitry Andric                           (setcc $in, 0, $cc)>,
36760b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36770b57cec5SDimitry Andric                              (RLWINM (i32not $in), 1, 31, 31)>,
36780b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36790b57cec5SDimitry Andric                              (RLDICL (i64not $in), 1, 63)> >;
36800b57cec5SDimitry Andric
36810b57cec5SDimitry Andricdefm : ExtSetCCPat<SETGT,
36820b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36830b57cec5SDimitry Andric                           (setcc $in, 0, $cc)>,
36840b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36850b57cec5SDimitry Andric                              (RLWINM (ANDC (NEG $in), $in), 1, 31, 31)>,
36860b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36870b57cec5SDimitry Andric                              (RLDICL (ANDC8 (NEG8 $in), $in), 1, 63)> >;
36880b57cec5SDimitry Andric
36890b57cec5SDimitry Andricdefm : ExtSetCCPat<SETLE,
36900b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36910b57cec5SDimitry Andric                           (setcc $in, 0, $cc)>,
36920b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36930b57cec5SDimitry Andric                              (RLWINM (ORC $in, (NEG $in)), 1, 31, 31)>,
36940b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
36950b57cec5SDimitry Andric                              (RLDICL (ORC8 $in, (NEG8 $in)), 1, 63)> >;
36960b57cec5SDimitry Andric
36970b57cec5SDimitry Andricdefm : ExtSetCCPat<SETLT,
36980b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
36990b57cec5SDimitry Andric                           (setcc $in, -1, $cc)>,
37000b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37010b57cec5SDimitry Andric                              (RLWINM (AND $in, (ADDI $in, 1)), 1, 31, 31)>,
37020b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37030b57cec5SDimitry Andric                              (RLDICL (AND8 $in, (ADDI8 $in, 1)), 1, 63)> >;
37040b57cec5SDimitry Andric
37050b57cec5SDimitry Andricdefm : ExtSetCCPat<SETGE,
37060b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
37070b57cec5SDimitry Andric                           (setcc $in, -1, $cc)>,
37080b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37090b57cec5SDimitry Andric                              (RLWINM (NAND $in, (ADDI $in, 1)), 1, 31, 31)>,
37100b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37110b57cec5SDimitry Andric                              (RLDICL (NAND8 $in, (ADDI8 $in, 1)), 1, 63)> >;
37120b57cec5SDimitry Andric
37130b57cec5SDimitry Andricdefm : ExtSetCCPat<SETGT,
37140b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
37150b57cec5SDimitry Andric                           (setcc $in, -1, $cc)>,
37160b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37170b57cec5SDimitry Andric                              (RLWINM (i32not $in), 1, 31, 31)>,
37180b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37190b57cec5SDimitry Andric                              (RLDICL (i64not $in), 1, 63)> >;
37200b57cec5SDimitry Andric
37210b57cec5SDimitry Andricdefm : ExtSetCCPat<SETLE,
37220b57cec5SDimitry Andric                   PatFrag<(ops node:$in, node:$cc),
37230b57cec5SDimitry Andric                           (setcc $in, -1, $cc)>,
37240b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37250b57cec5SDimitry Andric                              (RLWINM $in, 1, 31, 31)>,
37260b57cec5SDimitry Andric                   OutPatFrag<(ops node:$in),
37270b57cec5SDimitry Andric                              (RLDICL $in, 1, 63)> >;
37280b57cec5SDimitry Andric
37290b57cec5SDimitry Andric// An extended SETCC with shift amount.
37300b57cec5SDimitry Andricmulticlass ExtSetCCShiftPat<CondCode cc, PatFrag pfrag,
37310b57cec5SDimitry Andric                            OutPatFrag rfrag, OutPatFrag rfrag8> {
37320b57cec5SDimitry Andric  def : Pat<(i32 (zext (i1 (pfrag i32:$s1, i32:$sa, cc)))),
37330b57cec5SDimitry Andric            (rfrag $s1, $sa)>;
37340b57cec5SDimitry Andric  def : Pat<(i64 (zext (i1 (pfrag i64:$s1, i32:$sa, cc)))),
37350b57cec5SDimitry Andric            (rfrag8 $s1, $sa)>;
37360b57cec5SDimitry Andric  def : Pat<(i64 (zext (i1 (pfrag i32:$s1, i32:$sa, cc)))),
37370b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (rfrag $s1, $sa), sub_32)>;
37380b57cec5SDimitry Andric  def : Pat<(i32 (zext (i1 (pfrag i64:$s1, i32:$sa, cc)))),
37390b57cec5SDimitry Andric            (EXTRACT_SUBREG (rfrag8 $s1, $sa), sub_32)>;
37400b57cec5SDimitry Andric
37410b57cec5SDimitry Andric  def : Pat<(i32 (anyext (i1 (pfrag i32:$s1, i32:$sa, cc)))),
37420b57cec5SDimitry Andric            (rfrag $s1, $sa)>;
37430b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i1 (pfrag i64:$s1, i32:$sa, cc)))),
37440b57cec5SDimitry Andric            (rfrag8 $s1, $sa)>;
37450b57cec5SDimitry Andric  def : Pat<(i64 (anyext (i1 (pfrag i32:$s1, i32:$sa, cc)))),
37460b57cec5SDimitry Andric            (INSERT_SUBREG (i64 (IMPLICIT_DEF)), (rfrag $s1, $sa), sub_32)>;
37470b57cec5SDimitry Andric  def : Pat<(i32 (anyext (i1 (pfrag i64:$s1, i32:$sa, cc)))),
37480b57cec5SDimitry Andric            (EXTRACT_SUBREG (rfrag8 $s1, $sa), sub_32)>;
37490b57cec5SDimitry Andric}
37500b57cec5SDimitry Andric
37510b57cec5SDimitry Andricdefm : ExtSetCCShiftPat<SETNE,
37520b57cec5SDimitry Andric                        PatFrag<(ops node:$in, node:$sa, node:$cc),
37530b57cec5SDimitry Andric                                (setcc (and $in, (shl 1, $sa)), 0, $cc)>,
37540b57cec5SDimitry Andric                        OutPatFrag<(ops node:$in, node:$sa),
37550b57cec5SDimitry Andric                                   (RLWNM $in, (SUBFIC $sa, 32), 31, 31)>,
37560b57cec5SDimitry Andric                        OutPatFrag<(ops node:$in, node:$sa),
37570b57cec5SDimitry Andric                                   (RLDCL $in, (SUBFIC $sa, 64), 63)> >;
37580b57cec5SDimitry Andric
37590b57cec5SDimitry Andricdefm : ExtSetCCShiftPat<SETEQ,
37600b57cec5SDimitry Andric                        PatFrag<(ops node:$in, node:$sa, node:$cc),
37610b57cec5SDimitry Andric                                (setcc (and $in, (shl 1, $sa)), 0, $cc)>,
37620b57cec5SDimitry Andric                        OutPatFrag<(ops node:$in, node:$sa),
37630b57cec5SDimitry Andric                                   (RLWNM (i32not $in),
37640b57cec5SDimitry Andric                                          (SUBFIC $sa, 32), 31, 31)>,
37650b57cec5SDimitry Andric                        OutPatFrag<(ops node:$in, node:$sa),
37660b57cec5SDimitry Andric                                   (RLDCL (i64not $in),
37670b57cec5SDimitry Andric                                          (SUBFIC $sa, 64), 63)> >;
37680b57cec5SDimitry Andric
37690b57cec5SDimitry Andric// SETCC for i32.
37700b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, immZExt16:$imm, SETULT)),
37710b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_lt)>;
37720b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, imm32SExt16:$imm, SETLT)),
37730b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPWI $s1, imm:$imm), sub_lt)>;
37740b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, immZExt16:$imm, SETUGT)),
37750b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_gt)>;
37760b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, imm32SExt16:$imm, SETGT)),
37770b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPWI $s1, imm:$imm), sub_gt)>;
37780b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, imm32SExt16:$imm, SETEQ)),
37790b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPWI $s1, imm:$imm), sub_eq)>;
37800b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, immZExt16:$imm, SETEQ)),
37810b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_eq)>;
37820b57cec5SDimitry Andric
37830b57cec5SDimitry Andric// For non-equality comparisons, the default code would materialize the
37840b57cec5SDimitry Andric// constant, then compare against it, like this:
37850b57cec5SDimitry Andric//   lis r2, 4660
37860b57cec5SDimitry Andric//   ori r2, r2, 22136
37870b57cec5SDimitry Andric//   cmpw cr0, r3, r2
37880b57cec5SDimitry Andric//   beq cr0,L6
37890b57cec5SDimitry Andric// Since we are just comparing for equality, we can emit this instead:
37900b57cec5SDimitry Andric//   xoris r0,r3,0x1234
37910b57cec5SDimitry Andric//   cmplwi cr0,r0,0x5678
37920b57cec5SDimitry Andric//   beq cr0,L6
37930b57cec5SDimitry Andric
37940b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, imm:$imm, SETEQ)),
37950b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLWI (XORIS $s1, (HI16 imm:$imm)),
37960b57cec5SDimitry Andric                                  (LO16 imm:$imm)), sub_eq)>;
37970b57cec5SDimitry Andric
37980b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, i32:$s2, SETULT)),
37990b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLW $s1, $s2), sub_lt)>;
38000b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, i32:$s2, SETLT)),
38010b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPW $s1, $s2), sub_lt)>;
38020b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, i32:$s2, SETUGT)),
38030b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLW $s1, $s2), sub_gt)>;
38040b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, i32:$s2, SETGT)),
38050b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPW $s1, $s2), sub_gt)>;
38060b57cec5SDimitry Andricdef : Pat<(i1 (setcc i32:$s1, i32:$s2, SETEQ)),
38070b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPW $s1, $s2), sub_eq)>;
38080b57cec5SDimitry Andric
38090b57cec5SDimitry Andric// SETCC for i64.
38100b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, immZExt16:$imm, SETULT)),
38110b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLDI $s1, imm:$imm), sub_lt)>;
38120b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, imm64SExt16:$imm, SETLT)),
38130b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPDI $s1, imm:$imm), sub_lt)>;
38140b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, immZExt16:$imm, SETUGT)),
38150b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLDI $s1, imm:$imm), sub_gt)>;
38160b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, imm64SExt16:$imm, SETGT)),
38170b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPDI $s1, imm:$imm), sub_gt)>;
38180b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, imm64SExt16:$imm, SETEQ)),
38190b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPDI $s1, imm:$imm), sub_eq)>;
38200b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, immZExt16:$imm, SETEQ)),
38210b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLDI $s1, imm:$imm), sub_eq)>;
38220b57cec5SDimitry Andric
38230b57cec5SDimitry Andric// For non-equality comparisons, the default code would materialize the
38240b57cec5SDimitry Andric// constant, then compare against it, like this:
38250b57cec5SDimitry Andric//   lis r2, 4660
38260b57cec5SDimitry Andric//   ori r2, r2, 22136
38270b57cec5SDimitry Andric//   cmpd cr0, r3, r2
38280b57cec5SDimitry Andric//   beq cr0,L6
38290b57cec5SDimitry Andric// Since we are just comparing for equality, we can emit this instead:
38300b57cec5SDimitry Andric//   xoris r0,r3,0x1234
38310b57cec5SDimitry Andric//   cmpldi cr0,r0,0x5678
38320b57cec5SDimitry Andric//   beq cr0,L6
38330b57cec5SDimitry Andric
38340b57cec5SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, imm64ZExt32:$imm, SETEQ)),
38350b57cec5SDimitry Andric          (EXTRACT_SUBREG (CMPLDI (XORIS8 $s1, (HI16 imm:$imm)),
38360b57cec5SDimitry Andric                                  (LO16 imm:$imm)), sub_eq)>;
38370b57cec5SDimitry Andric
38388bcb0991SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, i64:$s2, SETULT)),
38398bcb0991SDimitry Andric          (EXTRACT_SUBREG (CMPLD $s1, $s2), sub_lt)>;
38408bcb0991SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, i64:$s2, SETLT)),
38418bcb0991SDimitry Andric          (EXTRACT_SUBREG (CMPD $s1, $s2), sub_lt)>;
38428bcb0991SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, i64:$s2, SETUGT)),
38438bcb0991SDimitry Andric          (EXTRACT_SUBREG (CMPLD $s1, $s2), sub_gt)>;
38448bcb0991SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, i64:$s2, SETGT)),
38458bcb0991SDimitry Andric          (EXTRACT_SUBREG (CMPD $s1, $s2), sub_gt)>;
38468bcb0991SDimitry Andricdef : Pat<(i1 (setcc i64:$s1, i64:$s2, SETEQ)),
38478bcb0991SDimitry Andric          (EXTRACT_SUBREG (CMPD $s1, $s2), sub_eq)>;
38488bcb0991SDimitry Andric
3849e8d8bef9SDimitry Andriclet Predicates = [IsNotISA3_1] in {
38508bcb0991SDimitry Andric// Instantiations of CRNotPat for i32.
38518bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, immZExt16:$imm, SETUGE)),
38528bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_lt)>;
38538bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, imm32SExt16:$imm, SETGE)),
38548bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPWI $s1, imm:$imm), sub_lt)>;
38558bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, immZExt16:$imm, SETULE)),
38568bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_gt)>;
38578bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, imm32SExt16:$imm, SETLE)),
38588bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPWI $s1, imm:$imm), sub_gt)>;
38598bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, imm32SExt16:$imm, SETNE)),
38608bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPWI $s1, imm:$imm), sub_eq)>;
38618bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, immZExt16:$imm, SETNE)),
38628bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPLWI $s1, imm:$imm), sub_eq)>;
38638bcb0991SDimitry Andric
38648bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, imm:$imm, SETNE)),
38658bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPLWI (XORIS $s1, (HI16 imm:$imm)),
38668bcb0991SDimitry Andric                                        (LO16 imm:$imm)), sub_eq)>;
38678bcb0991SDimitry Andric
38688bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, i32:$s2, SETUGE)),
38698bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPLW $s1, $s2), sub_lt)>;
38708bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, i32:$s2, SETGE)),
38718bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPW $s1, $s2), sub_lt)>;
38728bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, i32:$s2, SETULE)),
38738bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPLW $s1, $s2), sub_gt)>;
38748bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, i32:$s2, SETLE)),
38758bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPW $s1, $s2), sub_gt)>;
38768bcb0991SDimitry Andricdefm : CRNotPat<(i1 (setcc i32:$s1, i32:$s2, SETNE)),
38778bcb0991SDimitry Andric                (EXTRACT_SUBREG (CMPW $s1, $s2), sub_eq)>;
38788bcb0991SDimitry Andric
38798bcb0991SDimitry Andric// Instantiations of CRNotPat for i64.
38800b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, immZExt16:$imm, SETUGE)),
38810b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPLDI $s1, imm:$imm), sub_lt)>;
38820b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, imm64SExt16:$imm, SETGE)),
38830b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPDI $s1, imm:$imm), sub_lt)>;
38840b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, immZExt16:$imm, SETULE)),
38850b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPLDI $s1, imm:$imm), sub_gt)>;
38860b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, imm64SExt16:$imm, SETLE)),
38870b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPDI $s1, imm:$imm), sub_gt)>;
38880b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, imm64SExt16:$imm, SETNE)),
38890b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPDI $s1, imm:$imm), sub_eq)>;
38900b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, immZExt16:$imm, SETNE)),
38910b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPLDI $s1, imm:$imm), sub_eq)>;
38920b57cec5SDimitry Andric
38930b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, imm64ZExt32:$imm, SETNE)),
38940b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPLDI (XORIS8 $s1, (HI16 imm:$imm)),
38950b57cec5SDimitry Andric                                        (LO16 imm:$imm)), sub_eq)>;
38960b57cec5SDimitry Andric
38970b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETUGE)),
38980b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPLD $s1, $s2), sub_lt)>;
38990b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETGE)),
39000b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPD $s1, $s2), sub_lt)>;
39010b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETULE)),
39020b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPLD $s1, $s2), sub_gt)>;
39030b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETLE)),
39040b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPD $s1, $s2), sub_gt)>;
39050b57cec5SDimitry Andricdefm : CRNotPat<(i1 (setcc i64:$s1, i64:$s2, SETNE)),
39060b57cec5SDimitry Andric                (EXTRACT_SUBREG (CMPD $s1, $s2), sub_eq)>;
39078bcb0991SDimitry Andric}
39088bcb0991SDimitry Andric
3909fe6060f1SDimitry Andricmulticlass FSetCCPat<SDPatternOperator SetCC, ValueType Ty, I FCmp> {
3910e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUGE)),
391106c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
3912e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGE)),
391306c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
3914e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETULE)),
391506c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
3916e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLE)),
391706c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
3918e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUNE)),
391906c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
3920e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETNE)),
392106c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
3922e8d8bef9SDimitry Andric  defm : CRNotPat<(i1 (SetCC Ty:$s1, Ty:$s2, SETO)),
392306c3fb27SDimitry Andric                  (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
3924e8d8bef9SDimitry Andric
3925e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOLT)),
392606c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
3927e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETLT)),
392806c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_lt)>;
3929e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOGT)),
393006c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
3931e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETGT)),
393206c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_gt)>;
3933e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETOEQ)),
393406c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
3935e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETEQ)),
393606c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_eq)>;
3937e8d8bef9SDimitry Andric  def : Pat<(i1 (SetCC Ty:$s1, Ty:$s2, SETUO)),
393806c3fb27SDimitry Andric            (EXTRACT_SUBREG (FCmp $s1, $s2), sub_un)>;
3939e8d8bef9SDimitry Andric}
3940e8d8bef9SDimitry Andric
39410b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
3942e8d8bef9SDimitry Andric// FCMPU: If either of the operands is a Signaling NaN, then VXSNAN is set.
3943e8d8bef9SDimitry Andric// SETCC for f32.
3944e8d8bef9SDimitry Andricdefm : FSetCCPat<any_fsetcc, f32, FCMPUS>;
39450b57cec5SDimitry Andric
39460b57cec5SDimitry Andric// SETCC for f64.
3947e8d8bef9SDimitry Andricdefm : FSetCCPat<any_fsetcc, f64, FCMPUD>;
39480b57cec5SDimitry Andric
39490b57cec5SDimitry Andric// SETCC for f128.
3950e8d8bef9SDimitry Andricdefm : FSetCCPat<any_fsetcc, f128, XSCMPUQP>;
39510b57cec5SDimitry Andric
3952e8d8bef9SDimitry Andric// FCMPO: If either of the operands is a Signaling NaN, then VXSNAN is set and,
3953e8d8bef9SDimitry Andric// if neither operand is a Signaling NaN but at least one operand is a Quiet NaN,
3954e8d8bef9SDimitry Andric// then VXVC is set.
3955e8d8bef9SDimitry Andric// SETCCS for f32.
3956e8d8bef9SDimitry Andricdefm : FSetCCPat<strict_fsetccs, f32, FCMPOS>;
3957e8d8bef9SDimitry Andric
3958e8d8bef9SDimitry Andric// SETCCS for f64.
3959e8d8bef9SDimitry Andricdefm : FSetCCPat<strict_fsetccs, f64, FCMPOD>;
3960e8d8bef9SDimitry Andric
3961e8d8bef9SDimitry Andric// SETCCS for f128.
3962e8d8bef9SDimitry Andricdefm : FSetCCPat<strict_fsetccs, f128, XSCMPOQP>;
39630b57cec5SDimitry Andric}
39640b57cec5SDimitry Andric
39650b57cec5SDimitry Andric// This must be in this file because it relies on patterns defined in this file
39660b57cec5SDimitry Andric// after the inclusion of the instruction sets.
39670b57cec5SDimitry Andriclet Predicates = [HasSPE] in {
39680b57cec5SDimitry Andric// SETCC for f32.
3969fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETOLT)),
39700b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
3971fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETLT)),
39720b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
3973fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETOGT)),
39740b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
3975fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETGT)),
39760b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
3977fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETOEQ)),
39780b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
3979fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETEQ)),
39800b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
39810b57cec5SDimitry Andric
3982fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETUGE)),
39830b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
3984fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETGE)),
39850b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFSCMPLT $s1, $s2), sub_gt)>;
3986fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETULE)),
39870b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
3988fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETLE)),
39890b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFSCMPGT $s1, $s2), sub_gt)>;
3990fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETUNE)),
39910b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
3992fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f32:$s1, f32:$s2, SETNE)),
39930b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFSCMPEQ $s1, $s2), sub_gt)>;
39940b57cec5SDimitry Andric
39950b57cec5SDimitry Andric// SETCC for f64.
3996fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETOLT)),
39970b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
3998fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETLT)),
39990b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
4000fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETOGT)),
40010b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
4002fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETGT)),
40030b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
4004fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETOEQ)),
40050b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
4006fe6060f1SDimitry Andricdef : Pat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETEQ)),
40070b57cec5SDimitry Andric          (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
40080b57cec5SDimitry Andric
4009fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETUGE)),
40100b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
4011fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETGE)),
40120b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFDCMPLT $s1, $s2), sub_gt)>;
4013fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETULE)),
40140b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
4015fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETLE)),
40160b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFDCMPGT $s1, $s2), sub_gt)>;
4017fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETUNE)),
40180b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
4019fe6060f1SDimitry Andricdefm : CRNotPat<(i1 (any_fsetccs f64:$s1, f64:$s2, SETNE)),
40200b57cec5SDimitry Andric                (EXTRACT_SUBREG (EFDCMPEQ $s1, $s2), sub_gt)>;
40210b57cec5SDimitry Andric}
40220b57cec5SDimitry Andric// match select on i1 variables:
40230b57cec5SDimitry Andricdef : Pat<(i1 (select i1:$cond, i1:$tval, i1:$fval)),
40240b57cec5SDimitry Andric          (CROR (CRAND        $cond , $tval),
40250b57cec5SDimitry Andric                (CRAND (crnot $cond), $fval))>;
40260b57cec5SDimitry Andric
40270b57cec5SDimitry Andric// match selectcc on i1 variables:
40280b57cec5SDimitry Andric//   select (lhs == rhs), tval, fval is:
40290b57cec5SDimitry Andric//   ((lhs == rhs) & tval) | (!(lhs == rhs) & fval)
40300b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETLT)),
40310b57cec5SDimitry Andric           (CROR (CRAND (CRANDC $lhs, $rhs), $tval),
40320b57cec5SDimitry Andric                 (CRAND (CRORC  $rhs, $lhs), $fval))>;
40330b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETULT)),
40340b57cec5SDimitry Andric           (CROR (CRAND (CRANDC $rhs, $lhs), $tval),
40350b57cec5SDimitry Andric                 (CRAND (CRORC  $lhs, $rhs), $fval))>;
40360b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETLE)),
40370b57cec5SDimitry Andric           (CROR (CRAND (CRORC  $lhs, $rhs), $tval),
40380b57cec5SDimitry Andric                 (CRAND (CRANDC $rhs, $lhs), $fval))>;
40390b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETULE)),
40400b57cec5SDimitry Andric           (CROR (CRAND (CRORC  $rhs, $lhs), $tval),
40410b57cec5SDimitry Andric                 (CRAND (CRANDC $lhs, $rhs), $fval))>;
40420b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETEQ)),
40430b57cec5SDimitry Andric           (CROR (CRAND (CREQV $lhs, $rhs), $tval),
40440b57cec5SDimitry Andric                 (CRAND (CRXOR $lhs, $rhs), $fval))>;
40450b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETGE)),
40460b57cec5SDimitry Andric           (CROR (CRAND (CRORC  $rhs, $lhs), $tval),
40470b57cec5SDimitry Andric                 (CRAND (CRANDC $lhs, $rhs), $fval))>;
40480b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETUGE)),
40490b57cec5SDimitry Andric           (CROR (CRAND (CRORC  $lhs, $rhs), $tval),
40500b57cec5SDimitry Andric                 (CRAND (CRANDC $rhs, $lhs), $fval))>;
40510b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETGT)),
40520b57cec5SDimitry Andric           (CROR (CRAND (CRANDC $rhs, $lhs), $tval),
40530b57cec5SDimitry Andric                 (CRAND (CRORC  $lhs, $rhs), $fval))>;
40540b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETUGT)),
40550b57cec5SDimitry Andric           (CROR (CRAND (CRANDC $lhs, $rhs), $tval),
40560b57cec5SDimitry Andric                 (CRAND (CRORC  $rhs, $lhs), $fval))>;
40570b57cec5SDimitry Andricdef : Pat <(i1 (selectcc i1:$lhs, i1:$rhs, i1:$tval, i1:$fval, SETNE)),
40580b57cec5SDimitry Andric           (CROR (CRAND (CREQV $lhs, $rhs), $fval),
40590b57cec5SDimitry Andric                 (CRAND (CRXOR $lhs, $rhs), $tval))>;
40600b57cec5SDimitry Andric
40610b57cec5SDimitry Andric// match selectcc on i1 variables with non-i1 output.
40620b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETLT)),
40630b57cec5SDimitry Andric          (SELECT_I4 (CRANDC $lhs, $rhs), $tval, $fval)>;
40640b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETULT)),
40650b57cec5SDimitry Andric          (SELECT_I4 (CRANDC $rhs, $lhs), $tval, $fval)>;
40660b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETLE)),
40670b57cec5SDimitry Andric          (SELECT_I4 (CRORC  $lhs, $rhs), $tval, $fval)>;
40680b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETULE)),
40690b57cec5SDimitry Andric          (SELECT_I4 (CRORC  $rhs, $lhs), $tval, $fval)>;
40700b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETEQ)),
40710b57cec5SDimitry Andric          (SELECT_I4 (CREQV $lhs, $rhs), $tval, $fval)>;
40720b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETGE)),
40730b57cec5SDimitry Andric          (SELECT_I4 (CRORC  $rhs, $lhs), $tval, $fval)>;
40740b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETUGE)),
40750b57cec5SDimitry Andric          (SELECT_I4 (CRORC  $lhs, $rhs), $tval, $fval)>;
40760b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETGT)),
40770b57cec5SDimitry Andric          (SELECT_I4 (CRANDC $rhs, $lhs), $tval, $fval)>;
40780b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETUGT)),
40790b57cec5SDimitry Andric          (SELECT_I4 (CRANDC $lhs, $rhs), $tval, $fval)>;
40800b57cec5SDimitry Andricdef : Pat<(i32 (selectcc i1:$lhs, i1:$rhs, i32:$tval, i32:$fval, SETNE)),
40810b57cec5SDimitry Andric          (SELECT_I4 (CRXOR $lhs, $rhs), $tval, $fval)>;
40820b57cec5SDimitry Andric
40830b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETLT)),
40840b57cec5SDimitry Andric          (SELECT_I8 (CRANDC $lhs, $rhs), $tval, $fval)>;
40850b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETULT)),
40860b57cec5SDimitry Andric          (SELECT_I8 (CRANDC $rhs, $lhs), $tval, $fval)>;
40870b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETLE)),
40880b57cec5SDimitry Andric          (SELECT_I8 (CRORC  $lhs, $rhs), $tval, $fval)>;
40890b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETULE)),
40900b57cec5SDimitry Andric          (SELECT_I8 (CRORC  $rhs, $lhs), $tval, $fval)>;
40910b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETEQ)),
40920b57cec5SDimitry Andric          (SELECT_I8 (CREQV $lhs, $rhs), $tval, $fval)>;
40930b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETGE)),
40940b57cec5SDimitry Andric          (SELECT_I8 (CRORC  $rhs, $lhs), $tval, $fval)>;
40950b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETUGE)),
40960b57cec5SDimitry Andric          (SELECT_I8 (CRORC  $lhs, $rhs), $tval, $fval)>;
40970b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETGT)),
40980b57cec5SDimitry Andric          (SELECT_I8 (CRANDC $rhs, $lhs), $tval, $fval)>;
40990b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETUGT)),
41000b57cec5SDimitry Andric          (SELECT_I8 (CRANDC $lhs, $rhs), $tval, $fval)>;
41010b57cec5SDimitry Andricdef : Pat<(i64 (selectcc i1:$lhs, i1:$rhs, i64:$tval, i64:$fval, SETNE)),
41020b57cec5SDimitry Andric          (SELECT_I8 (CRXOR $lhs, $rhs), $tval, $fval)>;
41030b57cec5SDimitry Andric
41040b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
41050b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLT)),
41060b57cec5SDimitry Andric          (SELECT_F4 (CRANDC $lhs, $rhs), $tval, $fval)>;
41070b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULT)),
41080b57cec5SDimitry Andric          (SELECT_F4 (CRANDC $rhs, $lhs), $tval, $fval)>;
41090b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETLE)),
41100b57cec5SDimitry Andric          (SELECT_F4 (CRORC  $lhs, $rhs), $tval, $fval)>;
41110b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETULE)),
41120b57cec5SDimitry Andric          (SELECT_F4 (CRORC  $rhs, $lhs), $tval, $fval)>;
41130b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETEQ)),
41140b57cec5SDimitry Andric          (SELECT_F4 (CREQV $lhs, $rhs), $tval, $fval)>;
41150b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGE)),
41160b57cec5SDimitry Andric          (SELECT_F4 (CRORC  $rhs, $lhs), $tval, $fval)>;
41170b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGE)),
41180b57cec5SDimitry Andric          (SELECT_F4 (CRORC  $lhs, $rhs), $tval, $fval)>;
41190b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETGT)),
41200b57cec5SDimitry Andric          (SELECT_F4 (CRANDC $rhs, $lhs), $tval, $fval)>;
41210b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETUGT)),
41220b57cec5SDimitry Andric          (SELECT_F4 (CRANDC $lhs, $rhs), $tval, $fval)>;
41230b57cec5SDimitry Andricdef : Pat<(f32 (selectcc i1:$lhs, i1:$rhs, f32:$tval, f32:$fval, SETNE)),
41240b57cec5SDimitry Andric          (SELECT_F4 (CRXOR $lhs, $rhs), $tval, $fval)>;
41250b57cec5SDimitry Andric
41260b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLT)),
41270b57cec5SDimitry Andric          (SELECT_F8 (CRANDC $lhs, $rhs), $tval, $fval)>;
41280b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULT)),
41290b57cec5SDimitry Andric          (SELECT_F8 (CRANDC $rhs, $lhs), $tval, $fval)>;
41300b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETLE)),
41310b57cec5SDimitry Andric          (SELECT_F8 (CRORC  $lhs, $rhs), $tval, $fval)>;
41320b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETULE)),
41330b57cec5SDimitry Andric          (SELECT_F8 (CRORC  $rhs, $lhs), $tval, $fval)>;
41340b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETEQ)),
41350b57cec5SDimitry Andric          (SELECT_F8 (CREQV $lhs, $rhs), $tval, $fval)>;
41360b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGE)),
41370b57cec5SDimitry Andric          (SELECT_F8 (CRORC  $rhs, $lhs), $tval, $fval)>;
41380b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGE)),
41390b57cec5SDimitry Andric          (SELECT_F8 (CRORC  $lhs, $rhs), $tval, $fval)>;
41400b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETGT)),
41410b57cec5SDimitry Andric          (SELECT_F8 (CRANDC $rhs, $lhs), $tval, $fval)>;
41420b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETUGT)),
41430b57cec5SDimitry Andric          (SELECT_F8 (CRANDC $lhs, $rhs), $tval, $fval)>;
41440b57cec5SDimitry Andricdef : Pat<(f64 (selectcc i1:$lhs, i1:$rhs, f64:$tval, f64:$fval, SETNE)),
41450b57cec5SDimitry Andric          (SELECT_F8 (CRXOR $lhs, $rhs), $tval, $fval)>;
41460b57cec5SDimitry Andric}
41470b57cec5SDimitry Andric
41480b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETLT)),
41490b57cec5SDimitry Andric          (SELECT_F16 (CRANDC $lhs, $rhs), $tval, $fval)>;
41500b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETULT)),
41510b57cec5SDimitry Andric          (SELECT_F16 (CRANDC $rhs, $lhs), $tval, $fval)>;
41520b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETLE)),
41530b57cec5SDimitry Andric          (SELECT_F16 (CRORC  $lhs, $rhs), $tval, $fval)>;
41540b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETULE)),
41550b57cec5SDimitry Andric          (SELECT_F16 (CRORC  $rhs, $lhs), $tval, $fval)>;
41560b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETEQ)),
41570b57cec5SDimitry Andric          (SELECT_F16 (CREQV $lhs, $rhs), $tval, $fval)>;
41580b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETGE)),
41590b57cec5SDimitry Andric         (SELECT_F16 (CRORC  $rhs, $lhs), $tval, $fval)>;
41600b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETUGE)),
41610b57cec5SDimitry Andric          (SELECT_F16 (CRORC  $lhs, $rhs), $tval, $fval)>;
41620b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETGT)),
41630b57cec5SDimitry Andric          (SELECT_F16 (CRANDC $rhs, $lhs), $tval, $fval)>;
41640b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETUGT)),
41650b57cec5SDimitry Andric          (SELECT_F16 (CRANDC $lhs, $rhs), $tval, $fval)>;
41660b57cec5SDimitry Andricdef : Pat<(f128 (selectcc i1:$lhs, i1:$rhs, f128:$tval, f128:$fval, SETNE)),
41670b57cec5SDimitry Andric          (SELECT_F16 (CRXOR $lhs, $rhs), $tval, $fval)>;
41680b57cec5SDimitry Andric
41690b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETLT)),
41700b57cec5SDimitry Andric          (SELECT_VRRC (CRANDC $lhs, $rhs), $tval, $fval)>;
41710b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETULT)),
41720b57cec5SDimitry Andric          (SELECT_VRRC (CRANDC $rhs, $lhs), $tval, $fval)>;
41730b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETLE)),
41740b57cec5SDimitry Andric          (SELECT_VRRC (CRORC  $lhs, $rhs), $tval, $fval)>;
41750b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETULE)),
41760b57cec5SDimitry Andric          (SELECT_VRRC (CRORC  $rhs, $lhs), $tval, $fval)>;
41770b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETEQ)),
41780b57cec5SDimitry Andric          (SELECT_VRRC (CREQV $lhs, $rhs), $tval, $fval)>;
41790b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETGE)),
41800b57cec5SDimitry Andric          (SELECT_VRRC (CRORC  $rhs, $lhs), $tval, $fval)>;
41810b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETUGE)),
41820b57cec5SDimitry Andric          (SELECT_VRRC (CRORC  $lhs, $rhs), $tval, $fval)>;
41830b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETGT)),
41840b57cec5SDimitry Andric          (SELECT_VRRC (CRANDC $rhs, $lhs), $tval, $fval)>;
41850b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETUGT)),
41860b57cec5SDimitry Andric          (SELECT_VRRC (CRANDC $lhs, $rhs), $tval, $fval)>;
41870b57cec5SDimitry Andricdef : Pat<(v4i32 (selectcc i1:$lhs, i1:$rhs, v4i32:$tval, v4i32:$fval, SETNE)),
41880b57cec5SDimitry Andric          (SELECT_VRRC (CRXOR $lhs, $rhs), $tval, $fval)>;
41890b57cec5SDimitry Andric
41900fca6ea1SDimitry Andriclet Defs = [CR0] in {
4191480093f4SDimitry Andricdef ANDI_rec_1_EQ_BIT : PPCCustomInserterPseudo<(outs crbitrc:$dst), (ins gprc:$in),
4192480093f4SDimitry Andric                             "#ANDI_rec_1_EQ_BIT",
41930b57cec5SDimitry Andric                             [(set i1:$dst, (trunc (not i32:$in)))]>;
4194480093f4SDimitry Andricdef ANDI_rec_1_GT_BIT : PPCCustomInserterPseudo<(outs crbitrc:$dst), (ins gprc:$in),
4195480093f4SDimitry Andric                             "#ANDI_rec_1_GT_BIT",
41960b57cec5SDimitry Andric                             [(set i1:$dst, (trunc i32:$in))]>;
41970b57cec5SDimitry Andric
4198480093f4SDimitry Andricdef ANDI_rec_1_EQ_BIT8 : PPCCustomInserterPseudo<(outs crbitrc:$dst), (ins g8rc:$in),
4199480093f4SDimitry Andric                              "#ANDI_rec_1_EQ_BIT8",
42000b57cec5SDimitry Andric                              [(set i1:$dst, (trunc (not i64:$in)))]>;
4201480093f4SDimitry Andricdef ANDI_rec_1_GT_BIT8 : PPCCustomInserterPseudo<(outs crbitrc:$dst), (ins g8rc:$in),
4202480093f4SDimitry Andric                              "#ANDI_rec_1_GT_BIT8",
42030b57cec5SDimitry Andric                              [(set i1:$dst, (trunc i64:$in))]>;
42040fca6ea1SDimitry Andric}
42050b57cec5SDimitry Andric
42060b57cec5SDimitry Andricdef : Pat<(i1 (not (trunc i32:$in))),
4207480093f4SDimitry Andric           (ANDI_rec_1_EQ_BIT $in)>;
42080b57cec5SDimitry Andricdef : Pat<(i1 (not (trunc i64:$in))),
4209480093f4SDimitry Andric           (ANDI_rec_1_EQ_BIT8 $in)>;
42100b57cec5SDimitry Andric
4211fe6060f1SDimitry Andricdef : Pat<(int_ppc_fsel f8rc:$FRA, f8rc:$FRC, f8rc:$FRB), (FSELD $FRA, $FRC, $FRB)>;
4212fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrte f8rc:$frB), (FRSQRTE $frB)>;
4213fe6060f1SDimitry Andricdef : Pat<(int_ppc_frsqrtes f4rc:$frB), (FRSQRTES $frB)>;
4214fe6060f1SDimitry Andric
42150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
42160b57cec5SDimitry Andric// PowerPC Instructions used for assembler/disassembler only
42170b57cec5SDimitry Andric//
42180b57cec5SDimitry Andric
42190b57cec5SDimitry Andric// FIXME: For B=0 or B > 8, the registers following RT are used.
42200b57cec5SDimitry Andric// WARNING: Do not add patterns for this instruction without fixing this.
422106c3fb27SDimitry Andricdef LSWI  : XForm_base_r3xo_memOp<31, 597, (outs gprc:$RST),
422206c3fb27SDimitry Andric                                  (ins gprc:$RA, u5imm:$RB),
422306c3fb27SDimitry Andric                                  "lswi $RST, $RA, $RB", IIC_LdStLoad, []>;
42240b57cec5SDimitry Andric
42250b57cec5SDimitry Andric// FIXME: For B=0 or B > 8, the registers following RT are used.
42260b57cec5SDimitry Andric// WARNING: Do not add patterns for this instruction without fixing this.
42270b57cec5SDimitry Andricdef STSWI : XForm_base_r3xo_memOp<31, 725, (outs),
422806c3fb27SDimitry Andric                                  (ins gprc:$RST, gprc:$RA, u5imm:$RB),
422906c3fb27SDimitry Andric                                  "stswi $RST, $RA, $RB", IIC_LdStLoad, []>;
42300b57cec5SDimitry Andric
42310b57cec5SDimitry Andricdef ISYNC : XLForm_2_ext<19, 150, 0, 0, 0, (outs), (ins),
42320b57cec5SDimitry Andric                         "isync", IIC_SprISYNC, []>;
42330b57cec5SDimitry Andric
423406c3fb27SDimitry Andricdef ICBI : XForm_1a<31, 982, (outs), (ins (memrr $RA, $RB):$addr),
423506c3fb27SDimitry Andric                    "icbi $addr", IIC_LdStICBI, []>;
42360b57cec5SDimitry Andric
4237e8d8bef9SDimitry Andricdef WAIT : XForm_24_sync<31, 30, (outs), (ins u2imm:$L),
42380b57cec5SDimitry Andric                         "wait $L", IIC_LdStLoad, []>;
42390b57cec5SDimitry Andric
42400b57cec5SDimitry Andricdef MBAR : XForm_mbar<31, 854, (outs), (ins u5imm:$MO),
42410b57cec5SDimitry Andric                         "mbar $MO", IIC_LdStLoad>, Requires<[IsBookE]>;
42420b57cec5SDimitry Andric
42430b57cec5SDimitry Andricdef MTSR: XForm_sr<31, 210, (outs), (ins gprc:$RS, u4imm:$SR),
42440b57cec5SDimitry Andric            "mtsr $SR, $RS", IIC_SprMTSR>;
42450b57cec5SDimitry Andric
42460b57cec5SDimitry Andricdef MFSR: XForm_sr<31, 595, (outs gprc:$RS), (ins u4imm:$SR),
42470b57cec5SDimitry Andric            "mfsr $RS, $SR", IIC_SprMFSR>;
42480b57cec5SDimitry Andric
42490b57cec5SDimitry Andricdef MTSRIN: XForm_srin<31, 242, (outs), (ins gprc:$RS, gprc:$RB),
42500b57cec5SDimitry Andric            "mtsrin $RS, $RB", IIC_SprMTSR>;
42510b57cec5SDimitry Andric
42520b57cec5SDimitry Andricdef MFSRIN: XForm_srin<31, 659, (outs gprc:$RS), (ins gprc:$RB),
42530b57cec5SDimitry Andric            "mfsrin $RS, $RB", IIC_SprMFSR>;
42540b57cec5SDimitry Andric
4255e8d8bef9SDimitry Andricdef MTMSR: XForm_mtmsr<31, 146, (outs), (ins gprc:$RS, u1imm:$L),
42560b57cec5SDimitry Andric                    "mtmsr $RS, $L", IIC_SprMTMSR>;
42570b57cec5SDimitry Andric
42580b57cec5SDimitry Andricdef WRTEE: XForm_mtmsr<31, 131, (outs), (ins gprc:$RS),
42590b57cec5SDimitry Andric                    "wrtee $RS", IIC_SprMTMSR>, Requires<[IsBookE]> {
42600b57cec5SDimitry Andric  let L = 0;
42610b57cec5SDimitry Andric}
42620b57cec5SDimitry Andric
42630b57cec5SDimitry Andricdef WRTEEI: I<31, (outs), (ins i1imm:$E), "wrteei $E", IIC_SprMTMSR>,
42640b57cec5SDimitry Andric              Requires<[IsBookE]> {
42650b57cec5SDimitry Andric  bits<1> E;
42660b57cec5SDimitry Andric
42670b57cec5SDimitry Andric  let Inst{16} = E;
42680b57cec5SDimitry Andric  let Inst{21-30} = 163;
42690b57cec5SDimitry Andric}
42700b57cec5SDimitry Andric
427106c3fb27SDimitry Andricdef DCCCI : XForm_tlb<454, (outs), (ins gprc:$RA, gprc:$RB),
427206c3fb27SDimitry Andric               "dccci $RA, $RB", IIC_LdStLoad>, Requires<[IsPPC4xx]>;
427306c3fb27SDimitry Andricdef ICCCI : XForm_tlb<966, (outs), (ins gprc:$RA, gprc:$RB),
427406c3fb27SDimitry Andric               "iccci $RA, $RB", IIC_LdStLoad>, Requires<[IsPPC4xx]>;
42750b57cec5SDimitry Andric
42760b57cec5SDimitry Andricdef : InstAlias<"dci 0", (DCCCI R0, R0)>, Requires<[IsPPC4xx]>;
42770b57cec5SDimitry Andricdef : InstAlias<"dccci", (DCCCI R0, R0)>, Requires<[IsPPC4xx]>;
42780b57cec5SDimitry Andricdef : InstAlias<"ici 0", (ICCCI R0, R0)>, Requires<[IsPPC4xx]>;
42790b57cec5SDimitry Andricdef : InstAlias<"iccci", (ICCCI R0, R0)>, Requires<[IsPPC4xx]>;
42800b57cec5SDimitry Andric
428106c3fb27SDimitry Andricdef MFMSR : XForm_rs<31, 83, (outs gprc:$RST), (ins),
428206c3fb27SDimitry Andric                  "mfmsr $RST", IIC_SprMFMSR, []>;
42830b57cec5SDimitry Andric
4284e8d8bef9SDimitry Andricdef MTMSRD : XForm_mtmsr<31, 178, (outs), (ins gprc:$RS, u1imm:$L),
42850b57cec5SDimitry Andric                    "mtmsrd $RS, $L", IIC_SprMTMSRD>;
42860b57cec5SDimitry Andric
42870b57cec5SDimitry Andricdef MCRFS : XLForm_3<63, 64, (outs crrc:$BF), (ins crrc:$BFA),
42880b57cec5SDimitry Andric                     "mcrfs $BF, $BFA", IIC_BrMCR>;
42890b57cec5SDimitry Andric
4290fe6060f1SDimitry Andric// All MTFSF variants may change the rounding mode so conservatively set it
4291fe6060f1SDimitry Andric// as an implicit def for all of them.
42920b57cec5SDimitry Andriclet Predicates = [HasFPU] in {
4293349cc55cSDimitry Andriclet Defs = [RM], hasSideEffects = 1 in {
4294fe6060f1SDimitry Andriclet isCodeGenOnly = 1,
4295fe6060f1SDimitry Andric    Pattern = [(int_ppc_mtfsfi timm:$BF, timm:$U)], W = 0 in
4296fe6060f1SDimitry Andricdef MTFSFIb : XLForm_4<63, 134, (outs), (ins u3imm:$BF, u4imm:$U),
4297fe6060f1SDimitry Andric                       "mtfsfi $BF, $U", IIC_IntMFFS>;
4298fe6060f1SDimitry Andricdef MTFSFI : XLForm_4<63, 134, (outs), (ins u3imm:$BF, u4imm:$U, i32imm:$W),
4299fe6060f1SDimitry Andric                      "mtfsfi $BF, $U, $W", IIC_IntMFFS>;
4300fe6060f1SDimitry Andriclet Defs = [CR1] in
4301fe6060f1SDimitry Andricdef MTFSFI_rec : XLForm_4<63, 134, (outs), (ins u3imm:$BF, u4imm:$U, u1imm:$W),
4302fe6060f1SDimitry Andric                       "mtfsfi. $BF, $U, $W", IIC_IntMFFS>, isRecordForm;
4303fe6060f1SDimitry Andric
43040b57cec5SDimitry Andricdef MTFSF : XFLForm_1<63, 711, (outs),
4305e8d8bef9SDimitry Andric                      (ins i32imm:$FLM, f8rc:$FRB, u1imm:$L, i32imm:$W),
43060b57cec5SDimitry Andric                      "mtfsf $FLM, $FRB, $L, $W", IIC_IntMFFS, []>;
4307e8d8bef9SDimitry Andriclet Defs = [CR1] in
4308480093f4SDimitry Andricdef MTFSF_rec : XFLForm_1<63, 711, (outs),
4309e8d8bef9SDimitry Andric                       (ins i32imm:$FLM, f8rc:$FRB, u1imm:$L, i32imm:$W),
4310480093f4SDimitry Andric                       "mtfsf. $FLM, $FRB, $L, $W", IIC_IntMFFS, []>, isRecordForm;
4311e8d8bef9SDimitry Andric}
43120b57cec5SDimitry Andric
4313fe6060f1SDimitry Andricdef : InstAlias<"mtfsfi $BF, $U", (MTFSFI u3imm:$BF, u4imm:$U, 0)>;
4314fe6060f1SDimitry Andricdef : InstAlias<"mtfsfi. $BF, $U", (MTFSFI_rec u3imm:$BF, u4imm:$U, 0)>;
43150b57cec5SDimitry Andricdef : InstAlias<"mtfsf $FLM, $FRB", (MTFSF i32imm:$FLM, f8rc:$FRB, 0, 0)>;
4316480093f4SDimitry Andricdef : InstAlias<"mtfsf. $FLM, $FRB", (MTFSF_rec i32imm:$FLM, f8rc:$FRB, 0, 0)>;
43170b57cec5SDimitry Andric}
43180b57cec5SDimitry Andric
43190b57cec5SDimitry Andricdef SLBIE : XForm_16b<31, 434, (outs), (ins gprc:$RB),
43200b57cec5SDimitry Andric                        "slbie $RB", IIC_SprSLBIE, []>;
43210b57cec5SDimitry Andric
432206c3fb27SDimitry Andricdef SLBMTE : XForm_26<31, 402, (outs), (ins gprc:$RST, gprc:$RB),
432306c3fb27SDimitry Andric                    "slbmte $RST, $RB", IIC_SprSLBMTE, []>;
43240b57cec5SDimitry Andric
432506c3fb27SDimitry Andricdef SLBMFEE : XForm_26<31, 915, (outs gprc:$RST), (ins gprc:$RB),
432606c3fb27SDimitry Andric                       "slbmfee $RST, $RB", IIC_SprSLBMFEE, []>;
43270b57cec5SDimitry Andric
43280b57cec5SDimitry Andricdef SLBMFEV : XLForm_1_gen<31, 851, (outs gprc:$RT), (ins gprc:$RB),
43290b57cec5SDimitry Andric                       "slbmfev $RT, $RB", IIC_SprSLBMFEV, []>;
43300b57cec5SDimitry Andric
43310b57cec5SDimitry Andricdef SLBIA : XForm_0<31, 498, (outs), (ins), "slbia", IIC_SprSLBIA, []>;
43320b57cec5SDimitry Andric
43330b57cec5SDimitry Andriclet Defs = [CR0] in
433406c3fb27SDimitry Andricdef SLBFEE_rec : XForm_26<31, 979, (outs gprc:$RST), (ins gprc:$RB),
433506c3fb27SDimitry Andric                         "slbfee. $RST, $RB", IIC_SprSLBFEE, []>, isRecordForm;
43360b57cec5SDimitry Andric
43370b57cec5SDimitry Andricdef TLBIA : XForm_0<31, 370, (outs), (ins),
43380b57cec5SDimitry Andric                        "tlbia", IIC_SprTLBIA, []>;
43390b57cec5SDimitry Andric
43400b57cec5SDimitry Andricdef TLBSYNC : XForm_0<31, 566, (outs), (ins),
43410b57cec5SDimitry Andric                        "tlbsync", IIC_SprTLBSYNC, []>;
43420b57cec5SDimitry Andric
43430b57cec5SDimitry Andricdef TLBIEL : XForm_16b<31, 274, (outs), (ins gprc:$RB),
43440b57cec5SDimitry Andric                          "tlbiel $RB", IIC_SprTLBIEL, []>;
43450b57cec5SDimitry Andric
43460b57cec5SDimitry Andricdef TLBLD : XForm_16b<31, 978, (outs), (ins gprc:$RB),
43470b57cec5SDimitry Andric                          "tlbld $RB", IIC_LdStLoad, []>, Requires<[IsPPC6xx]>;
43480b57cec5SDimitry Andricdef TLBLI : XForm_16b<31, 1010, (outs), (ins gprc:$RB),
43490b57cec5SDimitry Andric                          "tlbli $RB", IIC_LdStLoad, []>, Requires<[IsPPC6xx]>;
43500b57cec5SDimitry Andric
435106c3fb27SDimitry Andricdef TLBIE : XForm_26<31, 306, (outs), (ins gprc:$RST, gprc:$RB),
435206c3fb27SDimitry Andric                          "tlbie $RB,$RST", IIC_SprTLBIE, []>;
43530b57cec5SDimitry Andric
435406c3fb27SDimitry Andricdef TLBSX : XForm_tlb<914, (outs), (ins gprc:$RA, gprc:$RB), "tlbsx $RA, $RB",
43550b57cec5SDimitry Andric                IIC_LdStLoad>, Requires<[IsBookE]>;
43560b57cec5SDimitry Andric
435706c3fb27SDimitry Andricdef TLBIVAX : XForm_tlb<786, (outs), (ins gprc:$RA, gprc:$RB), "tlbivax $RA, $RB",
43580b57cec5SDimitry Andric                IIC_LdStLoad>, Requires<[IsBookE]>;
43590b57cec5SDimitry Andric
43608a4dda33SDimitry Andricdef TLBILX : XForm_tlbilx<18, (outs), (ins u2imm:$T, gprc:$RA, gprc:$RB),
43618a4dda33SDimitry Andric    "tlbilx $T, $RA, $RB", IIC_LdStLoad>, Requires<[IsBookE]>;
43628a4dda33SDimitry Andric
43630b57cec5SDimitry Andricdef TLBRE : XForm_24_eieio<31, 946, (outs), (ins),
43640b57cec5SDimitry Andric                           "tlbre", IIC_LdStLoad, []>, Requires<[IsBookE]>;
43650b57cec5SDimitry Andric
43660b57cec5SDimitry Andricdef TLBWE : XForm_24_eieio<31, 978, (outs), (ins),
43670b57cec5SDimitry Andric                           "tlbwe", IIC_LdStLoad, []>, Requires<[IsBookE]>;
43680b57cec5SDimitry Andric
436906c3fb27SDimitry Andricdef TLBRE2 : XForm_tlbws<31, 946, (outs gprc:$RST), (ins gprc:$RA, i1imm:$WS),
437006c3fb27SDimitry Andric               "tlbre $RST, $RA, $WS", IIC_LdStLoad, []>, Requires<[IsPPC4xx]>;
43710b57cec5SDimitry Andric
437206c3fb27SDimitry Andricdef TLBWE2 : XForm_tlbws<31, 978, (outs), (ins gprc:$RST, gprc:$RA, i1imm:$WS),
437306c3fb27SDimitry Andric               "tlbwe $RST, $RA, $WS", IIC_LdStLoad, []>, Requires<[IsPPC4xx]>;
43740b57cec5SDimitry Andric
437506c3fb27SDimitry Andricdef TLBSX2 : XForm_base_r3xo<31, 914, (outs), (ins gprc:$RST, gprc:$RA, gprc:$RB),
437606c3fb27SDimitry Andric                             "tlbsx $RST, $RA, $RB", IIC_LdStLoad, []>,
43770b57cec5SDimitry Andric                             Requires<[IsPPC4xx]>;
43780b57cec5SDimitry Andricdef TLBSX2D : XForm_base_r3xo<31, 914, (outs),
437906c3fb27SDimitry Andric                              (ins gprc:$RST, gprc:$RA, gprc:$RB),
438006c3fb27SDimitry Andric                              "tlbsx. $RST, $RA, $RB", IIC_LdStLoad, []>,
4381480093f4SDimitry Andric                              Requires<[IsPPC4xx]>, isRecordForm;
43820b57cec5SDimitry Andric
43830b57cec5SDimitry Andricdef RFID : XForm_0<19, 18, (outs), (ins), "rfid", IIC_IntRFID, []>;
43840b57cec5SDimitry Andric
43850b57cec5SDimitry Andricdef RFI : XForm_0<19, 50, (outs), (ins), "rfi", IIC_SprRFI, []>,
43860b57cec5SDimitry Andric                  Requires<[IsBookE]>;
43870b57cec5SDimitry Andricdef RFCI : XForm_0<19, 51, (outs), (ins), "rfci", IIC_BrB, []>,
43880b57cec5SDimitry Andric                   Requires<[IsBookE]>;
43890b57cec5SDimitry Andric
43900b57cec5SDimitry Andricdef RFDI : XForm_0<19, 39, (outs), (ins), "rfdi", IIC_BrB, []>,
43910b57cec5SDimitry Andric                   Requires<[IsE500]>;
43920b57cec5SDimitry Andricdef RFMCI : XForm_0<19, 38, (outs), (ins), "rfmci", IIC_BrB, []>,
43930b57cec5SDimitry Andric                    Requires<[IsE500]>;
43940b57cec5SDimitry Andric
439506c3fb27SDimitry Andricdef MFDCR : XFXForm_1<31, 323, (outs gprc:$RST), (ins i32imm:$SPR),
439606c3fb27SDimitry Andric                      "mfdcr $RST, $SPR", IIC_SprMFSPR>, Requires<[IsPPC4xx]>;
439706c3fb27SDimitry Andricdef MTDCR : XFXForm_1<31, 451, (outs), (ins gprc:$RST, i32imm:$SPR),
439806c3fb27SDimitry Andric                      "mtdcr $SPR, $RST", IIC_SprMTSPR>, Requires<[IsPPC4xx]>;
43990b57cec5SDimitry Andric
44000b57cec5SDimitry Andricdef HRFID : XLForm_1_np<19, 274, (outs), (ins), "hrfid", IIC_BrB, []>;
44010b57cec5SDimitry Andricdef NAP   : XLForm_1_np<19, 434, (outs), (ins), "nap", IIC_BrB, []>;
44020b57cec5SDimitry Andric
44030b57cec5SDimitry Andricdef ATTN : XForm_attn<0, 256, (outs), (ins), "attn", IIC_BrB>;
44040b57cec5SDimitry Andric
44050b57cec5SDimitry Andricdef LBZCIX : XForm_base_r3xo_memOp<31, 853, (outs gprc:$RST),
440606c3fb27SDimitry Andric                                  (ins gprc:$RA, gprc:$RB),
440706c3fb27SDimitry Andric                                  "lbzcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44080b57cec5SDimitry Andricdef LHZCIX : XForm_base_r3xo_memOp<31, 821, (outs gprc:$RST),
440906c3fb27SDimitry Andric                                  (ins gprc:$RA, gprc:$RB),
441006c3fb27SDimitry Andric                                  "lhzcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44110b57cec5SDimitry Andricdef LWZCIX : XForm_base_r3xo_memOp<31, 789, (outs gprc:$RST),
441206c3fb27SDimitry Andric                                  (ins gprc:$RA, gprc:$RB),
441306c3fb27SDimitry Andric                                  "lwzcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44140b57cec5SDimitry Andricdef LDCIX :  XForm_base_r3xo_memOp<31, 885, (outs gprc:$RST),
441506c3fb27SDimitry Andric                                  (ins gprc:$RA, gprc:$RB),
441606c3fb27SDimitry Andric                                  "ldcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44170b57cec5SDimitry Andric
44180b57cec5SDimitry Andricdef STBCIX : XForm_base_r3xo_memOp<31, 981, (outs),
441906c3fb27SDimitry Andric                                  (ins gprc:$RST, gprc:$RA, gprc:$RB),
442006c3fb27SDimitry Andric                                  "stbcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44210b57cec5SDimitry Andricdef STHCIX : XForm_base_r3xo_memOp<31, 949, (outs),
442206c3fb27SDimitry Andric                                  (ins gprc:$RST, gprc:$RA, gprc:$RB),
442306c3fb27SDimitry Andric                                  "sthcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44240b57cec5SDimitry Andricdef STWCIX : XForm_base_r3xo_memOp<31, 917, (outs),
442506c3fb27SDimitry Andric                                  (ins gprc:$RST, gprc:$RA, gprc:$RB),
442606c3fb27SDimitry Andric                                  "stwcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44270b57cec5SDimitry Andricdef STDCIX : XForm_base_r3xo_memOp<31, 1013, (outs),
442806c3fb27SDimitry Andric                                  (ins gprc:$RST, gprc:$RA, gprc:$RB),
442906c3fb27SDimitry Andric                                  "stdcix $RST, $RA, $RB", IIC_LdStLoad, []>;
44300b57cec5SDimitry Andric
44310b57cec5SDimitry Andric// External PID Load Store Instructions
44320b57cec5SDimitry Andric
443306c3fb27SDimitry Andricdef LBEPX   : XForm_1<31, 95, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
443406c3fb27SDimitry Andric                      "lbepx $RST, $addr", IIC_LdStLoad, []>,
44350b57cec5SDimitry Andric                      Requires<[IsE500]>;
44360b57cec5SDimitry Andric
443706c3fb27SDimitry Andricdef LFDEPX  : XForm_25<31, 607, (outs f8rc:$RST), (ins (memrr $RA, $RB):$addr),
443806c3fb27SDimitry Andric                      "lfdepx $RST, $addr", IIC_LdStLFD, []>,
44390b57cec5SDimitry Andric                      Requires<[IsE500]>;
44400b57cec5SDimitry Andric
444106c3fb27SDimitry Andricdef LHEPX   : XForm_1<31, 287, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
444206c3fb27SDimitry Andric                      "lhepx $RST, $addr", IIC_LdStLoad, []>,
44430b57cec5SDimitry Andric                      Requires<[IsE500]>;
44440b57cec5SDimitry Andric
444506c3fb27SDimitry Andricdef LWEPX   : XForm_1<31, 31, (outs gprc:$RST), (ins (memrr $RA, $RB):$addr),
444606c3fb27SDimitry Andric                      "lwepx $RST, $addr", IIC_LdStLoad, []>,
44470b57cec5SDimitry Andric                      Requires<[IsE500]>;
44480b57cec5SDimitry Andric
444906c3fb27SDimitry Andricdef STBEPX  : XForm_8<31, 223, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
445006c3fb27SDimitry Andric                      "stbepx $RST, $addr", IIC_LdStStore, []>,
44510b57cec5SDimitry Andric                      Requires<[IsE500]>;
44520b57cec5SDimitry Andric
445306c3fb27SDimitry Andricdef STFDEPX : XForm_28_memOp<31, 735, (outs), (ins f8rc:$RST, (memrr $RA, $RB):$addr),
445406c3fb27SDimitry Andric                      "stfdepx $RST, $addr", IIC_LdStSTFD, []>,
44550b57cec5SDimitry Andric                      Requires<[IsE500]>;
44560b57cec5SDimitry Andric
445706c3fb27SDimitry Andricdef STHEPX  : XForm_8<31, 415, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
445806c3fb27SDimitry Andric                      "sthepx $RST, $addr", IIC_LdStStore, []>,
44590b57cec5SDimitry Andric                      Requires<[IsE500]>;
44600b57cec5SDimitry Andric
446106c3fb27SDimitry Andricdef STWEPX  : XForm_8<31, 159, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
446206c3fb27SDimitry Andric                      "stwepx $RST, $addr", IIC_LdStStore, []>,
44630b57cec5SDimitry Andric                      Requires<[IsE500]>;
44640b57cec5SDimitry Andric
446506c3fb27SDimitry Andricdef DCBFEP  : DCB_Form<127, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcbfep $addr",
44660b57cec5SDimitry Andric                      IIC_LdStDCBF, []>, Requires<[IsE500]>;
44670b57cec5SDimitry Andric
446806c3fb27SDimitry Andricdef DCBSTEP : DCB_Form<63, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcbstep $addr",
44690b57cec5SDimitry Andric                      IIC_LdStDCBF, []>, Requires<[IsE500]>;
44700b57cec5SDimitry Andric
447106c3fb27SDimitry Andricdef DCBTEP  : DCB_Form_hint<319, (outs), (ins (memrr $RA, $RB):$addr, u5imm:$TH),
447206c3fb27SDimitry Andric                      "dcbtep $TH, $addr", IIC_LdStDCBF, []>,
44730b57cec5SDimitry Andric                      Requires<[IsE500]>;
44740b57cec5SDimitry Andric
447506c3fb27SDimitry Andricdef DCBTSTEP : DCB_Form_hint<255, (outs), (ins (memrr $RA, $RB):$addr, u5imm:$TH),
447606c3fb27SDimitry Andric                      "dcbtstep $TH, $addr", IIC_LdStDCBF, []>,
44770b57cec5SDimitry Andric                      Requires<[IsE500]>;
44780b57cec5SDimitry Andric
447906c3fb27SDimitry Andricdef DCBZEP  : DCB_Form<1023, 0, (outs), (ins (memrr $RA, $RB):$addr), "dcbzep $addr",
44800b57cec5SDimitry Andric                      IIC_LdStDCBF, []>, Requires<[IsE500]>;
44810b57cec5SDimitry Andric
448206c3fb27SDimitry Andricdef DCBZLEP : DCB_Form<1023, 1, (outs), (ins (memrr $RA, $RB):$addr), "dcbzlep $addr",
44830b57cec5SDimitry Andric                      IIC_LdStDCBF, []>, Requires<[IsE500]>;
44840b57cec5SDimitry Andric
448506c3fb27SDimitry Andricdef ICBIEP  : XForm_1a<31, 991, (outs), (ins (memrr $RA, $RB):$addr), "icbiep $addr",
44860b57cec5SDimitry Andric                      IIC_LdStICBI, []>, Requires<[IsE500]>;
44870b57cec5SDimitry Andric
44880b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
44890b57cec5SDimitry Andric// PowerPC Assembler Instruction Aliases
44900b57cec5SDimitry Andric//
44910b57cec5SDimitry Andric
44920b57cec5SDimitry Andricdef : InstAlias<"sc", (SC 0)>;
44930b57cec5SDimitry Andric
44940b57cec5SDimitry Andricdef : InstAlias<"sync", (SYNC 0)>, Requires<[HasSYNC]>;
44950eae32dcSDimitry Andricdef : InstAlias<"hwsync", (SYNC 0), 0>, Requires<[HasSYNC]>;
44960b57cec5SDimitry Andricdef : InstAlias<"msync", (SYNC 0), 0>, Requires<[HasSYNC]>;
44970b57cec5SDimitry Andricdef : InstAlias<"lwsync", (SYNC 1)>, Requires<[HasSYNC]>;
44980b57cec5SDimitry Andricdef : InstAlias<"ptesync", (SYNC 2)>, Requires<[HasSYNC]>;
44990b57cec5SDimitry Andric
45000b57cec5SDimitry Andricdef : InstAlias<"wait", (WAIT 0)>;
45010b57cec5SDimitry Andricdef : InstAlias<"waitrsv", (WAIT 1)>;
45020b57cec5SDimitry Andricdef : InstAlias<"waitimpl", (WAIT 2)>;
45030b57cec5SDimitry Andric
45040b57cec5SDimitry Andricdef : InstAlias<"mbar", (MBAR 0)>, Requires<[IsBookE]>;
45050b57cec5SDimitry Andric
45060b57cec5SDimitry Andricdef DCBTx   : PPCAsmPseudo<"dcbt $dst", (ins memrr:$dst)>;
45070b57cec5SDimitry Andricdef DCBTSTx : PPCAsmPseudo<"dcbtst $dst", (ins memrr:$dst)>;
45080b57cec5SDimitry Andric
45090b57cec5SDimitry Andricdef DCBTCT : PPCAsmPseudo<"dcbtct $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
45100b57cec5SDimitry Andricdef DCBTDS : PPCAsmPseudo<"dcbtds $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
45110b57cec5SDimitry Andricdef DCBTT  : PPCAsmPseudo<"dcbtt $dst", (ins memrr:$dst)>;
45120b57cec5SDimitry Andric
45130b57cec5SDimitry Andricdef DCBTSTCT : PPCAsmPseudo<"dcbtstct $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
45140b57cec5SDimitry Andricdef DCBTSTDS : PPCAsmPseudo<"dcbtstds $dst, $TH", (ins memrr:$dst, u5imm:$TH)>;
45150b57cec5SDimitry Andricdef DCBTSTT  : PPCAsmPseudo<"dcbtstt $dst", (ins memrr:$dst)>;
45160b57cec5SDimitry Andric
45170b57cec5SDimitry Andricdef DCBFx  : PPCAsmPseudo<"dcbf $dst", (ins memrr:$dst)>;
45180b57cec5SDimitry Andricdef DCBFL  : PPCAsmPseudo<"dcbfl $dst", (ins memrr:$dst)>;
45190b57cec5SDimitry Andricdef DCBFLP : PPCAsmPseudo<"dcbflp $dst", (ins memrr:$dst)>;
45200b57cec5SDimitry Andric
45215ffd83dbSDimitry Andricdef : Pat<(int_ppc_isync),  (ISYNC)>;
45225ffd83dbSDimitry Andricdef : Pat<(int_ppc_dcbfl xoaddr:$dst),
45235ffd83dbSDimitry Andric          (DCBF 1, xoaddr:$dst)>;
45245ffd83dbSDimitry Andricdef : Pat<(int_ppc_dcbflp xoaddr:$dst),
45255ffd83dbSDimitry Andric          (DCBF 3, xoaddr:$dst)>;
45265ffd83dbSDimitry Andric
4527e8d8bef9SDimitry Andriclet Predicates = [IsISA3_1] in {
4528e8d8bef9SDimitry Andric  def DCBFPS  : PPCAsmPseudo<"dcbfps $dst", (ins memrr:$dst)>;
4529e8d8bef9SDimitry Andric  def DCBSTPS : PPCAsmPseudo<"dcbstps $dst", (ins memrr:$dst)>;
4530e8d8bef9SDimitry Andric
4531e8d8bef9SDimitry Andric  def : Pat<(int_ppc_dcbfps xoaddr:$dst),
4532e8d8bef9SDimitry Andric            (DCBF 4, xoaddr:$dst)>;
4533e8d8bef9SDimitry Andric  def : Pat<(int_ppc_dcbstps xoaddr:$dst),
4534e8d8bef9SDimitry Andric            (DCBF 6, xoaddr:$dst)>;
4535e8d8bef9SDimitry Andric}
4536e8d8bef9SDimitry Andric
45370b57cec5SDimitry Andricdef : InstAlias<"crset $bx", (CREQV crbitrc:$bx, crbitrc:$bx, crbitrc:$bx)>;
45380b57cec5SDimitry Andricdef : InstAlias<"crclr $bx", (CRXOR crbitrc:$bx, crbitrc:$bx, crbitrc:$bx)>;
45390b57cec5SDimitry Andricdef : InstAlias<"crmove $bx, $by", (CROR crbitrc:$bx, crbitrc:$by, crbitrc:$by)>;
45400b57cec5SDimitry Andricdef : InstAlias<"crnot $bx, $by", (CRNOR crbitrc:$bx, crbitrc:$by, crbitrc:$by)>;
45410b57cec5SDimitry Andric
45425ffd83dbSDimitry Andricdef : InstAlias<"mftb $Rx", (MFTB gprc:$Rx, 268)>;
45435ffd83dbSDimitry Andricdef : InstAlias<"mftbl $Rx", (MFTB gprc:$Rx, 268)>;
45445ffd83dbSDimitry Andricdef : InstAlias<"mftbu $Rx", (MFTB gprc:$Rx, 269)>;
45455ffd83dbSDimitry Andric
45465ffd83dbSDimitry Andricdef : InstAlias<"xnop", (XORI R0, R0, 0)>;
45475ffd83dbSDimitry Andric
4548fe6060f1SDimitry Andricdef : InstAlias<"mtxer $Rx", (MTSPR 1, gprc:$Rx)>;
4549fe6060f1SDimitry Andricdef : InstAlias<"mfxer $Rx", (MFSPR gprc:$Rx, 1)>;
4550fe6060f1SDimitry Andric
4551fe6060f1SDimitry Andric//Disable this alias on AIX for now because as does not support them.
4552fe6060f1SDimitry Andriclet Predicates = [ModernAs] in {
4553fe6060f1SDimitry Andric
45545ffd83dbSDimitry Andricforeach BR = 0-7 in {
45555ffd83dbSDimitry Andric    def : InstAlias<"mfbr"#BR#" $Rx",
45565ffd83dbSDimitry Andric                    (MFDCR gprc:$Rx, !add(BR, 0x80))>,
45575ffd83dbSDimitry Andric                    Requires<[IsPPC4xx]>;
45585ffd83dbSDimitry Andric    def : InstAlias<"mtbr"#BR#" $Rx",
45595ffd83dbSDimitry Andric                    (MTDCR gprc:$Rx, !add(BR, 0x80))>,
45605ffd83dbSDimitry Andric                    Requires<[IsPPC4xx]>;
45615ffd83dbSDimitry Andric}
45625ffd83dbSDimitry Andric
45635ffd83dbSDimitry Andricdef : InstAlias<"mtmsrd $RS", (MTMSRD gprc:$RS, 0)>;
45645ffd83dbSDimitry Andricdef : InstAlias<"mtmsr $RS", (MTMSR gprc:$RS, 0)>;
45655ffd83dbSDimitry Andricdef : InstAlias<"mtudscr $Rx", (MTSPR 3, gprc:$Rx)>;
45665ffd83dbSDimitry Andricdef : InstAlias<"mfudscr $Rx", (MFSPR gprc:$Rx, 3)>;
45675ffd83dbSDimitry Andric
45680b57cec5SDimitry Andricdef : InstAlias<"mfrtcu $Rx", (MFSPR gprc:$Rx, 4)>;
45690b57cec5SDimitry Andricdef : InstAlias<"mfrtcl $Rx", (MFSPR gprc:$Rx, 5)>;
45700b57cec5SDimitry Andric
45715ffd83dbSDimitry Andricdef : InstAlias<"mtlr $Rx", (MTSPR 8, gprc:$Rx)>;
45725ffd83dbSDimitry Andricdef : InstAlias<"mflr $Rx", (MFSPR gprc:$Rx, 8)>;
45735ffd83dbSDimitry Andric
45745ffd83dbSDimitry Andricdef : InstAlias<"mtctr $Rx", (MTSPR 9, gprc:$Rx)>;
45755ffd83dbSDimitry Andricdef : InstAlias<"mfctr $Rx", (MFSPR gprc:$Rx, 9)>;
45765ffd83dbSDimitry Andric
45775ffd83dbSDimitry Andricdef : InstAlias<"mtuamr $Rx", (MTSPR 13, gprc:$Rx)>;
45785ffd83dbSDimitry Andricdef : InstAlias<"mfuamr $Rx", (MFSPR gprc:$Rx, 13)>;
45795ffd83dbSDimitry Andric
45800b57cec5SDimitry Andricdef : InstAlias<"mtdscr $Rx", (MTSPR 17, gprc:$Rx)>;
45810b57cec5SDimitry Andricdef : InstAlias<"mfdscr $Rx", (MFSPR gprc:$Rx, 17)>;
45820b57cec5SDimitry Andric
45830b57cec5SDimitry Andricdef : InstAlias<"mtdsisr $Rx", (MTSPR 18, gprc:$Rx)>;
45840b57cec5SDimitry Andricdef : InstAlias<"mfdsisr $Rx", (MFSPR gprc:$Rx, 18)>;
45850b57cec5SDimitry Andric
45860b57cec5SDimitry Andricdef : InstAlias<"mtdar $Rx", (MTSPR 19, gprc:$Rx)>;
45870b57cec5SDimitry Andricdef : InstAlias<"mfdar $Rx", (MFSPR gprc:$Rx, 19)>;
45880b57cec5SDimitry Andric
45890b57cec5SDimitry Andricdef : InstAlias<"mtdec $Rx", (MTSPR 22, gprc:$Rx)>;
45900b57cec5SDimitry Andricdef : InstAlias<"mfdec $Rx", (MFSPR gprc:$Rx, 22)>;
45910b57cec5SDimitry Andric
45920b57cec5SDimitry Andricdef : InstAlias<"mtsdr1 $Rx", (MTSPR 25, gprc:$Rx)>;
45930b57cec5SDimitry Andricdef : InstAlias<"mfsdr1 $Rx", (MFSPR gprc:$Rx, 25)>;
45940b57cec5SDimitry Andric
45950b57cec5SDimitry Andricdef : InstAlias<"mtsrr0 $Rx", (MTSPR 26, gprc:$Rx)>;
45960b57cec5SDimitry Andricdef : InstAlias<"mfsrr0 $Rx", (MFSPR gprc:$Rx, 26)>;
45970b57cec5SDimitry Andric
45980b57cec5SDimitry Andricdef : InstAlias<"mtsrr1 $Rx", (MTSPR 27, gprc:$Rx)>;
45990b57cec5SDimitry Andricdef : InstAlias<"mfsrr1 $Rx", (MFSPR gprc:$Rx, 27)>;
46000b57cec5SDimitry Andric
46010b57cec5SDimitry Andricdef : InstAlias<"mtcfar $Rx", (MTSPR 28, gprc:$Rx)>;
46020b57cec5SDimitry Andricdef : InstAlias<"mfcfar $Rx", (MFSPR gprc:$Rx, 28)>;
46030b57cec5SDimitry Andric
46040b57cec5SDimitry Andricdef : InstAlias<"mtamr $Rx", (MTSPR 29, gprc:$Rx)>;
46050b57cec5SDimitry Andricdef : InstAlias<"mfamr $Rx", (MFSPR gprc:$Rx, 29)>;
46060b57cec5SDimitry Andric
46070b57cec5SDimitry Andricdef : InstAlias<"mtpid $Rx", (MTSPR 48, gprc:$Rx)>, Requires<[IsBookE]>;
46080b57cec5SDimitry Andricdef : InstAlias<"mfpid $Rx", (MFSPR gprc:$Rx, 48)>, Requires<[IsBookE]>;
46090b57cec5SDimitry Andric
46105ffd83dbSDimitry Andricforeach SPRG = 4-7 in {
46115ffd83dbSDimitry Andric  def : InstAlias<"mfsprg $RT, "#SPRG, (MFSPR gprc:$RT, !add(SPRG, 256))>,
46125ffd83dbSDimitry Andric                  Requires<[IsBookE]>;
46135ffd83dbSDimitry Andric  def : InstAlias<"mfsprg"#SPRG#" $RT", (MFSPR gprc:$RT, !add(SPRG, 256))>,
46145ffd83dbSDimitry Andric                  Requires<[IsBookE]>;
46155ffd83dbSDimitry Andric  def : InstAlias<"mtsprg "#SPRG#", $RT", (MTSPR !add(SPRG, 256), gprc:$RT)>,
46165ffd83dbSDimitry Andric                  Requires<[IsBookE]>;
46175ffd83dbSDimitry Andric  def : InstAlias<"mtsprg"#SPRG#" $RT", (MTSPR !add(SPRG, 256), gprc:$RT)>,
46185ffd83dbSDimitry Andric                  Requires<[IsBookE]>;
46195ffd83dbSDimitry Andric}
46205ffd83dbSDimitry Andric
46215ffd83dbSDimitry Andricforeach SPRG = 0-3 in {
46225ffd83dbSDimitry Andric  def : InstAlias<"mfsprg $RT, "#SPRG, (MFSPR gprc:$RT, !add(SPRG, 272))>;
46235ffd83dbSDimitry Andric  def : InstAlias<"mfsprg"#SPRG#" $RT", (MFSPR gprc:$RT, !add(SPRG, 272))>;
46245ffd83dbSDimitry Andric  def : InstAlias<"mtsprg "#SPRG#", $RT", (MTSPR !add(SPRG, 272), gprc:$RT)>;
46255ffd83dbSDimitry Andric  def : InstAlias<"mtsprg"#SPRG#" $RT", (MTSPR !add(SPRG, 272), gprc:$RT)>;
46265ffd83dbSDimitry Andric}
46275ffd83dbSDimitry Andric
46285ffd83dbSDimitry Andricdef : InstAlias<"mfasr $RT", (MFSPR gprc:$RT, 280)>;
46295ffd83dbSDimitry Andricdef : InstAlias<"mtasr $RT", (MTSPR 280, gprc:$RT)>;
46300b57cec5SDimitry Andric
46310b57cec5SDimitry Andricdef : InstAlias<"mttbl $Rx", (MTSPR 284, gprc:$Rx)>;
46320b57cec5SDimitry Andricdef : InstAlias<"mttbu $Rx", (MTSPR 285, gprc:$Rx)>;
46330b57cec5SDimitry Andric
46345ffd83dbSDimitry Andricdef : InstAlias<"mfpvr $RT", (MFSPR gprc:$RT, 287)>;
46350b57cec5SDimitry Andric
46365ffd83dbSDimitry Andricdef : InstAlias<"mfspefscr $Rx", (MFSPR gprc:$Rx, 512)>;
46375ffd83dbSDimitry Andricdef : InstAlias<"mtspefscr $Rx", (MTSPR 512, gprc:$Rx)>;
46380b57cec5SDimitry Andric
46390b57cec5SDimitry Andricforeach BATR = 0-3 in {
46400b57cec5SDimitry Andric    def : InstAlias<"mtdbatu "#BATR#", $Rx",
46410b57cec5SDimitry Andric                    (MTSPR !add(BATR, !add(BATR, 536)), gprc:$Rx)>,
46420b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46430b57cec5SDimitry Andric    def : InstAlias<"mfdbatu $Rx, "#BATR,
46440b57cec5SDimitry Andric                    (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 536)))>,
46450b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46460b57cec5SDimitry Andric    def : InstAlias<"mtdbatl "#BATR#", $Rx",
46470b57cec5SDimitry Andric                    (MTSPR !add(BATR, !add(BATR, 537)), gprc:$Rx)>,
46480b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46490b57cec5SDimitry Andric    def : InstAlias<"mfdbatl $Rx, "#BATR,
46500b57cec5SDimitry Andric                    (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 537)))>,
46510b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46520b57cec5SDimitry Andric    def : InstAlias<"mtibatu "#BATR#", $Rx",
46530b57cec5SDimitry Andric                    (MTSPR !add(BATR, !add(BATR, 528)), gprc:$Rx)>,
46540b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46550b57cec5SDimitry Andric    def : InstAlias<"mfibatu $Rx, "#BATR,
46560b57cec5SDimitry Andric                    (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 528)))>,
46570b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46580b57cec5SDimitry Andric    def : InstAlias<"mtibatl "#BATR#", $Rx",
46590b57cec5SDimitry Andric                    (MTSPR !add(BATR, !add(BATR, 529)), gprc:$Rx)>,
46600b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46610b57cec5SDimitry Andric    def : InstAlias<"mfibatl $Rx, "#BATR,
46620b57cec5SDimitry Andric                    (MFSPR gprc:$Rx, !add(BATR, !add(BATR, 529)))>,
46630b57cec5SDimitry Andric                    Requires<[IsPPC6xx]>;
46640b57cec5SDimitry Andric}
46650b57cec5SDimitry Andric
46665ffd83dbSDimitry Andricdef : InstAlias<"mtppr $RT", (MTSPR 896, gprc:$RT)>;
46675ffd83dbSDimitry Andricdef : InstAlias<"mfppr $RT", (MFSPR gprc:$RT, 896)>;
46685ffd83dbSDimitry Andric
46695ffd83dbSDimitry Andricdef : InstAlias<"mtesr $Rx", (MTSPR 980, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46705ffd83dbSDimitry Andricdef : InstAlias<"mfesr $Rx", (MFSPR gprc:$Rx, 980)>, Requires<[IsPPC4xx]>;
46715ffd83dbSDimitry Andric
46725ffd83dbSDimitry Andricdef : InstAlias<"mtdear $Rx", (MTSPR 981, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46735ffd83dbSDimitry Andricdef : InstAlias<"mfdear $Rx", (MFSPR gprc:$Rx, 981)>, Requires<[IsPPC4xx]>;
46745ffd83dbSDimitry Andric
46755ffd83dbSDimitry Andricdef : InstAlias<"mttcr $Rx", (MTSPR 986, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46765ffd83dbSDimitry Andricdef : InstAlias<"mftcr $Rx", (MFSPR gprc:$Rx, 986)>, Requires<[IsPPC4xx]>;
46775ffd83dbSDimitry Andric
46785ffd83dbSDimitry Andricdef : InstAlias<"mftbhi $Rx", (MFSPR gprc:$Rx, 988)>, Requires<[IsPPC4xx]>;
46795ffd83dbSDimitry Andricdef : InstAlias<"mttbhi $Rx", (MTSPR 988, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46805ffd83dbSDimitry Andric
46815ffd83dbSDimitry Andricdef : InstAlias<"mftblo $Rx", (MFSPR gprc:$Rx, 989)>, Requires<[IsPPC4xx]>;
46825ffd83dbSDimitry Andricdef : InstAlias<"mttblo $Rx", (MTSPR 989, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46835ffd83dbSDimitry Andric
46845ffd83dbSDimitry Andricdef : InstAlias<"mtsrr2 $Rx", (MTSPR 990, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46855ffd83dbSDimitry Andricdef : InstAlias<"mfsrr2 $Rx", (MFSPR gprc:$Rx, 990)>, Requires<[IsPPC4xx]>;
46865ffd83dbSDimitry Andric
46875ffd83dbSDimitry Andricdef : InstAlias<"mtsrr3 $Rx", (MTSPR 991, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46885ffd83dbSDimitry Andricdef : InstAlias<"mfsrr3 $Rx", (MFSPR gprc:$Rx, 991)>, Requires<[IsPPC4xx]>;
46890b57cec5SDimitry Andric
46900b57cec5SDimitry Andricdef : InstAlias<"mtdccr $Rx", (MTSPR 1018, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46910b57cec5SDimitry Andricdef : InstAlias<"mfdccr $Rx", (MFSPR gprc:$Rx, 1018)>, Requires<[IsPPC4xx]>;
46920b57cec5SDimitry Andric
46930b57cec5SDimitry Andricdef : InstAlias<"mticcr $Rx", (MTSPR 1019, gprc:$Rx)>, Requires<[IsPPC4xx]>;
46940b57cec5SDimitry Andricdef : InstAlias<"mficcr $Rx", (MFSPR gprc:$Rx, 1019)>, Requires<[IsPPC4xx]>;
46950b57cec5SDimitry Andric
4696fe6060f1SDimitry Andric}
46970b57cec5SDimitry Andric
46980b57cec5SDimitry Andricdef : InstAlias<"tlbie $RB", (TLBIE R0, gprc:$RB)>;
46990b57cec5SDimitry Andric
47000b57cec5SDimitry Andricdef : InstAlias<"tlbrehi $RS, $A", (TLBRE2 gprc:$RS, gprc:$A, 0)>,
47010b57cec5SDimitry Andric                Requires<[IsPPC4xx]>;
47020b57cec5SDimitry Andricdef : InstAlias<"tlbrelo $RS, $A", (TLBRE2 gprc:$RS, gprc:$A, 1)>,
47030b57cec5SDimitry Andric                Requires<[IsPPC4xx]>;
47040b57cec5SDimitry Andricdef : InstAlias<"tlbwehi $RS, $A", (TLBWE2 gprc:$RS, gprc:$A, 0)>,
47050b57cec5SDimitry Andric                Requires<[IsPPC4xx]>;
47060b57cec5SDimitry Andricdef : InstAlias<"tlbwelo $RS, $A", (TLBWE2 gprc:$RS, gprc:$A, 1)>,
47070b57cec5SDimitry Andric                Requires<[IsPPC4xx]>;
47080b57cec5SDimitry Andric
47098a4dda33SDimitry Andricdef : InstAlias<"tlbilxlpid", (TLBILX 0, R0, R0)>, Requires<[IsBookE]>;
47108a4dda33SDimitry Andricdef : InstAlias<"tlbilxpid", (TLBILX 1, R0, R0)>, Requires<[IsBookE]>;
47118a4dda33SDimitry Andricdef : InstAlias<"tlbilxva $RA, $RB", (TLBILX 3, gprc:$RA, gprc:$RB)>,
47128a4dda33SDimitry Andric                Requires<[IsBookE]>;
47138a4dda33SDimitry Andricdef : InstAlias<"tlbilxva $RB", (TLBILX 3, R0, gprc:$RB)>, Requires<[IsBookE]>;
47148a4dda33SDimitry Andric
47155ffd83dbSDimitry Andricdef LAx : PPCAsmPseudo<"la $rA, $addr", (ins gprc:$rA, memri:$addr)>;
47165ffd83dbSDimitry Andric
47175ffd83dbSDimitry Andricdef SUBI : PPCAsmPseudo<"subi $rA, $rB, $imm",
47185ffd83dbSDimitry Andric                        (ins gprc:$rA, gprc:$rB, s16imm:$imm)>;
47195ffd83dbSDimitry Andricdef SUBIS : PPCAsmPseudo<"subis $rA, $rB, $imm",
47205ffd83dbSDimitry Andric                         (ins gprc:$rA, gprc:$rB, s16imm:$imm)>;
47215ffd83dbSDimitry Andricdef SUBIC : PPCAsmPseudo<"subic $rA, $rB, $imm",
47225ffd83dbSDimitry Andric                         (ins gprc:$rA, gprc:$rB, s16imm:$imm)>;
47235ffd83dbSDimitry Andricdef SUBIC_rec : PPCAsmPseudo<"subic. $rA, $rB, $imm",
47245ffd83dbSDimitry Andric                          (ins gprc:$rA, gprc:$rB, s16imm:$imm)>;
47255ffd83dbSDimitry Andric
47260b57cec5SDimitry Andricdef EXTLWI : PPCAsmPseudo<"extlwi $rA, $rS, $n, $b",
4727bdd1243dSDimitry Andric                          (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>,
4728bdd1243dSDimitry Andric                          ZExt32To64;
4729480093f4SDimitry Andricdef EXTLWI_rec : PPCAsmPseudo<"extlwi. $rA, $rS, $n, $b",
4730bdd1243dSDimitry Andric                           (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>,
4731bdd1243dSDimitry Andric                           ZExt32To64;
47320b57cec5SDimitry Andricdef EXTRWI : PPCAsmPseudo<"extrwi $rA, $rS, $n, $b",
47330b57cec5SDimitry Andric                          (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>;
4734480093f4SDimitry Andricdef EXTRWI_rec : PPCAsmPseudo<"extrwi. $rA, $rS, $n, $b",
47350b57cec5SDimitry Andric                           (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>;
47360b57cec5SDimitry Andricdef INSLWI : PPCAsmPseudo<"inslwi $rA, $rS, $n, $b",
47370b57cec5SDimitry Andric                          (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>;
4738480093f4SDimitry Andricdef INSLWI_rec : PPCAsmPseudo<"inslwi. $rA, $rS, $n, $b",
47390b57cec5SDimitry Andric                           (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>;
47400b57cec5SDimitry Andricdef INSRWI : PPCAsmPseudo<"insrwi $rA, $rS, $n, $b",
47410b57cec5SDimitry Andric                          (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>;
4742480093f4SDimitry Andricdef INSRWI_rec : PPCAsmPseudo<"insrwi. $rA, $rS, $n, $b",
47430b57cec5SDimitry Andric                           (ins gprc:$rA, gprc:$rS, u5imm:$n, u5imm:$b)>;
47440b57cec5SDimitry Andricdef ROTRWI : PPCAsmPseudo<"rotrwi $rA, $rS, $n",
4745bdd1243dSDimitry Andric                          (ins gprc:$rA, gprc:$rS, u5imm:$n)>, ZExt32To64;
4746480093f4SDimitry Andricdef ROTRWI_rec : PPCAsmPseudo<"rotrwi. $rA, $rS, $n",
4747bdd1243dSDimitry Andric                           (ins gprc:$rA, gprc:$rS, u5imm:$n)>, ZExt32To64;
47480b57cec5SDimitry Andricdef SLWI : PPCAsmPseudo<"slwi $rA, $rS, $n",
4749bdd1243dSDimitry Andric                        (ins gprc:$rA, gprc:$rS, u5imm:$n)>, ZExt32To64;
4750480093f4SDimitry Andricdef SLWI_rec : PPCAsmPseudo<"slwi. $rA, $rS, $n",
4751bdd1243dSDimitry Andric                         (ins gprc:$rA, gprc:$rS, u5imm:$n)>, ZExt32To64;
47520b57cec5SDimitry Andricdef SRWI : PPCAsmPseudo<"srwi $rA, $rS, $n",
4753bdd1243dSDimitry Andric                        (ins gprc:$rA, gprc:$rS, u5imm:$n)>, ZExt32To64;
4754480093f4SDimitry Andricdef SRWI_rec : PPCAsmPseudo<"srwi. $rA, $rS, $n",
4755bdd1243dSDimitry Andric                         (ins gprc:$rA, gprc:$rS, u5imm:$n)>, ZExt32To64;
47560b57cec5SDimitry Andricdef CLRRWI : PPCAsmPseudo<"clrrwi $rA, $rS, $n",
47570b57cec5SDimitry Andric                          (ins gprc:$rA, gprc:$rS, u5imm:$n)>;
4758480093f4SDimitry Andricdef CLRRWI_rec : PPCAsmPseudo<"clrrwi. $rA, $rS, $n",
47590b57cec5SDimitry Andric                           (ins gprc:$rA, gprc:$rS, u5imm:$n)>;
47600b57cec5SDimitry Andricdef CLRLSLWI : PPCAsmPseudo<"clrlslwi $rA, $rS, $b, $n",
47610b57cec5SDimitry Andric                            (ins gprc:$rA, gprc:$rS, u5imm:$b, u5imm:$n)>;
4762480093f4SDimitry Andricdef CLRLSLWI_rec : PPCAsmPseudo<"clrlslwi. $rA, $rS, $b, $n",
47630b57cec5SDimitry Andric                             (ins gprc:$rA, gprc:$rS, u5imm:$b, u5imm:$n)>;
47640b57cec5SDimitry Andric
47655ffd83dbSDimitry Andricdef : InstAlias<"isellt $rT, $rA, $rB",
47665ffd83dbSDimitry Andric                (ISEL gprc:$rT, gprc_nor0:$rA, gprc:$rB, CR0LT)>;
47675ffd83dbSDimitry Andricdef : InstAlias<"iselgt $rT, $rA, $rB",
47685ffd83dbSDimitry Andric                (ISEL gprc:$rT, gprc_nor0:$rA, gprc:$rB, CR0GT)>;
47695ffd83dbSDimitry Andricdef : InstAlias<"iseleq $rT, $rA, $rB",
47705ffd83dbSDimitry Andric                (ISEL gprc:$rT, gprc_nor0:$rA, gprc:$rB, CR0EQ)>;
47715ffd83dbSDimitry Andric
47720b57cec5SDimitry Andricdef : InstAlias<"rotlwi $rA, $rS, $n", (RLWINM gprc:$rA, gprc:$rS, u5imm:$n, 0, 31)>;
4773480093f4SDimitry Andricdef : InstAlias<"rotlwi. $rA, $rS, $n", (RLWINM_rec gprc:$rA, gprc:$rS, u5imm:$n, 0, 31)>;
47740b57cec5SDimitry Andricdef : InstAlias<"rotlw $rA, $rS, $rB", (RLWNM gprc:$rA, gprc:$rS, gprc:$rB, 0, 31)>;
4775480093f4SDimitry Andricdef : InstAlias<"rotlw. $rA, $rS, $rB", (RLWNM_rec gprc:$rA, gprc:$rS, gprc:$rB, 0, 31)>;
47760b57cec5SDimitry Andricdef : InstAlias<"clrlwi $rA, $rS, $n", (RLWINM gprc:$rA, gprc:$rS, 0, u5imm:$n, 31)>;
4777480093f4SDimitry Andricdef : InstAlias<"clrlwi. $rA, $rS, $n", (RLWINM_rec gprc:$rA, gprc:$rS, 0, u5imm:$n, 31)>;
47780b57cec5SDimitry Andric
47790b57cec5SDimitry Andricdef : InstAlias<"cntlzw $rA, $rS", (CNTLZW gprc:$rA, gprc:$rS)>;
4780480093f4SDimitry Andricdef : InstAlias<"cntlzw. $rA, $rS", (CNTLZW_rec gprc:$rA, gprc:$rS)>;
47810b57cec5SDimitry Andric// The POWER variant
47820b57cec5SDimitry Andricdef : MnemonicAlias<"cntlz",  "cntlzw">;
47830b57cec5SDimitry Andricdef : MnemonicAlias<"cntlz.", "cntlzw.">;
47840b57cec5SDimitry Andric
47850b57cec5SDimitry Andricdef EXTLDI : PPCAsmPseudo<"extldi $rA, $rS, $n, $b",
47860b57cec5SDimitry Andric                          (ins g8rc:$rA, g8rc:$rS, u6imm:$n, u6imm:$b)>;
4787480093f4SDimitry Andricdef EXTLDI_rec : PPCAsmPseudo<"extldi. $rA, $rS, $n, $b",
47880b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u6imm:$n, u6imm:$b)>;
47890b57cec5SDimitry Andricdef EXTRDI : PPCAsmPseudo<"extrdi $rA, $rS, $n, $b",
47900b57cec5SDimitry Andric                          (ins g8rc:$rA, g8rc:$rS, u6imm:$n, u6imm:$b)>;
4791480093f4SDimitry Andricdef EXTRDI_rec : PPCAsmPseudo<"extrdi. $rA, $rS, $n, $b",
47920b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u6imm:$n, u6imm:$b)>;
47930b57cec5SDimitry Andricdef INSRDI : PPCAsmPseudo<"insrdi $rA, $rS, $n, $b",
47940b57cec5SDimitry Andric                          (ins g8rc:$rA, g8rc:$rS, u6imm:$n, u6imm:$b)>;
4795480093f4SDimitry Andricdef INSRDI_rec : PPCAsmPseudo<"insrdi. $rA, $rS, $n, $b",
47960b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u6imm:$n, u6imm:$b)>;
47970b57cec5SDimitry Andricdef ROTRDI : PPCAsmPseudo<"rotrdi $rA, $rS, $n",
47980b57cec5SDimitry Andric                          (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
4799480093f4SDimitry Andricdef ROTRDI_rec : PPCAsmPseudo<"rotrdi. $rA, $rS, $n",
48000b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
48010b57cec5SDimitry Andricdef SLDI : PPCAsmPseudo<"sldi $rA, $rS, $n",
48020b57cec5SDimitry Andric                        (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
4803480093f4SDimitry Andricdef SLDI_rec : PPCAsmPseudo<"sldi. $rA, $rS, $n",
48040b57cec5SDimitry Andric                         (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
48050b57cec5SDimitry Andricdef SRDI : PPCAsmPseudo<"srdi $rA, $rS, $n",
48060b57cec5SDimitry Andric                        (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
4807480093f4SDimitry Andricdef SRDI_rec : PPCAsmPseudo<"srdi. $rA, $rS, $n",
48080b57cec5SDimitry Andric                         (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
48090b57cec5SDimitry Andricdef CLRRDI : PPCAsmPseudo<"clrrdi $rA, $rS, $n",
48100b57cec5SDimitry Andric                          (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
4811480093f4SDimitry Andricdef CLRRDI_rec : PPCAsmPseudo<"clrrdi. $rA, $rS, $n",
48120b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u6imm:$n)>;
48130b57cec5SDimitry Andricdef CLRLSLDI : PPCAsmPseudo<"clrlsldi $rA, $rS, $b, $n",
48140b57cec5SDimitry Andric                            (ins g8rc:$rA, g8rc:$rS, u6imm:$b, u6imm:$n)>;
4815480093f4SDimitry Andricdef CLRLSLDI_rec : PPCAsmPseudo<"clrlsldi. $rA, $rS, $b, $n",
48160b57cec5SDimitry Andric                             (ins g8rc:$rA, g8rc:$rS, u6imm:$b, u6imm:$n)>;
48170b57cec5SDimitry Andricdef SUBPCIS : PPCAsmPseudo<"subpcis $RT, $D", (ins g8rc:$RT, s16imm:$D)>;
48180b57cec5SDimitry Andric
48190b57cec5SDimitry Andricdef : InstAlias<"rotldi $rA, $rS, $n", (RLDICL g8rc:$rA, g8rc:$rS, u6imm:$n, 0)>;
48205ffd83dbSDimitry Andricdef : InstAlias<"rotldi $rA, $rS, $n",
48215ffd83dbSDimitry Andric                (RLDICL_32_64 g8rc:$rA, gprc:$rS, u6imm:$n, 0)>;
4822480093f4SDimitry Andricdef : InstAlias<"rotldi. $rA, $rS, $n", (RLDICL_rec g8rc:$rA, g8rc:$rS, u6imm:$n, 0)>;
48230b57cec5SDimitry Andricdef : InstAlias<"rotld $rA, $rS, $rB", (RLDCL g8rc:$rA, g8rc:$rS, gprc:$rB, 0)>;
4824480093f4SDimitry Andricdef : InstAlias<"rotld. $rA, $rS, $rB", (RLDCL_rec g8rc:$rA, g8rc:$rS, gprc:$rB, 0)>;
48250b57cec5SDimitry Andricdef : InstAlias<"clrldi $rA, $rS, $n", (RLDICL g8rc:$rA, g8rc:$rS, 0, u6imm:$n)>;
48260b57cec5SDimitry Andricdef : InstAlias<"clrldi $rA, $rS, $n",
48270b57cec5SDimitry Andric                (RLDICL_32_64 g8rc:$rA, gprc:$rS, 0, u6imm:$n)>;
4828480093f4SDimitry Andricdef : InstAlias<"clrldi. $rA, $rS, $n", (RLDICL_rec g8rc:$rA, g8rc:$rS, 0, u6imm:$n)>;
48290b57cec5SDimitry Andricdef : InstAlias<"lnia $RT", (ADDPCIS g8rc:$RT, 0)>;
48300b57cec5SDimitry Andric
48310b57cec5SDimitry Andricdef RLWINMbm : PPCAsmPseudo<"rlwinm $rA, $rS, $n, $b",
48320b57cec5SDimitry Andric                            (ins g8rc:$rA, g8rc:$rS, u5imm:$n, i32imm:$b)>;
4833480093f4SDimitry Andricdef RLWINMbm_rec : PPCAsmPseudo<"rlwinm. $rA, $rS, $n, $b",
48340b57cec5SDimitry Andric                            (ins g8rc:$rA, g8rc:$rS, u5imm:$n, i32imm:$b)>;
48350b57cec5SDimitry Andricdef RLWIMIbm : PPCAsmPseudo<"rlwimi $rA, $rS, $n, $b",
48360b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u5imm:$n, i32imm:$b)>;
4837480093f4SDimitry Andricdef RLWIMIbm_rec : PPCAsmPseudo<"rlwimi. $rA, $rS, $n, $b",
48380b57cec5SDimitry Andric                            (ins g8rc:$rA, g8rc:$rS, u5imm:$n, i32imm:$b)>;
48390b57cec5SDimitry Andricdef RLWNMbm : PPCAsmPseudo<"rlwnm $rA, $rS, $n, $b",
48400b57cec5SDimitry Andric                          (ins g8rc:$rA, g8rc:$rS, u5imm:$n, i32imm:$b)>;
4841480093f4SDimitry Andricdef RLWNMbm_rec : PPCAsmPseudo<"rlwnm. $rA, $rS, $n, $b",
48420b57cec5SDimitry Andric                           (ins g8rc:$rA, g8rc:$rS, u5imm:$n, i32imm:$b)>;
48430fca6ea1SDimitry Andricdef PPCLdFixedAddr :
48440fca6ea1SDimitry Andric  PPCPostRAExpPseudo<(outs gprc:$rT), (ins i32imm:$imm), "#FA_LOAD",
48450fca6ea1SDimitry Andric                     [(set i32:$rT, (int_ppc_fixed_addr_ld timm:$imm))]>;
48460b57cec5SDimitry Andric
48470b57cec5SDimitry Andric// These generic branch instruction forms are used for the assembler parser only.
48480b57cec5SDimitry Andric// Defs and Uses are conservative, since we don't know the BO value.
4849349cc55cSDimitry Andriclet PPC970_Unit = 7, isBranch = 1, hasSideEffects = 0 in {
48500b57cec5SDimitry Andric  let Defs = [CTR], Uses = [CTR, RM] in {
48510b57cec5SDimitry Andric    def gBC : BForm_3<16, 0, 0, (outs),
485206c3fb27SDimitry Andric                      (ins u5imm:$BO, crbitrc:$BI, condbrtarget:$BD),
485306c3fb27SDimitry Andric                      "bc $BO, $BI, $BD">;
48540b57cec5SDimitry Andric    def gBCA : BForm_3<16, 1, 0, (outs),
485506c3fb27SDimitry Andric                       (ins u5imm:$BO, crbitrc:$BI, abscondbrtarget:$BD),
485606c3fb27SDimitry Andric                       "bca $BO, $BI, $BD">;
48570b57cec5SDimitry Andric    let isAsmParserOnly = 1 in {
48580b57cec5SDimitry Andric      def gBCat : BForm_3_at<16, 0, 0, (outs),
485906c3fb27SDimitry Andric                             (ins u5imm:$BO, atimm:$at, crbitrc:$BI,
486006c3fb27SDimitry Andric                                  condbrtarget:$BD),
486106c3fb27SDimitry Andric                                  "bc$at $BO, $BI, $BD">;
48620b57cec5SDimitry Andric      def gBCAat : BForm_3_at<16, 1, 0, (outs),
486306c3fb27SDimitry Andric                              (ins u5imm:$BO, atimm:$at, crbitrc:$BI,
486406c3fb27SDimitry Andric                                   abscondbrtarget:$BD),
486506c3fb27SDimitry Andric                                   "bca$at $BO, $BI, $BD">;
48660b57cec5SDimitry Andric    } // isAsmParserOnly = 1
48670b57cec5SDimitry Andric  }
48680b57cec5SDimitry Andric  let Defs = [LR, CTR], Uses = [CTR, RM] in {
48690b57cec5SDimitry Andric    def gBCL : BForm_3<16, 0, 1, (outs),
487006c3fb27SDimitry Andric                       (ins u5imm:$BO, crbitrc:$BI, condbrtarget:$BD),
487106c3fb27SDimitry Andric                       "bcl $BO, $BI, $BD">;
48720b57cec5SDimitry Andric    def gBCLA : BForm_3<16, 1, 1, (outs),
487306c3fb27SDimitry Andric                        (ins u5imm:$BO, crbitrc:$BI, abscondbrtarget:$BD),
487406c3fb27SDimitry Andric                        "bcla $BO, $BI, $BD">;
48750b57cec5SDimitry Andric    let isAsmParserOnly = 1 in {
48760b57cec5SDimitry Andric      def gBCLat : BForm_3_at<16, 0, 1, (outs),
487706c3fb27SDimitry Andric                         (ins u5imm:$BO, atimm:$at, crbitrc:$BI,
487806c3fb27SDimitry Andric                              condbrtarget:$BD),
487906c3fb27SDimitry Andric                              "bcl$at $BO, $BI, $BD">;
48800b57cec5SDimitry Andric      def gBCLAat : BForm_3_at<16, 1, 1, (outs),
488106c3fb27SDimitry Andric                          (ins u5imm:$BO, atimm:$at, crbitrc:$BI,
488206c3fb27SDimitry Andric                               abscondbrtarget:$BD),
488306c3fb27SDimitry Andric                               "bcla$at $BO, $BI, $BD">;
48840b57cec5SDimitry Andric    } // // isAsmParserOnly = 1
48850b57cec5SDimitry Andric  }
48860b57cec5SDimitry Andric  let Defs = [CTR], Uses = [CTR, LR, RM] in
48870b57cec5SDimitry Andric    def gBCLR : XLForm_2<19, 16, 0, (outs),
488806c3fb27SDimitry Andric                         (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH),
488906c3fb27SDimitry Andric                         "bclr $BO, $BI, $BH", IIC_BrB, []>;
48900b57cec5SDimitry Andric  let Defs = [LR, CTR], Uses = [CTR, LR, RM] in
48910b57cec5SDimitry Andric    def gBCLRL : XLForm_2<19, 16, 1, (outs),
489206c3fb27SDimitry Andric                          (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH),
489306c3fb27SDimitry Andric                          "bclrl $BO, $BI, $BH", IIC_BrB, []>;
48940b57cec5SDimitry Andric  let Defs = [CTR], Uses = [CTR, LR, RM] in
48950b57cec5SDimitry Andric    def gBCCTR : XLForm_2<19, 528, 0, (outs),
489606c3fb27SDimitry Andric                          (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH),
489706c3fb27SDimitry Andric                          "bcctr $BO, $BI, $BH", IIC_BrB, []>;
48980b57cec5SDimitry Andric  let Defs = [LR, CTR], Uses = [CTR, LR, RM] in
48990b57cec5SDimitry Andric    def gBCCTRL : XLForm_2<19, 528, 1, (outs),
490006c3fb27SDimitry Andric                           (ins u5imm:$BO, crbitrc:$BI, i32imm:$BH),
490106c3fb27SDimitry Andric                           "bcctrl $BO, $BI, $BH", IIC_BrB, []>;
49020b57cec5SDimitry Andric}
49030b57cec5SDimitry Andric
49040b57cec5SDimitry Andricmulticlass BranchSimpleMnemonicAT<string pm, int at> {
49050b57cec5SDimitry Andric  def : InstAlias<"bc"#pm#" $bo, $bi, $dst", (gBCat u5imm:$bo, at, crbitrc:$bi,
49060b57cec5SDimitry Andric                                                    condbrtarget:$dst)>;
49070b57cec5SDimitry Andric  def : InstAlias<"bca"#pm#" $bo, $bi, $dst", (gBCAat u5imm:$bo, at, crbitrc:$bi,
49080b57cec5SDimitry Andric                                                      condbrtarget:$dst)>;
49090b57cec5SDimitry Andric  def : InstAlias<"bcl"#pm#" $bo, $bi, $dst", (gBCLat u5imm:$bo, at, crbitrc:$bi,
49100b57cec5SDimitry Andric                                                      condbrtarget:$dst)>;
49110b57cec5SDimitry Andric  def : InstAlias<"bcla"#pm#" $bo, $bi, $dst", (gBCLAat u5imm:$bo, at, crbitrc:$bi,
49120b57cec5SDimitry Andric                                                        condbrtarget:$dst)>;
49130b57cec5SDimitry Andric}
49140b57cec5SDimitry Andricdefm : BranchSimpleMnemonicAT<"+", 3>;
49150b57cec5SDimitry Andricdefm : BranchSimpleMnemonicAT<"-", 2>;
49160b57cec5SDimitry Andric
49170b57cec5SDimitry Andricdef : InstAlias<"bclr $bo, $bi", (gBCLR u5imm:$bo, crbitrc:$bi, 0)>;
49180b57cec5SDimitry Andricdef : InstAlias<"bclrl $bo, $bi", (gBCLRL u5imm:$bo, crbitrc:$bi, 0)>;
49190b57cec5SDimitry Andricdef : InstAlias<"bcctr $bo, $bi", (gBCCTR u5imm:$bo, crbitrc:$bi, 0)>;
49200b57cec5SDimitry Andricdef : InstAlias<"bcctrl $bo, $bi", (gBCCTRL u5imm:$bo, crbitrc:$bi, 0)>;
49210b57cec5SDimitry Andric
49220b57cec5SDimitry Andricmulticlass BranchSimpleMnemonic1<string name, string pm, int bo> {
49230b57cec5SDimitry Andric  def : InstAlias<"b"#name#pm#" $bi, $dst", (gBC bo, crbitrc:$bi, condbrtarget:$dst)>;
49240b57cec5SDimitry Andric  def : InstAlias<"b"#name#"a"#pm#" $bi, $dst", (gBCA bo, crbitrc:$bi, abscondbrtarget:$dst)>;
49250b57cec5SDimitry Andric  def : InstAlias<"b"#name#"lr"#pm#" $bi", (gBCLR bo, crbitrc:$bi, 0)>;
49260b57cec5SDimitry Andric  def : InstAlias<"b"#name#"l"#pm#" $bi, $dst", (gBCL bo, crbitrc:$bi, condbrtarget:$dst)>;
49270b57cec5SDimitry Andric  def : InstAlias<"b"#name#"la"#pm#" $bi, $dst", (gBCLA bo, crbitrc:$bi, abscondbrtarget:$dst)>;
49280b57cec5SDimitry Andric  def : InstAlias<"b"#name#"lrl"#pm#" $bi", (gBCLRL bo, crbitrc:$bi, 0)>;
49290b57cec5SDimitry Andric}
49300b57cec5SDimitry Andricmulticlass BranchSimpleMnemonic2<string name, string pm, int bo>
49310b57cec5SDimitry Andric  : BranchSimpleMnemonic1<name, pm, bo> {
49320b57cec5SDimitry Andric  def : InstAlias<"b"#name#"ctr"#pm#" $bi", (gBCCTR bo, crbitrc:$bi, 0)>;
49330b57cec5SDimitry Andric  def : InstAlias<"b"#name#"ctrl"#pm#" $bi", (gBCCTRL bo, crbitrc:$bi, 0)>;
49340b57cec5SDimitry Andric}
49350b57cec5SDimitry Andricdefm : BranchSimpleMnemonic2<"t", "", 12>;
49360b57cec5SDimitry Andricdefm : BranchSimpleMnemonic2<"f", "", 4>;
49370b57cec5SDimitry Andricdefm : BranchSimpleMnemonic2<"t", "-", 14>;
49380b57cec5SDimitry Andricdefm : BranchSimpleMnemonic2<"f", "-", 6>;
49390b57cec5SDimitry Andricdefm : BranchSimpleMnemonic2<"t", "+", 15>;
49400b57cec5SDimitry Andricdefm : BranchSimpleMnemonic2<"f", "+", 7>;
49410b57cec5SDimitry Andricdefm : BranchSimpleMnemonic1<"dnzt", "", 8>;
49420b57cec5SDimitry Andricdefm : BranchSimpleMnemonic1<"dnzf", "", 0>;
49430b57cec5SDimitry Andricdefm : BranchSimpleMnemonic1<"dzt", "", 10>;
49440b57cec5SDimitry Andricdefm : BranchSimpleMnemonic1<"dzf", "", 2>;
49450b57cec5SDimitry Andric
49460b57cec5SDimitry Andricmulticlass BranchExtendedMnemonicPM<string name, string pm, int bibo> {
49470b57cec5SDimitry Andric  def : InstAlias<"b"#name#pm#" $cc, $dst",
49480b57cec5SDimitry Andric                  (BCC bibo, crrc:$cc, condbrtarget:$dst)>;
49490b57cec5SDimitry Andric  def : InstAlias<"b"#name#pm#" $dst",
49500b57cec5SDimitry Andric                  (BCC bibo, CR0, condbrtarget:$dst)>;
49510b57cec5SDimitry Andric
49520b57cec5SDimitry Andric  def : InstAlias<"b"#name#"a"#pm#" $cc, $dst",
49530b57cec5SDimitry Andric                  (BCCA bibo, crrc:$cc, abscondbrtarget:$dst)>;
49540b57cec5SDimitry Andric  def : InstAlias<"b"#name#"a"#pm#" $dst",
49550b57cec5SDimitry Andric                  (BCCA bibo, CR0, abscondbrtarget:$dst)>;
49560b57cec5SDimitry Andric
49570b57cec5SDimitry Andric  def : InstAlias<"b"#name#"lr"#pm#" $cc",
49580b57cec5SDimitry Andric                  (BCCLR bibo, crrc:$cc)>;
49590b57cec5SDimitry Andric  def : InstAlias<"b"#name#"lr"#pm,
49600b57cec5SDimitry Andric                  (BCCLR bibo, CR0)>;
49610b57cec5SDimitry Andric
49620b57cec5SDimitry Andric  def : InstAlias<"b"#name#"ctr"#pm#" $cc",
49630b57cec5SDimitry Andric                  (BCCCTR bibo, crrc:$cc)>;
49640b57cec5SDimitry Andric  def : InstAlias<"b"#name#"ctr"#pm,
49650b57cec5SDimitry Andric                  (BCCCTR bibo, CR0)>;
49660b57cec5SDimitry Andric
49670b57cec5SDimitry Andric  def : InstAlias<"b"#name#"l"#pm#" $cc, $dst",
49680b57cec5SDimitry Andric                  (BCCL bibo, crrc:$cc, condbrtarget:$dst)>;
49690b57cec5SDimitry Andric  def : InstAlias<"b"#name#"l"#pm#" $dst",
49700b57cec5SDimitry Andric                  (BCCL bibo, CR0, condbrtarget:$dst)>;
49710b57cec5SDimitry Andric
49720b57cec5SDimitry Andric  def : InstAlias<"b"#name#"la"#pm#" $cc, $dst",
49730b57cec5SDimitry Andric                  (BCCLA bibo, crrc:$cc, abscondbrtarget:$dst)>;
49740b57cec5SDimitry Andric  def : InstAlias<"b"#name#"la"#pm#" $dst",
49750b57cec5SDimitry Andric                  (BCCLA bibo, CR0, abscondbrtarget:$dst)>;
49760b57cec5SDimitry Andric
49770b57cec5SDimitry Andric  def : InstAlias<"b"#name#"lrl"#pm#" $cc",
49780b57cec5SDimitry Andric                  (BCCLRL bibo, crrc:$cc)>;
49790b57cec5SDimitry Andric  def : InstAlias<"b"#name#"lrl"#pm,
49800b57cec5SDimitry Andric                  (BCCLRL bibo, CR0)>;
49810b57cec5SDimitry Andric
49820b57cec5SDimitry Andric  def : InstAlias<"b"#name#"ctrl"#pm#" $cc",
49830b57cec5SDimitry Andric                  (BCCCTRL bibo, crrc:$cc)>;
49840b57cec5SDimitry Andric  def : InstAlias<"b"#name#"ctrl"#pm,
49850b57cec5SDimitry Andric                  (BCCCTRL bibo, CR0)>;
49860b57cec5SDimitry Andric}
49870b57cec5SDimitry Andricmulticlass BranchExtendedMnemonic<string name, int bibo> {
49880b57cec5SDimitry Andric  defm : BranchExtendedMnemonicPM<name, "", bibo>;
49890b57cec5SDimitry Andric  defm : BranchExtendedMnemonicPM<name, "-", !add(bibo, 2)>;
49900b57cec5SDimitry Andric  defm : BranchExtendedMnemonicPM<name, "+", !add(bibo, 3)>;
49910b57cec5SDimitry Andric}
49920b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"lt", 12>;
49930b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"gt", 44>;
49940b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"eq", 76>;
49950b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"un", 108>;
49960b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"so", 108>;
49970b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"ge", 4>;
49980b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"nl", 4>;
49990b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"le", 36>;
50000b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"ng", 36>;
50010b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"ne", 68>;
50020b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"nu", 100>;
50030b57cec5SDimitry Andricdefm : BranchExtendedMnemonic<"ns", 100>;
50040b57cec5SDimitry Andric
50050b57cec5SDimitry Andricdef : InstAlias<"cmpwi $rA, $imm", (CMPWI CR0, gprc:$rA, s16imm:$imm)>;
50060b57cec5SDimitry Andricdef : InstAlias<"cmpw $rA, $rB", (CMPW CR0, gprc:$rA, gprc:$rB)>;
50070b57cec5SDimitry Andricdef : InstAlias<"cmplwi $rA, $imm", (CMPLWI CR0, gprc:$rA, u16imm:$imm)>;
50080b57cec5SDimitry Andricdef : InstAlias<"cmplw $rA, $rB", (CMPLW CR0, gprc:$rA, gprc:$rB)>;
50090b57cec5SDimitry Andricdef : InstAlias<"cmpdi $rA, $imm", (CMPDI CR0, g8rc:$rA, s16imm64:$imm)>;
50100b57cec5SDimitry Andricdef : InstAlias<"cmpd $rA, $rB", (CMPD CR0, g8rc:$rA, g8rc:$rB)>;
50110b57cec5SDimitry Andricdef : InstAlias<"cmpldi $rA, $imm", (CMPLDI CR0, g8rc:$rA, u16imm64:$imm)>;
50120b57cec5SDimitry Andricdef : InstAlias<"cmpld $rA, $rB", (CMPLD CR0, g8rc:$rA, g8rc:$rB)>;
50130b57cec5SDimitry Andric
50140b57cec5SDimitry Andricdef : InstAlias<"cmpi $bf, 0, $rA, $imm", (CMPWI crrc:$bf, gprc:$rA, s16imm:$imm)>;
50150b57cec5SDimitry Andricdef : InstAlias<"cmp $bf, 0, $rA, $rB", (CMPW crrc:$bf, gprc:$rA, gprc:$rB)>;
50160b57cec5SDimitry Andricdef : InstAlias<"cmpli $bf, 0, $rA, $imm", (CMPLWI crrc:$bf, gprc:$rA, u16imm:$imm)>;
50170b57cec5SDimitry Andricdef : InstAlias<"cmpl $bf, 0, $rA, $rB", (CMPLW crrc:$bf, gprc:$rA, gprc:$rB)>;
50180b57cec5SDimitry Andricdef : InstAlias<"cmpi $bf, 1, $rA, $imm", (CMPDI crrc:$bf, g8rc:$rA, s16imm64:$imm)>;
50190b57cec5SDimitry Andricdef : InstAlias<"cmp $bf, 1, $rA, $rB", (CMPD crrc:$bf, g8rc:$rA, g8rc:$rB)>;
50200b57cec5SDimitry Andricdef : InstAlias<"cmpli $bf, 1, $rA, $imm", (CMPLDI crrc:$bf, g8rc:$rA, u16imm64:$imm)>;
50210b57cec5SDimitry Andricdef : InstAlias<"cmpl $bf, 1, $rA, $rB", (CMPLD crrc:$bf, g8rc:$rA, g8rc:$rB)>;
50220b57cec5SDimitry Andric
50235ffd83dbSDimitry Andricdef : InstAlias<"trap", (TW 31, R0, R0)>;
50245ffd83dbSDimitry Andric
50250b57cec5SDimitry Andricmulticlass TrapExtendedMnemonic<string name, int to> {
50260b57cec5SDimitry Andric  def : InstAlias<"td"#name#"i $rA, $imm", (TDI to, g8rc:$rA, s16imm:$imm)>;
50270b57cec5SDimitry Andric  def : InstAlias<"td"#name#" $rA, $rB", (TD to, g8rc:$rA, g8rc:$rB)>;
50280b57cec5SDimitry Andric  def : InstAlias<"tw"#name#"i $rA, $imm", (TWI to, gprc:$rA, s16imm:$imm)>;
50290b57cec5SDimitry Andric  def : InstAlias<"tw"#name#" $rA, $rB", (TW to, gprc:$rA, gprc:$rB)>;
50300b57cec5SDimitry Andric}
50310b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"lt", 16>;
50320b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"le", 20>;
50330b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"eq", 4>;
50340b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"ge", 12>;
50350b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"gt", 8>;
50360b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"nl", 12>;
50370b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"ne", 24>;
50380b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"ng", 20>;
50390b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"llt", 2>;
50400b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"lle", 6>;
50410b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"lge", 5>;
50420b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"lgt", 1>;
50430b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"lnl", 5>;
50440b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"lng", 6>;
50450b57cec5SDimitry Andricdefm : TrapExtendedMnemonic<"u", 31>;
50460b57cec5SDimitry Andric
50470b57cec5SDimitry Andric// Atomic loads
50480fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_load_8  DForm:$src)), (LBZ  memri:$src)>;
50490fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_load_16 DForm:$src)), (LHZ  memri:$src)>;
50500fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_load_32 DForm:$src)), (LWZ  memri:$src)>;
50510fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_load_8  XForm:$src)), (LBZX memrr:$src)>;
50520fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_load_16 XForm:$src)), (LHZX memrr:$src)>;
50530fca6ea1SDimitry Andricdef : Pat<(i32 (atomic_load_32 XForm:$src)), (LWZX memrr:$src)>;
50540b57cec5SDimitry Andric
50550b57cec5SDimitry Andric// Atomic stores
50565f757f3fSDimitry Andricdef : Pat<(atomic_store_8  i32:$val, DForm:$ptr), (STB  gprc:$val, memri:$ptr)>;
50575f757f3fSDimitry Andricdef : Pat<(atomic_store_16 i32:$val, DForm:$ptr), (STH  gprc:$val, memri:$ptr)>;
50585f757f3fSDimitry Andricdef : Pat<(atomic_store_32 i32:$val, DForm:$ptr), (STW  gprc:$val, memri:$ptr)>;
50595f757f3fSDimitry Andricdef : Pat<(atomic_store_8  i32:$val, XForm:$ptr), (STBX gprc:$val, memrr:$ptr)>;
50605f757f3fSDimitry Andricdef : Pat<(atomic_store_16 i32:$val, XForm:$ptr), (STHX gprc:$val, memrr:$ptr)>;
50615f757f3fSDimitry Andricdef : Pat<(atomic_store_32 i32:$val, XForm:$ptr), (STWX gprc:$val, memrr:$ptr)>;
50620b57cec5SDimitry Andric
50630b57cec5SDimitry Andriclet Predicates = [IsISA3_0] in {
50640b57cec5SDimitry Andric
50650b57cec5SDimitry Andric// Copy-Paste Facility
50660b57cec5SDimitry Andric// We prefix 'CP' to COPY due to name conflict in Target.td. We also prefix to
50670b57cec5SDimitry Andric// PASTE for naming consistency.
50680b57cec5SDimitry Andriclet mayLoad = 1 in
5069fe6060f1SDimitry Andricdef CP_COPY   : X_RA5_RB5<31, 774, "copy"  , gprc, IIC_LdStCOPY, []>;
50700b57cec5SDimitry Andric
50710b57cec5SDimitry Andriclet mayStore = 1, Defs = [CR0] in
5072480093f4SDimitry Andricdef CP_PASTE_rec : X_L1_RA5_RB5<31, 902, "paste.", gprc, IIC_LdStPASTE, []>, isRecordForm;
50730b57cec5SDimitry Andric
5074fe6060f1SDimitry Andricdef : InstAlias<"paste. $RA, $RB", (CP_PASTE_rec gprc:$RA, gprc:$RB, 1)>;
5075fe6060f1SDimitry Andricdef CP_ABORT : XForm_0<31, 838, (outs), (ins), "cpabort", IIC_SprABORT, []>;
50760b57cec5SDimitry Andric
50770b57cec5SDimitry Andric// Message Synchronize
50780b57cec5SDimitry Andricdef MSGSYNC : XForm_0<31, 886, (outs), (ins), "msgsync", IIC_SprMSGSYNC, []>;
50790b57cec5SDimitry Andric
50800b57cec5SDimitry Andric// Power-Saving Mode Instruction:
50810b57cec5SDimitry Andricdef STOP : XForm_0<19, 370, (outs), (ins), "stop", IIC_SprSTOP, []>;
50820b57cec5SDimitry Andric
5083fe6060f1SDimitry Andricdef SETB : XForm_44<31, 128, (outs gprc:$RT), (ins crrc:$BFA),
5084bdd1243dSDimitry Andric                       "setb $RT, $BFA", IIC_IntGeneral>, SExt32To64;
50850b57cec5SDimitry Andric} // IsISA3_0
50860b57cec5SDimitry Andric
5087fe6060f1SDimitry Andriclet Predicates = [IsISA3_0] in {
5088fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_cmprb i32:$a, gprc:$b, gprc:$c)),
5089fe6060f1SDimitry Andric          (i32 (SETB (CMPRB u1imm:$a, $b, $c)))>;
5090fe6060f1SDimitry Andric}
5091fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_mulhw gprc:$a, gprc:$b)),
5092fe6060f1SDimitry Andric          (i32 (MULHW $a, $b))>;
5093fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_mulhwu gprc:$a, gprc:$b)),
5094fe6060f1SDimitry Andric          (i32 (MULHWU $a, $b))>;
5095fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_cmpb gprc:$a, gprc:$b)),
5096fe6060f1SDimitry Andric          (i32 (CMPB $a, $b))>;
5097fe6060f1SDimitry Andric
5098fe6060f1SDimitry Andricdef : Pat<(int_ppc_load2r ForceXForm:$ptr),
5099fe6060f1SDimitry Andric          (LHBRX ForceXForm:$ptr)>;
5100fe6060f1SDimitry Andricdef : Pat<(int_ppc_load4r ForceXForm:$ptr),
5101fe6060f1SDimitry Andric          (LWBRX ForceXForm:$ptr)>;
5102fe6060f1SDimitry Andricdef : Pat<(int_ppc_store2r gprc:$a, ForceXForm:$ptr),
5103fe6060f1SDimitry Andric          (STHBRX gprc:$a, ForceXForm:$ptr)>;
5104fe6060f1SDimitry Andricdef : Pat<(int_ppc_store4r gprc:$a, ForceXForm:$ptr),
5105fe6060f1SDimitry Andric          (STWBRX gprc:$a, ForceXForm:$ptr)>;
5106fe6060f1SDimitry Andric
5107fe6060f1SDimitry Andric
51080b57cec5SDimitry Andric// Fast 32-bit reverse bits algorithm:
51090b57cec5SDimitry Andric// Step 1: 1-bit swap (swap odd 1-bit and even 1-bit):
51100b57cec5SDimitry Andric// n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xAAAAAAAA);
51110b57cec5SDimitry Andric// Step 2: 2-bit swap (swap odd 2-bit and even 2-bit):
51120b57cec5SDimitry Andric// n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xCCCCCCCC);
51130b57cec5SDimitry Andric// Step 3: 4-bit swap (swap odd 4-bit and even 4-bit):
51140b57cec5SDimitry Andric// n = ((n >> 4) & 0x0F0F0F0F) | ((n << 4) & 0xF0F0F0F0);
51150b57cec5SDimitry Andric// Step 4: byte reverse (Suppose n = [B1,B2,B3,B4]):
51160b57cec5SDimitry Andric// Step 4.1: Put B4,B2 in the right position (rotate left 3 bytes):
51170b57cec5SDimitry Andric// n' = (n rotl 24);  After which n' = [B4, B1, B2, B3]
51180b57cec5SDimitry Andric// Step 4.2: Insert B3 to the right position:
51190b57cec5SDimitry Andric// n' = rlwimi n', n, 8, 8, 15;  After which n' = [B4, B3, B2, B3]
51200b57cec5SDimitry Andric// Step 4.3: Insert B1 to the right position:
51210b57cec5SDimitry Andric// n' = rlwimi n', n, 8, 24, 31;  After which n' = [B4, B3, B2, B1]
51220b57cec5SDimitry Andricdef MaskValues {
51230b57cec5SDimitry Andric  dag Lo1 = (ORI (LIS 0x5555), 0x5555);
51240b57cec5SDimitry Andric  dag Hi1 = (ORI (LIS 0xAAAA), 0xAAAA);
51250b57cec5SDimitry Andric  dag Lo2 = (ORI (LIS 0x3333), 0x3333);
51260b57cec5SDimitry Andric  dag Hi2 = (ORI (LIS 0xCCCC), 0xCCCC);
51270b57cec5SDimitry Andric  dag Lo4 = (ORI (LIS 0x0F0F), 0x0F0F);
51280b57cec5SDimitry Andric  dag Hi4 = (ORI (LIS 0xF0F0), 0xF0F0);
51290b57cec5SDimitry Andric}
51300b57cec5SDimitry Andric
51310b57cec5SDimitry Andricdef Shift1 {
51320b57cec5SDimitry Andric  dag Right = (RLWINM $A, 31, 1, 31);
51330b57cec5SDimitry Andric  dag Left = (RLWINM $A, 1, 0, 30);
51340b57cec5SDimitry Andric}
51350b57cec5SDimitry Andric
51360b57cec5SDimitry Andricdef Swap1 {
51370b57cec5SDimitry Andric  dag Bit = (OR (AND Shift1.Right, MaskValues.Lo1),
51380b57cec5SDimitry Andric   (AND Shift1.Left, MaskValues.Hi1));
51390b57cec5SDimitry Andric}
51400b57cec5SDimitry Andric
51410b57cec5SDimitry Andricdef Shift2 {
51420b57cec5SDimitry Andric  dag Right = (RLWINM Swap1.Bit, 30, 2, 31);
51430b57cec5SDimitry Andric  dag Left = (RLWINM Swap1.Bit, 2, 0, 29);
51440b57cec5SDimitry Andric}
51450b57cec5SDimitry Andric
51460b57cec5SDimitry Andricdef Swap2 {
51470b57cec5SDimitry Andric  dag Bits = (OR (AND Shift2.Right, MaskValues.Lo2),
51480b57cec5SDimitry Andric                 (AND Shift2.Left, MaskValues.Hi2));
51490b57cec5SDimitry Andric}
51500b57cec5SDimitry Andric
51510b57cec5SDimitry Andricdef Shift4 {
51520b57cec5SDimitry Andric  dag Right = (RLWINM Swap2.Bits, 28, 4, 31);
51530b57cec5SDimitry Andric  dag Left = (RLWINM Swap2.Bits, 4, 0, 27);
51540b57cec5SDimitry Andric}
51550b57cec5SDimitry Andric
51560b57cec5SDimitry Andricdef Swap4 {
51570b57cec5SDimitry Andric  dag Bits = (OR (AND Shift4.Right, MaskValues.Lo4),
51580b57cec5SDimitry Andric                 (AND Shift4.Left, MaskValues.Hi4));
51590b57cec5SDimitry Andric}
51600b57cec5SDimitry Andric
51610b57cec5SDimitry Andricdef Rotate {
51620b57cec5SDimitry Andric  dag Left3Bytes = (RLWINM Swap4.Bits, 24, 0, 31);
51630b57cec5SDimitry Andric}
51640b57cec5SDimitry Andric
51650b57cec5SDimitry Andricdef RotateInsertByte3 {
51660b57cec5SDimitry Andric  dag Left = (RLWIMI Rotate.Left3Bytes, Swap4.Bits, 8, 8, 15);
51670b57cec5SDimitry Andric}
51680b57cec5SDimitry Andric
51690b57cec5SDimitry Andricdef RotateInsertByte1 {
51700b57cec5SDimitry Andric  dag Left = (RLWIMI RotateInsertByte3.Left, Swap4.Bits, 8, 24, 31);
51710b57cec5SDimitry Andric}
51720b57cec5SDimitry Andric
51735ffd83dbSDimitry Andric// Clear the upper half of the register when in 64-bit mode
51745ffd83dbSDimitry Andriclet Predicates = [In64BitMode] in
51755ffd83dbSDimitry Andricdef : Pat<(i32 (bitreverse i32:$A)), (RLDICL_32 RotateInsertByte1.Left, 0, 32)>;
51765ffd83dbSDimitry Andriclet Predicates = [In32BitMode] in
51775ffd83dbSDimitry Andricdef : Pat<(i32 (bitreverse i32:$A)), RotateInsertByte1.Left>;
51780b57cec5SDimitry Andric
51790b57cec5SDimitry Andric// Fast 64-bit reverse bits algorithm:
51800b57cec5SDimitry Andric// Step 1: 1-bit swap (swap odd 1-bit and even 1-bit):
51810b57cec5SDimitry Andric// n = ((n >> 1) & 0x5555555555555555) | ((n << 1) & 0xAAAAAAAAAAAAAAAA);
51820b57cec5SDimitry Andric// Step 2: 2-bit swap (swap odd 2-bit and even 2-bit):
51830b57cec5SDimitry Andric// n = ((n >> 2) & 0x3333333333333333) | ((n << 2) & 0xCCCCCCCCCCCCCCCC);
51840b57cec5SDimitry Andric// Step 3: 4-bit swap (swap odd 4-bit and even 4-bit):
51850b57cec5SDimitry Andric// n = ((n >> 4) & 0x0F0F0F0F0F0F0F0F) | ((n << 4) & 0xF0F0F0F0F0F0F0F0);
51860b57cec5SDimitry Andric// Step 4: byte reverse (Suppose n = [B0,B1,B2,B3,B4,B5,B6,B7]):
51870b57cec5SDimitry Andric// Apply the same byte reverse algorithm mentioned above for the fast 32-bit
51880b57cec5SDimitry Andric// reverse to both the high 32 bit and low 32 bit of the 64 bit value. And
51890b57cec5SDimitry Andric// then OR them together to get the final result.
51900b57cec5SDimitry Andricdef MaskValues64 {
51910b57cec5SDimitry Andric  dag Lo1 = (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), MaskValues.Lo1, sub_32));
51920b57cec5SDimitry Andric  dag Hi1 = (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), MaskValues.Hi1, sub_32));
51930b57cec5SDimitry Andric  dag Lo2 = (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), MaskValues.Lo2, sub_32));
51940b57cec5SDimitry Andric  dag Hi2 = (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), MaskValues.Hi2, sub_32));
51950b57cec5SDimitry Andric  dag Lo4 = (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), MaskValues.Lo4, sub_32));
51960b57cec5SDimitry Andric  dag Hi4 = (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), MaskValues.Hi4, sub_32));
51970b57cec5SDimitry Andric}
51980b57cec5SDimitry Andric
51990b57cec5SDimitry Andricdef DWMaskValues {
52000b57cec5SDimitry Andric  dag Lo1 = (ORI8 (ORIS8 (RLDICR MaskValues64.Lo1, 32, 31), 0x5555), 0x5555);
52010b57cec5SDimitry Andric  dag Hi1 = (ORI8 (ORIS8 (RLDICR MaskValues64.Hi1, 32, 31), 0xAAAA), 0xAAAA);
52020b57cec5SDimitry Andric  dag Lo2 = (ORI8 (ORIS8 (RLDICR MaskValues64.Lo2, 32, 31), 0x3333), 0x3333);
52030b57cec5SDimitry Andric  dag Hi2 = (ORI8 (ORIS8 (RLDICR MaskValues64.Hi2, 32, 31), 0xCCCC), 0xCCCC);
52040b57cec5SDimitry Andric  dag Lo4 = (ORI8 (ORIS8 (RLDICR MaskValues64.Lo4, 32, 31), 0x0F0F), 0x0F0F);
52050b57cec5SDimitry Andric  dag Hi4 = (ORI8 (ORIS8 (RLDICR MaskValues64.Hi4, 32, 31), 0xF0F0), 0xF0F0);
52060b57cec5SDimitry Andric}
52070b57cec5SDimitry Andric
52080b57cec5SDimitry Andricdef DWSwapInByte {
52090b57cec5SDimitry Andric  dag Swap1 = (OR8 (AND8 (RLDICL $A, 63, 1), DWMaskValues.Lo1),
52100b57cec5SDimitry Andric                   (AND8 (RLDICR $A, 1, 62), DWMaskValues.Hi1));
52110b57cec5SDimitry Andric  dag Swap2 = (OR8 (AND8 (RLDICL Swap1, 62, 2), DWMaskValues.Lo2),
52120b57cec5SDimitry Andric                   (AND8 (RLDICR Swap1, 2, 61), DWMaskValues.Hi2));
52130b57cec5SDimitry Andric  dag Swap4 = (OR8 (AND8 (RLDICL Swap2, 60, 4), DWMaskValues.Lo4),
52140b57cec5SDimitry Andric                   (AND8 (RLDICR Swap2, 4, 59), DWMaskValues.Hi4));
52150b57cec5SDimitry Andric}
52160b57cec5SDimitry Andric
52170b57cec5SDimitry Andric// Intra-byte swap is done, now start inter-byte swap.
52180b57cec5SDimitry Andricdef DWBytes4567 {
52190b57cec5SDimitry Andric  dag Word = (i32 (EXTRACT_SUBREG DWSwapInByte.Swap4, sub_32));
52200b57cec5SDimitry Andric}
52210b57cec5SDimitry Andric
52220b57cec5SDimitry Andricdef DWBytes7456 {
52230b57cec5SDimitry Andric  dag Word = (RLWINM DWBytes4567.Word, 24, 0, 31);
52240b57cec5SDimitry Andric}
52250b57cec5SDimitry Andric
52260b57cec5SDimitry Andricdef DWBytes7656 {
52270b57cec5SDimitry Andric  dag Word = (RLWIMI DWBytes7456.Word, DWBytes4567.Word, 8, 8, 15);
52280b57cec5SDimitry Andric}
52290b57cec5SDimitry Andric
52300b57cec5SDimitry Andric// B7 B6 B5 B4 in the right order
52310b57cec5SDimitry Andricdef DWBytes7654 {
52320b57cec5SDimitry Andric  dag Word = (RLWIMI DWBytes7656.Word, DWBytes4567.Word, 8, 24, 31);
52330b57cec5SDimitry Andric  dag DWord =
52340b57cec5SDimitry Andric    (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), Word, sub_32));
52350b57cec5SDimitry Andric}
52360b57cec5SDimitry Andric
52370b57cec5SDimitry Andricdef DWBytes0123 {
52380b57cec5SDimitry Andric  dag Word = (i32 (EXTRACT_SUBREG (RLDICL DWSwapInByte.Swap4, 32, 32), sub_32));
52390b57cec5SDimitry Andric}
52400b57cec5SDimitry Andric
52410b57cec5SDimitry Andricdef DWBytes3012 {
52420b57cec5SDimitry Andric  dag Word = (RLWINM DWBytes0123.Word, 24, 0, 31);
52430b57cec5SDimitry Andric}
52440b57cec5SDimitry Andric
52450b57cec5SDimitry Andricdef DWBytes3212 {
52460b57cec5SDimitry Andric  dag Word = (RLWIMI DWBytes3012.Word, DWBytes0123.Word, 8, 8, 15);
52470b57cec5SDimitry Andric}
52480b57cec5SDimitry Andric
52490b57cec5SDimitry Andric// B3 B2 B1 B0 in the right order
52500b57cec5SDimitry Andricdef DWBytes3210 {
52510b57cec5SDimitry Andric  dag Word = (RLWIMI DWBytes3212.Word, DWBytes0123.Word, 8, 24, 31);
52520b57cec5SDimitry Andric  dag DWord =
52530b57cec5SDimitry Andric    (i64 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), Word, sub_32));
52540b57cec5SDimitry Andric}
52550b57cec5SDimitry Andric
525604eeddc0SDimitry Andric// These instructions store a hash computed from the value of the link register
525704eeddc0SDimitry Andric// and the value of the stack pointer.
525804eeddc0SDimitry Andriclet mayStore = 1 in {
525904eeddc0SDimitry Andricdef HASHST : XForm_XD6_RA5_RB5<31, 722, (outs),
526006c3fb27SDimitry Andric                               (ins gprc:$RB, (memrihash $D, $RA):$addr),
526106c3fb27SDimitry Andric                               "hashst $RB, $addr", IIC_IntGeneral, []>;
526204eeddc0SDimitry Andricdef HASHSTP : XForm_XD6_RA5_RB5<31, 658, (outs),
526306c3fb27SDimitry Andric                                (ins gprc:$RB, (memrihash $D, $RA):$addr),
526406c3fb27SDimitry Andric                                "hashstp $RB, $addr", IIC_IntGeneral, []>;
526504eeddc0SDimitry Andric}
526604eeddc0SDimitry Andric
526704eeddc0SDimitry Andric// These instructions check a hash computed from the value of the link register
526804eeddc0SDimitry Andric// and the value of the stack pointer. The hasSideEffects flag is needed as the
526904eeddc0SDimitry Andric// instruction may TRAP if the hash does not match the hash stored at the
527004eeddc0SDimitry Andric// specified address.
527104eeddc0SDimitry Andriclet mayLoad = 1, hasSideEffects = 1 in {
527204eeddc0SDimitry Andricdef HASHCHK : XForm_XD6_RA5_RB5<31, 754, (outs),
527306c3fb27SDimitry Andric                                (ins gprc:$RB, (memrihash $D, $RA):$addr),
527406c3fb27SDimitry Andric                                "hashchk $RB, $addr", IIC_IntGeneral, []>;
527504eeddc0SDimitry Andricdef HASHCHKP : XForm_XD6_RA5_RB5<31, 690, (outs),
527606c3fb27SDimitry Andric                                 (ins gprc:$RB, (memrihash $D, $RA):$addr),
527706c3fb27SDimitry Andric                                 "hashchkp $RB, $addr", IIC_IntGeneral, []>;
527804eeddc0SDimitry Andric}
527904eeddc0SDimitry Andric
5280cb14a3feSDimitry Andriclet Defs = [CR7], Itinerary = IIC_LdStSync in
5281cb14a3feSDimitry Andricdef CFENCE : PPCPostRAExpPseudo<(outs), (ins gprc:$cr), "#CFENCE", []>;
5282cb14a3feSDimitry Andric
52830b57cec5SDimitry Andric// Now both high word and low word are reversed, next
52840b57cec5SDimitry Andric// swap the high word and low word.
52850b57cec5SDimitry Andricdef : Pat<(i64 (bitreverse i64:$A)),
52860b57cec5SDimitry Andric  (OR8 (RLDICR DWBytes7654.DWord, 32, 31), DWBytes3210.DWord)>;
5287fe6060f1SDimitry Andric
5288fe6060f1SDimitry Andricdef : Pat<(int_ppc_stwcx ForceXForm:$dst, gprc:$A),
5289*6c4b055cSDimitry Andric          (RLWINM (STWCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5290bdd1243dSDimitry Andricdef : Pat<(PPCStoreCond ForceXForm:$dst, gprc:$A, 4),
5291*6c4b055cSDimitry Andric          (RLWINM (STWCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5292fe6060f1SDimitry Andricdef : Pat<(int_ppc_stbcx ForceXForm:$dst, gprc:$A),
5293*6c4b055cSDimitry Andric          (RLWINM (STBCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5294bdd1243dSDimitry Andricdef : Pat<(PPCStoreCond ForceXForm:$dst, gprc:$A, 1),
5295*6c4b055cSDimitry Andric          (RLWINM (STBCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5296fe6060f1SDimitry Andric
5297fe6060f1SDimitry Andricdef : Pat<(int_ppc_fcfid f64:$A),
5298fe6060f1SDimitry Andric        (XSCVSXDDP $A)>;
5299fe6060f1SDimitry Andricdef : Pat<(int_ppc_fcfud f64:$A),
5300fe6060f1SDimitry Andric        (XSCVUXDDP $A)>;
5301fe6060f1SDimitry Andricdef : Pat<(int_ppc_fctid f64:$A),
5302fe6060f1SDimitry Andric        (FCTID $A)>;
5303fe6060f1SDimitry Andricdef : Pat<(int_ppc_fctidz f64:$A),
5304fe6060f1SDimitry Andric        (XSCVDPSXDS $A)>;
5305fe6060f1SDimitry Andricdef : Pat<(int_ppc_fctiw f64:$A),
5306fe6060f1SDimitry Andric        (FCTIW $A)>;
5307fe6060f1SDimitry Andricdef : Pat<(int_ppc_fctiwz f64:$A),
5308fe6060f1SDimitry Andric        (XSCVDPSXWS $A)>;
5309fe6060f1SDimitry Andricdef : Pat<(int_ppc_fctudz f64:$A),
5310fe6060f1SDimitry Andric        (XSCVDPUXDS $A)>;
5311fe6060f1SDimitry Andricdef : Pat<(int_ppc_fctuwz f64:$A),
5312fe6060f1SDimitry Andric        (XSCVDPUXWS $A)>;
5313fe6060f1SDimitry Andric
5314fe6060f1SDimitry Andricdef : Pat<(int_ppc_mfmsr), (MFMSR)>;
5315fe6060f1SDimitry Andricdef : Pat<(int_ppc_mftbu), (MFTB 269)>;
5316fe6060f1SDimitry Andricdef : Pat<(i32 (int_ppc_mfspr timm:$SPR)),
5317fe6060f1SDimitry Andric          (MFSPR $SPR)>;
5318fe6060f1SDimitry Andricdef : Pat<(int_ppc_mtspr timm:$SPR, gprc:$RT),
5319fe6060f1SDimitry Andric          (MTSPR $SPR, $RT)>;
5320fe6060f1SDimitry Andricdef : Pat<(int_ppc_mtmsr gprc:$RS),
5321fe6060f1SDimitry Andric          (MTMSR $RS, 0)>;
5322fe6060f1SDimitry Andric
5323fe6060f1SDimitry Andriclet Predicates = [IsISA2_07] in {
5324fe6060f1SDimitry Andric  def : Pat<(int_ppc_sthcx ForceXForm:$dst, gprc:$A),
5325*6c4b055cSDimitry Andric            (RLWINM (STHCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5326bdd1243dSDimitry Andric  def : Pat<(PPCStoreCond ForceXForm:$dst, gprc:$A, 2),
5327*6c4b055cSDimitry Andric            (RLWINM (STHCX gprc:$A, ForceXForm:$dst), 31, 31, 31)>;
5328fe6060f1SDimitry Andric}
5329fe6060f1SDimitry Andricdef : Pat<(int_ppc_dcbtstt ForceXForm:$dst),
5330fe6060f1SDimitry Andric          (DCBTST 16, ForceXForm:$dst)>;
5331fe6060f1SDimitry Andricdef : Pat<(int_ppc_dcbtt ForceXForm:$dst),
5332fe6060f1SDimitry Andric          (DCBT 16, ForceXForm:$dst)>;
5333fe6060f1SDimitry Andric
5334fe6060f1SDimitry Andricdef : Pat<(int_ppc_stfiw ForceXForm:$dst, f64:$XT),
5335fe6060f1SDimitry Andric          (STFIWX f64:$XT, ForceXForm:$dst)>;
5336