mesa/src/nouveau/codegen/nv50_ir_target_gv100.cpp
Dave Airlie 1f754b7aae nouveau: move codegen to a common higher level directory.
This allows it to be built independently of the gallium driver.

Acked-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Yusuf Khan<yusisamerican@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16763>
2022-06-03 03:57:18 +00:00

594 lines
19 KiB
C++

/*
* Copyright 2020 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nv50_ir_target_gv100.h"
#include "nv50_ir_lowering_gv100.h"
#include "nv50_ir_emit_gv100.h"
namespace nv50_ir {
void
TargetGV100::initOpInfo()
{
unsigned int i, j;
static const operation commutative[] =
{
OP_ADD, OP_MUL, OP_MAD, OP_FMA, OP_MAX, OP_MIN,
OP_SET_AND, OP_SET_OR, OP_SET_XOR, OP_SET, OP_SELP, OP_SLCT
};
static const operation noDest[] =
{
OP_EXIT
};
static const operation noPred[] =
{
};
for (i = 0; i < DATA_FILE_COUNT; ++i)
nativeFileMap[i] = (DataFile)i;
nativeFileMap[FILE_ADDRESS] = FILE_GPR;
nativeFileMap[FILE_FLAGS] = FILE_PREDICATE;
for (i = 0; i < OP_LAST; ++i) {
opInfo[i].variants = NULL;
opInfo[i].op = (operation)i;
opInfo[i].srcTypes = 1 << (int)TYPE_F32;
opInfo[i].dstTypes = 1 << (int)TYPE_F32;
opInfo[i].immdBits = 0;
opInfo[i].srcNr = operationSrcNr[i];
for (j = 0; j < opInfo[i].srcNr; ++j) {
opInfo[i].srcMods[j] = 0;
opInfo[i].srcFiles[j] = 1 << (int)FILE_GPR;
}
opInfo[i].dstMods = 0;
opInfo[i].dstFiles = 1 << (int)FILE_GPR;
opInfo[i].hasDest = 1;
opInfo[i].vector = (i >= OP_TEX && i <= OP_TEXCSAA);
opInfo[i].commutative = false; /* set below */
opInfo[i].pseudo = (i < OP_MOV);
opInfo[i].predicate = !opInfo[i].pseudo;
opInfo[i].flow = (i >= OP_BRA && i <= OP_JOIN);
opInfo[i].minEncSize = 16;
}
for (i = 0; i < ARRAY_SIZE(commutative); ++i)
opInfo[commutative[i]].commutative = true;
for (i = 0; i < ARRAY_SIZE(noDest); ++i)
opInfo[noDest[i]].hasDest = 0;
for (i = 0; i < ARRAY_SIZE(noPred); ++i)
opInfo[noPred[i]].predicate = 0;
}
struct opInfo {
struct {
uint8_t files;
uint8_t mods;
} src[3];
};
#define SRC_NONE 0
#define SRC_R (1 << FILE_GPR)
#define SRC_I (1 << FILE_MEMORY_CONST)
#define SRC_C (1 << FILE_IMMEDIATE)
#define SRC_RC (SRC_R | SRC_C)
#define SRC_RI (SRC_R | SRC_I )
#define SRC_RIC (SRC_R | SRC_I | SRC_C)
#define MOD_NONE 0
#define MOD_NEG NV50_IR_MOD_NEG
#define MOD_ABS NV50_IR_MOD_ABS
#define MOD_NOT NV50_IR_MOD_NOT
#define MOD_NA (MOD_NEG | MOD_ABS)
#define OPINFO(O,SA,MA,SB,MB,SC,MC) \
static struct opInfo \
opInfo_##O = { \
.src = { { SRC_##SA, MOD_##MA }, \
{ SRC_##SB, MOD_##MB }, \
{ SRC_##SC, MOD_##MC }}, \
};
/* Handled by GV100LegalizeSSA. */
OPINFO(FABS , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(FCMP , R , NONE, RIC , NONE, RIC , NONE); //XXX: use FSEL for mods
OPINFO(FNEG , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(FSET , R , NA , RIC , NA , NONE, NONE);
OPINFO(ICMP , R , NONE, RIC , NONE, RIC , NONE);
OPINFO(IMUL , R , NONE, RIC , NONE, NONE, NONE);
OPINFO(INEG , RIC , NEG , NONE, NONE, NONE, NONE);
OPINFO(ISET , R , NONE, RIC , NONE, NONE, NONE);
OPINFO(LOP2 , R , NOT , RIC , NOT , NONE, NONE);
OPINFO(NOT , RIC , NONE, NONE, NONE, NONE, NONE);
OPINFO(SAT , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(SHL , RIC , NONE, RIC , NONE, NONE, NONE);
OPINFO(SHR , RIC , NONE, RIC , NONE, NONE, NONE);
OPINFO(SUB , R , NONE, RIC , NEG , NONE, NONE);
OPINFO(IMNMX , R , NONE, RIC , NONE, NONE, NONE);
/* Handled by CodeEmitterGV100. */
OPINFO(AL2P , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(ALD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(AST , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(ATOM , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(ATOMS , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(BAR , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(BRA , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(BMSK , R , NONE, RIC , NONE, NONE, NONE);
OPINFO(BREV , RIC , NONE, NONE, NONE, NONE, NONE);
OPINFO(CCTL , NONE, NONE, NONE, NONE, NONE, NONE);
//OPINFO(CS2R , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(DADD , R , NA , RIC , NA , NONE, NONE);
OPINFO(DFMA , R , NA , RIC , NA , RIC , NA );
OPINFO(DMUL , R , NA , RIC , NA , NONE, NONE);
OPINFO(DSETP , R , NA , RIC , NA , NONE, NONE);
OPINFO(EXIT , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(F2F , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(F2I , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(FADD , R , NA , RIC , NA , NONE, NONE);
OPINFO(FFMA , R , NA , RIC , NA , RIC , NA );
OPINFO(FLO , RIC , NOT , NONE, NONE, NONE, NONE);
OPINFO(FMNMX , R , NA , RIC , NA , NONE, NONE);
OPINFO(FMUL , R , NA , RIC , NA , NONE, NONE);
OPINFO(FRND , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(FSET_BF , R , NA , RIC , NA , NONE, NONE);
OPINFO(FSETP , R , NA , RIC , NA , NONE, NONE);
OPINFO(FSWZADD , R , NONE, R , NONE, NONE, NONE);
OPINFO(I2F , RIC , NONE, NONE, NONE, NONE, NONE);
OPINFO(IABS , RIC , NONE, NONE, NONE, NONE, NONE);
OPINFO(IADD3 , R , NEG , RIC , NEG , R , NEG );
OPINFO(IMAD , R , NONE, RIC , NONE, RIC , NEG );
OPINFO(IMAD_WIDE, R , NONE, RIC , NONE, RC , NEG );
OPINFO(IPA , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(ISBERD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(ISETP , R , NONE, RIC , NONE, NONE, NONE);
OPINFO(KILL , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(LD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(LDC , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(LDL , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(LDS , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(LEA , R , NEG , I , NONE, RIC , NEG );
OPINFO(LOP3_LUT , R , NONE, RIC , NONE, R , NONE);
OPINFO(MEMBAR , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(MOV , RIC , NONE, NONE, NONE, NONE, NONE);
OPINFO(MUFU , RIC , NA , NONE, NONE, NONE, NONE);
OPINFO(NOP , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(OUT , R , NONE, RI , NONE, NONE, NONE);
OPINFO(PIXLD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(PLOP3_LUT, NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(POPC , RIC , NOT , NONE, NONE, NONE, NONE);
OPINFO(PRMT , R , NONE, RIC , NONE, RIC , NONE);
OPINFO(RED , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(SGXT , R , NONE, RIC , NONE, NONE, NONE);
OPINFO(S2R , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(SEL , R , NONE, RIC , NONE, NONE, NONE);
OPINFO(SHF , R , NONE, RIC , NONE, RIC , NONE);
OPINFO(SHFL , R , NONE, R , NONE, R , NONE);
OPINFO(ST , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(STL , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(STS , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(SUATOM , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(SULD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(SUST , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(TEX , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(TLD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(TLD4 , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(TMML , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(TXD , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(TXQ , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(VOTE , NONE, NONE, NONE, NONE, NONE, NONE);
OPINFO(WARPSYNC , R , NONE, NONE, NONE, NONE, NONE);
static const struct opInfo *
getOpInfo(const Instruction *i)
{
switch (i->op) {
case OP_ABS:
if (isFloatType(i->dType))
return &opInfo_FABS;
return &opInfo_IABS;
case OP_ADD:
if (isFloatType(i->dType)) {
if (i->dType == TYPE_F32)
return &opInfo_FADD;
else
return &opInfo_DADD;
} else {
return &opInfo_IADD3;
}
break;
case OP_AFETCH: return &opInfo_AL2P;
case OP_AND:
case OP_OR:
case OP_XOR:
if (i->def(0).getFile() == FILE_PREDICATE)
return &opInfo_PLOP3_LUT;
return &opInfo_LOP2;
case OP_ATOM:
if (i->src(0).getFile() == FILE_MEMORY_SHARED)
return &opInfo_ATOMS;
else
if (!i->defExists(0) && i->subOp < NV50_IR_SUBOP_ATOM_CAS)
return &opInfo_RED;
else
return &opInfo_ATOM;
break;
case OP_BAR: return &opInfo_BAR;
case OP_BFIND: return &opInfo_FLO;
case OP_BMSK: return &opInfo_BMSK;
case OP_BREV: return &opInfo_BREV;
case OP_BRA:
case OP_JOIN: return &opInfo_BRA; //XXX
case OP_CCTL: return &opInfo_CCTL;
case OP_CEIL:
case OP_CVT:
case OP_FLOOR:
case OP_TRUNC:
if (i->op == OP_CVT && (i->def(0).getFile() == FILE_PREDICATE ||
i->src(0).getFile() == FILE_PREDICATE)) {
return &opInfo_MOV;
} else if (isFloatType(i->dType)) {
if (isFloatType(i->sType)) {
if (i->sType == i->dType)
return &opInfo_FRND;
else
return &opInfo_F2F;
} else {
return &opInfo_I2F;
}
} else {
if (isFloatType(i->sType))
return &opInfo_F2I;
}
break;
case OP_COS:
case OP_EX2:
case OP_LG2:
case OP_RCP:
case OP_RSQ:
case OP_SIN:
case OP_SQRT: return &opInfo_MUFU;
case OP_DISCARD: return &opInfo_KILL;
case OP_EMIT:
case OP_FINAL:
case OP_RESTART: return &opInfo_OUT;
case OP_EXIT: return &opInfo_EXIT;
case OP_EXPORT: return &opInfo_AST;
case OP_FMA:
case OP_MAD:
if (isFloatType(i->dType)) {
if (i->dType == TYPE_F32)
return &opInfo_FFMA;
else
return &opInfo_DFMA;
} else {
if (typeSizeof(i->dType) != 8)
return &opInfo_IMAD;
else
return &opInfo_IMAD_WIDE;
}
break;
case OP_JOINAT: return &opInfo_NOP; //XXX
case OP_LINTERP: return &opInfo_IPA;
case OP_LOAD:
switch (i->src(0).getFile()) {
case FILE_MEMORY_CONST : return &opInfo_LDC;
case FILE_MEMORY_LOCAL : return &opInfo_LDL;
case FILE_MEMORY_SHARED: return &opInfo_LDS;
case FILE_MEMORY_GLOBAL: return &opInfo_LD;
default:
break;
}
break;
case OP_LOP3_LUT: return &opInfo_LOP3_LUT;
case OP_MAX:
case OP_MIN:
if (isFloatType(i->dType)) {
if (i->dType == TYPE_F32)
return &opInfo_FMNMX;
} else {
return &opInfo_IMNMX;
}
break;
case OP_MEMBAR: return &opInfo_MEMBAR;
case OP_MOV: return &opInfo_MOV;
case OP_MUL:
if (isFloatType(i->dType)) {
if (i->dType == TYPE_F32)
return &opInfo_FMUL;
else
return &opInfo_DMUL;
}
return &opInfo_IMUL;
case OP_NEG:
if (isFloatType(i->dType))
return &opInfo_FNEG;
return &opInfo_INEG;
case OP_NOT: return &opInfo_NOT;
case OP_PERMT: return &opInfo_PRMT;
case OP_PFETCH: return &opInfo_ISBERD;
case OP_PIXLD: return &opInfo_PIXLD;
case OP_POPCNT: return &opInfo_POPC;
case OP_QUADOP: return &opInfo_FSWZADD;
case OP_RDSV:
#if 0
if (targ->isCS2RSV(i->getSrc(0)->reg.data.sv.sv))
return &opInfo_CS2R;
#endif
return &opInfo_S2R;
case OP_SAT: return &opInfo_SAT;
case OP_SELP: return &opInfo_SEL;
case OP_SET:
case OP_SET_AND:
case OP_SET_OR:
case OP_SET_XOR:
if (i->def(0).getFile() != FILE_PREDICATE) {
if (isFloatType(i->dType)) {
if (i->dType == TYPE_F32)
return &opInfo_FSET_BF;
} else {
if (isFloatType(i->sType))
return &opInfo_FSET;
return &opInfo_ISET;
}
} else {
if (isFloatType(i->sType))
if (i->sType == TYPE_F64)
return &opInfo_DSETP;
else
return &opInfo_FSETP;
else
return &opInfo_ISETP;
}
break;
case OP_SGXT: return &opInfo_SGXT;
case OP_SHF: return &opInfo_SHF;
case OP_SHFL: return &opInfo_SHFL;
case OP_SHL: return &opInfo_SHL;
case OP_SHLADD: return &opInfo_LEA;
case OP_SHR: return &opInfo_SHR;
case OP_SLCT:
if (isFloatType(i->sType))
return &opInfo_FCMP;
return &opInfo_ICMP;
case OP_STORE:
switch (i->src(0).getFile()) {
case FILE_MEMORY_LOCAL : return &opInfo_STL;
case FILE_MEMORY_SHARED: return &opInfo_STS;
case FILE_MEMORY_GLOBAL: return &opInfo_ST;
default:
break;
}
break;
case OP_SUB: return &opInfo_SUB;
case OP_SULDB:
case OP_SULDP: return &opInfo_SULD;
case OP_SUREDB:
case OP_SUREDP: return &opInfo_SUATOM;
case OP_SUSTB:
case OP_SUSTP: return &opInfo_SUST;
case OP_TEX:
case OP_TXB:
case OP_TXL: return &opInfo_TEX;
case OP_TXD: return &opInfo_TXD;
case OP_TXF: return &opInfo_TLD;
case OP_TXG: return &opInfo_TLD4;
case OP_TXLQ: return &opInfo_TMML;
case OP_TXQ: return &opInfo_TXQ;
case OP_VFETCH: return &opInfo_ALD;
case OP_VOTE: return &opInfo_VOTE;
case OP_WARPSYNC: return &opInfo_WARPSYNC;
default:
break;
}
return NULL;
}
bool
TargetGV100::isSatSupported(const Instruction *i) const
{
switch (i->dType) {
case TYPE_F32:
switch (i->op) {
case OP_ADD:
case OP_FMA:
case OP_MAD:
case OP_MUL: return true;
default:
break;
}
break;
default:
break;
}
return false;
}
bool
TargetGV100::isModSupported(const Instruction *i, int s, Modifier mod) const
{
const struct opInfo *info = nv50_ir::getOpInfo(i);
uint8_t mods = 0;
if (info && s < (int)ARRAY_SIZE(info->src))
mods = info->src[s].mods;
return (mod & Modifier(mods)) == mod;
}
bool
TargetGV100::isOpSupported(operation op, DataType ty) const
{
if (op == OP_MAD || op == OP_FMA)
return true;
if (ty == TYPE_F32) {
if (op == OP_MAX)
return true;
}
if (op == OP_RSQ)
return true;
if (op == OP_SET ||
op == OP_SET_AND ||
op == OP_SET_OR ||
op == OP_SET_XOR)
return true;
if (op == OP_SHLADD)
return true;
return false;
}
bool
TargetGV100::isBarrierRequired(const Instruction *i) const
{
switch (i->op) {
case OP_BREV:
return true;
default:
break;
}
return TargetGM107::isBarrierRequired(i);
}
bool
TargetGV100::insnCanLoad(const Instruction *i, int s,
const Instruction *ld) const
{
const struct opInfo *info = nv50_ir::getOpInfo(i);
uint16_t files = 0;
if (ld->src(0).getFile() == FILE_IMMEDIATE && ld->getSrc(0)->reg.data.u64 == 0)
return (!i->isPseudo() &&
!i->asTex() &&
i->op != OP_EXPORT && i->op != OP_STORE);
if (ld->src(0).isIndirect(0))
return false;
if (info && s < (int)ARRAY_SIZE(info->src)) {
files = info->src[s].files;
if ((s == 1 && i->srcExists(2) && i->src(2).getFile() != FILE_GPR) ||
(s == 2 && i->srcExists(1) && i->src(1).getFile() != FILE_GPR)) {
files &= ~(1 << FILE_MEMORY_CONST);
files &= ~(1 << FILE_IMMEDIATE);
} else
if ((i->op == OP_SHL || i->op == OP_SHR) &&
((s == 0 && i->srcExists(1) && i->src(1).getFile() != FILE_GPR) ||
(s == 1 && i->srcExists(0) && i->src(0).getFile() != FILE_GPR))) {
files &= ~(1 << FILE_MEMORY_CONST);
files &= ~(1 << FILE_IMMEDIATE);
}
}
if (ld->src(0).getFile() == FILE_IMMEDIATE) {
if (i->sType == TYPE_F64) {
if (ld->getSrc(0)->asImm()->reg.data.u64 & 0x00000000ffffffff)
return false;
}
}
return (files & (1 << ld->src(0).getFile()));
}
void
TargetGV100::getBuiltinCode(const uint32_t **code, uint32_t *size) const
{
//XXX: find out why gv100 (tu1xx is fine) hangs without this
static uint32_t builtin[] = {
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
0x0000794d, 0x00000000, 0x03800000, 0x03ffde00,
};
*code = builtin;
*size = sizeof(builtin);
}
uint32_t
TargetGV100::getBuiltinOffset(int builtin) const
{
return 0;
}
bool
TargetGV100::runLegalizePass(Program *prog, CGStage stage) const
{
if (stage == CG_STAGE_PRE_SSA) {
GM107LoweringPass pass1(prog);
GV100LoweringPass pass2(prog);
pass1.run(prog, false, true);
pass2.run(prog, false, true);
return true;
} else
if (stage == CG_STAGE_SSA) {
GV100LegalizeSSA pass(prog);
return pass.run(prog, false, true);
} else
if (stage == CG_STAGE_POST_RA) {
NVC0LegalizePostRA pass(prog);
return pass.run(prog, false, true);
}
return false;
}
CodeEmitter *
TargetGV100::getCodeEmitter(Program::Type type)
{
return new CodeEmitterGV100(this);
}
TargetGV100::TargetGV100(unsigned int chipset)
: TargetGM107(chipset)
{
initOpInfo();
};
Target *getTargetGV100(unsigned int chipset)
{
return new TargetGV100(chipset);
}
};