Skip to content

Fix #12. #23

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 58 additions & 15 deletions llvm/lib/Target/Z80/GISel/Z80LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Z80MachineFunctionInfo.h"
#include "Z80Subtarget.h"
#include "Z80TargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
Expand All @@ -26,10 +27,49 @@ using namespace TargetOpcode;
using namespace LegalizeActions;
using namespace MIPatternMatch;

static LegalityPredicate typeNotInSet(unsigned TypeIdx,
std::initializer_list<LLT> TypesInit) {
using namespace LegalityPredicates;
SmallVector<LLT, 8> Types = TypesInit;
return [=](const LegalityQuery &Query) {
return !is_contained(Types, Query.Types[TypeIdx]);
};
}

static LegalityPredicate scalarNotInSet(unsigned TypeIdx,
std::initializer_list<LLT> Types) {
using namespace LegalityPredicates;
return all(isScalar(TypeIdx), typeNotInSet(TypeIdx, Types));
}

static LegalizeRuleSet &
widenScalarToNextOrNarrowToLast(LegalizeRuleSet &Builder, unsigned TypeIdx,
std::initializer_list<LLT> TypesInit) {
using namespace LegalityPredicates;
SmallVector<LLT, 8> Types = TypesInit;
assert(!Types.empty() && is_sorted(Types, [](LLT Ty1, LLT Ty2) {
return Ty1.getSizeInBits() < Ty2.getSizeInBits();
}) && "Expected type set to be not empty and sorted by width.");
return Builder.maxScalar(TypeIdx, Types.back())
.widenScalarIf(
scalarNotInSet(TypeIdx, TypesInit), [=](const LegalityQuery &Query) {
LLT QueryTy = Query.Types[TypeIdx];
for (LLT Ty : reverse(Types))
if (QueryTy.getSizeInBits() < Ty.getSizeInBits())
return std::make_pair(TypeIdx, Ty);
llvm_unreachable("Scalar wider than last already handled.");
});
}

Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
const Z80TargetMachine &TM)
: Subtarget(STI), TM(TM) {
using namespace LegalizeActions;
using namespace LegalityPredicates;
using namespace LegalizeMutations;

bool Is24Bit = Subtarget.is24Bit();
LegalityPredicate pred24Bit = [=](const LegalityQuery &) { return Is24Bit; };

std::array<LLT, 5> p;
for (int AddrSpace = 0; AddrSpace != p.size(); ++AddrSpace)
Expand All @@ -39,6 +79,7 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
LLT s16 = LLT::scalar(16);
LLT s24 = LLT::scalar(24);
LLT s32 = LLT::scalar(32);
LLT s48 = LLT::scalar(48);
LLT s64 = LLT::scalar(64);
LLT sMax = Is24Bit ? s24 : s16;
LLT sOther = Is24Bit ? s16 : s24;
Expand All @@ -57,6 +98,9 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
auto LegalLibcallScalars16 = {s8, s16, s32, s64};
auto LegalLibcallScalars =
Is24Bit ? LegalLibcallScalars24 : LegalLibcallScalars16;
auto LibcallScalars24 = {s8, s16, s24, s32, s48, s64};
auto LibcallScalars16 = {s8, s16, s32, s64};
auto LibcallScalars = Is24Bit ? LibcallScalars24 : LibcallScalars16;
auto NotMax24 = {s8, s16}, NotMax16 = {s8};
auto NotMax = Is24Bit ? NotMax24 : NotMax16;
auto NotMin24 = {s16, s24}, NotMin16 = {s16};
Expand Down Expand Up @@ -159,13 +203,11 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
.legalForCartesianProduct(LegalScalars, {s1})
.clampScalar(0, s8, sMax);

{
auto &&Mul = getActionDefinitionsBuilder(G_MUL);
if (Subtarget.hasZ180Ops())
Mul.legalFor({s8});
Mul.libcallFor(LegalLibcallScalars)
.clampScalar(0, s8, s32);
}
getActionDefinitionsBuilder(G_MUL)
.legalIf(all(pred24Bit, typeIs(0, s8)))
.libcallFor(LegalLibcallScalars)
.narrowScalarIf(all(pred24Bit, typeIs(0, s48)), changeTo(0, s24))
.clampScalar(0, s8, s32);

getActionDefinitionsBuilder({G_SDIV, G_UDIV, G_SREM, G_UREM})
.libcallFor(LegalLibcallScalars)
Expand All @@ -176,10 +218,12 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
.customFor(LegalLibcallScalars)
.clampScalar(0, s8, s32);

getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
.customForCartesianProduct(LegalLibcallScalars, {s8})
.clampScalar(1, s8, s8)
.clampScalar(0, s8, s64);
widenScalarToNextOrNarrowToLast(
getActionDefinitionsBuilder({G_SHL, G_LSHR, G_ASHR})
.customForCartesianProduct(LegalLibcallScalars, {s8})
.clampScalar(1, s8, s8)
.narrowScalarIf(all(pred24Bit, typeIs(0, s48)), changeTo(0, s24)),
0, LibcallScalars);

getActionDefinitionsBuilder({G_FSHL, G_FSHR, G_ROTR, G_ROTL, G_UMULO,
G_UMULFIX, G_SMULFIX, G_SMULFIXSAT, G_UMULFIXSAT,
Expand Down Expand Up @@ -260,11 +304,10 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
.customForCartesianProduct({s1}, {s32, s64})
.clampScalar(1, s8, s64);

getActionDefinitionsBuilder(G_FCMP)
.customForCartesianProduct({s1}, {s32, s64});
getActionDefinitionsBuilder(G_FCMP).customForCartesianProduct({s1},
{s32, s64});

getActionDefinitionsBuilder(G_BRCOND)
.legalFor({s1});
getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});

getActionDefinitionsBuilder(G_BRJT)
.legalForCartesianProduct({p[0]}, LegalScalars)
Expand Down