X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FWebAssembly%2FWebAssemblyISelLowering.cpp;h=ed7cb1909d9fd504d81f9c0ccee8c2b6e77e1cd9;hp=21a28e3b7673c2f56b51f36f79c6c2bfc74ee236;hb=f2640be5dfc41d11ca28ad60ab5e45bf4db7e36e;hpb=338412765288cd6041d31db12f33a39fbad6efcb diff --git a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index 21a28e3b767..ed7cb1909d9 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -134,7 +134,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( setCondCodeAction(CC, T, Expand); // Expand floating-point library function operators. for (auto Op : {ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOWI, ISD::FPOW, - ISD::FREM}) + ISD::FREM, ISD::FMA}) setOperationAction(Op, T, Expand); // Note supported floating-point library function operators that otherwise // default to expand. @@ -167,6 +167,8 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVTPtr, Expand); + setOperationAction(ISD::FrameIndex, MVT::i32, Custom); + // Expand these forms; we pattern-match the forms that we can handle in isel. for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64}) for (auto Op : {ISD::BR_CC, ISD::SELECT_CC}) @@ -179,7 +181,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( // - Floating-point extending loads. // - Floating-point truncating stores. // - i1 extending loads. - setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f64, Expand); + setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand); setTruncStoreAction(MVT::f64, MVT::f32, Expand); for (auto T : MVT::integer_valuetypes()) for (auto Ext : {ISD::EXTLOAD, ISD::ZEXTLOAD, ISD::SEXTLOAD}) @@ -205,6 +207,13 @@ MVT WebAssemblyTargetLowering::getScalarShiftAmountTy(const DataLayout & /*DL*/, unsigned BitWidth = NextPowerOf2(VT.getSizeInBits() - 1); if (BitWidth > 1 && BitWidth < 8) BitWidth = 8; + + if (BitWidth > 64) { + BitWidth = 64; + assert(BitWidth >= Log2_32_Ceil(VT.getSizeInBits()) && + "64-bit shift counts ought to be enough for anyone"); + } + MVT Result = MVT::getIntegerVT(BitWidth); assert(Result != MVT::INVALID_SIMPLE_VALUE_TYPE && "Unable to represent scalar shift amount type"); @@ -259,6 +268,24 @@ bool WebAssemblyTargetLowering::isCheapToSpeculateCtlz() const { return true; } +bool WebAssemblyTargetLowering::isLegalAddressingMode(const DataLayout &DL, + const AddrMode &AM, + Type *Ty, + unsigned AS) const { + // WebAssembly offsets are added as unsigned without wrapping. The + // isLegalAddressingMode gives us no way to determine if wrapping could be + // happening, so we approximate this by accepting only non-negative offsets. + if (AM.BaseOffs < 0) + return false; + + // WebAssembly has no scale register operands. + if (AM.Scale != 0) + return false; + + // Everything else is legal. + return true; +} + //===----------------------------------------------------------------------===// // WebAssembly Lowering private implementation. //===----------------------------------------------------------------------===// @@ -359,8 +386,11 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, unsigned NumBytes = CCInfo.getAlignedCallFrameSize(); - auto NB = DAG.getConstant(NumBytes, DL, PtrVT, true); - Chain = DAG.getCALLSEQ_START(Chain, NB, DL); + SDValue NB; + if (NumBytes) { + NB = DAG.getConstant(NumBytes, DL, PtrVT, true); + Chain = DAG.getCALLSEQ_START(Chain, NB, DL); + } if (IsVarArg) { // For non-fixed arguments, next emit stores to store the argument values @@ -403,7 +433,8 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, if (In.Flags.isInConsecutiveRegs()) fail(DL, DAG, "WebAssembly hasn't implemented cons regs return values"); if (In.Flags.isInConsecutiveRegsLast()) - fail(DL, DAG, "WebAssembly hasn't implemented cons regs last return values"); + fail(DL, DAG, + "WebAssembly hasn't implemented cons regs last return values"); // Ignore In.getOrigAlign() because all our arguments are passed in // registers. Tys.push_back(In.VT); @@ -420,8 +451,10 @@ WebAssemblyTargetLowering::LowerCall(CallLoweringInfo &CLI, Chain = Res.getValue(1); } - SDValue Unused = DAG.getUNDEF(PtrVT); - Chain = DAG.getCALLSEQ_END(Chain, NB, Unused, SDValue(), DL); + if (NumBytes) { + SDValue Unused = DAG.getTargetConstant(0, DL, PtrVT); + Chain = DAG.getCALLSEQ_END(Chain, NB, Unused, SDValue(), DL); + } return Chain; } @@ -515,6 +548,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op, default: llvm_unreachable("unimplemented operation lowering"); return SDValue(); + case ISD::FrameIndex: + return LowerFrameIndex(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::ExternalSymbol: @@ -528,6 +563,12 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op, } } +SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op, + SelectionDAG &DAG) const { + int FI = cast(Op)->getIndex(); + return DAG.getTargetFrameIndex(FI, Op.getValueType()); +} + SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { SDLoc DL(Op); @@ -536,9 +577,9 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op, assert(GA->getTargetFlags() == 0 && "WebAssembly doesn't set target flags"); if (GA->getAddressSpace() != 0) fail(DL, DAG, "WebAssembly only expects the 0 address space"); - return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT, - DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, - GA->getOffset())); + return DAG.getNode( + WebAssemblyISD::Wrapper, DL, VT, + DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset())); } SDValue