1 //===-- WebAssemblySelectionDAGInfo.cpp - WebAssembly SelectionDAG Info ---===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements the WebAssemblySelectionDAGInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "WebAssemblyTargetMachine.h"
17 #define DEBUG_TYPE "wasm-selectiondag-info"
19 WebAssemblySelectionDAGInfo::~WebAssemblySelectionDAGInfo() = default; // anchor
21 SDValue
WebAssemblySelectionDAGInfo::EmitTargetCodeForMemcpy(
22 SelectionDAG
&DAG
, const SDLoc
&DL
, SDValue Chain
, SDValue Dst
, SDValue Src
,
23 SDValue Size
, Align Alignment
, bool IsVolatile
, bool AlwaysInline
,
24 MachinePointerInfo DstPtrInfo
, MachinePointerInfo SrcPtrInfo
) const {
25 auto &ST
= DAG
.getMachineFunction().getSubtarget
<WebAssemblySubtarget
>();
26 if (!ST
.hasBulkMemoryOpt())
29 SDValue MemIdx
= DAG
.getConstant(0, DL
, MVT::i32
);
30 auto LenMVT
= ST
.hasAddr64() ? MVT::i64
: MVT::i32
;
32 // Use `MEMCPY` here instead of `MEMORY_COPY` because `memory.copy` traps
33 // if the pointers are invalid even if the length is zero. `MEMCPY` gets
34 // extra code to handle this in the way that LLVM IR expects.
36 WebAssemblyISD::MEMCPY
, DL
, MVT::Other
,
37 {Chain
, MemIdx
, MemIdx
, Dst
, Src
, DAG
.getZExtOrTrunc(Size
, DL
, LenMVT
)});
40 SDValue
WebAssemblySelectionDAGInfo::EmitTargetCodeForMemmove(
41 SelectionDAG
&DAG
, const SDLoc
&DL
, SDValue Chain
, SDValue Op1
, SDValue Op2
,
42 SDValue Op3
, Align Alignment
, bool IsVolatile
,
43 MachinePointerInfo DstPtrInfo
, MachinePointerInfo SrcPtrInfo
) const {
44 return EmitTargetCodeForMemcpy(DAG
, DL
, Chain
, Op1
, Op2
, Op3
,
45 Alignment
, IsVolatile
, false,
46 DstPtrInfo
, SrcPtrInfo
);
49 SDValue
WebAssemblySelectionDAGInfo::EmitTargetCodeForMemset(
50 SelectionDAG
&DAG
, const SDLoc
&DL
, SDValue Chain
, SDValue Dst
, SDValue Val
,
51 SDValue Size
, Align Alignment
, bool IsVolatile
, bool AlwaysInline
,
52 MachinePointerInfo DstPtrInfo
) const {
53 auto &ST
= DAG
.getMachineFunction().getSubtarget
<WebAssemblySubtarget
>();
54 if (!ST
.hasBulkMemoryOpt())
57 SDValue MemIdx
= DAG
.getConstant(0, DL
, MVT::i32
);
58 auto LenMVT
= ST
.hasAddr64() ? MVT::i64
: MVT::i32
;
60 // Use `MEMSET` here instead of `MEMORY_FILL` because `memory.fill` traps
61 // if the pointers are invalid even if the length is zero. `MEMSET` gets
62 // extra code to handle this in the way that LLVM IR expects.
64 // Only low byte matters for val argument, so anyext the i8
65 return DAG
.getNode(WebAssemblyISD::MEMSET
, DL
, MVT::Other
, Chain
, MemIdx
, Dst
,
66 DAG
.getAnyExtOrTrunc(Val
, DL
, MVT::i32
),
67 DAG
.getZExtOrTrunc(Size
, DL
, LenMVT
));