2 * Copyright 2014 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 #include "codegen/nv50_ir_target_gm107.h"
29 class CodeEmitterGM107
: public CodeEmitter
32 CodeEmitterGM107(const TargetGM107
*);
34 virtual bool emitInstruction(Instruction
*);
35 virtual uint32_t getMinEncodingSize(const Instruction
*) const;
37 virtual void prepareEmission(Program
*);
38 virtual void prepareEmission(Function
*);
40 inline void setProgramType(Program::Type pType
) { progType
= pType
; }
43 const TargetGM107
*targGM107
;
45 Program::Type progType
;
47 const Instruction
*insn
;
48 const bool writeIssueDelays
;
52 inline void emitField(uint32_t *, int, int, uint32_t);
53 inline void emitField(int b
, int s
, uint32_t v
) { emitField(code
, b
, s
, v
); }
55 inline void emitInsn(uint32_t, bool);
56 inline void emitInsn(uint32_t o
) { emitInsn(o
, true); }
57 inline void emitPred();
58 inline void emitGPR(int, const Value
*);
59 inline void emitGPR(int pos
) {
60 emitGPR(pos
, (const Value
*)NULL
);
62 inline void emitGPR(int pos
, const ValueRef
&ref
) {
63 emitGPR(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
65 inline void emitGPR(int pos
, const ValueRef
*ref
) {
66 emitGPR(pos
, ref
? ref
->rep() : (const Value
*)NULL
);
68 inline void emitGPR(int pos
, const ValueDef
&def
) {
69 emitGPR(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
71 inline void emitSYS(int, const Value
*);
72 inline void emitSYS(int pos
, const ValueRef
&ref
) {
73 emitSYS(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
75 inline void emitPRED(int, const Value
*);
76 inline void emitPRED(int pos
) {
77 emitPRED(pos
, (const Value
*)NULL
);
79 inline void emitPRED(int pos
, const ValueRef
&ref
) {
80 emitPRED(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
82 inline void emitPRED(int pos
, const ValueDef
&def
) {
83 emitPRED(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
85 inline void emitADDR(int, int, int, int, const ValueRef
&);
86 inline void emitCBUF(int, int, int, int, int, const ValueRef
&);
87 inline bool longIMMD(const ValueRef
&);
88 inline void emitIMMD(int, int, const ValueRef
&);
90 void emitCond3(int, CondCode
);
91 void emitCond4(int, CondCode
);
92 void emitCond5(int pos
, CondCode cc
) { emitCond4(pos
, cc
); }
93 inline void emitO(int);
94 inline void emitP(int);
95 inline void emitSAT(int);
96 inline void emitCC(int);
97 inline void emitX(int);
98 inline void emitABS(int, const ValueRef
&);
99 inline void emitNEG(int, const ValueRef
&);
100 inline void emitNEG2(int, const ValueRef
&, const ValueRef
&);
101 inline void emitFMZ(int, int);
102 inline void emitRND(int, RoundMode
, int);
103 inline void emitRND(int pos
) {
104 emitRND(pos
, insn
->rnd
, -1);
106 inline void emitPDIV(int);
107 inline void emitINV(int, const ValueRef
&);
166 void emitLDSTs(int, DataType
);
205 void emitSUHandle(const int s
);
210 /*******************************************************************************
211 * general instruction layout/fields
212 ******************************************************************************/
215 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
218 uint32_t m
= ((1ULL << s
) - 1);
219 uint64_t d
= (uint64_t)(v
& m
) << b
;
220 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
227 CodeEmitterGM107::emitPred()
229 if (insn
->predSrc
>= 0) {
230 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
231 emitField(19, 1, insn
->cc
== CC_NOT_P
);
238 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
240 code
[0] = 0x00000000;
247 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
249 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
253 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
255 int id
= val
? val
->reg
.data
.id
: -1;
258 case SV_LANEID
: id
= 0x00; break;
259 case SV_VERTEX_COUNT
: id
= 0x10; break;
260 case SV_INVOCATION_ID
: id
= 0x11; break;
261 case SV_THREAD_KILL
: id
= 0x13; break;
262 case SV_INVOCATION_INFO
: id
= 0x1d; break;
263 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
264 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
266 assert(!"invalid system value");
271 emitField(pos
, 8, id
);
275 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
277 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
281 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
284 const Value
*v
= ref
.get();
285 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
287 emitGPR(gpr
, ref
.getIndirect(0));
288 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
292 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
295 const Value
*v
= ref
.get();
296 const Symbol
*s
= v
->asSym();
298 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
300 emitField(buf
, 5, v
->reg
.fileIndex
);
302 emitGPR(gpr
, ref
.getIndirect(0));
303 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
307 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
309 if (ref
.getFile() == FILE_IMMEDIATE
) {
310 const ImmediateValue
*imm
= ref
.get()->asImm();
311 if (isFloatType(insn
->sType
)) {
312 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
315 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
316 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
324 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
326 const ImmediateValue
*imm
= ref
.get()->asImm();
327 uint32_t val
= imm
->reg
.data
.u32
;
330 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
331 assert(!(val
& 0x00000fff));
333 } else if (insn
->sType
== TYPE_F64
) {
334 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
335 val
= imm
->reg
.data
.u64
>> 44;
337 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
338 emitField( 56, 1, (val
& 0x80000) >> 19);
339 emitField(pos
, len
, (val
& 0x7ffff));
341 emitField(pos
, len
, val
);
345 /*******************************************************************************
347 ******************************************************************************/
350 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
355 case CC_FL
: data
= 0x00; break;
357 case CC_LT
: data
= 0x01; break;
359 case CC_EQ
: data
= 0x02; break;
361 case CC_LE
: data
= 0x03; break;
363 case CC_GT
: data
= 0x04; break;
365 case CC_NE
: data
= 0x05; break;
367 case CC_GE
: data
= 0x06; break;
368 case CC_TR
: data
= 0x07; break;
370 assert(!"invalid cond3");
374 emitField(pos
, 3, data
);
378 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
383 case CC_FL
: data
= 0x00; break;
384 case CC_LT
: data
= 0x01; break;
385 case CC_EQ
: data
= 0x02; break;
386 case CC_LE
: data
= 0x03; break;
387 case CC_GT
: data
= 0x04; break;
388 case CC_NE
: data
= 0x05; break;
389 case CC_GE
: data
= 0x06; break;
390 // case CC_NUM: data = 0x07; break;
391 // case CC_NAN: data = 0x08; break;
392 case CC_LTU
: data
= 0x09; break;
393 case CC_EQU
: data
= 0x0a; break;
394 case CC_LEU
: data
= 0x0b; break;
395 case CC_GTU
: data
= 0x0c; break;
396 case CC_NEU
: data
= 0x0d; break;
397 case CC_GEU
: data
= 0x0e; break;
398 case CC_TR
: data
= 0x0f; break;
400 assert(!"invalid cond4");
404 emitField(pos
, 4, data
);
408 CodeEmitterGM107::emitO(int pos
)
410 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
414 CodeEmitterGM107::emitP(int pos
)
416 emitField(pos
, 1, insn
->perPatch
);
420 CodeEmitterGM107::emitSAT(int pos
)
422 emitField(pos
, 1, insn
->saturate
);
426 CodeEmitterGM107::emitCC(int pos
)
428 emitField(pos
, 1, insn
->flagsDef
>= 0);
432 CodeEmitterGM107::emitX(int pos
)
434 emitField(pos
, 1, insn
->flagsSrc
>= 0);
438 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
440 emitField(pos
, 1, ref
.mod
.abs());
444 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
446 emitField(pos
, 1, ref
.mod
.neg());
450 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
452 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
456 CodeEmitterGM107::emitFMZ(int pos
, int len
)
458 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
462 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
466 case ROUND_NI
: ri
= 1;
467 case ROUND_N
: rm
= 0; break;
468 case ROUND_MI
: ri
= 1;
469 case ROUND_M
: rm
= 1; break;
470 case ROUND_PI
: ri
= 1;
471 case ROUND_P
: rm
= 2; break;
472 case ROUND_ZI
: ri
= 1;
473 case ROUND_Z
: rm
= 3; break;
475 assert(!"invalid round mode");
478 emitField(rip
, 1, ri
);
479 emitField(rmp
, 2, rm
);
483 CodeEmitterGM107::emitPDIV(int pos
)
485 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
486 if (insn
->postFactor
> 0)
487 emitField(pos
, 3, 7 - insn
->postFactor
);
489 emitField(pos
, 3, 0 - insn
->postFactor
);
493 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
495 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
498 /*******************************************************************************
500 ******************************************************************************/
503 CodeEmitterGM107::emitEXIT()
505 emitInsn (0xe3000000);
506 emitCond5(0x00, CC_TR
);
510 CodeEmitterGM107::emitBRA()
512 const FlowInstruction
*insn
= this->insn
->asFlow();
515 if (insn
->indirect
) {
517 emitInsn(0xe2000000); // JMX
519 emitInsn(0xe2500000); // BRX
523 emitInsn(0xe2100000); // JMP
525 emitInsn(0xe2400000); // BRA
526 emitField(0x07, 1, insn
->allWarp
);
529 emitField(0x06, 1, insn
->limit
);
530 emitCond5(0x00, CC_TR
);
532 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
533 int32_t pos
= insn
->target
.bb
->binPos
;
534 if (writeIssueDelays
&& !(pos
& 0x1f))
537 emitField(0x14, 24, pos
- (codeSize
+ 8));
539 emitField(0x14, 32, pos
);
541 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
542 emitField(0x05, 1, 1);
547 CodeEmitterGM107::emitCAL()
549 const FlowInstruction
*insn
= this->insn
->asFlow();
551 if (insn
->absolute
) {
552 emitInsn(0xe2200000, 0); // JCAL
554 emitInsn(0xe2600000, 0); // CAL
557 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
559 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
562 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
563 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
564 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
566 emitField(0x14, 32, insn
->target
.bb
->binPos
);
570 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
571 emitField(0x05, 1, 1);
576 CodeEmitterGM107::emitPCNT()
578 const FlowInstruction
*insn
= this->insn
->asFlow();
580 emitInsn(0xe2b00000, 0);
582 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
583 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
585 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
586 emitField(0x05, 1, 1);
591 CodeEmitterGM107::emitCONT()
593 emitInsn (0xe3500000);
594 emitCond5(0x00, CC_TR
);
598 CodeEmitterGM107::emitPBK()
600 const FlowInstruction
*insn
= this->insn
->asFlow();
602 emitInsn(0xe2a00000, 0);
604 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
605 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
607 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
608 emitField(0x05, 1, 1);
613 CodeEmitterGM107::emitBRK()
615 emitInsn (0xe3400000);
616 emitCond5(0x00, CC_TR
);
620 CodeEmitterGM107::emitPRET()
622 const FlowInstruction
*insn
= this->insn
->asFlow();
624 emitInsn(0xe2700000, 0);
626 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
627 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
629 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
630 emitField(0x05, 1, 1);
635 CodeEmitterGM107::emitRET()
637 emitInsn (0xe3200000);
638 emitCond5(0x00, CC_TR
);
642 CodeEmitterGM107::emitSSY()
644 const FlowInstruction
*insn
= this->insn
->asFlow();
646 emitInsn(0xe2900000, 0);
648 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
649 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
651 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
652 emitField(0x05, 1, 1);
657 CodeEmitterGM107::emitSYNC()
659 emitInsn (0xf0f80000);
660 emitCond5(0x00, CC_TR
);
664 CodeEmitterGM107::emitSAM()
666 emitInsn(0xe3700000, 0);
670 CodeEmitterGM107::emitRAM()
672 emitInsn(0xe3800000, 0);
675 /*******************************************************************************
677 ******************************************************************************/
679 /*******************************************************************************
680 * movement / conversion
681 ******************************************************************************/
684 CodeEmitterGM107::emitMOV()
686 if (insn
->src(0).getFile() != FILE_IMMEDIATE
) {
687 switch (insn
->src(0).getFile()) {
689 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
690 emitInsn(0x5b6a0000);
693 emitInsn(0x5c980000);
695 emitGPR (0x14, insn
->src(0));
697 case FILE_MEMORY_CONST
:
698 emitInsn(0x4c980000);
699 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
702 emitInsn(0x38980000);
703 emitIMMD(0x14, 19, insn
->src(0));
706 emitInsn(0x50880000);
707 emitPRED(0x0c, insn
->src(0));
712 assert(!"bad src file");
715 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
716 insn
->src(0).getFile() != FILE_PREDICATE
)
717 emitField(0x27, 4, insn
->lanes
);
719 emitInsn (0x01000000);
720 emitIMMD (0x14, 32, insn
->src(0));
721 emitField(0x0c, 4, insn
->lanes
);
724 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
726 emitPRED(0x03, insn
->def(0));
729 emitGPR(0x00, insn
->def(0));
734 CodeEmitterGM107::emitS2R()
736 emitInsn(0xf0c80000);
737 emitSYS (0x14, insn
->src(0));
738 emitGPR (0x00, insn
->def(0));
742 CodeEmitterGM107::emitF2F()
744 RoundMode rnd
= insn
->rnd
;
747 case OP_FLOOR
: rnd
= ROUND_MI
; break;
748 case OP_CEIL
: rnd
= ROUND_PI
; break;
749 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
754 switch (insn
->src(0).getFile()) {
756 emitInsn(0x5ca80000);
757 emitGPR (0x14, insn
->src(0));
759 case FILE_MEMORY_CONST
:
760 emitInsn(0x4ca80000);
761 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
764 emitInsn(0x38a80000);
765 emitIMMD(0x14, 19, insn
->src(0));
768 assert(!"bad src0 file");
772 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
773 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
775 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
777 emitField(0x29, 1, insn
->subOp
);
778 emitRND (0x27, rnd
, 0x2a);
779 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
780 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
781 emitGPR (0x00, insn
->def(0));
785 CodeEmitterGM107::emitF2I()
787 RoundMode rnd
= insn
->rnd
;
790 case OP_FLOOR
: rnd
= ROUND_M
; break;
791 case OP_CEIL
: rnd
= ROUND_P
; break;
792 case OP_TRUNC
: rnd
= ROUND_Z
; break;
797 switch (insn
->src(0).getFile()) {
799 emitInsn(0x5cb00000);
800 emitGPR (0x14, insn
->src(0));
802 case FILE_MEMORY_CONST
:
803 emitInsn(0x4cb00000);
804 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
807 emitInsn(0x38b00000);
808 emitIMMD(0x14, 19, insn
->src(0));
811 assert(!"bad src0 file");
815 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
817 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
819 emitRND (0x27, rnd
, 0x2a);
820 emitField(0x0c, 1, isSignedType(insn
->dType
));
821 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
822 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
823 emitGPR (0x00, insn
->def(0));
827 CodeEmitterGM107::emitI2F()
829 RoundMode rnd
= insn
->rnd
;
832 case OP_FLOOR
: rnd
= ROUND_M
; break;
833 case OP_CEIL
: rnd
= ROUND_P
; break;
834 case OP_TRUNC
: rnd
= ROUND_Z
; break;
839 switch (insn
->src(0).getFile()) {
841 emitInsn(0x5cb80000);
842 emitGPR (0x14, insn
->src(0));
844 case FILE_MEMORY_CONST
:
845 emitInsn(0x4cb80000);
846 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
849 emitInsn(0x38b80000);
850 emitIMMD(0x14, 19, insn
->src(0));
853 assert(!"bad src0 file");
857 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
859 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
860 emitField(0x29, 2, insn
->subOp
);
861 emitRND (0x27, rnd
, -1);
862 emitField(0x0d, 1, isSignedType(insn
->sType
));
863 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
864 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
865 emitGPR (0x00, insn
->def(0));
869 CodeEmitterGM107::emitI2I()
871 switch (insn
->src(0).getFile()) {
873 emitInsn(0x5ce00000);
874 emitGPR (0x14, insn
->src(0));
876 case FILE_MEMORY_CONST
:
877 emitInsn(0x4ce00000);
878 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
881 emitInsn(0x38e00000);
882 emitIMMD(0x14, 19, insn
->src(0));
885 assert(!"bad src0 file");
890 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
892 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
893 emitField(0x29, 2, insn
->subOp
);
894 emitField(0x0d, 1, isSignedType(insn
->sType
));
895 emitField(0x0c, 1, isSignedType(insn
->dType
));
896 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
897 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
898 emitGPR (0x00, insn
->def(0));
902 selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
904 int loc
= entry
->loc
;
905 if (data
.force_persample_interp
)
906 code
[loc
+ 1] |= 1 << 10;
908 code
[loc
+ 1] &= ~(1 << 10);
912 CodeEmitterGM107::emitSEL()
914 switch (insn
->src(1).getFile()) {
916 emitInsn(0x5ca00000);
917 emitGPR (0x14, insn
->src(1));
919 case FILE_MEMORY_CONST
:
920 emitInsn(0x4ca00000);
921 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
924 emitInsn(0x38a00000);
925 emitIMMD(0x14, 19, insn
->src(1));
928 assert(!"bad src1 file");
932 emitINV (0x2a, insn
->src(2));
933 emitPRED(0x27, insn
->src(2));
934 emitGPR (0x08, insn
->src(0));
935 emitGPR (0x00, insn
->def(0));
937 if (insn
->subOp
== 1) {
938 addInterp(0, 0, selpFlip
);
943 CodeEmitterGM107::emitSHFL()
947 emitInsn (0xef100000);
949 switch (insn
->src(1).getFile()) {
951 emitGPR(0x14, insn
->src(1));
954 emitIMMD(0x14, 5, insn
->src(1));
958 assert(!"invalid src1 file");
962 /*XXX: what is this arg? hardcode immediate for now */
963 emitField(0x22, 13, 0x1c03);
967 emitField(0x1e, 2, insn
->subOp
);
968 emitField(0x1c, 2, type
);
969 emitGPR (0x08, insn
->src(0));
970 emitGPR (0x00, insn
->def(0));
973 /*******************************************************************************
975 ******************************************************************************/
978 CodeEmitterGM107::emitDADD()
980 switch (insn
->src(1).getFile()) {
982 emitInsn(0x5c700000);
983 emitGPR (0x14, insn
->src(1));
985 case FILE_MEMORY_CONST
:
986 emitInsn(0x4c700000);
987 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
990 emitInsn(0x38700000);
991 emitIMMD(0x14, 19, insn
->src(1));
994 assert(!"bad src1 file");
997 emitABS(0x31, insn
->src(1));
998 emitNEG(0x30, insn
->src(0));
1000 emitABS(0x2e, insn
->src(0));
1001 emitNEG(0x2d, insn
->src(1));
1003 if (insn
->op
== OP_SUB
)
1004 code
[1] ^= 0x00002000;
1006 emitGPR(0x08, insn
->src(0));
1007 emitGPR(0x00, insn
->def(0));
1011 CodeEmitterGM107::emitDMUL()
1013 switch (insn
->src(1).getFile()) {
1015 emitInsn(0x5c800000);
1016 emitGPR (0x14, insn
->src(1));
1018 case FILE_MEMORY_CONST
:
1019 emitInsn(0x4c800000);
1020 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1022 case FILE_IMMEDIATE
:
1023 emitInsn(0x38800000);
1024 emitIMMD(0x14, 19, insn
->src(1));
1027 assert(!"bad src1 file");
1031 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1034 emitGPR (0x08, insn
->src(0));
1035 emitGPR (0x00, insn
->def(0));
1039 CodeEmitterGM107::emitDFMA()
1041 switch(insn
->src(2).getFile()) {
1043 switch (insn
->src(1).getFile()) {
1045 emitInsn(0x5b700000);
1046 emitGPR (0x14, insn
->src(1));
1048 case FILE_MEMORY_CONST
:
1049 emitInsn(0x4b700000);
1050 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1052 case FILE_IMMEDIATE
:
1053 emitInsn(0x36700000);
1054 emitIMMD(0x14, 19, insn
->src(1));
1057 assert(!"bad src1 file");
1060 emitGPR (0x27, insn
->src(2));
1062 case FILE_MEMORY_CONST
:
1063 emitInsn(0x53700000);
1064 emitGPR (0x27, insn
->src(1));
1065 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1068 assert(!"bad src2 file");
1073 emitNEG (0x31, insn
->src(2));
1074 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1076 emitGPR (0x08, insn
->src(0));
1077 emitGPR (0x00, insn
->def(0));
1081 CodeEmitterGM107::emitDMNMX()
1083 switch (insn
->src(1).getFile()) {
1085 emitInsn(0x5c500000);
1086 emitGPR (0x14, insn
->src(1));
1088 case FILE_MEMORY_CONST
:
1089 emitInsn(0x4c500000);
1090 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1092 case FILE_IMMEDIATE
:
1093 emitInsn(0x38500000);
1094 emitIMMD(0x14, 19, insn
->src(1));
1097 assert(!"bad src1 file");
1101 emitABS (0x31, insn
->src(1));
1102 emitNEG (0x30, insn
->src(0));
1104 emitABS (0x2e, insn
->src(0));
1105 emitNEG (0x2d, insn
->src(1));
1106 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1108 emitGPR (0x08, insn
->src(0));
1109 emitGPR (0x00, insn
->def(0));
1113 CodeEmitterGM107::emitDSET()
1115 const CmpInstruction
*insn
= this->insn
->asCmp();
1117 switch (insn
->src(1).getFile()) {
1119 emitInsn(0x59000000);
1120 emitGPR (0x14, insn
->src(1));
1122 case FILE_MEMORY_CONST
:
1123 emitInsn(0x49000000);
1124 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1126 case FILE_IMMEDIATE
:
1127 emitInsn(0x32000000);
1128 emitIMMD(0x14, 19, insn
->src(1));
1131 assert(!"bad src1 file");
1135 if (insn
->op
!= OP_SET
) {
1137 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1138 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1139 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1141 assert(!"invalid set op");
1144 emitPRED(0x27, insn
->src(2));
1149 emitABS (0x36, insn
->src(0));
1150 emitNEG (0x35, insn
->src(1));
1151 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1152 emitCond4(0x30, insn
->setCond
);
1154 emitABS (0x2c, insn
->src(1));
1155 emitNEG (0x2b, insn
->src(0));
1156 emitGPR (0x08, insn
->src(0));
1157 emitGPR (0x00, insn
->def(0));
1161 CodeEmitterGM107::emitDSETP()
1163 const CmpInstruction
*insn
= this->insn
->asCmp();
1165 switch (insn
->src(1).getFile()) {
1167 emitInsn(0x5b800000);
1168 emitGPR (0x14, insn
->src(1));
1170 case FILE_MEMORY_CONST
:
1171 emitInsn(0x4b800000);
1172 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1174 case FILE_IMMEDIATE
:
1175 emitInsn(0x36800000);
1176 emitIMMD(0x14, 19, insn
->src(1));
1179 assert(!"bad src1 file");
1183 if (insn
->op
!= OP_SET
) {
1185 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1186 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1187 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1189 assert(!"invalid set op");
1192 emitPRED(0x27, insn
->src(2));
1197 emitCond4(0x30, insn
->setCond
);
1198 emitABS (0x2c, insn
->src(1));
1199 emitNEG (0x2b, insn
->src(0));
1200 emitGPR (0x08, insn
->src(0));
1201 emitABS (0x07, insn
->src(0));
1202 emitNEG (0x06, insn
->src(1));
1203 emitPRED (0x03, insn
->def(0));
1204 if (insn
->defExists(1))
1205 emitPRED(0x00, insn
->def(1));
1210 /*******************************************************************************
1212 ******************************************************************************/
1215 CodeEmitterGM107::emitFADD()
1217 if (!longIMMD(insn
->src(1))) {
1218 switch (insn
->src(1).getFile()) {
1220 emitInsn(0x5c580000);
1221 emitGPR (0x14, insn
->src(1));
1223 case FILE_MEMORY_CONST
:
1224 emitInsn(0x4c580000);
1225 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1227 case FILE_IMMEDIATE
:
1228 emitInsn(0x38580000);
1229 emitIMMD(0x14, 19, insn
->src(1));
1232 assert(!"bad src1 file");
1236 emitABS(0x31, insn
->src(1));
1237 emitNEG(0x30, insn
->src(0));
1239 emitABS(0x2e, insn
->src(0));
1240 emitNEG(0x2d, insn
->src(1));
1243 if (insn
->op
== OP_SUB
)
1244 code
[1] ^= 0x00002000;
1246 emitInsn(0x08000000);
1247 emitABS(0x39, insn
->src(1));
1248 emitNEG(0x38, insn
->src(0));
1250 emitABS(0x36, insn
->src(0));
1251 emitNEG(0x35, insn
->src(1));
1253 emitIMMD(0x14, 32, insn
->src(1));
1255 if (insn
->op
== OP_SUB
)
1256 code
[1] ^= 0x00080000;
1259 emitGPR(0x08, insn
->src(0));
1260 emitGPR(0x00, insn
->def(0));
1264 CodeEmitterGM107::emitFMUL()
1266 if (!longIMMD(insn
->src(1))) {
1267 switch (insn
->src(1).getFile()) {
1269 emitInsn(0x5c680000);
1270 emitGPR (0x14, insn
->src(1));
1272 case FILE_MEMORY_CONST
:
1273 emitInsn(0x4c680000);
1274 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1276 case FILE_IMMEDIATE
:
1277 emitInsn(0x38680000);
1278 emitIMMD(0x14, 19, insn
->src(1));
1281 assert(!"bad src1 file");
1285 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1291 emitInsn(0x1e000000);
1295 emitIMMD(0x14, 32, insn
->src(1));
1296 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1297 code
[1] ^= 0x00080000; /* flip immd sign bit */
1300 emitGPR(0x08, insn
->src(0));
1301 emitGPR(0x00, insn
->def(0));
1305 CodeEmitterGM107::emitFFMA()
1307 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1308 switch(insn
->src(2).getFile()) {
1310 switch (insn
->src(1).getFile()) {
1312 emitInsn(0x59800000);
1313 emitGPR (0x14, insn
->src(1));
1315 case FILE_MEMORY_CONST
:
1316 emitInsn(0x49800000);
1317 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1319 case FILE_IMMEDIATE
:
1320 emitInsn(0x32800000);
1321 emitIMMD(0x14, 19, insn
->src(1));
1324 assert(!"bad src1 file");
1327 emitGPR (0x27, insn
->src(2));
1329 case FILE_MEMORY_CONST
:
1330 emitInsn(0x51800000);
1331 emitGPR (0x27, insn
->src(1));
1332 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1335 assert(!"bad src2 file");
1340 emitNEG (0x31, insn
->src(2));
1341 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1345 emitGPR(0x08, insn
->src(0));
1346 emitGPR(0x00, insn
->def(0));
1350 CodeEmitterGM107::emitMUFU()
1355 case OP_COS
: mufu
= 0; break;
1356 case OP_SIN
: mufu
= 1; break;
1357 case OP_EX2
: mufu
= 2; break;
1358 case OP_LG2
: mufu
= 3; break;
1359 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1360 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1362 assert(!"invalid mufu");
1366 emitInsn (0x50800000);
1368 emitNEG (0x30, insn
->src(0));
1369 emitABS (0x2e, insn
->src(0));
1370 emitField(0x14, 3, mufu
);
1371 emitGPR (0x08, insn
->src(0));
1372 emitGPR (0x00, insn
->def(0));
1376 CodeEmitterGM107::emitFMNMX()
1378 switch (insn
->src(1).getFile()) {
1380 emitInsn(0x5c600000);
1381 emitGPR (0x14, insn
->src(1));
1383 case FILE_MEMORY_CONST
:
1384 emitInsn(0x4c600000);
1385 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1387 case FILE_IMMEDIATE
:
1388 emitInsn(0x38600000);
1389 emitIMMD(0x14, 19, insn
->src(1));
1392 assert(!"bad src1 file");
1396 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1399 emitABS(0x31, insn
->src(1));
1400 emitNEG(0x30, insn
->src(0));
1402 emitABS(0x2e, insn
->src(0));
1403 emitNEG(0x2d, insn
->src(1));
1405 emitGPR(0x08, insn
->src(0));
1406 emitGPR(0x00, insn
->def(0));
1410 CodeEmitterGM107::emitRRO()
1412 switch (insn
->src(0).getFile()) {
1414 emitInsn(0x5c900000);
1415 emitGPR (0x14, insn
->src(0));
1417 case FILE_MEMORY_CONST
:
1418 emitInsn(0x4c900000);
1419 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1421 case FILE_IMMEDIATE
:
1422 emitInsn(0x38900000);
1423 emitIMMD(0x14, 19, insn
->src(0));
1426 assert(!"bad src file");
1430 emitABS (0x31, insn
->src(0));
1431 emitNEG (0x2d, insn
->src(0));
1432 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1433 emitGPR (0x00, insn
->def(0));
1437 CodeEmitterGM107::emitFCMP()
1439 const CmpInstruction
*insn
= this->insn
->asCmp();
1440 CondCode cc
= insn
->setCond
;
1442 if (insn
->src(2).mod
.neg())
1443 cc
= reverseCondCode(cc
);
1445 switch(insn
->src(2).getFile()) {
1447 switch (insn
->src(1).getFile()) {
1449 emitInsn(0x5ba00000);
1450 emitGPR (0x14, insn
->src(1));
1452 case FILE_MEMORY_CONST
:
1453 emitInsn(0x4ba00000);
1454 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1456 case FILE_IMMEDIATE
:
1457 emitInsn(0x36a00000);
1458 emitIMMD(0x14, 19, insn
->src(1));
1461 assert(!"bad src1 file");
1464 emitGPR (0x27, insn
->src(2));
1466 case FILE_MEMORY_CONST
:
1467 emitInsn(0x53a00000);
1468 emitGPR (0x27, insn
->src(1));
1469 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1472 assert(!"bad src2 file");
1476 emitCond4(0x30, cc
);
1478 emitGPR (0x08, insn
->src(0));
1479 emitGPR (0x00, insn
->def(0));
1483 CodeEmitterGM107::emitFSET()
1485 const CmpInstruction
*insn
= this->insn
->asCmp();
1487 switch (insn
->src(1).getFile()) {
1489 emitInsn(0x58000000);
1490 emitGPR (0x14, insn
->src(1));
1492 case FILE_MEMORY_CONST
:
1493 emitInsn(0x48000000);
1494 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1496 case FILE_IMMEDIATE
:
1497 emitInsn(0x30000000);
1498 emitIMMD(0x14, 19, insn
->src(1));
1501 assert(!"bad src1 file");
1505 if (insn
->op
!= OP_SET
) {
1507 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1508 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1509 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1511 assert(!"invalid set op");
1514 emitPRED(0x27, insn
->src(2));
1520 emitABS (0x36, insn
->src(0));
1521 emitNEG (0x35, insn
->src(1));
1522 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1523 emitCond4(0x30, insn
->setCond
);
1525 emitABS (0x2c, insn
->src(1));
1526 emitNEG (0x2b, insn
->src(0));
1527 emitGPR (0x08, insn
->src(0));
1528 emitGPR (0x00, insn
->def(0));
1532 CodeEmitterGM107::emitFSETP()
1534 const CmpInstruction
*insn
= this->insn
->asCmp();
1536 switch (insn
->src(1).getFile()) {
1538 emitInsn(0x5bb00000);
1539 emitGPR (0x14, insn
->src(1));
1541 case FILE_MEMORY_CONST
:
1542 emitInsn(0x4bb00000);
1543 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1545 case FILE_IMMEDIATE
:
1546 emitInsn(0x36b00000);
1547 emitIMMD(0x14, 19, insn
->src(1));
1550 assert(!"bad src1 file");
1554 if (insn
->op
!= OP_SET
) {
1556 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1557 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1558 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1560 assert(!"invalid set op");
1563 emitPRED(0x27, insn
->src(2));
1568 emitCond4(0x30, insn
->setCond
);
1570 emitABS (0x2c, insn
->src(1));
1571 emitNEG (0x2b, insn
->src(0));
1572 emitGPR (0x08, insn
->src(0));
1573 emitABS (0x07, insn
->src(0));
1574 emitNEG (0x06, insn
->src(1));
1575 emitPRED (0x03, insn
->def(0));
1576 if (insn
->defExists(1))
1577 emitPRED(0x00, insn
->def(1));
1583 CodeEmitterGM107::emitFSWZADD()
1585 emitInsn (0x50f80000);
1589 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1590 emitField(0x1c, 8, insn
->subOp
);
1591 if (insn
->predSrc
!= 1)
1592 emitGPR (0x14, insn
->src(1));
1595 emitGPR (0x08, insn
->src(0));
1596 emitGPR (0x00, insn
->def(0));
1599 /*******************************************************************************
1601 ******************************************************************************/
1604 CodeEmitterGM107::emitLOP()
1609 case OP_AND
: lop
= 0; break;
1610 case OP_OR
: lop
= 1; break;
1611 case OP_XOR
: lop
= 2; break;
1613 assert(!"invalid lop");
1617 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1618 switch (insn
->src(1).getFile()) {
1620 emitInsn(0x5c400000);
1621 emitGPR (0x14, insn
->src(1));
1623 case FILE_MEMORY_CONST
:
1624 emitInsn(0x4c400000);
1625 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1627 case FILE_IMMEDIATE
:
1628 emitInsn(0x38400000);
1629 emitIMMD(0x14, 19, insn
->src(1));
1632 assert(!"bad src1 file");
1638 emitField(0x29, 2, lop
);
1639 emitINV (0x28, insn
->src(1));
1640 emitINV (0x27, insn
->src(0));
1642 emitInsn (0x04000000);
1644 emitINV (0x38, insn
->src(1));
1645 emitINV (0x37, insn
->src(0));
1646 emitField(0x35, 2, lop
);
1648 emitIMMD (0x14, 32, insn
->src(1));
1651 emitGPR (0x08, insn
->src(0));
1652 emitGPR (0x00, insn
->def(0));
1655 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1657 CodeEmitterGM107::emitNOT()
1659 if (!longIMMD(insn
->src(0))) {
1660 switch (insn
->src(0).getFile()) {
1662 emitInsn(0x5c400700);
1663 emitGPR (0x14, insn
->src(0));
1665 case FILE_MEMORY_CONST
:
1666 emitInsn(0x4c400700);
1667 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1669 case FILE_IMMEDIATE
:
1670 emitInsn(0x38400700);
1671 emitIMMD(0x14, 19, insn
->src(0));
1674 assert(!"bad src1 file");
1679 emitInsn (0x05600000);
1680 emitIMMD (0x14, 32, insn
->src(1));
1684 emitGPR(0x00, insn
->def(0));
1688 CodeEmitterGM107::emitIADD()
1690 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1691 switch (insn
->src(1).getFile()) {
1693 emitInsn(0x5c100000);
1694 emitGPR (0x14, insn
->src(1));
1696 case FILE_MEMORY_CONST
:
1697 emitInsn(0x4c100000);
1698 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1700 case FILE_IMMEDIATE
:
1701 emitInsn(0x38100000);
1702 emitIMMD(0x14, 19, insn
->src(1));
1705 assert(!"bad src1 file");
1709 emitNEG(0x31, insn
->src(0));
1710 emitNEG(0x30, insn
->src(1));
1714 emitInsn(0x1c000000);
1715 emitNEG (0x38, insn
->src(0));
1719 emitIMMD(0x14, 32, insn
->src(1));
1722 if (insn
->op
== OP_SUB
)
1723 code
[1] ^= 0x00010000;
1725 emitGPR(0x08, insn
->src(0));
1726 emitGPR(0x00, insn
->def(0));
1730 CodeEmitterGM107::emitIMUL()
1732 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1733 switch (insn
->src(1).getFile()) {
1735 emitInsn(0x5c380000);
1736 emitGPR (0x14, insn
->src(1));
1738 case FILE_MEMORY_CONST
:
1739 emitInsn(0x4c380000);
1740 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1742 case FILE_IMMEDIATE
:
1743 emitInsn(0x38380000);
1744 emitIMMD(0x14, 19, insn
->src(1));
1747 assert(!"bad src1 file");
1751 emitField(0x29, 1, isSignedType(insn
->sType
));
1752 emitField(0x28, 1, isSignedType(insn
->dType
));
1753 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1755 emitInsn (0x1f000000);
1756 emitField(0x37, 1, isSignedType(insn
->sType
));
1757 emitField(0x36, 1, isSignedType(insn
->dType
));
1758 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1760 emitIMMD (0x14, 32, insn
->src(1));
1763 emitGPR(0x08, insn
->src(0));
1764 emitGPR(0x00, insn
->def(0));
1768 CodeEmitterGM107::emitIMAD()
1770 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1771 switch(insn
->src(2).getFile()) {
1773 switch (insn
->src(1).getFile()) {
1775 emitInsn(0x5a000000);
1776 emitGPR (0x14, insn
->src(1));
1778 case FILE_MEMORY_CONST
:
1779 emitInsn(0x4a000000);
1780 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1782 case FILE_IMMEDIATE
:
1783 emitInsn(0x34000000);
1784 emitIMMD(0x14, 19, insn
->src(1));
1787 assert(!"bad src1 file");
1790 emitGPR (0x27, insn
->src(2));
1792 case FILE_MEMORY_CONST
:
1793 emitInsn(0x52000000);
1794 emitGPR (0x27, insn
->src(1));
1795 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1798 assert(!"bad src2 file");
1802 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1803 emitField(0x35, 1, isSignedType(insn
->sType
));
1804 emitNEG (0x34, insn
->src(2));
1805 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1808 emitField(0x30, 1, isSignedType(insn
->dType
));
1810 emitGPR (0x08, insn
->src(0));
1811 emitGPR (0x00, insn
->def(0));
1815 CodeEmitterGM107::emitIMNMX()
1817 switch (insn
->src(1).getFile()) {
1819 emitInsn(0x5c200000);
1820 emitGPR (0x14, insn
->src(1));
1822 case FILE_MEMORY_CONST
:
1823 emitInsn(0x4c200000);
1824 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1826 case FILE_IMMEDIATE
:
1827 emitInsn(0x38200000);
1828 emitIMMD(0x14, 19, insn
->src(1));
1831 assert(!"bad src1 file");
1835 emitField(0x30, 1, isSignedType(insn
->dType
));
1837 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1839 emitGPR (0x08, insn
->src(0));
1840 emitGPR (0x00, insn
->def(0));
1844 CodeEmitterGM107::emitICMP()
1846 const CmpInstruction
*insn
= this->insn
->asCmp();
1847 CondCode cc
= insn
->setCond
;
1849 if (insn
->src(2).mod
.neg())
1850 cc
= reverseCondCode(cc
);
1852 switch(insn
->src(2).getFile()) {
1854 switch (insn
->src(1).getFile()) {
1856 emitInsn(0x5b400000);
1857 emitGPR (0x14, insn
->src(1));
1859 case FILE_MEMORY_CONST
:
1860 emitInsn(0x4b400000);
1861 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1863 case FILE_IMMEDIATE
:
1864 emitInsn(0x36400000);
1865 emitIMMD(0x14, 19, insn
->src(1));
1868 assert(!"bad src1 file");
1871 emitGPR (0x27, insn
->src(2));
1873 case FILE_MEMORY_CONST
:
1874 emitInsn(0x53400000);
1875 emitGPR (0x27, insn
->src(1));
1876 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1879 assert(!"bad src2 file");
1883 emitCond3(0x31, cc
);
1884 emitField(0x30, 1, isSignedType(insn
->sType
));
1885 emitGPR (0x08, insn
->src(0));
1886 emitGPR (0x00, insn
->def(0));
1890 CodeEmitterGM107::emitISET()
1892 const CmpInstruction
*insn
= this->insn
->asCmp();
1894 switch (insn
->src(1).getFile()) {
1896 emitInsn(0x5b500000);
1897 emitGPR (0x14, insn
->src(1));
1899 case FILE_MEMORY_CONST
:
1900 emitInsn(0x4b500000);
1901 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1903 case FILE_IMMEDIATE
:
1904 emitInsn(0x36500000);
1905 emitIMMD(0x14, 19, insn
->src(1));
1908 assert(!"bad src1 file");
1912 if (insn
->op
!= OP_SET
) {
1914 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1915 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1916 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1918 assert(!"invalid set op");
1921 emitPRED(0x27, insn
->src(2));
1926 emitCond3(0x31, insn
->setCond
);
1927 emitField(0x30, 1, isSignedType(insn
->sType
));
1929 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1931 emitGPR (0x08, insn
->src(0));
1932 emitGPR (0x00, insn
->def(0));
1936 CodeEmitterGM107::emitISETP()
1938 const CmpInstruction
*insn
= this->insn
->asCmp();
1940 switch (insn
->src(1).getFile()) {
1942 emitInsn(0x5b600000);
1943 emitGPR (0x14, insn
->src(1));
1945 case FILE_MEMORY_CONST
:
1946 emitInsn(0x4b600000);
1947 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1949 case FILE_IMMEDIATE
:
1950 emitInsn(0x36600000);
1951 emitIMMD(0x14, 19, insn
->src(1));
1954 assert(!"bad src1 file");
1958 if (insn
->op
!= OP_SET
) {
1960 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1961 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1962 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1964 assert(!"invalid set op");
1967 emitPRED(0x27, insn
->src(2));
1972 emitCond3(0x31, insn
->setCond
);
1973 emitField(0x30, 1, isSignedType(insn
->sType
));
1975 emitGPR (0x08, insn
->src(0));
1976 emitPRED (0x03, insn
->def(0));
1977 if (insn
->defExists(1))
1978 emitPRED(0x00, insn
->def(1));
1984 CodeEmitterGM107::emitSHL()
1986 switch (insn
->src(1).getFile()) {
1988 emitInsn(0x5c480000);
1989 emitGPR (0x14, insn
->src(1));
1991 case FILE_MEMORY_CONST
:
1992 emitInsn(0x4c480000);
1993 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1995 case FILE_IMMEDIATE
:
1996 emitInsn(0x38480000);
1997 emitIMMD(0x14, 19, insn
->src(1));
2000 assert(!"bad src1 file");
2006 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2007 emitGPR (0x08, insn
->src(0));
2008 emitGPR (0x00, insn
->def(0));
2012 CodeEmitterGM107::emitSHR()
2014 switch (insn
->src(1).getFile()) {
2016 emitInsn(0x5c280000);
2017 emitGPR (0x14, insn
->src(1));
2019 case FILE_MEMORY_CONST
:
2020 emitInsn(0x4c280000);
2021 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2023 case FILE_IMMEDIATE
:
2024 emitInsn(0x38280000);
2025 emitIMMD(0x14, 19, insn
->src(1));
2028 assert(!"bad src1 file");
2032 emitField(0x30, 1, isSignedType(insn
->dType
));
2035 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2036 emitGPR (0x08, insn
->src(0));
2037 emitGPR (0x00, insn
->def(0));
2041 CodeEmitterGM107::emitPOPC()
2043 switch (insn
->src(0).getFile()) {
2045 emitInsn(0x5c080000);
2046 emitGPR (0x14, insn
->src(0));
2048 case FILE_MEMORY_CONST
:
2049 emitInsn(0x4c080000);
2050 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2052 case FILE_IMMEDIATE
:
2053 emitInsn(0x38080000);
2054 emitIMMD(0x14, 19, insn
->src(0));
2057 assert(!"bad src1 file");
2061 emitINV(0x28, insn
->src(0));
2062 emitGPR(0x00, insn
->def(0));
2066 CodeEmitterGM107::emitBFI()
2068 switch(insn
->src(2).getFile()) {
2070 switch (insn
->src(1).getFile()) {
2072 emitInsn(0x5bf00000);
2073 emitGPR (0x14, insn
->src(1));
2075 case FILE_MEMORY_CONST
:
2076 emitInsn(0x4bf00000);
2077 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2079 case FILE_IMMEDIATE
:
2080 emitInsn(0x36f00000);
2081 emitIMMD(0x14, 19, insn
->src(1));
2084 assert(!"bad src1 file");
2087 emitGPR (0x27, insn
->src(2));
2089 case FILE_MEMORY_CONST
:
2090 emitInsn(0x53f00000);
2091 emitGPR (0x27, insn
->src(1));
2092 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2095 assert(!"bad src2 file");
2100 emitGPR (0x08, insn
->src(0));
2101 emitGPR (0x00, insn
->def(0));
2105 CodeEmitterGM107::emitBFE()
2107 switch (insn
->src(1).getFile()) {
2109 emitInsn(0x5c000000);
2110 emitGPR (0x14, insn
->src(1));
2112 case FILE_MEMORY_CONST
:
2113 emitInsn(0x4c000000);
2114 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2116 case FILE_IMMEDIATE
:
2117 emitInsn(0x38000000);
2118 emitIMMD(0x14, 19, insn
->src(1));
2121 assert(!"bad src1 file");
2125 emitField(0x30, 1, isSignedType(insn
->dType
));
2127 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2128 emitGPR (0x08, insn
->src(0));
2129 emitGPR (0x00, insn
->def(0));
2133 CodeEmitterGM107::emitFLO()
2135 switch (insn
->src(0).getFile()) {
2137 emitInsn(0x5c300000);
2138 emitGPR (0x14, insn
->src(0));
2140 case FILE_MEMORY_CONST
:
2141 emitInsn(0x4c300000);
2142 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2144 case FILE_IMMEDIATE
:
2145 emitInsn(0x38300000);
2146 emitIMMD(0x14, 19, insn
->src(0));
2149 assert(!"bad src1 file");
2153 emitField(0x30, 1, isSignedType(insn
->dType
));
2155 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2156 emitINV (0x28, insn
->src(0));
2157 emitGPR (0x00, insn
->def(0));
2160 /*******************************************************************************
2162 ******************************************************************************/
2165 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2169 switch (typeSizeof(type
)) {
2170 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2171 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2172 case 4: data
= 4; break;
2173 case 8: data
= 5; break;
2174 case 16: data
= 6; break;
2176 assert(!"bad type");
2180 emitField(pos
, 3, data
);
2184 CodeEmitterGM107::emitLDSTc(int pos
)
2188 switch (insn
->cache
) {
2189 case CACHE_CA
: mode
= 0; break;
2190 case CACHE_CG
: mode
= 1; break;
2191 case CACHE_CS
: mode
= 2; break;
2192 case CACHE_CV
: mode
= 3; break;
2194 assert(!"invalid caching mode");
2198 emitField(pos
, 2, mode
);
2202 CodeEmitterGM107::emitLDC()
2204 emitInsn (0xef900000);
2205 emitLDSTs(0x30, insn
->dType
);
2206 emitField(0x2c, 2, insn
->subOp
);
2207 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2208 emitGPR (0x00, insn
->def(0));
2212 CodeEmitterGM107::emitLDL()
2214 emitInsn (0xef400000);
2215 emitLDSTs(0x30, insn
->dType
);
2217 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2218 emitGPR (0x00, insn
->def(0));
2222 CodeEmitterGM107::emitLDS()
2224 emitInsn (0xef480000);
2225 emitLDSTs(0x30, insn
->dType
);
2226 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2227 emitGPR (0x00, insn
->def(0));
2231 CodeEmitterGM107::emitLD()
2233 emitInsn (0x80000000);
2236 emitLDSTs(0x35, insn
->dType
);
2237 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2238 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2239 emitGPR (0x00, insn
->def(0));
2243 CodeEmitterGM107::emitSTL()
2245 emitInsn (0xef500000);
2246 emitLDSTs(0x30, insn
->dType
);
2248 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2249 emitGPR (0x00, insn
->src(1));
2253 CodeEmitterGM107::emitSTS()
2255 emitInsn (0xef580000);
2256 emitLDSTs(0x30, insn
->dType
);
2257 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2258 emitGPR (0x00, insn
->src(1));
2262 CodeEmitterGM107::emitST()
2264 emitInsn (0xa0000000);
2267 emitLDSTs(0x35, insn
->dType
);
2268 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2269 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2270 emitGPR (0x00, insn
->src(1));
2274 CodeEmitterGM107::emitALD()
2276 emitInsn (0xefd80000);
2277 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2278 emitGPR (0x27, insn
->src(0).getIndirect(1));
2281 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2282 emitGPR (0x00, insn
->def(0));
2286 CodeEmitterGM107::emitAST()
2288 emitInsn (0xeff00000);
2289 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2290 emitGPR (0x27, insn
->src(0).getIndirect(1));
2292 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2293 emitGPR (0x00, insn
->src(1));
2297 CodeEmitterGM107::emitISBERD()
2299 emitInsn(0xefd00000);
2300 emitGPR (0x08, insn
->src(0));
2301 emitGPR (0x00, insn
->def(0));
2305 CodeEmitterGM107::emitAL2P()
2307 emitInsn (0xefa00000);
2308 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2310 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2311 emitGPR (0x08, insn
->src(0).getIndirect(0));
2312 emitGPR (0x00, insn
->def(0));
2316 interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2318 int ipa
= entry
->ipa
;
2319 int reg
= entry
->reg
;
2320 int loc
= entry
->loc
;
2322 if (data
.flatshade
&&
2323 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2324 ipa
= NV50_IR_INTERP_FLAT
;
2326 } else if (data
.force_persample_interp
&&
2327 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2328 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2329 ipa
|= NV50_IR_INTERP_CENTROID
;
2331 code
[loc
+ 1] &= ~(0xf << 0x14);
2332 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2333 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2334 code
[loc
+ 0] &= ~(0xff << 0x14);
2335 code
[loc
+ 0] |= reg
<< 0x14;
2339 CodeEmitterGM107::emitIPA()
2341 int ipam
= 0, ipas
= 0;
2343 switch (insn
->getInterpMode()) {
2344 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2345 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2346 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2347 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2349 assert(!"invalid ipa mode");
2353 switch (insn
->getSampleMode()) {
2354 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2355 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2356 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2358 assert(!"invalid ipa sample mode");
2362 emitInsn (0xe0000000);
2363 emitField(0x36, 2, ipam
);
2364 emitField(0x34, 2, ipas
);
2366 emitField(0x2f, 3, 7);
2367 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2368 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2369 code
[1] |= 0x00000040; /* .idx */
2370 emitGPR(0x00, insn
->def(0));
2372 if (insn
->op
== OP_PINTERP
) {
2373 emitGPR(0x14, insn
->src(1));
2374 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2375 emitGPR(0x27, insn
->src(2));
2376 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2378 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2379 emitGPR(0x27, insn
->src(1));
2381 addInterp(insn
->ipa
, 0xff, interpApply
);
2384 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2389 CodeEmitterGM107::emitATOM()
2391 unsigned dType
, subOp
;
2393 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2394 switch (insn
->dType
) {
2395 case TYPE_U32
: dType
= 0; break;
2396 case TYPE_U64
: dType
= 1; break;
2397 default: assert(!"unexpected dType"); dType
= 0; break;
2401 emitInsn (0xee000000);
2403 switch (insn
->dType
) {
2404 case TYPE_U32
: dType
= 0; break;
2405 case TYPE_S32
: dType
= 1; break;
2406 case TYPE_U64
: dType
= 2; break;
2407 case TYPE_F32
: dType
= 3; break;
2408 case TYPE_B128
: dType
= 4; break;
2409 case TYPE_S64
: dType
= 5; break;
2410 default: assert(!"unexpected dType"); dType
= 0; break;
2412 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2415 subOp
= insn
->subOp
;
2417 emitInsn (0xed000000);
2420 emitField(0x34, 4, subOp
);
2421 emitField(0x31, 3, dType
);
2422 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2423 emitGPR (0x14, insn
->src(1));
2424 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2425 emitGPR (0x00, insn
->def(0));
2429 CodeEmitterGM107::emitATOMS()
2431 unsigned dType
, subOp
;
2433 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2434 switch (insn
->dType
) {
2435 case TYPE_U32
: dType
= 0; break;
2436 case TYPE_U64
: dType
= 1; break;
2437 default: assert(!"unexpected dType"); dType
= 0; break;
2441 emitInsn (0xee000000);
2442 emitField(0x34, 1, dType
);
2444 switch (insn
->dType
) {
2445 case TYPE_U32
: dType
= 0; break;
2446 case TYPE_S32
: dType
= 1; break;
2447 case TYPE_U64
: dType
= 2; break;
2448 case TYPE_S64
: dType
= 3; break;
2449 default: assert(!"unexpected dType"); dType
= 0; break;
2452 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2455 subOp
= insn
->subOp
;
2457 emitInsn (0xec000000);
2458 emitField(0x1c, 3, dType
);
2461 emitField(0x34, 4, subOp
);
2462 emitGPR (0x14, insn
->src(1));
2463 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2464 emitGPR (0x00, insn
->def(0));
2468 CodeEmitterGM107::emitCCTL()
2471 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2472 emitInsn(0xef600000);
2475 emitInsn(0xef800000);
2478 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2479 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2480 emitField(0x00, 4, insn
->subOp
);
2483 /*******************************************************************************
2485 ******************************************************************************/
2488 CodeEmitterGM107::emitPIXLD()
2490 emitInsn (0xefe80000);
2492 emitField(0x1f, 3, insn
->subOp
);
2493 emitGPR (0x08, insn
->src(0));
2494 emitGPR (0x00, insn
->def(0));
2497 /*******************************************************************************
2499 ******************************************************************************/
2502 CodeEmitterGM107::emitTEXs(int pos
)
2504 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2505 if (insn
->srcExists(src1
))
2506 emitGPR(pos
, insn
->src(src1
));
2512 CodeEmitterGM107::emitTEX()
2514 const TexInstruction
*insn
= this->insn
->asTex();
2517 if (!insn
->tex
.levelZero
) {
2519 case OP_TEX
: lodm
= 0; break;
2520 case OP_TXB
: lodm
= 2; break;
2521 case OP_TXL
: lodm
= 3; break;
2523 assert(!"invalid tex op");
2530 if (insn
->tex
.rIndirectSrc
>= 0) {
2531 emitInsn (0xdeb80000);
2532 emitField(0x35, 2, lodm
);
2533 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2535 emitInsn (0xc0380000);
2536 emitField(0x37, 2, lodm
);
2537 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2538 emitField(0x24, 13, insn
->tex
.r
);
2541 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2542 emitField(0x31, 1, insn
->tex
.liveOnly
);
2543 emitField(0x23, 1, insn
->tex
.derivAll
);
2544 emitField(0x1f, 4, insn
->tex
.mask
);
2545 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2546 insn
->tex
.target
.getDim() - 1);
2547 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2549 emitGPR (0x08, insn
->src(0));
2550 emitGPR (0x00, insn
->def(0));
2554 CodeEmitterGM107::emitTLD()
2556 const TexInstruction
*insn
= this->insn
->asTex();
2558 if (insn
->tex
.rIndirectSrc
>= 0) {
2559 emitInsn (0xdd380000);
2561 emitInsn (0xdc380000);
2562 emitField(0x24, 13, insn
->tex
.r
);
2565 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2566 emitField(0x32, 1, insn
->tex
.target
.isMS());
2567 emitField(0x31, 1, insn
->tex
.liveOnly
);
2568 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2569 emitField(0x1f, 4, insn
->tex
.mask
);
2570 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2571 insn
->tex
.target
.getDim() - 1);
2572 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2574 emitGPR (0x08, insn
->src(0));
2575 emitGPR (0x00, insn
->def(0));
2579 CodeEmitterGM107::emitTLD4()
2581 const TexInstruction
*insn
= this->insn
->asTex();
2583 if (insn
->tex
.rIndirectSrc
>= 0) {
2584 emitInsn (0xdef80000);
2585 emitField(0x26, 2, insn
->tex
.gatherComp
);
2586 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2587 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2589 emitInsn (0xc8380000);
2590 emitField(0x38, 2, insn
->tex
.gatherComp
);
2591 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2592 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2593 emitField(0x24, 13, insn
->tex
.r
);
2596 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2597 emitField(0x31, 1, insn
->tex
.liveOnly
);
2598 emitField(0x23, 1, insn
->tex
.derivAll
);
2599 emitField(0x1f, 4, insn
->tex
.mask
);
2600 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2601 insn
->tex
.target
.getDim() - 1);
2602 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2604 emitGPR (0x08, insn
->src(0));
2605 emitGPR (0x00, insn
->def(0));
2609 CodeEmitterGM107::emitTXD()
2611 const TexInstruction
*insn
= this->insn
->asTex();
2613 if (insn
->tex
.rIndirectSrc
>= 0) {
2614 emitInsn (0xde780000);
2616 emitInsn (0xde380000);
2617 emitField(0x24, 13, insn
->tex
.r
);
2620 emitField(0x31, 1, insn
->tex
.liveOnly
);
2621 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2622 emitField(0x1f, 4, insn
->tex
.mask
);
2623 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2624 insn
->tex
.target
.getDim() - 1);
2625 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2627 emitGPR (0x08, insn
->src(0));
2628 emitGPR (0x00, insn
->def(0));
2632 CodeEmitterGM107::emitTMML()
2634 const TexInstruction
*insn
= this->insn
->asTex();
2636 if (insn
->tex
.rIndirectSrc
>= 0) {
2637 emitInsn (0xdf600000);
2639 emitInsn (0xdf580000);
2640 emitField(0x24, 13, insn
->tex
.r
);
2643 emitField(0x31, 1, insn
->tex
.liveOnly
);
2644 emitField(0x23, 1, insn
->tex
.derivAll
);
2645 emitField(0x1f, 4, insn
->tex
.mask
);
2646 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2647 insn
->tex
.target
.getDim() - 1);
2648 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2650 emitGPR (0x08, insn
->src(0));
2651 emitGPR (0x00, insn
->def(0));
2655 CodeEmitterGM107::emitTXQ()
2657 const TexInstruction
*insn
= this->insn
->asTex();
2660 switch (insn
->tex
.query
) {
2661 case TXQ_DIMS
: type
= 0x01; break;
2662 case TXQ_TYPE
: type
= 0x02; break;
2663 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2664 case TXQ_FILTER
: type
= 0x10; break;
2665 case TXQ_LOD
: type
= 0x12; break;
2666 case TXQ_WRAP
: type
= 0x14; break;
2667 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2669 assert(!"invalid txq query");
2673 if (insn
->tex
.rIndirectSrc
>= 0) {
2674 emitInsn (0xdf500000);
2676 emitInsn (0xdf480000);
2677 emitField(0x24, 13, insn
->tex
.r
);
2680 emitField(0x31, 1, insn
->tex
.liveOnly
);
2681 emitField(0x1f, 4, insn
->tex
.mask
);
2682 emitField(0x16, 6, type
);
2683 emitGPR (0x08, insn
->src(0));
2684 emitGPR (0x00, insn
->def(0));
2688 CodeEmitterGM107::emitDEPBAR()
2690 emitInsn (0xf0f00000);
2691 emitField(0x1d, 1, 1); /* le */
2692 emitField(0x1a, 3, 5);
2693 emitField(0x14, 6, insn
->subOp
);
2694 emitField(0x00, 6, insn
->subOp
);
2697 /*******************************************************************************
2699 ******************************************************************************/
2702 CodeEmitterGM107::emitNOP()
2704 emitInsn(0x50b00000);
2708 CodeEmitterGM107::emitKIL()
2710 emitInsn (0xe3300000);
2711 emitCond5(0x00, CC_TR
);
2715 CodeEmitterGM107::emitOUT()
2717 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2718 const int emit
= insn
->op
== OP_EMIT
;
2720 switch (insn
->src(1).getFile()) {
2722 emitInsn(0xfbe00000);
2723 emitGPR (0x14, insn
->src(1));
2725 case FILE_IMMEDIATE
:
2726 emitInsn(0xf6e00000);
2727 emitIMMD(0x14, 19, insn
->src(1));
2729 case FILE_MEMORY_CONST
:
2730 emitInsn(0xebe00000);
2731 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2734 assert(!"bad src1 file");
2738 emitField(0x27, 2, (cut
<< 1) | emit
);
2739 emitGPR (0x08, insn
->src(0));
2740 emitGPR (0x00, insn
->def(0));
2744 CodeEmitterGM107::emitBAR()
2748 emitInsn (0xf0a80000);
2750 switch (insn
->subOp
) {
2751 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2752 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2753 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2754 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2757 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2761 emitField(0x20, 8, subop
);
2764 if (insn
->src(0).getFile() == FILE_GPR
) {
2765 emitGPR(0x08, insn
->src(0));
2767 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2769 emitField(0x08, 8, imm
->reg
.data
.u32
);
2770 emitField(0x2b, 1, 1);
2774 if (insn
->src(1).getFile() == FILE_GPR
) {
2775 emitGPR(0x14, insn
->src(1));
2777 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2779 emitField(0x14, 12, imm
->reg
.data
.u32
);
2780 emitField(0x2c, 1, 1);
2783 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2784 emitPRED (0x27, insn
->src(2));
2785 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2787 emitField(0x27, 3, 7);
2792 CodeEmitterGM107::emitMEMBAR()
2794 emitInsn (0xef980000);
2795 emitField(0x08, 2, insn
->subOp
>> 2);
2799 CodeEmitterGM107::emitVOTE()
2801 assert(insn
->src(0).getFile() == FILE_PREDICATE
);
2804 for (int i
= 0; insn
->defExists(i
); i
++) {
2805 if (insn
->def(i
).getFile() == FILE_GPR
)
2807 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
2811 emitInsn (0x50d80000);
2812 emitField(0x30, 2, insn
->subOp
);
2814 emitGPR (0x00, insn
->def(r
));
2818 emitPRED (0x2d, insn
->def(p
));
2821 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2822 emitPRED (0x27, insn
->src(0));
2826 CodeEmitterGM107::emitSUTarget()
2828 const TexInstruction
*insn
= this->insn
->asTex();
2831 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2833 if (insn
->tex
.target
== TEX_TARGET_BUFFER
) {
2835 } else if (insn
->tex
.target
== TEX_TARGET_1D_ARRAY
) {
2837 } else if (insn
->tex
.target
== TEX_TARGET_2D
||
2838 insn
->tex
.target
== TEX_TARGET_RECT
) {
2840 } else if (insn
->tex
.target
== TEX_TARGET_2D_ARRAY
||
2841 insn
->tex
.target
== TEX_TARGET_CUBE
||
2842 insn
->tex
.target
== TEX_TARGET_CUBE_ARRAY
) {
2844 } else if (insn
->tex
.target
== TEX_TARGET_3D
) {
2847 assert(insn
->tex
.target
== TEX_TARGET_1D
);
2849 emitField(0x20, 4, target
);
2853 CodeEmitterGM107::emitSUHandle(const int s
)
2855 const TexInstruction
*insn
= this->insn
->asTex();
2857 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2859 if (insn
->src(s
).getFile() == FILE_GPR
) {
2860 emitGPR(0x27, insn
->src(s
));
2862 ImmediateValue
*imm
= insn
->getSrc(s
)->asImm();
2864 emitField(0x33, 1, 1);
2865 emitField(0x24, 13, imm
->reg
.data
.u32
);
2870 CodeEmitterGM107::emitSUSTx()
2872 const TexInstruction
*insn
= this->insn
->asTex();
2874 emitInsn(0xeb200000);
2875 if (insn
->op
== OP_SUSTB
)
2876 emitField(0x34, 1, 1);
2880 emitField(0x14, 4, 0xf); // rgba
2881 emitGPR (0x08, insn
->src(0));
2882 emitGPR (0x00, insn
->src(1));
2888 CodeEmitterGM107::emitSULDx()
2890 const TexInstruction
*insn
= this->insn
->asTex();
2893 emitInsn(0xeb000000);
2894 if (insn
->op
== OP_SULDB
)
2895 emitField(0x34, 1, 1);
2898 switch (insn
->dType
) {
2899 case TYPE_S8
: type
= 1; break;
2900 case TYPE_U16
: type
= 2; break;
2901 case TYPE_S16
: type
= 3; break;
2902 case TYPE_U32
: type
= 4; break;
2903 case TYPE_U64
: type
= 5; break;
2904 case TYPE_B128
: type
= 6; break;
2906 assert(insn
->dType
== TYPE_U8
);
2910 emitField(0x14, 3, type
);
2911 emitGPR (0x00, insn
->def(0));
2912 emitGPR (0x08, insn
->src(0));
2916 /*******************************************************************************
2917 * assembler front-end
2918 ******************************************************************************/
2921 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2923 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2928 if (insn
->encSize
!= 8) {
2929 ERROR("skipping undecodable instruction: "); insn
->print();
2932 if (codeSize
+ size
> codeSizeLimit
) {
2933 ERROR("code emitter output buffer too small\n");
2937 if (writeIssueDelays
) {
2938 int n
= ((codeSize
& 0x1f) / 8) - 1;
2941 data
[0] = 0x00000000;
2942 data
[1] = 0x00000000;
2948 emitField(data
, n
* 21, 21, insn
->sched
);
3004 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
3005 insn
->src(0).getFile() == FILE_PREDICATE
)) {
3007 } else if (isFloatType(insn
->dType
)) {
3008 if (isFloatType(insn
->sType
))
3013 if (isFloatType(insn
->sType
))
3024 if (isFloatType(insn
->dType
)) {
3025 if (insn
->dType
== TYPE_F64
)
3034 if (isFloatType(insn
->dType
)) {
3035 if (insn
->dType
== TYPE_F64
)
3045 if (isFloatType(insn
->dType
)) {
3046 if (insn
->dType
== TYPE_F64
)
3056 if (isFloatType(insn
->dType
)) {
3057 if (insn
->dType
== TYPE_F64
)
3084 if (isFloatType(insn
->dType
))
3093 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
3094 if (isFloatType(insn
->sType
))
3095 if (insn
->sType
== TYPE_F64
)
3102 if (isFloatType(insn
->sType
))
3103 if (insn
->sType
== TYPE_F64
)
3135 switch (insn
->src(0).getFile()) {
3136 case FILE_MEMORY_CONST
: emitLDC(); break;
3137 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3138 case FILE_MEMORY_SHARED
: emitLDS(); break;
3139 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3141 assert(!"invalid load");
3147 switch (insn
->src(0).getFile()) {
3148 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3149 case FILE_MEMORY_SHARED
: emitSTS(); break;
3150 case FILE_MEMORY_GLOBAL
: emitST(); break;
3152 assert(!"invalid store");
3158 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3239 assert(!"invalid opcode");
3255 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3260 /*******************************************************************************
3261 * sched data calculator
3262 ******************************************************************************/
3264 class SchedDataCalculatorGM107
: public Pass
3267 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3270 bool visit(BasicBlock
*bb
);
3274 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3276 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3278 insn
->sched
= 0x7e0;
3284 /*******************************************************************************
3286 ******************************************************************************/
3289 CodeEmitterGM107::prepareEmission(Function
*func
)
3291 SchedDataCalculatorGM107
sched(targ
);
3292 CodeEmitter::prepareEmission(func
);
3293 sched
.run(func
, true, true);
3296 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3298 return (size
+ 23) / 24;
3302 CodeEmitterGM107::prepareEmission(Program
*prog
)
3304 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3305 !fi
.end(); fi
.next()) {
3306 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3307 func
->binPos
= prog
->binSize
;
3308 prepareEmission(func
);
3310 // adjust sizes & positions for schedulding info:
3311 if (prog
->getTarget()->hasSWSched
) {
3312 uint32_t adjPos
= func
->binPos
;
3313 BasicBlock
*bb
= NULL
;
3314 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3315 bb
= func
->bbArray
[i
];
3316 int32_t adjSize
= bb
->binSize
;
3318 adjSize
-= 32 - adjPos
% 32;
3322 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3323 bb
->binPos
= adjPos
;
3324 bb
->binSize
= adjSize
;
3328 func
->binSize
= adjPos
- func
->binPos
;
3331 prog
->binSize
+= func
->binSize
;
3335 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3336 : CodeEmitter(target
),
3338 writeIssueDelays(target
->hasSWSched
)
3341 codeSize
= codeSizeLimit
= 0;
3346 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3348 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3349 emit
->setProgramType(type
);
3353 } // namespace nv50_ir