diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 72 |
1 files changed, 33 insertions, 39 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index c932f985489a..8a0092a3f298 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -640,6 +640,9 @@ bool WebAssemblyFastISel::fastLowerArguments() { if (F->isVarArg()) return false; + if (FuncInfo.Fn->getCallingConv() == CallingConv::Swift) + return false; + unsigned I = 0; for (auto const &Arg : F->args()) { const AttributeList &Attrs = F->getAttributes(); @@ -754,17 +757,18 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) { if (Func && Func->isIntrinsic()) return false; + if (Call->getCallingConv() == CallingConv::Swift) + return false; + bool IsDirect = Func != nullptr; - if (!IsDirect && isa<ConstantExpr>(Call->getCalledValue())) + if (!IsDirect && isa<ConstantExpr>(Call->getCalledOperand())) return false; FunctionType *FuncTy = Call->getFunctionType(); - unsigned Opc; + unsigned Opc = IsDirect ? WebAssembly::CALL : WebAssembly::CALL_INDIRECT; bool IsVoid = FuncTy->getReturnType()->isVoidTy(); unsigned ResultReg; - if (IsVoid) { - Opc = IsDirect ? WebAssembly::CALL_VOID : WebAssembly::PCALL_INDIRECT_VOID; - } else { + if (!IsVoid) { if (!Subtarget->hasSIMD128() && Call->getType()->isVectorTy()) return false; @@ -774,54 +778,36 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) { case MVT::i8: case MVT::i16: case MVT::i32: - Opc = IsDirect ? WebAssembly::CALL_i32 : WebAssembly::PCALL_INDIRECT_i32; ResultReg = createResultReg(&WebAssembly::I32RegClass); break; case MVT::i64: - Opc = IsDirect ? WebAssembly::CALL_i64 : WebAssembly::PCALL_INDIRECT_i64; ResultReg = createResultReg(&WebAssembly::I64RegClass); break; case MVT::f32: - Opc = IsDirect ? WebAssembly::CALL_f32 : WebAssembly::PCALL_INDIRECT_f32; ResultReg = createResultReg(&WebAssembly::F32RegClass); break; case MVT::f64: - Opc = IsDirect ? WebAssembly::CALL_f64 : WebAssembly::PCALL_INDIRECT_f64; ResultReg = createResultReg(&WebAssembly::F64RegClass); break; case MVT::v16i8: - Opc = IsDirect ? WebAssembly::CALL_v16i8 - : WebAssembly::PCALL_INDIRECT_v16i8; ResultReg = createResultReg(&WebAssembly::V128RegClass); break; case MVT::v8i16: - Opc = IsDirect ? WebAssembly::CALL_v8i16 - : WebAssembly::PCALL_INDIRECT_v8i16; ResultReg = createResultReg(&WebAssembly::V128RegClass); break; case MVT::v4i32: - Opc = IsDirect ? WebAssembly::CALL_v4i32 - : WebAssembly::PCALL_INDIRECT_v4i32; ResultReg = createResultReg(&WebAssembly::V128RegClass); break; case MVT::v2i64: - Opc = IsDirect ? WebAssembly::CALL_v2i64 - : WebAssembly::PCALL_INDIRECT_v2i64; ResultReg = createResultReg(&WebAssembly::V128RegClass); break; case MVT::v4f32: - Opc = IsDirect ? WebAssembly::CALL_v4f32 - : WebAssembly::PCALL_INDIRECT_v4f32; ResultReg = createResultReg(&WebAssembly::V128RegClass); break; case MVT::v2f64: - Opc = IsDirect ? WebAssembly::CALL_v2f64 - : WebAssembly::PCALL_INDIRECT_v2f64; ResultReg = createResultReg(&WebAssembly::V128RegClass); break; case MVT::exnref: - Opc = IsDirect ? WebAssembly::CALL_exnref - : WebAssembly::PCALL_INDIRECT_exnref; ResultReg = createResultReg(&WebAssembly::EXNREFRegClass); break; default: @@ -861,7 +847,7 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) { unsigned CalleeReg = 0; if (!IsDirect) { - CalleeReg = getRegForValue(Call->getCalledValue()); + CalleeReg = getRegForValue(Call->getCalledOperand()); if (!CalleeReg) return false; } @@ -871,14 +857,20 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) { if (!IsVoid) MIB.addReg(ResultReg, RegState::Define); - if (IsDirect) + if (IsDirect) { MIB.addGlobalAddress(Func); - else - MIB.addReg(CalleeReg); + } else { + // Add placeholders for the type index and immediate flags + MIB.addImm(0); + MIB.addImm(0); + } for (unsigned ArgReg : Args) MIB.addReg(ArgReg); + if (!IsDirect) + MIB.addReg(CalleeReg); + if (!IsVoid) updateValueMap(Call, ResultReg); return true; @@ -1168,30 +1160,31 @@ bool WebAssemblyFastISel::selectLoad(const Instruction *I) { unsigned Opc; const TargetRegisterClass *RC; + bool A64 = Subtarget->hasAddr64(); switch (getSimpleType(Load->getType())) { case MVT::i1: case MVT::i8: - Opc = WebAssembly::LOAD8_U_I32; + Opc = A64 ? WebAssembly::LOAD8_U_I32_A64 : WebAssembly::LOAD8_U_I32_A32; RC = &WebAssembly::I32RegClass; break; case MVT::i16: - Opc = WebAssembly::LOAD16_U_I32; + Opc = A64 ? WebAssembly::LOAD16_U_I32_A64 : WebAssembly::LOAD16_U_I32_A32; RC = &WebAssembly::I32RegClass; break; case MVT::i32: - Opc = WebAssembly::LOAD_I32; + Opc = A64 ? WebAssembly::LOAD_I32_A64 : WebAssembly::LOAD_I32_A32; RC = &WebAssembly::I32RegClass; break; case MVT::i64: - Opc = WebAssembly::LOAD_I64; + Opc = A64 ? WebAssembly::LOAD_I64_A64 : WebAssembly::LOAD_I64_A32; RC = &WebAssembly::I64RegClass; break; case MVT::f32: - Opc = WebAssembly::LOAD_F32; + Opc = A64 ? WebAssembly::LOAD_F32_A64 : WebAssembly::LOAD_F32_A32; RC = &WebAssembly::F32RegClass; break; case MVT::f64: - Opc = WebAssembly::LOAD_F64; + Opc = A64 ? WebAssembly::LOAD_F64_A64 : WebAssembly::LOAD_F64_A32; RC = &WebAssembly::F64RegClass; break; default: @@ -1224,27 +1217,28 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) { unsigned Opc; bool VTIsi1 = false; + bool A64 = Subtarget->hasAddr64(); switch (getSimpleType(Store->getValueOperand()->getType())) { case MVT::i1: VTIsi1 = true; LLVM_FALLTHROUGH; case MVT::i8: - Opc = WebAssembly::STORE8_I32; + Opc = A64 ? WebAssembly::STORE8_I32_A64 : WebAssembly::STORE8_I32_A32; break; case MVT::i16: - Opc = WebAssembly::STORE16_I32; + Opc = A64 ? WebAssembly::STORE16_I32_A64 : WebAssembly::STORE16_I32_A32; break; case MVT::i32: - Opc = WebAssembly::STORE_I32; + Opc = A64 ? WebAssembly::STORE_I32_A64 : WebAssembly::STORE_I32_A32; break; case MVT::i64: - Opc = WebAssembly::STORE_I64; + Opc = A64 ? WebAssembly::STORE_I64_A64 : WebAssembly::STORE_I64_A32; break; case MVT::f32: - Opc = WebAssembly::STORE_F32; + Opc = A64 ? WebAssembly::STORE_F32_A64 : WebAssembly::STORE_F32_A32; break; case MVT::f64: - Opc = WebAssembly::STORE_F64; + Opc = A64 ? WebAssembly::STORE_F64_A64 : WebAssembly::STORE_F64_A32; break; default: return false; |