blob: 12c53c788f7bc8ac2be4632e5c68ffa09f28351f [file] [edit]
//===- WebAssemblyLegalizerInfo.cpp ------------------------------*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements the targeting of the Machinelegalizer class for
/// WebAssembly.
//===----------------------------------------------------------------------===//
#include "WebAssemblyLegalizerInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssemblySubtarget.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
#define DEBUG_TYPE "wasm-legalinfo"
using namespace llvm;
using namespace LegalizeActions;
WebAssemblyLegalizerInfo::WebAssemblyLegalizerInfo(
const WebAssemblySubtarget &ST) {
using namespace TargetOpcode;
const LLT i32 = LLT::integer(32);
const LLT i64 = LLT::integer(64);
const LLT s32 = LLT::scalar(32);
const LLT s64 = LLT::scalar(64);
getActionDefinitionsBuilder({G_CONSTANT, G_IMPLICIT_DEF, G_ADD, G_SUB, G_MUL,
G_UDIV, G_SDIV, G_UREM, G_SREM, G_AND, G_OR,
G_XOR})
.legalFor({i32, i64})
.widenScalarToNextPow2(0)
.clampScalar(0, s32, s64);
getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
.legalFor({{i32, i32}, {i64, i64}})
.widenScalarToNextPow2(0)
.clampScalar(0, s32, s64)
.scalarSameSizeAs(1, 0);
getActionDefinitionsBuilder({G_CTLZ, G_CTTZ, G_CTPOP})
.legalFor({{i32, i32}, {i64, i64}})
.widenScalarToNextPow2(1)
.clampScalar(1, s32, s64)
.scalarSameSizeAs(0, 1);
getActionDefinitionsBuilder({G_CTLZ_ZERO_UNDEF, G_CTTZ_ZERO_UNDEF}).lower();
getActionDefinitionsBuilder({G_ROTL, G_ROTR})
.legalFor({{i32, i32}, {i64, i64}})
.scalarSameSizeAs(1, 0)
.lower();
getActionDefinitionsBuilder({G_FSHL, G_FSHR}).lower();
getActionDefinitionsBuilder({G_ANYEXT, G_SEXT, G_ZEXT})
.legalFor({{i64, i32}})
.clampScalar(0, s64, s64)
.clampScalar(1, s32, s32);
getActionDefinitionsBuilder(G_TRUNC)
.legalFor({{i32, i64}})
.clampScalar(0, s32, s32)
.clampScalar(1, s64, s64);
getActionDefinitionsBuilder(G_SEXT_INREG)
.customFor(ST.hasSignExt(), {i32, i64})
.clampScalar(0, s32, s64)
.lower();
getLegacyLegalizerInfo().computeTables();
}
bool WebAssemblyLegalizerInfo::legalizeCustom(
LegalizerHelper &Helper, MachineInstr &MI,
LostDebugLocObserver &LocObserver) const {
switch (MI.getOpcode()) {
case TargetOpcode::G_SEXT_INREG: {
assert(MI.getOperand(2).isImm() && "Expected immediate");
// Mark only 8/16/32-bit SEXT_INREG as legal
auto [DstType, SrcType] = MI.getFirst2LLTs();
auto ExtFromWidth = MI.getOperand(2).getImm();
if (ExtFromWidth == 8 || ExtFromWidth == 16 ||
(DstType.getScalarSizeInBits() == 64 && ExtFromWidth == 32)) {
return true;
}
return Helper.lower(MI, 0, DstType) != LegalizerHelper::UnableToLegalize;
}
default:
break;
}
return false;
}