LegalizeIntegerTypes.cpp revision fd87a544c00c2ca04ee23aae67bbcad4dc852a54
169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===//
2cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
3cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//                     The LLVM Compiler Infrastructure
4cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
8cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
9cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
1069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// This file implements integer type expansion and promotion for LegalizeTypes.
1169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// Promotion is the act of changing a computation in an illegal type into a
1269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// computation in a larger type.  For example, implementing i8 arithmetic in an
1369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// i32 register (often needed on powerpc).
1469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// Expansion is the act of changing a computation in an illegal type into a
1578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands// computation in two identical registers of a smaller type.  For example,
1669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// implementing i64 arithmetic in two i32 registers (often needed on 32-bit
1769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands// targets).
18cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//
19cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
20cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
21cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#include "LegalizeTypes.h"
22c82bf9b268eb63f7cf6f435d9ea222ddb8e3c5a8Mon P Wang#include "llvm/CodeGen/PseudoSourceValue.h"
237d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h"
24fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman#include "llvm/Support/raw_ostream.h"
25cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattnerusing namespace llvm;
26cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
27cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
2869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Result Promotion
29cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
30cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
3169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// PromoteIntegerResult - This method is called when a result of a node is
3269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// found to be in need of promotion to a larger type.  At this point, the node
3369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// may also have invalid operands or may have other results that need
3469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// expansion, we just know that (at least) one result needs promotion.
3569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
36fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman  DEBUG(errs() << "Promote integer result: "; N->dump(&DAG); errs() << "\n");
379fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  SDValue Res = SDValue();
3869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
39126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands  // See if the target wants to custom expand this node.
40f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getValueType(ResNo), true))
411607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands    return;
42126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands
4369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (N->getOpcode()) {
4469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  default:
4569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands#ifndef NDEBUG
46fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    errs() << "PromoteIntegerResult #" << ResNo << ": ";
47fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    N->dump(&DAG); errs() << "\n";
4869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands#endif
49c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to promote this operator!");
509fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::AssertSext:  Res = PromoteIntRes_AssertSext(N); break;
519fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::AssertZext:  Res = PromoteIntRes_AssertZext(N); break;
529fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BIT_CONVERT: Res = PromoteIntRes_BIT_CONVERT(N); break;
539fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BSWAP:       Res = PromoteIntRes_BSWAP(N); break;
549fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::BUILD_PAIR:  Res = PromoteIntRes_BUILD_PAIR(N); break;
559fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::Constant:    Res = PromoteIntRes_Constant(N); break;
5600ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  case ISD::CONVERT_RNDSAT:
579fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_CONVERT_RNDSAT(N); break;
589fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTLZ:        Res = PromoteIntRes_CTLZ(N); break;
599fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTPOP:       Res = PromoteIntRes_CTPOP(N); break;
609fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::CTTZ:        Res = PromoteIntRes_CTTZ(N); break;
61bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  case ISD::EXTRACT_VECTOR_ELT:
629fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break;
639fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::LOAD:        Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N));break;
649fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SELECT:      Res = PromoteIntRes_SELECT(N); break;
659fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SELECT_CC:   Res = PromoteIntRes_SELECT_CC(N); break;
669fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SETCC:       Res = PromoteIntRes_SETCC(N); break;
679fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SHL:         Res = PromoteIntRes_SHL(N); break;
688d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands  case ISD::SIGN_EXTEND_INREG:
699fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands                         Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break;
709fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SRA:         Res = PromoteIntRes_SRA(N); break;
719fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SRL:         Res = PromoteIntRes_SRL(N); break;
729fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::TRUNCATE:    Res = PromoteIntRes_TRUNCATE(N); break;
739fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UNDEF:       Res = PromoteIntRes_UNDEF(N); break;
749fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::VAARG:       Res = PromoteIntRes_VAARG(N); break;
75bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
7669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SIGN_EXTEND:
7769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ZERO_EXTEND:
789fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::ANY_EXTEND:  Res = PromoteIntRes_INT_EXTEND(N); break;
79bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
8069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_SINT:
819fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::FP_TO_UINT:  Res = PromoteIntRes_FP_TO_XINT(N); break;
8269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
8369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::AND:
8469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::OR:
8569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::XOR:
8669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ADD:
8769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SUB:
889fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::MUL:         Res = PromoteIntRes_SimpleIntBinOp(N); break;
8969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
9069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SDIV:
919fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SREM:        Res = PromoteIntRes_SDIV(N); break;
9269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
9369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::UDIV:
949fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UREM:        Res = PromoteIntRes_UDIV(N); break;
958ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
96253174bf50c932abaa680f465e2888c0e5272267Bill Wendling  case ISD::SADDO:
979fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::SSUBO:       Res = PromoteIntRes_SADDSUBO(N, ResNo); break;
9874c376529101acbe141a256d0bf23a44eb454c84Bill Wendling  case ISD::UADDO:
999fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::USUBO:       Res = PromoteIntRes_UADDSUBO(N, ResNo); break;
10074c376529101acbe141a256d0bf23a44eb454c84Bill Wendling  case ISD::SMULO:
1019fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  case ISD::UMULO:       Res = PromoteIntRes_XMULO(N, ResNo); break;
102b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
1030b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_ADD:
1040b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_SUB:
1050b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_AND:
1060b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_OR:
1070b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_XOR:
1080b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_NAND:
1090b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_MIN:
1100b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_MAX:
1110b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_UMIN:
1120b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_LOAD_UMAX:
1130b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_SWAP:
1149fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break;
115b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
1160b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman  case ISD::ATOMIC_CMP_SWAP:
1179fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    Res = PromoteIntRes_Atomic2(cast<AtomicSDNode>(N)); break;
11869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
11969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1209fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  // If the result is null then the sub-method took care of registering it.
1219fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  if (Res.getNode())
1229fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands    SetPromotedInteger(SDValue(N, ResNo), Res);
12369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
12469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
125475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) {
12695db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  // Sign-extend the new bits, and continue the assertion.
127c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = SExtPromotedInteger(N->getOperand(0));
128786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::AssertSext, N->getDebugLoc(),
129786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
13095db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
13195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
132475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) {
13395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  // Zero the new bits, and continue the assertion.
134c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
135786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::AssertZext, N->getDebugLoc(),
136786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
13795db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
13895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
139b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) {
140b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
1417fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
142786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                              N->getMemoryVT(),
1430b1d4a798d1dd2f39521b6b381cd1c1911c9ab52Dan Gohman                              N->getChain(), N->getBasePtr(),
144b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands                              Op2, N->getSrcValue(), N->getAlignment());
145b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
146b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // use the new one.
147b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
148b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  return Res;
149b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands}
150b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
151b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) {
152b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op2 = GetPromotedInteger(N->getOperand(2));
153b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  SDValue Op3 = GetPromotedInteger(N->getOperand(3));
154fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel  SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(),
155f8d3ec2c5725a2010f11de4ba78f6127712a5fe7Dale Johannesen                              N->getMemoryVT(), N->getChain(), N->getBasePtr(),
156b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands                              Op2, Op3, N->getSrcValue(), N->getAlignment());
157b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
158b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  // use the new one.
159b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
160b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands  return Res;
161b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands}
162b5f68e241f9eb19e5694131df830acbfce20a6ebDuncan Sands
163475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
164475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InOp = N->getOperand(0);
16569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT InVT = InOp.getValueType();
16669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT NInVT = TLI.getTypeToTransformTo(InVT);
16747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  MVT OutVT = N->getValueType(0);
16847d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  MVT NOutVT = TLI.getTypeToTransformTo(OutVT);
169786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
17069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
17169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (getTypeAction(InVT)) {
17269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  default:
17369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    assert(false && "Unknown type action!");
17469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
17569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case Legal:
17669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
17769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case PromoteInteger:
17847d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands    if (NOutVT.bitsEq(NInVT))
17969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands      // The input promotes to the same size.  Convert the promoted value.
1807fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands      return DAG.getNode(ISD::BIT_CONVERT, dl,
181786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                         NOutVT, GetPromotedInteger(InOp));
18269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
1834fc4fd657d4266059dac3849133a3a351b03d99dDuncan Sands  case SoftenFloat:
18469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Promote the integer operand by hand.
185786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp));
18669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ExpandInteger:
18769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ExpandFloat:
18869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    break;
189f4e4629ee8c218f892ad8ae3e182fe40bc160895Duncan Sands  case ScalarizeVector:
19069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Convert the element to an integer and promote it by hand.
191786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
19269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                       BitConvertToInteger(GetScalarizedVector(InOp)));
19387c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang  case SplitVector: {
19469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // For example, i32 = BIT_CONVERT v2i16 on alpha.  Convert the split
19569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // pieces of the input into integers and reassemble in the final type.
196475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
19769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetSplitVector(N->getOperand(0), Lo, Hi);
19869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    Lo = BitConvertToInteger(Lo);
19969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    Hi = BitConvertToInteger(Hi);
20069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
20169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    if (TLI.isBigEndian())
20269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands      std::swap(Lo, Hi);
20369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
204786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    InOp = DAG.getNode(ISD::ANY_EXTEND, dl,
20547d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands                       MVT::getIntegerVT(NOutVT.getSizeInBits()),
20669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                       JoinIntegers(Lo, Hi));
207786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, InOp);
20869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
20987c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang  case WidenVector:
21087c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang    if (OutVT.bitsEq(NInVT))
21187c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang      // The input is widened to the same size.  Convert to the widened value.
212786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      return DAG.getNode(ISD::BIT_CONVERT, dl, OutVT, GetWidenedVector(InOp));
21387c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang  }
21469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
215aad3460086a1b29c55f7490c6d8743ea4e53f07dEli Friedman  return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT,
216aad3460086a1b29c55f7490c6d8743ea4e53f07dEli Friedman                     CreateStackStoreLoad(InOp, OutVT));
21769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
21869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
219475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) {
220475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
221c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands  MVT OVT = N->getValueType(0);
222c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands  MVT NVT = Op.getValueType();
223786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
224c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands
225c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands  unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
226786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op),
22792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(DiffBits, TLI.getPointerTy()));
228c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands}
229c07e6e53f757da1a7c79c66ed53f2844de85a77eDuncan Sands
230475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
231bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The pair element type may be legal, or may not promote to the same type as
232bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // the result, for example i14 = BUILD_PAIR (i7, i7).  Handle all cases.
233786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(),
234bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     TLI.getTypeToTransformTo(N->getValueType(0)),
235bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     JoinIntegers(N->getOperand(0), N->getOperand(1)));
23669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
23769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
238475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
23969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT VT = N->getValueType(0);
240b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  // FIXME there is no actual debug info here
241b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  DebugLoc dl = N->getDebugLoc();
242bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Zero extend things like i1, sign extend everything else.  It shouldn't
243bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // matter in theory which one we pick, but this tends to give better code?
244bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
245b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  SDValue Result = DAG.getNode(Opc, dl, TLI.getTypeToTransformTo(VT),
246a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands                               SDValue(N, 0));
247bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
248bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return Result;
24969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
25069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
25100ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P WangSDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_RNDSAT(SDNode *N) {
25200ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
25300ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
25400ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
25500ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang           CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
25600ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang          "can only promote integers");
25700ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang  MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
258c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen  return DAG.getConvertRndSat(OutVT, N->getDebugLoc(), N->getOperand(0),
25900ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang                              N->getOperand(1), N->getOperand(2),
26000ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang                              N->getOperand(3), N->getOperand(4), CvtCode);
26100ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang}
26200ec49b6bafc33ee17d97ec1c723e1edb41d4c97Mon P Wang
263475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
264c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  // Zero extend to the promoted type and do the count there.
265c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
266b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  DebugLoc dl = N->getDebugLoc();
26769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT OVT = N->getValueType(0);
26869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT NVT = Op.getValueType();
269b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  Op = DAG.getNode(ISD::CTLZ, dl, NVT, Op);
27069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Subtract off the extra leading bits in the bigger type.
271b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  return DAG.getNode(ISD::SUB, dl, NVT, Op,
27269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                     DAG.getConstant(NVT.getSizeInBits() -
27369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                     OVT.getSizeInBits(), NVT));
27469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
27569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
276475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
27769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Zero extend to the promoted type and do the count there.
278c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Op = ZExtPromotedInteger(N->getOperand(0));
279786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op);
28069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
28169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
282475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
283475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
28469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT OVT = N->getValueType(0);
28569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT NVT = Op.getValueType();
286786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
28769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // The count is the same in the promoted type except if the original
28869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // value was zero.  This can be handled by setting the bit just off
28969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // the top of the original type.
29003dc093a2e63d20984c8fd67809fa762f1e31f1aDuncan Sands  APInt TopBit(NVT.getSizeInBits(), 0);
29103dc093a2e63d20984c8fd67809fa762f1e31f1aDuncan Sands  TopBit.set(OVT.getSizeInBits());
292786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
293786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::CTTZ, dl, NVT, Op);
29469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
29569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
296475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
297786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
298c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
299c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman  return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0),
300c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman                     N->getOperand(1));
30169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
30269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
303475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
304bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
305a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  unsigned NewOpc = N->getOpcode();
306786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
307d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands
3084c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is
3094c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // not Legal, check to see if we can use FP_TO_SINT instead.  (If both UINT
3104c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen  // and SINT conversions are Custom, there is no way to tell which is preferable.
3118c899ee031481dbece5f111379a274c848cb5902Duncan Sands  // We choose SINT because that's the right thing on PPC.)
312a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  if (N->getOpcode() == ISD::FP_TO_UINT &&
3134c9369df57a52cec5e1fc735e61a979766288074Dale Johannesen      !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
314f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman      TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
315a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands    NewOpc = ISD::FP_TO_SINT;
316a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands
317786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0));
318a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands
319a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // Assert that the converted value fits in the original type.  If it doesn't
320a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // (eg: because the value being converted is too big), then the result of the
321a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  // original operation was undefined anyway, so the assert is still correct.
322a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands  return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ?
323786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     ISD::AssertZext : ISD::AssertSext, dl,
324a29c13086a3add78a3a79f744573fe09eaa9dc88Duncan Sands                     NVT, Res, DAG.getValueType(N->getValueType(0)));
325d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands}
326d3ca9fc9984d036146886a40ad3f73aaf7a424ebDuncan Sands
327475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
328bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
329786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
330be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands
331bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) {
332475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(N->getOperand(0));
3336959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands    assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!");
334126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands
335bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    // If the result and operand types are the same after promotion, simplify
336bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    // to an in-register extension.
337bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    if (NVT == Res.getValueType()) {
338bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      // The high bits are not guaranteed to be anything.  Insert an extend.
339bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      if (N->getOpcode() == ISD::SIGN_EXTEND)
340786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
341bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                           DAG.getValueType(N->getOperand(0).getValueType()));
342bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      if (N->getOpcode() == ISD::ZERO_EXTEND)
3434be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen        return DAG.getZeroExtendInReg(Res, dl, N->getOperand(0).getValueType());
344bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
345bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands      return Res;
346126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands    }
34769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
34869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
349bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Otherwise, just extend the original operand all the way to the larger type.
350786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0));
351bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
35269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
353475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
354bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
355bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
356bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  ISD::LoadExtType ExtType =
357bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
358786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
359786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(),
36047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands                               N->getSrcValue(), N->getSrcValueOffset(),
36147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands                               N->getMemoryVT(), N->isVolatile(),
36247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands                               N->getAlignment());
36369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
364bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Legalized the chain result - switch anything that used the old chain to
365bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // use the new one.
366475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Res.getValue(1));
367bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return Res;
36869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
36969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
370874ae251c317788391f9c3f113957802d390a063Dale Johannesen/// Promote the overflow flag of an overflowing arithmetic node.
371ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) {
372ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Simply change the return type of the boolean result.
373ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
374ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  MVT ValueVTs[] = { N->getValueType(0), NVT };
375ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
376786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(),
377786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                            DAG.getVTList(ValueVTs, 2), Ops, 2);
378ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
379ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Modified the sum result - switch anything that used the old sum to use
380ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the new one.
381ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 0), Res);
382ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
383ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return SDValue(Res.getNode(), 1);
384ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
385ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
386ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
387ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  if (ResNo == 1)
388ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands    return PromoteIntRes_Overflow(N);
389ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
390ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // The operation overflowed iff the result in the larger type is not the
391ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // sign extension of its truncation to the original type.
392ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
393ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
394ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  MVT OVT = N->getOperand(0).getValueType();
395ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  MVT NVT = LHS.getValueType();
396786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
397ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
398ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Do the arithmetic in the larger type.
399ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB;
400786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
401ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
402ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Calculate the overflow flag: sign extend the arithmetic result from
403ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the original type.
404786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res,
405ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands                            DAG.getValueType(OVT));
406ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Overflowed if and only if this is not equal to Res.
407786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
408ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
409ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Use the calculated overflow everywhere.
410ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 1), Ofl);
411ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
412ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return Res;
413ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
414ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
415475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
416bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Sign extend the input.
417c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue LHS = SExtPromotedInteger(N->getOperand(0));
418c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue RHS = SExtPromotedInteger(N->getOperand(1));
419786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
420786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), LHS, RHS);
42169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
42269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
423475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
424475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(1));
425475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(2));
426786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SELECT, N->getDebugLoc(),
427786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), N->getOperand(0),LHS,RHS);
42869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
42969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
430475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
431475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(2));
432475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(3));
433786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(),
434786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), N->getOperand(0),
435bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     N->getOperand(1), LHS, RHS, N->getOperand(4));
43669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
43769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
438475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
4395480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  MVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType());
4407e4982287591945c4e42ba8470a978e629789c76Duncan Sands  assert(isTypeLegal(SVT) && "Illegal SetCC type!");
441786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
4427e4982287591945c4e42ba8470a978e629789c76Duncan Sands
4437e4982287591945c4e42ba8470a978e629789c76Duncan Sands  // Get the SETCC result using the canonical SETCC type.
444786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0),
4457e4982287591945c4e42ba8470a978e629789c76Duncan Sands                              N->getOperand(1), N->getOperand(2));
4467e4982287591945c4e42ba8470a978e629789c76Duncan Sands
4477e4982287591945c4e42ba8470a978e629789c76Duncan Sands  // Convert to the expected type.
4487e4982287591945c4e42ba8470a978e629789c76Duncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
4496959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands  assert(NVT.bitsLE(SVT) && "Integer type overpromoted?");
450786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC);
45169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
45269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
453475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
454786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SHL, N->getDebugLoc(),
455786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     TLI.getTypeToTransformTo(N->getValueType(0)),
456bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
45769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
45869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
459475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) {
460475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
461786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(),
462786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Op.getValueType(), Op, N->getOperand(1));
4638d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands}
4648d56a6f4d8b010d4c582225a08ece971613f6fe3Duncan Sands
465475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
466bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input may have strange things in the top bits of the registers, but
467bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // these operations don't care.  They may have weird bits going out, but
468bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // that too is okay if they are integer operations.
469475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = GetPromotedInteger(N->getOperand(0));
470475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = GetPromotedInteger(N->getOperand(1));
471786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
472786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                    LHS.getValueType(), LHS, RHS);
47369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
47469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
475475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
476bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input value must be properly sign extended.
477c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Res = SExtPromotedInteger(N->getOperand(0));
478786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRA, N->getDebugLoc(),
479786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     Res.getValueType(), Res, N->getOperand(1));
480bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
48169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
482475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
483bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The input value must be properly zero extended.
484bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT VT = N->getValueType(0);
485bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(VT);
486475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = ZExtPromotedInteger(N->getOperand(0));
487786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1));
48869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
48969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
490475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
4916959b2bb6521baca57e5507ca039e51002d4a971Duncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
492475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res;
49369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
494bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  switch (getTypeAction(N->getOperand(0).getValueType())) {
495c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown type action!");
496bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  case Legal:
497bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  case ExpandInteger:
498bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    Res = N->getOperand(0);
499bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    break;
500bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  case PromoteInteger:
501bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    Res = GetPromotedInteger(N->getOperand(0));
502bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    break;
503bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  }
504bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
505bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Truncate to NVT instead of VT
506786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), NVT, Res);
50769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
50869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
509ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) {
510ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  if (ResNo == 1)
511ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands    return PromoteIntRes_Overflow(N);
512ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
513ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // The operation overflowed iff the result in the larger type is not the
514ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // zero extension of its truncation to the original type.
515c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
516c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
517ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  MVT OVT = N->getOperand(0).getValueType();
518ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  MVT NVT = LHS.getValueType();
519786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
52069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
521ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Do the arithmetic in the larger type.
522ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB;
523786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS);
5248ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
525ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Calculate the overflow flag: zero extend the arithmetic result from
526ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // the original type.
5274be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT);
528ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Overflowed if and only if this is not equal to Res.
529786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE);
5308ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
531ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Use the calculated overflow everywhere.
532ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  ReplaceValueWith(SDValue(N, 1), Ofl);
5338ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
534ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return Res;
535ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
536ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands
537ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
538ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  // Zero extend the input.
539ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue LHS = ZExtPromotedInteger(N->getOperand(0));
540ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  SDValue RHS = ZExtPromotedInteger(N->getOperand(1));
541786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(N->getOpcode(), N->getDebugLoc(),
542786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     LHS.getValueType(), LHS, RHS);
5438ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling}
5448ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling
545475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
546e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen  return DAG.getUNDEF(TLI.getTypeToTransformTo(N->getValueType(0)));
54769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
54869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
549475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
550475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Chain = N->getOperand(0); // Get the chain.
551475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getOperand(1); // Get the pointer.
552bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT VT = N->getValueType(0);
553786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
55469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
555d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  MVT RegVT = TLI.getRegisterType(VT);
556d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  unsigned NumRegs = TLI.getNumRegisters(VT);
557d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // The argument is passed as NumRegs registers of type RegVT.
558d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands
559d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  SmallVector<SDValue, 8> Parts(NumRegs);
560d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  for (unsigned i = 0; i < NumRegs; ++i) {
561c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen    Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2));
562d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    Chain = Parts[i].getValue(1);
563d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  }
56469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
565d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Handle endianness of the load.
566d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  if (TLI.isBigEndian())
567d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    std::reverse(Parts.begin(), Parts.end());
56869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
569d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Assemble the parts in the promoted type.
570d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
571786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]);
572d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  for (unsigned i = 1; i < NumRegs; ++i) {
573786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]);
574d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands    // Shift it to the right position and "or" it in.
575786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Part = DAG.getNode(ISD::SHL, dl, NVT, Part,
576d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands                       DAG.getConstant(i * RegVT.getSizeInBits(),
57792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
578786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part);
579d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  }
58069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
581d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  // Modified the chain result - switch anything that used the old chain to
582bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // use the new one.
583d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  ReplaceValueWith(SDValue(N, 1), Chain);
584d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands
585d821726a91000c1b2de7ca8aafdc27b1a311741bDuncan Sands  return Res;
58669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
58769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
588ab0c578bfd1380326830180a9209df6c5be58887Duncan SandsSDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) {
589ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  assert(ResNo == 1 && "Only boolean result promotion currently supported!");
590ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands  return PromoteIntRes_Overflow(N);
591ab0c578bfd1380326830180a9209df6c5be58887Duncan Sands}
5927fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
593bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//===----------------------------------------------------------------------===//
594bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//  Integer Operand Promotion
595bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands//===----------------------------------------------------------------------===//
5967fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
597bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// PromoteIntegerOperand - This method is called when the specified operand of
598bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// the specified node is found to need promotion.  At this point, all of the
599bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// result types of the node are known to be legal, but other operands of the
600bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands/// node may need promotion or expansion as well as the specified one.
601bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sandsbool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
602fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman  DEBUG(errs() << "Promote integer operand: "; N->dump(&DAG); errs() << "\n");
603475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = SDValue();
6047fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26Duncan Sands
605f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
606bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    return false;
60769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
608bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  switch (N->getOpcode()) {
609bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    default:
610bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  #ifndef NDEBUG
611fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    errs() << "PromoteIntegerOperand Op #" << OpNo << ": ";
612fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    N->dump(&DAG); errs() << "\n";
613bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  #endif
614c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to promote this operator's operand!");
615bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
616bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::ANY_EXTEND:   Res = PromoteIntOp_ANY_EXTEND(N); break;
61727759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  case ISD::BIT_CONVERT:  Res = PromoteIntOp_BIT_CONVERT(N); break;
618bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BR_CC:        Res = PromoteIntOp_BR_CC(N, OpNo); break;
619bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BRCOND:       Res = PromoteIntOp_BRCOND(N, OpNo); break;
620bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BUILD_PAIR:   Res = PromoteIntOp_BUILD_PAIR(N); break;
621bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
622bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::CONVERT_RNDSAT:
623bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                          Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
624bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::INSERT_VECTOR_ELT:
625bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                          Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break;
626bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::MEMBARRIER:   Res = PromoteIntOp_MEMBARRIER(N); break;
627aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang  case ISD::SCALAR_TO_VECTOR:
628aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang                          Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break;
629bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SELECT:       Res = PromoteIntOp_SELECT(N, OpNo); break;
630bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SELECT_CC:    Res = PromoteIntOp_SELECT_CC(N, OpNo); break;
631bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SETCC:        Res = PromoteIntOp_SETCC(N, OpNo); break;
632bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SIGN_EXTEND:  Res = PromoteIntOp_SIGN_EXTEND(N); break;
633bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SINT_TO_FP:   Res = PromoteIntOp_SINT_TO_FP(N); break;
634bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::STORE:        Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
635bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta                                                   OpNo); break;
636bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::TRUNCATE:     Res = PromoteIntOp_TRUNCATE(N); break;
637bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::UINT_TO_FP:   Res = PromoteIntOp_UINT_TO_FP(N); break;
638bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::ZERO_EXTEND:  Res = PromoteIntOp_ZERO_EXTEND(N); break;
63955467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
64055467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SHL:
64155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRA:
64255467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRL:
64355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTL:
64455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
645bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  }
6469fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands
647bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // If the result is null, the sub-method took care of registering results etc.
6489fbc7e2e7a765298fb4326885b407e0962f7ab62Duncan Sands  if (!Res.getNode()) return false;
64947d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
65047d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // If the result is N, the sub-method updated N in place.  Tell the legalizer
65147d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // core about this.
65247d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  if (Res.getNode() == N)
653bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands    return true;
654bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
655bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
656bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands         "Invalid operand expansion");
657bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
658475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 0), Res);
659bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  return false;
66069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
66169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
66269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
66369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// shared among BR_CC, SELECT_CC, and SETCC handlers.
664475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS,
66569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                            ISD::CondCode CCCode) {
666cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // We have to insert explicit sign or zero extends.  Note that we could
667cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // insert sign extends for ALL conditions, but zero extend is cheaper on
668cff50d9e20d7bbc3acf4845fe826bfb3095126c4Duncan Sands  // many machines (an AND instead of two shifts), so prefer it.
66969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  switch (CCCode) {
670c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer comparison!");
67169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETEQ:
67269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETNE:
67369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETUGE:
67469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETUGT:
67569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETULE:
67669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETULT:
67769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // ALL of these operations will work if we either sign or zero extend
67869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // the operands (including the unsigned comparisons!).  Zero extend is
67969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // usually a simpler/cheaper operation, so prefer it.
680c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewLHS = ZExtPromotedInteger(NewLHS);
681c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewRHS = ZExtPromotedInteger(NewRHS);
68211ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    break;
68369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETGE:
68469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETGT:
68569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETLT:
68669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::SETLE:
687c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewLHS = SExtPromotedInteger(NewLHS);
688c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands    NewRHS = SExtPromotedInteger(NewRHS);
68911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    break;
69069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
69169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
69269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
693475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
694475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
695786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op);
696bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
69769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
69827759f41ca1c930e2860275c9ba2567a5890d7d2Eli FriedmanSDValue DAGTypeLegalizer::PromoteIntOp_BIT_CONVERT(SDNode *N) {
69927759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  // This should only occur in unusual situations like bitcasting to an
70027759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  // x86_fp80, so just turn it into a store+load
70127759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
70227759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman}
70327759f41ca1c930e2860275c9ba2567a5890d7d2Eli Friedman
704475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
705bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 2 && "Don't know how to promote this operand!");
70669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
707475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(2);
708475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(3);
709bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
71069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
711bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
712bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // legal types.
713475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
714bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                                N->getOperand(1), LHS, RHS, N->getOperand(4));
715bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
716bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
717475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
718bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 1 && "only know how to promote condition");
719bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
720b6e223a9e806921183da972253c49082a2e07944Duncan Sands  // Promote all the way up to the canonical SetCC type.
7215480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  MVT SVT = TLI.getSetCCResultType(MVT::Other);
722b6e223a9e806921183da972253c49082a2e07944Duncan Sands  SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT);
723bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
724bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
725475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Cond,
726bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                                N->getOperand(2));
727bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
728bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
729475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
730bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Since the result type is legal, the operands must promote to it.
731bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  MVT OVT = N->getOperand(0).getValueType();
732c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Lo = ZExtPromotedInteger(N->getOperand(0));
733475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Hi = GetPromotedInteger(N->getOperand(1));
734bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
735786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
736bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
737786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi,
73892abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                   DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy()));
739786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi);
74069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
74169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
742475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
74369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // The vector type is legal but the element type is not.  This implies
74469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // that the vector is a power-of-two in length and that the element
74569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // type does not have a strange size (eg: it is not i1).
74669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  MVT VecVT = N->getValueType(0);
74769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  unsigned NumElts = VecVT.getVectorNumElements();
74869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  assert(!(NumElts & 1) && "Legal vector of one illegal element?");
74969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
750b1303d05a89972195de023fda432cc621375a27cBob Wilson  // Promote the inserted value.  The type does not need to match the
751b1303d05a89972195de023fda432cc621375a27cBob Wilson  // vector element type.  Check that any extra bits introduced will be
752b1303d05a89972195de023fda432cc621375a27cBob Wilson  // truncated away.
753b1303d05a89972195de023fda432cc621375a27cBob Wilson  assert(N->getOperand(0).getValueType().getSizeInBits() >=
754b1303d05a89972195de023fda432cc621375a27cBob Wilson         N->getValueType(0).getVectorElementType().getSizeInBits() &&
755b1303d05a89972195de023fda432cc621375a27cBob Wilson         "Type of inserted value narrower than vector element type!");
75669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
757b1303d05a89972195de023fda432cc621375a27cBob Wilson  SmallVector<SDValue, 16> NewOps;
758c885165e664f3b465403e1b6ce57ba63f57c5f0cBob Wilson  for (unsigned i = 0; i < NumElts; ++i)
759b1303d05a89972195de023fda432cc621375a27cBob Wilson    NewOps.push_back(GetPromotedInteger(N->getOperand(i)));
76069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
761b1303d05a89972195de023fda432cc621375a27cBob Wilson  return DAG.UpdateNodeOperands(SDValue(N, 0), &NewOps[0], NumElts);
76269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
76369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
76428088d3c049017a131aa7b07201c6e19c0227cefMon P WangSDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
76528088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
76628088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
76728088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
76828088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           CvtCode == ISD::CVT_FS || CvtCode == ISD::CVT_FU) &&
76928088d3c049017a131aa7b07201c6e19c0227cefMon P Wang           "can only promote integer arguments");
77028088d3c049017a131aa7b07201c6e19c0227cefMon P Wang  SDValue InOp = GetPromotedInteger(N->getOperand(0));
771c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen  return DAG.getConvertRndSat(N->getValueType(0), N->getDebugLoc(), InOp,
77228088d3c049017a131aa7b07201c6e19c0227cefMon P Wang                              N->getOperand(1), N->getOperand(2),
77328088d3c049017a131aa7b07201c6e19c0227cefMon P Wang                              N->getOperand(3), N->getOperand(4), CvtCode);
77428088d3c049017a131aa7b07201c6e19c0227cefMon P Wang}
77528088d3c049017a131aa7b07201c6e19c0227cefMon P Wang
776475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
777475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                         unsigned OpNo) {
77869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  if (OpNo == 1) {
77969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Promote the inserted value.  This is valid because the type does not
78069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // have to match the vector element type.
78169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
78269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    // Check that any extra bits introduced will be truncated away.
78369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    assert(N->getOperand(1).getValueType().getSizeInBits() >=
78469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands           N->getValueType(0).getVectorElementType().getSizeInBits() &&
78569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands           "Type of inserted value narrower than vector element type!");
786475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
78769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                  GetPromotedInteger(N->getOperand(1)),
78869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                  N->getOperand(2));
78969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
79069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
79169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  assert(OpNo == 2 && "Different operand and result vector types?");
79269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
79369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // Promote the index.
794c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  SDValue Idx = ZExtPromotedInteger(N->getOperand(2));
795475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
79669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                N->getOperand(1), Idx);
79769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
79869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
799475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
800475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewOps[6];
8014be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  DebugLoc dl = N->getDebugLoc();
80269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  NewOps[0] = N->getOperand(0);
80369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
804475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Flag = GetPromotedInteger(N->getOperand(i));
8054be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen    NewOps[i] = DAG.getZeroExtendInReg(Flag, dl, MVT::i1);
80669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  }
807475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue (N, 0), NewOps,
80869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands                                array_lengthof(NewOps));
80969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands}
81069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
811aa9df0b0c3cef33514095bde2eedead986677955Mon P WangSDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) {
812b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  // Integer SCALAR_TO_VECTOR operands are implicitly truncated, so just promote
813b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  // the operand in place.
814b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands  return DAG.UpdateNodeOperands(SDValue(N, 0),
815b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands                                GetPromotedInteger(N->getOperand(0)));
816aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang}
817aa9df0b0c3cef33514095bde2eedead986677955Mon P Wang
818475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
819bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Only know how to promote condition");
8207e4982287591945c4e42ba8470a978e629789c76Duncan Sands
821b6e223a9e806921183da972253c49082a2e07944Duncan Sands  // Promote all the way up to the canonical SetCC type.
8225480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  MVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType());
823b6e223a9e806921183da972253c49082a2e07944Duncan Sands  SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT);
824bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
8257e4982287591945c4e42ba8470a978e629789c76Duncan Sands  return DAG.UpdateNodeOperands(SDValue(N, 0), Cond,
8267e4982287591945c4e42ba8470a978e629789c76Duncan Sands                                N->getOperand(1), N->getOperand(2));
827bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
828bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
829475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) {
830bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Don't know how to promote this operand!");
831bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
832475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(0);
833475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(1);
834bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get());
835bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
836bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The CC (#4) and the possible return values (#2 and #3) have legal types.
837475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), LHS, RHS, N->getOperand(2),
838bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                                N->getOperand(3), N->getOperand(4));
839bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
840bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
841475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
842bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(OpNo == 0 && "Don't know how to promote this operand!");
843bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
844475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHS = N->getOperand(0);
845475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue RHS = N->getOperand(1);
846bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
847bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
848bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // The CC (#2) is always legal.
849475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), LHS, RHS, N->getOperand(2));
850bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
851bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
85255467af31620c9d027e071ebcd9746b7593cff17Sanjiv GuptaSDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
85355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
85455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta                                ZExtPromotedInteger(N->getOperand(1)));
85555467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta}
85655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
857475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
858475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
859786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
860786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
861786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(),
862bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                     Op, DAG.getValueType(N->getOperand(0).getValueType()));
863bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
864bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
865c08468774b65dc288c44076d428f4beddabe58e2Duncan SandsSDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) {
866c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  return DAG.UpdateNodeOperands(SDValue(N, 0),
867c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands                                SExtPromotedInteger(N->getOperand(0)));
868c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands}
869c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands
870475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
871bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
872475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch = N->getChain(), Ptr = N->getBasePtr();
873bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  int SVOffset = N->getSrcValueOffset();
874bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  unsigned Alignment = N->getAlignment();
875bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  bool isVolatile = N->isVolatile();
876786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
877bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
878475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Val = GetPromotedInteger(N->getValue());  // Get promoted value.
879bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
880bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands  // Truncate the value and store the result.
881786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(),
882bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                           SVOffset, N->getMemoryVT(),
883bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands                           isVolatile, Alignment);
884bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
885bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
886475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
887475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
888786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op);
889bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
890bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
891c08468774b65dc288c44076d428f4beddabe58e2Duncan SandsSDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) {
892c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands  return DAG.UpdateNodeOperands(SDValue(N, 0),
893c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands                                ZExtPromotedInteger(N->getOperand(0)));
894c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands}
895c08468774b65dc288c44076d428f4beddabe58e2Duncan Sands
896475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
8974be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  DebugLoc dl = N->getDebugLoc();
898475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = GetPromotedInteger(N->getOperand(0));
8994be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op);
9004be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen  return DAG.getZeroExtendInReg(Op, dl, N->getOperand(0).getValueType());
901bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands}
902bf304c20651b80309af4c0fb3a14c0d73eaa984fDuncan Sands
90369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
90469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----------------------------------------------------------------------===//
90569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Result Expansion
90669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//===----------------------------------------------------------------------===//
90769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
90869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands/// ExpandIntegerResult - This method is called when the specified result of the
909cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// specified node is found to need expansion.  At this point, the node may also
910cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// have invalid operands or may have other results that need promotion, we just
911cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner/// know that (at least) one result needs expansion.
91269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
913fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman  DEBUG(errs() << "Expand integer result: "; N->dump(&DAG); errs() << "\n");
914475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
915475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  Lo = Hi = SDValue();
916cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
917cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // See if the target wants to custom expand this node.
918f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getValueType(ResNo), true))
9191607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands    return;
920cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
921cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  switch (N->getOpcode()) {
922cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  default:
923cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#ifndef NDEBUG
924fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    errs() << "ExpandIntegerResult #" << ResNo << ": ";
925fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    N->dump(&DAG); errs() << "\n";
926cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner#endif
927c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to expand the result of this operator!");
92869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
92978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
93078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::SELECT:       SplitRes_SELECT(N, Lo, Hi); break;
93178cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::SELECT_CC:    SplitRes_SELECT_CC(N, Lo, Hi); break;
93278cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::UNDEF:        SplitRes_UNDEF(N, Lo, Hi); break;
93378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
93478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::BIT_CONVERT:        ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
93578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::BUILD_PAIR:         ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
9364a307ecce68f90e0eebf1ded52b947816cdc2304Duncan Sands  case ISD::EXTRACT_ELEMENT:    ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
93778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
93821c2972f7d24680f6475877a3398b7f8cf515b33Duncan Sands  case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;
93978cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
94069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::ANY_EXTEND:  ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
94195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  case ISD::AssertSext:  ExpandIntRes_AssertSext(N, Lo, Hi); break;
94269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::AssertZext:  ExpandIntRes_AssertZext(N, Lo, Hi); break;
94305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::BSWAP:       ExpandIntRes_BSWAP(N, Lo, Hi); break;
94405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::Constant:    ExpandIntRes_Constant(N, Lo, Hi); break;
94505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTLZ:        ExpandIntRes_CTLZ(N, Lo, Hi); break;
94605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTPOP:       ExpandIntRes_CTPOP(N, Lo, Hi); break;
94705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::CTTZ:        ExpandIntRes_CTTZ(N, Lo, Hi); break;
94869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_SINT:  ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
94969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::FP_TO_UINT:  ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
95069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  case ISD::LOAD:        ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
95105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::MUL:         ExpandIntRes_MUL(N, Lo, Hi); break;
95205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SDIV:        ExpandIntRes_SDIV(N, Lo, Hi); break;
95305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
95405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
95505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SREM:        ExpandIntRes_SREM(N, Lo, Hi); break;
95605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::TRUNCATE:    ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
95705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::UDIV:        ExpandIntRes_UDIV(N, Lo, Hi); break;
95805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::UREM:        ExpandIntRes_UREM(N, Lo, Hi); break;
95905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
96069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
961cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::AND:
962cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::OR:
96305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break;
96405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
965cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADD:
96605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
96705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
968cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADDC:
96905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
97005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
971cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::ADDE:
97205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
97305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
974cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SHL:
975cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SRA:
97605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break;
977cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
978d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
979cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If Lo/Hi is null, the sub-method took care of registering results etc.
980ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (Lo.getNode())
981475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SetExpandedInteger(SDValue(N, ResNo), Lo, Hi);
982cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
983cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
98405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
98505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// and the shift amount is a constant 'Amt'.  Expand the operation.
98605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
987475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
988786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
98905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the incoming operand to be shifted, so that we have its parts
990475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
99105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
992cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
99305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = InL.getValueType();
99405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned VTBits = N->getValueType(0).getSizeInBits();
99505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
99605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT ShTy = N->getOperand(1).getValueType();
997cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
99805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::SHL) {
99905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (Amt > VTBits) {
100005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = Hi = DAG.getConstant(0, NVT);
100105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt > NVTBits) {
100205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
10037fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands      Hi = DAG.getNode(ISD::SHL, dl,
1004786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy));
100505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt == NVTBits) {
100605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
100705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = InL;
1008104de6cf7b80ec5e9beb502a069f376810a0a1e3Richard Osborne    } else if (Amt == 1 &&
1009f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman               TLI.isOperationLegalOrCustom(ISD::ADDC,
1010f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman                                            TLI.getTypeToExpandTo(NVT))) {
101105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      // Emit this X << 1 as X+X.
1012874ae251c317788391f9c3f113957802d390a063Dale Johannesen      SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
1013475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue LoOps[2] = { InL, InL };
1014786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
1015475871a144eb604ddaf37503397ba0941442e5fbDan Gohman      SDValue HiOps[3] = { InH, InH, Lo.getValue(1) };
1016786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
101705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else {
1018786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Amt, ShTy));
1019786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::OR, dl, NVT,
1020786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SHL, dl, NVT, InH,
102105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(Amt, ShTy)),
1022786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SRL, dl, NVT, InL,
102305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(NVTBits-Amt, ShTy)));
102405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
102505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return;
1026cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1027cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
102805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::SRL) {
102905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (Amt > VTBits) {
103005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);
103105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
103205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt > NVTBits) {
10337fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands      Lo = DAG.getNode(ISD::SRL, dl,
1034786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
103505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
103605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else if (Amt == NVTBits) {
103705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = InH;
103805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);
103905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    } else {
1040786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::OR, dl, NVT,
1041786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SRL, dl, NVT, InL,
104205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(Amt, ShTy)),
1043786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SHL, dl, NVT, InH,
104405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                   DAG.getConstant(NVTBits-Amt, ShTy)));
1045786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Amt, ShTy));
104605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
104705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return;
1048cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1049d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands
105005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
105105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Amt > VTBits) {
1052786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = Lo = DAG.getNode(ISD::SRA, dl, NVT, InH,
105305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                          DAG.getConstant(NVTBits-1, ShTy));
105405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else if (Amt > NVTBits) {
1055786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SRA, dl, NVT, InH,
105605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(Amt-NVTBits, ShTy));
1057786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,
105805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(NVTBits-1, ShTy));
105905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else if (Amt == NVTBits) {
106005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Lo = InH;
1061786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,
106205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(NVTBits-1, ShTy));
1063d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands  } else {
1064de06470330260f5937e7ca558f5f5b3e171f2ee5Dale Johannesen    Lo = DAG.getNode(ISD::OR, dl, NVT,
1065786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     DAG.getNode(ISD::SRL, dl, NVT, InL,
106605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(Amt, ShTy)),
1067786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                     DAG.getNode(ISD::SHL, dl, NVT, InH,
106805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(NVTBits-Amt, ShTy)));
1069786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Amt, ShTy));
1070d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands  }
1071d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands}
1072d885dbdf9eb7a51ebb9a15a85921f27d8219997cDuncan Sands
107305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
107405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// this shift based on knowledge of the high bit of the shift amount.  If we
107505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
107605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// shift amount.
107705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsbool DAGTypeLegalizer::
1078475871a144eb604ddaf37503397ba0941442e5fbDan GohmanExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
1079475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Amt = N->getOperand(1);
108083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
108105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT ShTy = Amt.getValueType();
108205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned ShBits = ShTy.getSizeInBits();
108305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
108405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(isPowerOf2_32(NVTBits) &&
108505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Expanded integer type size not a power of two!");
1086786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1087cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
108805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
108905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  APInt KnownZero, KnownOne;
109005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
1091cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
109205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we don't know anything about the high bits, exit.
109305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (((KnownZero|KnownOne) & HighBitMask) == 0)
109405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return false;
1095cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
109605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Get the incoming operand to be shifted.
1097475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
109805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
1099be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands
110005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we know that any of the high bits of the shift amount are one, then we
110105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // can do this as a couple of simple shifts.
110205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (KnownOne.intersects(HighBitMask)) {
110305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Mask out the high bit, which we know is set.
1104786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt,
110505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                      DAG.getConstant(~HighBitMask, ShTy));
110605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
110705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    switch (N->getOpcode()) {
1108c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown shift");
110905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SHL:
111005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Lo = DAG.getConstant(0, NVT);              // Low part is zero.
1111786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
111205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
111305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRL:
111405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Hi = DAG.getConstant(0, NVT);              // Hi part is zero.
1115786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
111605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
111705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRA:
1118786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRA, dl, NVT, InH,       // Sign extend high part.
111905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                       DAG.getConstant(NVTBits-1, ShTy));
1120786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
112105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      return true;
112205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
112305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
112405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
112528dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman#if 0
112628dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman  // FIXME: This code is broken for shifts with a zero amount!
112705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If we know that all of the high bits of the shift amount are zero, then we
112805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // can do this as a couple of simple shifts.
112905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if ((KnownZero & HighBitMask) == HighBitMask) {
113005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Compute 32-amt.
1131475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Amt2 = DAG.getNode(ISD::SUB, ShTy,
113205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 DAG.getConstant(NVTBits, ShTy),
113305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                 Amt);
113405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned Op1, Op2;
113505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    switch (N->getOpcode()) {
1136c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown shift");
113705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SHL:  Op1 = ISD::SHL; Op2 = ISD::SRL; break;
113805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRL:
113905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    case ISD::SRA:  Op1 = ISD::SRL; Op2 = ISD::SHL; break;
114005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    }
114105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
114205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
114305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getNode(ISD::OR, NVT,
114405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getNode(Op1, NVT, InH, Amt),
114505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getNode(Op2, NVT, InL, Amt2));
114605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return true;
114705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
114828dc98f7521933872b93156e3ebf5c9f8327b2b3Eli Friedman#endif
114905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
115005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  return false;
115105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
115205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
11536fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift
11546fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng/// of any size.
11556fb2168aaed06e4685d064b6f63dc4c668b42728Evan Chengbool DAGTypeLegalizer::
11566fb2168aaed06e4685d064b6f63dc4c668b42728Evan ChengExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) {
11576fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue Amt = N->getOperand(1);
11586fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
11596fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  MVT ShTy = Amt.getValueType();
11606fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  unsigned NVTBits = NVT.getSizeInBits();
11616fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  assert(isPowerOf2_32(NVTBits) &&
11626fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng         "Expanded integer type size not a power of two!");
11636fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  DebugLoc dl = N->getDebugLoc();
11646fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
11656fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  // Get the incoming operand to be shifted.
11666fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue InL, InH;
11676fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  GetExpandedInteger(N->getOperand(0), InL, InH);
11686fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
11696fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy);
11706fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue Amt2 = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt);
11716fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue Cmp = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy),
11726fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                             Amt, NVBitsNode, ISD::SETULT);
11736fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
11746fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  SDValue Lo1, Hi1, Lo2, Hi2;
11756fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  switch (N->getOpcode()) {
1176c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown shift");
11776fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SHL:
11786fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    // ShAmt < NVTBits
11796fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo1 = DAG.getConstant(0, NVT);                  // Low part is zero.
11806fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi1 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part.
11816fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
11826fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    // ShAmt >= NVTBits
11836fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo2 = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt);
11846fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi2 = DAG.getNode(ISD::OR, dl, NVT,
11856fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SHL, dl, NVT, InH, Amt),
11866fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SRL, dl, NVT, InL, Amt2));
11876fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
11886fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
11896fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
11906fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
11916fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SRL:
11926fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    // ShAmt < NVTBits
11936fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi1 = DAG.getConstant(0, NVT);                  // Hi part is zero.
11946fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo1 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part.
11956fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
11966fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    // ShAmt >= NVTBits
11976fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi2 = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt);
11986fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo2 = DAG.getNode(ISD::OR, dl, NVT,
11996fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                     DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
12006fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                     DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
12016fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
12026fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
12036fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
12046fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
12056fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  case ISD::SRA:
12066fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    // ShAmt < NVTBits
12076fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi1 = DAG.getNode(ISD::SRA, dl, NVT, InH,       // Sign extend high part.
12086fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                       DAG.getConstant(NVTBits-1, ShTy));
12096fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo1 = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part.
12106fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
12116fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    // ShAmt >= NVTBits
12126fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi2 = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt);
12136fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo2 = DAG.getNode(ISD::OR, dl, NVT,
12146fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SRL, dl, NVT, InL, Amt),
12156fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng                      DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2));
12166fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
12176fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Lo = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Lo1, Lo2);
12186fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    Hi = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, Hi1, Hi2);
12196fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return true;
12206fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  }
12216fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
12226fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  return false;
12236fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng}
12246fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng
122505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
1226475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                           SDValue &Lo, SDValue &Hi) {
1227786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
122805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1229475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
123005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
123105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
123229a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands
123329a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  MVT NVT = LHSL.getValueType();
1234475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[2] = { LHSL, RHSL };
1235475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
123605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
123729a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support
123829a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // them.  TODO: Teach operation legalization how to expand unsupported
123929a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // ADDC/ADDE/SUBC/SUBE.  The problem is that these operations generate
124029a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // a carry of type MVT::Flag, but there doesn't seem to be any way to
124129a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  // generate a value of this type in the expanded code sequence.
124229a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  bool hasCarry =
1243f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman    TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
1244f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman                                   ISD::ADDC : ISD::SUBC,
1245f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman                                 TLI.getTypeToExpandTo(NVT));
124629a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands
124729a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands  if (hasCarry) {
1248874ae251c317788391f9c3f113957802d390a063Dale Johannesen    SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
124929a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    if (N->getOpcode() == ISD::ADD) {
1250786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
125129a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands      HiOps[2] = Lo.getValue(1);
1252786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
125329a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    } else {
1254786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
125529a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands      HiOps[2] = Lo.getValue(1);
1256786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
125729a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    }
125805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
125929a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    if (N->getOpcode() == ISD::ADD) {
1260786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2);
1261786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2);
1262786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0],
126329a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                  ISD::SETULT);
1264786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1,
126529a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                   DAG.getConstant(1, NVT),
126629a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                   DAG.getConstant(0, NVT));
1267786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1],
126829a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                  ISD::SETULT);
1269786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2,
127029a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                   DAG.getConstant(1, NVT), Carry1);
1271786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2);
127229a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    } else {
1273786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2);
1274786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2);
12755480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands      SDValue Cmp =
1276f8d3ec2c5725a2010f11de4ba78f6127712a5fe7Dale Johannesen        DAG.getSetCC(dl, TLI.getSetCCResultType(LoOps[0].getValueType()),
12775480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                     LoOps[0], LoOps[1], ISD::SETULT);
1278786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp,
127929a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                   DAG.getConstant(1, NVT),
128029a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands                                   DAG.getConstant(0, NVT));
1281786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow);
128229a2822f287275a0d4df49f98104409d8f97c5dfDuncan Sands    }
128305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
128405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
128505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
128605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
1287475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
128805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1289475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
1290786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
129105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
129205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1293874ae251c317788391f9c3f113957802d390a063Dale Johannesen  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
1294475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[2] = { LHSL, RHSL };
1295475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
129605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
129705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (N->getOpcode() == ISD::ADDC) {
1298786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2);
129905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    HiOps[2] = Lo.getValue(1);
1300786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3);
130105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
1302786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2);
130305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    HiOps[2] = Lo.getValue(1);
1304786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3);
130505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
130605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1307874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // Legalized the flag result - switch anything that used the old flag to
1308874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // use the new one.
1309475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
131005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
131105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
131205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
1313475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
131405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Expand the subcomponents.
1315475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSL, LHSH, RHSL, RHSH;
1316786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
131705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
131805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
1319874ae251c317788391f9c3f113957802d390a063Dale Johannesen  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
1320475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
1321475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue HiOps[3] = { LHSH, RHSH };
132205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1323786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3);
132405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  HiOps[2] = Lo.getValue(1);
1325786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3);
132605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1327874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // Legalized the flag result - switch anything that used the old flag to
1328874ae251c317788391f9c3f113957802d390a063Dale Johannesen  // use the new one.
1329475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Hi.getValue(1));
133005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
133105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
133205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
1333475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
133405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
1335786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1336475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
133705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
133805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The low part is any extension of the input (which degenerates to a copy).
1339786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op);
1340e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen    Hi = DAG.getUNDEF(NVT);   // The high part is undefined.
134105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
134205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
134305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
134405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
134505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
1346475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
134705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
134805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
134905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
135005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
135105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
135205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
135305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
135495db39a9de48f69f4d764335b492b83a698c7854Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N,
1355475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
1356786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
135795db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
135895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  MVT NVT = Lo.getValueType();
135995db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
136095db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  unsigned NVTBits = NVT.getSizeInBits();
136195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  unsigned EVTBits = EVT.getSizeInBits();
136295db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
136395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  if (NVTBits < EVTBits) {
1364786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi,
136595db39a9de48f69f4d764335b492b83a698c7854Duncan Sands                     DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits)));
136695db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  } else {
1367786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT));
136895db39a9de48f69f4d764335b492b83a698c7854Duncan Sands    // The high part replicates the sign bit of Lo, make it explicit.
1369786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
137092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(NVTBits-1, TLI.getPointerTy()));
137195db39a9de48f69f4d764335b492b83a698c7854Duncan Sands  }
137295db39a9de48f69f4d764335b492b83a698c7854Duncan Sands}
137395db39a9de48f69f4d764335b492b83a698c7854Duncan Sands
137405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
1375475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Lo, SDValue &Hi) {
1376786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
137705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
137805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = Lo.getValueType();
137905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
138005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NVTBits = NVT.getSizeInBits();
138105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned EVTBits = EVT.getSizeInBits();
138205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
138305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (NVTBits < EVTBits) {
1384786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi,
138505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits)));
138605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
1387786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT));
138805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part must be zero, make it explicit.
138905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getConstant(0, NVT);
139005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
139105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
139205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
139305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
1394475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1395786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
139605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Hi, Lo);  // Note swapped operands.
1397786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo);
1398786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi);
139905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
140005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
140105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
1402475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
140305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
140405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  unsigned NBitWidth = NVT.getSizeInBits();
140505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue();
140605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Lo = DAG.getConstant(APInt(Cst).trunc(NBitWidth), NVT);
140705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
140805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
140905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
141005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
1411475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1412786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
141305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
141405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
141505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = Lo.getValueType();
141605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1417786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi,
1418ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   DAG.getConstant(0, NVT), ISD::SETNE);
141905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1420786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo);
1421786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi);
142205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1423786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ,
1424786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::ADD, dl, NVT, LoLZ,
142505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
142605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
142705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
142805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
142905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
1430475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
1431786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
143205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
143305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
143405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = Lo.getValueType();
1435b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen  Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo),
1436786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::CTPOP, dl, NVT, Hi));
143705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
143805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
143905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
144005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
1441475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1442786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
144305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
144405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
144505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = Lo.getValueType();
144605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1447786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo,
1448ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   DAG.getConstant(0, NVT), ISD::SETNE);
144905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1450786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo);
1451786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi);
145205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1453786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ,
1454786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   DAG.getNode(ISD::ADD, dl, NVT, HiLZ,
145505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
145605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  Hi = DAG.getConstant(0, NVT);
145705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
145805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1459475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo,
1460475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Hi) {
1461c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
146205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT VT = N->getValueType(0);
1463475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
1464b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT);
1465be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!");
1466c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi);
1467ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1468ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
1469475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo,
1470475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                               SDValue &Hi) {
1471c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
147283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT VT = N->getValueType(0);
1473475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
1474b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT);
1475be1ad4de2900451626c8d4ace07b9ea16099ea1dDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!");
1476c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi);
1477ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1478ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
147969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
1480475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
1481ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  if (ISD::isNormalLoad(N)) {
1482ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands    ExpandRes_NormalLoad(N, Lo, Hi);
148378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands    return;
148478cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  }
148578cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
148678cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
148778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
148883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT VT = N->getValueType(0);
148983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(VT);
1490475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch  = N->getChain();
1491475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getBasePtr();
1492cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  ISD::LoadExtType ExtType = N->getExtensionType();
1493cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  int SVOffset = N->getSrcValueOffset();
1494cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned Alignment = N->getAlignment();
1495cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  bool isVolatile = N->isVolatile();
1496786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1497cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
149878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
1499cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
150078cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getMemoryVT().bitsLE(NVT)) {
150183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT EVT = N->getMemoryVT();
1502cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1503786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
1504786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                        EVT, isVolatile, Alignment);
1505cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1506cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Remember the chain.
1507cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    Ch = Lo.getValue(1);
1508cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1509cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    if (ExtType == ISD::SEXTLOAD) {
1510cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is obtained by SRA'ing all but one of the bits of the
1511cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // lo part.
151283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      unsigned LoSize = Lo.getValueType().getSizeInBits();
1513786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
151492abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                       DAG.getConstant(LoSize-1, TLI.getPointerTy()));
1515cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    } else if (ExtType == ISD::ZEXTLOAD) {
1516cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is just a zero.
1517cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Hi = DAG.getConstant(0, NVT);
1518cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    } else {
1519cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
1520cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The high part is undefined.
1521e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen      Hi = DAG.getUNDEF(NVT);
1522cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1523cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else if (TLI.isLittleEndian()) {
1524cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Little-endian - low bits are at low addresses.
1525786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset,
1526cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     isVolatile, Alignment);
1527cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1528cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits =
152983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
153083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT NEVT = MVT::getIntegerVT(ExcessBits);
1531cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1532cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
153383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
1534786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
15350bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
1536786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(),
1537cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                        SVOffset+IncrementSize, NEVT,
1538cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                        isVolatile, MinAlign(Alignment, IncrementSize));
1539cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1540cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Build a factor node to remember that this load is independent of the
1541cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // other one.
1542786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1543cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     Hi.getValue(1));
1544cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else {
1545cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Big-endian - high bits are at low addresses.  Favor aligned loads at
1546cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // the cost of some bit-fiddling.
154783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT EVT = N->getMemoryVT();
154883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned EBytes = EVT.getStoreSizeInBits()/8;
154983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
1550cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits = (EBytes - IncrementSize)*8;
1551cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1552cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Load both the high bits and maybe some of the low bits.
1553786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
155483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                        MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits),
1555cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                        isVolatile, Alignment);
1556cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1557cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
1558786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
15590bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
1560cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Load the rest of the low bits.
1561786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(),
156283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                        SVOffset+IncrementSize,
156383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                        MVT::getIntegerVT(ExcessBits),
1564cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                        isVolatile, MinAlign(Alignment, IncrementSize));
1565cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1566cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Build a factor node to remember that this load is independent of the
1567cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // other one.
1568786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1),
1569cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                     Hi.getValue(1));
1570cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
157183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    if (ExcessBits < NVT.getSizeInBits()) {
1572cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Transfer low bits from the bottom of Hi to the top of Lo.
1573786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::OR, dl, NVT, Lo,
1574786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       DAG.getNode(ISD::SHL, dl, NVT, Hi,
1575cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                   DAG.getConstant(ExcessBits,
157692abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                                   TLI.getPointerTy())));
1577cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Move high bits to the right position in Hi.
15787fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands      Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl,
1579786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       NVT, Hi,
158083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
158192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
1582cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1583cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
1584cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1585cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Legalized the chain result - switch anything that used the old chain to
1586cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // use the new one.
1587475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 1), Ch);
1588cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1589cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
159069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
1591475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                            SDValue &Lo, SDValue &Hi) {
1592786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1593475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LL, LH, RL, RH;
159469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(0), LL, LH);
159569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(1), RL, RH);
1596786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL);
1597786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH);
1598cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1599cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
160005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
1601475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                        SDValue &Lo, SDValue &Hi) {
160205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT VT = N->getValueType(0);
160305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(VT);
1604c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
160569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1606f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT);
1607f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT);
1608f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT);
1609f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman  bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT);
1610cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
1611475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue LL, LH, RL, RH;
161269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(0), LL, LH);
161369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(1), RL, RH);
161483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned OuterBitSize = VT.getSizeInBits();
1615e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    unsigned InnerBitSize = NVT.getSizeInBits();
1616cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
1617cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
161869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1619e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
1620e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
1621e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands        DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
1622cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The inputs are both zero-extended.
1623cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasUMUL_LOHI) {
1624cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a umul_lohi.
1625786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
1626ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        Hi = SDValue(Lo.getNode(), 1);
1627cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1628cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1629cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasMULHU) {
1630cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a mulhu+mul.
1631786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1632786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
1633cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1634cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1635cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1636e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
1637cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // The input values are both sign-extended.
1638cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasSMUL_LOHI) {
1639cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a smul_lohi.
1640786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL);
1641ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif        Hi = SDValue(Lo.getNode(), 1);
1642cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1643cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1644cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      if (HasMULHS) {
1645cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        // We can emit a mulhs+mul.
1646786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1647786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen        Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL);
1648cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        return;
1649cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      }
1650cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1651cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    if (HasUMUL_LOHI) {
1652cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Lo,Hi = umul LHS, RHS.
1653786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl,
1654cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                       DAG.getVTList(NVT, NVT), LL, RL);
1655cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Lo = UMulLOHI;
1656cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Hi = UMulLOHI.getValue(1);
1657786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
1658786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
1659786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
1660786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
1661cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      return;
1662cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
1663e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    if (HasMULHU) {
1664786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL);
1665786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL);
1666786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH);
1667786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL);
1668786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH);
1669786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH);
1670e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands      return;
1671e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    }
1672cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
167341edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
1674cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If nothing else, we can make a libcall.
16755ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
167615c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta  if (VT == MVT::i16)
167715c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    LC = RTLIB::MUL_I16;
167815c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta  else if (VT == MVT::i32)
16795ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::MUL_I32;
16805ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  else if (VT == MVT::i64)
1681e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands    LC = RTLIB::MUL_I64;
16825ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  else if (VT == MVT::i128)
16835ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::MUL_I128;
16845ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!");
1685e9c80f4d576bf1ff682958d447c1a60fa9348da3Duncan Sands
1686475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1687c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi);
168841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands}
1689cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
169069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
1691475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
16925ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  MVT VT = N->getValueType(0);
1693c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
16945ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands
16955ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1696a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  if (VT == MVT::i16)
1697a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::SDIV_I16;
1698a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  else if (VT == MVT::i32)
16995ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I32;
17005ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  else if (VT == MVT::i64)
17015ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I64;
17025ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  else if (VT == MVT::i128)
17035ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands    LC = RTLIB::SDIV_I128;
17045ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!");
17055ac319ac7125b009adddcc49294d2e040c4a91e5Duncan Sands
1706475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1707c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
1708ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands}
1709ddc016cc8592fe5c9379feb42a1fb4fb63164a91Duncan Sands
171069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
1711475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                          SDValue &Lo, SDValue &Hi) {
171283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT VT = N->getValueType(0);
1713c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
171469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
171569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  // If we can emit an efficient shift operation, do so now.  Check to see if
1716cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // the RHS is a constant.
1717cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
1718f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman    return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi);
1719cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1720cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If we can determine that the high bit of the shift is zero or one, even if
1721cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // the low bits are variable, emit this shift in an optimized form.
1722cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
1723cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
172469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1725cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If this target supports shift_PARTS, use it.  First, map to the _PARTS opc.
1726cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned PartsOpc;
172741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  if (N->getOpcode() == ISD::SHL) {
1728cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SHL_PARTS;
172941edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else if (N->getOpcode() == ISD::SRL) {
1730cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SRL_PARTS;
173141edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else {
1732cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
1733cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    PartsOpc = ISD::SRA_PARTS;
1734cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
173569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1736cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Next check to see if the target supports this SHL_PARTS operation or if it
1737cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // will custom expand it.
173883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(VT);
1739cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
1740cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
1741cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      Action == TargetLowering::Custom) {
1742cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Expand the subcomponents.
1743475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue LHSL, LHSH;
174469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
174569b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
1746475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) };
174783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT VT = LHSL.getValueType();
1748fc1665793e62eb4f26d24b8a19eecf59cd872e2aDan Gohman    Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops, 3);
1749cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    Hi = Lo.getValue(1);
1750cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
1751cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
175241edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
1753cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Otherwise, emit a libcall.
1754dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
175541edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  bool isSigned;
175641edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  if (N->getOpcode() == ISD::SHL) {
175741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = false; /*sign irrelevant*/
175815c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    if (VT == MVT::i16)
175915c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SHL_I16;
176015c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    else if (VT == MVT::i32)
1761dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I32;
1762dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands    else if (VT == MVT::i64)
1763dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I64;
1764dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands    else if (VT == MVT::i128)
1765dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SHL_I128;
176641edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else if (N->getOpcode() == ISD::SRL) {
176741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = false;
176815c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    if (VT == MVT::i16)
176915c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SRL_I16;
177015c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    else if (VT == MVT::i32)
1771dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I32;
1772dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands    else if (VT == MVT::i64)
1773dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I64;
1774dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands    else if (VT == MVT::i128)
1775dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRL_I128;
177641edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  } else {
177741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
177841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands    isSigned = true;
177915c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    if (VT == MVT::i16)
178015c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta      LC = RTLIB::SRA_I16;
178115c94d08ab2be2e3d00de4edbfc7adde6545a7dbSanjiv Gupta    else if (VT == MVT::i32)
1782dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I32;
1783dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands    else if (VT == MVT::i64)
1784dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I64;
1785dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands    else if (VT == MVT::i128)
1786dddc6291fb5274282a20d5923b50535d456d34a4Duncan Sands      LC = RTLIB::SRA_I128;
178741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands  }
17888c899ee031481dbece5f111379a274c848cb5902Duncan Sands
17896fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) {
17906fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
17916fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi);
17926fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng    return;
17936fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  }
179441edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
17956fb2168aaed06e4685d064b6f63dc4c668b42728Evan Cheng  if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi))
1796c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported shift!");
179741edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands}
1798cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
179905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
1800475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                SDValue &Lo, SDValue &Hi) {
180105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
1802786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1803475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
180405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
1805b3bc6352defdf1a5c6b1b0770d0c4d603f6524a8Duncan Sands    // The low part is sign extension of the input (degenerates to a copy).
1806786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0));
180705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part is obtained by SRA'ing all but one of the bits of low part.
180805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned LoSize = NVT.getSizeInBits();
1809786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo,
181092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                     DAG.getConstant(LoSize-1, TLI.getPointerTy()));
181105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
181205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
181305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
181405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
181505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
1816475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
181705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
181805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
181905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
182005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
182105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
182205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
1823786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
182405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
182505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
182605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
182705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
182805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::
1829475871a144eb604ddaf37503397ba0941442e5fbDan GohmanExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) {
1830786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
183169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(N->getOperand(0), Lo, Hi);
183205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
1833d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
183405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (EVT.bitsLE(Lo.getValueType())) {
183505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // sext_inreg the low part if needed.
1836786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo,
183705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     N->getOperand(1));
1838d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
183905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The high part gets the sign extension from the lo-part.  This handles
184005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // things like sextinreg V:i64 from i8.
1841786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo,
184205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
184392abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                     TLI.getPointerTy()));
184405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
184505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  Leave the low part alone,
184605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // sext_inreg the high part.
184705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
184805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
1849786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi,
185005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                     DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
185105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
185205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
1853d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
185405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
1855475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
185605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT VT = N->getValueType(0);
1857c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
185805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
185905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1860a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  if (VT == MVT::i16)
1861a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::SREM_I16;
1862a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  else if (VT == MVT::i32)
186305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I32;
186405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  else if (VT == MVT::i64)
186505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I64;
186605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  else if (VT == MVT::i128)
186705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::SREM_I128;
186805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!");
186905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
1870475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1871c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi);
1872d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
1873d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
187405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
1875475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                             SDValue &Lo, SDValue &Hi) {
187605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
1877786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1878786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0));
1879786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::SRL, dl,
1880786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                   N->getOperand(0).getValueType(), N->getOperand(0),
188192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                   DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy()));
1882786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi);
1883d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
1884d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
188505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
1886475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
188705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT VT = N->getValueType(0);
1888c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1889d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
189005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1891a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  if (VT == MVT::i16)
1892a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::UDIV_I16;
1893a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  else if (VT == MVT::i32)
189405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I32;
189505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  else if (VT == MVT::i64)
189605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I64;
189705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  else if (VT == MVT::i128)
189805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UDIV_I128;
189905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!");
1900d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands
1901475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1902c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
1903d462ba853981d45bf9c777564e79dc9e1c850ca6Duncan Sands}
1904cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
190505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
1906475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                         SDValue &Lo, SDValue &Hi) {
190705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT VT = N->getValueType(0);
1908c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
190969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
191005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1911a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  if (VT == MVT::i16)
1912a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta    LC = RTLIB::UREM_I16;
1913a43a7aefd753fe7d6005cbebc9619268db4ae139Sanjiv Gupta  else if (VT == MVT::i32)
191405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I32;
191505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  else if (VT == MVT::i64)
191605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I64;
191705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  else if (VT == MVT::i128)
191805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    LC = RTLIB::UREM_I128;
191905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!");
1920cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1921475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1922c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi);
1923cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1924cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
192505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsvoid DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
1926475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                SDValue &Lo, SDValue &Hi) {
192783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
1928786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
1929475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
193005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (Op.getValueType().bitsLE(NVT)) {
1931b3bc6352defdf1a5c6b1b0770d0c4d603f6524a8Duncan Sands    // The low part is zero extension of the input (degenerates to a copy).
1932786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0));
193305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    Hi = DAG.getConstant(0, NVT);   // The high part is just a zero.
193405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  } else {
193505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // For example, extension of an i48 to an i64.  The operand type necessarily
193605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // promotes to the result type, so will end up being expanded too.
193705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
193805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Only know how to promote this result!");
1939475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Res = GetPromotedInteger(Op);
194005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(Res.getValueType() == N->getValueType(0) &&
194105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Operand over promoted?");
194205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Split the promoted operand.  This will simplify when it is expanded.
194305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SplitInteger(Res, Lo, Hi);
194405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    unsigned ExcessBits =
194505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
19464be0bdf7c1162824927dd3de89e016ae4934d0d6Dale Johannesen    Hi = DAG.getZeroExtendInReg(Hi, dl, MVT::getIntegerVT(ExcessBits));
19479e255b7df5a0a629920706e086e78ef89bf2f183Dan Gohman  }
1948cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
1949cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1950cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
1951cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
195269b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands//  Integer Operand Expansion
1953cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner//===----------------------------------------------------------------------===//
1954cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
195505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// ExpandIntegerOperand - This method is called when the specified operand of
195605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// the specified node is found to need expansion.  At this point, all of the
195705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// result types of the node are known to be legal, but other operands of the
195805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands/// node may need promotion or expansion as well as the specified one.
195905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sandsbool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
1960fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman  DEBUG(errs() << "Expand integer operand: "; N->dump(&DAG); errs() << "\n");
1961475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Res = SDValue();
1962051bb7b07504be9f848f7cce802e62ed24980bc5Duncan Sands
1963f43071beddb7ed5b2fd7d2f06c4130460616a13dDuncan Sands  if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false))
1964bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta    return false;
196511ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands
1966bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  switch (N->getOpcode()) {
1967bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  default:
196805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  #ifndef NDEBUG
1969fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    errs() << "ExpandIntegerOperand Op #" << OpNo << ": ";
1970fd87a544c00c2ca04ee23aae67bbcad4dc852a54Dan Gohman    N->dump(&DAG); errs() << "\n";
197105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  #endif
1972c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Do not know how to expand this operator's operand!");
1973bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta
1974bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::BIT_CONVERT:       Res = ExpandOp_BIT_CONVERT(N); break;
197592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::BR_CC:             Res = ExpandIntOp_BR_CC(N); break;
197692abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::BUILD_VECTOR:      Res = ExpandOp_BUILD_VECTOR(N); break;
1977bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::EXTRACT_ELEMENT:   Res = ExpandOp_EXTRACT_ELEMENT(N); break;
1978bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break;
1979bb326bbe88d0b243d5d9d224308eb0c028d4d4afSanjiv Gupta  case ISD::SCALAR_TO_VECTOR:  Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
198092abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SELECT_CC:         Res = ExpandIntOp_SELECT_CC(N); break;
198192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SETCC:             Res = ExpandIntOp_SETCC(N); break;
198292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::SINT_TO_FP:        Res = ExpandIntOp_SINT_TO_FP(N); break;
198392abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::STORE:   Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
198492abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::TRUNCATE:          Res = ExpandIntOp_TRUNCATE(N); break;
198592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands  case ISD::UINT_TO_FP:        Res = ExpandIntOp_UINT_TO_FP(N); break;
198655467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
198755467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SHL:
198855467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRA:
198955467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::SRL:
199055467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTL:
199155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  case ISD::ROTR: Res = ExpandIntOp_Shift(N); break;
199205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
199369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
199405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If the result is null, the sub-method took care of registering results etc.
1995ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Res.getNode()) return false;
199647d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands
199747d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // If the result is N, the sub-method updated N in place.  Tell the legalizer
199847d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  // core about this.
199947d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7Duncan Sands  if (Res.getNode() == N)
200005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return true;
2001cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
200205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
200305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Invalid operand expansion");
200405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2005475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  ReplaceValueWith(SDValue(N, 0), Res);
200605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  return false;
2007cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2008cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
200911ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands/// IntegerExpandSetCCOperands - Expand the operands of a comparison.  This code
201011ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
2011475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
2012475871a144eb604ddaf37503397ba0941442e5fbDan Gohman                                                  SDValue &NewRHS,
2013c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen                                                  ISD::CondCode &CCCode,
2014c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen                                                  DebugLoc dl) {
2015475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue LHSLo, LHSHi, RHSLo, RHSHi;
201669b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(NewLHS, LHSLo, LHSHi);
201769b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands  GetExpandedInteger(NewRHS, RHSLo, RHSHi);
201841edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
201983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT VT = NewLHS.getValueType();
202041edfb8ae119d6cf6579046619dd2820ec876065Duncan Sands
2021cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
202211ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    if (RHSLo == RHSHi) {
202311ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands      if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
2024cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        if (RHSCST->isAllOnesValue()) {
2025cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          // Equality comparison to -1.
20267fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands          NewLHS = DAG.getNode(ISD::AND, dl,
2027786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                               LHSLo.getValueType(), LHSLo, LHSHi);
2028cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          NewRHS = RHSLo;
2029cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner          return;
2030cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        }
203111ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands      }
203211ac797f5ed142f11aafde3dd76c28a73d84282eDuncan Sands    }
203369b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2034786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo);
2035786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi);
2036786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS);
2037cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
2038cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2039cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
204069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2041cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // If this is a comparison of the sign bit, just look at the top part.
2042cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // X > -1,  x < 0
2043cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS))
2044002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman    if ((CCCode == ISD::SETLT && CST->isNullValue()) ||     // X < 0
2045cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        (CCCode == ISD::SETGT && CST->isAllOnesValue())) {  // X > -1
2046cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      NewLHS = LHSHi;
2047cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      NewRHS = RHSHi;
2048cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      return;
2049cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
205069b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2051cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // FIXME: This generated code sucks.
2052cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  ISD::CondCode LowCC;
2053cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  switch (CCCode) {
2054c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown integer setcc!");
2055cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETLT:
2056cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETULT: LowCC = ISD::SETULT; break;
2057cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETGT:
2058cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETUGT: LowCC = ISD::SETUGT; break;
2059cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETLE:
2060cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETULE: LowCC = ISD::SETULE; break;
2061cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETGE:
2062cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  case ISD::SETUGE: LowCC = ISD::SETUGE; break;
2063cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
206469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2065cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Tmp1 = lo(op1) < lo(op2)   // Always unsigned comparison
2066cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // Tmp2 = hi(op1) < hi(op2)   // Signedness depends on operands
2067cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
206869b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2069cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // NOTE: on targets without efficient SELECT of bools, we can always use
2070cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
207178d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen  TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, true, NULL);
2072475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Tmp1, Tmp2;
20735480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
2074ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                           LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl);
2075ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Tmp1.getNode())
2076786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()),
20775480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                        LHSLo, RHSLo, LowCC);
20785480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
2079ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                           LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl);
2080ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!Tmp2.getNode())
2081786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Tmp2 = DAG.getNode(ISD::SETCC, dl,
2082786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                       TLI.getSetCCResultType(LHSHi.getValueType()),
20835480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                       LHSHi, RHSHi, DAG.getCondCode(CCCode));
208469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
2085ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode());
2086ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode());
2087002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman  if ((Tmp1C && Tmp1C->isNullValue()) ||
2088002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman      (Tmp2C && Tmp2C->isNullValue() &&
2089cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner       (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
2090cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
2091002e5d0a170dadd5c307e0b00d8c7970835837e6Dan Gohman      (Tmp2C && Tmp2C->getAPIntValue() == 1 &&
2092cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner       (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
2093cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner        CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
2094cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // low part is known false, returns high part.
2095cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // For LE / GE, if high part is known false, ignore the low part.
2096cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // For LT / GT, if high part is known true, ignore the low part.
2097cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    NewLHS = Tmp2;
2098475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    NewRHS = SDValue();
2099cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    return;
2100cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
210169b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands
21025480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
2103fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel                             LHSHi, RHSHi, ISD::SETEQ, false,
2104ff97d4fe81ef0dcee9fe490bed8ab08e40251905Dale Johannesen                             DagCombineInfo, dl);
2105ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (!NewLHS.getNode())
2106786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()),
21075480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                          LHSHi, RHSHi, ISD::SETEQ);
2108786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(),
2109cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                       NewLHS, Tmp1, Tmp2);
2110475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  NewRHS = SDValue();
2111cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
2112cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2113475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
2114475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
211505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
2116c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
211705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
211805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, we need to compare the result
211905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // against zero to select between true and false values.
2120ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
212105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
212205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    CCCode = ISD::SETNE;
212305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
212405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
212505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Update N to have the operands specified.
2126475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
212705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
212805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                N->getOperand(4));
212905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
213005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2131475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
2132475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
213305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
2134c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
213505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
213605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, we need to compare the result
213705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // against zero to select between true and false values.
2138ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
213905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
214005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    CCCode = ISD::SETNE;
214105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
214205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
214305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Update N to have the operands specified.
2144475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
214505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                N->getOperand(2), N->getOperand(3),
214605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                DAG.getCondCode(CCCode));
214705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
214805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2149475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
2150475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
215105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
2152c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc());
215305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
215405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // If ExpandSetCCOperands returned a scalar, use it.
2155ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif  if (NewRHS.getNode() == 0) {
215605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    assert(NewLHS.getValueType() == N->getValueType(0) &&
215705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands           "Unexpected setcc expansion!");
215805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    return NewLHS;
215905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
216005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
216105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Otherwise, update N to have the operands specified.
2162475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
216305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands                                DAG.getCondCode(CCCode));
216405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
216505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
216655467af31620c9d027e071ebcd9746b7593cff17Sanjiv GuptaSDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
216755467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // The value being shifted is legal, but the shift amount is too big.
216855467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // It follows that either the result of the shift is undefined, or the
216955467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  // upper half of the shift amount is zero.  Just use the lower half.
217055467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  SDValue Lo, Hi;
217155467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  GetExpandedInteger(N->getOperand(1), Lo, Hi);
217255467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Lo);
217355467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta}
217455467af31620c9d027e071ebcd9746b7593cff17Sanjiv Gupta
2175475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
2176475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
217705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT DstVT = N->getValueType(0);
2178b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT);
217905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
218005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Don't know how to expand this SINT_TO_FP!");
2181c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc());
218205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
218305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2184475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
2185ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands  if (ISD::isNormalStore(N))
2186ab09b7e8f34075c1759127a113f41bdf921f4034Duncan Sands    return ExpandOp_NormalStore(N, OpNo);
218778cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands
218878cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
2189cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  assert(OpNo == 1 && "Can only expand the stored value so far");
2190cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
219183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT VT = N->getOperand(1).getValueType();
219283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands  MVT NVT = TLI.getTypeToTransformTo(VT);
2193475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ch  = N->getChain();
2194475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Ptr = N->getBasePtr();
2195cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  int SVOffset = N->getSrcValueOffset();
2196cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  unsigned Alignment = N->getAlignment();
2197cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  bool isVolatile = N->isVolatile();
2198786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  DebugLoc dl = N->getDebugLoc();
2199475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Lo, Hi;
2200cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2201a1ace76c70ae5332d6f33fce5c0c1e2fdb8cca11Duncan Sands  assert(NVT.isByteSized() && "Expanded type not byte sized!");
2202cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
220378cd649ad326f79a1f8424ca2b63cea3239a9a52Duncan Sands  if (N->getMemoryVT().bitsLE(NVT)) {
220469b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2205786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
2206b625f2f8960de32bc973092aaee8ac62863006feDan Gohman                             N->getMemoryVT(), isVolatile, Alignment);
2207cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else if (TLI.isLittleEndian()) {
2208cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Little-endian - low bits are at low addresses.
220969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2210cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2211786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset,
2212cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                      isVolatile, Alignment);
2213cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2214cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits =
221583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
221683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT NEVT = MVT::getIntegerVT(ExcessBits);
2217cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2218cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
221983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
2220786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
22210bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
2222786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
2223cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                           SVOffset+IncrementSize, NEVT,
2224cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                           isVolatile, MinAlign(Alignment, IncrementSize));
2225786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2226cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  } else {
2227cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Big-endian - high bits are at low addresses.  Favor aligned stores at
2228cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // the cost of some bit-fiddling.
222969b01e92a29ce6d7e435171aeea3fbc987b81586Duncan Sands    GetExpandedInteger(N->getValue(), Lo, Hi);
2230cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
223183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT EVT = N->getMemoryVT();
223283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned EBytes = EVT.getStoreSizeInBits()/8;
223383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    unsigned IncrementSize = NVT.getSizeInBits()/8;
2234cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    unsigned ExcessBits = (EBytes - IncrementSize)*8;
223583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    MVT HiVT = MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits);
2236cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
223783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands    if (ExcessBits < NVT.getSizeInBits()) {
2238cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner      // Transfer high bits from the top of Lo to the bottom of Hi.
2239786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi,
224083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
224192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                       TLI.getPointerTy()));
2242786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen      Hi = DAG.getNode(ISD::OR, dl, NVT, Hi,
2243de06470330260f5937e7ca558f5f5b3e171f2ee5Dale Johannesen                       DAG.getNode(ISD::SRL, dl, NVT, Lo,
2244cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                                   DAG.getConstant(ExcessBits,
224592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands                                                   TLI.getPointerTy())));
2246cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    }
2247cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2248cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Store both the high bits and maybe some of the low bits.
2249786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(),
2250cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                           SVOffset, HiVT, isVolatile, Alignment);
2251cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner
2252cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Increment the pointer to the other half.
2253786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr,
22540bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner                      DAG.getIntPtrConstant(IncrementSize));
2255cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner    // Store the lowest ExcessBits bits in the second half.
2256786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(),
2257cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                           SVOffset+IncrementSize,
225883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands                           MVT::getIntegerVT(ExcessBits),
2259cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner                           isVolatile, MinAlign(Alignment, IncrementSize));
2260786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
2261cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner  }
2262cc663a8112017f06e0cd4b6fe1546ccfcd5d05c3Chris Lattner}
226305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2264475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
2265475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue InL, InH;
226605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  GetExpandedInteger(N->getOperand(0), InL, InH);
226705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Just truncate the low part of the source.
2268786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen  return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL);
226905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
227005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
2271475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
2272475871a144eb604ddaf37503397ba0941442e5fbDan Gohman  SDValue Op = N->getOperand(0);
227305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT SrcVT = Op.getValueType();
227405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  MVT DstVT = N->getValueType(0);
2275c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  DebugLoc dl = N->getDebugLoc();
227605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
227705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
227805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Do a signed conversion then adjust the result.
2279786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op);
228005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    SignedConv = TLI.LowerOperation(SignedConv, DAG);
228105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
228205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // The result of the signed conversion needs adjusting if the 'sign bit' of
228305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // the incoming integer was set.  To handle this, we dynamically test to see
228405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // if it is set, and, if so, add a fudge factor.
228505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
228605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE32  = 0x4F800000ULL;
228705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE64  = 0x5F800000ULL;
228805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    const uint64_t F32TwoE128 = 0x7F800000ULL;
228905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
229005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    APInt FF(32, 0);
229105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (SrcVT == MVT::i32)
229205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE32);
229305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    else if (SrcVT == MVT::i64)
229405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE64);
229505c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    else if (SrcVT == MVT::i128)
229605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      FF = APInt(32, F32TwoE128);
229705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    else
229805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands      assert(false && "Unsupported UINT_TO_FP!");
229905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
230005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Check whether the sign bit is set.
2301475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Lo, Hi;
230205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    GetExpandedInteger(Op, Lo, Hi);
23037fb085871857134f8cbeb17499d4ab771ba8da42Duncan Sands    SDValue SignSet = DAG.getSetCC(dl,
2304786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen                                   TLI.getSetCCResultType(Hi.getValueType()),
23055480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands                                   Hi, DAG.getConstant(0, Hi.getValueType()),
2306ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                   ISD::SETLT);
230705c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
230805c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.
2309001dbfebcbbded8c8e74b19e838b50da2b6c6fb5Owen Anderson    SDValue FudgePtr = DAG.getConstantPool(
2310eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson                               ConstantInt::get(*DAG.getContext(), FF.zext(64)),
231149c18cce976c158e86f54c681dff21bb81640fb8Duncan Sands                                           TLI.getPointerTy());
231205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
231305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
2314475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Zero = DAG.getIntPtrConstant(0);
2315475871a144eb604ddaf37503397ba0941442e5fbDan Gohman    SDValue Four = DAG.getIntPtrConstant(4);
231605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    if (TLI.isBigEndian()) std::swap(Zero, Four);
2317786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet,
2318ef5b199905cee0b78eb30cd44836e5b6ca5cbd09Duncan Sands                                 Zero, Four);
23191606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment();
2320786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset);
232187a0f10dc7eff8cf5e83a754f75adf9cb3991435Dan Gohman    Alignment = std::min(Alignment, 4u);
232205c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
232305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // Load the value out, extending it from f32 to the destination float type.
232405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands    // FIXME: Avoid the extend by constructing the right constant pool?
2325786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(),
232687a0f10dc7eff8cf5e83a754f75adf9cb3991435Dan Gohman                                   FudgePtr, NULL, 0, MVT::f32,
232787a0f10dc7eff8cf5e83a754f75adf9cb3991435Dan Gohman                                   false, Alignment);
2328786fd4dded6a42561c0d82bbd9d13b9a4d8d9675Dale Johannesen    return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge);
232905c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  }
233005c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands
233105c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  // Otherwise, use a libcall.
2332b2ff885aaed8f9b033b16ca78d645650efc32433Duncan Sands  RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT);
233305c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
233405c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands         "Don't know how to expand this UINT_TO_FP!");
2335c8fc99d66a03dc603f49d653937ad1d94e833006Dale Johannesen  return MakeLibCall(LC, DstVT, &Op, 1, true, dl);
233605c397d52a145c8844790d6491c4c51d4bbfed7cDuncan Sands}
2337