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
);
207 void emitSUHandle(const int s
);
213 /*******************************************************************************
214 * general instruction layout/fields
215 ******************************************************************************/
218 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
221 uint32_t m
= ((1ULL << s
) - 1);
222 uint64_t d
= (uint64_t)(v
& m
) << b
;
223 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
230 CodeEmitterGM107::emitPred()
232 if (insn
->predSrc
>= 0) {
233 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
234 emitField(19, 1, insn
->cc
== CC_NOT_P
);
241 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
243 code
[0] = 0x00000000;
250 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
252 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
256 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
258 int id
= val
? val
->reg
.data
.id
: -1;
261 case SV_LANEID
: id
= 0x00; break;
262 case SV_VERTEX_COUNT
: id
= 0x10; break;
263 case SV_INVOCATION_ID
: id
= 0x11; break;
264 case SV_THREAD_KILL
: id
= 0x13; break;
265 case SV_INVOCATION_INFO
: id
= 0x1d; break;
266 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
267 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
269 assert(!"invalid system value");
274 emitField(pos
, 8, id
);
278 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
280 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
284 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
287 const Value
*v
= ref
.get();
288 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
290 emitGPR(gpr
, ref
.getIndirect(0));
291 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
295 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
298 const Value
*v
= ref
.get();
299 const Symbol
*s
= v
->asSym();
301 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
303 emitField(buf
, 5, v
->reg
.fileIndex
);
305 emitGPR(gpr
, ref
.getIndirect(0));
306 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
310 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
312 if (ref
.getFile() == FILE_IMMEDIATE
) {
313 const ImmediateValue
*imm
= ref
.get()->asImm();
314 if (isFloatType(insn
->sType
)) {
315 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
318 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
319 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
327 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
329 const ImmediateValue
*imm
= ref
.get()->asImm();
330 uint32_t val
= imm
->reg
.data
.u32
;
333 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
334 assert(!(val
& 0x00000fff));
336 } else if (insn
->sType
== TYPE_F64
) {
337 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
338 val
= imm
->reg
.data
.u64
>> 44;
340 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
341 emitField( 56, 1, (val
& 0x80000) >> 19);
342 emitField(pos
, len
, (val
& 0x7ffff));
344 emitField(pos
, len
, val
);
348 /*******************************************************************************
350 ******************************************************************************/
353 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
358 case CC_FL
: data
= 0x00; break;
360 case CC_LT
: data
= 0x01; break;
362 case CC_EQ
: data
= 0x02; break;
364 case CC_LE
: data
= 0x03; break;
366 case CC_GT
: data
= 0x04; break;
368 case CC_NE
: data
= 0x05; break;
370 case CC_GE
: data
= 0x06; break;
371 case CC_TR
: data
= 0x07; break;
373 assert(!"invalid cond3");
377 emitField(pos
, 3, data
);
381 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
386 case CC_FL
: data
= 0x00; break;
387 case CC_LT
: data
= 0x01; break;
388 case CC_EQ
: data
= 0x02; break;
389 case CC_LE
: data
= 0x03; break;
390 case CC_GT
: data
= 0x04; break;
391 case CC_NE
: data
= 0x05; break;
392 case CC_GE
: data
= 0x06; break;
393 // case CC_NUM: data = 0x07; break;
394 // case CC_NAN: data = 0x08; break;
395 case CC_LTU
: data
= 0x09; break;
396 case CC_EQU
: data
= 0x0a; break;
397 case CC_LEU
: data
= 0x0b; break;
398 case CC_GTU
: data
= 0x0c; break;
399 case CC_NEU
: data
= 0x0d; break;
400 case CC_GEU
: data
= 0x0e; break;
401 case CC_TR
: data
= 0x0f; break;
403 assert(!"invalid cond4");
407 emitField(pos
, 4, data
);
411 CodeEmitterGM107::emitO(int pos
)
413 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
417 CodeEmitterGM107::emitP(int pos
)
419 emitField(pos
, 1, insn
->perPatch
);
423 CodeEmitterGM107::emitSAT(int pos
)
425 emitField(pos
, 1, insn
->saturate
);
429 CodeEmitterGM107::emitCC(int pos
)
431 emitField(pos
, 1, insn
->flagsDef
>= 0);
435 CodeEmitterGM107::emitX(int pos
)
437 emitField(pos
, 1, insn
->flagsSrc
>= 0);
441 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
443 emitField(pos
, 1, ref
.mod
.abs());
447 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
449 emitField(pos
, 1, ref
.mod
.neg());
453 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
455 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
459 CodeEmitterGM107::emitFMZ(int pos
, int len
)
461 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
465 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
469 case ROUND_NI
: ri
= 1;
470 case ROUND_N
: rm
= 0; break;
471 case ROUND_MI
: ri
= 1;
472 case ROUND_M
: rm
= 1; break;
473 case ROUND_PI
: ri
= 1;
474 case ROUND_P
: rm
= 2; break;
475 case ROUND_ZI
: ri
= 1;
476 case ROUND_Z
: rm
= 3; break;
478 assert(!"invalid round mode");
481 emitField(rip
, 1, ri
);
482 emitField(rmp
, 2, rm
);
486 CodeEmitterGM107::emitPDIV(int pos
)
488 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
489 if (insn
->postFactor
> 0)
490 emitField(pos
, 3, 7 - insn
->postFactor
);
492 emitField(pos
, 3, 0 - insn
->postFactor
);
496 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
498 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
501 /*******************************************************************************
503 ******************************************************************************/
506 CodeEmitterGM107::emitEXIT()
508 emitInsn (0xe3000000);
509 emitCond5(0x00, CC_TR
);
513 CodeEmitterGM107::emitBRA()
515 const FlowInstruction
*insn
= this->insn
->asFlow();
518 if (insn
->indirect
) {
520 emitInsn(0xe2000000); // JMX
522 emitInsn(0xe2500000); // BRX
526 emitInsn(0xe2100000); // JMP
528 emitInsn(0xe2400000); // BRA
529 emitField(0x07, 1, insn
->allWarp
);
532 emitField(0x06, 1, insn
->limit
);
533 emitCond5(0x00, CC_TR
);
535 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
536 int32_t pos
= insn
->target
.bb
->binPos
;
537 if (writeIssueDelays
&& !(pos
& 0x1f))
540 emitField(0x14, 24, pos
- (codeSize
+ 8));
542 emitField(0x14, 32, pos
);
544 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
545 emitField(0x05, 1, 1);
550 CodeEmitterGM107::emitCAL()
552 const FlowInstruction
*insn
= this->insn
->asFlow();
554 if (insn
->absolute
) {
555 emitInsn(0xe2200000, 0); // JCAL
557 emitInsn(0xe2600000, 0); // CAL
560 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
562 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
565 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
566 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
567 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
569 emitField(0x14, 32, insn
->target
.bb
->binPos
);
573 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
574 emitField(0x05, 1, 1);
579 CodeEmitterGM107::emitPCNT()
581 const FlowInstruction
*insn
= this->insn
->asFlow();
583 emitInsn(0xe2b00000, 0);
585 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
586 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
588 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
589 emitField(0x05, 1, 1);
594 CodeEmitterGM107::emitCONT()
596 emitInsn (0xe3500000);
597 emitCond5(0x00, CC_TR
);
601 CodeEmitterGM107::emitPBK()
603 const FlowInstruction
*insn
= this->insn
->asFlow();
605 emitInsn(0xe2a00000, 0);
607 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
608 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
610 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
611 emitField(0x05, 1, 1);
616 CodeEmitterGM107::emitBRK()
618 emitInsn (0xe3400000);
619 emitCond5(0x00, CC_TR
);
623 CodeEmitterGM107::emitPRET()
625 const FlowInstruction
*insn
= this->insn
->asFlow();
627 emitInsn(0xe2700000, 0);
629 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
630 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
632 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
633 emitField(0x05, 1, 1);
638 CodeEmitterGM107::emitRET()
640 emitInsn (0xe3200000);
641 emitCond5(0x00, CC_TR
);
645 CodeEmitterGM107::emitSSY()
647 const FlowInstruction
*insn
= this->insn
->asFlow();
649 emitInsn(0xe2900000, 0);
651 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
652 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
654 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
655 emitField(0x05, 1, 1);
660 CodeEmitterGM107::emitSYNC()
662 emitInsn (0xf0f80000);
663 emitCond5(0x00, CC_TR
);
667 CodeEmitterGM107::emitSAM()
669 emitInsn(0xe3700000, 0);
673 CodeEmitterGM107::emitRAM()
675 emitInsn(0xe3800000, 0);
678 /*******************************************************************************
680 ******************************************************************************/
682 /*******************************************************************************
683 * movement / conversion
684 ******************************************************************************/
687 CodeEmitterGM107::emitMOV()
689 if (insn
->src(0).getFile() != FILE_IMMEDIATE
) {
690 switch (insn
->src(0).getFile()) {
692 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
693 emitInsn(0x5b6a0000);
696 emitInsn(0x5c980000);
698 emitGPR (0x14, insn
->src(0));
700 case FILE_MEMORY_CONST
:
701 emitInsn(0x4c980000);
702 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
705 emitInsn(0x38980000);
706 emitIMMD(0x14, 19, insn
->src(0));
709 emitInsn(0x50880000);
710 emitPRED(0x0c, insn
->src(0));
715 assert(!"bad src file");
718 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
719 insn
->src(0).getFile() != FILE_PREDICATE
)
720 emitField(0x27, 4, insn
->lanes
);
722 emitInsn (0x01000000);
723 emitIMMD (0x14, 32, insn
->src(0));
724 emitField(0x0c, 4, insn
->lanes
);
727 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
729 emitPRED(0x03, insn
->def(0));
732 emitGPR(0x00, insn
->def(0));
737 CodeEmitterGM107::emitS2R()
739 emitInsn(0xf0c80000);
740 emitSYS (0x14, insn
->src(0));
741 emitGPR (0x00, insn
->def(0));
745 CodeEmitterGM107::emitF2F()
747 RoundMode rnd
= insn
->rnd
;
750 case OP_FLOOR
: rnd
= ROUND_MI
; break;
751 case OP_CEIL
: rnd
= ROUND_PI
; break;
752 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
757 switch (insn
->src(0).getFile()) {
759 emitInsn(0x5ca80000);
760 emitGPR (0x14, insn
->src(0));
762 case FILE_MEMORY_CONST
:
763 emitInsn(0x4ca80000);
764 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
767 emitInsn(0x38a80000);
768 emitIMMD(0x14, 19, insn
->src(0));
771 assert(!"bad src0 file");
775 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
776 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
778 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
780 emitField(0x29, 1, insn
->subOp
);
781 emitRND (0x27, rnd
, 0x2a);
782 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
783 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
784 emitGPR (0x00, insn
->def(0));
788 CodeEmitterGM107::emitF2I()
790 RoundMode rnd
= insn
->rnd
;
793 case OP_FLOOR
: rnd
= ROUND_M
; break;
794 case OP_CEIL
: rnd
= ROUND_P
; break;
795 case OP_TRUNC
: rnd
= ROUND_Z
; break;
800 switch (insn
->src(0).getFile()) {
802 emitInsn(0x5cb00000);
803 emitGPR (0x14, insn
->src(0));
805 case FILE_MEMORY_CONST
:
806 emitInsn(0x4cb00000);
807 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
810 emitInsn(0x38b00000);
811 emitIMMD(0x14, 19, insn
->src(0));
814 assert(!"bad src0 file");
818 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
820 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
822 emitRND (0x27, rnd
, 0x2a);
823 emitField(0x0c, 1, isSignedType(insn
->dType
));
824 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
825 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
826 emitGPR (0x00, insn
->def(0));
830 CodeEmitterGM107::emitI2F()
832 RoundMode rnd
= insn
->rnd
;
835 case OP_FLOOR
: rnd
= ROUND_M
; break;
836 case OP_CEIL
: rnd
= ROUND_P
; break;
837 case OP_TRUNC
: rnd
= ROUND_Z
; break;
842 switch (insn
->src(0).getFile()) {
844 emitInsn(0x5cb80000);
845 emitGPR (0x14, insn
->src(0));
847 case FILE_MEMORY_CONST
:
848 emitInsn(0x4cb80000);
849 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
852 emitInsn(0x38b80000);
853 emitIMMD(0x14, 19, insn
->src(0));
856 assert(!"bad src0 file");
860 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
862 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
863 emitField(0x29, 2, insn
->subOp
);
864 emitRND (0x27, rnd
, -1);
865 emitField(0x0d, 1, isSignedType(insn
->sType
));
866 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
867 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
868 emitGPR (0x00, insn
->def(0));
872 CodeEmitterGM107::emitI2I()
874 switch (insn
->src(0).getFile()) {
876 emitInsn(0x5ce00000);
877 emitGPR (0x14, insn
->src(0));
879 case FILE_MEMORY_CONST
:
880 emitInsn(0x4ce00000);
881 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
884 emitInsn(0x38e00000);
885 emitIMMD(0x14, 19, insn
->src(0));
888 assert(!"bad src0 file");
893 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
895 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
896 emitField(0x29, 2, insn
->subOp
);
897 emitField(0x0d, 1, isSignedType(insn
->sType
));
898 emitField(0x0c, 1, isSignedType(insn
->dType
));
899 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
900 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
901 emitGPR (0x00, insn
->def(0));
905 selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
907 int loc
= entry
->loc
;
908 if (data
.force_persample_interp
)
909 code
[loc
+ 1] |= 1 << 10;
911 code
[loc
+ 1] &= ~(1 << 10);
915 CodeEmitterGM107::emitSEL()
917 switch (insn
->src(1).getFile()) {
919 emitInsn(0x5ca00000);
920 emitGPR (0x14, insn
->src(1));
922 case FILE_MEMORY_CONST
:
923 emitInsn(0x4ca00000);
924 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
927 emitInsn(0x38a00000);
928 emitIMMD(0x14, 19, insn
->src(1));
931 assert(!"bad src1 file");
935 emitINV (0x2a, insn
->src(2));
936 emitPRED(0x27, insn
->src(2));
937 emitGPR (0x08, insn
->src(0));
938 emitGPR (0x00, insn
->def(0));
940 if (insn
->subOp
== 1) {
941 addInterp(0, 0, selpFlip
);
946 CodeEmitterGM107::emitSHFL()
950 emitInsn (0xef100000);
952 switch (insn
->src(1).getFile()) {
954 emitGPR(0x14, insn
->src(1));
957 emitIMMD(0x14, 5, insn
->src(1));
961 assert(!"invalid src1 file");
965 /*XXX: what is this arg? hardcode immediate for now */
966 emitField(0x22, 13, 0x1c03);
970 emitField(0x1e, 2, insn
->subOp
);
971 emitField(0x1c, 2, type
);
972 emitGPR (0x08, insn
->src(0));
973 emitGPR (0x00, insn
->def(0));
976 /*******************************************************************************
978 ******************************************************************************/
981 CodeEmitterGM107::emitDADD()
983 switch (insn
->src(1).getFile()) {
985 emitInsn(0x5c700000);
986 emitGPR (0x14, insn
->src(1));
988 case FILE_MEMORY_CONST
:
989 emitInsn(0x4c700000);
990 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
993 emitInsn(0x38700000);
994 emitIMMD(0x14, 19, insn
->src(1));
997 assert(!"bad src1 file");
1000 emitABS(0x31, insn
->src(1));
1001 emitNEG(0x30, insn
->src(0));
1003 emitABS(0x2e, insn
->src(0));
1004 emitNEG(0x2d, insn
->src(1));
1006 if (insn
->op
== OP_SUB
)
1007 code
[1] ^= 0x00002000;
1009 emitGPR(0x08, insn
->src(0));
1010 emitGPR(0x00, insn
->def(0));
1014 CodeEmitterGM107::emitDMUL()
1016 switch (insn
->src(1).getFile()) {
1018 emitInsn(0x5c800000);
1019 emitGPR (0x14, insn
->src(1));
1021 case FILE_MEMORY_CONST
:
1022 emitInsn(0x4c800000);
1023 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1025 case FILE_IMMEDIATE
:
1026 emitInsn(0x38800000);
1027 emitIMMD(0x14, 19, insn
->src(1));
1030 assert(!"bad src1 file");
1034 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1037 emitGPR (0x08, insn
->src(0));
1038 emitGPR (0x00, insn
->def(0));
1042 CodeEmitterGM107::emitDFMA()
1044 switch(insn
->src(2).getFile()) {
1046 switch (insn
->src(1).getFile()) {
1048 emitInsn(0x5b700000);
1049 emitGPR (0x14, insn
->src(1));
1051 case FILE_MEMORY_CONST
:
1052 emitInsn(0x4b700000);
1053 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1055 case FILE_IMMEDIATE
:
1056 emitInsn(0x36700000);
1057 emitIMMD(0x14, 19, insn
->src(1));
1060 assert(!"bad src1 file");
1063 emitGPR (0x27, insn
->src(2));
1065 case FILE_MEMORY_CONST
:
1066 emitInsn(0x53700000);
1067 emitGPR (0x27, insn
->src(1));
1068 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1071 assert(!"bad src2 file");
1076 emitNEG (0x31, insn
->src(2));
1077 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1079 emitGPR (0x08, insn
->src(0));
1080 emitGPR (0x00, insn
->def(0));
1084 CodeEmitterGM107::emitDMNMX()
1086 switch (insn
->src(1).getFile()) {
1088 emitInsn(0x5c500000);
1089 emitGPR (0x14, insn
->src(1));
1091 case FILE_MEMORY_CONST
:
1092 emitInsn(0x4c500000);
1093 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1095 case FILE_IMMEDIATE
:
1096 emitInsn(0x38500000);
1097 emitIMMD(0x14, 19, insn
->src(1));
1100 assert(!"bad src1 file");
1104 emitABS (0x31, insn
->src(1));
1105 emitNEG (0x30, insn
->src(0));
1107 emitABS (0x2e, insn
->src(0));
1108 emitNEG (0x2d, insn
->src(1));
1109 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1111 emitGPR (0x08, insn
->src(0));
1112 emitGPR (0x00, insn
->def(0));
1116 CodeEmitterGM107::emitDSET()
1118 const CmpInstruction
*insn
= this->insn
->asCmp();
1120 switch (insn
->src(1).getFile()) {
1122 emitInsn(0x59000000);
1123 emitGPR (0x14, insn
->src(1));
1125 case FILE_MEMORY_CONST
:
1126 emitInsn(0x49000000);
1127 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1129 case FILE_IMMEDIATE
:
1130 emitInsn(0x32000000);
1131 emitIMMD(0x14, 19, insn
->src(1));
1134 assert(!"bad src1 file");
1138 if (insn
->op
!= OP_SET
) {
1140 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1141 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1142 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1144 assert(!"invalid set op");
1147 emitPRED(0x27, insn
->src(2));
1152 emitABS (0x36, insn
->src(0));
1153 emitNEG (0x35, insn
->src(1));
1154 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1155 emitCond4(0x30, insn
->setCond
);
1157 emitABS (0x2c, insn
->src(1));
1158 emitNEG (0x2b, insn
->src(0));
1159 emitGPR (0x08, insn
->src(0));
1160 emitGPR (0x00, insn
->def(0));
1164 CodeEmitterGM107::emitDSETP()
1166 const CmpInstruction
*insn
= this->insn
->asCmp();
1168 switch (insn
->src(1).getFile()) {
1170 emitInsn(0x5b800000);
1171 emitGPR (0x14, insn
->src(1));
1173 case FILE_MEMORY_CONST
:
1174 emitInsn(0x4b800000);
1175 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1177 case FILE_IMMEDIATE
:
1178 emitInsn(0x36800000);
1179 emitIMMD(0x14, 19, insn
->src(1));
1182 assert(!"bad src1 file");
1186 if (insn
->op
!= OP_SET
) {
1188 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1189 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1190 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1192 assert(!"invalid set op");
1195 emitPRED(0x27, insn
->src(2));
1200 emitCond4(0x30, insn
->setCond
);
1201 emitABS (0x2c, insn
->src(1));
1202 emitNEG (0x2b, insn
->src(0));
1203 emitGPR (0x08, insn
->src(0));
1204 emitABS (0x07, insn
->src(0));
1205 emitNEG (0x06, insn
->src(1));
1206 emitPRED (0x03, insn
->def(0));
1207 if (insn
->defExists(1))
1208 emitPRED(0x00, insn
->def(1));
1213 /*******************************************************************************
1215 ******************************************************************************/
1218 CodeEmitterGM107::emitFADD()
1220 if (!longIMMD(insn
->src(1))) {
1221 switch (insn
->src(1).getFile()) {
1223 emitInsn(0x5c580000);
1224 emitGPR (0x14, insn
->src(1));
1226 case FILE_MEMORY_CONST
:
1227 emitInsn(0x4c580000);
1228 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1230 case FILE_IMMEDIATE
:
1231 emitInsn(0x38580000);
1232 emitIMMD(0x14, 19, insn
->src(1));
1235 assert(!"bad src1 file");
1239 emitABS(0x31, insn
->src(1));
1240 emitNEG(0x30, insn
->src(0));
1242 emitABS(0x2e, insn
->src(0));
1243 emitNEG(0x2d, insn
->src(1));
1246 if (insn
->op
== OP_SUB
)
1247 code
[1] ^= 0x00002000;
1249 emitInsn(0x08000000);
1250 emitABS(0x39, insn
->src(1));
1251 emitNEG(0x38, insn
->src(0));
1253 emitABS(0x36, insn
->src(0));
1254 emitNEG(0x35, insn
->src(1));
1256 emitIMMD(0x14, 32, insn
->src(1));
1258 if (insn
->op
== OP_SUB
)
1259 code
[1] ^= 0x00080000;
1262 emitGPR(0x08, insn
->src(0));
1263 emitGPR(0x00, insn
->def(0));
1267 CodeEmitterGM107::emitFMUL()
1269 if (!longIMMD(insn
->src(1))) {
1270 switch (insn
->src(1).getFile()) {
1272 emitInsn(0x5c680000);
1273 emitGPR (0x14, insn
->src(1));
1275 case FILE_MEMORY_CONST
:
1276 emitInsn(0x4c680000);
1277 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1279 case FILE_IMMEDIATE
:
1280 emitInsn(0x38680000);
1281 emitIMMD(0x14, 19, insn
->src(1));
1284 assert(!"bad src1 file");
1288 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1294 emitInsn(0x1e000000);
1298 emitIMMD(0x14, 32, insn
->src(1));
1299 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1300 code
[1] ^= 0x00080000; /* flip immd sign bit */
1303 emitGPR(0x08, insn
->src(0));
1304 emitGPR(0x00, insn
->def(0));
1308 CodeEmitterGM107::emitFFMA()
1310 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1311 switch(insn
->src(2).getFile()) {
1313 switch (insn
->src(1).getFile()) {
1315 emitInsn(0x59800000);
1316 emitGPR (0x14, insn
->src(1));
1318 case FILE_MEMORY_CONST
:
1319 emitInsn(0x49800000);
1320 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1322 case FILE_IMMEDIATE
:
1323 emitInsn(0x32800000);
1324 emitIMMD(0x14, 19, insn
->src(1));
1327 assert(!"bad src1 file");
1330 emitGPR (0x27, insn
->src(2));
1332 case FILE_MEMORY_CONST
:
1333 emitInsn(0x51800000);
1334 emitGPR (0x27, insn
->src(1));
1335 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1338 assert(!"bad src2 file");
1343 emitNEG (0x31, insn
->src(2));
1344 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1348 emitGPR(0x08, insn
->src(0));
1349 emitGPR(0x00, insn
->def(0));
1353 CodeEmitterGM107::emitMUFU()
1358 case OP_COS
: mufu
= 0; break;
1359 case OP_SIN
: mufu
= 1; break;
1360 case OP_EX2
: mufu
= 2; break;
1361 case OP_LG2
: mufu
= 3; break;
1362 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1363 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1365 assert(!"invalid mufu");
1369 emitInsn (0x50800000);
1371 emitNEG (0x30, insn
->src(0));
1372 emitABS (0x2e, insn
->src(0));
1373 emitField(0x14, 3, mufu
);
1374 emitGPR (0x08, insn
->src(0));
1375 emitGPR (0x00, insn
->def(0));
1379 CodeEmitterGM107::emitFMNMX()
1381 switch (insn
->src(1).getFile()) {
1383 emitInsn(0x5c600000);
1384 emitGPR (0x14, insn
->src(1));
1386 case FILE_MEMORY_CONST
:
1387 emitInsn(0x4c600000);
1388 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1390 case FILE_IMMEDIATE
:
1391 emitInsn(0x38600000);
1392 emitIMMD(0x14, 19, insn
->src(1));
1395 assert(!"bad src1 file");
1399 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1402 emitABS(0x31, insn
->src(1));
1403 emitNEG(0x30, insn
->src(0));
1405 emitABS(0x2e, insn
->src(0));
1406 emitNEG(0x2d, insn
->src(1));
1408 emitGPR(0x08, insn
->src(0));
1409 emitGPR(0x00, insn
->def(0));
1413 CodeEmitterGM107::emitRRO()
1415 switch (insn
->src(0).getFile()) {
1417 emitInsn(0x5c900000);
1418 emitGPR (0x14, insn
->src(0));
1420 case FILE_MEMORY_CONST
:
1421 emitInsn(0x4c900000);
1422 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1424 case FILE_IMMEDIATE
:
1425 emitInsn(0x38900000);
1426 emitIMMD(0x14, 19, insn
->src(0));
1429 assert(!"bad src file");
1433 emitABS (0x31, insn
->src(0));
1434 emitNEG (0x2d, insn
->src(0));
1435 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1436 emitGPR (0x00, insn
->def(0));
1440 CodeEmitterGM107::emitFCMP()
1442 const CmpInstruction
*insn
= this->insn
->asCmp();
1443 CondCode cc
= insn
->setCond
;
1445 if (insn
->src(2).mod
.neg())
1446 cc
= reverseCondCode(cc
);
1448 switch(insn
->src(2).getFile()) {
1450 switch (insn
->src(1).getFile()) {
1452 emitInsn(0x5ba00000);
1453 emitGPR (0x14, insn
->src(1));
1455 case FILE_MEMORY_CONST
:
1456 emitInsn(0x4ba00000);
1457 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1459 case FILE_IMMEDIATE
:
1460 emitInsn(0x36a00000);
1461 emitIMMD(0x14, 19, insn
->src(1));
1464 assert(!"bad src1 file");
1467 emitGPR (0x27, insn
->src(2));
1469 case FILE_MEMORY_CONST
:
1470 emitInsn(0x53a00000);
1471 emitGPR (0x27, insn
->src(1));
1472 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1475 assert(!"bad src2 file");
1479 emitCond4(0x30, cc
);
1481 emitGPR (0x08, insn
->src(0));
1482 emitGPR (0x00, insn
->def(0));
1486 CodeEmitterGM107::emitFSET()
1488 const CmpInstruction
*insn
= this->insn
->asCmp();
1490 switch (insn
->src(1).getFile()) {
1492 emitInsn(0x58000000);
1493 emitGPR (0x14, insn
->src(1));
1495 case FILE_MEMORY_CONST
:
1496 emitInsn(0x48000000);
1497 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1499 case FILE_IMMEDIATE
:
1500 emitInsn(0x30000000);
1501 emitIMMD(0x14, 19, insn
->src(1));
1504 assert(!"bad src1 file");
1508 if (insn
->op
!= OP_SET
) {
1510 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1511 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1512 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1514 assert(!"invalid set op");
1517 emitPRED(0x27, insn
->src(2));
1523 emitABS (0x36, insn
->src(0));
1524 emitNEG (0x35, insn
->src(1));
1525 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1526 emitCond4(0x30, insn
->setCond
);
1528 emitABS (0x2c, insn
->src(1));
1529 emitNEG (0x2b, insn
->src(0));
1530 emitGPR (0x08, insn
->src(0));
1531 emitGPR (0x00, insn
->def(0));
1535 CodeEmitterGM107::emitFSETP()
1537 const CmpInstruction
*insn
= this->insn
->asCmp();
1539 switch (insn
->src(1).getFile()) {
1541 emitInsn(0x5bb00000);
1542 emitGPR (0x14, insn
->src(1));
1544 case FILE_MEMORY_CONST
:
1545 emitInsn(0x4bb00000);
1546 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1548 case FILE_IMMEDIATE
:
1549 emitInsn(0x36b00000);
1550 emitIMMD(0x14, 19, insn
->src(1));
1553 assert(!"bad src1 file");
1557 if (insn
->op
!= OP_SET
) {
1559 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1560 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1561 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1563 assert(!"invalid set op");
1566 emitPRED(0x27, insn
->src(2));
1571 emitCond4(0x30, insn
->setCond
);
1573 emitABS (0x2c, insn
->src(1));
1574 emitNEG (0x2b, insn
->src(0));
1575 emitGPR (0x08, insn
->src(0));
1576 emitABS (0x07, insn
->src(0));
1577 emitNEG (0x06, insn
->src(1));
1578 emitPRED (0x03, insn
->def(0));
1579 if (insn
->defExists(1))
1580 emitPRED(0x00, insn
->def(1));
1586 CodeEmitterGM107::emitFSWZADD()
1588 emitInsn (0x50f80000);
1592 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1593 emitField(0x1c, 8, insn
->subOp
);
1594 if (insn
->predSrc
!= 1)
1595 emitGPR (0x14, insn
->src(1));
1598 emitGPR (0x08, insn
->src(0));
1599 emitGPR (0x00, insn
->def(0));
1602 /*******************************************************************************
1604 ******************************************************************************/
1607 CodeEmitterGM107::emitLOP()
1612 case OP_AND
: lop
= 0; break;
1613 case OP_OR
: lop
= 1; break;
1614 case OP_XOR
: lop
= 2; break;
1616 assert(!"invalid lop");
1620 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1621 switch (insn
->src(1).getFile()) {
1623 emitInsn(0x5c400000);
1624 emitGPR (0x14, insn
->src(1));
1626 case FILE_MEMORY_CONST
:
1627 emitInsn(0x4c400000);
1628 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1630 case FILE_IMMEDIATE
:
1631 emitInsn(0x38400000);
1632 emitIMMD(0x14, 19, insn
->src(1));
1635 assert(!"bad src1 file");
1641 emitField(0x29, 2, lop
);
1642 emitINV (0x28, insn
->src(1));
1643 emitINV (0x27, insn
->src(0));
1645 emitInsn (0x04000000);
1647 emitINV (0x38, insn
->src(1));
1648 emitINV (0x37, insn
->src(0));
1649 emitField(0x35, 2, lop
);
1651 emitIMMD (0x14, 32, insn
->src(1));
1654 emitGPR (0x08, insn
->src(0));
1655 emitGPR (0x00, insn
->def(0));
1658 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1660 CodeEmitterGM107::emitNOT()
1662 if (!longIMMD(insn
->src(0))) {
1663 switch (insn
->src(0).getFile()) {
1665 emitInsn(0x5c400700);
1666 emitGPR (0x14, insn
->src(0));
1668 case FILE_MEMORY_CONST
:
1669 emitInsn(0x4c400700);
1670 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1672 case FILE_IMMEDIATE
:
1673 emitInsn(0x38400700);
1674 emitIMMD(0x14, 19, insn
->src(0));
1677 assert(!"bad src1 file");
1682 emitInsn (0x05600000);
1683 emitIMMD (0x14, 32, insn
->src(1));
1687 emitGPR(0x00, insn
->def(0));
1691 CodeEmitterGM107::emitIADD()
1693 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1694 switch (insn
->src(1).getFile()) {
1696 emitInsn(0x5c100000);
1697 emitGPR (0x14, insn
->src(1));
1699 case FILE_MEMORY_CONST
:
1700 emitInsn(0x4c100000);
1701 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1703 case FILE_IMMEDIATE
:
1704 emitInsn(0x38100000);
1705 emitIMMD(0x14, 19, insn
->src(1));
1708 assert(!"bad src1 file");
1712 emitNEG(0x31, insn
->src(0));
1713 emitNEG(0x30, insn
->src(1));
1717 emitInsn(0x1c000000);
1718 emitNEG (0x38, insn
->src(0));
1722 emitIMMD(0x14, 32, insn
->src(1));
1725 if (insn
->op
== OP_SUB
)
1726 code
[1] ^= 0x00010000;
1728 emitGPR(0x08, insn
->src(0));
1729 emitGPR(0x00, insn
->def(0));
1733 CodeEmitterGM107::emitIMUL()
1735 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1736 switch (insn
->src(1).getFile()) {
1738 emitInsn(0x5c380000);
1739 emitGPR (0x14, insn
->src(1));
1741 case FILE_MEMORY_CONST
:
1742 emitInsn(0x4c380000);
1743 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1745 case FILE_IMMEDIATE
:
1746 emitInsn(0x38380000);
1747 emitIMMD(0x14, 19, insn
->src(1));
1750 assert(!"bad src1 file");
1754 emitField(0x29, 1, isSignedType(insn
->sType
));
1755 emitField(0x28, 1, isSignedType(insn
->dType
));
1756 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1758 emitInsn (0x1f000000);
1759 emitField(0x37, 1, isSignedType(insn
->sType
));
1760 emitField(0x36, 1, isSignedType(insn
->dType
));
1761 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1763 emitIMMD (0x14, 32, insn
->src(1));
1766 emitGPR(0x08, insn
->src(0));
1767 emitGPR(0x00, insn
->def(0));
1771 CodeEmitterGM107::emitIMAD()
1773 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1774 switch(insn
->src(2).getFile()) {
1776 switch (insn
->src(1).getFile()) {
1778 emitInsn(0x5a000000);
1779 emitGPR (0x14, insn
->src(1));
1781 case FILE_MEMORY_CONST
:
1782 emitInsn(0x4a000000);
1783 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1785 case FILE_IMMEDIATE
:
1786 emitInsn(0x34000000);
1787 emitIMMD(0x14, 19, insn
->src(1));
1790 assert(!"bad src1 file");
1793 emitGPR (0x27, insn
->src(2));
1795 case FILE_MEMORY_CONST
:
1796 emitInsn(0x52000000);
1797 emitGPR (0x27, insn
->src(1));
1798 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1801 assert(!"bad src2 file");
1805 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1806 emitField(0x35, 1, isSignedType(insn
->sType
));
1807 emitNEG (0x34, insn
->src(2));
1808 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1811 emitField(0x30, 1, isSignedType(insn
->dType
));
1813 emitGPR (0x08, insn
->src(0));
1814 emitGPR (0x00, insn
->def(0));
1818 CodeEmitterGM107::emitISCADD()
1820 switch (insn
->src(2).getFile()) {
1822 emitInsn(0x5c180000);
1823 emitGPR (0x14, insn
->src(2));
1825 case FILE_MEMORY_CONST
:
1826 emitInsn(0x4c180000);
1827 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1829 case FILE_IMMEDIATE
:
1830 emitInsn(0x38180000);
1831 emitIMMD(0x14, 19, insn
->src(2));
1834 assert(!"bad src1 file");
1837 emitNEG (0x31, insn
->src(0));
1838 emitNEG (0x30, insn
->src(2));
1840 emitIMMD(0x27, 5, insn
->src(1));
1841 emitGPR (0x08, insn
->src(0));
1842 emitGPR (0x00, insn
->def(0));
1846 CodeEmitterGM107::emitIMNMX()
1848 switch (insn
->src(1).getFile()) {
1850 emitInsn(0x5c200000);
1851 emitGPR (0x14, insn
->src(1));
1853 case FILE_MEMORY_CONST
:
1854 emitInsn(0x4c200000);
1855 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1857 case FILE_IMMEDIATE
:
1858 emitInsn(0x38200000);
1859 emitIMMD(0x14, 19, insn
->src(1));
1862 assert(!"bad src1 file");
1866 emitField(0x30, 1, isSignedType(insn
->dType
));
1868 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1870 emitGPR (0x08, insn
->src(0));
1871 emitGPR (0x00, insn
->def(0));
1875 CodeEmitterGM107::emitICMP()
1877 const CmpInstruction
*insn
= this->insn
->asCmp();
1878 CondCode cc
= insn
->setCond
;
1880 if (insn
->src(2).mod
.neg())
1881 cc
= reverseCondCode(cc
);
1883 switch(insn
->src(2).getFile()) {
1885 switch (insn
->src(1).getFile()) {
1887 emitInsn(0x5b400000);
1888 emitGPR (0x14, insn
->src(1));
1890 case FILE_MEMORY_CONST
:
1891 emitInsn(0x4b400000);
1892 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1894 case FILE_IMMEDIATE
:
1895 emitInsn(0x36400000);
1896 emitIMMD(0x14, 19, insn
->src(1));
1899 assert(!"bad src1 file");
1902 emitGPR (0x27, insn
->src(2));
1904 case FILE_MEMORY_CONST
:
1905 emitInsn(0x53400000);
1906 emitGPR (0x27, insn
->src(1));
1907 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1910 assert(!"bad src2 file");
1914 emitCond3(0x31, cc
);
1915 emitField(0x30, 1, isSignedType(insn
->sType
));
1916 emitGPR (0x08, insn
->src(0));
1917 emitGPR (0x00, insn
->def(0));
1921 CodeEmitterGM107::emitISET()
1923 const CmpInstruction
*insn
= this->insn
->asCmp();
1925 switch (insn
->src(1).getFile()) {
1927 emitInsn(0x5b500000);
1928 emitGPR (0x14, insn
->src(1));
1930 case FILE_MEMORY_CONST
:
1931 emitInsn(0x4b500000);
1932 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1934 case FILE_IMMEDIATE
:
1935 emitInsn(0x36500000);
1936 emitIMMD(0x14, 19, insn
->src(1));
1939 assert(!"bad src1 file");
1943 if (insn
->op
!= OP_SET
) {
1945 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1946 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1947 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1949 assert(!"invalid set op");
1952 emitPRED(0x27, insn
->src(2));
1957 emitCond3(0x31, insn
->setCond
);
1958 emitField(0x30, 1, isSignedType(insn
->sType
));
1960 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1962 emitGPR (0x08, insn
->src(0));
1963 emitGPR (0x00, insn
->def(0));
1967 CodeEmitterGM107::emitISETP()
1969 const CmpInstruction
*insn
= this->insn
->asCmp();
1971 switch (insn
->src(1).getFile()) {
1973 emitInsn(0x5b600000);
1974 emitGPR (0x14, insn
->src(1));
1976 case FILE_MEMORY_CONST
:
1977 emitInsn(0x4b600000);
1978 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1980 case FILE_IMMEDIATE
:
1981 emitInsn(0x36600000);
1982 emitIMMD(0x14, 19, insn
->src(1));
1985 assert(!"bad src1 file");
1989 if (insn
->op
!= OP_SET
) {
1991 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1992 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1993 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1995 assert(!"invalid set op");
1998 emitPRED(0x27, insn
->src(2));
2003 emitCond3(0x31, insn
->setCond
);
2004 emitField(0x30, 1, isSignedType(insn
->sType
));
2006 emitGPR (0x08, insn
->src(0));
2007 emitPRED (0x03, insn
->def(0));
2008 if (insn
->defExists(1))
2009 emitPRED(0x00, insn
->def(1));
2015 CodeEmitterGM107::emitSHL()
2017 switch (insn
->src(1).getFile()) {
2019 emitInsn(0x5c480000);
2020 emitGPR (0x14, insn
->src(1));
2022 case FILE_MEMORY_CONST
:
2023 emitInsn(0x4c480000);
2024 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2026 case FILE_IMMEDIATE
:
2027 emitInsn(0x38480000);
2028 emitIMMD(0x14, 19, insn
->src(1));
2031 assert(!"bad src1 file");
2037 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2038 emitGPR (0x08, insn
->src(0));
2039 emitGPR (0x00, insn
->def(0));
2043 CodeEmitterGM107::emitSHR()
2045 switch (insn
->src(1).getFile()) {
2047 emitInsn(0x5c280000);
2048 emitGPR (0x14, insn
->src(1));
2050 case FILE_MEMORY_CONST
:
2051 emitInsn(0x4c280000);
2052 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2054 case FILE_IMMEDIATE
:
2055 emitInsn(0x38280000);
2056 emitIMMD(0x14, 19, insn
->src(1));
2059 assert(!"bad src1 file");
2063 emitField(0x30, 1, isSignedType(insn
->dType
));
2066 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2067 emitGPR (0x08, insn
->src(0));
2068 emitGPR (0x00, insn
->def(0));
2072 CodeEmitterGM107::emitPOPC()
2074 switch (insn
->src(0).getFile()) {
2076 emitInsn(0x5c080000);
2077 emitGPR (0x14, insn
->src(0));
2079 case FILE_MEMORY_CONST
:
2080 emitInsn(0x4c080000);
2081 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2083 case FILE_IMMEDIATE
:
2084 emitInsn(0x38080000);
2085 emitIMMD(0x14, 19, insn
->src(0));
2088 assert(!"bad src1 file");
2092 emitINV(0x28, insn
->src(0));
2093 emitGPR(0x00, insn
->def(0));
2097 CodeEmitterGM107::emitBFI()
2099 switch(insn
->src(2).getFile()) {
2101 switch (insn
->src(1).getFile()) {
2103 emitInsn(0x5bf00000);
2104 emitGPR (0x14, insn
->src(1));
2106 case FILE_MEMORY_CONST
:
2107 emitInsn(0x4bf00000);
2108 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2110 case FILE_IMMEDIATE
:
2111 emitInsn(0x36f00000);
2112 emitIMMD(0x14, 19, insn
->src(1));
2115 assert(!"bad src1 file");
2118 emitGPR (0x27, insn
->src(2));
2120 case FILE_MEMORY_CONST
:
2121 emitInsn(0x53f00000);
2122 emitGPR (0x27, insn
->src(1));
2123 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2126 assert(!"bad src2 file");
2131 emitGPR (0x08, insn
->src(0));
2132 emitGPR (0x00, insn
->def(0));
2136 CodeEmitterGM107::emitBFE()
2138 switch (insn
->src(1).getFile()) {
2140 emitInsn(0x5c000000);
2141 emitGPR (0x14, insn
->src(1));
2143 case FILE_MEMORY_CONST
:
2144 emitInsn(0x4c000000);
2145 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2147 case FILE_IMMEDIATE
:
2148 emitInsn(0x38000000);
2149 emitIMMD(0x14, 19, insn
->src(1));
2152 assert(!"bad src1 file");
2156 emitField(0x30, 1, isSignedType(insn
->dType
));
2158 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2159 emitGPR (0x08, insn
->src(0));
2160 emitGPR (0x00, insn
->def(0));
2164 CodeEmitterGM107::emitFLO()
2166 switch (insn
->src(0).getFile()) {
2168 emitInsn(0x5c300000);
2169 emitGPR (0x14, insn
->src(0));
2171 case FILE_MEMORY_CONST
:
2172 emitInsn(0x4c300000);
2173 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2175 case FILE_IMMEDIATE
:
2176 emitInsn(0x38300000);
2177 emitIMMD(0x14, 19, insn
->src(0));
2180 assert(!"bad src1 file");
2184 emitField(0x30, 1, isSignedType(insn
->dType
));
2186 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2187 emitINV (0x28, insn
->src(0));
2188 emitGPR (0x00, insn
->def(0));
2191 /*******************************************************************************
2193 ******************************************************************************/
2196 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2200 switch (typeSizeof(type
)) {
2201 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2202 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2203 case 4: data
= 4; break;
2204 case 8: data
= 5; break;
2205 case 16: data
= 6; break;
2207 assert(!"bad type");
2211 emitField(pos
, 3, data
);
2215 CodeEmitterGM107::emitLDSTc(int pos
)
2219 switch (insn
->cache
) {
2220 case CACHE_CA
: mode
= 0; break;
2221 case CACHE_CG
: mode
= 1; break;
2222 case CACHE_CS
: mode
= 2; break;
2223 case CACHE_CV
: mode
= 3; break;
2225 assert(!"invalid caching mode");
2229 emitField(pos
, 2, mode
);
2233 CodeEmitterGM107::emitLDC()
2235 emitInsn (0xef900000);
2236 emitLDSTs(0x30, insn
->dType
);
2237 emitField(0x2c, 2, insn
->subOp
);
2238 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2239 emitGPR (0x00, insn
->def(0));
2243 CodeEmitterGM107::emitLDL()
2245 emitInsn (0xef400000);
2246 emitLDSTs(0x30, insn
->dType
);
2248 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2249 emitGPR (0x00, insn
->def(0));
2253 CodeEmitterGM107::emitLDS()
2255 emitInsn (0xef480000);
2256 emitLDSTs(0x30, insn
->dType
);
2257 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2258 emitGPR (0x00, insn
->def(0));
2262 CodeEmitterGM107::emitLD()
2264 emitInsn (0x80000000);
2267 emitLDSTs(0x35, insn
->dType
);
2268 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2269 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2270 emitGPR (0x00, insn
->def(0));
2274 CodeEmitterGM107::emitSTL()
2276 emitInsn (0xef500000);
2277 emitLDSTs(0x30, insn
->dType
);
2279 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2280 emitGPR (0x00, insn
->src(1));
2284 CodeEmitterGM107::emitSTS()
2286 emitInsn (0xef580000);
2287 emitLDSTs(0x30, insn
->dType
);
2288 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2289 emitGPR (0x00, insn
->src(1));
2293 CodeEmitterGM107::emitST()
2295 emitInsn (0xa0000000);
2298 emitLDSTs(0x35, insn
->dType
);
2299 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2300 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2301 emitGPR (0x00, insn
->src(1));
2305 CodeEmitterGM107::emitALD()
2307 emitInsn (0xefd80000);
2308 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2309 emitGPR (0x27, insn
->src(0).getIndirect(1));
2312 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2313 emitGPR (0x00, insn
->def(0));
2317 CodeEmitterGM107::emitAST()
2319 emitInsn (0xeff00000);
2320 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2321 emitGPR (0x27, insn
->src(0).getIndirect(1));
2323 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2324 emitGPR (0x00, insn
->src(1));
2328 CodeEmitterGM107::emitISBERD()
2330 emitInsn(0xefd00000);
2331 emitGPR (0x08, insn
->src(0));
2332 emitGPR (0x00, insn
->def(0));
2336 CodeEmitterGM107::emitAL2P()
2338 emitInsn (0xefa00000);
2339 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2342 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2343 emitGPR (0x08, insn
->src(0).getIndirect(0));
2344 emitGPR (0x00, insn
->def(0));
2348 interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2350 int ipa
= entry
->ipa
;
2351 int reg
= entry
->reg
;
2352 int loc
= entry
->loc
;
2354 if (data
.flatshade
&&
2355 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2356 ipa
= NV50_IR_INTERP_FLAT
;
2358 } else if (data
.force_persample_interp
&&
2359 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2360 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2361 ipa
|= NV50_IR_INTERP_CENTROID
;
2363 code
[loc
+ 1] &= ~(0xf << 0x14);
2364 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2365 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2366 code
[loc
+ 0] &= ~(0xff << 0x14);
2367 code
[loc
+ 0] |= reg
<< 0x14;
2371 CodeEmitterGM107::emitIPA()
2373 int ipam
= 0, ipas
= 0;
2375 switch (insn
->getInterpMode()) {
2376 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2377 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2378 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2379 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2381 assert(!"invalid ipa mode");
2385 switch (insn
->getSampleMode()) {
2386 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2387 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2388 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2390 assert(!"invalid ipa sample mode");
2394 emitInsn (0xe0000000);
2395 emitField(0x36, 2, ipam
);
2396 emitField(0x34, 2, ipas
);
2398 emitField(0x2f, 3, 7);
2399 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2400 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2401 code
[1] |= 0x00000040; /* .idx */
2402 emitGPR(0x00, insn
->def(0));
2404 if (insn
->op
== OP_PINTERP
) {
2405 emitGPR(0x14, insn
->src(1));
2406 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2407 emitGPR(0x27, insn
->src(2));
2408 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2410 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2411 emitGPR(0x27, insn
->src(1));
2413 addInterp(insn
->ipa
, 0xff, interpApply
);
2416 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2421 CodeEmitterGM107::emitATOM()
2423 unsigned dType
, subOp
;
2425 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2426 switch (insn
->dType
) {
2427 case TYPE_U32
: dType
= 0; break;
2428 case TYPE_U64
: dType
= 1; break;
2429 default: assert(!"unexpected dType"); dType
= 0; break;
2433 emitInsn (0xee000000);
2435 switch (insn
->dType
) {
2436 case TYPE_U32
: dType
= 0; break;
2437 case TYPE_S32
: dType
= 1; break;
2438 case TYPE_U64
: dType
= 2; break;
2439 case TYPE_F32
: dType
= 3; break;
2440 case TYPE_B128
: dType
= 4; break;
2441 case TYPE_S64
: dType
= 5; break;
2442 default: assert(!"unexpected dType"); dType
= 0; break;
2444 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2447 subOp
= insn
->subOp
;
2449 emitInsn (0xed000000);
2452 emitField(0x34, 4, subOp
);
2453 emitField(0x31, 3, dType
);
2454 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2455 emitGPR (0x14, insn
->src(1));
2456 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2457 emitGPR (0x00, insn
->def(0));
2461 CodeEmitterGM107::emitATOMS()
2463 unsigned dType
, subOp
;
2465 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2466 switch (insn
->dType
) {
2467 case TYPE_U32
: dType
= 0; break;
2468 case TYPE_U64
: dType
= 1; break;
2469 default: assert(!"unexpected dType"); dType
= 0; break;
2473 emitInsn (0xee000000);
2474 emitField(0x34, 1, dType
);
2476 switch (insn
->dType
) {
2477 case TYPE_U32
: dType
= 0; break;
2478 case TYPE_S32
: dType
= 1; break;
2479 case TYPE_U64
: dType
= 2; break;
2480 case TYPE_S64
: dType
= 3; break;
2481 default: assert(!"unexpected dType"); dType
= 0; break;
2484 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2487 subOp
= insn
->subOp
;
2489 emitInsn (0xec000000);
2490 emitField(0x1c, 3, dType
);
2493 emitField(0x34, 4, subOp
);
2494 emitGPR (0x14, insn
->src(1));
2495 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2496 emitGPR (0x00, insn
->def(0));
2500 CodeEmitterGM107::emitRED()
2504 switch (insn
->dType
) {
2505 case TYPE_U32
: dType
= 0; break;
2506 case TYPE_S32
: dType
= 1; break;
2507 case TYPE_U64
: dType
= 2; break;
2508 case TYPE_F32
: dType
= 3; break;
2509 case TYPE_B128
: dType
= 4; break;
2510 case TYPE_S64
: dType
= 5; break;
2511 default: assert(!"unexpected dType"); dType
= 0; break;
2514 emitInsn (0xebf80000);
2515 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2516 emitField(0x17, 3, insn
->subOp
);
2517 emitField(0x14, 3, dType
);
2518 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2519 emitGPR (0x00, insn
->src(1));
2523 CodeEmitterGM107::emitCCTL()
2526 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2527 emitInsn(0xef600000);
2530 emitInsn(0xef800000);
2533 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2534 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2535 emitField(0x00, 4, insn
->subOp
);
2538 /*******************************************************************************
2540 ******************************************************************************/
2543 CodeEmitterGM107::emitPIXLD()
2545 emitInsn (0xefe80000);
2547 emitField(0x1f, 3, insn
->subOp
);
2548 emitGPR (0x08, insn
->src(0));
2549 emitGPR (0x00, insn
->def(0));
2552 /*******************************************************************************
2554 ******************************************************************************/
2557 CodeEmitterGM107::emitTEXs(int pos
)
2559 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2560 if (insn
->srcExists(src1
))
2561 emitGPR(pos
, insn
->src(src1
));
2567 CodeEmitterGM107::emitTEX()
2569 const TexInstruction
*insn
= this->insn
->asTex();
2572 if (!insn
->tex
.levelZero
) {
2574 case OP_TEX
: lodm
= 0; break;
2575 case OP_TXB
: lodm
= 2; break;
2576 case OP_TXL
: lodm
= 3; break;
2578 assert(!"invalid tex op");
2585 if (insn
->tex
.rIndirectSrc
>= 0) {
2586 emitInsn (0xdeb80000);
2587 emitField(0x25, 2, lodm
);
2588 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2590 emitInsn (0xc0380000);
2591 emitField(0x37, 2, lodm
);
2592 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2593 emitField(0x24, 13, insn
->tex
.r
);
2596 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2597 emitField(0x31, 1, insn
->tex
.liveOnly
);
2598 emitField(0x23, 1, insn
->tex
.derivAll
);
2599 emitField(0x1f, 4, insn
->tex
.mask
);
2600 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2601 insn
->tex
.target
.getDim() - 1);
2602 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2604 emitGPR (0x08, insn
->src(0));
2605 emitGPR (0x00, insn
->def(0));
2609 CodeEmitterGM107::emitTLD()
2611 const TexInstruction
*insn
= this->insn
->asTex();
2613 if (insn
->tex
.rIndirectSrc
>= 0) {
2614 emitInsn (0xdd380000);
2616 emitInsn (0xdc380000);
2617 emitField(0x24, 13, insn
->tex
.r
);
2620 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2621 emitField(0x32, 1, insn
->tex
.target
.isMS());
2622 emitField(0x31, 1, insn
->tex
.liveOnly
);
2623 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2624 emitField(0x1f, 4, insn
->tex
.mask
);
2625 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2626 insn
->tex
.target
.getDim() - 1);
2627 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2629 emitGPR (0x08, insn
->src(0));
2630 emitGPR (0x00, insn
->def(0));
2634 CodeEmitterGM107::emitTLD4()
2636 const TexInstruction
*insn
= this->insn
->asTex();
2638 if (insn
->tex
.rIndirectSrc
>= 0) {
2639 emitInsn (0xdef80000);
2640 emitField(0x26, 2, insn
->tex
.gatherComp
);
2641 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2642 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2644 emitInsn (0xc8380000);
2645 emitField(0x38, 2, insn
->tex
.gatherComp
);
2646 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2647 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2648 emitField(0x24, 13, insn
->tex
.r
);
2651 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2652 emitField(0x31, 1, insn
->tex
.liveOnly
);
2653 emitField(0x23, 1, insn
->tex
.derivAll
);
2654 emitField(0x1f, 4, insn
->tex
.mask
);
2655 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2656 insn
->tex
.target
.getDim() - 1);
2657 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2659 emitGPR (0x08, insn
->src(0));
2660 emitGPR (0x00, insn
->def(0));
2664 CodeEmitterGM107::emitTXD()
2666 const TexInstruction
*insn
= this->insn
->asTex();
2668 if (insn
->tex
.rIndirectSrc
>= 0) {
2669 emitInsn (0xde780000);
2671 emitInsn (0xde380000);
2672 emitField(0x24, 13, insn
->tex
.r
);
2675 emitField(0x31, 1, insn
->tex
.liveOnly
);
2676 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2677 emitField(0x1f, 4, insn
->tex
.mask
);
2678 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2679 insn
->tex
.target
.getDim() - 1);
2680 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2682 emitGPR (0x08, insn
->src(0));
2683 emitGPR (0x00, insn
->def(0));
2687 CodeEmitterGM107::emitTMML()
2689 const TexInstruction
*insn
= this->insn
->asTex();
2691 if (insn
->tex
.rIndirectSrc
>= 0) {
2692 emitInsn (0xdf600000);
2694 emitInsn (0xdf580000);
2695 emitField(0x24, 13, insn
->tex
.r
);
2698 emitField(0x31, 1, insn
->tex
.liveOnly
);
2699 emitField(0x23, 1, insn
->tex
.derivAll
);
2700 emitField(0x1f, 4, insn
->tex
.mask
);
2701 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2702 insn
->tex
.target
.getDim() - 1);
2703 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2705 emitGPR (0x08, insn
->src(0));
2706 emitGPR (0x00, insn
->def(0));
2710 CodeEmitterGM107::emitTXQ()
2712 const TexInstruction
*insn
= this->insn
->asTex();
2715 switch (insn
->tex
.query
) {
2716 case TXQ_DIMS
: type
= 0x01; break;
2717 case TXQ_TYPE
: type
= 0x02; break;
2718 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2719 case TXQ_FILTER
: type
= 0x10; break;
2720 case TXQ_LOD
: type
= 0x12; break;
2721 case TXQ_WRAP
: type
= 0x14; break;
2722 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2724 assert(!"invalid txq query");
2728 if (insn
->tex
.rIndirectSrc
>= 0) {
2729 emitInsn (0xdf500000);
2731 emitInsn (0xdf480000);
2732 emitField(0x24, 13, insn
->tex
.r
);
2735 emitField(0x31, 1, insn
->tex
.liveOnly
);
2736 emitField(0x1f, 4, insn
->tex
.mask
);
2737 emitField(0x16, 6, type
);
2738 emitGPR (0x08, insn
->src(0));
2739 emitGPR (0x00, insn
->def(0));
2743 CodeEmitterGM107::emitDEPBAR()
2745 emitInsn (0xf0f00000);
2746 emitField(0x1d, 1, 1); /* le */
2747 emitField(0x1a, 3, 5);
2748 emitField(0x14, 6, insn
->subOp
);
2749 emitField(0x00, 6, insn
->subOp
);
2752 /*******************************************************************************
2754 ******************************************************************************/
2757 CodeEmitterGM107::emitNOP()
2759 emitInsn(0x50b00000);
2763 CodeEmitterGM107::emitKIL()
2765 emitInsn (0xe3300000);
2766 emitCond5(0x00, CC_TR
);
2770 CodeEmitterGM107::emitOUT()
2772 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2773 const int emit
= insn
->op
== OP_EMIT
;
2775 switch (insn
->src(1).getFile()) {
2777 emitInsn(0xfbe00000);
2778 emitGPR (0x14, insn
->src(1));
2780 case FILE_IMMEDIATE
:
2781 emitInsn(0xf6e00000);
2782 emitIMMD(0x14, 19, insn
->src(1));
2784 case FILE_MEMORY_CONST
:
2785 emitInsn(0xebe00000);
2786 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2789 assert(!"bad src1 file");
2793 emitField(0x27, 2, (cut
<< 1) | emit
);
2794 emitGPR (0x08, insn
->src(0));
2795 emitGPR (0x00, insn
->def(0));
2799 CodeEmitterGM107::emitBAR()
2803 emitInsn (0xf0a80000);
2805 switch (insn
->subOp
) {
2806 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2807 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2808 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2809 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2812 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2816 emitField(0x20, 8, subop
);
2819 if (insn
->src(0).getFile() == FILE_GPR
) {
2820 emitGPR(0x08, insn
->src(0));
2822 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2824 emitField(0x08, 8, imm
->reg
.data
.u32
);
2825 emitField(0x2b, 1, 1);
2829 if (insn
->src(1).getFile() == FILE_GPR
) {
2830 emitGPR(0x14, insn
->src(1));
2832 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2834 emitField(0x14, 12, imm
->reg
.data
.u32
);
2835 emitField(0x2c, 1, 1);
2838 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2839 emitPRED (0x27, insn
->src(2));
2840 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2842 emitField(0x27, 3, 7);
2847 CodeEmitterGM107::emitMEMBAR()
2849 emitInsn (0xef980000);
2850 emitField(0x08, 2, insn
->subOp
>> 2);
2854 CodeEmitterGM107::emitVOTE()
2856 assert(insn
->src(0).getFile() == FILE_PREDICATE
);
2859 for (int i
= 0; insn
->defExists(i
); i
++) {
2860 if (insn
->def(i
).getFile() == FILE_GPR
)
2862 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
2866 emitInsn (0x50d80000);
2867 emitField(0x30, 2, insn
->subOp
);
2869 emitGPR (0x00, insn
->def(r
));
2873 emitPRED (0x2d, insn
->def(p
));
2876 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2877 emitPRED (0x27, insn
->src(0));
2881 CodeEmitterGM107::emitSUTarget()
2883 const TexInstruction
*insn
= this->insn
->asTex();
2886 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2888 if (insn
->tex
.target
== TEX_TARGET_BUFFER
) {
2890 } else if (insn
->tex
.target
== TEX_TARGET_1D_ARRAY
) {
2892 } else if (insn
->tex
.target
== TEX_TARGET_2D
||
2893 insn
->tex
.target
== TEX_TARGET_RECT
) {
2895 } else if (insn
->tex
.target
== TEX_TARGET_2D_ARRAY
||
2896 insn
->tex
.target
== TEX_TARGET_CUBE
||
2897 insn
->tex
.target
== TEX_TARGET_CUBE_ARRAY
) {
2899 } else if (insn
->tex
.target
== TEX_TARGET_3D
) {
2902 assert(insn
->tex
.target
== TEX_TARGET_1D
);
2904 emitField(0x20, 4, target
);
2908 CodeEmitterGM107::emitSUHandle(const int s
)
2910 const TexInstruction
*insn
= this->insn
->asTex();
2912 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
2914 if (insn
->src(s
).getFile() == FILE_GPR
) {
2915 emitGPR(0x27, insn
->src(s
));
2917 ImmediateValue
*imm
= insn
->getSrc(s
)->asImm();
2919 emitField(0x33, 1, 1);
2920 emitField(0x24, 13, imm
->reg
.data
.u32
);
2925 CodeEmitterGM107::emitSUSTx()
2927 const TexInstruction
*insn
= this->insn
->asTex();
2929 emitInsn(0xeb200000);
2930 if (insn
->op
== OP_SUSTB
)
2931 emitField(0x34, 1, 1);
2935 emitField(0x14, 4, 0xf); // rgba
2936 emitGPR (0x08, insn
->src(0));
2937 emitGPR (0x00, insn
->src(1));
2943 CodeEmitterGM107::emitSULDx()
2945 const TexInstruction
*insn
= this->insn
->asTex();
2948 emitInsn(0xeb000000);
2949 if (insn
->op
== OP_SULDB
)
2950 emitField(0x34, 1, 1);
2953 switch (insn
->dType
) {
2954 case TYPE_S8
: type
= 1; break;
2955 case TYPE_U16
: type
= 2; break;
2956 case TYPE_S16
: type
= 3; break;
2957 case TYPE_U32
: type
= 4; break;
2958 case TYPE_U64
: type
= 5; break;
2959 case TYPE_B128
: type
= 6; break;
2961 assert(insn
->dType
== TYPE_U8
);
2965 emitField(0x14, 3, type
);
2966 emitGPR (0x00, insn
->def(0));
2967 emitGPR (0x08, insn
->src(0));
2973 CodeEmitterGM107::emitSUREDx()
2975 const TexInstruction
*insn
= this->insn
->asTex();
2976 uint8_t type
= 0, subOp
;
2978 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
)
2979 emitInsn(0xeac00000);
2981 emitInsn(0xea600000);
2983 if (insn
->op
== OP_SUREDB
)
2984 emitField(0x34, 1, 1);
2988 switch (insn
->dType
) {
2989 case TYPE_S32
: type
= 1; break;
2990 case TYPE_U64
: type
= 2; break;
2991 case TYPE_F32
: type
= 3; break;
2992 case TYPE_S64
: type
= 5; break;
2994 assert(insn
->dType
== TYPE_U32
);
2999 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
3001 } else if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
) {
3004 subOp
= insn
->subOp
;
3007 emitField(0x24, 3, type
);
3008 emitField(0x1d, 4, subOp
);
3009 emitGPR (0x14, insn
->src(1));
3010 emitGPR (0x08, insn
->src(0));
3011 emitGPR (0x00, insn
->def(0));
3016 /*******************************************************************************
3017 * assembler front-end
3018 ******************************************************************************/
3021 CodeEmitterGM107::emitInstruction(Instruction
*i
)
3023 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
3028 if (insn
->encSize
!= 8) {
3029 ERROR("skipping undecodable instruction: "); insn
->print();
3032 if (codeSize
+ size
> codeSizeLimit
) {
3033 ERROR("code emitter output buffer too small\n");
3037 if (writeIssueDelays
) {
3038 int n
= ((codeSize
& 0x1f) / 8) - 1;
3041 data
[0] = 0x00000000;
3042 data
[1] = 0x00000000;
3048 emitField(data
, n
* 21, 21, insn
->sched
);
3104 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
3105 insn
->src(0).getFile() == FILE_PREDICATE
)) {
3107 } else if (isFloatType(insn
->dType
)) {
3108 if (isFloatType(insn
->sType
))
3113 if (isFloatType(insn
->sType
))
3124 if (isFloatType(insn
->dType
)) {
3125 if (insn
->dType
== TYPE_F64
)
3134 if (isFloatType(insn
->dType
)) {
3135 if (insn
->dType
== TYPE_F64
)
3145 if (isFloatType(insn
->dType
)) {
3146 if (insn
->dType
== TYPE_F64
)
3159 if (isFloatType(insn
->dType
)) {
3160 if (insn
->dType
== TYPE_F64
)
3187 if (isFloatType(insn
->dType
))
3196 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
3197 if (isFloatType(insn
->sType
))
3198 if (insn
->sType
== TYPE_F64
)
3205 if (isFloatType(insn
->sType
))
3206 if (insn
->sType
== TYPE_F64
)
3238 switch (insn
->src(0).getFile()) {
3239 case FILE_MEMORY_CONST
: emitLDC(); break;
3240 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3241 case FILE_MEMORY_SHARED
: emitLDS(); break;
3242 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3244 assert(!"invalid load");
3250 switch (insn
->src(0).getFile()) {
3251 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3252 case FILE_MEMORY_SHARED
: emitSTS(); break;
3253 case FILE_MEMORY_GLOBAL
: emitST(); break;
3255 assert(!"invalid store");
3261 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3264 if (!insn
->defExists(0) && insn
->subOp
< NV50_IR_SUBOP_ATOM_CAS
)
3349 assert(!"invalid opcode");
3365 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3370 /*******************************************************************************
3371 * sched data calculator
3372 ******************************************************************************/
3374 class SchedDataCalculatorGM107
: public Pass
3377 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3380 bool visit(BasicBlock
*bb
);
3384 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3386 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3388 insn
->sched
= 0x7e0;
3394 /*******************************************************************************
3396 ******************************************************************************/
3399 CodeEmitterGM107::prepareEmission(Function
*func
)
3401 SchedDataCalculatorGM107
sched(targ
);
3402 CodeEmitter::prepareEmission(func
);
3403 sched
.run(func
, true, true);
3406 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3408 return (size
+ 23) / 24;
3412 CodeEmitterGM107::prepareEmission(Program
*prog
)
3414 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3415 !fi
.end(); fi
.next()) {
3416 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3417 func
->binPos
= prog
->binSize
;
3418 prepareEmission(func
);
3420 // adjust sizes & positions for schedulding info:
3421 if (prog
->getTarget()->hasSWSched
) {
3422 uint32_t adjPos
= func
->binPos
;
3423 BasicBlock
*bb
= NULL
;
3424 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3425 bb
= func
->bbArray
[i
];
3426 int32_t adjSize
= bb
->binSize
;
3428 adjSize
-= 32 - adjPos
% 32;
3432 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3433 bb
->binPos
= adjPos
;
3434 bb
->binSize
= adjSize
;
3438 func
->binSize
= adjPos
- func
->binPos
;
3441 prog
->binSize
+= func
->binSize
;
3445 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3446 : CodeEmitter(target
),
3448 writeIssueDelays(target
->hasSWSched
)
3451 codeSize
= codeSizeLimit
= 0;
3456 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3458 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3459 emit
->setProgramType(type
);
3463 } // namespace nv50_ir