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
&);
167 void emitLDSTs(int, DataType
);
206 void emitSUHandle(const int s
);
212 /*******************************************************************************
213 * general instruction layout/fields
214 ******************************************************************************/
217 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
220 uint32_t m
= ((1ULL << s
) - 1);
221 uint64_t d
= (uint64_t)(v
& m
) << b
;
222 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
229 CodeEmitterGM107::emitPred()
231 if (insn
->predSrc
>= 0) {
232 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
233 emitField(19, 1, insn
->cc
== CC_NOT_P
);
240 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
242 code
[0] = 0x00000000;
249 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
251 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
255 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
257 int id
= val
? val
->reg
.data
.id
: -1;
260 case SV_LANEID
: id
= 0x00; break;
261 case SV_VERTEX_COUNT
: id
= 0x10; break;
262 case SV_INVOCATION_ID
: id
= 0x11; break;
263 case SV_THREAD_KILL
: id
= 0x13; break;
264 case SV_INVOCATION_INFO
: id
= 0x1d; break;
265 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
266 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
268 assert(!"invalid system value");
273 emitField(pos
, 8, id
);
277 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
279 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
283 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
286 const Value
*v
= ref
.get();
287 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
289 emitGPR(gpr
, ref
.getIndirect(0));
290 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
294 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
297 const Value
*v
= ref
.get();
298 const Symbol
*s
= v
->asSym();
300 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
302 emitField(buf
, 5, v
->reg
.fileIndex
);
304 emitGPR(gpr
, ref
.getIndirect(0));
305 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
309 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
311 if (ref
.getFile() == FILE_IMMEDIATE
) {
312 const ImmediateValue
*imm
= ref
.get()->asImm();
313 if (isFloatType(insn
->sType
)) {
314 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
317 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
318 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
326 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
328 const ImmediateValue
*imm
= ref
.get()->asImm();
329 uint32_t val
= imm
->reg
.data
.u32
;
332 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
333 assert(!(val
& 0x00000fff));
335 } else if (insn
->sType
== TYPE_F64
) {
336 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
337 val
= imm
->reg
.data
.u64
>> 44;
339 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
340 emitField( 56, 1, (val
& 0x80000) >> 19);
341 emitField(pos
, len
, (val
& 0x7ffff));
343 emitField(pos
, len
, val
);
347 /*******************************************************************************
349 ******************************************************************************/
352 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
357 case CC_FL
: data
= 0x00; break;
359 case CC_LT
: data
= 0x01; break;
361 case CC_EQ
: data
= 0x02; break;
363 case CC_LE
: data
= 0x03; break;
365 case CC_GT
: data
= 0x04; break;
367 case CC_NE
: data
= 0x05; break;
369 case CC_GE
: data
= 0x06; break;
370 case CC_TR
: data
= 0x07; break;
372 assert(!"invalid cond3");
376 emitField(pos
, 3, data
);
380 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
385 case CC_FL
: data
= 0x00; break;
386 case CC_LT
: data
= 0x01; break;
387 case CC_EQ
: data
= 0x02; break;
388 case CC_LE
: data
= 0x03; break;
389 case CC_GT
: data
= 0x04; break;
390 case CC_NE
: data
= 0x05; break;
391 case CC_GE
: data
= 0x06; break;
392 // case CC_NUM: data = 0x07; break;
393 // case CC_NAN: data = 0x08; break;
394 case CC_LTU
: data
= 0x09; break;
395 case CC_EQU
: data
= 0x0a; break;
396 case CC_LEU
: data
= 0x0b; break;
397 case CC_GTU
: data
= 0x0c; break;
398 case CC_NEU
: data
= 0x0d; break;
399 case CC_GEU
: data
= 0x0e; break;
400 case CC_TR
: data
= 0x0f; break;
402 assert(!"invalid cond4");
406 emitField(pos
, 4, data
);
410 CodeEmitterGM107::emitO(int pos
)
412 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
416 CodeEmitterGM107::emitP(int pos
)
418 emitField(pos
, 1, insn
->perPatch
);
422 CodeEmitterGM107::emitSAT(int pos
)
424 emitField(pos
, 1, insn
->saturate
);
428 CodeEmitterGM107::emitCC(int pos
)
430 emitField(pos
, 1, insn
->flagsDef
>= 0);
434 CodeEmitterGM107::emitX(int pos
)
436 emitField(pos
, 1, insn
->flagsSrc
>= 0);
440 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
442 emitField(pos
, 1, ref
.mod
.abs());
446 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
448 emitField(pos
, 1, ref
.mod
.neg());
452 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
454 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
458 CodeEmitterGM107::emitFMZ(int pos
, int len
)
460 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
464 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
468 case ROUND_NI
: ri
= 1;
469 case ROUND_N
: rm
= 0; break;
470 case ROUND_MI
: ri
= 1;
471 case ROUND_M
: rm
= 1; break;
472 case ROUND_PI
: ri
= 1;
473 case ROUND_P
: rm
= 2; break;
474 case ROUND_ZI
: ri
= 1;
475 case ROUND_Z
: rm
= 3; break;
477 assert(!"invalid round mode");
480 emitField(rip
, 1, ri
);
481 emitField(rmp
, 2, rm
);
485 CodeEmitterGM107::emitPDIV(int pos
)
487 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
488 if (insn
->postFactor
> 0)
489 emitField(pos
, 3, 7 - insn
->postFactor
);
491 emitField(pos
, 3, 0 - insn
->postFactor
);
495 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
497 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
500 /*******************************************************************************
502 ******************************************************************************/
505 CodeEmitterGM107::emitEXIT()
507 emitInsn (0xe3000000);
508 emitCond5(0x00, CC_TR
);
512 CodeEmitterGM107::emitBRA()
514 const FlowInstruction
*insn
= this->insn
->asFlow();
517 if (insn
->indirect
) {
519 emitInsn(0xe2000000); // JMX
521 emitInsn(0xe2500000); // BRX
525 emitInsn(0xe2100000); // JMP
527 emitInsn(0xe2400000); // BRA
528 emitField(0x07, 1, insn
->allWarp
);
531 emitField(0x06, 1, insn
->limit
);
532 emitCond5(0x00, CC_TR
);
534 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
535 int32_t pos
= insn
->target
.bb
->binPos
;
536 if (writeIssueDelays
&& !(pos
& 0x1f))
539 emitField(0x14, 24, pos
- (codeSize
+ 8));
541 emitField(0x14, 32, pos
);
543 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
544 emitField(0x05, 1, 1);
549 CodeEmitterGM107::emitCAL()
551 const FlowInstruction
*insn
= this->insn
->asFlow();
553 if (insn
->absolute
) {
554 emitInsn(0xe2200000, 0); // JCAL
556 emitInsn(0xe2600000, 0); // CAL
559 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
561 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
564 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
565 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
566 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
568 emitField(0x14, 32, insn
->target
.bb
->binPos
);
572 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
573 emitField(0x05, 1, 1);
578 CodeEmitterGM107::emitPCNT()
580 const FlowInstruction
*insn
= this->insn
->asFlow();
582 emitInsn(0xe2b00000, 0);
584 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
585 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
587 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
588 emitField(0x05, 1, 1);
593 CodeEmitterGM107::emitCONT()
595 emitInsn (0xe3500000);
596 emitCond5(0x00, CC_TR
);
600 CodeEmitterGM107::emitPBK()
602 const FlowInstruction
*insn
= this->insn
->asFlow();
604 emitInsn(0xe2a00000, 0);
606 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
607 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
609 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
610 emitField(0x05, 1, 1);
615 CodeEmitterGM107::emitBRK()
617 emitInsn (0xe3400000);
618 emitCond5(0x00, CC_TR
);
622 CodeEmitterGM107::emitPRET()
624 const FlowInstruction
*insn
= this->insn
->asFlow();
626 emitInsn(0xe2700000, 0);
628 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
629 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
631 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
632 emitField(0x05, 1, 1);
637 CodeEmitterGM107::emitRET()
639 emitInsn (0xe3200000);
640 emitCond5(0x00, CC_TR
);
644 CodeEmitterGM107::emitSSY()
646 const FlowInstruction
*insn
= this->insn
->asFlow();
648 emitInsn(0xe2900000, 0);
650 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
651 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
653 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
654 emitField(0x05, 1, 1);
659 CodeEmitterGM107::emitSYNC()
661 emitInsn (0xf0f80000);
662 emitCond5(0x00, CC_TR
);
666 CodeEmitterGM107::emitSAM()
668 emitInsn(0xe3700000, 0);
672 CodeEmitterGM107::emitRAM()
674 emitInsn(0xe3800000, 0);
677 /*******************************************************************************
679 ******************************************************************************/
681 /*******************************************************************************
682 * movement / conversion
683 ******************************************************************************/
686 CodeEmitterGM107::emitMOV()
688 if (insn
->src(0).getFile() != FILE_IMMEDIATE
) {
689 switch (insn
->src(0).getFile()) {
691 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
692 emitInsn(0x5b6a0000);
695 emitInsn(0x5c980000);
697 emitGPR (0x14, insn
->src(0));
699 case FILE_MEMORY_CONST
:
700 emitInsn(0x4c980000);
701 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
704 emitInsn(0x38980000);
705 emitIMMD(0x14, 19, insn
->src(0));
708 emitInsn(0x50880000);
709 emitPRED(0x0c, insn
->src(0));
714 assert(!"bad src file");
717 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
718 insn
->src(0).getFile() != FILE_PREDICATE
)
719 emitField(0x27, 4, insn
->lanes
);
721 emitInsn (0x01000000);
722 emitIMMD (0x14, 32, insn
->src(0));
723 emitField(0x0c, 4, insn
->lanes
);
726 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
728 emitPRED(0x03, insn
->def(0));
731 emitGPR(0x00, insn
->def(0));
736 CodeEmitterGM107::emitS2R()
738 emitInsn(0xf0c80000);
739 emitSYS (0x14, insn
->src(0));
740 emitGPR (0x00, insn
->def(0));
744 CodeEmitterGM107::emitF2F()
746 RoundMode rnd
= insn
->rnd
;
749 case OP_FLOOR
: rnd
= ROUND_MI
; break;
750 case OP_CEIL
: rnd
= ROUND_PI
; break;
751 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
756 switch (insn
->src(0).getFile()) {
758 emitInsn(0x5ca80000);
759 emitGPR (0x14, insn
->src(0));
761 case FILE_MEMORY_CONST
:
762 emitInsn(0x4ca80000);
763 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
766 emitInsn(0x38a80000);
767 emitIMMD(0x14, 19, insn
->src(0));
770 assert(!"bad src0 file");
774 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
775 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
777 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
779 emitField(0x29, 1, insn
->subOp
);
780 emitRND (0x27, rnd
, 0x2a);
781 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
782 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
783 emitGPR (0x00, insn
->def(0));
787 CodeEmitterGM107::emitF2I()
789 RoundMode rnd
= insn
->rnd
;
792 case OP_FLOOR
: rnd
= ROUND_M
; break;
793 case OP_CEIL
: rnd
= ROUND_P
; break;
794 case OP_TRUNC
: rnd
= ROUND_Z
; break;
799 switch (insn
->src(0).getFile()) {
801 emitInsn(0x5cb00000);
802 emitGPR (0x14, insn
->src(0));
804 case FILE_MEMORY_CONST
:
805 emitInsn(0x4cb00000);
806 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
809 emitInsn(0x38b00000);
810 emitIMMD(0x14, 19, insn
->src(0));
813 assert(!"bad src0 file");
817 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
819 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
821 emitRND (0x27, rnd
, 0x2a);
822 emitField(0x0c, 1, isSignedType(insn
->dType
));
823 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
824 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
825 emitGPR (0x00, insn
->def(0));
829 CodeEmitterGM107::emitI2F()
831 RoundMode rnd
= insn
->rnd
;
834 case OP_FLOOR
: rnd
= ROUND_M
; break;
835 case OP_CEIL
: rnd
= ROUND_P
; break;
836 case OP_TRUNC
: rnd
= ROUND_Z
; break;
841 switch (insn
->src(0).getFile()) {
843 emitInsn(0x5cb80000);
844 emitGPR (0x14, insn
->src(0));
846 case FILE_MEMORY_CONST
:
847 emitInsn(0x4cb80000);
848 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
851 emitInsn(0x38b80000);
852 emitIMMD(0x14, 19, insn
->src(0));
855 assert(!"bad src0 file");
859 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
861 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
862 emitField(0x29, 2, insn
->subOp
);
863 emitRND (0x27, rnd
, -1);
864 emitField(0x0d, 1, isSignedType(insn
->sType
));
865 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
866 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
867 emitGPR (0x00, insn
->def(0));
871 CodeEmitterGM107::emitI2I()
873 switch (insn
->src(0).getFile()) {
875 emitInsn(0x5ce00000);
876 emitGPR (0x14, insn
->src(0));
878 case FILE_MEMORY_CONST
:
879 emitInsn(0x4ce00000);
880 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
883 emitInsn(0x38e00000);
884 emitIMMD(0x14, 19, insn
->src(0));
887 assert(!"bad src0 file");
892 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
894 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
895 emitField(0x29, 2, insn
->subOp
);
896 emitField(0x0d, 1, isSignedType(insn
->sType
));
897 emitField(0x0c, 1, isSignedType(insn
->dType
));
898 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
899 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
900 emitGPR (0x00, insn
->def(0));
904 selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
906 int loc
= entry
->loc
;
907 if (data
.force_persample_interp
)
908 code
[loc
+ 1] |= 1 << 10;
910 code
[loc
+ 1] &= ~(1 << 10);
914 CodeEmitterGM107::emitSEL()
916 switch (insn
->src(1).getFile()) {
918 emitInsn(0x5ca00000);
919 emitGPR (0x14, insn
->src(1));
921 case FILE_MEMORY_CONST
:
922 emitInsn(0x4ca00000);
923 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
926 emitInsn(0x38a00000);
927 emitIMMD(0x14, 19, insn
->src(1));
930 assert(!"bad src1 file");
934 emitINV (0x2a, insn
->src(2));
935 emitPRED(0x27, insn
->src(2));
936 emitGPR (0x08, insn
->src(0));
937 emitGPR (0x00, insn
->def(0));
939 if (insn
->subOp
== 1) {
940 addInterp(0, 0, selpFlip
);
945 CodeEmitterGM107::emitSHFL()
949 emitInsn (0xef100000);
951 switch (insn
->src(1).getFile()) {
953 emitGPR(0x14, insn
->src(1));
956 emitIMMD(0x14, 5, insn
->src(1));
960 assert(!"invalid src1 file");
964 /*XXX: what is this arg? hardcode immediate for now */
965 emitField(0x22, 13, 0x1c03);
969 emitField(0x1e, 2, insn
->subOp
);
970 emitField(0x1c, 2, type
);
971 emitGPR (0x08, insn
->src(0));
972 emitGPR (0x00, insn
->def(0));
975 /*******************************************************************************
977 ******************************************************************************/
980 CodeEmitterGM107::emitDADD()
982 switch (insn
->src(1).getFile()) {
984 emitInsn(0x5c700000);
985 emitGPR (0x14, insn
->src(1));
987 case FILE_MEMORY_CONST
:
988 emitInsn(0x4c700000);
989 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
992 emitInsn(0x38700000);
993 emitIMMD(0x14, 19, insn
->src(1));
996 assert(!"bad src1 file");
999 emitABS(0x31, insn
->src(1));
1000 emitNEG(0x30, insn
->src(0));
1002 emitABS(0x2e, insn
->src(0));
1003 emitNEG(0x2d, insn
->src(1));
1005 if (insn
->op
== OP_SUB
)
1006 code
[1] ^= 0x00002000;
1008 emitGPR(0x08, insn
->src(0));
1009 emitGPR(0x00, insn
->def(0));
1013 CodeEmitterGM107::emitDMUL()
1015 switch (insn
->src(1).getFile()) {
1017 emitInsn(0x5c800000);
1018 emitGPR (0x14, insn
->src(1));
1020 case FILE_MEMORY_CONST
:
1021 emitInsn(0x4c800000);
1022 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1024 case FILE_IMMEDIATE
:
1025 emitInsn(0x38800000);
1026 emitIMMD(0x14, 19, insn
->src(1));
1029 assert(!"bad src1 file");
1033 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1036 emitGPR (0x08, insn
->src(0));
1037 emitGPR (0x00, insn
->def(0));
1041 CodeEmitterGM107::emitDFMA()
1043 switch(insn
->src(2).getFile()) {
1045 switch (insn
->src(1).getFile()) {
1047 emitInsn(0x5b700000);
1048 emitGPR (0x14, insn
->src(1));
1050 case FILE_MEMORY_CONST
:
1051 emitInsn(0x4b700000);
1052 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1054 case FILE_IMMEDIATE
:
1055 emitInsn(0x36700000);
1056 emitIMMD(0x14, 19, insn
->src(1));
1059 assert(!"bad src1 file");
1062 emitGPR (0x27, insn
->src(2));
1064 case FILE_MEMORY_CONST
:
1065 emitInsn(0x53700000);
1066 emitGPR (0x27, insn
->src(1));
1067 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1070 assert(!"bad src2 file");
1075 emitNEG (0x31, insn
->src(2));
1076 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1078 emitGPR (0x08, insn
->src(0));
1079 emitGPR (0x00, insn
->def(0));
1083 CodeEmitterGM107::emitDMNMX()
1085 switch (insn
->src(1).getFile()) {
1087 emitInsn(0x5c500000);
1088 emitGPR (0x14, insn
->src(1));
1090 case FILE_MEMORY_CONST
:
1091 emitInsn(0x4c500000);
1092 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1094 case FILE_IMMEDIATE
:
1095 emitInsn(0x38500000);
1096 emitIMMD(0x14, 19, insn
->src(1));
1099 assert(!"bad src1 file");
1103 emitABS (0x31, insn
->src(1));
1104 emitNEG (0x30, insn
->src(0));
1106 emitABS (0x2e, insn
->src(0));
1107 emitNEG (0x2d, insn
->src(1));
1108 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1110 emitGPR (0x08, insn
->src(0));
1111 emitGPR (0x00, insn
->def(0));
1115 CodeEmitterGM107::emitDSET()
1117 const CmpInstruction
*insn
= this->insn
->asCmp();
1119 switch (insn
->src(1).getFile()) {
1121 emitInsn(0x59000000);
1122 emitGPR (0x14, insn
->src(1));
1124 case FILE_MEMORY_CONST
:
1125 emitInsn(0x49000000);
1126 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1128 case FILE_IMMEDIATE
:
1129 emitInsn(0x32000000);
1130 emitIMMD(0x14, 19, insn
->src(1));
1133 assert(!"bad src1 file");
1137 if (insn
->op
!= OP_SET
) {
1139 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1140 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1141 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1143 assert(!"invalid set op");
1146 emitPRED(0x27, insn
->src(2));
1151 emitABS (0x36, insn
->src(0));
1152 emitNEG (0x35, insn
->src(1));
1153 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1154 emitCond4(0x30, insn
->setCond
);
1156 emitABS (0x2c, insn
->src(1));
1157 emitNEG (0x2b, insn
->src(0));
1158 emitGPR (0x08, insn
->src(0));
1159 emitGPR (0x00, insn
->def(0));
1163 CodeEmitterGM107::emitDSETP()
1165 const CmpInstruction
*insn
= this->insn
->asCmp();
1167 switch (insn
->src(1).getFile()) {
1169 emitInsn(0x5b800000);
1170 emitGPR (0x14, insn
->src(1));
1172 case FILE_MEMORY_CONST
:
1173 emitInsn(0x4b800000);
1174 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1176 case FILE_IMMEDIATE
:
1177 emitInsn(0x36800000);
1178 emitIMMD(0x14, 19, insn
->src(1));
1181 assert(!"bad src1 file");
1185 if (insn
->op
!= OP_SET
) {
1187 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1188 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1189 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1191 assert(!"invalid set op");
1194 emitPRED(0x27, insn
->src(2));
1199 emitCond4(0x30, insn
->setCond
);
1200 emitABS (0x2c, insn
->src(1));
1201 emitNEG (0x2b, insn
->src(0));
1202 emitGPR (0x08, insn
->src(0));
1203 emitABS (0x07, insn
->src(0));
1204 emitNEG (0x06, insn
->src(1));
1205 emitPRED (0x03, insn
->def(0));
1206 if (insn
->defExists(1))
1207 emitPRED(0x00, insn
->def(1));
1212 /*******************************************************************************
1214 ******************************************************************************/
1217 CodeEmitterGM107::emitFADD()
1219 if (!longIMMD(insn
->src(1))) {
1220 switch (insn
->src(1).getFile()) {
1222 emitInsn(0x5c580000);
1223 emitGPR (0x14, insn
->src(1));
1225 case FILE_MEMORY_CONST
:
1226 emitInsn(0x4c580000);
1227 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1229 case FILE_IMMEDIATE
:
1230 emitInsn(0x38580000);
1231 emitIMMD(0x14, 19, insn
->src(1));
1234 assert(!"bad src1 file");
1238 emitABS(0x31, insn
->src(1));
1239 emitNEG(0x30, insn
->src(0));
1241 emitABS(0x2e, insn
->src(0));
1242 emitNEG(0x2d, insn
->src(1));
1245 if (insn
->op
== OP_SUB
)
1246 code
[1] ^= 0x00002000;
1248 emitInsn(0x08000000);
1249 emitABS(0x39, insn
->src(1));
1250 emitNEG(0x38, insn
->src(0));
1252 emitABS(0x36, insn
->src(0));
1253 emitNEG(0x35, insn
->src(1));
1255 emitIMMD(0x14, 32, insn
->src(1));
1257 if (insn
->op
== OP_SUB
)
1258 code
[1] ^= 0x00080000;
1261 emitGPR(0x08, insn
->src(0));
1262 emitGPR(0x00, insn
->def(0));
1266 CodeEmitterGM107::emitFMUL()
1268 if (!longIMMD(insn
->src(1))) {
1269 switch (insn
->src(1).getFile()) {
1271 emitInsn(0x5c680000);
1272 emitGPR (0x14, insn
->src(1));
1274 case FILE_MEMORY_CONST
:
1275 emitInsn(0x4c680000);
1276 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1278 case FILE_IMMEDIATE
:
1279 emitInsn(0x38680000);
1280 emitIMMD(0x14, 19, insn
->src(1));
1283 assert(!"bad src1 file");
1287 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1293 emitInsn(0x1e000000);
1297 emitIMMD(0x14, 32, insn
->src(1));
1298 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1299 code
[1] ^= 0x00080000; /* flip immd sign bit */
1302 emitGPR(0x08, insn
->src(0));
1303 emitGPR(0x00, insn
->def(0));
1307 CodeEmitterGM107::emitFFMA()
1309 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1310 switch(insn
->src(2).getFile()) {
1312 switch (insn
->src(1).getFile()) {
1314 emitInsn(0x59800000);
1315 emitGPR (0x14, insn
->src(1));
1317 case FILE_MEMORY_CONST
:
1318 emitInsn(0x49800000);
1319 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1321 case FILE_IMMEDIATE
:
1322 emitInsn(0x32800000);
1323 emitIMMD(0x14, 19, insn
->src(1));
1326 assert(!"bad src1 file");
1329 emitGPR (0x27, insn
->src(2));
1331 case FILE_MEMORY_CONST
:
1332 emitInsn(0x51800000);
1333 emitGPR (0x27, insn
->src(1));
1334 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1337 assert(!"bad src2 file");
1342 emitNEG (0x31, insn
->src(2));
1343 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1347 emitGPR(0x08, insn
->src(0));
1348 emitGPR(0x00, insn
->def(0));
1352 CodeEmitterGM107::emitMUFU()
1357 case OP_COS
: mufu
= 0; break;
1358 case OP_SIN
: mufu
= 1; break;
1359 case OP_EX2
: mufu
= 2; break;
1360 case OP_LG2
: mufu
= 3; break;
1361 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1362 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1364 assert(!"invalid mufu");
1368 emitInsn (0x50800000);
1370 emitNEG (0x30, insn
->src(0));
1371 emitABS (0x2e, insn
->src(0));
1372 emitField(0x14, 3, mufu
);
1373 emitGPR (0x08, insn
->src(0));
1374 emitGPR (0x00, insn
->def(0));
1378 CodeEmitterGM107::emitFMNMX()
1380 switch (insn
->src(1).getFile()) {
1382 emitInsn(0x5c600000);
1383 emitGPR (0x14, insn
->src(1));
1385 case FILE_MEMORY_CONST
:
1386 emitInsn(0x4c600000);
1387 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1389 case FILE_IMMEDIATE
:
1390 emitInsn(0x38600000);
1391 emitIMMD(0x14, 19, insn
->src(1));
1394 assert(!"bad src1 file");
1398 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1401 emitABS(0x31, insn
->src(1));
1402 emitNEG(0x30, insn
->src(0));
1404 emitABS(0x2e, insn
->src(0));
1405 emitNEG(0x2d, insn
->src(1));
1407 emitGPR(0x08, insn
->src(0));
1408 emitGPR(0x00, insn
->def(0));
1412 CodeEmitterGM107::emitRRO()
1414 switch (insn
->src(0).getFile()) {
1416 emitInsn(0x5c900000);
1417 emitGPR (0x14, insn
->src(0));
1419 case FILE_MEMORY_CONST
:
1420 emitInsn(0x4c900000);
1421 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1423 case FILE_IMMEDIATE
:
1424 emitInsn(0x38900000);
1425 emitIMMD(0x14, 19, insn
->src(0));
1428 assert(!"bad src file");
1432 emitABS (0x31, insn
->src(0));
1433 emitNEG (0x2d, insn
->src(0));
1434 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1435 emitGPR (0x00, insn
->def(0));
1439 CodeEmitterGM107::emitFCMP()
1441 const CmpInstruction
*insn
= this->insn
->asCmp();
1442 CondCode cc
= insn
->setCond
;
1444 if (insn
->src(2).mod
.neg())
1445 cc
= reverseCondCode(cc
);
1447 switch(insn
->src(2).getFile()) {
1449 switch (insn
->src(1).getFile()) {
1451 emitInsn(0x5ba00000);
1452 emitGPR (0x14, insn
->src(1));
1454 case FILE_MEMORY_CONST
:
1455 emitInsn(0x4ba00000);
1456 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1458 case FILE_IMMEDIATE
:
1459 emitInsn(0x36a00000);
1460 emitIMMD(0x14, 19, insn
->src(1));
1463 assert(!"bad src1 file");
1466 emitGPR (0x27, insn
->src(2));
1468 case FILE_MEMORY_CONST
:
1469 emitInsn(0x53a00000);
1470 emitGPR (0x27, insn
->src(1));
1471 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1474 assert(!"bad src2 file");
1478 emitCond4(0x30, cc
);
1480 emitGPR (0x08, insn
->src(0));
1481 emitGPR (0x00, insn
->def(0));
1485 CodeEmitterGM107::emitFSET()
1487 const CmpInstruction
*insn
= this->insn
->asCmp();
1489 switch (insn
->src(1).getFile()) {
1491 emitInsn(0x58000000);
1492 emitGPR (0x14, insn
->src(1));
1494 case FILE_MEMORY_CONST
:
1495 emitInsn(0x48000000);
1496 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1498 case FILE_IMMEDIATE
:
1499 emitInsn(0x30000000);
1500 emitIMMD(0x14, 19, insn
->src(1));
1503 assert(!"bad src1 file");
1507 if (insn
->op
!= OP_SET
) {
1509 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1510 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1511 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1513 assert(!"invalid set op");
1516 emitPRED(0x27, insn
->src(2));
1522 emitABS (0x36, insn
->src(0));
1523 emitNEG (0x35, insn
->src(1));
1524 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1525 emitCond4(0x30, insn
->setCond
);
1527 emitABS (0x2c, insn
->src(1));
1528 emitNEG (0x2b, insn
->src(0));
1529 emitGPR (0x08, insn
->src(0));
1530 emitGPR (0x00, insn
->def(0));
1534 CodeEmitterGM107::emitFSETP()
1536 const CmpInstruction
*insn
= this->insn
->asCmp();
1538 switch (insn
->src(1).getFile()) {
1540 emitInsn(0x5bb00000);
1541 emitGPR (0x14, insn
->src(1));
1543 case FILE_MEMORY_CONST
:
1544 emitInsn(0x4bb00000);
1545 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1547 case FILE_IMMEDIATE
:
1548 emitInsn(0x36b00000);
1549 emitIMMD(0x14, 19, insn
->src(1));
1552 assert(!"bad src1 file");
1556 if (insn
->op
!= OP_SET
) {
1558 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1559 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1560 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1562 assert(!"invalid set op");
1565 emitPRED(0x27, insn
->src(2));
1570 emitCond4(0x30, insn
->setCond
);
1572 emitABS (0x2c, insn
->src(1));
1573 emitNEG (0x2b, insn
->src(0));
1574 emitGPR (0x08, insn
->src(0));
1575 emitABS (0x07, insn
->src(0));
1576 emitNEG (0x06, insn
->src(1));
1577 emitPRED (0x03, insn
->def(0));
1578 if (insn
->defExists(1))
1579 emitPRED(0x00, insn
->def(1));
1585 CodeEmitterGM107::emitFSWZADD()
1587 emitInsn (0x50f80000);
1591 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1592 emitField(0x1c, 8, insn
->subOp
);
1593 if (insn
->predSrc
!= 1)
1594 emitGPR (0x14, insn
->src(1));
1597 emitGPR (0x08, insn
->src(0));
1598 emitGPR (0x00, insn
->def(0));
1601 /*******************************************************************************
1603 ******************************************************************************/
1606 CodeEmitterGM107::emitLOP()
1611 case OP_AND
: lop
= 0; break;
1612 case OP_OR
: lop
= 1; break;
1613 case OP_XOR
: lop
= 2; break;
1615 assert(!"invalid lop");
1619 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1620 switch (insn
->src(1).getFile()) {
1622 emitInsn(0x5c400000);
1623 emitGPR (0x14, insn
->src(1));
1625 case FILE_MEMORY_CONST
:
1626 emitInsn(0x4c400000);
1627 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1629 case FILE_IMMEDIATE
:
1630 emitInsn(0x38400000);
1631 emitIMMD(0x14, 19, insn
->src(1));
1634 assert(!"bad src1 file");
1640 emitField(0x29, 2, lop
);
1641 emitINV (0x28, insn
->src(1));
1642 emitINV (0x27, insn
->src(0));
1644 emitInsn (0x04000000);
1646 emitINV (0x38, insn
->src(1));
1647 emitINV (0x37, insn
->src(0));
1648 emitField(0x35, 2, lop
);
1650 emitIMMD (0x14, 32, insn
->src(1));
1653 emitGPR (0x08, insn
->src(0));
1654 emitGPR (0x00, insn
->def(0));
1657 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1659 CodeEmitterGM107::emitNOT()
1661 if (!longIMMD(insn
->src(0))) {
1662 switch (insn
->src(0).getFile()) {
1664 emitInsn(0x5c400700);
1665 emitGPR (0x14, insn
->src(0));
1667 case FILE_MEMORY_CONST
:
1668 emitInsn(0x4c400700);
1669 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1671 case FILE_IMMEDIATE
:
1672 emitInsn(0x38400700);
1673 emitIMMD(0x14, 19, insn
->src(0));
1676 assert(!"bad src1 file");
1681 emitInsn (0x05600000);
1682 emitIMMD (0x14, 32, insn
->src(1));
1686 emitGPR(0x00, insn
->def(0));
1690 CodeEmitterGM107::emitIADD()
1692 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1693 switch (insn
->src(1).getFile()) {
1695 emitInsn(0x5c100000);
1696 emitGPR (0x14, insn
->src(1));
1698 case FILE_MEMORY_CONST
:
1699 emitInsn(0x4c100000);
1700 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1702 case FILE_IMMEDIATE
:
1703 emitInsn(0x38100000);
1704 emitIMMD(0x14, 19, insn
->src(1));
1707 assert(!"bad src1 file");
1711 emitNEG(0x31, insn
->src(0));
1712 emitNEG(0x30, insn
->src(1));
1716 emitInsn(0x1c000000);
1717 emitNEG (0x38, insn
->src(0));
1721 emitIMMD(0x14, 32, insn
->src(1));
1724 if (insn
->op
== OP_SUB
)
1725 code
[1] ^= 0x00010000;
1727 emitGPR(0x08, insn
->src(0));
1728 emitGPR(0x00, insn
->def(0));
1732 CodeEmitterGM107::emitIMUL()
1734 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1735 switch (insn
->src(1).getFile()) {
1737 emitInsn(0x5c380000);
1738 emitGPR (0x14, insn
->src(1));
1740 case FILE_MEMORY_CONST
:
1741 emitInsn(0x4c380000);
1742 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1744 case FILE_IMMEDIATE
:
1745 emitInsn(0x38380000);
1746 emitIMMD(0x14, 19, insn
->src(1));
1749 assert(!"bad src1 file");
1753 emitField(0x29, 1, isSignedType(insn
->sType
));
1754 emitField(0x28, 1, isSignedType(insn
->dType
));
1755 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1757 emitInsn (0x1f000000);
1758 emitField(0x37, 1, isSignedType(insn
->sType
));
1759 emitField(0x36, 1, isSignedType(insn
->dType
));
1760 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1762 emitIMMD (0x14, 32, insn
->src(1));
1765 emitGPR(0x08, insn
->src(0));
1766 emitGPR(0x00, insn
->def(0));
1770 CodeEmitterGM107::emitIMAD()
1772 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1773 switch(insn
->src(2).getFile()) {
1775 switch (insn
->src(1).getFile()) {
1777 emitInsn(0x5a000000);
1778 emitGPR (0x14, insn
->src(1));
1780 case FILE_MEMORY_CONST
:
1781 emitInsn(0x4a000000);
1782 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1784 case FILE_IMMEDIATE
:
1785 emitInsn(0x34000000);
1786 emitIMMD(0x14, 19, insn
->src(1));
1789 assert(!"bad src1 file");
1792 emitGPR (0x27, insn
->src(2));
1794 case FILE_MEMORY_CONST
:
1795 emitInsn(0x52000000);
1796 emitGPR (0x27, insn
->src(1));
1797 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1800 assert(!"bad src2 file");
1804 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1805 emitField(0x35, 1, isSignedType(insn
->sType
));
1806 emitNEG (0x34, insn
->src(2));
1807 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1810 emitField(0x30, 1, isSignedType(insn
->dType
));
1812 emitGPR (0x08, insn
->src(0));
1813 emitGPR (0x00, insn
->def(0));
1817 CodeEmitterGM107::emitISCADD()
1819 switch (insn
->src(2).getFile()) {
1821 emitInsn(0x5c180000);
1822 emitGPR (0x14, insn
->src(2));
1824 case FILE_MEMORY_CONST
:
1825 emitInsn(0x4c180000);
1826 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1828 case FILE_IMMEDIATE
:
1829 emitInsn(0x38180000);
1830 emitIMMD(0x14, 19, insn
->src(2));
1833 assert(!"bad src1 file");
1836 emitNEG (0x31, insn
->src(0));
1837 emitNEG (0x30, insn
->src(2));
1839 emitIMMD(0x27, 5, insn
->src(1));
1840 emitGPR (0x08, insn
->src(0));
1841 emitGPR (0x00, insn
->def(0));
1845 CodeEmitterGM107::emitIMNMX()
1847 switch (insn
->src(1).getFile()) {
1849 emitInsn(0x5c200000);
1850 emitGPR (0x14, insn
->src(1));
1852 case FILE_MEMORY_CONST
:
1853 emitInsn(0x4c200000);
1854 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1856 case FILE_IMMEDIATE
:
1857 emitInsn(0x38200000);
1858 emitIMMD(0x14, 19, insn
->src(1));
1861 assert(!"bad src1 file");
1865 emitField(0x30, 1, isSignedType(insn
->dType
));
1867 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1869 emitGPR (0x08, insn
->src(0));
1870 emitGPR (0x00, insn
->def(0));
1874 CodeEmitterGM107::emitICMP()
1876 const CmpInstruction
*insn
= this->insn
->asCmp();
1877 CondCode cc
= insn
->setCond
;
1879 if (insn
->src(2).mod
.neg())
1880 cc
= reverseCondCode(cc
);
1882 switch(insn
->src(2).getFile()) {
1884 switch (insn
->src(1).getFile()) {
1886 emitInsn(0x5b400000);
1887 emitGPR (0x14, insn
->src(1));
1889 case FILE_MEMORY_CONST
:
1890 emitInsn(0x4b400000);
1891 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1893 case FILE_IMMEDIATE
:
1894 emitInsn(0x36400000);
1895 emitIMMD(0x14, 19, insn
->src(1));
1898 assert(!"bad src1 file");
1901 emitGPR (0x27, insn
->src(2));
1903 case FILE_MEMORY_CONST
:
1904 emitInsn(0x53400000);
1905 emitGPR (0x27, insn
->src(1));
1906 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1909 assert(!"bad src2 file");
1913 emitCond3(0x31, cc
);
1914 emitField(0x30, 1, isSignedType(insn
->sType
));
1915 emitGPR (0x08, insn
->src(0));
1916 emitGPR (0x00, insn
->def(0));
1920 CodeEmitterGM107::emitISET()
1922 const CmpInstruction
*insn
= this->insn
->asCmp();
1924 switch (insn
->src(1).getFile()) {
1926 emitInsn(0x5b500000);
1927 emitGPR (0x14, insn
->src(1));
1929 case FILE_MEMORY_CONST
:
1930 emitInsn(0x4b500000);
1931 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1933 case FILE_IMMEDIATE
:
1934 emitInsn(0x36500000);
1935 emitIMMD(0x14, 19, insn
->src(1));
1938 assert(!"bad src1 file");
1942 if (insn
->op
!= OP_SET
) {
1944 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1945 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1946 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1948 assert(!"invalid set op");
1951 emitPRED(0x27, insn
->src(2));
1956 emitCond3(0x31, insn
->setCond
);
1957 emitField(0x30, 1, isSignedType(insn
->sType
));
1959 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1961 emitGPR (0x08, insn
->src(0));
1962 emitGPR (0x00, insn
->def(0));
1966 CodeEmitterGM107::emitISETP()
1968 const CmpInstruction
*insn
= this->insn
->asCmp();
1970 switch (insn
->src(1).getFile()) {
1972 emitInsn(0x5b600000);
1973 emitGPR (0x14, insn
->src(1));
1975 case FILE_MEMORY_CONST
:
1976 emitInsn(0x4b600000);
1977 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1979 case FILE_IMMEDIATE
:
1980 emitInsn(0x36600000);
1981 emitIMMD(0x14, 19, insn
->src(1));
1984 assert(!"bad src1 file");
1988 if (insn
->op
!= OP_SET
) {
1990 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1991 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1992 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1994 assert(!"invalid set op");
1997 emitPRED(0x27, insn
->src(2));
2002 emitCond3(0x31, insn
->setCond
);
2003 emitField(0x30, 1, isSignedType(insn
->sType
));
2005 emitGPR (0x08, insn
->src(0));
2006 emitPRED (0x03, insn
->def(0));
2007 if (insn
->defExists(1))
2008 emitPRED(0x00, insn
->def(1));
2014 CodeEmitterGM107::emitSHL()
2016 switch (insn
->src(1).getFile()) {
2018 emitInsn(0x5c480000);
2019 emitGPR (0x14, insn
->src(1));
2021 case FILE_MEMORY_CONST
:
2022 emitInsn(0x4c480000);
2023 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2025 case FILE_IMMEDIATE
:
2026 emitInsn(0x38480000);
2027 emitIMMD(0x14, 19, insn
->src(1));
2030 assert(!"bad src1 file");
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::emitSHR()
2044 switch (insn
->src(1).getFile()) {
2046 emitInsn(0x5c280000);
2047 emitGPR (0x14, insn
->src(1));
2049 case FILE_MEMORY_CONST
:
2050 emitInsn(0x4c280000);
2051 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2053 case FILE_IMMEDIATE
:
2054 emitInsn(0x38280000);
2055 emitIMMD(0x14, 19, insn
->src(1));
2058 assert(!"bad src1 file");
2062 emitField(0x30, 1, isSignedType(insn
->dType
));
2065 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2066 emitGPR (0x08, insn
->src(0));
2067 emitGPR (0x00, insn
->def(0));
2071 CodeEmitterGM107::emitPOPC()
2073 switch (insn
->src(0).getFile()) {
2075 emitInsn(0x5c080000);
2076 emitGPR (0x14, insn
->src(0));
2078 case FILE_MEMORY_CONST
:
2079 emitInsn(0x4c080000);
2080 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2082 case FILE_IMMEDIATE
:
2083 emitInsn(0x38080000);
2084 emitIMMD(0x14, 19, insn
->src(0));
2087 assert(!"bad src1 file");
2091 emitINV(0x28, insn
->src(0));
2092 emitGPR(0x00, insn
->def(0));
2096 CodeEmitterGM107::emitBFI()
2098 switch(insn
->src(2).getFile()) {
2100 switch (insn
->src(1).getFile()) {
2102 emitInsn(0x5bf00000);
2103 emitGPR (0x14, insn
->src(1));
2105 case FILE_MEMORY_CONST
:
2106 emitInsn(0x4bf00000);
2107 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2109 case FILE_IMMEDIATE
:
2110 emitInsn(0x36f00000);
2111 emitIMMD(0x14, 19, insn
->src(1));
2114 assert(!"bad src1 file");
2117 emitGPR (0x27, insn
->src(2));
2119 case FILE_MEMORY_CONST
:
2120 emitInsn(0x53f00000);
2121 emitGPR (0x27, insn
->src(1));
2122 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2125 assert(!"bad src2 file");
2130 emitGPR (0x08, insn
->src(0));
2131 emitGPR (0x00, insn
->def(0));
2135 CodeEmitterGM107::emitBFE()
2137 switch (insn
->src(1).getFile()) {
2139 emitInsn(0x5c000000);
2140 emitGPR (0x14, insn
->src(1));
2142 case FILE_MEMORY_CONST
:
2143 emitInsn(0x4c000000);
2144 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2146 case FILE_IMMEDIATE
:
2147 emitInsn(0x38000000);
2148 emitIMMD(0x14, 19, insn
->src(1));
2151 assert(!"bad src1 file");
2155 emitField(0x30, 1, isSignedType(insn
->dType
));
2157 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2158 emitGPR (0x08, insn
->src(0));
2159 emitGPR (0x00, insn
->def(0));
2163 CodeEmitterGM107::emitFLO()
2165 switch (insn
->src(0).getFile()) {
2167 emitInsn(0x5c300000);
2168 emitGPR (0x14, insn
->src(0));
2170 case FILE_MEMORY_CONST
:
2171 emitInsn(0x4c300000);
2172 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2174 case FILE_IMMEDIATE
:
2175 emitInsn(0x38300000);
2176 emitIMMD(0x14, 19, insn
->src(0));
2179 assert(!"bad src1 file");
2183 emitField(0x30, 1, isSignedType(insn
->dType
));
2185 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2186 emitINV (0x28, insn
->src(0));
2187 emitGPR (0x00, insn
->def(0));
2190 /*******************************************************************************
2192 ******************************************************************************/
2195 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2199 switch (typeSizeof(type
)) {
2200 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2201 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2202 case 4: data
= 4; break;
2203 case 8: data
= 5; break;
2204 case 16: data
= 6; break;
2206 assert(!"bad type");
2210 emitField(pos
, 3, data
);
2214 CodeEmitterGM107::emitLDSTc(int pos
)
2218 switch (insn
->cache
) {
2219 case CACHE_CA
: mode
= 0; break;
2220 case CACHE_CG
: mode
= 1; break;
2221 case CACHE_CS
: mode
= 2; break;
2222 case CACHE_CV
: mode
= 3; break;
2224 assert(!"invalid caching mode");
2228 emitField(pos
, 2, mode
);
2232 CodeEmitterGM107::emitLDC()
2234 emitInsn (0xef900000);
2235 emitLDSTs(0x30, insn
->dType
);
2236 emitField(0x2c, 2, insn
->subOp
);
2237 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2238 emitGPR (0x00, insn
->def(0));
2242 CodeEmitterGM107::emitLDL()
2244 emitInsn (0xef400000);
2245 emitLDSTs(0x30, insn
->dType
);
2247 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2248 emitGPR (0x00, insn
->def(0));
2252 CodeEmitterGM107::emitLDS()
2254 emitInsn (0xef480000);
2255 emitLDSTs(0x30, insn
->dType
);
2256 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2257 emitGPR (0x00, insn
->def(0));
2261 CodeEmitterGM107::emitLD()
2263 emitInsn (0x80000000);
2266 emitLDSTs(0x35, insn
->dType
);
2267 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2268 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2269 emitGPR (0x00, insn
->def(0));
2273 CodeEmitterGM107::emitSTL()
2275 emitInsn (0xef500000);
2276 emitLDSTs(0x30, insn
->dType
);
2278 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2279 emitGPR (0x00, insn
->src(1));
2283 CodeEmitterGM107::emitSTS()
2285 emitInsn (0xef580000);
2286 emitLDSTs(0x30, insn
->dType
);
2287 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2288 emitGPR (0x00, insn
->src(1));
2292 CodeEmitterGM107::emitST()
2294 emitInsn (0xa0000000);
2297 emitLDSTs(0x35, insn
->dType
);
2298 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2299 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2300 emitGPR (0x00, insn
->src(1));
2304 CodeEmitterGM107::emitALD()
2306 emitInsn (0xefd80000);
2307 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2308 emitGPR (0x27, insn
->src(0).getIndirect(1));
2311 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2312 emitGPR (0x00, insn
->def(0));
2316 CodeEmitterGM107::emitAST()
2318 emitInsn (0xeff00000);
2319 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2320 emitGPR (0x27, insn
->src(0).getIndirect(1));
2322 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2323 emitGPR (0x00, insn
->src(1));
2327 CodeEmitterGM107::emitISBERD()
2329 emitInsn(0xefd00000);
2330 emitGPR (0x08, insn
->src(0));
2331 emitGPR (0x00, insn
->def(0));
2335 CodeEmitterGM107::emitAL2P()
2337 emitInsn (0xefa00000);
2338 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2341 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2342 emitGPR (0x08, insn
->src(0).getIndirect(0));
2343 emitGPR (0x00, insn
->def(0));
2347 interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2349 int ipa
= entry
->ipa
;
2350 int reg
= entry
->reg
;
2351 int loc
= entry
->loc
;
2353 if (data
.flatshade
&&
2354 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2355 ipa
= NV50_IR_INTERP_FLAT
;
2357 } else if (data
.force_persample_interp
&&
2358 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2359 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2360 ipa
|= NV50_IR_INTERP_CENTROID
;
2362 code
[loc
+ 1] &= ~(0xf << 0x14);
2363 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2364 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2365 code
[loc
+ 0] &= ~(0xff << 0x14);
2366 code
[loc
+ 0] |= reg
<< 0x14;
2370 CodeEmitterGM107::emitIPA()
2372 int ipam
= 0, ipas
= 0;
2374 switch (insn
->getInterpMode()) {
2375 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2376 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2377 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2378 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2380 assert(!"invalid ipa mode");
2384 switch (insn
->getSampleMode()) {
2385 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2386 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2387 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2389 assert(!"invalid ipa sample mode");
2393 emitInsn (0xe0000000);
2394 emitField(0x36, 2, ipam
);
2395 emitField(0x34, 2, ipas
);
2397 emitField(0x2f, 3, 7);
2398 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2399 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2400 code
[1] |= 0x00000040; /* .idx */
2401 emitGPR(0x00, insn
->def(0));
2403 if (insn
->op
== OP_PINTERP
) {
2404 emitGPR(0x14, insn
->src(1));
2405 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2406 emitGPR(0x27, insn
->src(2));
2407 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2409 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2410 emitGPR(0x27, insn
->src(1));
2412 addInterp(insn
->ipa
, 0xff, interpApply
);
2415 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2420 CodeEmitterGM107::emitATOM()
2422 unsigned dType
, subOp
;
2424 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2425 switch (insn
->dType
) {
2426 case TYPE_U32
: dType
= 0; break;
2427 case TYPE_U64
: dType
= 1; break;
2428 default: assert(!"unexpected dType"); dType
= 0; break;
2432 emitInsn (0xee000000);
2434 switch (insn
->dType
) {
2435 case TYPE_U32
: dType
= 0; break;
2436 case TYPE_S32
: dType
= 1; break;
2437 case TYPE_U64
: dType
= 2; break;
2438 case TYPE_F32
: dType
= 3; break;
2439 case TYPE_B128
: dType
= 4; break;
2440 case TYPE_S64
: dType
= 5; break;
2441 default: assert(!"unexpected dType"); dType
= 0; break;
2443 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2446 subOp
= insn
->subOp
;
2448 emitInsn (0xed000000);
2451 emitField(0x34, 4, subOp
);
2452 emitField(0x31, 3, dType
);
2453 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2454 emitGPR (0x14, insn
->src(1));
2455 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2456 emitGPR (0x00, insn
->def(0));
2460 CodeEmitterGM107::emitATOMS()
2462 unsigned dType
, subOp
;
2464 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2465 switch (insn
->dType
) {
2466 case TYPE_U32
: dType
= 0; break;
2467 case TYPE_U64
: dType
= 1; break;
2468 default: assert(!"unexpected dType"); dType
= 0; break;
2472 emitInsn (0xee000000);
2473 emitField(0x34, 1, dType
);
2475 switch (insn
->dType
) {
2476 case TYPE_U32
: dType
= 0; break;
2477 case TYPE_S32
: dType
= 1; break;
2478 case TYPE_U64
: dType
= 2; break;
2479 case TYPE_S64
: dType
= 3; break;
2480 default: assert(!"unexpected dType"); dType
= 0; break;
2483 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2486 subOp
= insn
->subOp
;
2488 emitInsn (0xec000000);
2489 emitField(0x1c, 3, dType
);
2492 emitField(0x34, 4, subOp
);
2493 emitGPR (0x14, insn
->src(1));
2494 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2495 emitGPR (0x00, insn
->def(0));
2499 CodeEmitterGM107::emitCCTL()
2502 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2503 emitInsn(0xef600000);
2506 emitInsn(0xef800000);
2509 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2510 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2511 emitField(0x00, 4, insn
->subOp
);
2514 /*******************************************************************************
2516 ******************************************************************************/
2519 CodeEmitterGM107::emitPIXLD()
2521 emitInsn (0xefe80000);
2523 emitField(0x1f, 3, insn
->subOp
);
2524 emitGPR (0x08, insn
->src(0));
2525 emitGPR (0x00, insn
->def(0));
2528 /*******************************************************************************
2530 ******************************************************************************/
2533 CodeEmitterGM107::emitTEXs(int pos
)
2535 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2536 if (insn
->srcExists(src1
))
2537 emitGPR(pos
, insn
->src(src1
));
2543 CodeEmitterGM107::emitTEX()
2545 const TexInstruction
*insn
= this->insn
->asTex();
2548 if (!insn
->tex
.levelZero
) {
2550 case OP_TEX
: lodm
= 0; break;
2551 case OP_TXB
: lodm
= 2; break;
2552 case OP_TXL
: lodm
= 3; break;
2554 assert(!"invalid tex op");
2561 if (insn
->tex
.rIndirectSrc
>= 0) {
2562 emitInsn (0xdeb80000);
2563 emitField(0x25, 2, lodm
);
2564 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2566 emitInsn (0xc0380000);
2567 emitField(0x37, 2, lodm
);
2568 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2569 emitField(0x24, 13, insn
->tex
.r
);
2572 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2573 emitField(0x31, 1, insn
->tex
.liveOnly
);
2574 emitField(0x23, 1, insn
->tex
.derivAll
);
2575 emitField(0x1f, 4, insn
->tex
.mask
);
2576 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2577 insn
->tex
.target
.getDim() - 1);
2578 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2580 emitGPR (0x08, insn
->src(0));
2581 emitGPR (0x00, insn
->def(0));
2585 CodeEmitterGM107::emitTLD()
2587 const TexInstruction
*insn
= this->insn
->asTex();
2589 if (insn
->tex
.rIndirectSrc
>= 0) {
2590 emitInsn (0xdd380000);
2592 emitInsn (0xdc380000);
2593 emitField(0x24, 13, insn
->tex
.r
);
2596 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2597 emitField(0x32, 1, insn
->tex
.target
.isMS());
2598 emitField(0x31, 1, insn
->tex
.liveOnly
);
2599 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2600 emitField(0x1f, 4, insn
->tex
.mask
);
2601 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2602 insn
->tex
.target
.getDim() - 1);
2603 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2605 emitGPR (0x08, insn
->src(0));
2606 emitGPR (0x00, insn
->def(0));
2610 CodeEmitterGM107::emitTLD4()
2612 const TexInstruction
*insn
= this->insn
->asTex();
2614 if (insn
->tex
.rIndirectSrc
>= 0) {
2615 emitInsn (0xdef80000);
2616 emitField(0x26, 2, insn
->tex
.gatherComp
);
2617 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2618 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2620 emitInsn (0xc8380000);
2621 emitField(0x38, 2, insn
->tex
.gatherComp
);
2622 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2623 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2624 emitField(0x24, 13, insn
->tex
.r
);
2627 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2628 emitField(0x31, 1, insn
->tex
.liveOnly
);
2629 emitField(0x23, 1, insn
->tex
.derivAll
);
2630 emitField(0x1f, 4, insn
->tex
.mask
);
2631 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2632 insn
->tex
.target
.getDim() - 1);
2633 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2635 emitGPR (0x08, insn
->src(0));
2636 emitGPR (0x00, insn
->def(0));
2640 CodeEmitterGM107::emitTXD()
2642 const TexInstruction
*insn
= this->insn
->asTex();
2644 if (insn
->tex
.rIndirectSrc
>= 0) {
2645 emitInsn (0xde780000);
2647 emitInsn (0xde380000);
2648 emitField(0x24, 13, insn
->tex
.r
);
2651 emitField(0x31, 1, insn
->tex
.liveOnly
);
2652 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2653 emitField(0x1f, 4, insn
->tex
.mask
);
2654 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2655 insn
->tex
.target
.getDim() - 1);
2656 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2658 emitGPR (0x08, insn
->src(0));
2659 emitGPR (0x00, insn
->def(0));
2663 CodeEmitterGM107::emitTMML()
2665 const TexInstruction
*insn
= this->insn
->asTex();
2667 if (insn
->tex
.rIndirectSrc
>= 0) {
2668 emitInsn (0xdf600000);
2670 emitInsn (0xdf580000);
2671 emitField(0x24, 13, insn
->tex
.r
);
2674 emitField(0x31, 1, insn
->tex
.liveOnly
);
2675 emitField(0x23, 1, insn
->tex
.derivAll
);
2676 emitField(0x1f, 4, insn
->tex
.mask
);
2677 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2678 insn
->tex
.target
.getDim() - 1);
2679 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2681 emitGPR (0x08, insn
->src(0));
2682 emitGPR (0x00, insn
->def(0));
2686 CodeEmitterGM107::emitTXQ()
2688 const TexInstruction
*insn
= this->insn
->asTex();
2691 switch (insn
->tex
.query
) {
2692 case TXQ_DIMS
: type
= 0x01; break;
2693 case TXQ_TYPE
: type
= 0x02; break;
2694 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2695 case TXQ_FILTER
: type
= 0x10; break;
2696 case TXQ_LOD
: type
= 0x12; break;
2697 case TXQ_WRAP
: type
= 0x14; break;
2698 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2700 assert(!"invalid txq query");
2704 if (insn
->tex
.rIndirectSrc
>= 0) {
2705 emitInsn (0xdf500000);
2707 emitInsn (0xdf480000);
2708 emitField(0x24, 13, insn
->tex
.r
);
2711 emitField(0x31, 1, insn
->tex
.liveOnly
);
2712 emitField(0x1f, 4, insn
->tex
.mask
);
2713 emitField(0x16, 6, type
);
2714 emitGPR (0x08, insn
->src(0));
2715 emitGPR (0x00, insn
->def(0));
2719 CodeEmitterGM107::emitDEPBAR()
2721 emitInsn (0xf0f00000);
2722 emitField(0x1d, 1, 1); /* le */
2723 emitField(0x1a, 3, 5);
2724 emitField(0x14, 6, insn
->subOp
);
2725 emitField(0x00, 6, insn
->subOp
);
2728 /*******************************************************************************
2730 ******************************************************************************/
2733 CodeEmitterGM107::emitNOP()
2735 emitInsn(0x50b00000);
2739 CodeEmitterGM107::emitKIL()
2741 emitInsn (0xe3300000);
2742 emitCond5(0x00, CC_TR
);
2746 CodeEmitterGM107::emitOUT()
2748 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2749 const int emit
= insn
->op
== OP_EMIT
;
2751 switch (insn
->src(1).getFile()) {
2753 emitInsn(0xfbe00000);
2754 emitGPR (0x14, insn
->src(1));
2756 case FILE_IMMEDIATE
:
2757 emitInsn(0xf6e00000);
2758 emitIMMD(0x14, 19, insn
->src(1));
2760 case FILE_MEMORY_CONST
:
2761 emitInsn(0xebe00000);
2762 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2765 assert(!"bad src1 file");
2769 emitField(0x27, 2, (cut
<< 1) | emit
);
2770 emitGPR (0x08, insn
->src(0));
2771 emitGPR (0x00, insn
->def(0));
2775 CodeEmitterGM107::emitBAR()
2779 emitInsn (0xf0a80000);
2781 switch (insn
->subOp
) {
2782 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2783 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2784 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2785 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2788 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2792 emitField(0x20, 8, subop
);
2795 if (insn
->src(0).getFile() == FILE_GPR
) {
2796 emitGPR(0x08, insn
->src(0));
2798 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2800 emitField(0x08, 8, imm
->reg
.data
.u32
);
2801 emitField(0x2b, 1, 1);
2805 if (insn
->src(1).getFile() == FILE_GPR
) {
2806 emitGPR(0x14, insn
->src(1));
2808 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2810 emitField(0x14, 12, imm
->reg
.data
.u32
);
2811 emitField(0x2c, 1, 1);
2814 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2815 emitPRED (0x27, insn
->src(2));
2816 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2818 emitField(0x27, 3, 7);
2823 CodeEmitterGM107::emitMEMBAR()
2825 emitInsn (0xef980000);
2826 emitField(0x08, 2, insn
->subOp
>> 2);
2830 CodeEmitterGM107::emitVOTE()
2832 assert(insn
->src(0).getFile() == FILE_PREDICATE
);
2835 for (int i
= 0; insn
->defExists(i
); i
++) {
2836 if (insn
->def(i
).getFile() == FILE_GPR
)
2838 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
2842 emitInsn (0x50d80000);
2843 emitField(0x30, 2, insn
->subOp
);
2845 emitGPR (0x00, insn
->def(r
));
2849 emitPRED (0x2d, insn
->def(p
));
2852 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2853 emitPRED (0x27, insn
->src(0));
2857 CodeEmitterGM107::emitSUTarget()
2859 const TexInstruction
*insn
= this->insn
->asTex();
2862 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2864 if (insn
->tex
.target
== TEX_TARGET_BUFFER
) {
2866 } else if (insn
->tex
.target
== TEX_TARGET_1D_ARRAY
) {
2868 } else if (insn
->tex
.target
== TEX_TARGET_2D
||
2869 insn
->tex
.target
== TEX_TARGET_RECT
) {
2871 } else if (insn
->tex
.target
== TEX_TARGET_2D_ARRAY
||
2872 insn
->tex
.target
== TEX_TARGET_CUBE
||
2873 insn
->tex
.target
== TEX_TARGET_CUBE_ARRAY
) {
2875 } else if (insn
->tex
.target
== TEX_TARGET_3D
) {
2878 assert(insn
->tex
.target
== TEX_TARGET_1D
);
2880 emitField(0x20, 4, target
);
2884 CodeEmitterGM107::emitSUHandle(const int s
)
2886 const TexInstruction
*insn
= this->insn
->asTex();
2888 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2890 if (insn
->src(s
).getFile() == FILE_GPR
) {
2891 emitGPR(0x27, insn
->src(s
));
2893 ImmediateValue
*imm
= insn
->getSrc(s
)->asImm();
2895 emitField(0x33, 1, 1);
2896 emitField(0x24, 13, imm
->reg
.data
.u32
);
2901 CodeEmitterGM107::emitSUSTx()
2903 const TexInstruction
*insn
= this->insn
->asTex();
2905 emitInsn(0xeb200000);
2906 if (insn
->op
== OP_SUSTB
)
2907 emitField(0x34, 1, 1);
2911 emitField(0x14, 4, 0xf); // rgba
2912 emitGPR (0x08, insn
->src(0));
2913 emitGPR (0x00, insn
->src(1));
2919 CodeEmitterGM107::emitSULDx()
2921 const TexInstruction
*insn
= this->insn
->asTex();
2924 emitInsn(0xeb000000);
2925 if (insn
->op
== OP_SULDB
)
2926 emitField(0x34, 1, 1);
2929 switch (insn
->dType
) {
2930 case TYPE_S8
: type
= 1; break;
2931 case TYPE_U16
: type
= 2; break;
2932 case TYPE_S16
: type
= 3; break;
2933 case TYPE_U32
: type
= 4; break;
2934 case TYPE_U64
: type
= 5; break;
2935 case TYPE_B128
: type
= 6; break;
2937 assert(insn
->dType
== TYPE_U8
);
2941 emitField(0x14, 3, type
);
2942 emitGPR (0x00, insn
->def(0));
2943 emitGPR (0x08, insn
->src(0));
2949 CodeEmitterGM107::emitSUREDx()
2951 const TexInstruction
*insn
= this->insn
->asTex();
2952 uint8_t type
= 0, subOp
;
2954 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
)
2955 emitInsn(0xeac00000);
2957 emitInsn(0xea600000);
2959 if (insn
->op
== OP_SUREDB
)
2960 emitField(0x34, 1, 1);
2964 switch (insn
->dType
) {
2965 case TYPE_S32
: type
= 1; break;
2966 case TYPE_U64
: type
= 2; break;
2967 case TYPE_F32
: type
= 3; break;
2968 case TYPE_S64
: type
= 5; break;
2970 assert(insn
->dType
== TYPE_U32
);
2975 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2977 } else if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
) {
2980 subOp
= insn
->subOp
;
2983 emitField(0x24, 3, type
);
2984 emitField(0x1d, 4, subOp
);
2985 emitGPR (0x14, insn
->src(1));
2986 emitGPR (0x08, insn
->src(0));
2987 emitGPR (0x00, insn
->def(0));
2992 /*******************************************************************************
2993 * assembler front-end
2994 ******************************************************************************/
2997 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2999 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
3004 if (insn
->encSize
!= 8) {
3005 ERROR("skipping undecodable instruction: "); insn
->print();
3008 if (codeSize
+ size
> codeSizeLimit
) {
3009 ERROR("code emitter output buffer too small\n");
3013 if (writeIssueDelays
) {
3014 int n
= ((codeSize
& 0x1f) / 8) - 1;
3017 data
[0] = 0x00000000;
3018 data
[1] = 0x00000000;
3024 emitField(data
, n
* 21, 21, insn
->sched
);
3080 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
3081 insn
->src(0).getFile() == FILE_PREDICATE
)) {
3083 } else if (isFloatType(insn
->dType
)) {
3084 if (isFloatType(insn
->sType
))
3089 if (isFloatType(insn
->sType
))
3100 if (isFloatType(insn
->dType
)) {
3101 if (insn
->dType
== TYPE_F64
)
3110 if (isFloatType(insn
->dType
)) {
3111 if (insn
->dType
== TYPE_F64
)
3121 if (isFloatType(insn
->dType
)) {
3122 if (insn
->dType
== TYPE_F64
)
3135 if (isFloatType(insn
->dType
)) {
3136 if (insn
->dType
== TYPE_F64
)
3163 if (isFloatType(insn
->dType
))
3172 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
3173 if (isFloatType(insn
->sType
))
3174 if (insn
->sType
== TYPE_F64
)
3181 if (isFloatType(insn
->sType
))
3182 if (insn
->sType
== TYPE_F64
)
3214 switch (insn
->src(0).getFile()) {
3215 case FILE_MEMORY_CONST
: emitLDC(); break;
3216 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3217 case FILE_MEMORY_SHARED
: emitLDS(); break;
3218 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3220 assert(!"invalid load");
3226 switch (insn
->src(0).getFile()) {
3227 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3228 case FILE_MEMORY_SHARED
: emitSTS(); break;
3229 case FILE_MEMORY_GLOBAL
: emitST(); break;
3231 assert(!"invalid store");
3237 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3322 assert(!"invalid opcode");
3338 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3343 /*******************************************************************************
3344 * sched data calculator
3345 ******************************************************************************/
3347 class SchedDataCalculatorGM107
: public Pass
3350 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3353 bool visit(BasicBlock
*bb
);
3357 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3359 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3361 insn
->sched
= 0x7e0;
3367 /*******************************************************************************
3369 ******************************************************************************/
3372 CodeEmitterGM107::prepareEmission(Function
*func
)
3374 SchedDataCalculatorGM107
sched(targ
);
3375 CodeEmitter::prepareEmission(func
);
3376 sched
.run(func
, true, true);
3379 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3381 return (size
+ 23) / 24;
3385 CodeEmitterGM107::prepareEmission(Program
*prog
)
3387 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3388 !fi
.end(); fi
.next()) {
3389 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3390 func
->binPos
= prog
->binSize
;
3391 prepareEmission(func
);
3393 // adjust sizes & positions for schedulding info:
3394 if (prog
->getTarget()->hasSWSched
) {
3395 uint32_t adjPos
= func
->binPos
;
3396 BasicBlock
*bb
= NULL
;
3397 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3398 bb
= func
->bbArray
[i
];
3399 int32_t adjSize
= bb
->binSize
;
3401 adjSize
-= 32 - adjPos
% 32;
3405 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3406 bb
->binPos
= adjPos
;
3407 bb
->binSize
= adjSize
;
3411 func
->binSize
= adjPos
- func
->binPos
;
3414 prog
->binSize
+= func
->binSize
;
3418 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3419 : CodeEmitter(target
),
3421 writeIssueDelays(target
->hasSWSched
)
3424 codeSize
= codeSizeLimit
= 0;
3429 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3431 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3432 emit
->setProgramType(type
);
3436 } // namespace nv50_ir