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
);
211 /*******************************************************************************
212 * general instruction layout/fields
213 ******************************************************************************/
216 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
219 uint32_t m
= ((1ULL << s
) - 1);
220 uint64_t d
= (uint64_t)(v
& m
) << b
;
221 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
228 CodeEmitterGM107::emitPred()
230 if (insn
->predSrc
>= 0) {
231 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
232 emitField(19, 1, insn
->cc
== CC_NOT_P
);
239 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
241 code
[0] = 0x00000000;
248 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
250 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
254 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
256 int id
= val
? val
->reg
.data
.id
: -1;
259 case SV_LANEID
: id
= 0x00; break;
260 case SV_VERTEX_COUNT
: id
= 0x10; break;
261 case SV_INVOCATION_ID
: id
= 0x11; break;
262 case SV_THREAD_KILL
: id
= 0x13; break;
263 case SV_INVOCATION_INFO
: id
= 0x1d; break;
264 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
265 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
267 assert(!"invalid system value");
272 emitField(pos
, 8, id
);
276 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
278 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
282 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
285 const Value
*v
= ref
.get();
286 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
288 emitGPR(gpr
, ref
.getIndirect(0));
289 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
293 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
296 const Value
*v
= ref
.get();
297 const Symbol
*s
= v
->asSym();
299 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
301 emitField(buf
, 5, v
->reg
.fileIndex
);
303 emitGPR(gpr
, ref
.getIndirect(0));
304 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
308 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
310 if (ref
.getFile() == FILE_IMMEDIATE
) {
311 const ImmediateValue
*imm
= ref
.get()->asImm();
312 if (isFloatType(insn
->sType
)) {
313 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
316 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
317 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
325 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
327 const ImmediateValue
*imm
= ref
.get()->asImm();
328 uint32_t val
= imm
->reg
.data
.u32
;
331 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
332 assert(!(val
& 0x00000fff));
334 } else if (insn
->sType
== TYPE_F64
) {
335 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
336 val
= imm
->reg
.data
.u64
>> 44;
338 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
339 emitField( 56, 1, (val
& 0x80000) >> 19);
340 emitField(pos
, len
, (val
& 0x7ffff));
342 emitField(pos
, len
, val
);
346 /*******************************************************************************
348 ******************************************************************************/
351 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
356 case CC_FL
: data
= 0x00; break;
358 case CC_LT
: data
= 0x01; break;
360 case CC_EQ
: data
= 0x02; break;
362 case CC_LE
: data
= 0x03; break;
364 case CC_GT
: data
= 0x04; break;
366 case CC_NE
: data
= 0x05; break;
368 case CC_GE
: data
= 0x06; break;
369 case CC_TR
: data
= 0x07; break;
371 assert(!"invalid cond3");
375 emitField(pos
, 3, data
);
379 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
384 case CC_FL
: data
= 0x00; break;
385 case CC_LT
: data
= 0x01; break;
386 case CC_EQ
: data
= 0x02; break;
387 case CC_LE
: data
= 0x03; break;
388 case CC_GT
: data
= 0x04; break;
389 case CC_NE
: data
= 0x05; break;
390 case CC_GE
: data
= 0x06; break;
391 // case CC_NUM: data = 0x07; break;
392 // case CC_NAN: data = 0x08; break;
393 case CC_LTU
: data
= 0x09; break;
394 case CC_EQU
: data
= 0x0a; break;
395 case CC_LEU
: data
= 0x0b; break;
396 case CC_GTU
: data
= 0x0c; break;
397 case CC_NEU
: data
= 0x0d; break;
398 case CC_GEU
: data
= 0x0e; break;
399 case CC_TR
: data
= 0x0f; break;
401 assert(!"invalid cond4");
405 emitField(pos
, 4, data
);
409 CodeEmitterGM107::emitO(int pos
)
411 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
415 CodeEmitterGM107::emitP(int pos
)
417 emitField(pos
, 1, insn
->perPatch
);
421 CodeEmitterGM107::emitSAT(int pos
)
423 emitField(pos
, 1, insn
->saturate
);
427 CodeEmitterGM107::emitCC(int pos
)
429 emitField(pos
, 1, insn
->flagsDef
>= 0);
433 CodeEmitterGM107::emitX(int pos
)
435 emitField(pos
, 1, insn
->flagsSrc
>= 0);
439 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
441 emitField(pos
, 1, ref
.mod
.abs());
445 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
447 emitField(pos
, 1, ref
.mod
.neg());
451 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
453 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
457 CodeEmitterGM107::emitFMZ(int pos
, int len
)
459 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
463 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
467 case ROUND_NI
: ri
= 1;
468 case ROUND_N
: rm
= 0; break;
469 case ROUND_MI
: ri
= 1;
470 case ROUND_M
: rm
= 1; break;
471 case ROUND_PI
: ri
= 1;
472 case ROUND_P
: rm
= 2; break;
473 case ROUND_ZI
: ri
= 1;
474 case ROUND_Z
: rm
= 3; break;
476 assert(!"invalid round mode");
479 emitField(rip
, 1, ri
);
480 emitField(rmp
, 2, rm
);
484 CodeEmitterGM107::emitPDIV(int pos
)
486 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
487 if (insn
->postFactor
> 0)
488 emitField(pos
, 3, 7 - insn
->postFactor
);
490 emitField(pos
, 3, 0 - insn
->postFactor
);
494 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
496 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
499 /*******************************************************************************
501 ******************************************************************************/
504 CodeEmitterGM107::emitEXIT()
506 emitInsn (0xe3000000);
507 emitCond5(0x00, CC_TR
);
511 CodeEmitterGM107::emitBRA()
513 const FlowInstruction
*insn
= this->insn
->asFlow();
516 if (insn
->indirect
) {
518 emitInsn(0xe2000000); // JMX
520 emitInsn(0xe2500000); // BRX
524 emitInsn(0xe2100000); // JMP
526 emitInsn(0xe2400000); // BRA
527 emitField(0x07, 1, insn
->allWarp
);
530 emitField(0x06, 1, insn
->limit
);
531 emitCond5(0x00, CC_TR
);
533 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
534 int32_t pos
= insn
->target
.bb
->binPos
;
535 if (writeIssueDelays
&& !(pos
& 0x1f))
538 emitField(0x14, 24, pos
- (codeSize
+ 8));
540 emitField(0x14, 32, pos
);
542 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
543 emitField(0x05, 1, 1);
548 CodeEmitterGM107::emitCAL()
550 const FlowInstruction
*insn
= this->insn
->asFlow();
552 if (insn
->absolute
) {
553 emitInsn(0xe2200000, 0); // JCAL
555 emitInsn(0xe2600000, 0); // CAL
558 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
560 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
563 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
564 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
565 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
567 emitField(0x14, 32, insn
->target
.bb
->binPos
);
571 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
572 emitField(0x05, 1, 1);
577 CodeEmitterGM107::emitPCNT()
579 const FlowInstruction
*insn
= this->insn
->asFlow();
581 emitInsn(0xe2b00000, 0);
583 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
584 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
586 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
587 emitField(0x05, 1, 1);
592 CodeEmitterGM107::emitCONT()
594 emitInsn (0xe3500000);
595 emitCond5(0x00, CC_TR
);
599 CodeEmitterGM107::emitPBK()
601 const FlowInstruction
*insn
= this->insn
->asFlow();
603 emitInsn(0xe2a00000, 0);
605 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
606 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
608 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
609 emitField(0x05, 1, 1);
614 CodeEmitterGM107::emitBRK()
616 emitInsn (0xe3400000);
617 emitCond5(0x00, CC_TR
);
621 CodeEmitterGM107::emitPRET()
623 const FlowInstruction
*insn
= this->insn
->asFlow();
625 emitInsn(0xe2700000, 0);
627 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
628 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
630 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
631 emitField(0x05, 1, 1);
636 CodeEmitterGM107::emitRET()
638 emitInsn (0xe3200000);
639 emitCond5(0x00, CC_TR
);
643 CodeEmitterGM107::emitSSY()
645 const FlowInstruction
*insn
= this->insn
->asFlow();
647 emitInsn(0xe2900000, 0);
649 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
650 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
652 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
653 emitField(0x05, 1, 1);
658 CodeEmitterGM107::emitSYNC()
660 emitInsn (0xf0f80000);
661 emitCond5(0x00, CC_TR
);
665 CodeEmitterGM107::emitSAM()
667 emitInsn(0xe3700000, 0);
671 CodeEmitterGM107::emitRAM()
673 emitInsn(0xe3800000, 0);
676 /*******************************************************************************
678 ******************************************************************************/
680 /*******************************************************************************
681 * movement / conversion
682 ******************************************************************************/
685 CodeEmitterGM107::emitMOV()
687 if (insn
->src(0).getFile() != FILE_IMMEDIATE
) {
688 switch (insn
->src(0).getFile()) {
690 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
691 emitInsn(0x5b6a0000);
694 emitInsn(0x5c980000);
696 emitGPR (0x14, insn
->src(0));
698 case FILE_MEMORY_CONST
:
699 emitInsn(0x4c980000);
700 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
703 emitInsn(0x38980000);
704 emitIMMD(0x14, 19, insn
->src(0));
707 emitInsn(0x50880000);
708 emitPRED(0x0c, insn
->src(0));
713 assert(!"bad src file");
716 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
717 insn
->src(0).getFile() != FILE_PREDICATE
)
718 emitField(0x27, 4, insn
->lanes
);
720 emitInsn (0x01000000);
721 emitIMMD (0x14, 32, insn
->src(0));
722 emitField(0x0c, 4, insn
->lanes
);
725 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
727 emitPRED(0x03, insn
->def(0));
730 emitGPR(0x00, insn
->def(0));
735 CodeEmitterGM107::emitS2R()
737 emitInsn(0xf0c80000);
738 emitSYS (0x14, insn
->src(0));
739 emitGPR (0x00, insn
->def(0));
743 CodeEmitterGM107::emitF2F()
745 RoundMode rnd
= insn
->rnd
;
748 case OP_FLOOR
: rnd
= ROUND_MI
; break;
749 case OP_CEIL
: rnd
= ROUND_PI
; break;
750 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
755 switch (insn
->src(0).getFile()) {
757 emitInsn(0x5ca80000);
758 emitGPR (0x14, insn
->src(0));
760 case FILE_MEMORY_CONST
:
761 emitInsn(0x4ca80000);
762 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
765 emitInsn(0x38a80000);
766 emitIMMD(0x14, 19, insn
->src(0));
769 assert(!"bad src0 file");
773 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
774 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
776 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
778 emitField(0x29, 1, insn
->subOp
);
779 emitRND (0x27, rnd
, 0x2a);
780 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
781 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
782 emitGPR (0x00, insn
->def(0));
786 CodeEmitterGM107::emitF2I()
788 RoundMode rnd
= insn
->rnd
;
791 case OP_FLOOR
: rnd
= ROUND_M
; break;
792 case OP_CEIL
: rnd
= ROUND_P
; break;
793 case OP_TRUNC
: rnd
= ROUND_Z
; break;
798 switch (insn
->src(0).getFile()) {
800 emitInsn(0x5cb00000);
801 emitGPR (0x14, insn
->src(0));
803 case FILE_MEMORY_CONST
:
804 emitInsn(0x4cb00000);
805 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
808 emitInsn(0x38b00000);
809 emitIMMD(0x14, 19, insn
->src(0));
812 assert(!"bad src0 file");
816 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
818 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
820 emitRND (0x27, rnd
, 0x2a);
821 emitField(0x0c, 1, isSignedType(insn
->dType
));
822 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
823 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
824 emitGPR (0x00, insn
->def(0));
828 CodeEmitterGM107::emitI2F()
830 RoundMode rnd
= insn
->rnd
;
833 case OP_FLOOR
: rnd
= ROUND_M
; break;
834 case OP_CEIL
: rnd
= ROUND_P
; break;
835 case OP_TRUNC
: rnd
= ROUND_Z
; break;
840 switch (insn
->src(0).getFile()) {
842 emitInsn(0x5cb80000);
843 emitGPR (0x14, insn
->src(0));
845 case FILE_MEMORY_CONST
:
846 emitInsn(0x4cb80000);
847 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
850 emitInsn(0x38b80000);
851 emitIMMD(0x14, 19, insn
->src(0));
854 assert(!"bad src0 file");
858 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
860 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
861 emitField(0x29, 2, insn
->subOp
);
862 emitRND (0x27, rnd
, -1);
863 emitField(0x0d, 1, isSignedType(insn
->sType
));
864 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
865 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
866 emitGPR (0x00, insn
->def(0));
870 CodeEmitterGM107::emitI2I()
872 switch (insn
->src(0).getFile()) {
874 emitInsn(0x5ce00000);
875 emitGPR (0x14, insn
->src(0));
877 case FILE_MEMORY_CONST
:
878 emitInsn(0x4ce00000);
879 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
882 emitInsn(0x38e00000);
883 emitIMMD(0x14, 19, insn
->src(0));
886 assert(!"bad src0 file");
891 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
893 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
894 emitField(0x29, 2, insn
->subOp
);
895 emitField(0x0d, 1, isSignedType(insn
->sType
));
896 emitField(0x0c, 1, isSignedType(insn
->dType
));
897 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
898 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
899 emitGPR (0x00, insn
->def(0));
903 selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
905 int loc
= entry
->loc
;
906 if (data
.force_persample_interp
)
907 code
[loc
+ 1] |= 1 << 10;
909 code
[loc
+ 1] &= ~(1 << 10);
913 CodeEmitterGM107::emitSEL()
915 switch (insn
->src(1).getFile()) {
917 emitInsn(0x5ca00000);
918 emitGPR (0x14, insn
->src(1));
920 case FILE_MEMORY_CONST
:
921 emitInsn(0x4ca00000);
922 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
925 emitInsn(0x38a00000);
926 emitIMMD(0x14, 19, insn
->src(1));
929 assert(!"bad src1 file");
933 emitINV (0x2a, insn
->src(2));
934 emitPRED(0x27, insn
->src(2));
935 emitGPR (0x08, insn
->src(0));
936 emitGPR (0x00, insn
->def(0));
938 if (insn
->subOp
== 1) {
939 addInterp(0, 0, selpFlip
);
944 CodeEmitterGM107::emitSHFL()
948 emitInsn (0xef100000);
950 switch (insn
->src(1).getFile()) {
952 emitGPR(0x14, insn
->src(1));
955 emitIMMD(0x14, 5, insn
->src(1));
959 assert(!"invalid src1 file");
963 /*XXX: what is this arg? hardcode immediate for now */
964 emitField(0x22, 13, 0x1c03);
968 emitField(0x1e, 2, insn
->subOp
);
969 emitField(0x1c, 2, type
);
970 emitGPR (0x08, insn
->src(0));
971 emitGPR (0x00, insn
->def(0));
974 /*******************************************************************************
976 ******************************************************************************/
979 CodeEmitterGM107::emitDADD()
981 switch (insn
->src(1).getFile()) {
983 emitInsn(0x5c700000);
984 emitGPR (0x14, insn
->src(1));
986 case FILE_MEMORY_CONST
:
987 emitInsn(0x4c700000);
988 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
991 emitInsn(0x38700000);
992 emitIMMD(0x14, 19, insn
->src(1));
995 assert(!"bad src1 file");
998 emitABS(0x31, insn
->src(1));
999 emitNEG(0x30, insn
->src(0));
1001 emitABS(0x2e, insn
->src(0));
1002 emitNEG(0x2d, insn
->src(1));
1004 if (insn
->op
== OP_SUB
)
1005 code
[1] ^= 0x00002000;
1007 emitGPR(0x08, insn
->src(0));
1008 emitGPR(0x00, insn
->def(0));
1012 CodeEmitterGM107::emitDMUL()
1014 switch (insn
->src(1).getFile()) {
1016 emitInsn(0x5c800000);
1017 emitGPR (0x14, insn
->src(1));
1019 case FILE_MEMORY_CONST
:
1020 emitInsn(0x4c800000);
1021 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1023 case FILE_IMMEDIATE
:
1024 emitInsn(0x38800000);
1025 emitIMMD(0x14, 19, insn
->src(1));
1028 assert(!"bad src1 file");
1032 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1035 emitGPR (0x08, insn
->src(0));
1036 emitGPR (0x00, insn
->def(0));
1040 CodeEmitterGM107::emitDFMA()
1042 switch(insn
->src(2).getFile()) {
1044 switch (insn
->src(1).getFile()) {
1046 emitInsn(0x5b700000);
1047 emitGPR (0x14, insn
->src(1));
1049 case FILE_MEMORY_CONST
:
1050 emitInsn(0x4b700000);
1051 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1053 case FILE_IMMEDIATE
:
1054 emitInsn(0x36700000);
1055 emitIMMD(0x14, 19, insn
->src(1));
1058 assert(!"bad src1 file");
1061 emitGPR (0x27, insn
->src(2));
1063 case FILE_MEMORY_CONST
:
1064 emitInsn(0x53700000);
1065 emitGPR (0x27, insn
->src(1));
1066 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1069 assert(!"bad src2 file");
1074 emitNEG (0x31, insn
->src(2));
1075 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1077 emitGPR (0x08, insn
->src(0));
1078 emitGPR (0x00, insn
->def(0));
1082 CodeEmitterGM107::emitDMNMX()
1084 switch (insn
->src(1).getFile()) {
1086 emitInsn(0x5c500000);
1087 emitGPR (0x14, insn
->src(1));
1089 case FILE_MEMORY_CONST
:
1090 emitInsn(0x4c500000);
1091 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1093 case FILE_IMMEDIATE
:
1094 emitInsn(0x38500000);
1095 emitIMMD(0x14, 19, insn
->src(1));
1098 assert(!"bad src1 file");
1102 emitABS (0x31, insn
->src(1));
1103 emitNEG (0x30, insn
->src(0));
1105 emitABS (0x2e, insn
->src(0));
1106 emitNEG (0x2d, insn
->src(1));
1107 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1109 emitGPR (0x08, insn
->src(0));
1110 emitGPR (0x00, insn
->def(0));
1114 CodeEmitterGM107::emitDSET()
1116 const CmpInstruction
*insn
= this->insn
->asCmp();
1118 switch (insn
->src(1).getFile()) {
1120 emitInsn(0x59000000);
1121 emitGPR (0x14, insn
->src(1));
1123 case FILE_MEMORY_CONST
:
1124 emitInsn(0x49000000);
1125 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1127 case FILE_IMMEDIATE
:
1128 emitInsn(0x32000000);
1129 emitIMMD(0x14, 19, insn
->src(1));
1132 assert(!"bad src1 file");
1136 if (insn
->op
!= OP_SET
) {
1138 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1139 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1140 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1142 assert(!"invalid set op");
1145 emitPRED(0x27, insn
->src(2));
1150 emitABS (0x36, insn
->src(0));
1151 emitNEG (0x35, insn
->src(1));
1152 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1153 emitCond4(0x30, insn
->setCond
);
1155 emitABS (0x2c, insn
->src(1));
1156 emitNEG (0x2b, insn
->src(0));
1157 emitGPR (0x08, insn
->src(0));
1158 emitGPR (0x00, insn
->def(0));
1162 CodeEmitterGM107::emitDSETP()
1164 const CmpInstruction
*insn
= this->insn
->asCmp();
1166 switch (insn
->src(1).getFile()) {
1168 emitInsn(0x5b800000);
1169 emitGPR (0x14, insn
->src(1));
1171 case FILE_MEMORY_CONST
:
1172 emitInsn(0x4b800000);
1173 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1175 case FILE_IMMEDIATE
:
1176 emitInsn(0x36800000);
1177 emitIMMD(0x14, 19, insn
->src(1));
1180 assert(!"bad src1 file");
1184 if (insn
->op
!= OP_SET
) {
1186 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1187 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1188 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1190 assert(!"invalid set op");
1193 emitPRED(0x27, insn
->src(2));
1198 emitCond4(0x30, insn
->setCond
);
1199 emitABS (0x2c, insn
->src(1));
1200 emitNEG (0x2b, insn
->src(0));
1201 emitGPR (0x08, insn
->src(0));
1202 emitABS (0x07, insn
->src(0));
1203 emitNEG (0x06, insn
->src(1));
1204 emitPRED (0x03, insn
->def(0));
1205 if (insn
->defExists(1))
1206 emitPRED(0x00, insn
->def(1));
1211 /*******************************************************************************
1213 ******************************************************************************/
1216 CodeEmitterGM107::emitFADD()
1218 if (!longIMMD(insn
->src(1))) {
1219 switch (insn
->src(1).getFile()) {
1221 emitInsn(0x5c580000);
1222 emitGPR (0x14, insn
->src(1));
1224 case FILE_MEMORY_CONST
:
1225 emitInsn(0x4c580000);
1226 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1228 case FILE_IMMEDIATE
:
1229 emitInsn(0x38580000);
1230 emitIMMD(0x14, 19, insn
->src(1));
1233 assert(!"bad src1 file");
1237 emitABS(0x31, insn
->src(1));
1238 emitNEG(0x30, insn
->src(0));
1240 emitABS(0x2e, insn
->src(0));
1241 emitNEG(0x2d, insn
->src(1));
1244 if (insn
->op
== OP_SUB
)
1245 code
[1] ^= 0x00002000;
1247 emitInsn(0x08000000);
1248 emitABS(0x39, insn
->src(1));
1249 emitNEG(0x38, insn
->src(0));
1251 emitABS(0x36, insn
->src(0));
1252 emitNEG(0x35, insn
->src(1));
1254 emitIMMD(0x14, 32, insn
->src(1));
1256 if (insn
->op
== OP_SUB
)
1257 code
[1] ^= 0x00080000;
1260 emitGPR(0x08, insn
->src(0));
1261 emitGPR(0x00, insn
->def(0));
1265 CodeEmitterGM107::emitFMUL()
1267 if (!longIMMD(insn
->src(1))) {
1268 switch (insn
->src(1).getFile()) {
1270 emitInsn(0x5c680000);
1271 emitGPR (0x14, insn
->src(1));
1273 case FILE_MEMORY_CONST
:
1274 emitInsn(0x4c680000);
1275 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1277 case FILE_IMMEDIATE
:
1278 emitInsn(0x38680000);
1279 emitIMMD(0x14, 19, insn
->src(1));
1282 assert(!"bad src1 file");
1286 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1292 emitInsn(0x1e000000);
1296 emitIMMD(0x14, 32, insn
->src(1));
1297 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1298 code
[1] ^= 0x00080000; /* flip immd sign bit */
1301 emitGPR(0x08, insn
->src(0));
1302 emitGPR(0x00, insn
->def(0));
1306 CodeEmitterGM107::emitFFMA()
1308 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1309 switch(insn
->src(2).getFile()) {
1311 switch (insn
->src(1).getFile()) {
1313 emitInsn(0x59800000);
1314 emitGPR (0x14, insn
->src(1));
1316 case FILE_MEMORY_CONST
:
1317 emitInsn(0x49800000);
1318 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1320 case FILE_IMMEDIATE
:
1321 emitInsn(0x32800000);
1322 emitIMMD(0x14, 19, insn
->src(1));
1325 assert(!"bad src1 file");
1328 emitGPR (0x27, insn
->src(2));
1330 case FILE_MEMORY_CONST
:
1331 emitInsn(0x51800000);
1332 emitGPR (0x27, insn
->src(1));
1333 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1336 assert(!"bad src2 file");
1341 emitNEG (0x31, insn
->src(2));
1342 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1346 emitGPR(0x08, insn
->src(0));
1347 emitGPR(0x00, insn
->def(0));
1351 CodeEmitterGM107::emitMUFU()
1356 case OP_COS
: mufu
= 0; break;
1357 case OP_SIN
: mufu
= 1; break;
1358 case OP_EX2
: mufu
= 2; break;
1359 case OP_LG2
: mufu
= 3; break;
1360 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1361 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1363 assert(!"invalid mufu");
1367 emitInsn (0x50800000);
1369 emitNEG (0x30, insn
->src(0));
1370 emitABS (0x2e, insn
->src(0));
1371 emitField(0x14, 3, mufu
);
1372 emitGPR (0x08, insn
->src(0));
1373 emitGPR (0x00, insn
->def(0));
1377 CodeEmitterGM107::emitFMNMX()
1379 switch (insn
->src(1).getFile()) {
1381 emitInsn(0x5c600000);
1382 emitGPR (0x14, insn
->src(1));
1384 case FILE_MEMORY_CONST
:
1385 emitInsn(0x4c600000);
1386 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1388 case FILE_IMMEDIATE
:
1389 emitInsn(0x38600000);
1390 emitIMMD(0x14, 19, insn
->src(1));
1393 assert(!"bad src1 file");
1397 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1400 emitABS(0x31, insn
->src(1));
1401 emitNEG(0x30, insn
->src(0));
1403 emitABS(0x2e, insn
->src(0));
1404 emitNEG(0x2d, insn
->src(1));
1406 emitGPR(0x08, insn
->src(0));
1407 emitGPR(0x00, insn
->def(0));
1411 CodeEmitterGM107::emitRRO()
1413 switch (insn
->src(0).getFile()) {
1415 emitInsn(0x5c900000);
1416 emitGPR (0x14, insn
->src(0));
1418 case FILE_MEMORY_CONST
:
1419 emitInsn(0x4c900000);
1420 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1422 case FILE_IMMEDIATE
:
1423 emitInsn(0x38900000);
1424 emitIMMD(0x14, 19, insn
->src(0));
1427 assert(!"bad src file");
1431 emitABS (0x31, insn
->src(0));
1432 emitNEG (0x2d, insn
->src(0));
1433 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1434 emitGPR (0x00, insn
->def(0));
1438 CodeEmitterGM107::emitFCMP()
1440 const CmpInstruction
*insn
= this->insn
->asCmp();
1441 CondCode cc
= insn
->setCond
;
1443 if (insn
->src(2).mod
.neg())
1444 cc
= reverseCondCode(cc
);
1446 switch(insn
->src(2).getFile()) {
1448 switch (insn
->src(1).getFile()) {
1450 emitInsn(0x5ba00000);
1451 emitGPR (0x14, insn
->src(1));
1453 case FILE_MEMORY_CONST
:
1454 emitInsn(0x4ba00000);
1455 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1457 case FILE_IMMEDIATE
:
1458 emitInsn(0x36a00000);
1459 emitIMMD(0x14, 19, insn
->src(1));
1462 assert(!"bad src1 file");
1465 emitGPR (0x27, insn
->src(2));
1467 case FILE_MEMORY_CONST
:
1468 emitInsn(0x53a00000);
1469 emitGPR (0x27, insn
->src(1));
1470 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1473 assert(!"bad src2 file");
1477 emitCond4(0x30, cc
);
1479 emitGPR (0x08, insn
->src(0));
1480 emitGPR (0x00, insn
->def(0));
1484 CodeEmitterGM107::emitFSET()
1486 const CmpInstruction
*insn
= this->insn
->asCmp();
1488 switch (insn
->src(1).getFile()) {
1490 emitInsn(0x58000000);
1491 emitGPR (0x14, insn
->src(1));
1493 case FILE_MEMORY_CONST
:
1494 emitInsn(0x48000000);
1495 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1497 case FILE_IMMEDIATE
:
1498 emitInsn(0x30000000);
1499 emitIMMD(0x14, 19, insn
->src(1));
1502 assert(!"bad src1 file");
1506 if (insn
->op
!= OP_SET
) {
1508 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1509 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1510 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1512 assert(!"invalid set op");
1515 emitPRED(0x27, insn
->src(2));
1521 emitABS (0x36, insn
->src(0));
1522 emitNEG (0x35, insn
->src(1));
1523 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1524 emitCond4(0x30, insn
->setCond
);
1526 emitABS (0x2c, insn
->src(1));
1527 emitNEG (0x2b, insn
->src(0));
1528 emitGPR (0x08, insn
->src(0));
1529 emitGPR (0x00, insn
->def(0));
1533 CodeEmitterGM107::emitFSETP()
1535 const CmpInstruction
*insn
= this->insn
->asCmp();
1537 switch (insn
->src(1).getFile()) {
1539 emitInsn(0x5bb00000);
1540 emitGPR (0x14, insn
->src(1));
1542 case FILE_MEMORY_CONST
:
1543 emitInsn(0x4bb00000);
1544 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1546 case FILE_IMMEDIATE
:
1547 emitInsn(0x36b00000);
1548 emitIMMD(0x14, 19, insn
->src(1));
1551 assert(!"bad src1 file");
1555 if (insn
->op
!= OP_SET
) {
1557 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1558 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1559 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1561 assert(!"invalid set op");
1564 emitPRED(0x27, insn
->src(2));
1569 emitCond4(0x30, insn
->setCond
);
1571 emitABS (0x2c, insn
->src(1));
1572 emitNEG (0x2b, insn
->src(0));
1573 emitGPR (0x08, insn
->src(0));
1574 emitABS (0x07, insn
->src(0));
1575 emitNEG (0x06, insn
->src(1));
1576 emitPRED (0x03, insn
->def(0));
1577 if (insn
->defExists(1))
1578 emitPRED(0x00, insn
->def(1));
1584 CodeEmitterGM107::emitFSWZADD()
1586 emitInsn (0x50f80000);
1590 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1591 emitField(0x1c, 8, insn
->subOp
);
1592 if (insn
->predSrc
!= 1)
1593 emitGPR (0x14, insn
->src(1));
1596 emitGPR (0x08, insn
->src(0));
1597 emitGPR (0x00, insn
->def(0));
1600 /*******************************************************************************
1602 ******************************************************************************/
1605 CodeEmitterGM107::emitLOP()
1610 case OP_AND
: lop
= 0; break;
1611 case OP_OR
: lop
= 1; break;
1612 case OP_XOR
: lop
= 2; break;
1614 assert(!"invalid lop");
1618 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1619 switch (insn
->src(1).getFile()) {
1621 emitInsn(0x5c400000);
1622 emitGPR (0x14, insn
->src(1));
1624 case FILE_MEMORY_CONST
:
1625 emitInsn(0x4c400000);
1626 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1628 case FILE_IMMEDIATE
:
1629 emitInsn(0x38400000);
1630 emitIMMD(0x14, 19, insn
->src(1));
1633 assert(!"bad src1 file");
1639 emitField(0x29, 2, lop
);
1640 emitINV (0x28, insn
->src(1));
1641 emitINV (0x27, insn
->src(0));
1643 emitInsn (0x04000000);
1645 emitINV (0x38, insn
->src(1));
1646 emitINV (0x37, insn
->src(0));
1647 emitField(0x35, 2, lop
);
1649 emitIMMD (0x14, 32, insn
->src(1));
1652 emitGPR (0x08, insn
->src(0));
1653 emitGPR (0x00, insn
->def(0));
1656 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1658 CodeEmitterGM107::emitNOT()
1660 if (!longIMMD(insn
->src(0))) {
1661 switch (insn
->src(0).getFile()) {
1663 emitInsn(0x5c400700);
1664 emitGPR (0x14, insn
->src(0));
1666 case FILE_MEMORY_CONST
:
1667 emitInsn(0x4c400700);
1668 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1670 case FILE_IMMEDIATE
:
1671 emitInsn(0x38400700);
1672 emitIMMD(0x14, 19, insn
->src(0));
1675 assert(!"bad src1 file");
1680 emitInsn (0x05600000);
1681 emitIMMD (0x14, 32, insn
->src(1));
1685 emitGPR(0x00, insn
->def(0));
1689 CodeEmitterGM107::emitIADD()
1691 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1692 switch (insn
->src(1).getFile()) {
1694 emitInsn(0x5c100000);
1695 emitGPR (0x14, insn
->src(1));
1697 case FILE_MEMORY_CONST
:
1698 emitInsn(0x4c100000);
1699 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1701 case FILE_IMMEDIATE
:
1702 emitInsn(0x38100000);
1703 emitIMMD(0x14, 19, insn
->src(1));
1706 assert(!"bad src1 file");
1710 emitNEG(0x31, insn
->src(0));
1711 emitNEG(0x30, insn
->src(1));
1715 emitInsn(0x1c000000);
1716 emitNEG (0x38, insn
->src(0));
1720 emitIMMD(0x14, 32, insn
->src(1));
1723 if (insn
->op
== OP_SUB
)
1724 code
[1] ^= 0x00010000;
1726 emitGPR(0x08, insn
->src(0));
1727 emitGPR(0x00, insn
->def(0));
1731 CodeEmitterGM107::emitIMUL()
1733 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1734 switch (insn
->src(1).getFile()) {
1736 emitInsn(0x5c380000);
1737 emitGPR (0x14, insn
->src(1));
1739 case FILE_MEMORY_CONST
:
1740 emitInsn(0x4c380000);
1741 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1743 case FILE_IMMEDIATE
:
1744 emitInsn(0x38380000);
1745 emitIMMD(0x14, 19, insn
->src(1));
1748 assert(!"bad src1 file");
1752 emitField(0x29, 1, isSignedType(insn
->sType
));
1753 emitField(0x28, 1, isSignedType(insn
->dType
));
1754 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1756 emitInsn (0x1f000000);
1757 emitField(0x37, 1, isSignedType(insn
->sType
));
1758 emitField(0x36, 1, isSignedType(insn
->dType
));
1759 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1761 emitIMMD (0x14, 32, insn
->src(1));
1764 emitGPR(0x08, insn
->src(0));
1765 emitGPR(0x00, insn
->def(0));
1769 CodeEmitterGM107::emitIMAD()
1771 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1772 switch(insn
->src(2).getFile()) {
1774 switch (insn
->src(1).getFile()) {
1776 emitInsn(0x5a000000);
1777 emitGPR (0x14, insn
->src(1));
1779 case FILE_MEMORY_CONST
:
1780 emitInsn(0x4a000000);
1781 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1783 case FILE_IMMEDIATE
:
1784 emitInsn(0x34000000);
1785 emitIMMD(0x14, 19, insn
->src(1));
1788 assert(!"bad src1 file");
1791 emitGPR (0x27, insn
->src(2));
1793 case FILE_MEMORY_CONST
:
1794 emitInsn(0x52000000);
1795 emitGPR (0x27, insn
->src(1));
1796 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1799 assert(!"bad src2 file");
1803 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1804 emitField(0x35, 1, isSignedType(insn
->sType
));
1805 emitNEG (0x34, insn
->src(2));
1806 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1809 emitField(0x30, 1, isSignedType(insn
->dType
));
1811 emitGPR (0x08, insn
->src(0));
1812 emitGPR (0x00, insn
->def(0));
1816 CodeEmitterGM107::emitIMNMX()
1818 switch (insn
->src(1).getFile()) {
1820 emitInsn(0x5c200000);
1821 emitGPR (0x14, insn
->src(1));
1823 case FILE_MEMORY_CONST
:
1824 emitInsn(0x4c200000);
1825 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1827 case FILE_IMMEDIATE
:
1828 emitInsn(0x38200000);
1829 emitIMMD(0x14, 19, insn
->src(1));
1832 assert(!"bad src1 file");
1836 emitField(0x30, 1, isSignedType(insn
->dType
));
1838 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1840 emitGPR (0x08, insn
->src(0));
1841 emitGPR (0x00, insn
->def(0));
1845 CodeEmitterGM107::emitICMP()
1847 const CmpInstruction
*insn
= this->insn
->asCmp();
1848 CondCode cc
= insn
->setCond
;
1850 if (insn
->src(2).mod
.neg())
1851 cc
= reverseCondCode(cc
);
1853 switch(insn
->src(2).getFile()) {
1855 switch (insn
->src(1).getFile()) {
1857 emitInsn(0x5b400000);
1858 emitGPR (0x14, insn
->src(1));
1860 case FILE_MEMORY_CONST
:
1861 emitInsn(0x4b400000);
1862 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1864 case FILE_IMMEDIATE
:
1865 emitInsn(0x36400000);
1866 emitIMMD(0x14, 19, insn
->src(1));
1869 assert(!"bad src1 file");
1872 emitGPR (0x27, insn
->src(2));
1874 case FILE_MEMORY_CONST
:
1875 emitInsn(0x53400000);
1876 emitGPR (0x27, insn
->src(1));
1877 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1880 assert(!"bad src2 file");
1884 emitCond3(0x31, cc
);
1885 emitField(0x30, 1, isSignedType(insn
->sType
));
1886 emitGPR (0x08, insn
->src(0));
1887 emitGPR (0x00, insn
->def(0));
1891 CodeEmitterGM107::emitISET()
1893 const CmpInstruction
*insn
= this->insn
->asCmp();
1895 switch (insn
->src(1).getFile()) {
1897 emitInsn(0x5b500000);
1898 emitGPR (0x14, insn
->src(1));
1900 case FILE_MEMORY_CONST
:
1901 emitInsn(0x4b500000);
1902 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1904 case FILE_IMMEDIATE
:
1905 emitInsn(0x36500000);
1906 emitIMMD(0x14, 19, insn
->src(1));
1909 assert(!"bad src1 file");
1913 if (insn
->op
!= OP_SET
) {
1915 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1916 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1917 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1919 assert(!"invalid set op");
1922 emitPRED(0x27, insn
->src(2));
1927 emitCond3(0x31, insn
->setCond
);
1928 emitField(0x30, 1, isSignedType(insn
->sType
));
1930 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1932 emitGPR (0x08, insn
->src(0));
1933 emitGPR (0x00, insn
->def(0));
1937 CodeEmitterGM107::emitISETP()
1939 const CmpInstruction
*insn
= this->insn
->asCmp();
1941 switch (insn
->src(1).getFile()) {
1943 emitInsn(0x5b600000);
1944 emitGPR (0x14, insn
->src(1));
1946 case FILE_MEMORY_CONST
:
1947 emitInsn(0x4b600000);
1948 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1950 case FILE_IMMEDIATE
:
1951 emitInsn(0x36600000);
1952 emitIMMD(0x14, 19, insn
->src(1));
1955 assert(!"bad src1 file");
1959 if (insn
->op
!= OP_SET
) {
1961 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1962 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1963 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1965 assert(!"invalid set op");
1968 emitPRED(0x27, insn
->src(2));
1973 emitCond3(0x31, insn
->setCond
);
1974 emitField(0x30, 1, isSignedType(insn
->sType
));
1976 emitGPR (0x08, insn
->src(0));
1977 emitPRED (0x03, insn
->def(0));
1978 if (insn
->defExists(1))
1979 emitPRED(0x00, insn
->def(1));
1985 CodeEmitterGM107::emitSHL()
1987 switch (insn
->src(1).getFile()) {
1989 emitInsn(0x5c480000);
1990 emitGPR (0x14, insn
->src(1));
1992 case FILE_MEMORY_CONST
:
1993 emitInsn(0x4c480000);
1994 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1996 case FILE_IMMEDIATE
:
1997 emitInsn(0x38480000);
1998 emitIMMD(0x14, 19, insn
->src(1));
2001 assert(!"bad src1 file");
2007 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2008 emitGPR (0x08, insn
->src(0));
2009 emitGPR (0x00, insn
->def(0));
2013 CodeEmitterGM107::emitSHR()
2015 switch (insn
->src(1).getFile()) {
2017 emitInsn(0x5c280000);
2018 emitGPR (0x14, insn
->src(1));
2020 case FILE_MEMORY_CONST
:
2021 emitInsn(0x4c280000);
2022 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2024 case FILE_IMMEDIATE
:
2025 emitInsn(0x38280000);
2026 emitIMMD(0x14, 19, insn
->src(1));
2029 assert(!"bad src1 file");
2033 emitField(0x30, 1, isSignedType(insn
->dType
));
2036 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2037 emitGPR (0x08, insn
->src(0));
2038 emitGPR (0x00, insn
->def(0));
2042 CodeEmitterGM107::emitPOPC()
2044 switch (insn
->src(0).getFile()) {
2046 emitInsn(0x5c080000);
2047 emitGPR (0x14, insn
->src(0));
2049 case FILE_MEMORY_CONST
:
2050 emitInsn(0x4c080000);
2051 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2053 case FILE_IMMEDIATE
:
2054 emitInsn(0x38080000);
2055 emitIMMD(0x14, 19, insn
->src(0));
2058 assert(!"bad src1 file");
2062 emitINV(0x28, insn
->src(0));
2063 emitGPR(0x00, insn
->def(0));
2067 CodeEmitterGM107::emitBFI()
2069 switch(insn
->src(2).getFile()) {
2071 switch (insn
->src(1).getFile()) {
2073 emitInsn(0x5bf00000);
2074 emitGPR (0x14, insn
->src(1));
2076 case FILE_MEMORY_CONST
:
2077 emitInsn(0x4bf00000);
2078 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2080 case FILE_IMMEDIATE
:
2081 emitInsn(0x36f00000);
2082 emitIMMD(0x14, 19, insn
->src(1));
2085 assert(!"bad src1 file");
2088 emitGPR (0x27, insn
->src(2));
2090 case FILE_MEMORY_CONST
:
2091 emitInsn(0x53f00000);
2092 emitGPR (0x27, insn
->src(1));
2093 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2096 assert(!"bad src2 file");
2101 emitGPR (0x08, insn
->src(0));
2102 emitGPR (0x00, insn
->def(0));
2106 CodeEmitterGM107::emitBFE()
2108 switch (insn
->src(1).getFile()) {
2110 emitInsn(0x5c000000);
2111 emitGPR (0x14, insn
->src(1));
2113 case FILE_MEMORY_CONST
:
2114 emitInsn(0x4c000000);
2115 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2117 case FILE_IMMEDIATE
:
2118 emitInsn(0x38000000);
2119 emitIMMD(0x14, 19, insn
->src(1));
2122 assert(!"bad src1 file");
2126 emitField(0x30, 1, isSignedType(insn
->dType
));
2128 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2129 emitGPR (0x08, insn
->src(0));
2130 emitGPR (0x00, insn
->def(0));
2134 CodeEmitterGM107::emitFLO()
2136 switch (insn
->src(0).getFile()) {
2138 emitInsn(0x5c300000);
2139 emitGPR (0x14, insn
->src(0));
2141 case FILE_MEMORY_CONST
:
2142 emitInsn(0x4c300000);
2143 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2145 case FILE_IMMEDIATE
:
2146 emitInsn(0x38300000);
2147 emitIMMD(0x14, 19, insn
->src(0));
2150 assert(!"bad src1 file");
2154 emitField(0x30, 1, isSignedType(insn
->dType
));
2156 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2157 emitINV (0x28, insn
->src(0));
2158 emitGPR (0x00, insn
->def(0));
2161 /*******************************************************************************
2163 ******************************************************************************/
2166 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2170 switch (typeSizeof(type
)) {
2171 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2172 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2173 case 4: data
= 4; break;
2174 case 8: data
= 5; break;
2175 case 16: data
= 6; break;
2177 assert(!"bad type");
2181 emitField(pos
, 3, data
);
2185 CodeEmitterGM107::emitLDSTc(int pos
)
2189 switch (insn
->cache
) {
2190 case CACHE_CA
: mode
= 0; break;
2191 case CACHE_CG
: mode
= 1; break;
2192 case CACHE_CS
: mode
= 2; break;
2193 case CACHE_CV
: mode
= 3; break;
2195 assert(!"invalid caching mode");
2199 emitField(pos
, 2, mode
);
2203 CodeEmitterGM107::emitLDC()
2205 emitInsn (0xef900000);
2206 emitLDSTs(0x30, insn
->dType
);
2207 emitField(0x2c, 2, insn
->subOp
);
2208 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2209 emitGPR (0x00, insn
->def(0));
2213 CodeEmitterGM107::emitLDL()
2215 emitInsn (0xef400000);
2216 emitLDSTs(0x30, insn
->dType
);
2218 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2219 emitGPR (0x00, insn
->def(0));
2223 CodeEmitterGM107::emitLDS()
2225 emitInsn (0xef480000);
2226 emitLDSTs(0x30, insn
->dType
);
2227 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2228 emitGPR (0x00, insn
->def(0));
2232 CodeEmitterGM107::emitLD()
2234 emitInsn (0x80000000);
2237 emitLDSTs(0x35, insn
->dType
);
2238 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2239 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2240 emitGPR (0x00, insn
->def(0));
2244 CodeEmitterGM107::emitSTL()
2246 emitInsn (0xef500000);
2247 emitLDSTs(0x30, insn
->dType
);
2249 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2250 emitGPR (0x00, insn
->src(1));
2254 CodeEmitterGM107::emitSTS()
2256 emitInsn (0xef580000);
2257 emitLDSTs(0x30, insn
->dType
);
2258 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2259 emitGPR (0x00, insn
->src(1));
2263 CodeEmitterGM107::emitST()
2265 emitInsn (0xa0000000);
2268 emitLDSTs(0x35, insn
->dType
);
2269 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2270 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2271 emitGPR (0x00, insn
->src(1));
2275 CodeEmitterGM107::emitALD()
2277 emitInsn (0xefd80000);
2278 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2279 emitGPR (0x27, insn
->src(0).getIndirect(1));
2282 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2283 emitGPR (0x00, insn
->def(0));
2287 CodeEmitterGM107::emitAST()
2289 emitInsn (0xeff00000);
2290 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2291 emitGPR (0x27, insn
->src(0).getIndirect(1));
2293 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2294 emitGPR (0x00, insn
->src(1));
2298 CodeEmitterGM107::emitISBERD()
2300 emitInsn(0xefd00000);
2301 emitGPR (0x08, insn
->src(0));
2302 emitGPR (0x00, insn
->def(0));
2306 CodeEmitterGM107::emitAL2P()
2308 emitInsn (0xefa00000);
2309 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2312 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2313 emitGPR (0x08, insn
->src(0).getIndirect(0));
2314 emitGPR (0x00, insn
->def(0));
2318 interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2320 int ipa
= entry
->ipa
;
2321 int reg
= entry
->reg
;
2322 int loc
= entry
->loc
;
2324 if (data
.flatshade
&&
2325 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2326 ipa
= NV50_IR_INTERP_FLAT
;
2328 } else if (data
.force_persample_interp
&&
2329 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2330 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2331 ipa
|= NV50_IR_INTERP_CENTROID
;
2333 code
[loc
+ 1] &= ~(0xf << 0x14);
2334 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2335 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2336 code
[loc
+ 0] &= ~(0xff << 0x14);
2337 code
[loc
+ 0] |= reg
<< 0x14;
2341 CodeEmitterGM107::emitIPA()
2343 int ipam
= 0, ipas
= 0;
2345 switch (insn
->getInterpMode()) {
2346 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2347 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2348 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2349 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2351 assert(!"invalid ipa mode");
2355 switch (insn
->getSampleMode()) {
2356 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2357 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2358 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2360 assert(!"invalid ipa sample mode");
2364 emitInsn (0xe0000000);
2365 emitField(0x36, 2, ipam
);
2366 emitField(0x34, 2, ipas
);
2368 emitField(0x2f, 3, 7);
2369 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2370 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2371 code
[1] |= 0x00000040; /* .idx */
2372 emitGPR(0x00, insn
->def(0));
2374 if (insn
->op
== OP_PINTERP
) {
2375 emitGPR(0x14, insn
->src(1));
2376 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2377 emitGPR(0x27, insn
->src(2));
2378 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2380 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2381 emitGPR(0x27, insn
->src(1));
2383 addInterp(insn
->ipa
, 0xff, interpApply
);
2386 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2391 CodeEmitterGM107::emitATOM()
2393 unsigned dType
, subOp
;
2395 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2396 switch (insn
->dType
) {
2397 case TYPE_U32
: dType
= 0; break;
2398 case TYPE_U64
: dType
= 1; break;
2399 default: assert(!"unexpected dType"); dType
= 0; break;
2403 emitInsn (0xee000000);
2405 switch (insn
->dType
) {
2406 case TYPE_U32
: dType
= 0; break;
2407 case TYPE_S32
: dType
= 1; break;
2408 case TYPE_U64
: dType
= 2; break;
2409 case TYPE_F32
: dType
= 3; break;
2410 case TYPE_B128
: dType
= 4; break;
2411 case TYPE_S64
: dType
= 5; break;
2412 default: assert(!"unexpected dType"); dType
= 0; break;
2414 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2417 subOp
= insn
->subOp
;
2419 emitInsn (0xed000000);
2422 emitField(0x34, 4, subOp
);
2423 emitField(0x31, 3, dType
);
2424 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2425 emitGPR (0x14, insn
->src(1));
2426 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2427 emitGPR (0x00, insn
->def(0));
2431 CodeEmitterGM107::emitATOMS()
2433 unsigned dType
, subOp
;
2435 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2436 switch (insn
->dType
) {
2437 case TYPE_U32
: dType
= 0; break;
2438 case TYPE_U64
: dType
= 1; break;
2439 default: assert(!"unexpected dType"); dType
= 0; break;
2443 emitInsn (0xee000000);
2444 emitField(0x34, 1, dType
);
2446 switch (insn
->dType
) {
2447 case TYPE_U32
: dType
= 0; break;
2448 case TYPE_S32
: dType
= 1; break;
2449 case TYPE_U64
: dType
= 2; break;
2450 case TYPE_S64
: dType
= 3; break;
2451 default: assert(!"unexpected dType"); dType
= 0; break;
2454 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2457 subOp
= insn
->subOp
;
2459 emitInsn (0xec000000);
2460 emitField(0x1c, 3, dType
);
2463 emitField(0x34, 4, subOp
);
2464 emitGPR (0x14, insn
->src(1));
2465 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2466 emitGPR (0x00, insn
->def(0));
2470 CodeEmitterGM107::emitCCTL()
2473 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2474 emitInsn(0xef600000);
2477 emitInsn(0xef800000);
2480 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2481 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2482 emitField(0x00, 4, insn
->subOp
);
2485 /*******************************************************************************
2487 ******************************************************************************/
2490 CodeEmitterGM107::emitPIXLD()
2492 emitInsn (0xefe80000);
2494 emitField(0x1f, 3, insn
->subOp
);
2495 emitGPR (0x08, insn
->src(0));
2496 emitGPR (0x00, insn
->def(0));
2499 /*******************************************************************************
2501 ******************************************************************************/
2504 CodeEmitterGM107::emitTEXs(int pos
)
2506 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2507 if (insn
->srcExists(src1
))
2508 emitGPR(pos
, insn
->src(src1
));
2514 CodeEmitterGM107::emitTEX()
2516 const TexInstruction
*insn
= this->insn
->asTex();
2519 if (!insn
->tex
.levelZero
) {
2521 case OP_TEX
: lodm
= 0; break;
2522 case OP_TXB
: lodm
= 2; break;
2523 case OP_TXL
: lodm
= 3; break;
2525 assert(!"invalid tex op");
2532 if (insn
->tex
.rIndirectSrc
>= 0) {
2533 emitInsn (0xdeb80000);
2534 emitField(0x35, 2, lodm
);
2535 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2537 emitInsn (0xc0380000);
2538 emitField(0x37, 2, lodm
);
2539 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2540 emitField(0x24, 13, insn
->tex
.r
);
2543 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2544 emitField(0x31, 1, insn
->tex
.liveOnly
);
2545 emitField(0x23, 1, insn
->tex
.derivAll
);
2546 emitField(0x1f, 4, insn
->tex
.mask
);
2547 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2548 insn
->tex
.target
.getDim() - 1);
2549 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2551 emitGPR (0x08, insn
->src(0));
2552 emitGPR (0x00, insn
->def(0));
2556 CodeEmitterGM107::emitTLD()
2558 const TexInstruction
*insn
= this->insn
->asTex();
2560 if (insn
->tex
.rIndirectSrc
>= 0) {
2561 emitInsn (0xdd380000);
2563 emitInsn (0xdc380000);
2564 emitField(0x24, 13, insn
->tex
.r
);
2567 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2568 emitField(0x32, 1, insn
->tex
.target
.isMS());
2569 emitField(0x31, 1, insn
->tex
.liveOnly
);
2570 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2571 emitField(0x1f, 4, insn
->tex
.mask
);
2572 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2573 insn
->tex
.target
.getDim() - 1);
2574 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2576 emitGPR (0x08, insn
->src(0));
2577 emitGPR (0x00, insn
->def(0));
2581 CodeEmitterGM107::emitTLD4()
2583 const TexInstruction
*insn
= this->insn
->asTex();
2585 if (insn
->tex
.rIndirectSrc
>= 0) {
2586 emitInsn (0xdef80000);
2587 emitField(0x26, 2, insn
->tex
.gatherComp
);
2588 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2589 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2591 emitInsn (0xc8380000);
2592 emitField(0x38, 2, insn
->tex
.gatherComp
);
2593 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2594 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2595 emitField(0x24, 13, insn
->tex
.r
);
2598 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2599 emitField(0x31, 1, insn
->tex
.liveOnly
);
2600 emitField(0x23, 1, insn
->tex
.derivAll
);
2601 emitField(0x1f, 4, insn
->tex
.mask
);
2602 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2603 insn
->tex
.target
.getDim() - 1);
2604 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2606 emitGPR (0x08, insn
->src(0));
2607 emitGPR (0x00, insn
->def(0));
2611 CodeEmitterGM107::emitTXD()
2613 const TexInstruction
*insn
= this->insn
->asTex();
2615 if (insn
->tex
.rIndirectSrc
>= 0) {
2616 emitInsn (0xde780000);
2618 emitInsn (0xde380000);
2619 emitField(0x24, 13, insn
->tex
.r
);
2622 emitField(0x31, 1, insn
->tex
.liveOnly
);
2623 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2624 emitField(0x1f, 4, insn
->tex
.mask
);
2625 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2626 insn
->tex
.target
.getDim() - 1);
2627 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2629 emitGPR (0x08, insn
->src(0));
2630 emitGPR (0x00, insn
->def(0));
2634 CodeEmitterGM107::emitTMML()
2636 const TexInstruction
*insn
= this->insn
->asTex();
2638 if (insn
->tex
.rIndirectSrc
>= 0) {
2639 emitInsn (0xdf600000);
2641 emitInsn (0xdf580000);
2642 emitField(0x24, 13, insn
->tex
.r
);
2645 emitField(0x31, 1, insn
->tex
.liveOnly
);
2646 emitField(0x23, 1, insn
->tex
.derivAll
);
2647 emitField(0x1f, 4, insn
->tex
.mask
);
2648 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2649 insn
->tex
.target
.getDim() - 1);
2650 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2652 emitGPR (0x08, insn
->src(0));
2653 emitGPR (0x00, insn
->def(0));
2657 CodeEmitterGM107::emitTXQ()
2659 const TexInstruction
*insn
= this->insn
->asTex();
2662 switch (insn
->tex
.query
) {
2663 case TXQ_DIMS
: type
= 0x01; break;
2664 case TXQ_TYPE
: type
= 0x02; break;
2665 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2666 case TXQ_FILTER
: type
= 0x10; break;
2667 case TXQ_LOD
: type
= 0x12; break;
2668 case TXQ_WRAP
: type
= 0x14; break;
2669 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2671 assert(!"invalid txq query");
2675 if (insn
->tex
.rIndirectSrc
>= 0) {
2676 emitInsn (0xdf500000);
2678 emitInsn (0xdf480000);
2679 emitField(0x24, 13, insn
->tex
.r
);
2682 emitField(0x31, 1, insn
->tex
.liveOnly
);
2683 emitField(0x1f, 4, insn
->tex
.mask
);
2684 emitField(0x16, 6, type
);
2685 emitGPR (0x08, insn
->src(0));
2686 emitGPR (0x00, insn
->def(0));
2690 CodeEmitterGM107::emitDEPBAR()
2692 emitInsn (0xf0f00000);
2693 emitField(0x1d, 1, 1); /* le */
2694 emitField(0x1a, 3, 5);
2695 emitField(0x14, 6, insn
->subOp
);
2696 emitField(0x00, 6, insn
->subOp
);
2699 /*******************************************************************************
2701 ******************************************************************************/
2704 CodeEmitterGM107::emitNOP()
2706 emitInsn(0x50b00000);
2710 CodeEmitterGM107::emitKIL()
2712 emitInsn (0xe3300000);
2713 emitCond5(0x00, CC_TR
);
2717 CodeEmitterGM107::emitOUT()
2719 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2720 const int emit
= insn
->op
== OP_EMIT
;
2722 switch (insn
->src(1).getFile()) {
2724 emitInsn(0xfbe00000);
2725 emitGPR (0x14, insn
->src(1));
2727 case FILE_IMMEDIATE
:
2728 emitInsn(0xf6e00000);
2729 emitIMMD(0x14, 19, insn
->src(1));
2731 case FILE_MEMORY_CONST
:
2732 emitInsn(0xebe00000);
2733 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2736 assert(!"bad src1 file");
2740 emitField(0x27, 2, (cut
<< 1) | emit
);
2741 emitGPR (0x08, insn
->src(0));
2742 emitGPR (0x00, insn
->def(0));
2746 CodeEmitterGM107::emitBAR()
2750 emitInsn (0xf0a80000);
2752 switch (insn
->subOp
) {
2753 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2754 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2755 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2756 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2759 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2763 emitField(0x20, 8, subop
);
2766 if (insn
->src(0).getFile() == FILE_GPR
) {
2767 emitGPR(0x08, insn
->src(0));
2769 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2771 emitField(0x08, 8, imm
->reg
.data
.u32
);
2772 emitField(0x2b, 1, 1);
2776 if (insn
->src(1).getFile() == FILE_GPR
) {
2777 emitGPR(0x14, insn
->src(1));
2779 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2781 emitField(0x14, 12, imm
->reg
.data
.u32
);
2782 emitField(0x2c, 1, 1);
2785 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2786 emitPRED (0x27, insn
->src(2));
2787 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2789 emitField(0x27, 3, 7);
2794 CodeEmitterGM107::emitMEMBAR()
2796 emitInsn (0xef980000);
2797 emitField(0x08, 2, insn
->subOp
>> 2);
2801 CodeEmitterGM107::emitVOTE()
2803 assert(insn
->src(0).getFile() == FILE_PREDICATE
);
2806 for (int i
= 0; insn
->defExists(i
); i
++) {
2807 if (insn
->def(i
).getFile() == FILE_GPR
)
2809 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
2813 emitInsn (0x50d80000);
2814 emitField(0x30, 2, insn
->subOp
);
2816 emitGPR (0x00, insn
->def(r
));
2820 emitPRED (0x2d, insn
->def(p
));
2823 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2824 emitPRED (0x27, insn
->src(0));
2828 CodeEmitterGM107::emitSUTarget()
2830 const TexInstruction
*insn
= this->insn
->asTex();
2833 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2835 if (insn
->tex
.target
== TEX_TARGET_BUFFER
) {
2837 } else if (insn
->tex
.target
== TEX_TARGET_1D_ARRAY
) {
2839 } else if (insn
->tex
.target
== TEX_TARGET_2D
||
2840 insn
->tex
.target
== TEX_TARGET_RECT
) {
2842 } else if (insn
->tex
.target
== TEX_TARGET_2D_ARRAY
||
2843 insn
->tex
.target
== TEX_TARGET_CUBE
||
2844 insn
->tex
.target
== TEX_TARGET_CUBE_ARRAY
) {
2846 } else if (insn
->tex
.target
== TEX_TARGET_3D
) {
2849 assert(insn
->tex
.target
== TEX_TARGET_1D
);
2851 emitField(0x20, 4, target
);
2855 CodeEmitterGM107::emitSUHandle(const int s
)
2857 const TexInstruction
*insn
= this->insn
->asTex();
2859 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2861 if (insn
->src(s
).getFile() == FILE_GPR
) {
2862 emitGPR(0x27, insn
->src(s
));
2864 ImmediateValue
*imm
= insn
->getSrc(s
)->asImm();
2866 emitField(0x33, 1, 1);
2867 emitField(0x24, 13, imm
->reg
.data
.u32
);
2872 CodeEmitterGM107::emitSUSTx()
2874 const TexInstruction
*insn
= this->insn
->asTex();
2876 emitInsn(0xeb200000);
2877 if (insn
->op
== OP_SUSTB
)
2878 emitField(0x34, 1, 1);
2882 emitField(0x14, 4, 0xf); // rgba
2883 emitGPR (0x08, insn
->src(0));
2884 emitGPR (0x00, insn
->src(1));
2890 CodeEmitterGM107::emitSULDx()
2892 const TexInstruction
*insn
= this->insn
->asTex();
2895 emitInsn(0xeb000000);
2896 if (insn
->op
== OP_SULDB
)
2897 emitField(0x34, 1, 1);
2900 switch (insn
->dType
) {
2901 case TYPE_S8
: type
= 1; break;
2902 case TYPE_U16
: type
= 2; break;
2903 case TYPE_S16
: type
= 3; break;
2904 case TYPE_U32
: type
= 4; break;
2905 case TYPE_U64
: type
= 5; break;
2906 case TYPE_B128
: type
= 6; break;
2908 assert(insn
->dType
== TYPE_U8
);
2912 emitField(0x14, 3, type
);
2913 emitGPR (0x00, insn
->def(0));
2914 emitGPR (0x08, insn
->src(0));
2920 CodeEmitterGM107::emitSUREDx()
2922 const TexInstruction
*insn
= this->insn
->asTex();
2923 uint8_t type
= 0, subOp
;
2925 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
)
2926 emitInsn(0xeac00000);
2928 emitInsn(0xea600000);
2930 if (insn
->op
== OP_SUREDB
)
2931 emitField(0x34, 1, 1);
2935 switch (insn
->dType
) {
2936 case TYPE_S32
: type
= 1; break;
2937 case TYPE_U64
: type
= 2; break;
2938 case TYPE_F32
: type
= 3; break;
2939 case TYPE_S64
: type
= 5; break;
2941 assert(insn
->dType
== TYPE_U32
);
2946 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2948 } else if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
) {
2951 subOp
= insn
->subOp
;
2954 emitField(0x24, 3, type
);
2955 emitField(0x1d, 4, subOp
);
2956 emitGPR (0x14, insn
->src(1));
2957 emitGPR (0x08, insn
->src(0));
2958 emitGPR (0x00, insn
->def(0));
2963 /*******************************************************************************
2964 * assembler front-end
2965 ******************************************************************************/
2968 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2970 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2975 if (insn
->encSize
!= 8) {
2976 ERROR("skipping undecodable instruction: "); insn
->print();
2979 if (codeSize
+ size
> codeSizeLimit
) {
2980 ERROR("code emitter output buffer too small\n");
2984 if (writeIssueDelays
) {
2985 int n
= ((codeSize
& 0x1f) / 8) - 1;
2988 data
[0] = 0x00000000;
2989 data
[1] = 0x00000000;
2995 emitField(data
, n
* 21, 21, insn
->sched
);
3051 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
3052 insn
->src(0).getFile() == FILE_PREDICATE
)) {
3054 } else if (isFloatType(insn
->dType
)) {
3055 if (isFloatType(insn
->sType
))
3060 if (isFloatType(insn
->sType
))
3071 if (isFloatType(insn
->dType
)) {
3072 if (insn
->dType
== TYPE_F64
)
3081 if (isFloatType(insn
->dType
)) {
3082 if (insn
->dType
== TYPE_F64
)
3092 if (isFloatType(insn
->dType
)) {
3093 if (insn
->dType
== TYPE_F64
)
3103 if (isFloatType(insn
->dType
)) {
3104 if (insn
->dType
== TYPE_F64
)
3131 if (isFloatType(insn
->dType
))
3140 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
3141 if (isFloatType(insn
->sType
))
3142 if (insn
->sType
== TYPE_F64
)
3149 if (isFloatType(insn
->sType
))
3150 if (insn
->sType
== TYPE_F64
)
3182 switch (insn
->src(0).getFile()) {
3183 case FILE_MEMORY_CONST
: emitLDC(); break;
3184 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3185 case FILE_MEMORY_SHARED
: emitLDS(); break;
3186 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3188 assert(!"invalid load");
3194 switch (insn
->src(0).getFile()) {
3195 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3196 case FILE_MEMORY_SHARED
: emitSTS(); break;
3197 case FILE_MEMORY_GLOBAL
: emitST(); break;
3199 assert(!"invalid store");
3205 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3290 assert(!"invalid opcode");
3306 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3311 /*******************************************************************************
3312 * sched data calculator
3313 ******************************************************************************/
3315 class SchedDataCalculatorGM107
: public Pass
3318 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3321 bool visit(BasicBlock
*bb
);
3325 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3327 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3329 insn
->sched
= 0x7e0;
3335 /*******************************************************************************
3337 ******************************************************************************/
3340 CodeEmitterGM107::prepareEmission(Function
*func
)
3342 SchedDataCalculatorGM107
sched(targ
);
3343 CodeEmitter::prepareEmission(func
);
3344 sched
.run(func
, true, true);
3347 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3349 return (size
+ 23) / 24;
3353 CodeEmitterGM107::prepareEmission(Program
*prog
)
3355 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3356 !fi
.end(); fi
.next()) {
3357 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3358 func
->binPos
= prog
->binSize
;
3359 prepareEmission(func
);
3361 // adjust sizes & positions for schedulding info:
3362 if (prog
->getTarget()->hasSWSched
) {
3363 uint32_t adjPos
= func
->binPos
;
3364 BasicBlock
*bb
= NULL
;
3365 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3366 bb
= func
->bbArray
[i
];
3367 int32_t adjSize
= bb
->binSize
;
3369 adjSize
-= 32 - adjPos
% 32;
3373 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3374 bb
->binPos
= adjPos
;
3375 bb
->binSize
= adjSize
;
3379 func
->binSize
= adjPos
- func
->binPos
;
3382 prog
->binSize
+= func
->binSize
;
3386 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3387 : CodeEmitter(target
),
3389 writeIssueDelays(target
->hasSWSched
)
3392 codeSize
= codeSizeLimit
= 0;
3397 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3399 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3400 emit
->setProgramType(type
);
3404 } // namespace nv50_ir