X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fnouveau%2Fcodegen%2Fnv50_ir_emit_gm107.cpp;h=5ae189873ad365ede9ee935e341d1578374a93fd;hb=0904a2ba9717e5706f8869dc9244e2c742fadd12;hp=93c40d15e465fe02b8164206722d9d7e85df6737;hpb=ca23c8081f1f9f709df7a63b9e6de379c0b8df44;p=mesa.git diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp index 93c40d15e46..5ae189873ad 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -126,6 +126,7 @@ private: void emitF2I(); void emitI2F(); void emitI2I(); + void emitSEL(); void emitSHFL(); void emitDADD(); @@ -177,6 +178,7 @@ private: void emitAL2P(); void emitIPA(); void emitATOM(); + void emitATOMS(); void emitCCTL(); void emitPIXLD(); @@ -194,7 +196,10 @@ private: void emitKIL(); void emitOUT(); + void emitBAR(); void emitMEMBAR(); + + void emitVOTE(); }; /******************************************************************************* @@ -415,7 +420,7 @@ CodeEmitterGM107::emitSAT(int pos) void CodeEmitterGM107::emitCC(int pos) { - emitField(pos, 1, insn->defExists(1)); + emitField(pos, 1, insn->flagsDef >= 0); } void @@ -673,8 +678,7 @@ CodeEmitterGM107::emitRAM() void CodeEmitterGM107::emitMOV() { - if ( insn->src(0).getFile() != FILE_IMMEDIATE || - (insn->sType != TYPE_F32 && !longIMMD(insn->src(0)))) { + if (insn->src(0).getFile() != FILE_IMMEDIATE) { switch (insn->src(0).getFile()) { case FILE_GPR: if (insn->def(0).getFile() == FILE_PREDICATE) { @@ -889,6 +893,47 @@ CodeEmitterGM107::emitI2I() emitGPR (0x00, insn->def(0)); } +static void +selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data) +{ + int loc = entry->loc; + if (data.force_persample_interp) + code[loc + 1] |= 1 << 10; + else + code[loc + 1] &= ~(1 << 10); +} + +void +CodeEmitterGM107::emitSEL() +{ + switch (insn->src(1).getFile()) { + case FILE_GPR: + emitInsn(0x5ca00000); + emitGPR (0x14, insn->src(1)); + break; + case FILE_MEMORY_CONST: + emitInsn(0x4ca00000); + emitCBUF(0x22, -1, 0x14, 16, 2, insn->src(1)); + break; + case FILE_IMMEDIATE: + emitInsn(0x38a00000); + emitIMMD(0x14, 19, insn->src(1)); + break; + default: + assert(!"bad src1 file"); + break; + } + + emitINV (0x2a, insn->src(2)); + emitPRED(0x27, insn->src(2)); + emitGPR (0x08, insn->src(0)); + emitGPR (0x00, insn->def(0)); + + if (insn->subOp == 1) { + addInterp(0, 0, selpFlip); + } +} + void CodeEmitterGM107::emitSHFL() { @@ -1189,6 +1234,9 @@ CodeEmitterGM107::emitFADD() emitABS(0x2e, insn->src(0)); emitNEG(0x2d, insn->src(1)); emitFMZ(0x2c, 1); + + if (insn->op == OP_SUB) + code[1] ^= 0x00002000; } else { emitInsn(0x08000000); emitABS(0x39, insn->src(1)); @@ -1198,10 +1246,10 @@ CodeEmitterGM107::emitFADD() emitNEG(0x35, insn->src(1)); emitCC (0x34); emitIMMD(0x14, 32, insn->src(1)); - } - if (insn->op == OP_SUB) - code[1] ^= 0x00002000; + if (insn->op == OP_SUB) + code[1] ^= 0x00080000; + } emitGPR(0x08, insn->src(0)); emitGPR(0x00, insn->def(0)); @@ -1561,7 +1609,7 @@ CodeEmitterGM107::emitLOP() break; } - if (!longIMMD(insn->src(1))) { + if (insn->src(1).getFile() != FILE_IMMEDIATE) { switch (insn->src(1).getFile()) { case FILE_GPR: emitInsn(0x5c400000); @@ -1580,6 +1628,7 @@ CodeEmitterGM107::emitLOP() break; } emitPRED (0x30); + emitCC (0x2f); emitX (0x2b); emitField(0x29, 2, lop); emitINV (0x28, insn->src(1)); @@ -1590,6 +1639,7 @@ CodeEmitterGM107::emitLOP() emitINV (0x38, insn->src(1)); emitINV (0x37, insn->src(0)); emitField(0x35, 2, lop); + emitCC (0x34); emitIMMD (0x14, 32, insn->src(1)); } @@ -1657,6 +1707,7 @@ CodeEmitterGM107::emitIADD() emitX (0x2b); } else { emitInsn(0x1c000000); + emitNEG (0x38, insn->src(0)); emitSAT (0x36); emitX (0x35); emitCC (0x34); @@ -1673,7 +1724,7 @@ CodeEmitterGM107::emitIADD() void CodeEmitterGM107::emitIMUL() { - if (!longIMMD(insn->src(1))) { + if (insn->src(1).getFile() != FILE_IMMEDIATE) { switch (insn->src(1).getFile()) { case FILE_GPR: emitInsn(0x5c380000); @@ -2257,18 +2308,17 @@ CodeEmitterGM107::emitAL2P() } static void -interpApply(const InterpEntry *entry, uint32_t *code, - bool force_persample_interp, bool flatshade) +interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data) { int ipa = entry->ipa; int reg = entry->reg; int loc = entry->loc; - if (flatshade && + if (data.flatshade && (ipa & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_SC) { ipa = NV50_IR_INTERP_FLAT; reg = 0xff; - } else if (force_persample_interp && + } else if (data.force_persample_interp && (ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT && (ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) { ipa |= NV50_IR_INTERP_CENTROID; @@ -2370,6 +2420,45 @@ CodeEmitterGM107::emitATOM() emitGPR (0x00, insn->def(0)); } +void +CodeEmitterGM107::emitATOMS() +{ + unsigned dType, subOp; + + if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) { + switch (insn->dType) { + case TYPE_U32: dType = 0; break; + case TYPE_U64: dType = 1; break; + default: assert(!"unexpected dType"); dType = 0; break; + } + subOp = 4; + + emitInsn (0xee000000); + emitField(0x34, 1, dType); + } else { + switch (insn->dType) { + case TYPE_U32: dType = 0; break; + case TYPE_S32: dType = 1; break; + case TYPE_U64: dType = 2; break; + case TYPE_S64: dType = 3; break; + default: assert(!"unexpected dType"); dType = 0; break; + } + + if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH) + subOp = 8; + else + subOp = insn->subOp; + + emitInsn (0xec000000); + emitField(0x1c, 3, dType); + } + + emitField(0x34, 4, subOp); + emitGPR (0x14, insn->src(1)); + emitADDR (0x08, 0x12, 22, 0, insn->src(0)); + emitGPR (0x00, insn->def(0)); +} + void CodeEmitterGM107::emitCCTL() { @@ -2646,6 +2735,54 @@ CodeEmitterGM107::emitOUT() emitGPR (0x00, insn->def(0)); } +void +CodeEmitterGM107::emitBAR() +{ + uint8_t subop; + + emitInsn (0xf0a80000); + + switch (insn->subOp) { + case NV50_IR_SUBOP_BAR_RED_POPC: subop = 0x02; break; + case NV50_IR_SUBOP_BAR_RED_AND: subop = 0x0a; break; + case NV50_IR_SUBOP_BAR_RED_OR: subop = 0x12; break; + case NV50_IR_SUBOP_BAR_ARRIVE: subop = 0x81; break; + default: + subop = 0x80; + assert(insn->subOp == NV50_IR_SUBOP_BAR_SYNC); + break; + } + + emitField(0x20, 8, subop); + + // barrier id + if (insn->src(0).getFile() == FILE_GPR) { + emitGPR(0x08, insn->src(0)); + } else { + ImmediateValue *imm = insn->getSrc(0)->asImm(); + assert(imm); + emitField(0x08, 8, imm->reg.data.u32); + emitField(0x2b, 1, 1); + } + + // thread count + if (insn->src(1).getFile() == FILE_GPR) { + emitGPR(0x14, insn->src(1)); + } else { + ImmediateValue *imm = insn->getSrc(0)->asImm(); + assert(imm); + emitField(0x14, 12, imm->reg.data.u32); + emitField(0x2c, 1, 1); + } + + if (insn->srcExists(2) && (insn->predSrc != 2)) { + emitPRED (0x27, insn->src(2)); + emitField(0x2a, 1, insn->src(2).mod == Modifier(NV50_IR_MOD_NOT)); + } else { + emitField(0x27, 3, 7); + } +} + void CodeEmitterGM107::emitMEMBAR() { @@ -2653,6 +2790,33 @@ CodeEmitterGM107::emitMEMBAR() emitField(0x08, 2, insn->subOp >> 2); } +void +CodeEmitterGM107::emitVOTE() +{ + assert(insn->src(0).getFile() == FILE_PREDICATE); + + int r = -1, p = -1; + for (int i = 0; insn->defExists(i); i++) { + if (insn->def(i).getFile() == FILE_GPR) + r = i; + else if (insn->def(i).getFile() == FILE_PREDICATE) + p = i; + } + + emitInsn (0x50d80000); + emitField(0x30, 2, insn->subOp); + if (r >= 0) + emitGPR (0x00, insn->def(r)); + else + emitGPR (0x00); + if (p >= 0) + emitPRED (0x2d, insn->def(p)); + else + emitPRED (0x2d); + emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT)); + emitPRED (0x27, insn->src(0)); +} + /******************************************************************************* * assembler front-end ******************************************************************************/ @@ -2848,6 +3012,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i) emitISETP(); } break; + case OP_SELP: + emitSEL(); + break; case OP_PRESIN: case OP_PREEX2: emitRRO(); @@ -2886,13 +3053,16 @@ CodeEmitterGM107::emitInstruction(Instruction *i) case FILE_MEMORY_SHARED: emitSTS(); break; case FILE_MEMORY_GLOBAL: emitST(); break; default: - assert(!"invalid load"); + assert(!"invalid store"); emitNOP(); break; } break; case OP_ATOM: - emitATOM(); + if (insn->src(0).getFile() == FILE_MEMORY_SHARED) + emitATOMS(); + else + emitATOM(); break; case OP_CCTL: emitCCTL(); @@ -2952,9 +3122,15 @@ CodeEmitterGM107::emitInstruction(Instruction *i) case OP_RESTART: emitOUT(); break; + case OP_BAR: + emitBAR(); + break; case OP_MEMBAR: emitMEMBAR(); break; + case OP_VOTE: + emitVOTE(); + break; default: assert(!"invalid opcode"); emitNOP();