1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file implements integer type expansion and promotion for LegalizeTypes. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Promotion is the act of changing a computation in an illegal type into a 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// computation in a larger type. For example, implementing i8 arithmetic in an 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// i32 register (often needed on powerpc). 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Expansion is the act of changing a computation in an illegal type into a 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// computation in two identical registers of a smaller type. For example, 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// implementing i64 arithmetic in two i32 registers (often needed on 32-bit 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// targets). 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "LegalizeTypes.h" 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/DerivedTypes.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/PseudoSourceValue.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Integer Result Promotion 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PromoteIntegerResult - This method is called when a result of a node is 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// found to be in need of promotion to a larger type. At this point, the node 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// may also have invalid operands or may have other results that need 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// expansion, we just know that (at least) one result needs promotion. 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "Promote integer result: "; N->dump(&DAG); dbgs() << "\n"); 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = SDValue(); 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // See if the target wants to custom expand this node. 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CustomLowerNode(N, N->getValueType(ResNo), true)) 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "PromoteIntegerResult #" << ResNo << ": "; 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->dump(&DAG); dbgs() << "\n"; 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Do not know how to promote this operator!"); 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::MERGE_VALUES:Res = PromoteIntRes_MERGE_VALUES(N, ResNo); break; 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AssertSext: Res = PromoteIntRes_AssertSext(N); break; 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AssertZext: Res = PromoteIntRes_AssertZext(N); break; 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::BITCAST: Res = PromoteIntRes_BITCAST(N); break; 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BSWAP: Res = PromoteIntRes_BSWAP(N); break; 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_PAIR: Res = PromoteIntRes_BUILD_PAIR(N); break; 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::Constant: Res = PromoteIntRes_Constant(N); break; 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CONVERT_RNDSAT: 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntRes_CONVERT_RNDSAT(N); break; 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTLZ: Res = PromoteIntRes_CTLZ(N); break; 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTPOP: Res = PromoteIntRes_CTPOP(N); break; 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTTZ: Res = PromoteIntRes_CTTZ(N); break; 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_VECTOR_ELT: 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break; 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::LOAD: Res = PromoteIntRes_LOAD(cast<LoadSDNode>(N));break; 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT: Res = PromoteIntRes_SELECT(N); break; 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::VSELECT: Res = PromoteIntRes_VSELECT(N); break; 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: Res = PromoteIntRes_SELECT_CC(N); break; 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: Res = PromoteIntRes_SETCC(N); break; 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: Res = PromoteIntRes_SHL(N); break; 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND_INREG: 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break; 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: Res = PromoteIntRes_SRA(N); break; 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: Res = PromoteIntRes_SRL(N); break; 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TRUNCATE: Res = PromoteIntRes_TRUNCATE(N); break; 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UNDEF: Res = PromoteIntRes_UNDEF(N); break; 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VAARG: Res = PromoteIntRes_VAARG(N); break; 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EXTRACT_SUBVECTOR: 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_EXTRACT_SUBVECTOR(N); break; 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::VECTOR_SHUFFLE: 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_VECTOR_SHUFFLE(N); break; 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::INSERT_VECTOR_ELT: 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_INSERT_VECTOR_ELT(N); break; 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::BUILD_VECTOR: 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_BUILD_VECTOR(N); break; 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SCALAR_TO_VECTOR: 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_SCALAR_TO_VECTOR(N); break; 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::CONCAT_VECTORS: 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_CONCAT_VECTORS(N); break; 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND: 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ZERO_EXTEND: 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ANY_EXTEND: Res = PromoteIntRes_INT_EXTEND(N); break; 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_SINT: 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_UINT: Res = PromoteIntRes_FP_TO_XINT(N); break; 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP32_TO_FP16:Res = PromoteIntRes_FP32_TO_FP16(N); break; 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AND: 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::OR: 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::XOR: 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADD: 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUB: 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MUL: Res = PromoteIntRes_SimpleIntBinOp(N); break; 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SDIV: 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SREM: Res = PromoteIntRes_SDIV(N); break; 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UDIV: 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UREM: Res = PromoteIntRes_UDIV(N); break; 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SADDO: 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SSUBO: Res = PromoteIntRes_SADDSUBO(N, ResNo); break; 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UADDO: 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::USUBO: Res = PromoteIntRes_UADDSUBO(N, ResNo); break; 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SMULO: 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break; 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD: 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntRes_Atomic0(cast<AtomicSDNode>(N)); break; 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_ADD: 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_SUB: 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_AND: 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_OR: 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_XOR: 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_NAND: 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_MIN: 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_MAX: 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_UMIN: 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_UMAX: 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_SWAP: 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntRes_Atomic1(cast<AtomicSDNode>(N)); break; 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_CMP_SWAP: 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntRes_Atomic2(cast<AtomicSDNode>(N)); break; 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the result is null then the sub-method took care of registering it. 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Res.getNode()) 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetPromotedInteger(SDValue(N, ResNo), Res); 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_MERGE_VALUES(SDNode *N, 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ResNo) { 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return GetPromotedInteger(Op); 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Sign-extend the new bits, and continue the assertion. 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = SExtPromotedInteger(N->getOperand(0)); 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::AssertSext, N->getDebugLoc(), 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getValueType(), Op, N->getOperand(1)); 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero the new bits, and continue the assertion. 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = ZExtPromotedInteger(N->getOperand(0)); 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::AssertZext, N->getDebugLoc(), 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getValueType(), Op, N->getOperand(1)); 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_Atomic0(AtomicSDNode *N) { 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ResVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getMemoryVT(), ResVT, 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getChain(), N->getBasePtr(), 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getMemOperand(), N->getOrdering(), 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getSynchScope()); 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Legalized the chain result - switch anything that used the old chain to 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // use the new one. 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Res; 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op2 = GetPromotedInteger(N->getOperand(2)); 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getMemoryVT(), 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getChain(), N->getBasePtr(), 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op2, N->getMemOperand(), N->getOrdering(), 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getSynchScope()); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalized the chain result - switch anything that used the old chain to 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) { 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op2 = GetPromotedInteger(N->getOperand(2)); 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op3 = GetPromotedInteger(N->getOperand(3)); 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getMemoryVT(), N->getChain(), N->getBasePtr(), 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op2, Op3, N->getMemOperand(), N->getOrdering(), 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getSynchScope()); 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalized the chain result - switch anything that used the old chain to 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_BITCAST(SDNode *N) { 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InOp = N->getOperand(0); 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT InVT = InOp.getValueType(); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NInVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT); 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OutVT = N->getValueType(0); 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (getTypeAction(InVT)) { 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(false && "Unknown type action!"); 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeLegal: 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypePromoteInteger: 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NOutVT.bitsEq(NInVT)) 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input promotes to the same size. Convert the promoted value. 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, NOutVT, GetPromotedInteger(InOp)); 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeSoftenFloat: 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote the integer operand by hand. 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp)); 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeExpandInteger: 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeExpandFloat: 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeScalarizeVector: 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert the element to an integer and promote it by hand. 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!NOutVT.isVector()) 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BitConvertToInteger(GetScalarizedVector(InOp))); 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeSplitVector: { 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For example, i32 = BITCAST v2i16 on alpha. Convert the split 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // pieces of the input into integers and reassemble in the final type. 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetSplitVector(N->getOperand(0), Lo, Hi); 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = BitConvertToInteger(Lo); 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = BitConvertToInteger(Hi); 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isBigEndian()) 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::swap(Lo, Hi); 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InOp = DAG.getNode(ISD::ANY_EXTEND, dl, 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT::getIntegerVT(*DAG.getContext(), 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NOutVT.getSizeInBits()), 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman JoinIntegers(Lo, Hi)); 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, NOutVT, InOp); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeWidenVector: 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OutVT.bitsEq(NInVT)) 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input is widened to the same size. Convert to the widened value. 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BITCAST, dl, OutVT, GetWidenedVector(InOp)); 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CreateStackStoreLoad(InOp, OutVT)); 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) { 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = N->getValueType(0); 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Op.getValueType(); 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op), 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(DiffBits, TLI.getPointerTy())); 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) { 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The pair element type may be legal, or may not promote to the same type as 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases. 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTypeToTransformTo(*DAG.getContext(), 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getValueType(0)), JoinIntegers(N->getOperand(0), 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1))); 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) { 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME there is no actual debug info here 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero extend things like i1, sign extend everything else. It shouldn't 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // matter in theory which one we pick, but this tends to give better code? 289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; 290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Result = DAG.getNode(Opc, dl, 291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTypeToTransformTo(*DAG.getContext(), VT), 292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(N, 0)); 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?"); 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_CONVERT_RNDSAT(SDNode *N) { 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU || 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU || 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) && 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "can only promote integers"); 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OutVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getConvertRndSat(OutVT, N->getDebugLoc(), N->getOperand(0), 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1), N->getOperand(2), 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(3), N->getOperand(4), CvtCode); 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) { 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero extend to the promoted type and do the count there. 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = ZExtPromotedInteger(N->getOperand(0)); 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = N->getValueType(0); 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Op.getValueType(); 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op = DAG.getNode(ISD::CTLZ, dl, NVT, Op); 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Subtract off the extra leading bits in the bigger type. 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SUB, dl, NVT, Op, 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVT.getSizeInBits() - 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OVT.getSizeInBits(), NVT)); 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) { 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero extend to the promoted type and do the count there. 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = ZExtPromotedInteger(N->getOperand(0)); 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op); 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = N->getValueType(0); 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Op.getValueType(); 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The count is the same in the promoted type except if the original 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // value was zero. This can be handled by setting the bit just off 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the top of the original type. 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt TopBit(NVT.getSizeInBits(), 0); 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TopBit.setBit(OVT.getSizeInBits()); 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT)); 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::CTTZ, dl, NVT, Op); 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0), 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1)); 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NewOpc = N->getOpcode(); 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we're promoting a UINT to a larger size and the larger FP_TO_UINT is 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // not Legal, check to see if we can use FP_TO_SINT instead. (If both UINT 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and SINT conversions are Custom, there is no way to tell which is 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // preferable. We choose SINT because that's the right thing on PPC.) 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::FP_TO_UINT && 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT)) 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOpc = ISD::FP_TO_SINT; 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0)); 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Assert that the converted value fits in the original type. If it doesn't 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // (eg: because the value being converted is too big), then the result of the 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // original operation was undefined anyway, so the assert is still correct. 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ? 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::AssertZext : ISD::AssertSext, dl, NVT, Res, 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getValueType(N->getValueType(0).getScalarType())); 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_FP32_TO_FP16(SDNode *N) { 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0)); 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::AssertZext, dl, 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NVT, Res, DAG.getValueType(N->getValueType(0))); 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (getTypeAction(N->getOperand(0).getValueType()) 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman == TargetLowering::TypePromoteInteger) { 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = GetPromotedInteger(N->getOperand(0)); 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Res.getValueType().bitsLE(NVT) && "Extension doesn't make sense!"); 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the result and operand types are the same after promotion, simplify 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to an in-register extension. 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NVT == Res.getValueType()) { 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high bits are not guaranteed to be anything. Insert an extend. 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::SIGN_EXTEND) 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res, 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getValueType(N->getOperand(0).getValueType())); 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::ZERO_EXTEND) 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getZeroExtendInReg(Res, dl, 40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(0).getValueType().getScalarType()); 402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!"); 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, just extend the original operand all the way to the larger type. 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0)); 409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) { 412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::LoadExtType ExtType = 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(), 41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getPointerInfo(), 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getMemoryVT(), N->isVolatile(), 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->isNonTemporal(), N->getAlignment()); 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalized the chain result - switch anything that used the old chain to 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Promote the overflow flag of an overflowing arithmetic node. 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) { 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Simply change the return type of the boolean result. 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(1)); 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ValueVTs[] = { N->getValueType(0), NVT }; 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[] = { N->getOperand(0), N->getOperand(1) }; 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(), 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getVTList(ValueVTs, 2), Ops, 2); 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Modified the sum result - switch anything that used the old sum to use 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the new one. 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 0), Res); 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(Res.getNode(), 1); 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) { 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ResNo == 1) 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return PromoteIntRes_Overflow(N); 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The operation overflowed iff the result in the larger type is not the 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sign extension of its truncation to the original type. 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = SExtPromotedInteger(N->getOperand(0)); 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = SExtPromotedInteger(N->getOperand(1)); 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = N->getOperand(0).getValueType(); 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = LHS.getValueType(); 454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do the arithmetic in the larger type. 457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB; 458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS); 459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Calculate the overflow flag: sign extend the arithmetic result from 461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the original type. 462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res, 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getValueType(OVT)); 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Overflowed if and only if this is not equal to Res. 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE); 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use the calculated overflow everywhere. 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Ofl); 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) { 474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Sign extend the input. 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = SExtPromotedInteger(N->getOperand(0)); 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = SExtPromotedInteger(N->getOperand(1)); 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(N->getOpcode(), N->getDebugLoc(), 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS.getValueType(), LHS, RHS); 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) { 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = GetPromotedInteger(N->getOperand(1)); 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = GetPromotedInteger(N->getOperand(2)); 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SELECT, N->getDebugLoc(), 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS.getValueType(), N->getOperand(0),LHS,RHS); 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_VSELECT(SDNode *N) { 48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Mask = GetPromotedInteger(N->getOperand(0)); 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue LHS = GetPromotedInteger(N->getOperand(1)); 49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue RHS = GetPromotedInteger(N->getOperand(2)); 49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::VSELECT, N->getDebugLoc(), 49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LHS.getValueType(), Mask, LHS, RHS); 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) { 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = GetPromotedInteger(N->getOperand(2)); 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = GetPromotedInteger(N->getOperand(3)); 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS.getValueType(), N->getOperand(0), 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1), LHS, RHS, N->getOperand(4)); 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType()); 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Only use the result of getSetCCResultType if it is legal, 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // otherwise just use the promoted result type (NVT). 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TLI.isTypeLegal(SVT)) 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SVT = NVT; 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(SVT.isVector() == N->getOperand(0).getValueType().isVector() && 51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Vector compare must return a vector result!"); 517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the SETCC result using the canonical SETCC type. 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue SetCC = DAG.getNode(N->getOpcode(), dl, SVT, N->getOperand(0), 520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1), N->getOperand(2)); 521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NVT.bitsLE(SVT) && "Integer type overpromoted?"); 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Convert to the expected type. 524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC); 525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) { 528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SHL, N->getDebugLoc(), 529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)), 530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetPromotedInteger(N->getOperand(0)), N->getOperand(1)); 531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) { 534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), 536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getValueType(), Op, N->getOperand(1)); 537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) { 540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input may have strange things in the top bits of the registers, but 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // these operations don't care. They may have weird bits going out, but 542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // that too is okay if they are integer operations. 543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = GetPromotedInteger(N->getOperand(0)); 544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = GetPromotedInteger(N->getOperand(1)); 545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(N->getOpcode(), N->getDebugLoc(), 546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS.getValueType(), LHS, RHS); 547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) { 550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input value must be properly sign extended. 551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = SExtPromotedInteger(N->getOperand(0)); 552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SRA, N->getDebugLoc(), 553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res.getValueType(), Res, N->getOperand(1)); 554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { 557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input value must be properly zero extended. 558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = ZExtPromotedInteger(N->getOperand(0)); 561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1)); 562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { 565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res; 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue InOp = N->getOperand(0); 56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (getTypeAction(InOp.getValueType())) { 571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown type action!"); 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeLegal: 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeExpandInteger: 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = InOp; 575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypePromoteInteger: 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = GetPromotedInteger(InOp); 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::TypeSplitVector: 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT InVT = InOp.getValueType(); 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(InVT.isVector() && "Cannot split scalar types"); 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElts = InVT.getVectorNumElements(); 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NumElts == NVT.getVectorNumElements() && 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Dst and Src must have the same number of elements"); 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT EltVT = InVT.getScalarType(); 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(isPowerOf2_32(NumElts) && 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Promoted vector type must be a power of two"); 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts/2); 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT HalfNVT = EVT::getVectorVT(*DAG.getContext(), NVT.getScalarType(), 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NumElts/2); 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue EOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfVT, InOp, 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(0)); 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue EOp2 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HalfVT, InOp, 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(NumElts/2)); 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EOp1 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp1); 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EOp2 = DAG.getNode(ISD::TRUNCATE, dl, HalfNVT, EOp2); 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, EOp1, EOp2); 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Truncate to NVT instead of VT 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res); 605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) { 608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ResNo == 1) 609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return PromoteIntRes_Overflow(N); 610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The operation overflowed iff the result in the larger type is not the 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // zero extension of its truncation to the original type. 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); 614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); 615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = N->getOperand(0).getValueType(); 616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = LHS.getValueType(); 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do the arithmetic in the larger type. 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB; 621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS); 622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Calculate the overflow flag: zero extend the arithmetic result from 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the original type. 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ofl = DAG.getZeroExtendInReg(Res, dl, OVT); 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Overflowed if and only if this is not equal to Res. 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE); 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use the calculated overflow everywhere. 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Ofl); 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_XMULO(SDNode *N, unsigned ResNo) { 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Promote the overflow bit trivially. 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ResNo == 1) 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return PromoteIntRes_Overflow(N); 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue LHS = N->getOperand(0), RHS = N->getOperand(1); 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc DL = N->getDebugLoc(); 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SmallVT = LHS.getValueType(); 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // To determine if the result overflowed in a larger type, we extend the 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // input to the larger type, do the multiply, then check the high bits of 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the result to see if the overflow happened. 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (N->getOpcode() == ISD::SMULO) { 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LHS = SExtPromotedInteger(LHS); 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RHS = SExtPromotedInteger(RHS); 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LHS = ZExtPromotedInteger(LHS); 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RHS = ZExtPromotedInteger(RHS); 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Mul = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS); 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Overflow occurred iff the high part of the result does not 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // zero/sign-extend the low part. 65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Overflow; 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (N->getOpcode() == ISD::UMULO) { 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Unsigned overflow occurred iff the high part is non-zero. 66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Hi = DAG.getNode(ISD::SRL, DL, Mul.getValueType(), Mul, 66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(SmallVT.getSizeInBits())); 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overflow = DAG.getSetCC(DL, N->getValueType(1), Hi, 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, Hi.getValueType()), ISD::SETNE); 66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Signed overflow occurred iff the high part does not sign extend the low. 66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue SExt = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, Mul.getValueType(), 66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Mul, DAG.getValueType(SmallVT)); 66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overflow = DAG.getSetCC(DL, N->getValueType(1), SExt, Mul, ISD::SETNE); 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Use the calculated overflow everywhere. 67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 1), Overflow); 67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Mul; 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) { 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero extend the input. 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(N->getOpcode(), N->getDebugLoc(), 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS.getValueType(), LHS, RHS); 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) { 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(), 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getValueType(0))); 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Chain = N->getOperand(0); // Get the chain. 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ptr = N->getOperand(1); // Get the pointer. 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT RegVT = TLI.getRegisterType(*DAG.getContext(), VT); 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumRegs = TLI.getNumRegisters(*DAG.getContext(), VT); 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The argument is passed as NumRegs registers of type RegVT. 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Parts(NumRegs); 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < NumRegs; ++i) { 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Parts[i] = DAG.getVAArg(RegVT, dl, Chain, Ptr, N->getOperand(2), 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getConstantOperandVal(3)); 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = Parts[i].getValue(1); 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Handle endianness of the load. 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isBigEndian()) 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::reverse(Parts.begin(), Parts.end()); 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Assemble the parts in the promoted type. 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]); 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 1; i < NumRegs; ++i) { 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]); 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Shift it to the right position and "or" it in. 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Part = DAG.getNode(ISD::SHL, dl, NVT, Part, 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(i * RegVT.getSizeInBits(), 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy())); 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part); 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Modified the chain result - switch anything that used the old chain to 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Chain); 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Res; 728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Integer Operand Promotion 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PromoteIntegerOperand - This method is called when the specified operand of 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the specified node is found to need promotion. At this point, all of the 736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// result types of the node are known to be legal, but other operands of the 737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// node may need promotion or expansion as well as the specified one. 738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { 739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "Promote integer operand: "; N->dump(&DAG); dbgs() << "\n"); 740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = SDValue(); 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman #ifndef NDEBUG 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "PromoteIntegerOperand Op #" << OpNo << ": "; 749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->dump(&DAG); dbgs() << "\n"; 750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman #endif 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Do not know how to promote this operator's operand!"); 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; 75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_STORE: 75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Res = PromoteIntOp_ATOMIC_STORE(cast<AtomicSDNode>(N)); 75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::BITCAST: Res = PromoteIntOp_BITCAST(N); break; 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; 761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; 76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::CONCAT_VECTORS: Res = PromoteIntOp_CONCAT_VECTORS(N); break; 76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EXTRACT_VECTOR_ELT: Res = PromoteIntOp_EXTRACT_VECTOR_ELT(N); break; 764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CONVERT_RNDSAT: 765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntOp_CONVERT_RNDSAT(N); break; 766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INSERT_VECTOR_ELT: 767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break; 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SCALAR_TO_VECTOR: 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break; 77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::VSELECT: 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; 774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; 775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N), 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpNo); break; 779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; 780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP16_TO_FP32: 781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTL: 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTR: Res = PromoteIntOp_Shift(N); break; 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the result is null, the sub-method took care of registering results etc. 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Res.getNode()) return false; 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the result is N, the sub-method updated N in place. Tell the legalizer 795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // core about this. 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Res.getNode() == N) 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Invalid operand expansion"); 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 0), Res); 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PromoteSetCCOperands - Promote the operands of a comparison. This code is 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// shared among BR_CC, SELECT_CC, and SETCC handlers. 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode) { 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We have to insert explicit sign or zero extends. Note that we could 811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // insert sign extends for ALL conditions, but zero extend is cheaper on 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // many machines (an AND instead of two shifts), so prefer it. 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (CCCode) { 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown integer comparison!"); 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETEQ: 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETNE: 817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGE: 818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGT: 819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULE: 820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULT: 821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ALL of these operations will work if we either sign or zero extend 822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the operands (including the unsigned comparisons!). Zero extend is 823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // usually a simpler/cheaper operation, so prefer it. 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = ZExtPromotedInteger(NewLHS); 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = ZExtPromotedInteger(NewRHS); 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETGE: 828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETGT: 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETLT: 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETLE: 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = SExtPromotedInteger(NewLHS); 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = SExtPromotedInteger(NewRHS); 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) { 838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op); 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N) { 84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op2 = GetPromotedInteger(N->getOperand(2)); 84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), N->getMemoryVT(), 84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getChain(), N->getBasePtr(), Op2, N->getMemOperand(), 84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOrdering(), N->getSynchScope()); 84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_BITCAST(SDNode *N) { 850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This should only occur in unusual situations like bitcasting to an 851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // x86_fp80, so just turn it into a store+load 852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); 853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) { 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OpNo == 2 && "Don't know how to promote this operand!"); 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = N->getOperand(2); 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = N->getOperand(3); 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get()); 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // legal types. 864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), 865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1), LHS, RHS, N->getOperand(4)), 866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 0); 867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) { 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OpNo == 1 && "only know how to promote condition"); 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote all the way up to the canonical SetCC type. 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT SVT = TLI.getSetCCResultType(MVT::Other); 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Cond = PromoteTargetBoolean(N->getOperand(1), SVT); 875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The chain (Op#0) and basic block destination (Op#2) are always legal types. 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Cond, 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(2)), 0); 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) { 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Since the result type is legal, the operands must promote to it. 883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = N->getOperand(0).getValueType(); 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = ZExtPromotedInteger(N->getOperand(0)); 885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = GetPromotedInteger(N->getOperand(1)); 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?"); 887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi, 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy())); 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi); 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The vector type is legal but the element type is not. This implies 896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // that the vector is a power-of-two in length and that the element 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // type does not have a strange size (eg: it is not i1). 898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VecVT = N->getValueType(0); 899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumElts = VecVT.getVectorNumElements(); 900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!(NumElts & 1) && "Legal vector of one illegal element?"); 901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote the inserted value. The type does not need to match the 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // vector element type. Check that any extra bits introduced will be 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // truncated away. 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(N->getOperand(0).getValueType().getSizeInBits() >= 906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getValueType(0).getVectorElementType().getSizeInBits() && 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Type of inserted value narrower than vector element type!"); 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 16> NewOps; 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < NumElts; ++i) 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOps.push_back(GetPromotedInteger(N->getOperand(i))); 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, &NewOps[0], NumElts), 0); 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) { 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode(); 918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU || 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU || 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CvtCode == ISD::CVT_FS || CvtCode == ISD::CVT_FU) && 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "can only promote integer arguments"); 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InOp = GetPromotedInteger(N->getOperand(0)); 923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getConvertRndSat(N->getValueType(0), N->getDebugLoc(), InOp, 924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1), N->getOperand(2), 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(3), N->getOperand(4), CvtCode); 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, 929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned OpNo) { 930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpNo == 1) { 931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote the inserted value. This is valid because the type does not 932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // have to match the vector element type. 933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check that any extra bits introduced will be truncated away. 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(N->getOperand(1).getValueType().getSizeInBits() >= 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getValueType(0).getVectorElementType().getSizeInBits() && 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Type of inserted value narrower than vector element type!"); 938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), 939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetPromotedInteger(N->getOperand(1)), 940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(2)), 941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 0); 942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OpNo == 2 && "Different operand and result vector types?"); 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote the index. 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Idx = ZExtPromotedInteger(N->getOperand(2)); 948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1), Idx), 0); 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) { 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue NewOps[6]; 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOps[0] = N->getOperand(0); 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 1; i < array_lengthof(NewOps); ++i) { 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Flag = GetPromotedInteger(N->getOperand(i)); 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOps[i] = DAG.getZeroExtendInReg(Flag, dl, MVT::i1); 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, NewOps, array_lengthof(NewOps)), 0); 961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) { 964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Integer SCALAR_TO_VECTOR operands are implicitly truncated, so just promote 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the operand in place. 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetPromotedInteger(N->getOperand(0))), 0); 968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { 97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(OpNo == 0 && "Only know how to promote the condition!"); 97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Cond = N->getOperand(0); 97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OpTy = N->getOperand(1).getValueType(); 974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote all the way up to the canonical SetCC type. 97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SVT = TLI.getSetCCResultType(N->getOpcode() == ISD::SELECT ? 97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OpTy.getScalarType() : OpTy); 97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Cond = PromoteTargetBoolean(Cond, SVT); 979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1), 98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(2)), 0); 982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) { 985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OpNo == 0 && "Don't know how to promote this operand!"); 986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = N->getOperand(0); 988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = N->getOperand(1); 989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(4))->get()); 990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The CC (#4) and the possible return values (#2 and #3) have legal types. 992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2), 993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(3), N->getOperand(4)), 0); 994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) { 997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OpNo == 0 && "Don't know how to promote this operand!"); 998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = N->getOperand(0); 1000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = N->getOperand(1); 1001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get()); 1002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The CC (#2) is always legal. 1004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS, N->getOperand(2)), 0); 1005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) { 1008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), 1009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ZExtPromotedInteger(N->getOperand(1))), 0); 1010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) { 1013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 1014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op); 1016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(), 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op, DAG.getValueType(N->getOperand(0).getValueType())); 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_SINT_TO_FP(SDNode *N) { 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SExtPromotedInteger(N->getOperand(0))), 0); 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){ 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ch = N->getChain(), Ptr = N->getBasePtr(); 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = N->getAlignment(); 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isVolatile = N->isVolatile(); 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isNonTemporal = N->isNonTemporal(); 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value. 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Truncate the value and store the result. 103619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getPointerInfo(), 103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getMemoryVT(), 1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, Alignment); 1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) { 1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op); 1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) { 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ZExtPromotedInteger(N->getOperand(0))), 0); 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) { 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = GetPromotedInteger(N->getOperand(0)); 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op); 105519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getZeroExtendInReg(Op, dl, 105619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(0).getValueType().getScalarType()); 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Integer Result Expansion 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandIntegerResult - This method is called when the specified result of the 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// specified node is found to need expansion. At this point, the node may also 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// have invalid operands or may have other results that need promotion, we just 1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// know that (at least) one result needs expansion. 1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "Expand integer result: "; N->dump(&DAG); dbgs() << "\n"); 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = Hi = SDValue(); 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // See if the target wants to custom expand this node. 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CustomLowerNode(N, N->getValueType(ResNo), true)) 1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "ExpandIntegerResult #" << ResNo << ": "; 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->dump(&DAG); dbgs() << "\n"; 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Do not know how to expand the result of this operator!"); 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 108519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break; 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break; 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AssertSext: ExpandIntRes_AssertSext(N, Lo, Hi); break; 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break; 1099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BSWAP: ExpandIntRes_BSWAP(N, Lo, Hi); break; 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break; 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break; 1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break; 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break; 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break; 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break; 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::LOAD: ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break; 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break; 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break; 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break; 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break; 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break; 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break; 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UDIV: ExpandIntRes_UDIV(N, Lo, Hi); break; 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break; 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break; 111619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD: ExpandIntRes_ATOMIC_LOAD(N, Lo, Hi); break; 111719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 111819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_ADD: 111919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_SUB: 112019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_AND: 112119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_OR: 112219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_XOR: 112319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_NAND: 112419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_MIN: 112519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_MAX: 112619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_UMIN: 112719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_UMAX: 112819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_SWAP: { 112919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<SDValue, SDValue> Tmp = ExpandAtomic(N); 113019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SplitInteger(Tmp.first, Lo, Hi); 113119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 1), Tmp.second); 113219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 113319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AND: 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::OR: 1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::XOR: ExpandIntRes_Logical(N, Lo, Hi); break; 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADD: 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break; 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADDC: 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break; 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADDE: 1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break; 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: 1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: ExpandIntRes_Shift(N, Lo, Hi); break; 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SADDO: 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SSUBO: ExpandIntRes_SADDSUBO(N, Lo, Hi); break; 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UADDO: 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::USUBO: ExpandIntRes_UADDSUBO(N, Lo, Hi); break; 115619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::UMULO: 115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SMULO: ExpandIntRes_XMULO(N, Lo, Hi); break; 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If Lo/Hi is null, the sub-method took care of registering results etc. 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Lo.getNode()) 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SetExpandedInteger(SDValue(N, ResNo), Lo, Hi); 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Lower an atomic node to the appropriate builtin call. 116619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstd::pair <SDValue, SDValue> DAGTypeLegalizer::ExpandAtomic(SDNode *Node) { 116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Opc = Node->getOpcode(); 116819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT(); 116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RTLIB::Libcall LC; 117019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 117119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (Opc) { 117219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 117319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm_unreachable("Unhandled atomic intrinsic Expand!"); 117419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 117519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_SWAP: 117619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 117719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 117819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break; 117919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break; 118019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break; 118119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break; 118219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 118319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 118419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_CMP_SWAP: 118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break; 118819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break; 118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break; 119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break; 119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 119219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 119319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_ADD: 119419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 119519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_ADD_1; break; 119719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break; 119819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break; 119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break; 120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 120119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 120219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_SUB: 120319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 120519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_SUB_1; break; 120619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break; 120719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break; 120819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break; 120919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 121019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 121119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_AND: 121219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 121319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_AND_1; break; 121519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break; 121619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break; 121719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break; 121819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 121919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 122019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_OR: 122119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 122319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_OR_1; break; 122419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break; 122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break; 122619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break; 122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_XOR: 123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_XOR_1; break; 123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break; 123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break; 123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break; 123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD_NAND: 123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (VT.SimpleTy) { 124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_NAND_1; break; 124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break; 124319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break; 124419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break; 124519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 124619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 124719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 124819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 124919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ExpandChainLibCall(LC, Node, false); 125019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded, 1253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// and the shift amount is a constant 'Amt'. Expand the operation. 1254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, 1255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 125619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc DL = N->getDebugLoc(); 1257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the incoming operand to be shifted, so that we have its parts 1258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InL, InH; 1259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), InL, InH); 1260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = InL.getValueType(); 1262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned VTBits = N->getValueType(0).getSizeInBits(); 1263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NVTBits = NVT.getSizeInBits(); 1264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ShTy = N->getOperand(1).getValueType(); 1265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::SHL) { 1267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Amt > VTBits) { 1268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = Hi = DAG.getConstant(0, NVT); 1269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt > NVTBits) { 1270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getConstant(0, NVT); 127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SHL, DL, 127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NVT, InL, DAG.getConstant(Amt-NVTBits, ShTy)); 1273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt == NVTBits) { 1274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getConstant(0, NVT); 1275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = InL; 1276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt == 1 && 1277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.isOperationLegalOrCustom(ISD::ADDC, 1278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTypeToExpandTo(*DAG.getContext(), NVT))) { 1279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit this X << 1 as X+X. 128019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDVTList VTList = DAG.getVTList(NVT, MVT::Glue); 1281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoOps[2] = { InL, InL }; 128219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::ADDC, DL, VTList, LoOps, 2); 1283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiOps[3] = { InH, InH, Lo.getValue(1) }; 128419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::ADDE, DL, VTList, HiOps, 3); 1285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 128619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::SHL, DL, NVT, InL, DAG.getConstant(Amt, ShTy)); 128719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::OR, DL, NVT, 128819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SHL, DL, NVT, InH, 1289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(Amt, ShTy)), 129019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, DL, NVT, InL, 1291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-Amt, ShTy))); 1292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::SRL) { 1297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Amt > VTBits) { 1298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getConstant(0, NVT); 1299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt > NVTBits) { 130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::SRL, DL, 1302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); 1303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt == NVTBits) { 1305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = InH; 1306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 130819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::OR, DL, NVT, 130919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, DL, NVT, InL, 1310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(Amt, ShTy)), 131119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SHL, DL, NVT, InH, 1312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-Amt, ShTy))); 131319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SRL, DL, NVT, InH, DAG.getConstant(Amt, ShTy)); 1314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); 1319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Amt > VTBits) { 132019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = Lo = DAG.getNode(ISD::SRA, DL, NVT, InH, 1321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-1, ShTy)); 1322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt > NVTBits) { 132319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::SRA, DL, NVT, InH, 1324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(Amt-NVTBits, ShTy)); 132519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, 1326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-1, ShTy)); 1327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Amt == NVTBits) { 1328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = InH; 132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, 1330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-1, ShTy)); 1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 133219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::OR, DL, NVT, 133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, DL, NVT, InL, 1334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(Amt, ShTy)), 133519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SHL, DL, NVT, InH, 1336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-Amt, ShTy))); 133719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SRA, DL, NVT, InH, DAG.getConstant(Amt, ShTy)); 1338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify 1342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// this shift based on knowledge of the high bit of the shift amount. If we 1343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// can tell this, we know that it is >= 32 or < 32, without knowing the actual 1344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// shift amount. 1345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool DAGTypeLegalizer:: 1346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { 1347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Amt = N->getOperand(1); 1348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 1349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ShTy = Amt.getValueType(); 1350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ShBits = ShTy.getScalarType().getSizeInBits(); 1351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NVTBits = NVT.getScalarType().getSizeInBits(); 1352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(isPowerOf2_32(NVTBits) && 1353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Expanded integer type size not a power of two!"); 1354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits)); 1357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt KnownZero, KnownOne; 1358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne); 1359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we don't know anything about the high bits, exit. 1361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (((KnownZero|KnownOne) & HighBitMask) == 0) 1362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the incoming operand to be shifted. 1365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InL, InH; 1366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), InL, InH); 1367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we know that any of the high bits of the shift amount are one, then we 1369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // can do this as a couple of simple shifts. 1370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (KnownOne.intersects(HighBitMask)) { 1371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Mask out the high bit, which we know is set. 1372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt, 1373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(~HighBitMask, ShTy)); 1374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 1376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown shift"); 1377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 1378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getConstant(0, NVT); // Low part is zero. 1379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part. 1380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 1382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); // Hi part is zero. 1383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part. 1384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: 1386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part. 1387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-1, ShTy)); 1388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part. 1389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#if 0 1394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: This code is broken for shifts with a zero amount! 1395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we know that all of the high bits of the shift amount are zero, then we 1396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // can do this as a couple of simple shifts. 1397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((KnownZero & HighBitMask) == HighBitMask) { 1398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Compute 32-amt. 1399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Amt2 = DAG.getNode(ISD::SUB, ShTy, 1400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits, ShTy), 1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Amt); 1402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Op1, Op2; 1403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 1404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown shift"); 1405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: Op1 = ISD::SHL; Op2 = ISD::SRL; break; 1406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 1407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: Op1 = ISD::SRL; Op2 = ISD::SHL; break; 1408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt); 1411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::OR, NVT, 1412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Op1, NVT, InH, Amt), 1413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(Op2, NVT, InL, Amt2)); 1414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 1417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandShiftWithUnknownAmountBit - Fully general expansion of integer shift 1422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// of any size. 1423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool DAGTypeLegalizer:: 1424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanExpandShiftWithUnknownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { 1425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Amt = N->getOperand(1); 1426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 1427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ShTy = Amt.getValueType(); 1428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NVTBits = NVT.getSizeInBits(); 1429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(isPowerOf2_32(NVTBits) && 1430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Expanded integer type size not a power of two!"); 1431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the incoming operand to be shifted. 1434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InL, InH; 1435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), InL, InH); 1436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue NVBitsNode = DAG.getConstant(NVTBits, ShTy); 1438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue AmtExcess = DAG.getNode(ISD::SUB, dl, ShTy, Amt, NVBitsNode); 1439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue AmtLack = DAG.getNode(ISD::SUB, dl, ShTy, NVBitsNode, Amt); 1440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue isShort = DAG.getSetCC(dl, TLI.getSetCCResultType(ShTy), 1441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Amt, NVBitsNode, ISD::SETULT); 1442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoS, HiS, LoL, HiL; 1444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 1445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown shift"); 1446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 1447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Short: ShAmt < NVTBits 1448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoS = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); 1449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiS = DAG.getNode(ISD::OR, dl, NVT, 1450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SHL, dl, NVT, InH, Amt), 1451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: If Amt is zero, the following shift generates an undefined result 1452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // on some architectures. 1453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, NVT, InL, AmtLack)); 1454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Long: ShAmt >= NVTBits 1456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoL = DAG.getConstant(0, NVT); // Lo part is zero. 1457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiL = DAG.getNode(ISD::SHL, dl, NVT, InL, AmtExcess); // Hi from Lo part. 1458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL); 1460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL); 1461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 1463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Short: ShAmt < NVTBits 1464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiS = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); 1465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoS = DAG.getNode(ISD::OR, dl, NVT, 1466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, NVT, InL, Amt), 1467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: If Amt is zero, the following shift generates an undefined result 1468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // on some architectures. 1469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack)); 1470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Long: ShAmt >= NVTBits 1472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiL = DAG.getConstant(0, NVT); // Hi part is zero. 1473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoL = DAG.getNode(ISD::SRL, dl, NVT, InH, AmtExcess); // Lo from Hi part. 1474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL); 1476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL); 1477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: 1479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Short: ShAmt < NVTBits 1480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiS = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); 1481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoS = DAG.getNode(ISD::OR, dl, NVT, 1482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, NVT, InL, Amt), 1483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: If Amt is zero, the following shift generates an undefined result 1484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // on some architectures. 1485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SHL, dl, NVT, InH, AmtLack)); 1486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Long: ShAmt >= NVTBits 1488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiL = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign of Hi part. 1489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-1, ShTy)); 1490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoL = DAG.getNode(ISD::SRA, dl, NVT, InH, AmtExcess); // Lo from Hi part. 1491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SELECT, dl, NVT, isShort, LoS, LoL); 1493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SELECT, dl, NVT, isShort, HiS, HiL); 1494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 1495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 1498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, 1501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the subcomponents. 1504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSL, LHSH, RHSL, RHSH; 1505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 1506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(1), RHSL, RHSH); 1507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = LHSL.getValueType(); 1509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoOps[2] = { LHSL, RHSL }; 1510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiOps[3] = { LHSH, RHSH }; 1511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do not generate ADDC/ADDE or SUBC/SUBE if the target does not support 1513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // them. TODO: Teach operation legalization how to expand unsupported 1514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ADDC/ADDE/SUBC/SUBE. The problem is that these operations generate 151519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // a carry of type MVT::Glue, but there doesn't seem to be any way to 1516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // generate a value of this type in the expanded code sequence. 1517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool hasCarry = 1518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ? 1519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::ADDC : ISD::SUBC, 1520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTypeToExpandTo(*DAG.getContext(), NVT)); 1521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (hasCarry) { 152319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDVTList VTList = DAG.getVTList(NVT, MVT::Glue); 1524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::ADD) { 1525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); 1526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiOps[2] = Lo.getValue(1); 1527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); 1528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); 1530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiOps[2] = Lo.getValue(1); 1531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); 1532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 153319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 153419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 153519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 153619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (N->getOpcode() == ISD::ADD) { 153719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2); 153819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2); 153919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0], 154019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::SETULT); 154119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1, 154219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, NVT), 154319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, NVT)); 154419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1], 154519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::SETULT); 154619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2, 154719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, NVT), Carry1); 154819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2); 1549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 155019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2); 155119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2); 155219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Cmp = 155319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getSetCC(dl, TLI.getSetCCResultType(LoOps[0].getValueType()), 155419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoOps[0], LoOps[1], ISD::SETULT); 155519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, 155619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, NVT), 155719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, NVT)); 155819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow); 1559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N, 1563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the subcomponents. 1565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSL, LHSH, RHSL, RHSH; 1566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 1568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(1), RHSL, RHSH); 156919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue); 1570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoOps[2] = { LHSL, RHSL }; 1571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiOps[3] = { LHSH, RHSH }; 1572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::ADDC) { 1574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); 1575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiOps[2] = Lo.getValue(1); 1576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); 1577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); 1579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiOps[2] = Lo.getValue(1); 1580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); 1581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalized the flag result - switch anything that used the old flag to 1584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 1585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); 1586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, 1589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the subcomponents. 1591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSL, LHSH, RHSL, RHSH; 1592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 1594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(1), RHSL, RHSH); 159519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Glue); 1596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; 1597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiOps[3] = { LHSH, RHSH }; 1598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3); 1600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiOps[2] = Lo.getValue(1); 1601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3); 1602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalized the flag result - switch anything that used the old flag to 1604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 1605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); 1606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 160819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N, unsigned ResNo, 160919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue &Lo, SDValue &Hi) { 161019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Res = DisintegrateMERGE_VALUES(N, ResNo); 161119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SplitInteger(Res, Lo, Hi); 161219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 161319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, 1615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 1617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 1619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op.getValueType().bitsLE(NVT)) { 1620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The low part is any extension of the input (which degenerates to a copy). 1621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op); 1622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getUNDEF(NVT); // The high part is undefined. 1623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For example, extension of an i48 to an i64. The operand type necessarily 1625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // promotes to the result type, so will end up being expanded too. 162619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(getTypeAction(Op.getValueType()) == 162719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::TypePromoteInteger && 1628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Only know how to promote this result!"); 1629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = GetPromotedInteger(Op); 1630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Res.getValueType() == N->getValueType(0) && 1631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Operand over promoted?"); 1632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Split the promoted operand. This will simplify when it is expanded. 1633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(Res, Lo, Hi); 1634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N, 1638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 1641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Lo.getValueType(); 1642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 1643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NVTBits = NVT.getSizeInBits(); 1644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EVTBits = EVT.getSizeInBits(); 1645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NVTBits < EVTBits) { 1647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi, 1648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), 1649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVTBits - NVTBits))); 1650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT)); 1652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part replicates the sign bit of Lo, make it explicit. 1653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, 1654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVTBits-1, TLI.getPointerTy())); 1655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N, 1659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 1662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Lo.getValueType(); 1663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 1664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NVTBits = NVT.getSizeInBits(); 1665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EVTBits = EVT.getSizeInBits(); 1666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NVTBits < EVTBits) { 1668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi, 1669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), 1670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVTBits - NVTBits))); 1671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT)); 1673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part must be zero, make it explicit. 1674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N, 1679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands. 1682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo); 1683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi); 1684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N, 1687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 1689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NBitWidth = NVT.getSizeInBits(); 1690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue(); 169119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getConstant(Cst.trunc(NBitWidth), NVT); 1692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT); 1693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N, 1696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32) 1699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 1700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Lo.getValueType(); 1701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi, 1703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0, NVT), ISD::SETNE); 1704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo); 1706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi); 1707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ, 1709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::ADD, dl, NVT, LoLZ, 1710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVT.getSizeInBits(), NVT))); 1711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N, 1715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo) 1718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 1719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Lo.getValueType(); 1720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, dl, NVT, Lo), 1721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::CTPOP, dl, NVT, Hi)); 1722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N, 1726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32) 1729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 1730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Lo.getValueType(); 1731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, 1733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0, NVT), ISD::SETNE); 1734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo); 1736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi); 1737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ, 1739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::ADD, dl, NVT, HiLZ, 1740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVT.getSizeInBits(), NVT))); 1741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo, 1745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Hi) { 1746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 1748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 1749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT); 1750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!"); 1751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi); 1752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo, 1755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Hi) { 1756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 1758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 1759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT); 1760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!"); 1761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi); 1762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, 1765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ISD::isNormalLoad(N)) { 1767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExpandRes_NormalLoad(N, Lo, Hi); 1768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 1772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 1774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 1775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ch = N->getChain(); 1776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ptr = N->getBasePtr(); 1777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::LoadExtType ExtType = N->getExtensionType(); 1778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = N->getAlignment(); 1779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isVolatile = N->isVolatile(); 1780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isNonTemporal = N->isNonTemporal(); 1781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getMemoryVT().bitsLE(NVT)) { 1786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT MemVT = N->getMemoryVT(); 1787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 178819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(), 1789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemVT, isVolatile, isNonTemporal, Alignment); 1790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Remember the chain. 1792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ch = Lo.getValue(1); 1793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ExtType == ISD::SEXTLOAD) { 1795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part is obtained by SRA'ing all but one of the bits of the 1796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lo part. 1797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned LoSize = Lo.getValueType().getSizeInBits(); 1798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, 1799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(LoSize-1, TLI.getPointerTy())); 1800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (ExtType == ISD::ZEXTLOAD) { 1801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part is just a zero. 1802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); 1803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ExtType == ISD::EXTLOAD && "Unknown extload!"); 1805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part is undefined. 1806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getUNDEF(NVT); 1807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (TLI.isLittleEndian()) { 1809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Little-endian - low bits are at low addresses. 181019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getPointerInfo(), 1811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, Alignment); 1812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExcessBits = 1814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits(); 1815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits); 1816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Increment the pointer to the other half. 1818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned IncrementSize = NVT.getSizeInBits()/8; 1819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 1820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(IncrementSize)); 182119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, 182219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getPointerInfo().getWithOffset(IncrementSize), NEVT, 1823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, 1824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MinAlign(Alignment, IncrementSize)); 1825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Build a factor node to remember that this load is independent of the 1827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // other one. 1828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi.getValue(1)); 1830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Big-endian - high bits are at low addresses. Favor aligned loads at 1832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the cost of some bit-fiddling. 1833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT MemVT = N->getMemoryVT(); 1834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EBytes = MemVT.getStoreSize(); 1835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned IncrementSize = NVT.getSizeInBits()/8; 1836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExcessBits = (EBytes - IncrementSize)*8; 1837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load both the high bits and maybe some of the low bits. 183919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getPointerInfo(), 1840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT::getIntegerVT(*DAG.getContext(), 1841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MemVT.getSizeInBits() - ExcessBits), 1842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, Alignment); 1843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Increment the pointer to the other half. 1845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 1846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(IncrementSize)); 1847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load the rest of the low bits. 184819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, 184919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getPointerInfo().getWithOffset(IncrementSize), 1850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT::getIntegerVT(*DAG.getContext(), ExcessBits), 1851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, 1852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MinAlign(Alignment, IncrementSize)); 1853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Build a factor node to remember that this load is independent of the 1855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // other one. 1856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi.getValue(1)); 1858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ExcessBits < NVT.getSizeInBits()) { 1860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Transfer low bits from the bottom of Hi to the top of Lo. 1861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::OR, dl, NVT, Lo, 1862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SHL, dl, NVT, Hi, 1863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(ExcessBits, 1864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy()))); 1865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Move high bits to the right position in Hi. 1866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, 1867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NVT, Hi, 1868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVT.getSizeInBits() - ExcessBits, 1869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy())); 1870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalized the chain result - switch anything that used the old chain to 1874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // use the new one. 1875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Ch); 1876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N, 1879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LL, LH, RL, RH; 1882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), LL, LH); 1883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(1), RL, RH); 1884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL); 1885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH); 1886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, 1889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 1891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 1892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 1893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT); 1895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT); 1896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT); 1897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT); 1898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { 1899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LL, LH, RL, RH; 1900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), LL, LH); 1901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(1), RL, RH); 1902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned OuterBitSize = VT.getSizeInBits(); 1903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned InnerBitSize = NVT.getSizeInBits(); 1904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0)); 1905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1)); 1906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize); 1908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) && 1909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) { 1910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The inputs are both zero-extended. 1911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasUMUL_LOHI) { 1912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We can emit a umul_lohi. 1913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); 1914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = SDValue(Lo.getNode(), 1); 1915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasMULHU) { 1918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We can emit a mulhu+mul. 1919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); 1920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); 1921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) { 1925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input values are both sign-extended. 1926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasSMUL_LOHI) { 1927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We can emit a smul_lohi. 1928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); 1929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = SDValue(Lo.getNode(), 1); 1930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasMULHS) { 1933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We can emit a mulhs+mul. 1934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); 1935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL); 1936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasUMUL_LOHI) { 1940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Lo,Hi = umul LHS, RHS. 1941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl, 1942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getVTList(NVT, NVT), LL, RL); 1943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = UMulLOHI; 1944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = UMulLOHI.getValue(1); 1945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); 1946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); 1947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); 1948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); 1949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasMULHU) { 1952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); 1953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); 1954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); 1955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); 1956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); 1957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); 1958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 1959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If nothing else, we can make a libcall. 1963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 1965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::MUL_I16; 1966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 1967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::MUL_I32; 1968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 1969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::MUL_I64; 1970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 1971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::MUL_I128; 1972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!"); 1973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi); 1976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_SADDSUBO(SDNode *Node, 1979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 1980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = Node->getOperand(0); 1981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = Node->getOperand(1); 1982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 1983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the result by simply replacing it with the equivalent 1985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // non-overflow-checking operation. 1986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ? 1987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 1988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS, RHS); 1989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(Sum, Lo, Hi); 1990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Compute the overflow. 1992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // LHSSign -> LHS >= 0 1994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // RHSSign -> RHS >= 0 1995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SumSign -> Sum >= 0 1996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add: 1998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign) 1999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Sub: 2000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign) 2001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 2002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OType = Node->getValueType(1); 2003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, LHS.getValueType()); 2004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE); 2006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE); 2007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign, 2008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::SADDO ? 2009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETEQ : ISD::SETNE); 2010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE); 2012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE); 2013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE); 2015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use the calculated overflow everywhere. 2017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(Node, 1), Cmp); 2018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N, 2021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 2023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SDIV_I16; 2028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SDIV_I32; 2030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SDIV_I64; 2032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SDIV_I128; 2034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!"); 2035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 2037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi); 2038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, 2041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 2043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we can emit an efficient shift operation, do so now. Check to see if 2046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the RHS is a constant. 2047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1))) 2048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandShiftByConstant(N, CN->getZExtValue(), Lo, Hi); 2049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we can determine that the high bit of the shift is zero or one, even if 2051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the low bits are variable, emit this shift in an optimized form. 2052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ExpandShiftWithKnownAmountBit(N, Lo, Hi)) 2053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this target supports shift_PARTS, use it. First, map to the _PARTS opc. 2056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned PartsOpc; 2057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::SHL) { 2058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PartsOpc = ISD::SHL_PARTS; 2059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (N->getOpcode() == ISD::SRL) { 2060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PartsOpc = ISD::SRL_PARTS; 2061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); 2063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PartsOpc = ISD::SRA_PARTS; 2064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Next check to see if the target supports this SHL_PARTS operation or if it 2067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // will custom expand it. 2068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 2069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT); 2070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || 2071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action == TargetLowering::Custom) { 2072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the subcomponents. 2073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSL, LHSH; 2074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), LHSL, LHSH); 2075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) }; 2077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = LHSL.getValueType(); 2078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(PartsOpc, dl, DAG.getVTList(VT, VT), Ops, 3); 2079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = Lo.getValue(1); 2080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, emit a libcall. 2084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned; 2086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getOpcode() == ISD::SHL) { 2087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isSigned = false; /*sign irrelevant*/ 2088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SHL_I16; 2090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SHL_I32; 2092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SHL_I64; 2094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SHL_I128; 2096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (N->getOpcode() == ISD::SRL) { 2097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isSigned = false; 2098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRL_I16; 2100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRL_I32; 2102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRL_I64; 2104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRL_I128; 2106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); 2108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isSigned = true; 2109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRA_I16; 2111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRA_I32; 2113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRA_I64; 2115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SRA_I128; 2117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LC != RTLIB::UNKNOWN_LIBCALL && TLI.getLibcallName(LC)) { 2120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 2121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi); 2122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ExpandShiftWithUnknownAmountBit(N, Lo, Hi)) 2126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Unsupported shift!"); 2127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, 2130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 2134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op.getValueType().bitsLE(NVT)) { 2135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The low part is sign extension of the input (degenerates to a copy). 2136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0)); 2137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part is obtained by SRA'ing all but one of the bits of low part. 2138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned LoSize = NVT.getSizeInBits(); 2139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, 2140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(LoSize-1, TLI.getPointerTy())); 2141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For example, extension of an i48 to an i64. The operand type necessarily 2143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // promotes to the result type, so will end up being expanded too. 214419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(getTypeAction(Op.getValueType()) == 214519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::TypePromoteInteger && 2146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Only know how to promote this result!"); 2147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = GetPromotedInteger(Op); 2148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Res.getValueType() == N->getValueType(0) && 2149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Operand over promoted?"); 2150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Split the promoted operand. This will simplify when it is expanded. 2151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(Res, Lo, Hi); 2152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExcessBits = 2153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getValueType().getSizeInBits() - NVT.getSizeInBits(); 2154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi, 2155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), 2156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExcessBits))); 2157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer:: 2161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) { 2162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 2164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT(); 2165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (EVT.bitsLE(Lo.getValueType())) { 2167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sext_inreg the low part if needed. 2168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo, 2169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(1)); 2170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The high part gets the sign extension from the lo-part. This handles 2172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // things like sextinreg V:i64 from i8. 2173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo, 2174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(Hi.getValueType().getSizeInBits()-1, 2175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy())); 2176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For example, extension of an i48 to an i64. Leave the low part alone, 2178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sext_inreg the high part. 2179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExcessBits = 2180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT.getSizeInBits() - Lo.getValueType().getSizeInBits(); 2181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi, 2182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getValueType(EVT::getIntegerVT(*DAG.getContext(), 2183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExcessBits))); 2184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, 2188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 2190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SREM_I16; 2195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SREM_I32; 2197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SREM_I64; 2199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::SREM_I128; 2201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!"); 2202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 2204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi); 2205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, 2208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0)); 2212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRL, dl, 2213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(0).getValueType(), N->getOperand(0), 2214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy())); 2215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi); 2216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N, 2219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = N->getOperand(0); 2221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = N->getOperand(1); 2222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand the result by simply replacing it with the equivalent 2225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // non-overflow-checking operation. 2226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum = DAG.getNode(N->getOpcode() == ISD::UADDO ? 2227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 2228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS, RHS); 2229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(Sum, Lo, Hi); 2230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Calculate the overflow: addition overflows iff a + b < a, and subtraction 2232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // overflows iff a - b > a. 2233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Sum, LHS, 2234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOpcode () == ISD::UADDO ? 2235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETULT : ISD::SETUGT); 2236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Use the calculated overflow everywhere. 2238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 1), Ofl); 2239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 224119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N, 224219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue &Lo, SDValue &Hi) { 224319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VT = N->getValueType(0); 224419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *RetTy = VT.getTypeForEVT(*DAG.getContext()); 224519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT PtrVT = TLI.getPointerTy(); 224619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext()); 224719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 224819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 224919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // A divide for UMULO should be faster than a function call. 225019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (N->getOpcode() == ISD::UMULO) { 225119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue LHS = N->getOperand(0), RHS = N->getOperand(1); 225219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc DL = N->getDebugLoc(); 225319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 225419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue MUL = DAG.getNode(ISD::MUL, DL, LHS.getValueType(), LHS, RHS); 225519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SplitInteger(MUL, Lo, Hi); 225619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 225719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // A divide for UMULO will be faster than a function call. Select to 225819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // make sure we aren't using 0. 225919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue isZero = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), 226019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RHS, DAG.getConstant(0, VT), ISD::SETNE); 226119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue NotZero = DAG.getNode(ISD::SELECT, dl, VT, isZero, 226219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, VT), RHS); 226319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue DIV = DAG.getNode(ISD::UDIV, DL, LHS.getValueType(), MUL, NotZero); 226419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Overflow; 226519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overflow = DAG.getSetCC(DL, N->getValueType(1), DIV, LHS, ISD::SETNE); 226619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 1), Overflow); 226719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 226819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 226919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 227019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Replace this with a libcall that will check overflow. 227119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 227219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VT == MVT::i32) 227319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MULO_I32; 227419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (VT == MVT::i64) 227519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MULO_I64; 227619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (VT == MVT::i128) 227719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MULO_I128; 227819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XMULO!"); 227919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 228019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Temp = DAG.CreateStackTemporary(PtrVT); 228119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Temporary for the overflow value, default it to zero. 228219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, 228319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, PtrVT), Temp, 228419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0); 228519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 228619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::ArgListTy Args; 228719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::ArgListEntry Entry; 228819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 228919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ArgVT = N->getOperand(i).getValueType(); 229019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 229119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Node = N->getOperand(i); 229219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Ty = ArgTy; 229319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isSExt = true; 229419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isZExt = false; 229519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Args.push_back(Entry); 229619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 229719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 229819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Also pass the address of the overflow check. 229919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Node = Temp; 230019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Ty = PtrTy->getPointerTo(); 230119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isSExt = true; 230219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isZExt = false; 230319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Args.push_back(Entry); 230419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 230519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Func = DAG.getExternalSymbol(TLI.getLibcallName(LC), PtrVT); 230619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<SDValue, SDValue> CallInfo = 230719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.LowerCallTo(Chain, RetTy, true, false, false, false, 230819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 0, TLI.getLibcallCallingConv(LC), false, 230919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman true, Func, Args, DAG, dl); 231019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 231119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SplitInteger(CallInfo.first, Lo, Hi); 231219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Temp2 = DAG.getLoad(PtrVT, dl, CallInfo.second, Temp, 231319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0); 231419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ofl = DAG.getSetCC(dl, N->getValueType(1), Temp2, 231519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, PtrVT), 231619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::SETNE); 231719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Use the overflow from the libcall everywhere. 231819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 1), Ofl); 231919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 232019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, 2322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 2324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UDIV_I16; 2329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UDIV_I32; 2331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UDIV_I64; 2333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UDIV_I128; 2335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!"); 2336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 2338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi); 2339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, 2342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getValueType(0); 2344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT == MVT::i16) 2348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UREM_I16; 2349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i32) 2350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UREM_I32; 2351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i64) 2352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UREM_I64; 2353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (VT == MVT::i128) 2354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LC = RTLIB::UREM_I128; 2355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!"); 2356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 2358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi); 2359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N, 2362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &Lo, SDValue &Hi) { 2363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 2364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 2366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op.getValueType().bitsLE(NVT)) { 2367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The low part is zero extension of the input (degenerates to a copy). 2368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0)); 2369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getConstant(0, NVT); // The high part is just a zero. 2370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For example, extension of an i48 to an i64. The operand type necessarily 2372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // promotes to the result type, so will end up being expanded too. 237319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(getTypeAction(Op.getValueType()) == 237419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::TypePromoteInteger && 2375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Only know how to promote this result!"); 2376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = GetPromotedInteger(Op); 2377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Res.getValueType() == N->getValueType(0) && 2378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Operand over promoted?"); 2379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Split the promoted operand. This will simplify when it is expanded. 2380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SplitInteger(Res, Lo, Hi); 2381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExcessBits = 2382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op.getValueType().getSizeInBits() - NVT.getSizeInBits(); 2383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getZeroExtendInReg(Hi, dl, 2384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT::getIntegerVT(*DAG.getContext(), 2385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExcessBits)); 2386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 238919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N, 239019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue &Lo, SDValue &Hi) { 239119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 239219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VT = cast<AtomicSDNode>(N)->getMemoryVT(); 239319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Zero = DAG.getConstant(0, VT); 239419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Swap = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, VT, 239519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(0), 239619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(1), Zero, Zero, 239719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getMemOperand(), 239819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getOrdering(), 239919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getSynchScope()); 240019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 0), Swap.getValue(0)); 240119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceValueWith(SDValue(N, 1), Swap.getValue(1)); 240219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 2403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 2405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Integer Operand Expansion 2406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 2407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandIntegerOperand - This method is called when the specified operand of 2409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the specified node is found to need expansion. At this point, all of the 2410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// result types of the node are known to be legal, but other operands of the 2411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// node may need promotion or expansion as well as the specified one. 2412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { 2413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(dbgs() << "Expand integer operand: "; N->dump(&DAG); dbgs() << "\n"); 2414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Res = SDValue(); 2415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CustomLowerNode(N, N->getOperand(OpNo).getValueType(), false)) 2417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 2418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (N->getOpcode()) { 2420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman #ifndef NDEBUG 2422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "ExpandIntegerOperand Op #" << OpNo << ": "; 2423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->dump(&DAG); dbgs() << "\n"; 2424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman #endif 2425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Do not know how to expand this operator's operand!"); 2426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 242719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::BITCAST: Res = ExpandOp_BITCAST(N); break; 2428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; 2429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 2430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 2431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break; 2432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break; 2433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break; 2434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; 2435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break; 2436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break; 2437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; 2438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; 2439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 2441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: 2442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 2443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTL: 2444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTR: Res = ExpandIntOp_Shift(N); break; 2445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::RETURNADDR: 2446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FRAMEADDR: Res = ExpandIntOp_RETURNADDR(N); break; 244719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 244819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_STORE: Res = ExpandIntOp_ATOMIC_STORE(N); break; 2449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the result is null, the sub-method took care of registering results etc. 2452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Res.getNode()) return false; 2453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the result is N, the sub-method updated N in place. Tell the legalizer 2455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // core about this. 2456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Res.getNode() == N) 2457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 2458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 2460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Invalid operand expansion"); 2461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceValueWith(SDValue(N, 0), Res); 2463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 2464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code 2467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// is shared among BR_CC, SELECT_CC, and SETCC handlers. 2468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, 2469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &NewRHS, 2470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode &CCCode, 2471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 2472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSLo, LHSHi, RHSLo, RHSHi; 2473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(NewLHS, LHSLo, LHSHi); 2474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(NewRHS, RHSLo, RHSHi); 2475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) { 2477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RHSLo == RHSHi) { 2478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) { 2479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RHSCST->isAllOnesValue()) { 2480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Equality comparison to -1. 2481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = DAG.getNode(ISD::AND, dl, 2482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSLo.getValueType(), LHSLo, LHSHi); 2483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = RHSLo; 2484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo); 2490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi); 2491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS); 2492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 2493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is a comparison of the sign bit, just look at the top part. 2497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // X > -1, x < 0 2498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(NewRHS)) 2499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((CCCode == ISD::SETLT && CST->isNullValue()) || // X < 0 2500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (CCCode == ISD::SETGT && CST->isAllOnesValue())) { // X > -1 2501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = LHSHi; 2502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = RHSHi; 2503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: This generated code sucks. 2507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode LowCC; 2508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (CCCode) { 2509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown integer setcc!"); 2510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETLT: 2511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULT: LowCC = ISD::SETULT; break; 2512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETGT: 2513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGT: LowCC = ISD::SETUGT; break; 2514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETLE: 2515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULE: LowCC = ISD::SETULE; break; 2516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETGE: 2517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGE: LowCC = ISD::SETUGE; break; 2518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison 2521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands 2522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; 2523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: on targets without efficient SELECT of bools, we can always use 2525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) 2526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, true, NULL); 2527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1, Tmp2; 2528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()), 2529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl); 2530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Tmp1.getNode()) 2531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), 2532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSLo, RHSLo, LowCC); 2533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 2534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl); 2535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Tmp2.getNode()) 2536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::SETCC, dl, 2537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getSetCCResultType(LHSHi.getValueType()), 2538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSHi, RHSHi, DAG.getCondCode(CCCode)); 2539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.getNode()); 2541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.getNode()); 2542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Tmp1C && Tmp1C->isNullValue()) || 2543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (Tmp2C && Tmp2C->isNullValue() && 2544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (CCCode == ISD::SETLE || CCCode == ISD::SETGE || 2545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) || 2546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (Tmp2C && Tmp2C->getAPIntValue() == 1 && 2547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (CCCode == ISD::SETLT || CCCode == ISD::SETGT || 2548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) { 2549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // low part is known false, returns high part. 2550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For LE / GE, if high part is known false, ignore the low part. 2551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For LT / GT, if high part is known true, ignore the low part. 2552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = Tmp2; 2553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = SDValue(); 2554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return; 2555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 2558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSHi, RHSHi, ISD::SETEQ, false, 2559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DagCombineInfo, dl); 2560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!NewLHS.getNode()) 2561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 2562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHSHi, RHSHi, ISD::SETEQ); 2563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(), 2564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLHS, Tmp1, Tmp2); 2565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = SDValue(); 2566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) { 2569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 2570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 2571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 2572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If ExpandSetCCOperands returned a scalar, we need to compare the result 2574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // against zero to select between true and false values. 2575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NewRHS.getNode() == 0) { 2576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 2577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCCode = ISD::SETNE; 2578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update N to have the operands specified. 2581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), 2582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCondCode(CCCode), NewLHS, NewRHS, 2583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(4)), 0); 2584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) { 2587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 2588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 2589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 2590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If ExpandSetCCOperands returned a scalar, we need to compare the result 2592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // against zero to select between true and false values. 2593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NewRHS.getNode() == 0) { 2594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 2595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CCCode = ISD::SETNE; 2596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Update N to have the operands specified. 2599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS, 2600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getOperand(2), N->getOperand(3), 2601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCondCode(CCCode)), 0); 2602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) { 2605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 2606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 2607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 2608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If ExpandSetCCOperands returned a scalar, use it. 2610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NewRHS.getNode() == 0) { 2611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NewLHS.getValueType() == N->getValueType(0) && 2612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unexpected setcc expansion!"); 2613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return NewLHS; 2614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, update N to have the operands specified. 2617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, NewLHS, NewRHS, 2618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getCondCode(CCCode)), 0); 2619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) { 2622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The value being shifted is legal, but the shift amount is too big. 2623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // It follows that either the result of the shift is undefined, or the 2624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // upper half of the shift amount is zero. Just use the lower half. 2625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 2626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(1), Lo, Hi); 2627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0); 2628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) { 2631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant. This 2632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // surely makes pretty nice problems on 8/16 bit targets. Just truncate this 2633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // constant to valid type. 2634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 2635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), Lo, Hi); 2636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return SDValue(DAG.UpdateNodeOperands(N, Lo), 0); 2637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) { 2640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 2641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT DstVT = N->getValueType(0); 2642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT); 2643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && 2644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Don't know how to expand this SINT_TO_FP!"); 2645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc()); 2646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { 2649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ISD::isNormalStore(N)) 2650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandOp_NormalStore(N, OpNo); 2651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 2653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OpNo == 1 && "Can only expand the stored value so far"); 2654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = N->getOperand(1).getValueType(); 2656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 2657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ch = N->getChain(); 2658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ptr = N->getBasePtr(); 2659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = N->getAlignment(); 2660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isVolatile = N->isVolatile(); 2661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isNonTemporal = N->isNonTemporal(); 2662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 2664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NVT.isByteSized() && "Expanded type not byte sized!"); 2666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N->getMemoryVT().bitsLE(NVT)) { 2668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getValue(), Lo, Hi); 266919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getPointerInfo(), 2670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getMemoryVT(), isVolatile, isNonTemporal, 2671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Alignment); 267219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 267319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 267419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isLittleEndian()) { 2675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Little-endian - low bits are at low addresses. 2676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getValue(), Lo, Hi); 2677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 267819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getPointerInfo(), 2679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, Alignment); 2680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExcessBits = 2682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits(); 2683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NEVT = EVT::getIntegerVT(*DAG.getContext(), ExcessBits); 2684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Increment the pointer to the other half. 2686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned IncrementSize = NVT.getSizeInBits()/8; 2687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 2688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(IncrementSize)); 268919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, 269019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getPointerInfo().getWithOffset(IncrementSize), 269119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NEVT, isVolatile, isNonTemporal, 2692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MinAlign(Alignment, IncrementSize)); 2693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 269419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 2695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 269619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Big-endian - high bits are at low addresses. Favor aligned stores at 269719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the cost of some bit-fiddling. 269819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman GetExpandedInteger(N->getValue(), Lo, Hi); 269919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 270019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ExtVT = N->getMemoryVT(); 270119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned EBytes = ExtVT.getStoreSize(); 270219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned IncrementSize = NVT.getSizeInBits()/8; 270319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ExcessBits = (EBytes - IncrementSize)*8; 270419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT HiVT = EVT::getIntegerVT(*DAG.getContext(), 270519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtVT.getSizeInBits() - ExcessBits); 270619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 270719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ExcessBits < NVT.getSizeInBits()) { 270819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Transfer high bits from the top of Lo to the bottom of Hi. 270919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi, 271019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(NVT.getSizeInBits() - ExcessBits, 271119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getPointerTy())); 271219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::OR, dl, NVT, Hi, 271319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, dl, NVT, Lo, 271419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(ExcessBits, 271519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getPointerTy()))); 271619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 2717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 271819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store both the high bits and maybe some of the low bits. 271919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getPointerInfo(), 272019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman HiVT, isVolatile, isNonTemporal, Alignment); 2721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 272219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Increment the pointer to the other half. 272319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 272419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(IncrementSize)); 272519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store the lowest ExcessBits bits in the second half. 272619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, 272719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getPointerInfo().getWithOffset(IncrementSize), 272819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT::getIntegerVT(*DAG.getContext(), ExcessBits), 272919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isVolatile, isNonTemporal, 273019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(Alignment, IncrementSize)); 273119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 2732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) { 2735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InL, InH; 2736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(N->getOperand(0), InL, InH); 2737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Just truncate the low part of the source. 2738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL); 2739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic const fltSemantics *EVTToAPFloatSemantics(EVT VT) { 2742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.getSimpleVT().SimpleTy) { 2743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unknown FP format"); 2744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: return &APFloat::IEEEsingle; 2745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: return &APFloat::IEEEdouble; 2746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f80: return &APFloat::x87DoubleExtended; 2747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f128: return &APFloat::IEEEquad; 2748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::ppcf128: return &APFloat::PPCDoubleDouble; 2749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { 2753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op = N->getOperand(0); 2754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT SrcVT = Op.getValueType(); 2755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT DstVT = N->getValueType(0); 2756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = N->getDebugLoc(); 2757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The following optimization is valid only if every value in SrcVT (when 2759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // treated as signed) is representable in DstVT. Check that the mantissa 2760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // size of DstVT is >= than the number of bits in SrcVT -1. 2761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const fltSemantics *sem = EVTToAPFloatSemantics(DstVT); 2762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (APFloat::semanticsPrecision(*sem) >= SrcVT.getSizeInBits()-1 && 2763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){ 2764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do a signed conversion then adjust the result. 2765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op); 2766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SignedConv = TLI.LowerOperation(SignedConv, DAG); 2767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The result of the signed conversion needs adjusting if the 'sign bit' of 2769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the incoming integer was set. To handle this, we dynamically test to see 2770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // if it is set, and, if so, add a fudge factor. 2771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const uint64_t F32TwoE32 = 0x4F800000ULL; 2773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const uint64_t F32TwoE64 = 0x5F800000ULL; 2774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const uint64_t F32TwoE128 = 0x7F800000ULL; 2775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt FF(32, 0); 2777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SrcVT == MVT::i32) 2778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FF = APInt(32, F32TwoE32); 2779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (SrcVT == MVT::i64) 2780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FF = APInt(32, F32TwoE64); 2781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (SrcVT == MVT::i128) 2782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FF = APInt(32, F32TwoE128); 2783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 2784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(false && "Unsupported UINT_TO_FP!"); 2785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check whether the sign bit is set. 2787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 2788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman GetExpandedInteger(Op, Lo, Hi); 2789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignSet = DAG.getSetCC(dl, 2790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getSetCCResultType(Hi.getValueType()), 2791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi, DAG.getConstant(0, Hi.getValueType()), 2792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETLT); 2793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits. 2795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue FudgePtr = DAG.getConstantPool( 2796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantInt::get(*DAG.getContext(), FF.zext(64)), 2797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy()); 2798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get a pointer to FF if the sign bit was set, or to 0 otherwise. 2800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getIntPtrConstant(0); 2801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Four = DAG.getIntPtrConstant(4); 2802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isBigEndian()) std::swap(Zero, Four); 2803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet, 2804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Zero, Four); 2805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment(); 2806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset); 2807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Alignment = std::min(Alignment, 4u); 2808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load the value out, extending it from f32 to the destination float type. 2810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Avoid the extend by constructing the right constant pool? 281119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(), 281219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FudgePtr, 281319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getConstantPool(), 281419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::f32, 2815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, Alignment); 2816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge); 2817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, use a libcall. 2820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT); 2821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && 2822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Don't know how to expand this UINT_TO_FP!"); 2823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MakeLibCall(LC, DstVT, &Op, 1, true, dl); 2824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 282519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 282619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) { 282719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 282819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl, 282919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getMemoryVT(), 283019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(0), 283119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman N->getOperand(1), N->getOperand(2), 283219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getMemOperand(), 283319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getOrdering(), 283419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(N)->getSynchScope()); 283519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Swap.getValue(1); 283619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 283719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 283819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 283919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) { 284019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue InOp0 = N->getOperand(0); 284119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT InVT = InOp0.getValueType(); 284219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 284319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutVT = N->getValueType(0); 284419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 284519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NOutVT.isVector() && "This type must be promoted to a vector type"); 284619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned OutNumElems = OutVT.getVectorNumElements(); 284719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVTElem = NOutVT.getVectorElementType(); 284819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 284919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 285019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue BaseIdx = N->getOperand(1); 285119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 285219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Ops; 285319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops.reserve(OutNumElems); 285419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != OutNumElems; ++i) { 285519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 285619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Extract the element from the original vector. 285719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Index = DAG.getNode(ISD::ADD, dl, BaseIdx.getValueType(), 285819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BaseIdx, DAG.getIntPtrConstant(i)); 285919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 286019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman InVT.getVectorElementType(), N->getOperand(0), Index); 286119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 286219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, Ext); 286319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Insert the converted element to the new vector. 286419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops.push_back(Op); 286519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 286619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 286719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size()); 286819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 286919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 287019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 287119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) { 287219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ShuffleVectorSDNode *SV = cast<ShuffleVectorSDNode>(N); 287319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VT = N->getValueType(0); 287419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 287519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 287619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElts = VT.getVectorNumElements(); 287719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<int, 8> NewMask; 287819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != NumElts; ++i) { 287919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewMask.push_back(SV->getMaskElt(i)); 288019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 288119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 288219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue V0 = GetPromotedInteger(N->getOperand(0)); 288319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue V1 = GetPromotedInteger(N->getOperand(1)); 288419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutVT = V0.getValueType(); 288519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 288619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getVectorShuffle(OutVT, dl, V0, V1, &NewMask[0]); 288719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 288819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 288919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 289019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_BUILD_VECTOR(SDNode *N) { 289119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutVT = N->getValueType(0); 289219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 289319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NOutVT.isVector() && "This type must be promoted to a vector type"); 289419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElems = N->getNumOperands(); 289519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVTElem = NOutVT.getVectorElementType(); 289619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 289719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 289819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 289919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Ops; 290019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops.reserve(NumElems); 290119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != NumElems; ++i) { 290219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(i)); 290319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops.push_back(Op); 290419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 290519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 290619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size()); 290719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 290819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 290919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N) { 291019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 291119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 291219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 291319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!N->getOperand(0).getValueType().isVector() && 291419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Input must be a scalar"); 291519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 291619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutVT = N->getValueType(0); 291719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 291819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NOutVT.isVector() && "This type must be promoted to a vector type"); 291919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVTElem = NOutVT.getVectorElementType(); 292019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 292119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(0)); 292219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 292319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NOutVT, Op); 292419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 292519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 292619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) { 292719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 292819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 292919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op0 = N->getOperand(1); 293019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op1 = N->getOperand(1); 293119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Op0.getValueType() == Op1.getValueType() && 293219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Invalid input vector types"); 293319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 293419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutVT = N->getValueType(0); 293519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 293619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NOutVT.isVector() && "This type must be promoted to a vector type"); 293719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 293819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutElemTy = NOutVT.getVectorElementType(); 293919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 294019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem0 = Op0.getValueType().getVectorNumElements(); 294119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem1 = Op1.getValueType().getVectorNumElements(); 294219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumOutElem = NOutVT.getVectorNumElements(); 294319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NumElem0 + NumElem1 == NumOutElem && 294419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Invalid number of incoming elements"); 294519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 294619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Take the elements from the first vector. 294719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Ops(NumOutElem); 294819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i < NumElem0; ++i) { 294919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 295019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0.getValueType().getScalarType(), Op0, 295119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(i)); 295219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[i] = DAG.getNode(ISD::ANY_EXTEND, dl, OutElemTy, Ext); 295319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 295419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 295519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Take the elements from the second vector 295619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i < NumElem1; ++i) { 295719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 295819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op1.getValueType().getScalarType(), Op1, 295919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(i)); 296019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[i + NumElem0] = DAG.getNode(ISD::ANY_EXTEND, dl, OutElemTy, Ext); 296119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 296219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 296319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size()); 296419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 296519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 296619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) { 296719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT OutVT = N->getValueType(0); 296819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); 296919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(NOutVT.isVector() && "This type must be promoted to a vector type"); 297019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 297119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NOutVTElem = NOutVT.getVectorElementType(); 297219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 297319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 297419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue V0 = GetPromotedInteger(N->getOperand(0)); 297519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 297619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl, 297719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NOutVTElem, N->getOperand(1)); 297819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT, 297919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman V0, ConvElem, N->getOperand(2)); 298019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 298119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 298219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) { 298319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 298419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue V0 = GetPromotedInteger(N->getOperand(0)); 298519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue V1 = N->getOperand(1); 298619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 298719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman V0->getValueType(0).getScalarType(), V0, V1); 298819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 298919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // EXTRACT_VECTOR_ELT can return types which are wider than the incoming 299019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // element types. If this is the case then we need to expand the outgoing 299119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // value and not truncate it. 299219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0)); 299319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 299419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 299519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) { 299619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = N->getDebugLoc(); 299719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElems = N->getNumOperands(); 299819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 299919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RetSclrTy = N->getValueType(0).getVectorElementType(); 300019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 300119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> NewOps; 300219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewOps.reserve(NumElems); 300319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 300419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For each incoming vector 300519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) { 300619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx)); 300719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SclrTy = Incoming->getValueType(0).getVectorElementType(); 300819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem = Incoming->getValueType(0).getVectorNumElements(); 300919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 301019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i=0; i<NumElem; ++i) { 301119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Extract element from incoming vector 301219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, SclrTy, 301319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Incoming, DAG.getIntPtrConstant(i)); 301419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Tr = DAG.getNode(ISD::TRUNCATE, dl, RetSclrTy, Ex); 301519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewOps.push_back(Tr); 301619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 301719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 301819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 301919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::BUILD_VECTOR, dl, N->getValueType(0), 302019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman &NewOps[0], NewOps.size()); 302119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 3022