diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 80 |
1 files changed, 76 insertions, 4 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index 7bfa4074849..b4786e5518f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -113,6 +113,13 @@ private: case MVT::f32: case MVT::f64: return VT; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v4f32: + if (Subtarget->hasSIMD128()) + return VT; + break; default: break; } @@ -575,7 +582,9 @@ bool WebAssemblyFastISel::fastLowerArguments() { return false; Type *ArgTy = Arg.getType(); - if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) + if (ArgTy->isStructTy() || ArgTy->isArrayTy()) + return false; + if (!Subtarget->hasSIMD128() && ArgTy->isVectorTy()) return false; unsigned Opc; @@ -600,6 +609,22 @@ bool WebAssemblyFastISel::fastLowerArguments() { Opc = WebAssembly::ARGUMENT_F64; RC = &WebAssembly::F64RegClass; break; + case MVT::v16i8: + Opc = WebAssembly::ARGUMENT_v16i8; + RC = &WebAssembly::V128RegClass; + break; + case MVT::v8i16: + Opc = WebAssembly::ARGUMENT_v8i16; + RC = &WebAssembly::V128RegClass; + break; + case MVT::v4i32: + Opc = WebAssembly::ARGUMENT_v4i32; + RC = &WebAssembly::V128RegClass; + break; + case MVT::v4f32: + Opc = WebAssembly::ARGUMENT_v4f32; + RC = &WebAssembly::V128RegClass; + break; default: return false; } @@ -639,6 +664,9 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) { if (IsVoid) { Opc = IsDirect ? WebAssembly::CALL_VOID : WebAssembly::CALL_INDIRECT_VOID; } else { + if (!Subtarget->hasSIMD128() && Call->getType()->isVectorTy()) + return false; + MVT::SimpleValueType RetTy = getSimpleType(Call->getType()); switch (RetTy) { case MVT::i1: @@ -660,6 +688,26 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) { Opc = IsDirect ? WebAssembly::CALL_F64 : WebAssembly::CALL_INDIRECT_F64; ResultReg = createResultReg(&WebAssembly::F64RegClass); break; + case MVT::v16i8: + Opc = + IsDirect ? WebAssembly::CALL_v16i8 : WebAssembly::CALL_INDIRECT_v16i8; + ResultReg = createResultReg(&WebAssembly::V128RegClass); + break; + case MVT::v8i16: + Opc = + IsDirect ? WebAssembly::CALL_v8i16 : WebAssembly::CALL_INDIRECT_v8i16; + ResultReg = createResultReg(&WebAssembly::V128RegClass); + break; + case MVT::v4i32: + Opc = + IsDirect ? WebAssembly::CALL_v4i32 : WebAssembly::CALL_INDIRECT_v4i32; + ResultReg = createResultReg(&WebAssembly::V128RegClass); + break; + case MVT::v4f32: + Opc = + IsDirect ? WebAssembly::CALL_v4f32 : WebAssembly::CALL_INDIRECT_v4f32; + ResultReg = createResultReg(&WebAssembly::V128RegClass); + break; default: return false; } @@ -972,6 +1020,8 @@ bool WebAssemblyFastISel::selectLoad(const Instruction *I) { const LoadInst *Load = cast<LoadInst>(I); if (Load->isAtomic()) return false; + if (!Subtarget->hasSIMD128() && Load->getType()->isVectorTy()) + return false; Address Addr; if (!computeAddress(Load->getPointerOperand(), Addr)) @@ -1027,6 +1077,9 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) { const StoreInst *Store = cast<StoreInst>(I); if (Store->isAtomic()) return false; + if (!Subtarget->hasSIMD128() && + Store->getValueOperand()->getType()->isVectorTy()) + return false; Address Addr; if (!computeAddress(Store->getPointerOperand(), Addr)) @@ -1102,7 +1155,7 @@ bool WebAssemblyFastISel::selectBr(const Instruction *I) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)) .addMBB(TBB) .addReg(CondReg); - + finishCondBranch(Br->getParent(), TBB, FBB); return true; } @@ -1120,6 +1173,9 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) { } Value *RV = Ret->getOperand(0); + if (!Subtarget->hasSIMD128() && RV->getType()->isVectorTy()) + return false; + unsigned Opc; switch (getSimpleType(RV->getType())) { case MVT::i1: case MVT::i8: @@ -1129,8 +1185,24 @@ bool WebAssemblyFastISel::selectRet(const Instruction *I) { case MVT::i64: Opc = WebAssembly::RETURN_I64; break; - case MVT::f32: Opc = WebAssembly::RETURN_F32; break; - case MVT::f64: Opc = WebAssembly::RETURN_F64; break; + case MVT::f32: + Opc = WebAssembly::RETURN_F32; + break; + case MVT::f64: + Opc = WebAssembly::RETURN_F64; + break; + case MVT::v16i8: + Opc = WebAssembly::RETURN_v16i8; + break; + case MVT::v8i16: + Opc = WebAssembly::RETURN_v8i16; + break; + case MVT::v4i32: + Opc = WebAssembly::RETURN_v4i32; + break; + case MVT::v4f32: + Opc = WebAssembly::RETURN_v4f32; + break; default: return false; } |