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
&);
165 void emitLDSTs(int, DataType
);
204 /*******************************************************************************
205 * general instruction layout/fields
206 ******************************************************************************/
209 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
212 uint32_t m
= ((1ULL << s
) - 1);
213 uint64_t d
= (uint64_t)(v
& m
) << b
;
214 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
221 CodeEmitterGM107::emitPred()
223 if (insn
->predSrc
>= 0) {
224 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
225 emitField(19, 1, insn
->cc
== CC_NOT_P
);
232 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
234 code
[0] = 0x00000000;
241 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
243 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
247 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
249 int id
= val
? val
->reg
.data
.id
: -1;
252 case SV_LANEID
: id
= 0x00; break;
253 case SV_VERTEX_COUNT
: id
= 0x10; break;
254 case SV_INVOCATION_ID
: id
= 0x11; break;
255 case SV_THREAD_KILL
: id
= 0x13; break;
256 case SV_INVOCATION_INFO
: id
= 0x1d; break;
257 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
258 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
260 assert(!"invalid system value");
265 emitField(pos
, 8, id
);
269 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
271 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
275 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
278 const Value
*v
= ref
.get();
279 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
281 emitGPR(gpr
, ref
.getIndirect(0));
282 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
286 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
289 const Value
*v
= ref
.get();
290 const Symbol
*s
= v
->asSym();
292 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
294 emitField(buf
, 5, v
->reg
.fileIndex
);
296 emitGPR(gpr
, ref
.getIndirect(0));
297 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
301 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
303 if (ref
.getFile() == FILE_IMMEDIATE
) {
304 const ImmediateValue
*imm
= ref
.get()->asImm();
305 if (isFloatType(insn
->sType
)) {
306 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
309 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
310 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
318 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
320 const ImmediateValue
*imm
= ref
.get()->asImm();
321 uint32_t val
= imm
->reg
.data
.u32
;
324 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
325 assert(!(val
& 0x00000fff));
327 } else if (insn
->sType
== TYPE_F64
) {
328 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
329 val
= imm
->reg
.data
.u64
>> 44;
331 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
332 emitField( 56, 1, (val
& 0x80000) >> 19);
333 emitField(pos
, len
, (val
& 0x7ffff));
335 emitField(pos
, len
, val
);
339 /*******************************************************************************
341 ******************************************************************************/
344 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
349 case CC_FL
: data
= 0x00; break;
351 case CC_LT
: data
= 0x01; break;
353 case CC_EQ
: data
= 0x02; break;
355 case CC_LE
: data
= 0x03; break;
357 case CC_GT
: data
= 0x04; break;
359 case CC_NE
: data
= 0x05; break;
361 case CC_GE
: data
= 0x06; break;
362 case CC_TR
: data
= 0x07; break;
364 assert(!"invalid cond3");
368 emitField(pos
, 3, data
);
372 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
377 case CC_FL
: data
= 0x00; break;
378 case CC_LT
: data
= 0x01; break;
379 case CC_EQ
: data
= 0x02; break;
380 case CC_LE
: data
= 0x03; break;
381 case CC_GT
: data
= 0x04; break;
382 case CC_NE
: data
= 0x05; break;
383 case CC_GE
: data
= 0x06; break;
384 // case CC_NUM: data = 0x07; break;
385 // case CC_NAN: data = 0x08; break;
386 case CC_LTU
: data
= 0x09; break;
387 case CC_EQU
: data
= 0x0a; break;
388 case CC_LEU
: data
= 0x0b; break;
389 case CC_GTU
: data
= 0x0c; break;
390 case CC_NEU
: data
= 0x0d; break;
391 case CC_GEU
: data
= 0x0e; break;
392 case CC_TR
: data
= 0x0f; break;
394 assert(!"invalid cond4");
398 emitField(pos
, 4, data
);
402 CodeEmitterGM107::emitO(int pos
)
404 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
408 CodeEmitterGM107::emitP(int pos
)
410 emitField(pos
, 1, insn
->perPatch
);
414 CodeEmitterGM107::emitSAT(int pos
)
416 emitField(pos
, 1, insn
->saturate
);
420 CodeEmitterGM107::emitCC(int pos
)
422 emitField(pos
, 1, insn
->defExists(1));
426 CodeEmitterGM107::emitX(int pos
)
428 emitField(pos
, 1, insn
->flagsSrc
>= 0);
432 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
434 emitField(pos
, 1, ref
.mod
.abs());
438 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
440 emitField(pos
, 1, ref
.mod
.neg());
444 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
446 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
450 CodeEmitterGM107::emitFMZ(int pos
, int len
)
452 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
456 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
460 case ROUND_NI
: ri
= 1;
461 case ROUND_N
: rm
= 0; break;
462 case ROUND_MI
: ri
= 1;
463 case ROUND_M
: rm
= 1; break;
464 case ROUND_PI
: ri
= 1;
465 case ROUND_P
: rm
= 2; break;
466 case ROUND_ZI
: ri
= 1;
467 case ROUND_Z
: rm
= 3; break;
469 assert(!"invalid round mode");
472 emitField(rip
, 1, ri
);
473 emitField(rmp
, 2, rm
);
477 CodeEmitterGM107::emitPDIV(int pos
)
479 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
480 if (insn
->postFactor
> 0)
481 emitField(pos
, 3, 7 - insn
->postFactor
);
483 emitField(pos
, 3, 0 - insn
->postFactor
);
487 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
489 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
492 /*******************************************************************************
494 ******************************************************************************/
497 CodeEmitterGM107::emitEXIT()
499 emitInsn (0xe3000000);
500 emitCond5(0x00, CC_TR
);
504 CodeEmitterGM107::emitBRA()
506 const FlowInstruction
*insn
= this->insn
->asFlow();
509 if (insn
->indirect
) {
511 emitInsn(0xe2000000); // JMX
513 emitInsn(0xe2500000); // BRX
517 emitInsn(0xe2100000); // JMP
519 emitInsn(0xe2400000); // BRA
520 emitField(0x07, 1, insn
->allWarp
);
523 emitField(0x06, 1, insn
->limit
);
524 emitCond5(0x00, CC_TR
);
526 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
527 int32_t pos
= insn
->target
.bb
->binPos
;
528 if (writeIssueDelays
&& !(pos
& 0x1f))
531 emitField(0x14, 24, pos
- (codeSize
+ 8));
533 emitField(0x14, 32, pos
);
535 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
536 emitField(0x05, 1, 1);
541 CodeEmitterGM107::emitCAL()
543 const FlowInstruction
*insn
= this->insn
->asFlow();
545 if (insn
->absolute
) {
546 emitInsn(0xe2200000, 0); // JCAL
548 emitInsn(0xe2600000, 0); // CAL
551 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
553 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
556 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
557 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
558 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
560 emitField(0x14, 32, insn
->target
.bb
->binPos
);
564 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
565 emitField(0x05, 1, 1);
570 CodeEmitterGM107::emitPCNT()
572 const FlowInstruction
*insn
= this->insn
->asFlow();
574 emitInsn(0xe2b00000, 0);
576 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
577 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
579 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
580 emitField(0x05, 1, 1);
585 CodeEmitterGM107::emitCONT()
587 emitInsn (0xe3500000);
588 emitCond5(0x00, CC_TR
);
592 CodeEmitterGM107::emitPBK()
594 const FlowInstruction
*insn
= this->insn
->asFlow();
596 emitInsn(0xe2a00000, 0);
598 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
599 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
601 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
602 emitField(0x05, 1, 1);
607 CodeEmitterGM107::emitBRK()
609 emitInsn (0xe3400000);
610 emitCond5(0x00, CC_TR
);
614 CodeEmitterGM107::emitPRET()
616 const FlowInstruction
*insn
= this->insn
->asFlow();
618 emitInsn(0xe2700000, 0);
620 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
621 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
623 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
624 emitField(0x05, 1, 1);
629 CodeEmitterGM107::emitRET()
631 emitInsn (0xe3200000);
632 emitCond5(0x00, CC_TR
);
636 CodeEmitterGM107::emitSSY()
638 const FlowInstruction
*insn
= this->insn
->asFlow();
640 emitInsn(0xe2900000, 0);
642 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
643 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
645 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
646 emitField(0x05, 1, 1);
651 CodeEmitterGM107::emitSYNC()
653 emitInsn (0xf0f80000);
654 emitCond5(0x00, CC_TR
);
658 CodeEmitterGM107::emitSAM()
660 emitInsn(0xe3700000, 0);
664 CodeEmitterGM107::emitRAM()
666 emitInsn(0xe3800000, 0);
669 /*******************************************************************************
671 ******************************************************************************/
673 /*******************************************************************************
674 * movement / conversion
675 ******************************************************************************/
678 CodeEmitterGM107::emitMOV()
680 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
681 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
682 switch (insn
->src(0).getFile()) {
684 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
685 emitInsn(0x5b6a0000);
688 emitInsn(0x5c980000);
690 emitGPR (0x14, insn
->src(0));
692 case FILE_MEMORY_CONST
:
693 emitInsn(0x4c980000);
694 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
697 emitInsn(0x38980000);
698 emitIMMD(0x14, 19, insn
->src(0));
701 emitInsn(0x50880000);
702 emitPRED(0x0c, insn
->src(0));
707 assert(!"bad src file");
710 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
711 insn
->src(0).getFile() != FILE_PREDICATE
)
712 emitField(0x27, 4, insn
->lanes
);
714 emitInsn (0x01000000);
715 emitIMMD (0x14, 32, insn
->src(0));
716 emitField(0x0c, 4, insn
->lanes
);
719 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
721 emitPRED(0x03, insn
->def(0));
724 emitGPR(0x00, insn
->def(0));
729 CodeEmitterGM107::emitS2R()
731 emitInsn(0xf0c80000);
732 emitSYS (0x14, insn
->src(0));
733 emitGPR (0x00, insn
->def(0));
737 CodeEmitterGM107::emitF2F()
739 RoundMode rnd
= insn
->rnd
;
742 case OP_FLOOR
: rnd
= ROUND_MI
; break;
743 case OP_CEIL
: rnd
= ROUND_PI
; break;
744 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
749 switch (insn
->src(0).getFile()) {
751 emitInsn(0x5ca80000);
752 emitGPR (0x14, insn
->src(0));
754 case FILE_MEMORY_CONST
:
755 emitInsn(0x4ca80000);
756 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
759 emitInsn(0x38a80000);
760 emitIMMD(0x14, 19, insn
->src(0));
763 assert(!"bad src0 file");
767 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
768 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
770 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
772 emitField(0x29, 1, insn
->subOp
);
773 emitRND (0x27, rnd
, 0x2a);
774 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
775 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
776 emitGPR (0x00, insn
->def(0));
780 CodeEmitterGM107::emitF2I()
782 RoundMode rnd
= insn
->rnd
;
785 case OP_FLOOR
: rnd
= ROUND_M
; break;
786 case OP_CEIL
: rnd
= ROUND_P
; break;
787 case OP_TRUNC
: rnd
= ROUND_Z
; break;
792 switch (insn
->src(0).getFile()) {
794 emitInsn(0x5cb00000);
795 emitGPR (0x14, insn
->src(0));
797 case FILE_MEMORY_CONST
:
798 emitInsn(0x4cb00000);
799 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
802 emitInsn(0x38b00000);
803 emitIMMD(0x14, 19, insn
->src(0));
806 assert(!"bad src0 file");
810 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
812 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
814 emitRND (0x27, rnd
, 0x2a);
815 emitField(0x0c, 1, isSignedType(insn
->dType
));
816 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
817 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
818 emitGPR (0x00, insn
->def(0));
822 CodeEmitterGM107::emitI2F()
824 RoundMode rnd
= insn
->rnd
;
827 case OP_FLOOR
: rnd
= ROUND_M
; break;
828 case OP_CEIL
: rnd
= ROUND_P
; break;
829 case OP_TRUNC
: rnd
= ROUND_Z
; break;
834 switch (insn
->src(0).getFile()) {
836 emitInsn(0x5cb80000);
837 emitGPR (0x14, insn
->src(0));
839 case FILE_MEMORY_CONST
:
840 emitInsn(0x4cb80000);
841 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
844 emitInsn(0x38b80000);
845 emitIMMD(0x14, 19, insn
->src(0));
848 assert(!"bad src0 file");
852 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
854 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
855 emitField(0x29, 2, insn
->subOp
);
856 emitRND (0x27, rnd
, -1);
857 emitField(0x0d, 1, isSignedType(insn
->sType
));
858 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
859 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
860 emitGPR (0x00, insn
->def(0));
864 CodeEmitterGM107::emitI2I()
866 switch (insn
->src(0).getFile()) {
868 emitInsn(0x5ce00000);
869 emitGPR (0x14, insn
->src(0));
871 case FILE_MEMORY_CONST
:
872 emitInsn(0x4ce00000);
873 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
876 emitInsn(0x38e00000);
877 emitIMMD(0x14, 19, insn
->src(0));
880 assert(!"bad src0 file");
885 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
887 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
888 emitField(0x29, 2, insn
->subOp
);
889 emitField(0x0d, 1, isSignedType(insn
->sType
));
890 emitField(0x0c, 1, isSignedType(insn
->dType
));
891 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
892 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
893 emitGPR (0x00, insn
->def(0));
897 CodeEmitterGM107::emitSHFL()
901 emitInsn (0xef100000);
903 switch (insn
->src(1).getFile()) {
905 emitGPR(0x14, insn
->src(1));
908 emitIMMD(0x14, 5, insn
->src(1));
912 assert(!"invalid src1 file");
916 /*XXX: what is this arg? hardcode immediate for now */
917 emitField(0x22, 13, 0x1c03);
921 emitField(0x1e, 2, insn
->subOp
);
922 emitField(0x1c, 2, type
);
923 emitGPR (0x08, insn
->src(0));
924 emitGPR (0x00, insn
->def(0));
927 /*******************************************************************************
929 ******************************************************************************/
932 CodeEmitterGM107::emitDADD()
934 switch (insn
->src(1).getFile()) {
936 emitInsn(0x5c700000);
937 emitGPR (0x14, insn
->src(1));
939 case FILE_MEMORY_CONST
:
940 emitInsn(0x4c700000);
941 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
944 emitInsn(0x38700000);
945 emitIMMD(0x14, 19, insn
->src(1));
948 assert(!"bad src1 file");
951 emitABS(0x31, insn
->src(1));
952 emitNEG(0x30, insn
->src(0));
954 emitABS(0x2e, insn
->src(0));
955 emitNEG(0x2d, insn
->src(1));
957 if (insn
->op
== OP_SUB
)
958 code
[1] ^= 0x00002000;
960 emitGPR(0x08, insn
->src(0));
961 emitGPR(0x00, insn
->def(0));
965 CodeEmitterGM107::emitDMUL()
967 switch (insn
->src(1).getFile()) {
969 emitInsn(0x5c800000);
970 emitGPR (0x14, insn
->src(1));
972 case FILE_MEMORY_CONST
:
973 emitInsn(0x4c800000);
974 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
977 emitInsn(0x38800000);
978 emitIMMD(0x14, 19, insn
->src(1));
981 assert(!"bad src1 file");
985 emitNEG2(0x30, insn
->src(0), insn
->src(1));
988 emitGPR (0x08, insn
->src(0));
989 emitGPR (0x00, insn
->def(0));
993 CodeEmitterGM107::emitDFMA()
995 switch(insn
->src(2).getFile()) {
997 switch (insn
->src(1).getFile()) {
999 emitInsn(0x5b700000);
1000 emitGPR (0x14, insn
->src(1));
1002 case FILE_MEMORY_CONST
:
1003 emitInsn(0x4b700000);
1004 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1006 case FILE_IMMEDIATE
:
1007 emitInsn(0x36700000);
1008 emitIMMD(0x14, 19, insn
->src(1));
1011 assert(!"bad src1 file");
1014 emitGPR (0x27, insn
->src(2));
1016 case FILE_MEMORY_CONST
:
1017 emitInsn(0x53700000);
1018 emitGPR (0x27, insn
->src(1));
1019 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1022 assert(!"bad src2 file");
1027 emitNEG (0x31, insn
->src(2));
1028 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1030 emitGPR (0x08, insn
->src(0));
1031 emitGPR (0x00, insn
->def(0));
1035 CodeEmitterGM107::emitDMNMX()
1037 switch (insn
->src(1).getFile()) {
1039 emitInsn(0x5c500000);
1040 emitGPR (0x14, insn
->src(1));
1042 case FILE_MEMORY_CONST
:
1043 emitInsn(0x4c500000);
1044 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1046 case FILE_IMMEDIATE
:
1047 emitInsn(0x38500000);
1048 emitIMMD(0x14, 19, insn
->src(1));
1051 assert(!"bad src1 file");
1055 emitABS (0x31, insn
->src(1));
1056 emitNEG (0x30, insn
->src(0));
1058 emitABS (0x2e, insn
->src(0));
1059 emitNEG (0x2d, insn
->src(1));
1060 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1062 emitGPR (0x08, insn
->src(0));
1063 emitGPR (0x00, insn
->def(0));
1067 CodeEmitterGM107::emitDSET()
1069 const CmpInstruction
*insn
= this->insn
->asCmp();
1071 switch (insn
->src(1).getFile()) {
1073 emitInsn(0x59000000);
1074 emitGPR (0x14, insn
->src(1));
1076 case FILE_MEMORY_CONST
:
1077 emitInsn(0x49000000);
1078 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1080 case FILE_IMMEDIATE
:
1081 emitInsn(0x32000000);
1082 emitIMMD(0x14, 19, insn
->src(1));
1085 assert(!"bad src1 file");
1089 if (insn
->op
!= OP_SET
) {
1091 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1092 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1093 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1095 assert(!"invalid set op");
1098 emitPRED(0x27, insn
->src(2));
1103 emitABS (0x36, insn
->src(0));
1104 emitNEG (0x35, insn
->src(1));
1105 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1106 emitCond4(0x30, insn
->setCond
);
1108 emitABS (0x2c, insn
->src(1));
1109 emitNEG (0x2b, insn
->src(0));
1110 emitGPR (0x08, insn
->src(0));
1111 emitGPR (0x00, insn
->def(0));
1115 CodeEmitterGM107::emitDSETP()
1117 const CmpInstruction
*insn
= this->insn
->asCmp();
1119 switch (insn
->src(1).getFile()) {
1121 emitInsn(0x5b800000);
1122 emitGPR (0x14, insn
->src(1));
1124 case FILE_MEMORY_CONST
:
1125 emitInsn(0x4b800000);
1126 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1128 case FILE_IMMEDIATE
:
1129 emitInsn(0x36800000);
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 emitCond4(0x30, insn
->setCond
);
1152 emitABS (0x2c, insn
->src(1));
1153 emitNEG (0x2b, insn
->src(0));
1154 emitGPR (0x08, insn
->src(0));
1155 emitABS (0x07, insn
->src(0));
1156 emitNEG (0x06, insn
->src(1));
1157 emitPRED (0x03, insn
->def(0));
1158 if (insn
->defExists(1))
1159 emitPRED(0x00, insn
->def(1));
1164 /*******************************************************************************
1166 ******************************************************************************/
1169 CodeEmitterGM107::emitFADD()
1171 if (!longIMMD(insn
->src(1))) {
1172 switch (insn
->src(1).getFile()) {
1174 emitInsn(0x5c580000);
1175 emitGPR (0x14, insn
->src(1));
1177 case FILE_MEMORY_CONST
:
1178 emitInsn(0x4c580000);
1179 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1181 case FILE_IMMEDIATE
:
1182 emitInsn(0x38580000);
1183 emitIMMD(0x14, 19, insn
->src(1));
1186 assert(!"bad src1 file");
1190 emitABS(0x31, insn
->src(1));
1191 emitNEG(0x30, insn
->src(0));
1193 emitABS(0x2e, insn
->src(0));
1194 emitNEG(0x2d, insn
->src(1));
1197 emitInsn(0x08000000);
1198 emitABS(0x39, insn
->src(1));
1199 emitNEG(0x38, insn
->src(0));
1201 emitABS(0x36, insn
->src(0));
1202 emitNEG(0x35, insn
->src(1));
1204 emitIMMD(0x14, 32, insn
->src(1));
1207 if (insn
->op
== OP_SUB
)
1208 code
[1] ^= 0x00002000;
1210 emitGPR(0x08, insn
->src(0));
1211 emitGPR(0x00, insn
->def(0));
1215 CodeEmitterGM107::emitFMUL()
1217 if (!longIMMD(insn
->src(1))) {
1218 switch (insn
->src(1).getFile()) {
1220 emitInsn(0x5c680000);
1221 emitGPR (0x14, insn
->src(1));
1223 case FILE_MEMORY_CONST
:
1224 emitInsn(0x4c680000);
1225 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1227 case FILE_IMMEDIATE
:
1228 emitInsn(0x38680000);
1229 emitIMMD(0x14, 19, insn
->src(1));
1232 assert(!"bad src1 file");
1236 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1242 emitInsn(0x1e000000);
1246 emitIMMD(0x14, 32, insn
->src(1));
1247 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1248 code
[1] ^= 0x00080000; /* flip immd sign bit */
1251 emitGPR(0x08, insn
->src(0));
1252 emitGPR(0x00, insn
->def(0));
1256 CodeEmitterGM107::emitFFMA()
1258 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1259 switch(insn
->src(2).getFile()) {
1261 switch (insn
->src(1).getFile()) {
1263 emitInsn(0x59800000);
1264 emitGPR (0x14, insn
->src(1));
1266 case FILE_MEMORY_CONST
:
1267 emitInsn(0x49800000);
1268 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1270 case FILE_IMMEDIATE
:
1271 emitInsn(0x32800000);
1272 emitIMMD(0x14, 19, insn
->src(1));
1275 assert(!"bad src1 file");
1278 emitGPR (0x27, insn
->src(2));
1280 case FILE_MEMORY_CONST
:
1281 emitInsn(0x51800000);
1282 emitGPR (0x27, insn
->src(1));
1283 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1286 assert(!"bad src2 file");
1291 emitNEG (0x31, insn
->src(2));
1292 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1296 emitGPR(0x08, insn
->src(0));
1297 emitGPR(0x00, insn
->def(0));
1301 CodeEmitterGM107::emitMUFU()
1306 case OP_COS
: mufu
= 0; break;
1307 case OP_SIN
: mufu
= 1; break;
1308 case OP_EX2
: mufu
= 2; break;
1309 case OP_LG2
: mufu
= 3; break;
1310 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1311 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1313 assert(!"invalid mufu");
1317 emitInsn (0x50800000);
1319 emitNEG (0x30, insn
->src(0));
1320 emitABS (0x2e, insn
->src(0));
1321 emitField(0x14, 3, mufu
);
1322 emitGPR (0x08, insn
->src(0));
1323 emitGPR (0x00, insn
->def(0));
1327 CodeEmitterGM107::emitFMNMX()
1329 switch (insn
->src(1).getFile()) {
1331 emitInsn(0x5c600000);
1332 emitGPR (0x14, insn
->src(1));
1334 case FILE_MEMORY_CONST
:
1335 emitInsn(0x4c600000);
1336 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1338 case FILE_IMMEDIATE
:
1339 emitInsn(0x38600000);
1340 emitIMMD(0x14, 19, insn
->src(1));
1343 assert(!"bad src1 file");
1347 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1350 emitABS(0x31, insn
->src(1));
1351 emitNEG(0x30, insn
->src(0));
1353 emitABS(0x2e, insn
->src(0));
1354 emitNEG(0x2d, insn
->src(1));
1356 emitGPR(0x08, insn
->src(0));
1357 emitGPR(0x00, insn
->def(0));
1361 CodeEmitterGM107::emitRRO()
1363 switch (insn
->src(0).getFile()) {
1365 emitInsn(0x5c900000);
1366 emitGPR (0x14, insn
->src(0));
1368 case FILE_MEMORY_CONST
:
1369 emitInsn(0x4c900000);
1370 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1372 case FILE_IMMEDIATE
:
1373 emitInsn(0x38900000);
1374 emitIMMD(0x14, 19, insn
->src(0));
1377 assert(!"bad src file");
1381 emitABS (0x31, insn
->src(0));
1382 emitNEG (0x2d, insn
->src(0));
1383 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1384 emitGPR (0x00, insn
->def(0));
1388 CodeEmitterGM107::emitFCMP()
1390 const CmpInstruction
*insn
= this->insn
->asCmp();
1391 CondCode cc
= insn
->setCond
;
1393 if (insn
->src(2).mod
.neg())
1394 cc
= reverseCondCode(cc
);
1396 switch(insn
->src(2).getFile()) {
1398 switch (insn
->src(1).getFile()) {
1400 emitInsn(0x5ba00000);
1401 emitGPR (0x14, insn
->src(1));
1403 case FILE_MEMORY_CONST
:
1404 emitInsn(0x4ba00000);
1405 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1407 case FILE_IMMEDIATE
:
1408 emitInsn(0x36a00000);
1409 emitIMMD(0x14, 19, insn
->src(1));
1412 assert(!"bad src1 file");
1415 emitGPR (0x27, insn
->src(2));
1417 case FILE_MEMORY_CONST
:
1418 emitInsn(0x53a00000);
1419 emitGPR (0x27, insn
->src(1));
1420 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1423 assert(!"bad src2 file");
1427 emitCond4(0x30, cc
);
1429 emitGPR (0x08, insn
->src(0));
1430 emitGPR (0x00, insn
->def(0));
1434 CodeEmitterGM107::emitFSET()
1436 const CmpInstruction
*insn
= this->insn
->asCmp();
1438 switch (insn
->src(1).getFile()) {
1440 emitInsn(0x58000000);
1441 emitGPR (0x14, insn
->src(1));
1443 case FILE_MEMORY_CONST
:
1444 emitInsn(0x48000000);
1445 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1447 case FILE_IMMEDIATE
:
1448 emitInsn(0x30000000);
1449 emitIMMD(0x14, 19, insn
->src(1));
1452 assert(!"bad src1 file");
1456 if (insn
->op
!= OP_SET
) {
1458 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1459 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1460 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1462 assert(!"invalid set op");
1465 emitPRED(0x27, insn
->src(2));
1471 emitABS (0x36, insn
->src(0));
1472 emitNEG (0x35, insn
->src(1));
1473 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1474 emitCond4(0x30, insn
->setCond
);
1476 emitABS (0x2c, insn
->src(1));
1477 emitNEG (0x2b, insn
->src(0));
1478 emitGPR (0x08, insn
->src(0));
1479 emitGPR (0x00, insn
->def(0));
1483 CodeEmitterGM107::emitFSETP()
1485 const CmpInstruction
*insn
= this->insn
->asCmp();
1487 switch (insn
->src(1).getFile()) {
1489 emitInsn(0x5bb00000);
1490 emitGPR (0x14, insn
->src(1));
1492 case FILE_MEMORY_CONST
:
1493 emitInsn(0x4bb00000);
1494 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1496 case FILE_IMMEDIATE
:
1497 emitInsn(0x36b00000);
1498 emitIMMD(0x14, 19, insn
->src(1));
1501 assert(!"bad src1 file");
1505 if (insn
->op
!= OP_SET
) {
1507 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1508 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1509 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1511 assert(!"invalid set op");
1514 emitPRED(0x27, insn
->src(2));
1519 emitCond4(0x30, insn
->setCond
);
1521 emitABS (0x2c, insn
->src(1));
1522 emitNEG (0x2b, insn
->src(0));
1523 emitGPR (0x08, insn
->src(0));
1524 emitABS (0x07, insn
->src(0));
1525 emitNEG (0x06, insn
->src(1));
1526 emitPRED (0x03, insn
->def(0));
1527 if (insn
->defExists(1))
1528 emitPRED(0x00, insn
->def(1));
1534 CodeEmitterGM107::emitFSWZADD()
1536 emitInsn (0x50f80000);
1540 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1541 emitField(0x1c, 8, insn
->subOp
);
1542 if (insn
->predSrc
!= 1)
1543 emitGPR (0x14, insn
->src(1));
1546 emitGPR (0x08, insn
->src(0));
1547 emitGPR (0x00, insn
->def(0));
1550 /*******************************************************************************
1552 ******************************************************************************/
1555 CodeEmitterGM107::emitLOP()
1560 case OP_AND
: lop
= 0; break;
1561 case OP_OR
: lop
= 1; break;
1562 case OP_XOR
: lop
= 2; break;
1564 assert(!"invalid lop");
1568 if (!longIMMD(insn
->src(1))) {
1569 switch (insn
->src(1).getFile()) {
1571 emitInsn(0x5c400000);
1572 emitGPR (0x14, insn
->src(1));
1574 case FILE_MEMORY_CONST
:
1575 emitInsn(0x4c400000);
1576 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1578 case FILE_IMMEDIATE
:
1579 emitInsn(0x38400000);
1580 emitIMMD(0x14, 19, insn
->src(1));
1583 assert(!"bad src1 file");
1588 emitField(0x29, 2, lop
);
1589 emitINV (0x28, insn
->src(1));
1590 emitINV (0x27, insn
->src(0));
1592 emitInsn (0x04000000);
1594 emitINV (0x38, insn
->src(1));
1595 emitINV (0x37, insn
->src(0));
1596 emitField(0x35, 2, lop
);
1597 emitIMMD (0x14, 32, insn
->src(1));
1600 emitGPR (0x08, insn
->src(0));
1601 emitGPR (0x00, insn
->def(0));
1604 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1606 CodeEmitterGM107::emitNOT()
1608 if (!longIMMD(insn
->src(0))) {
1609 switch (insn
->src(0).getFile()) {
1611 emitInsn(0x5c400700);
1612 emitGPR (0x14, insn
->src(0));
1614 case FILE_MEMORY_CONST
:
1615 emitInsn(0x4c400700);
1616 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1618 case FILE_IMMEDIATE
:
1619 emitInsn(0x38400700);
1620 emitIMMD(0x14, 19, insn
->src(0));
1623 assert(!"bad src1 file");
1628 emitInsn (0x05600000);
1629 emitIMMD (0x14, 32, insn
->src(1));
1633 emitGPR(0x00, insn
->def(0));
1637 CodeEmitterGM107::emitIADD()
1639 if (!longIMMD(insn
->src(1))) {
1640 switch (insn
->src(1).getFile()) {
1642 emitInsn(0x5c100000);
1643 emitGPR (0x14, insn
->src(1));
1645 case FILE_MEMORY_CONST
:
1646 emitInsn(0x4c100000);
1647 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1649 case FILE_IMMEDIATE
:
1650 emitInsn(0x38100000);
1651 emitIMMD(0x14, 19, insn
->src(1));
1654 assert(!"bad src1 file");
1658 emitNEG(0x31, insn
->src(0));
1659 emitNEG(0x30, insn
->src(1));
1663 emitInsn(0x1c000000);
1667 emitIMMD(0x14, 32, insn
->src(1));
1670 if (insn
->op
== OP_SUB
)
1671 code
[1] ^= 0x00010000;
1673 emitGPR(0x08, insn
->src(0));
1674 emitGPR(0x00, insn
->def(0));
1678 CodeEmitterGM107::emitIMUL()
1680 if (!longIMMD(insn
->src(1))) {
1681 switch (insn
->src(1).getFile()) {
1683 emitInsn(0x5c380000);
1684 emitGPR (0x14, insn
->src(1));
1686 case FILE_MEMORY_CONST
:
1687 emitInsn(0x4c380000);
1688 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1690 case FILE_IMMEDIATE
:
1691 emitInsn(0x38380000);
1692 emitIMMD(0x14, 19, insn
->src(1));
1695 assert(!"bad src1 file");
1699 emitField(0x29, 1, isSignedType(insn
->sType
));
1700 emitField(0x28, 1, isSignedType(insn
->dType
));
1701 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1703 emitInsn (0x1f000000);
1704 emitField(0x37, 1, isSignedType(insn
->sType
));
1705 emitField(0x36, 1, isSignedType(insn
->dType
));
1706 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1708 emitIMMD (0x14, 32, insn
->src(1));
1711 emitGPR(0x08, insn
->src(0));
1712 emitGPR(0x00, insn
->def(0));
1716 CodeEmitterGM107::emitIMAD()
1718 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1719 switch(insn
->src(2).getFile()) {
1721 switch (insn
->src(1).getFile()) {
1723 emitInsn(0x5a000000);
1724 emitGPR (0x14, insn
->src(1));
1726 case FILE_MEMORY_CONST
:
1727 emitInsn(0x4a000000);
1728 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1730 case FILE_IMMEDIATE
:
1731 emitInsn(0x34000000);
1732 emitIMMD(0x14, 19, insn
->src(1));
1735 assert(!"bad src1 file");
1738 emitGPR (0x27, insn
->src(2));
1740 case FILE_MEMORY_CONST
:
1741 emitInsn(0x52000000);
1742 emitGPR (0x27, insn
->src(1));
1743 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1746 assert(!"bad src2 file");
1750 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1751 emitField(0x35, 1, isSignedType(insn
->sType
));
1752 emitNEG (0x34, insn
->src(2));
1753 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1756 emitField(0x30, 1, isSignedType(insn
->dType
));
1758 emitGPR (0x08, insn
->src(0));
1759 emitGPR (0x00, insn
->def(0));
1763 CodeEmitterGM107::emitIMNMX()
1765 switch (insn
->src(1).getFile()) {
1767 emitInsn(0x5c200000);
1768 emitGPR (0x14, insn
->src(1));
1770 case FILE_MEMORY_CONST
:
1771 emitInsn(0x4c200000);
1772 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1774 case FILE_IMMEDIATE
:
1775 emitInsn(0x38200000);
1776 emitIMMD(0x14, 19, insn
->src(1));
1779 assert(!"bad src1 file");
1783 emitField(0x30, 1, isSignedType(insn
->dType
));
1785 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1787 emitGPR (0x08, insn
->src(0));
1788 emitGPR (0x00, insn
->def(0));
1792 CodeEmitterGM107::emitICMP()
1794 const CmpInstruction
*insn
= this->insn
->asCmp();
1795 CondCode cc
= insn
->setCond
;
1797 if (insn
->src(2).mod
.neg())
1798 cc
= reverseCondCode(cc
);
1800 switch(insn
->src(2).getFile()) {
1802 switch (insn
->src(1).getFile()) {
1804 emitInsn(0x5b400000);
1805 emitGPR (0x14, insn
->src(1));
1807 case FILE_MEMORY_CONST
:
1808 emitInsn(0x4b400000);
1809 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1811 case FILE_IMMEDIATE
:
1812 emitInsn(0x36400000);
1813 emitIMMD(0x14, 19, insn
->src(1));
1816 assert(!"bad src1 file");
1819 emitGPR (0x27, insn
->src(2));
1821 case FILE_MEMORY_CONST
:
1822 emitInsn(0x53400000);
1823 emitGPR (0x27, insn
->src(1));
1824 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1827 assert(!"bad src2 file");
1831 emitCond3(0x31, cc
);
1832 emitField(0x30, 1, isSignedType(insn
->sType
));
1833 emitGPR (0x08, insn
->src(0));
1834 emitGPR (0x00, insn
->def(0));
1838 CodeEmitterGM107::emitISET()
1840 const CmpInstruction
*insn
= this->insn
->asCmp();
1842 switch (insn
->src(1).getFile()) {
1844 emitInsn(0x5b500000);
1845 emitGPR (0x14, insn
->src(1));
1847 case FILE_MEMORY_CONST
:
1848 emitInsn(0x4b500000);
1849 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1851 case FILE_IMMEDIATE
:
1852 emitInsn(0x36500000);
1853 emitIMMD(0x14, 19, insn
->src(1));
1856 assert(!"bad src1 file");
1860 if (insn
->op
!= OP_SET
) {
1862 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1863 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1864 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1866 assert(!"invalid set op");
1869 emitPRED(0x27, insn
->src(2));
1874 emitCond3(0x31, insn
->setCond
);
1875 emitField(0x30, 1, isSignedType(insn
->sType
));
1877 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1879 emitGPR (0x08, insn
->src(0));
1880 emitGPR (0x00, insn
->def(0));
1884 CodeEmitterGM107::emitISETP()
1886 const CmpInstruction
*insn
= this->insn
->asCmp();
1888 switch (insn
->src(1).getFile()) {
1890 emitInsn(0x5b600000);
1891 emitGPR (0x14, insn
->src(1));
1893 case FILE_MEMORY_CONST
:
1894 emitInsn(0x4b600000);
1895 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1897 case FILE_IMMEDIATE
:
1898 emitInsn(0x36600000);
1899 emitIMMD(0x14, 19, insn
->src(1));
1902 assert(!"bad src1 file");
1906 if (insn
->op
!= OP_SET
) {
1908 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1909 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1910 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1912 assert(!"invalid set op");
1915 emitPRED(0x27, insn
->src(2));
1920 emitCond3(0x31, insn
->setCond
);
1921 emitField(0x30, 1, isSignedType(insn
->sType
));
1923 emitGPR (0x08, insn
->src(0));
1924 emitPRED (0x03, insn
->def(0));
1925 if (insn
->defExists(1))
1926 emitPRED(0x00, insn
->def(1));
1932 CodeEmitterGM107::emitSHL()
1934 switch (insn
->src(1).getFile()) {
1936 emitInsn(0x5c480000);
1937 emitGPR (0x14, insn
->src(1));
1939 case FILE_MEMORY_CONST
:
1940 emitInsn(0x4c480000);
1941 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1943 case FILE_IMMEDIATE
:
1944 emitInsn(0x38480000);
1945 emitIMMD(0x14, 19, insn
->src(1));
1948 assert(!"bad src1 file");
1954 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1955 emitGPR (0x08, insn
->src(0));
1956 emitGPR (0x00, insn
->def(0));
1960 CodeEmitterGM107::emitSHR()
1962 switch (insn
->src(1).getFile()) {
1964 emitInsn(0x5c280000);
1965 emitGPR (0x14, insn
->src(1));
1967 case FILE_MEMORY_CONST
:
1968 emitInsn(0x4c280000);
1969 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1971 case FILE_IMMEDIATE
:
1972 emitInsn(0x38280000);
1973 emitIMMD(0x14, 19, insn
->src(1));
1976 assert(!"bad src1 file");
1980 emitField(0x30, 1, isSignedType(insn
->dType
));
1983 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1984 emitGPR (0x08, insn
->src(0));
1985 emitGPR (0x00, insn
->def(0));
1989 CodeEmitterGM107::emitPOPC()
1991 switch (insn
->src(0).getFile()) {
1993 emitInsn(0x5c080000);
1994 emitGPR (0x14, insn
->src(0));
1996 case FILE_MEMORY_CONST
:
1997 emitInsn(0x4c080000);
1998 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2000 case FILE_IMMEDIATE
:
2001 emitInsn(0x38080000);
2002 emitIMMD(0x14, 19, insn
->src(0));
2005 assert(!"bad src1 file");
2009 emitINV(0x28, insn
->src(0));
2010 emitGPR(0x00, insn
->def(0));
2014 CodeEmitterGM107::emitBFI()
2016 switch(insn
->src(2).getFile()) {
2018 switch (insn
->src(1).getFile()) {
2020 emitInsn(0x5bf00000);
2021 emitGPR (0x14, insn
->src(1));
2023 case FILE_MEMORY_CONST
:
2024 emitInsn(0x4bf00000);
2025 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2027 case FILE_IMMEDIATE
:
2028 emitInsn(0x36f00000);
2029 emitIMMD(0x14, 19, insn
->src(1));
2032 assert(!"bad src1 file");
2035 emitGPR (0x27, insn
->src(2));
2037 case FILE_MEMORY_CONST
:
2038 emitInsn(0x53f00000);
2039 emitGPR (0x27, insn
->src(1));
2040 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2043 assert(!"bad src2 file");
2048 emitGPR (0x08, insn
->src(0));
2049 emitGPR (0x00, insn
->def(0));
2053 CodeEmitterGM107::emitBFE()
2055 switch (insn
->src(1).getFile()) {
2057 emitInsn(0x5c000000);
2058 emitGPR (0x14, insn
->src(1));
2060 case FILE_MEMORY_CONST
:
2061 emitInsn(0x4c000000);
2062 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2064 case FILE_IMMEDIATE
:
2065 emitInsn(0x38000000);
2066 emitIMMD(0x14, 19, insn
->src(1));
2069 assert(!"bad src1 file");
2073 emitField(0x30, 1, isSignedType(insn
->dType
));
2075 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2076 emitGPR (0x08, insn
->src(0));
2077 emitGPR (0x00, insn
->def(0));
2081 CodeEmitterGM107::emitFLO()
2083 switch (insn
->src(0).getFile()) {
2085 emitInsn(0x5c300000);
2086 emitGPR (0x14, insn
->src(0));
2088 case FILE_MEMORY_CONST
:
2089 emitInsn(0x4c300000);
2090 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2092 case FILE_IMMEDIATE
:
2093 emitInsn(0x38300000);
2094 emitIMMD(0x14, 19, insn
->src(0));
2097 assert(!"bad src1 file");
2101 emitField(0x30, 1, isSignedType(insn
->dType
));
2103 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2104 emitINV (0x28, insn
->src(0));
2105 emitGPR (0x00, insn
->def(0));
2108 /*******************************************************************************
2110 ******************************************************************************/
2113 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2117 switch (typeSizeof(type
)) {
2118 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2119 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2120 case 4: data
= 4; break;
2121 case 8: data
= 5; break;
2122 case 16: data
= 6; break;
2124 assert(!"bad type");
2128 emitField(pos
, 3, data
);
2132 CodeEmitterGM107::emitLDSTc(int pos
)
2136 switch (insn
->cache
) {
2137 case CACHE_CA
: mode
= 0; break;
2138 case CACHE_CG
: mode
= 1; break;
2139 case CACHE_CS
: mode
= 2; break;
2140 case CACHE_CV
: mode
= 3; break;
2142 assert(!"invalid caching mode");
2146 emitField(pos
, 2, mode
);
2150 CodeEmitterGM107::emitLDC()
2152 emitInsn (0xef900000);
2153 emitLDSTs(0x30, insn
->dType
);
2154 emitField(0x2c, 2, insn
->subOp
);
2155 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2156 emitGPR (0x00, insn
->def(0));
2160 CodeEmitterGM107::emitLDL()
2162 emitInsn (0xef400000);
2163 emitLDSTs(0x30, insn
->dType
);
2165 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2166 emitGPR (0x00, insn
->def(0));
2170 CodeEmitterGM107::emitLDS()
2172 emitInsn (0xef480000);
2173 emitLDSTs(0x30, insn
->dType
);
2174 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2175 emitGPR (0x00, insn
->def(0));
2179 CodeEmitterGM107::emitLD()
2181 emitInsn (0x80000000);
2184 emitLDSTs(0x35, insn
->dType
);
2185 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2186 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2187 emitGPR (0x00, insn
->def(0));
2191 CodeEmitterGM107::emitSTL()
2193 emitInsn (0xef500000);
2194 emitLDSTs(0x30, insn
->dType
);
2196 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2197 emitGPR (0x00, insn
->src(1));
2201 CodeEmitterGM107::emitSTS()
2203 emitInsn (0xef580000);
2204 emitLDSTs(0x30, insn
->dType
);
2205 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2206 emitGPR (0x00, insn
->src(1));
2210 CodeEmitterGM107::emitST()
2212 emitInsn (0xa0000000);
2215 emitLDSTs(0x35, insn
->dType
);
2216 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2217 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2218 emitGPR (0x00, insn
->src(1));
2222 CodeEmitterGM107::emitALD()
2224 emitInsn (0xefd80000);
2225 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2226 emitGPR (0x27, insn
->src(0).getIndirect(1));
2229 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2230 emitGPR (0x00, insn
->def(0));
2234 CodeEmitterGM107::emitAST()
2236 emitInsn (0xeff00000);
2237 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2238 emitGPR (0x27, insn
->src(0).getIndirect(1));
2240 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2241 emitGPR (0x00, insn
->src(1));
2245 CodeEmitterGM107::emitISBERD()
2247 emitInsn(0xefd00000);
2248 emitGPR (0x08, insn
->src(0));
2249 emitGPR (0x00, insn
->def(0));
2253 CodeEmitterGM107::emitAL2P()
2255 emitInsn (0xefa00000);
2256 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2258 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2259 emitGPR (0x08, insn
->src(0).getIndirect(0));
2260 emitGPR (0x00, insn
->def(0));
2264 interpApply(const InterpEntry
*entry
, uint32_t *code
,
2265 bool force_persample_interp
, bool flatshade
)
2267 int ipa
= entry
->ipa
;
2268 int reg
= entry
->reg
;
2269 int loc
= entry
->loc
;
2272 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2273 ipa
= NV50_IR_INTERP_FLAT
;
2275 } else if (force_persample_interp
&&
2276 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2277 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2278 ipa
|= NV50_IR_INTERP_CENTROID
;
2280 code
[loc
+ 1] &= ~(0xf << 0x14);
2281 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2282 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2283 code
[loc
+ 0] &= ~(0xff << 0x14);
2284 code
[loc
+ 0] |= reg
<< 0x14;
2288 CodeEmitterGM107::emitIPA()
2290 int ipam
= 0, ipas
= 0;
2292 switch (insn
->getInterpMode()) {
2293 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2294 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2295 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2296 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2298 assert(!"invalid ipa mode");
2302 switch (insn
->getSampleMode()) {
2303 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2304 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2305 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2307 assert(!"invalid ipa sample mode");
2311 emitInsn (0xe0000000);
2312 emitField(0x36, 2, ipam
);
2313 emitField(0x34, 2, ipas
);
2315 emitField(0x2f, 3, 7);
2316 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2317 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2318 code
[1] |= 0x00000040; /* .idx */
2319 emitGPR(0x00, insn
->def(0));
2321 if (insn
->op
== OP_PINTERP
) {
2322 emitGPR(0x14, insn
->src(1));
2323 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2324 emitGPR(0x27, insn
->src(2));
2325 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2327 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2328 emitGPR(0x27, insn
->src(1));
2330 addInterp(insn
->ipa
, 0xff, interpApply
);
2333 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2338 CodeEmitterGM107::emitATOM()
2340 unsigned dType
, subOp
;
2342 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2343 switch (insn
->dType
) {
2344 case TYPE_U32
: dType
= 0; break;
2345 case TYPE_U64
: dType
= 1; break;
2346 default: assert(!"unexpected dType"); dType
= 0; break;
2350 emitInsn (0xee000000);
2352 switch (insn
->dType
) {
2353 case TYPE_U32
: dType
= 0; break;
2354 case TYPE_S32
: dType
= 1; break;
2355 case TYPE_U64
: dType
= 2; break;
2356 case TYPE_F32
: dType
= 3; break;
2357 case TYPE_B128
: dType
= 4; break;
2358 case TYPE_S64
: dType
= 5; break;
2359 default: assert(!"unexpected dType"); dType
= 0; break;
2361 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2364 subOp
= insn
->subOp
;
2366 emitInsn (0xed000000);
2369 emitField(0x34, 4, subOp
);
2370 emitField(0x31, 3, dType
);
2371 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2372 emitGPR (0x14, insn
->src(1));
2373 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2374 emitGPR (0x00, insn
->def(0));
2378 CodeEmitterGM107::emitATOMS()
2380 unsigned dType
, subOp
;
2382 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2383 switch (insn
->dType
) {
2384 case TYPE_U32
: dType
= 0; break;
2385 case TYPE_U64
: dType
= 1; break;
2386 default: assert(!"unexpected dType"); dType
= 0; break;
2390 emitInsn (0xee000000);
2391 emitField(0x34, 1, dType
);
2393 switch (insn
->dType
) {
2394 case TYPE_U32
: dType
= 0; break;
2395 case TYPE_S32
: dType
= 1; break;
2396 case TYPE_U64
: dType
= 2; break;
2397 case TYPE_S64
: dType
= 3; break;
2398 default: assert(!"unexpected dType"); dType
= 0; break;
2401 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2404 subOp
= insn
->subOp
;
2406 emitInsn (0xec000000);
2407 emitField(0x1c, 3, dType
);
2410 emitField(0x34, 4, subOp
);
2411 emitGPR (0x14, insn
->src(1));
2412 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2413 emitGPR (0x00, insn
->def(0));
2417 CodeEmitterGM107::emitCCTL()
2420 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2421 emitInsn(0xef600000);
2424 emitInsn(0xef800000);
2427 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2428 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2429 emitField(0x00, 4, insn
->subOp
);
2432 /*******************************************************************************
2434 ******************************************************************************/
2437 CodeEmitterGM107::emitPIXLD()
2439 emitInsn (0xefe80000);
2441 emitField(0x1f, 3, insn
->subOp
);
2442 emitGPR (0x08, insn
->src(0));
2443 emitGPR (0x00, insn
->def(0));
2446 /*******************************************************************************
2448 ******************************************************************************/
2451 CodeEmitterGM107::emitTEXs(int pos
)
2453 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2454 if (insn
->srcExists(src1
))
2455 emitGPR(pos
, insn
->src(src1
));
2461 CodeEmitterGM107::emitTEX()
2463 const TexInstruction
*insn
= this->insn
->asTex();
2466 if (!insn
->tex
.levelZero
) {
2468 case OP_TEX
: lodm
= 0; break;
2469 case OP_TXB
: lodm
= 2; break;
2470 case OP_TXL
: lodm
= 3; break;
2472 assert(!"invalid tex op");
2479 if (insn
->tex
.rIndirectSrc
>= 0) {
2480 emitInsn (0xdeb80000);
2481 emitField(0x35, 2, lodm
);
2482 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2484 emitInsn (0xc0380000);
2485 emitField(0x37, 2, lodm
);
2486 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2487 emitField(0x24, 13, insn
->tex
.r
);
2490 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2491 emitField(0x31, 1, insn
->tex
.liveOnly
);
2492 emitField(0x23, 1, insn
->tex
.derivAll
);
2493 emitField(0x1f, 4, insn
->tex
.mask
);
2494 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2495 insn
->tex
.target
.getDim() - 1);
2496 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2498 emitGPR (0x08, insn
->src(0));
2499 emitGPR (0x00, insn
->def(0));
2503 CodeEmitterGM107::emitTLD()
2505 const TexInstruction
*insn
= this->insn
->asTex();
2507 if (insn
->tex
.rIndirectSrc
>= 0) {
2508 emitInsn (0xdd380000);
2510 emitInsn (0xdc380000);
2511 emitField(0x24, 13, insn
->tex
.r
);
2514 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2515 emitField(0x32, 1, insn
->tex
.target
.isMS());
2516 emitField(0x31, 1, insn
->tex
.liveOnly
);
2517 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2518 emitField(0x1f, 4, insn
->tex
.mask
);
2519 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2520 insn
->tex
.target
.getDim() - 1);
2521 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2523 emitGPR (0x08, insn
->src(0));
2524 emitGPR (0x00, insn
->def(0));
2528 CodeEmitterGM107::emitTLD4()
2530 const TexInstruction
*insn
= this->insn
->asTex();
2532 if (insn
->tex
.rIndirectSrc
>= 0) {
2533 emitInsn (0xdef80000);
2534 emitField(0x26, 2, insn
->tex
.gatherComp
);
2535 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2536 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2538 emitInsn (0xc8380000);
2539 emitField(0x38, 2, insn
->tex
.gatherComp
);
2540 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2541 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2542 emitField(0x24, 13, insn
->tex
.r
);
2545 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2546 emitField(0x31, 1, insn
->tex
.liveOnly
);
2547 emitField(0x23, 1, insn
->tex
.derivAll
);
2548 emitField(0x1f, 4, insn
->tex
.mask
);
2549 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2550 insn
->tex
.target
.getDim() - 1);
2551 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2553 emitGPR (0x08, insn
->src(0));
2554 emitGPR (0x00, insn
->def(0));
2558 CodeEmitterGM107::emitTXD()
2560 const TexInstruction
*insn
= this->insn
->asTex();
2562 if (insn
->tex
.rIndirectSrc
>= 0) {
2563 emitInsn (0xde780000);
2565 emitInsn (0xde380000);
2566 emitField(0x24, 13, insn
->tex
.r
);
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::emitTMML()
2583 const TexInstruction
*insn
= this->insn
->asTex();
2585 if (insn
->tex
.rIndirectSrc
>= 0) {
2586 emitInsn (0xdf600000);
2588 emitInsn (0xdf580000);
2589 emitField(0x24, 13, insn
->tex
.r
);
2592 emitField(0x31, 1, insn
->tex
.liveOnly
);
2593 emitField(0x23, 1, insn
->tex
.derivAll
);
2594 emitField(0x1f, 4, insn
->tex
.mask
);
2595 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2596 insn
->tex
.target
.getDim() - 1);
2597 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2599 emitGPR (0x08, insn
->src(0));
2600 emitGPR (0x00, insn
->def(0));
2604 CodeEmitterGM107::emitTXQ()
2606 const TexInstruction
*insn
= this->insn
->asTex();
2609 switch (insn
->tex
.query
) {
2610 case TXQ_DIMS
: type
= 0x01; break;
2611 case TXQ_TYPE
: type
= 0x02; break;
2612 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2613 case TXQ_FILTER
: type
= 0x10; break;
2614 case TXQ_LOD
: type
= 0x12; break;
2615 case TXQ_WRAP
: type
= 0x14; break;
2616 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2618 assert(!"invalid txq query");
2622 if (insn
->tex
.rIndirectSrc
>= 0) {
2623 emitInsn (0xdf500000);
2625 emitInsn (0xdf480000);
2626 emitField(0x24, 13, insn
->tex
.r
);
2629 emitField(0x31, 1, insn
->tex
.liveOnly
);
2630 emitField(0x1f, 4, insn
->tex
.mask
);
2631 emitField(0x16, 6, type
);
2632 emitGPR (0x08, insn
->src(0));
2633 emitGPR (0x00, insn
->def(0));
2637 CodeEmitterGM107::emitDEPBAR()
2639 emitInsn (0xf0f00000);
2640 emitField(0x1d, 1, 1); /* le */
2641 emitField(0x1a, 3, 5);
2642 emitField(0x14, 6, insn
->subOp
);
2643 emitField(0x00, 6, insn
->subOp
);
2646 /*******************************************************************************
2648 ******************************************************************************/
2651 CodeEmitterGM107::emitNOP()
2653 emitInsn(0x50b00000);
2657 CodeEmitterGM107::emitKIL()
2659 emitInsn (0xe3300000);
2660 emitCond5(0x00, CC_TR
);
2664 CodeEmitterGM107::emitOUT()
2666 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2667 const int emit
= insn
->op
== OP_EMIT
;
2669 switch (insn
->src(1).getFile()) {
2671 emitInsn(0xfbe00000);
2672 emitGPR (0x14, insn
->src(1));
2674 case FILE_IMMEDIATE
:
2675 emitInsn(0xf6e00000);
2676 emitIMMD(0x14, 19, insn
->src(1));
2678 case FILE_MEMORY_CONST
:
2679 emitInsn(0xebe00000);
2680 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2683 assert(!"bad src1 file");
2687 emitField(0x27, 2, (cut
<< 1) | emit
);
2688 emitGPR (0x08, insn
->src(0));
2689 emitGPR (0x00, insn
->def(0));
2693 CodeEmitterGM107::emitBAR()
2697 emitInsn (0xf0a80000);
2699 switch (insn
->subOp
) {
2700 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2701 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2702 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2703 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2706 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2710 emitField(0x20, 8, subop
);
2713 if (insn
->src(0).getFile() == FILE_GPR
) {
2714 emitGPR(0x08, insn
->src(0));
2716 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2718 emitField(0x08, 8, imm
->reg
.data
.u32
);
2719 emitField(0x2b, 1, 1);
2723 if (insn
->src(1).getFile() == FILE_GPR
) {
2724 emitGPR(0x14, insn
->src(1));
2726 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2728 emitField(0x14, 12, imm
->reg
.data
.u32
);
2729 emitField(0x2c, 1, 1);
2732 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2733 emitPRED (0x27, insn
->src(2));
2734 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2736 emitField(0x27, 3, 7);
2741 CodeEmitterGM107::emitMEMBAR()
2743 emitInsn (0xef980000);
2744 emitField(0x08, 2, insn
->subOp
>> 2);
2748 CodeEmitterGM107::emitVOTE()
2752 assert(insn
->src(0).getFile() == FILE_PREDICATE
&&
2753 insn
->def(1).getFile() == FILE_PREDICATE
);
2755 switch (insn
->subOp
) {
2756 case NV50_IR_SUBOP_VOTE_ANY
: subOp
= 1; break;
2758 assert(insn
->subOp
== NV50_IR_SUBOP_VOTE_ALL
);
2763 emitInsn (0x50d80000);
2764 emitField(0x30, 2, subOp
);
2765 emitGPR (0x00, insn
->def(0));
2766 emitPRED (0x2d, insn
->def(1));
2767 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2768 emitPRED (0x27, insn
->src(0));
2771 /*******************************************************************************
2772 * assembler front-end
2773 ******************************************************************************/
2776 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2778 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2783 if (insn
->encSize
!= 8) {
2784 ERROR("skipping undecodable instruction: "); insn
->print();
2787 if (codeSize
+ size
> codeSizeLimit
) {
2788 ERROR("code emitter output buffer too small\n");
2792 if (writeIssueDelays
) {
2793 int n
= ((codeSize
& 0x1f) / 8) - 1;
2796 data
[0] = 0x00000000;
2797 data
[1] = 0x00000000;
2803 emitField(data
, n
* 21, 21, insn
->sched
);
2859 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
2860 insn
->src(0).getFile() == FILE_PREDICATE
)) {
2862 } else if (isFloatType(insn
->dType
)) {
2863 if (isFloatType(insn
->sType
))
2868 if (isFloatType(insn
->sType
))
2879 if (isFloatType(insn
->dType
)) {
2880 if (insn
->dType
== TYPE_F64
)
2889 if (isFloatType(insn
->dType
)) {
2890 if (insn
->dType
== TYPE_F64
)
2900 if (isFloatType(insn
->dType
)) {
2901 if (insn
->dType
== TYPE_F64
)
2911 if (isFloatType(insn
->dType
)) {
2912 if (insn
->dType
== TYPE_F64
)
2939 if (isFloatType(insn
->dType
))
2948 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2949 if (isFloatType(insn
->sType
))
2950 if (insn
->sType
== TYPE_F64
)
2957 if (isFloatType(insn
->sType
))
2958 if (insn
->sType
== TYPE_F64
)
2987 switch (insn
->src(0).getFile()) {
2988 case FILE_MEMORY_CONST
: emitLDC(); break;
2989 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2990 case FILE_MEMORY_SHARED
: emitLDS(); break;
2991 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2993 assert(!"invalid load");
2999 switch (insn
->src(0).getFile()) {
3000 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3001 case FILE_MEMORY_SHARED
: emitSTS(); break;
3002 case FILE_MEMORY_GLOBAL
: emitST(); break;
3004 assert(!"invalid load");
3010 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3083 assert(!"invalid opcode");
3099 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3104 /*******************************************************************************
3105 * sched data calculator
3106 ******************************************************************************/
3108 class SchedDataCalculatorGM107
: public Pass
3111 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3114 bool visit(BasicBlock
*bb
);
3118 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3120 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3122 insn
->sched
= 0x7e0;
3128 /*******************************************************************************
3130 ******************************************************************************/
3133 CodeEmitterGM107::prepareEmission(Function
*func
)
3135 SchedDataCalculatorGM107
sched(targ
);
3136 CodeEmitter::prepareEmission(func
);
3137 sched
.run(func
, true, true);
3140 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3142 return (size
+ 23) / 24;
3146 CodeEmitterGM107::prepareEmission(Program
*prog
)
3148 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3149 !fi
.end(); fi
.next()) {
3150 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3151 func
->binPos
= prog
->binSize
;
3152 prepareEmission(func
);
3154 // adjust sizes & positions for schedulding info:
3155 if (prog
->getTarget()->hasSWSched
) {
3156 uint32_t adjPos
= func
->binPos
;
3157 BasicBlock
*bb
= NULL
;
3158 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3159 bb
= func
->bbArray
[i
];
3160 int32_t adjSize
= bb
->binSize
;
3162 adjSize
-= 32 - adjPos
% 32;
3166 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3167 bb
->binPos
= adjPos
;
3168 bb
->binSize
= adjSize
;
3172 func
->binSize
= adjPos
- func
->binPos
;
3175 prog
->binSize
+= func
->binSize
;
3179 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3180 : CodeEmitter(target
),
3182 writeIssueDelays(target
->hasSWSched
)
3185 codeSize
= codeSizeLimit
= 0;
3190 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3192 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3193 emit
->setProgramType(type
);
3197 } // namespace nv50_ir