2 * Copyright 2014 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 #include "codegen/nv50_ir_target_gm107.h"
29 class CodeEmitterGM107
: public CodeEmitter
32 CodeEmitterGM107(const TargetGM107
*);
34 virtual bool emitInstruction(Instruction
*);
35 virtual uint32_t getMinEncodingSize(const Instruction
*) const;
37 virtual void prepareEmission(Program
*);
38 virtual void prepareEmission(Function
*);
40 inline void setProgramType(Program::Type pType
) { progType
= pType
; }
43 const TargetGM107
*targGM107
;
45 Program::Type progType
;
47 const Instruction
*insn
;
48 const bool writeIssueDelays
;
52 inline void emitField(uint32_t *, int, int, uint32_t);
53 inline void emitField(int b
, int s
, uint32_t v
) { emitField(code
, b
, s
, v
); }
55 inline void emitInsn(uint32_t, bool);
56 inline void emitInsn(uint32_t o
) { emitInsn(o
, true); }
57 inline void emitPred();
58 inline void emitGPR(int, const Value
*);
59 inline void emitGPR(int pos
) {
60 emitGPR(pos
, (const Value
*)NULL
);
62 inline void emitGPR(int pos
, const ValueRef
&ref
) {
63 emitGPR(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
65 inline void emitGPR(int pos
, const ValueRef
*ref
) {
66 emitGPR(pos
, ref
? ref
->rep() : (const Value
*)NULL
);
68 inline void emitGPR(int pos
, const ValueDef
&def
) {
69 emitGPR(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
71 inline void emitSYS(int, const Value
*);
72 inline void emitSYS(int pos
, const ValueRef
&ref
) {
73 emitSYS(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
75 inline void emitPRED(int, const Value
*);
76 inline void emitPRED(int pos
) {
77 emitPRED(pos
, (const Value
*)NULL
);
79 inline void emitPRED(int pos
, const ValueRef
&ref
) {
80 emitPRED(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
82 inline void emitPRED(int pos
, const ValueDef
&def
) {
83 emitPRED(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
85 inline void emitADDR(int, int, int, int, const ValueRef
&);
86 inline void emitCBUF(int, int, int, int, int, const ValueRef
&);
87 inline bool longIMMD(const ValueRef
&);
88 inline void emitIMMD(int, int, const ValueRef
&);
90 void emitCond3(int, CondCode
);
91 void emitCond4(int, CondCode
);
92 void emitCond5(int pos
, CondCode cc
) { emitCond4(pos
, cc
); }
93 inline void emitO(int);
94 inline void emitP(int);
95 inline void emitSAT(int);
96 inline void emitCC(int);
97 inline void emitX(int);
98 inline void emitABS(int, const ValueRef
&);
99 inline void emitNEG(int, const ValueRef
&);
100 inline void emitNEG2(int, const ValueRef
&, const ValueRef
&);
101 inline void emitFMZ(int, int);
102 inline void emitRND(int, RoundMode
, int);
103 inline void emitRND(int pos
) {
104 emitRND(pos
, insn
->rnd
, -1);
106 inline void emitPDIV(int);
107 inline void emitINV(int, const ValueRef
&);
166 void emitLDSTs(int, DataType
);
205 /*******************************************************************************
206 * general instruction layout/fields
207 ******************************************************************************/
210 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
213 uint32_t m
= ((1ULL << s
) - 1);
214 uint64_t d
= (uint64_t)(v
& m
) << b
;
215 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
222 CodeEmitterGM107::emitPred()
224 if (insn
->predSrc
>= 0) {
225 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
226 emitField(19, 1, insn
->cc
== CC_NOT_P
);
233 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
235 code
[0] = 0x00000000;
242 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
244 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
248 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
250 int id
= val
? val
->reg
.data
.id
: -1;
253 case SV_LANEID
: id
= 0x00; break;
254 case SV_VERTEX_COUNT
: id
= 0x10; break;
255 case SV_INVOCATION_ID
: id
= 0x11; break;
256 case SV_THREAD_KILL
: id
= 0x13; break;
257 case SV_INVOCATION_INFO
: id
= 0x1d; break;
258 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
259 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
261 assert(!"invalid system value");
266 emitField(pos
, 8, id
);
270 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
272 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
276 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
279 const Value
*v
= ref
.get();
280 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
282 emitGPR(gpr
, ref
.getIndirect(0));
283 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
287 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
290 const Value
*v
= ref
.get();
291 const Symbol
*s
= v
->asSym();
293 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
295 emitField(buf
, 5, v
->reg
.fileIndex
);
297 emitGPR(gpr
, ref
.getIndirect(0));
298 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
302 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
304 if (ref
.getFile() == FILE_IMMEDIATE
) {
305 const ImmediateValue
*imm
= ref
.get()->asImm();
306 if (isFloatType(insn
->sType
)) {
307 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
310 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
311 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
319 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
321 const ImmediateValue
*imm
= ref
.get()->asImm();
322 uint32_t val
= imm
->reg
.data
.u32
;
325 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
326 assert(!(val
& 0x00000fff));
328 } else if (insn
->sType
== TYPE_F64
) {
329 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
330 val
= imm
->reg
.data
.u64
>> 44;
332 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
333 emitField( 56, 1, (val
& 0x80000) >> 19);
334 emitField(pos
, len
, (val
& 0x7ffff));
336 emitField(pos
, len
, val
);
340 /*******************************************************************************
342 ******************************************************************************/
345 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
350 case CC_FL
: data
= 0x00; break;
352 case CC_LT
: data
= 0x01; break;
354 case CC_EQ
: data
= 0x02; break;
356 case CC_LE
: data
= 0x03; break;
358 case CC_GT
: data
= 0x04; break;
360 case CC_NE
: data
= 0x05; break;
362 case CC_GE
: data
= 0x06; break;
363 case CC_TR
: data
= 0x07; break;
365 assert(!"invalid cond3");
369 emitField(pos
, 3, data
);
373 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
378 case CC_FL
: data
= 0x00; break;
379 case CC_LT
: data
= 0x01; break;
380 case CC_EQ
: data
= 0x02; break;
381 case CC_LE
: data
= 0x03; break;
382 case CC_GT
: data
= 0x04; break;
383 case CC_NE
: data
= 0x05; break;
384 case CC_GE
: data
= 0x06; break;
385 // case CC_NUM: data = 0x07; break;
386 // case CC_NAN: data = 0x08; break;
387 case CC_LTU
: data
= 0x09; break;
388 case CC_EQU
: data
= 0x0a; break;
389 case CC_LEU
: data
= 0x0b; break;
390 case CC_GTU
: data
= 0x0c; break;
391 case CC_NEU
: data
= 0x0d; break;
392 case CC_GEU
: data
= 0x0e; break;
393 case CC_TR
: data
= 0x0f; break;
395 assert(!"invalid cond4");
399 emitField(pos
, 4, data
);
403 CodeEmitterGM107::emitO(int pos
)
405 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
409 CodeEmitterGM107::emitP(int pos
)
411 emitField(pos
, 1, insn
->perPatch
);
415 CodeEmitterGM107::emitSAT(int pos
)
417 emitField(pos
, 1, insn
->saturate
);
421 CodeEmitterGM107::emitCC(int pos
)
423 emitField(pos
, 1, insn
->defExists(1));
427 CodeEmitterGM107::emitX(int pos
)
429 emitField(pos
, 1, insn
->flagsSrc
>= 0);
433 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
435 emitField(pos
, 1, ref
.mod
.abs());
439 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
441 emitField(pos
, 1, ref
.mod
.neg());
445 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
447 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
451 CodeEmitterGM107::emitFMZ(int pos
, int len
)
453 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
457 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
461 case ROUND_NI
: ri
= 1;
462 case ROUND_N
: rm
= 0; break;
463 case ROUND_MI
: ri
= 1;
464 case ROUND_M
: rm
= 1; break;
465 case ROUND_PI
: ri
= 1;
466 case ROUND_P
: rm
= 2; break;
467 case ROUND_ZI
: ri
= 1;
468 case ROUND_Z
: rm
= 3; break;
470 assert(!"invalid round mode");
473 emitField(rip
, 1, ri
);
474 emitField(rmp
, 2, rm
);
478 CodeEmitterGM107::emitPDIV(int pos
)
480 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
481 if (insn
->postFactor
> 0)
482 emitField(pos
, 3, 7 - insn
->postFactor
);
484 emitField(pos
, 3, 0 - insn
->postFactor
);
488 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
490 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
493 /*******************************************************************************
495 ******************************************************************************/
498 CodeEmitterGM107::emitEXIT()
500 emitInsn (0xe3000000);
501 emitCond5(0x00, CC_TR
);
505 CodeEmitterGM107::emitBRA()
507 const FlowInstruction
*insn
= this->insn
->asFlow();
510 if (insn
->indirect
) {
512 emitInsn(0xe2000000); // JMX
514 emitInsn(0xe2500000); // BRX
518 emitInsn(0xe2100000); // JMP
520 emitInsn(0xe2400000); // BRA
521 emitField(0x07, 1, insn
->allWarp
);
524 emitField(0x06, 1, insn
->limit
);
525 emitCond5(0x00, CC_TR
);
527 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
528 int32_t pos
= insn
->target
.bb
->binPos
;
529 if (writeIssueDelays
&& !(pos
& 0x1f))
532 emitField(0x14, 24, pos
- (codeSize
+ 8));
534 emitField(0x14, 32, pos
);
536 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
537 emitField(0x05, 1, 1);
542 CodeEmitterGM107::emitCAL()
544 const FlowInstruction
*insn
= this->insn
->asFlow();
546 if (insn
->absolute
) {
547 emitInsn(0xe2200000, 0); // JCAL
549 emitInsn(0xe2600000, 0); // CAL
552 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
554 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
557 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
558 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
559 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
561 emitField(0x14, 32, insn
->target
.bb
->binPos
);
565 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
566 emitField(0x05, 1, 1);
571 CodeEmitterGM107::emitPCNT()
573 const FlowInstruction
*insn
= this->insn
->asFlow();
575 emitInsn(0xe2b00000, 0);
577 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
578 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
580 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
581 emitField(0x05, 1, 1);
586 CodeEmitterGM107::emitCONT()
588 emitInsn (0xe3500000);
589 emitCond5(0x00, CC_TR
);
593 CodeEmitterGM107::emitPBK()
595 const FlowInstruction
*insn
= this->insn
->asFlow();
597 emitInsn(0xe2a00000, 0);
599 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
600 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
602 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
603 emitField(0x05, 1, 1);
608 CodeEmitterGM107::emitBRK()
610 emitInsn (0xe3400000);
611 emitCond5(0x00, CC_TR
);
615 CodeEmitterGM107::emitPRET()
617 const FlowInstruction
*insn
= this->insn
->asFlow();
619 emitInsn(0xe2700000, 0);
621 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
622 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
624 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
625 emitField(0x05, 1, 1);
630 CodeEmitterGM107::emitRET()
632 emitInsn (0xe3200000);
633 emitCond5(0x00, CC_TR
);
637 CodeEmitterGM107::emitSSY()
639 const FlowInstruction
*insn
= this->insn
->asFlow();
641 emitInsn(0xe2900000, 0);
643 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
644 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
646 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
647 emitField(0x05, 1, 1);
652 CodeEmitterGM107::emitSYNC()
654 emitInsn (0xf0f80000);
655 emitCond5(0x00, CC_TR
);
659 CodeEmitterGM107::emitSAM()
661 emitInsn(0xe3700000, 0);
665 CodeEmitterGM107::emitRAM()
667 emitInsn(0xe3800000, 0);
670 /*******************************************************************************
672 ******************************************************************************/
674 /*******************************************************************************
675 * movement / conversion
676 ******************************************************************************/
679 CodeEmitterGM107::emitMOV()
681 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
682 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
683 switch (insn
->src(0).getFile()) {
685 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
686 emitInsn(0x5b6a0000);
689 emitInsn(0x5c980000);
691 emitGPR (0x14, insn
->src(0));
693 case FILE_MEMORY_CONST
:
694 emitInsn(0x4c980000);
695 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
698 emitInsn(0x38980000);
699 emitIMMD(0x14, 19, insn
->src(0));
702 emitInsn(0x50880000);
703 emitPRED(0x0c, insn
->src(0));
708 assert(!"bad src file");
711 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
712 insn
->src(0).getFile() != FILE_PREDICATE
)
713 emitField(0x27, 4, insn
->lanes
);
715 emitInsn (0x01000000);
716 emitIMMD (0x14, 32, insn
->src(0));
717 emitField(0x0c, 4, insn
->lanes
);
720 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
722 emitPRED(0x03, insn
->def(0));
725 emitGPR(0x00, insn
->def(0));
730 CodeEmitterGM107::emitS2R()
732 emitInsn(0xf0c80000);
733 emitSYS (0x14, insn
->src(0));
734 emitGPR (0x00, insn
->def(0));
738 CodeEmitterGM107::emitF2F()
740 RoundMode rnd
= insn
->rnd
;
743 case OP_FLOOR
: rnd
= ROUND_MI
; break;
744 case OP_CEIL
: rnd
= ROUND_PI
; break;
745 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
750 switch (insn
->src(0).getFile()) {
752 emitInsn(0x5ca80000);
753 emitGPR (0x14, insn
->src(0));
755 case FILE_MEMORY_CONST
:
756 emitInsn(0x4ca80000);
757 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
760 emitInsn(0x38a80000);
761 emitIMMD(0x14, 19, insn
->src(0));
764 assert(!"bad src0 file");
768 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
769 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
771 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
773 emitField(0x29, 1, insn
->subOp
);
774 emitRND (0x27, rnd
, 0x2a);
775 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
776 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
777 emitGPR (0x00, insn
->def(0));
781 CodeEmitterGM107::emitF2I()
783 RoundMode rnd
= insn
->rnd
;
786 case OP_FLOOR
: rnd
= ROUND_M
; break;
787 case OP_CEIL
: rnd
= ROUND_P
; break;
788 case OP_TRUNC
: rnd
= ROUND_Z
; break;
793 switch (insn
->src(0).getFile()) {
795 emitInsn(0x5cb00000);
796 emitGPR (0x14, insn
->src(0));
798 case FILE_MEMORY_CONST
:
799 emitInsn(0x4cb00000);
800 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
803 emitInsn(0x38b00000);
804 emitIMMD(0x14, 19, insn
->src(0));
807 assert(!"bad src0 file");
811 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
813 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
815 emitRND (0x27, rnd
, 0x2a);
816 emitField(0x0c, 1, isSignedType(insn
->dType
));
817 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
818 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
819 emitGPR (0x00, insn
->def(0));
823 CodeEmitterGM107::emitI2F()
825 RoundMode rnd
= insn
->rnd
;
828 case OP_FLOOR
: rnd
= ROUND_M
; break;
829 case OP_CEIL
: rnd
= ROUND_P
; break;
830 case OP_TRUNC
: rnd
= ROUND_Z
; break;
835 switch (insn
->src(0).getFile()) {
837 emitInsn(0x5cb80000);
838 emitGPR (0x14, insn
->src(0));
840 case FILE_MEMORY_CONST
:
841 emitInsn(0x4cb80000);
842 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
845 emitInsn(0x38b80000);
846 emitIMMD(0x14, 19, insn
->src(0));
849 assert(!"bad src0 file");
853 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
855 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
856 emitField(0x29, 2, insn
->subOp
);
857 emitRND (0x27, rnd
, -1);
858 emitField(0x0d, 1, isSignedType(insn
->sType
));
859 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
860 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
861 emitGPR (0x00, insn
->def(0));
865 CodeEmitterGM107::emitI2I()
867 switch (insn
->src(0).getFile()) {
869 emitInsn(0x5ce00000);
870 emitGPR (0x14, insn
->src(0));
872 case FILE_MEMORY_CONST
:
873 emitInsn(0x4ce00000);
874 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
877 emitInsn(0x38e00000);
878 emitIMMD(0x14, 19, insn
->src(0));
881 assert(!"bad src0 file");
886 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
888 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
889 emitField(0x29, 2, insn
->subOp
);
890 emitField(0x0d, 1, isSignedType(insn
->sType
));
891 emitField(0x0c, 1, isSignedType(insn
->dType
));
892 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
893 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
894 emitGPR (0x00, insn
->def(0));
898 selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
900 int loc
= entry
->loc
;
901 if (data
.force_persample_interp
)
902 code
[loc
+ 1] |= 1 << 10;
904 code
[loc
+ 1] &= ~(1 << 10);
908 CodeEmitterGM107::emitSEL()
910 switch (insn
->src(1).getFile()) {
912 emitInsn(0x5ca00000);
913 emitGPR (0x14, insn
->src(1));
915 case FILE_MEMORY_CONST
:
916 emitInsn(0x4ca00000);
917 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
920 emitInsn(0x38a00000);
921 emitIMMD(0x14, 19, insn
->src(1));
924 assert(!"bad src1 file");
928 emitINV (0x2a, insn
->src(2));
929 emitPRED(0x27, insn
->src(2));
930 emitGPR (0x08, insn
->src(0));
931 emitGPR (0x00, insn
->def(0));
933 if (insn
->subOp
== 1) {
934 addInterp(0, 0, selpFlip
);
939 CodeEmitterGM107::emitSHFL()
943 emitInsn (0xef100000);
945 switch (insn
->src(1).getFile()) {
947 emitGPR(0x14, insn
->src(1));
950 emitIMMD(0x14, 5, insn
->src(1));
954 assert(!"invalid src1 file");
958 /*XXX: what is this arg? hardcode immediate for now */
959 emitField(0x22, 13, 0x1c03);
963 emitField(0x1e, 2, insn
->subOp
);
964 emitField(0x1c, 2, type
);
965 emitGPR (0x08, insn
->src(0));
966 emitGPR (0x00, insn
->def(0));
969 /*******************************************************************************
971 ******************************************************************************/
974 CodeEmitterGM107::emitDADD()
976 switch (insn
->src(1).getFile()) {
978 emitInsn(0x5c700000);
979 emitGPR (0x14, insn
->src(1));
981 case FILE_MEMORY_CONST
:
982 emitInsn(0x4c700000);
983 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
986 emitInsn(0x38700000);
987 emitIMMD(0x14, 19, insn
->src(1));
990 assert(!"bad src1 file");
993 emitABS(0x31, insn
->src(1));
994 emitNEG(0x30, insn
->src(0));
996 emitABS(0x2e, insn
->src(0));
997 emitNEG(0x2d, insn
->src(1));
999 if (insn
->op
== OP_SUB
)
1000 code
[1] ^= 0x00002000;
1002 emitGPR(0x08, insn
->src(0));
1003 emitGPR(0x00, insn
->def(0));
1007 CodeEmitterGM107::emitDMUL()
1009 switch (insn
->src(1).getFile()) {
1011 emitInsn(0x5c800000);
1012 emitGPR (0x14, insn
->src(1));
1014 case FILE_MEMORY_CONST
:
1015 emitInsn(0x4c800000);
1016 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1018 case FILE_IMMEDIATE
:
1019 emitInsn(0x38800000);
1020 emitIMMD(0x14, 19, insn
->src(1));
1023 assert(!"bad src1 file");
1027 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1030 emitGPR (0x08, insn
->src(0));
1031 emitGPR (0x00, insn
->def(0));
1035 CodeEmitterGM107::emitDFMA()
1037 switch(insn
->src(2).getFile()) {
1039 switch (insn
->src(1).getFile()) {
1041 emitInsn(0x5b700000);
1042 emitGPR (0x14, insn
->src(1));
1044 case FILE_MEMORY_CONST
:
1045 emitInsn(0x4b700000);
1046 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1048 case FILE_IMMEDIATE
:
1049 emitInsn(0x36700000);
1050 emitIMMD(0x14, 19, insn
->src(1));
1053 assert(!"bad src1 file");
1056 emitGPR (0x27, insn
->src(2));
1058 case FILE_MEMORY_CONST
:
1059 emitInsn(0x53700000);
1060 emitGPR (0x27, insn
->src(1));
1061 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1064 assert(!"bad src2 file");
1069 emitNEG (0x31, insn
->src(2));
1070 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1072 emitGPR (0x08, insn
->src(0));
1073 emitGPR (0x00, insn
->def(0));
1077 CodeEmitterGM107::emitDMNMX()
1079 switch (insn
->src(1).getFile()) {
1081 emitInsn(0x5c500000);
1082 emitGPR (0x14, insn
->src(1));
1084 case FILE_MEMORY_CONST
:
1085 emitInsn(0x4c500000);
1086 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1088 case FILE_IMMEDIATE
:
1089 emitInsn(0x38500000);
1090 emitIMMD(0x14, 19, insn
->src(1));
1093 assert(!"bad src1 file");
1097 emitABS (0x31, insn
->src(1));
1098 emitNEG (0x30, insn
->src(0));
1100 emitABS (0x2e, insn
->src(0));
1101 emitNEG (0x2d, insn
->src(1));
1102 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1104 emitGPR (0x08, insn
->src(0));
1105 emitGPR (0x00, insn
->def(0));
1109 CodeEmitterGM107::emitDSET()
1111 const CmpInstruction
*insn
= this->insn
->asCmp();
1113 switch (insn
->src(1).getFile()) {
1115 emitInsn(0x59000000);
1116 emitGPR (0x14, insn
->src(1));
1118 case FILE_MEMORY_CONST
:
1119 emitInsn(0x49000000);
1120 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1122 case FILE_IMMEDIATE
:
1123 emitInsn(0x32000000);
1124 emitIMMD(0x14, 19, insn
->src(1));
1127 assert(!"bad src1 file");
1131 if (insn
->op
!= OP_SET
) {
1133 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1134 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1135 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1137 assert(!"invalid set op");
1140 emitPRED(0x27, insn
->src(2));
1145 emitABS (0x36, insn
->src(0));
1146 emitNEG (0x35, insn
->src(1));
1147 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1148 emitCond4(0x30, insn
->setCond
);
1150 emitABS (0x2c, insn
->src(1));
1151 emitNEG (0x2b, insn
->src(0));
1152 emitGPR (0x08, insn
->src(0));
1153 emitGPR (0x00, insn
->def(0));
1157 CodeEmitterGM107::emitDSETP()
1159 const CmpInstruction
*insn
= this->insn
->asCmp();
1161 switch (insn
->src(1).getFile()) {
1163 emitInsn(0x5b800000);
1164 emitGPR (0x14, insn
->src(1));
1166 case FILE_MEMORY_CONST
:
1167 emitInsn(0x4b800000);
1168 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1170 case FILE_IMMEDIATE
:
1171 emitInsn(0x36800000);
1172 emitIMMD(0x14, 19, insn
->src(1));
1175 assert(!"bad src1 file");
1179 if (insn
->op
!= OP_SET
) {
1181 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1182 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1183 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1185 assert(!"invalid set op");
1188 emitPRED(0x27, insn
->src(2));
1193 emitCond4(0x30, insn
->setCond
);
1194 emitABS (0x2c, insn
->src(1));
1195 emitNEG (0x2b, insn
->src(0));
1196 emitGPR (0x08, insn
->src(0));
1197 emitABS (0x07, insn
->src(0));
1198 emitNEG (0x06, insn
->src(1));
1199 emitPRED (0x03, insn
->def(0));
1200 if (insn
->defExists(1))
1201 emitPRED(0x00, insn
->def(1));
1206 /*******************************************************************************
1208 ******************************************************************************/
1211 CodeEmitterGM107::emitFADD()
1213 if (!longIMMD(insn
->src(1))) {
1214 switch (insn
->src(1).getFile()) {
1216 emitInsn(0x5c580000);
1217 emitGPR (0x14, insn
->src(1));
1219 case FILE_MEMORY_CONST
:
1220 emitInsn(0x4c580000);
1221 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1223 case FILE_IMMEDIATE
:
1224 emitInsn(0x38580000);
1225 emitIMMD(0x14, 19, insn
->src(1));
1228 assert(!"bad src1 file");
1232 emitABS(0x31, insn
->src(1));
1233 emitNEG(0x30, insn
->src(0));
1235 emitABS(0x2e, insn
->src(0));
1236 emitNEG(0x2d, insn
->src(1));
1239 emitInsn(0x08000000);
1240 emitABS(0x39, insn
->src(1));
1241 emitNEG(0x38, insn
->src(0));
1243 emitABS(0x36, insn
->src(0));
1244 emitNEG(0x35, insn
->src(1));
1246 emitIMMD(0x14, 32, insn
->src(1));
1249 if (insn
->op
== OP_SUB
)
1250 code
[1] ^= 0x00002000;
1252 emitGPR(0x08, insn
->src(0));
1253 emitGPR(0x00, insn
->def(0));
1257 CodeEmitterGM107::emitFMUL()
1259 if (!longIMMD(insn
->src(1))) {
1260 switch (insn
->src(1).getFile()) {
1262 emitInsn(0x5c680000);
1263 emitGPR (0x14, insn
->src(1));
1265 case FILE_MEMORY_CONST
:
1266 emitInsn(0x4c680000);
1267 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1269 case FILE_IMMEDIATE
:
1270 emitInsn(0x38680000);
1271 emitIMMD(0x14, 19, insn
->src(1));
1274 assert(!"bad src1 file");
1278 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1284 emitInsn(0x1e000000);
1288 emitIMMD(0x14, 32, insn
->src(1));
1289 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1290 code
[1] ^= 0x00080000; /* flip immd sign bit */
1293 emitGPR(0x08, insn
->src(0));
1294 emitGPR(0x00, insn
->def(0));
1298 CodeEmitterGM107::emitFFMA()
1300 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1301 switch(insn
->src(2).getFile()) {
1303 switch (insn
->src(1).getFile()) {
1305 emitInsn(0x59800000);
1306 emitGPR (0x14, insn
->src(1));
1308 case FILE_MEMORY_CONST
:
1309 emitInsn(0x49800000);
1310 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1312 case FILE_IMMEDIATE
:
1313 emitInsn(0x32800000);
1314 emitIMMD(0x14, 19, insn
->src(1));
1317 assert(!"bad src1 file");
1320 emitGPR (0x27, insn
->src(2));
1322 case FILE_MEMORY_CONST
:
1323 emitInsn(0x51800000);
1324 emitGPR (0x27, insn
->src(1));
1325 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1328 assert(!"bad src2 file");
1333 emitNEG (0x31, insn
->src(2));
1334 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1338 emitGPR(0x08, insn
->src(0));
1339 emitGPR(0x00, insn
->def(0));
1343 CodeEmitterGM107::emitMUFU()
1348 case OP_COS
: mufu
= 0; break;
1349 case OP_SIN
: mufu
= 1; break;
1350 case OP_EX2
: mufu
= 2; break;
1351 case OP_LG2
: mufu
= 3; break;
1352 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1353 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1355 assert(!"invalid mufu");
1359 emitInsn (0x50800000);
1361 emitNEG (0x30, insn
->src(0));
1362 emitABS (0x2e, insn
->src(0));
1363 emitField(0x14, 3, mufu
);
1364 emitGPR (0x08, insn
->src(0));
1365 emitGPR (0x00, insn
->def(0));
1369 CodeEmitterGM107::emitFMNMX()
1371 switch (insn
->src(1).getFile()) {
1373 emitInsn(0x5c600000);
1374 emitGPR (0x14, insn
->src(1));
1376 case FILE_MEMORY_CONST
:
1377 emitInsn(0x4c600000);
1378 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1380 case FILE_IMMEDIATE
:
1381 emitInsn(0x38600000);
1382 emitIMMD(0x14, 19, insn
->src(1));
1385 assert(!"bad src1 file");
1389 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1392 emitABS(0x31, insn
->src(1));
1393 emitNEG(0x30, insn
->src(0));
1395 emitABS(0x2e, insn
->src(0));
1396 emitNEG(0x2d, insn
->src(1));
1398 emitGPR(0x08, insn
->src(0));
1399 emitGPR(0x00, insn
->def(0));
1403 CodeEmitterGM107::emitRRO()
1405 switch (insn
->src(0).getFile()) {
1407 emitInsn(0x5c900000);
1408 emitGPR (0x14, insn
->src(0));
1410 case FILE_MEMORY_CONST
:
1411 emitInsn(0x4c900000);
1412 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1414 case FILE_IMMEDIATE
:
1415 emitInsn(0x38900000);
1416 emitIMMD(0x14, 19, insn
->src(0));
1419 assert(!"bad src file");
1423 emitABS (0x31, insn
->src(0));
1424 emitNEG (0x2d, insn
->src(0));
1425 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1426 emitGPR (0x00, insn
->def(0));
1430 CodeEmitterGM107::emitFCMP()
1432 const CmpInstruction
*insn
= this->insn
->asCmp();
1433 CondCode cc
= insn
->setCond
;
1435 if (insn
->src(2).mod
.neg())
1436 cc
= reverseCondCode(cc
);
1438 switch(insn
->src(2).getFile()) {
1440 switch (insn
->src(1).getFile()) {
1442 emitInsn(0x5ba00000);
1443 emitGPR (0x14, insn
->src(1));
1445 case FILE_MEMORY_CONST
:
1446 emitInsn(0x4ba00000);
1447 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1449 case FILE_IMMEDIATE
:
1450 emitInsn(0x36a00000);
1451 emitIMMD(0x14, 19, insn
->src(1));
1454 assert(!"bad src1 file");
1457 emitGPR (0x27, insn
->src(2));
1459 case FILE_MEMORY_CONST
:
1460 emitInsn(0x53a00000);
1461 emitGPR (0x27, insn
->src(1));
1462 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1465 assert(!"bad src2 file");
1469 emitCond4(0x30, cc
);
1471 emitGPR (0x08, insn
->src(0));
1472 emitGPR (0x00, insn
->def(0));
1476 CodeEmitterGM107::emitFSET()
1478 const CmpInstruction
*insn
= this->insn
->asCmp();
1480 switch (insn
->src(1).getFile()) {
1482 emitInsn(0x58000000);
1483 emitGPR (0x14, insn
->src(1));
1485 case FILE_MEMORY_CONST
:
1486 emitInsn(0x48000000);
1487 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1489 case FILE_IMMEDIATE
:
1490 emitInsn(0x30000000);
1491 emitIMMD(0x14, 19, insn
->src(1));
1494 assert(!"bad src1 file");
1498 if (insn
->op
!= OP_SET
) {
1500 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1501 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1502 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1504 assert(!"invalid set op");
1507 emitPRED(0x27, insn
->src(2));
1513 emitABS (0x36, insn
->src(0));
1514 emitNEG (0x35, insn
->src(1));
1515 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1516 emitCond4(0x30, insn
->setCond
);
1518 emitABS (0x2c, insn
->src(1));
1519 emitNEG (0x2b, insn
->src(0));
1520 emitGPR (0x08, insn
->src(0));
1521 emitGPR (0x00, insn
->def(0));
1525 CodeEmitterGM107::emitFSETP()
1527 const CmpInstruction
*insn
= this->insn
->asCmp();
1529 switch (insn
->src(1).getFile()) {
1531 emitInsn(0x5bb00000);
1532 emitGPR (0x14, insn
->src(1));
1534 case FILE_MEMORY_CONST
:
1535 emitInsn(0x4bb00000);
1536 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1538 case FILE_IMMEDIATE
:
1539 emitInsn(0x36b00000);
1540 emitIMMD(0x14, 19, insn
->src(1));
1543 assert(!"bad src1 file");
1547 if (insn
->op
!= OP_SET
) {
1549 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1550 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1551 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1553 assert(!"invalid set op");
1556 emitPRED(0x27, insn
->src(2));
1561 emitCond4(0x30, insn
->setCond
);
1563 emitABS (0x2c, insn
->src(1));
1564 emitNEG (0x2b, insn
->src(0));
1565 emitGPR (0x08, insn
->src(0));
1566 emitABS (0x07, insn
->src(0));
1567 emitNEG (0x06, insn
->src(1));
1568 emitPRED (0x03, insn
->def(0));
1569 if (insn
->defExists(1))
1570 emitPRED(0x00, insn
->def(1));
1576 CodeEmitterGM107::emitFSWZADD()
1578 emitInsn (0x50f80000);
1582 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1583 emitField(0x1c, 8, insn
->subOp
);
1584 if (insn
->predSrc
!= 1)
1585 emitGPR (0x14, insn
->src(1));
1588 emitGPR (0x08, insn
->src(0));
1589 emitGPR (0x00, insn
->def(0));
1592 /*******************************************************************************
1594 ******************************************************************************/
1597 CodeEmitterGM107::emitLOP()
1602 case OP_AND
: lop
= 0; break;
1603 case OP_OR
: lop
= 1; break;
1604 case OP_XOR
: lop
= 2; break;
1606 assert(!"invalid lop");
1610 if (!longIMMD(insn
->src(1))) {
1611 switch (insn
->src(1).getFile()) {
1613 emitInsn(0x5c400000);
1614 emitGPR (0x14, insn
->src(1));
1616 case FILE_MEMORY_CONST
:
1617 emitInsn(0x4c400000);
1618 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1620 case FILE_IMMEDIATE
:
1621 emitInsn(0x38400000);
1622 emitIMMD(0x14, 19, insn
->src(1));
1625 assert(!"bad src1 file");
1630 emitField(0x29, 2, lop
);
1631 emitINV (0x28, insn
->src(1));
1632 emitINV (0x27, insn
->src(0));
1634 emitInsn (0x04000000);
1636 emitINV (0x38, insn
->src(1));
1637 emitINV (0x37, insn
->src(0));
1638 emitField(0x35, 2, lop
);
1639 emitIMMD (0x14, 32, insn
->src(1));
1642 emitGPR (0x08, insn
->src(0));
1643 emitGPR (0x00, insn
->def(0));
1646 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1648 CodeEmitterGM107::emitNOT()
1650 if (!longIMMD(insn
->src(0))) {
1651 switch (insn
->src(0).getFile()) {
1653 emitInsn(0x5c400700);
1654 emitGPR (0x14, insn
->src(0));
1656 case FILE_MEMORY_CONST
:
1657 emitInsn(0x4c400700);
1658 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1660 case FILE_IMMEDIATE
:
1661 emitInsn(0x38400700);
1662 emitIMMD(0x14, 19, insn
->src(0));
1665 assert(!"bad src1 file");
1670 emitInsn (0x05600000);
1671 emitIMMD (0x14, 32, insn
->src(1));
1675 emitGPR(0x00, insn
->def(0));
1679 CodeEmitterGM107::emitIADD()
1681 if (!longIMMD(insn
->src(1))) {
1682 switch (insn
->src(1).getFile()) {
1684 emitInsn(0x5c100000);
1685 emitGPR (0x14, insn
->src(1));
1687 case FILE_MEMORY_CONST
:
1688 emitInsn(0x4c100000);
1689 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1691 case FILE_IMMEDIATE
:
1692 emitInsn(0x38100000);
1693 emitIMMD(0x14, 19, insn
->src(1));
1696 assert(!"bad src1 file");
1700 emitNEG(0x31, insn
->src(0));
1701 emitNEG(0x30, insn
->src(1));
1705 emitInsn(0x1c000000);
1709 emitIMMD(0x14, 32, insn
->src(1));
1712 if (insn
->op
== OP_SUB
)
1713 code
[1] ^= 0x00010000;
1715 emitGPR(0x08, insn
->src(0));
1716 emitGPR(0x00, insn
->def(0));
1720 CodeEmitterGM107::emitIMUL()
1722 if (!longIMMD(insn
->src(1))) {
1723 switch (insn
->src(1).getFile()) {
1725 emitInsn(0x5c380000);
1726 emitGPR (0x14, insn
->src(1));
1728 case FILE_MEMORY_CONST
:
1729 emitInsn(0x4c380000);
1730 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1732 case FILE_IMMEDIATE
:
1733 emitInsn(0x38380000);
1734 emitIMMD(0x14, 19, insn
->src(1));
1737 assert(!"bad src1 file");
1741 emitField(0x29, 1, isSignedType(insn
->sType
));
1742 emitField(0x28, 1, isSignedType(insn
->dType
));
1743 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1745 emitInsn (0x1f000000);
1746 emitField(0x37, 1, isSignedType(insn
->sType
));
1747 emitField(0x36, 1, isSignedType(insn
->dType
));
1748 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1750 emitIMMD (0x14, 32, insn
->src(1));
1753 emitGPR(0x08, insn
->src(0));
1754 emitGPR(0x00, insn
->def(0));
1758 CodeEmitterGM107::emitIMAD()
1760 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1761 switch(insn
->src(2).getFile()) {
1763 switch (insn
->src(1).getFile()) {
1765 emitInsn(0x5a000000);
1766 emitGPR (0x14, insn
->src(1));
1768 case FILE_MEMORY_CONST
:
1769 emitInsn(0x4a000000);
1770 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1772 case FILE_IMMEDIATE
:
1773 emitInsn(0x34000000);
1774 emitIMMD(0x14, 19, insn
->src(1));
1777 assert(!"bad src1 file");
1780 emitGPR (0x27, insn
->src(2));
1782 case FILE_MEMORY_CONST
:
1783 emitInsn(0x52000000);
1784 emitGPR (0x27, insn
->src(1));
1785 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1788 assert(!"bad src2 file");
1792 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1793 emitField(0x35, 1, isSignedType(insn
->sType
));
1794 emitNEG (0x34, insn
->src(2));
1795 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1798 emitField(0x30, 1, isSignedType(insn
->dType
));
1800 emitGPR (0x08, insn
->src(0));
1801 emitGPR (0x00, insn
->def(0));
1805 CodeEmitterGM107::emitIMNMX()
1807 switch (insn
->src(1).getFile()) {
1809 emitInsn(0x5c200000);
1810 emitGPR (0x14, insn
->src(1));
1812 case FILE_MEMORY_CONST
:
1813 emitInsn(0x4c200000);
1814 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1816 case FILE_IMMEDIATE
:
1817 emitInsn(0x38200000);
1818 emitIMMD(0x14, 19, insn
->src(1));
1821 assert(!"bad src1 file");
1825 emitField(0x30, 1, isSignedType(insn
->dType
));
1827 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1829 emitGPR (0x08, insn
->src(0));
1830 emitGPR (0x00, insn
->def(0));
1834 CodeEmitterGM107::emitICMP()
1836 const CmpInstruction
*insn
= this->insn
->asCmp();
1837 CondCode cc
= insn
->setCond
;
1839 if (insn
->src(2).mod
.neg())
1840 cc
= reverseCondCode(cc
);
1842 switch(insn
->src(2).getFile()) {
1844 switch (insn
->src(1).getFile()) {
1846 emitInsn(0x5b400000);
1847 emitGPR (0x14, insn
->src(1));
1849 case FILE_MEMORY_CONST
:
1850 emitInsn(0x4b400000);
1851 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1853 case FILE_IMMEDIATE
:
1854 emitInsn(0x36400000);
1855 emitIMMD(0x14, 19, insn
->src(1));
1858 assert(!"bad src1 file");
1861 emitGPR (0x27, insn
->src(2));
1863 case FILE_MEMORY_CONST
:
1864 emitInsn(0x53400000);
1865 emitGPR (0x27, insn
->src(1));
1866 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1869 assert(!"bad src2 file");
1873 emitCond3(0x31, cc
);
1874 emitField(0x30, 1, isSignedType(insn
->sType
));
1875 emitGPR (0x08, insn
->src(0));
1876 emitGPR (0x00, insn
->def(0));
1880 CodeEmitterGM107::emitISET()
1882 const CmpInstruction
*insn
= this->insn
->asCmp();
1884 switch (insn
->src(1).getFile()) {
1886 emitInsn(0x5b500000);
1887 emitGPR (0x14, insn
->src(1));
1889 case FILE_MEMORY_CONST
:
1890 emitInsn(0x4b500000);
1891 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1893 case FILE_IMMEDIATE
:
1894 emitInsn(0x36500000);
1895 emitIMMD(0x14, 19, insn
->src(1));
1898 assert(!"bad src1 file");
1902 if (insn
->op
!= OP_SET
) {
1904 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1905 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1906 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1908 assert(!"invalid set op");
1911 emitPRED(0x27, insn
->src(2));
1916 emitCond3(0x31, insn
->setCond
);
1917 emitField(0x30, 1, isSignedType(insn
->sType
));
1919 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1921 emitGPR (0x08, insn
->src(0));
1922 emitGPR (0x00, insn
->def(0));
1926 CodeEmitterGM107::emitISETP()
1928 const CmpInstruction
*insn
= this->insn
->asCmp();
1930 switch (insn
->src(1).getFile()) {
1932 emitInsn(0x5b600000);
1933 emitGPR (0x14, insn
->src(1));
1935 case FILE_MEMORY_CONST
:
1936 emitInsn(0x4b600000);
1937 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1939 case FILE_IMMEDIATE
:
1940 emitInsn(0x36600000);
1941 emitIMMD(0x14, 19, insn
->src(1));
1944 assert(!"bad src1 file");
1948 if (insn
->op
!= OP_SET
) {
1950 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1951 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1952 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1954 assert(!"invalid set op");
1957 emitPRED(0x27, insn
->src(2));
1962 emitCond3(0x31, insn
->setCond
);
1963 emitField(0x30, 1, isSignedType(insn
->sType
));
1965 emitGPR (0x08, insn
->src(0));
1966 emitPRED (0x03, insn
->def(0));
1967 if (insn
->defExists(1))
1968 emitPRED(0x00, insn
->def(1));
1974 CodeEmitterGM107::emitSHL()
1976 switch (insn
->src(1).getFile()) {
1978 emitInsn(0x5c480000);
1979 emitGPR (0x14, insn
->src(1));
1981 case FILE_MEMORY_CONST
:
1982 emitInsn(0x4c480000);
1983 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1985 case FILE_IMMEDIATE
:
1986 emitInsn(0x38480000);
1987 emitIMMD(0x14, 19, insn
->src(1));
1990 assert(!"bad src1 file");
1996 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1997 emitGPR (0x08, insn
->src(0));
1998 emitGPR (0x00, insn
->def(0));
2002 CodeEmitterGM107::emitSHR()
2004 switch (insn
->src(1).getFile()) {
2006 emitInsn(0x5c280000);
2007 emitGPR (0x14, insn
->src(1));
2009 case FILE_MEMORY_CONST
:
2010 emitInsn(0x4c280000);
2011 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2013 case FILE_IMMEDIATE
:
2014 emitInsn(0x38280000);
2015 emitIMMD(0x14, 19, insn
->src(1));
2018 assert(!"bad src1 file");
2022 emitField(0x30, 1, isSignedType(insn
->dType
));
2025 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2026 emitGPR (0x08, insn
->src(0));
2027 emitGPR (0x00, insn
->def(0));
2031 CodeEmitterGM107::emitPOPC()
2033 switch (insn
->src(0).getFile()) {
2035 emitInsn(0x5c080000);
2036 emitGPR (0x14, insn
->src(0));
2038 case FILE_MEMORY_CONST
:
2039 emitInsn(0x4c080000);
2040 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2042 case FILE_IMMEDIATE
:
2043 emitInsn(0x38080000);
2044 emitIMMD(0x14, 19, insn
->src(0));
2047 assert(!"bad src1 file");
2051 emitINV(0x28, insn
->src(0));
2052 emitGPR(0x00, insn
->def(0));
2056 CodeEmitterGM107::emitBFI()
2058 switch(insn
->src(2).getFile()) {
2060 switch (insn
->src(1).getFile()) {
2062 emitInsn(0x5bf00000);
2063 emitGPR (0x14, insn
->src(1));
2065 case FILE_MEMORY_CONST
:
2066 emitInsn(0x4bf00000);
2067 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2069 case FILE_IMMEDIATE
:
2070 emitInsn(0x36f00000);
2071 emitIMMD(0x14, 19, insn
->src(1));
2074 assert(!"bad src1 file");
2077 emitGPR (0x27, insn
->src(2));
2079 case FILE_MEMORY_CONST
:
2080 emitInsn(0x53f00000);
2081 emitGPR (0x27, insn
->src(1));
2082 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2085 assert(!"bad src2 file");
2090 emitGPR (0x08, insn
->src(0));
2091 emitGPR (0x00, insn
->def(0));
2095 CodeEmitterGM107::emitBFE()
2097 switch (insn
->src(1).getFile()) {
2099 emitInsn(0x5c000000);
2100 emitGPR (0x14, insn
->src(1));
2102 case FILE_MEMORY_CONST
:
2103 emitInsn(0x4c000000);
2104 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2106 case FILE_IMMEDIATE
:
2107 emitInsn(0x38000000);
2108 emitIMMD(0x14, 19, insn
->src(1));
2111 assert(!"bad src1 file");
2115 emitField(0x30, 1, isSignedType(insn
->dType
));
2117 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2118 emitGPR (0x08, insn
->src(0));
2119 emitGPR (0x00, insn
->def(0));
2123 CodeEmitterGM107::emitFLO()
2125 switch (insn
->src(0).getFile()) {
2127 emitInsn(0x5c300000);
2128 emitGPR (0x14, insn
->src(0));
2130 case FILE_MEMORY_CONST
:
2131 emitInsn(0x4c300000);
2132 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2134 case FILE_IMMEDIATE
:
2135 emitInsn(0x38300000);
2136 emitIMMD(0x14, 19, insn
->src(0));
2139 assert(!"bad src1 file");
2143 emitField(0x30, 1, isSignedType(insn
->dType
));
2145 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2146 emitINV (0x28, insn
->src(0));
2147 emitGPR (0x00, insn
->def(0));
2150 /*******************************************************************************
2152 ******************************************************************************/
2155 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2159 switch (typeSizeof(type
)) {
2160 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2161 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2162 case 4: data
= 4; break;
2163 case 8: data
= 5; break;
2164 case 16: data
= 6; break;
2166 assert(!"bad type");
2170 emitField(pos
, 3, data
);
2174 CodeEmitterGM107::emitLDSTc(int pos
)
2178 switch (insn
->cache
) {
2179 case CACHE_CA
: mode
= 0; break;
2180 case CACHE_CG
: mode
= 1; break;
2181 case CACHE_CS
: mode
= 2; break;
2182 case CACHE_CV
: mode
= 3; break;
2184 assert(!"invalid caching mode");
2188 emitField(pos
, 2, mode
);
2192 CodeEmitterGM107::emitLDC()
2194 emitInsn (0xef900000);
2195 emitLDSTs(0x30, insn
->dType
);
2196 emitField(0x2c, 2, insn
->subOp
);
2197 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2198 emitGPR (0x00, insn
->def(0));
2202 CodeEmitterGM107::emitLDL()
2204 emitInsn (0xef400000);
2205 emitLDSTs(0x30, insn
->dType
);
2207 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2208 emitGPR (0x00, insn
->def(0));
2212 CodeEmitterGM107::emitLDS()
2214 emitInsn (0xef480000);
2215 emitLDSTs(0x30, insn
->dType
);
2216 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2217 emitGPR (0x00, insn
->def(0));
2221 CodeEmitterGM107::emitLD()
2223 emitInsn (0x80000000);
2226 emitLDSTs(0x35, insn
->dType
);
2227 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2228 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2229 emitGPR (0x00, insn
->def(0));
2233 CodeEmitterGM107::emitSTL()
2235 emitInsn (0xef500000);
2236 emitLDSTs(0x30, insn
->dType
);
2238 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2239 emitGPR (0x00, insn
->src(1));
2243 CodeEmitterGM107::emitSTS()
2245 emitInsn (0xef580000);
2246 emitLDSTs(0x30, insn
->dType
);
2247 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2248 emitGPR (0x00, insn
->src(1));
2252 CodeEmitterGM107::emitST()
2254 emitInsn (0xa0000000);
2257 emitLDSTs(0x35, insn
->dType
);
2258 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2259 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2260 emitGPR (0x00, insn
->src(1));
2264 CodeEmitterGM107::emitALD()
2266 emitInsn (0xefd80000);
2267 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2268 emitGPR (0x27, insn
->src(0).getIndirect(1));
2271 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2272 emitGPR (0x00, insn
->def(0));
2276 CodeEmitterGM107::emitAST()
2278 emitInsn (0xeff00000);
2279 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2280 emitGPR (0x27, insn
->src(0).getIndirect(1));
2282 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2283 emitGPR (0x00, insn
->src(1));
2287 CodeEmitterGM107::emitISBERD()
2289 emitInsn(0xefd00000);
2290 emitGPR (0x08, insn
->src(0));
2291 emitGPR (0x00, insn
->def(0));
2295 CodeEmitterGM107::emitAL2P()
2297 emitInsn (0xefa00000);
2298 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2300 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2301 emitGPR (0x08, insn
->src(0).getIndirect(0));
2302 emitGPR (0x00, insn
->def(0));
2306 interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2308 int ipa
= entry
->ipa
;
2309 int reg
= entry
->reg
;
2310 int loc
= entry
->loc
;
2312 if (data
.flatshade
&&
2313 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2314 ipa
= NV50_IR_INTERP_FLAT
;
2316 } else if (data
.force_persample_interp
&&
2317 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2318 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2319 ipa
|= NV50_IR_INTERP_CENTROID
;
2321 code
[loc
+ 1] &= ~(0xf << 0x14);
2322 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2323 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2324 code
[loc
+ 0] &= ~(0xff << 0x14);
2325 code
[loc
+ 0] |= reg
<< 0x14;
2329 CodeEmitterGM107::emitIPA()
2331 int ipam
= 0, ipas
= 0;
2333 switch (insn
->getInterpMode()) {
2334 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2335 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2336 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2337 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2339 assert(!"invalid ipa mode");
2343 switch (insn
->getSampleMode()) {
2344 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2345 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2346 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2348 assert(!"invalid ipa sample mode");
2352 emitInsn (0xe0000000);
2353 emitField(0x36, 2, ipam
);
2354 emitField(0x34, 2, ipas
);
2356 emitField(0x2f, 3, 7);
2357 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2358 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2359 code
[1] |= 0x00000040; /* .idx */
2360 emitGPR(0x00, insn
->def(0));
2362 if (insn
->op
== OP_PINTERP
) {
2363 emitGPR(0x14, insn
->src(1));
2364 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2365 emitGPR(0x27, insn
->src(2));
2366 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2368 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2369 emitGPR(0x27, insn
->src(1));
2371 addInterp(insn
->ipa
, 0xff, interpApply
);
2374 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2379 CodeEmitterGM107::emitATOM()
2381 unsigned dType
, subOp
;
2383 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2384 switch (insn
->dType
) {
2385 case TYPE_U32
: dType
= 0; break;
2386 case TYPE_U64
: dType
= 1; break;
2387 default: assert(!"unexpected dType"); dType
= 0; break;
2391 emitInsn (0xee000000);
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_F32
: dType
= 3; break;
2398 case TYPE_B128
: dType
= 4; break;
2399 case TYPE_S64
: dType
= 5; break;
2400 default: assert(!"unexpected dType"); dType
= 0; break;
2402 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2405 subOp
= insn
->subOp
;
2407 emitInsn (0xed000000);
2410 emitField(0x34, 4, subOp
);
2411 emitField(0x31, 3, dType
);
2412 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2413 emitGPR (0x14, insn
->src(1));
2414 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2415 emitGPR (0x00, insn
->def(0));
2419 CodeEmitterGM107::emitATOMS()
2421 unsigned dType
, subOp
;
2423 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2424 switch (insn
->dType
) {
2425 case TYPE_U32
: dType
= 0; break;
2426 case TYPE_U64
: dType
= 1; break;
2427 default: assert(!"unexpected dType"); dType
= 0; break;
2431 emitInsn (0xee000000);
2432 emitField(0x34, 1, dType
);
2434 switch (insn
->dType
) {
2435 case TYPE_U32
: dType
= 0; break;
2436 case TYPE_S32
: dType
= 1; break;
2437 case TYPE_U64
: dType
= 2; break;
2438 case TYPE_S64
: dType
= 3; break;
2439 default: assert(!"unexpected dType"); dType
= 0; break;
2442 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2445 subOp
= insn
->subOp
;
2447 emitInsn (0xec000000);
2448 emitField(0x1c, 3, dType
);
2451 emitField(0x34, 4, subOp
);
2452 emitGPR (0x14, insn
->src(1));
2453 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2454 emitGPR (0x00, insn
->def(0));
2458 CodeEmitterGM107::emitCCTL()
2461 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2462 emitInsn(0xef600000);
2465 emitInsn(0xef800000);
2468 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2469 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2470 emitField(0x00, 4, insn
->subOp
);
2473 /*******************************************************************************
2475 ******************************************************************************/
2478 CodeEmitterGM107::emitPIXLD()
2480 emitInsn (0xefe80000);
2482 emitField(0x1f, 3, insn
->subOp
);
2483 emitGPR (0x08, insn
->src(0));
2484 emitGPR (0x00, insn
->def(0));
2487 /*******************************************************************************
2489 ******************************************************************************/
2492 CodeEmitterGM107::emitTEXs(int pos
)
2494 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2495 if (insn
->srcExists(src1
))
2496 emitGPR(pos
, insn
->src(src1
));
2502 CodeEmitterGM107::emitTEX()
2504 const TexInstruction
*insn
= this->insn
->asTex();
2507 if (!insn
->tex
.levelZero
) {
2509 case OP_TEX
: lodm
= 0; break;
2510 case OP_TXB
: lodm
= 2; break;
2511 case OP_TXL
: lodm
= 3; break;
2513 assert(!"invalid tex op");
2520 if (insn
->tex
.rIndirectSrc
>= 0) {
2521 emitInsn (0xdeb80000);
2522 emitField(0x35, 2, lodm
);
2523 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2525 emitInsn (0xc0380000);
2526 emitField(0x37, 2, lodm
);
2527 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2528 emitField(0x24, 13, insn
->tex
.r
);
2531 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2532 emitField(0x31, 1, insn
->tex
.liveOnly
);
2533 emitField(0x23, 1, insn
->tex
.derivAll
);
2534 emitField(0x1f, 4, insn
->tex
.mask
);
2535 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2536 insn
->tex
.target
.getDim() - 1);
2537 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2539 emitGPR (0x08, insn
->src(0));
2540 emitGPR (0x00, insn
->def(0));
2544 CodeEmitterGM107::emitTLD()
2546 const TexInstruction
*insn
= this->insn
->asTex();
2548 if (insn
->tex
.rIndirectSrc
>= 0) {
2549 emitInsn (0xdd380000);
2551 emitInsn (0xdc380000);
2552 emitField(0x24, 13, insn
->tex
.r
);
2555 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2556 emitField(0x32, 1, insn
->tex
.target
.isMS());
2557 emitField(0x31, 1, insn
->tex
.liveOnly
);
2558 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2559 emitField(0x1f, 4, insn
->tex
.mask
);
2560 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2561 insn
->tex
.target
.getDim() - 1);
2562 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2564 emitGPR (0x08, insn
->src(0));
2565 emitGPR (0x00, insn
->def(0));
2569 CodeEmitterGM107::emitTLD4()
2571 const TexInstruction
*insn
= this->insn
->asTex();
2573 if (insn
->tex
.rIndirectSrc
>= 0) {
2574 emitInsn (0xdef80000);
2575 emitField(0x26, 2, insn
->tex
.gatherComp
);
2576 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2577 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2579 emitInsn (0xc8380000);
2580 emitField(0x38, 2, insn
->tex
.gatherComp
);
2581 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2582 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2583 emitField(0x24, 13, insn
->tex
.r
);
2586 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2587 emitField(0x31, 1, insn
->tex
.liveOnly
);
2588 emitField(0x23, 1, insn
->tex
.derivAll
);
2589 emitField(0x1f, 4, insn
->tex
.mask
);
2590 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2591 insn
->tex
.target
.getDim() - 1);
2592 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2594 emitGPR (0x08, insn
->src(0));
2595 emitGPR (0x00, insn
->def(0));
2599 CodeEmitterGM107::emitTXD()
2601 const TexInstruction
*insn
= this->insn
->asTex();
2603 if (insn
->tex
.rIndirectSrc
>= 0) {
2604 emitInsn (0xde780000);
2606 emitInsn (0xde380000);
2607 emitField(0x24, 13, insn
->tex
.r
);
2610 emitField(0x31, 1, insn
->tex
.liveOnly
);
2611 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2612 emitField(0x1f, 4, insn
->tex
.mask
);
2613 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2614 insn
->tex
.target
.getDim() - 1);
2615 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2617 emitGPR (0x08, insn
->src(0));
2618 emitGPR (0x00, insn
->def(0));
2622 CodeEmitterGM107::emitTMML()
2624 const TexInstruction
*insn
= this->insn
->asTex();
2626 if (insn
->tex
.rIndirectSrc
>= 0) {
2627 emitInsn (0xdf600000);
2629 emitInsn (0xdf580000);
2630 emitField(0x24, 13, insn
->tex
.r
);
2633 emitField(0x31, 1, insn
->tex
.liveOnly
);
2634 emitField(0x23, 1, insn
->tex
.derivAll
);
2635 emitField(0x1f, 4, insn
->tex
.mask
);
2636 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2637 insn
->tex
.target
.getDim() - 1);
2638 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2640 emitGPR (0x08, insn
->src(0));
2641 emitGPR (0x00, insn
->def(0));
2645 CodeEmitterGM107::emitTXQ()
2647 const TexInstruction
*insn
= this->insn
->asTex();
2650 switch (insn
->tex
.query
) {
2651 case TXQ_DIMS
: type
= 0x01; break;
2652 case TXQ_TYPE
: type
= 0x02; break;
2653 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2654 case TXQ_FILTER
: type
= 0x10; break;
2655 case TXQ_LOD
: type
= 0x12; break;
2656 case TXQ_WRAP
: type
= 0x14; break;
2657 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2659 assert(!"invalid txq query");
2663 if (insn
->tex
.rIndirectSrc
>= 0) {
2664 emitInsn (0xdf500000);
2666 emitInsn (0xdf480000);
2667 emitField(0x24, 13, insn
->tex
.r
);
2670 emitField(0x31, 1, insn
->tex
.liveOnly
);
2671 emitField(0x1f, 4, insn
->tex
.mask
);
2672 emitField(0x16, 6, type
);
2673 emitGPR (0x08, insn
->src(0));
2674 emitGPR (0x00, insn
->def(0));
2678 CodeEmitterGM107::emitDEPBAR()
2680 emitInsn (0xf0f00000);
2681 emitField(0x1d, 1, 1); /* le */
2682 emitField(0x1a, 3, 5);
2683 emitField(0x14, 6, insn
->subOp
);
2684 emitField(0x00, 6, insn
->subOp
);
2687 /*******************************************************************************
2689 ******************************************************************************/
2692 CodeEmitterGM107::emitNOP()
2694 emitInsn(0x50b00000);
2698 CodeEmitterGM107::emitKIL()
2700 emitInsn (0xe3300000);
2701 emitCond5(0x00, CC_TR
);
2705 CodeEmitterGM107::emitOUT()
2707 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2708 const int emit
= insn
->op
== OP_EMIT
;
2710 switch (insn
->src(1).getFile()) {
2712 emitInsn(0xfbe00000);
2713 emitGPR (0x14, insn
->src(1));
2715 case FILE_IMMEDIATE
:
2716 emitInsn(0xf6e00000);
2717 emitIMMD(0x14, 19, insn
->src(1));
2719 case FILE_MEMORY_CONST
:
2720 emitInsn(0xebe00000);
2721 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2724 assert(!"bad src1 file");
2728 emitField(0x27, 2, (cut
<< 1) | emit
);
2729 emitGPR (0x08, insn
->src(0));
2730 emitGPR (0x00, insn
->def(0));
2734 CodeEmitterGM107::emitBAR()
2738 emitInsn (0xf0a80000);
2740 switch (insn
->subOp
) {
2741 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2742 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2743 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2744 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2747 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2751 emitField(0x20, 8, subop
);
2754 if (insn
->src(0).getFile() == FILE_GPR
) {
2755 emitGPR(0x08, insn
->src(0));
2757 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2759 emitField(0x08, 8, imm
->reg
.data
.u32
);
2760 emitField(0x2b, 1, 1);
2764 if (insn
->src(1).getFile() == FILE_GPR
) {
2765 emitGPR(0x14, insn
->src(1));
2767 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2769 emitField(0x14, 12, imm
->reg
.data
.u32
);
2770 emitField(0x2c, 1, 1);
2773 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2774 emitPRED (0x27, insn
->src(2));
2775 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2777 emitField(0x27, 3, 7);
2782 CodeEmitterGM107::emitMEMBAR()
2784 emitInsn (0xef980000);
2785 emitField(0x08, 2, insn
->subOp
>> 2);
2789 CodeEmitterGM107::emitVOTE()
2791 assert(insn
->src(0).getFile() == FILE_PREDICATE
);
2794 for (int i
= 0; insn
->defExists(i
); i
++) {
2795 if (insn
->def(i
).getFile() == FILE_GPR
)
2797 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
2801 emitInsn (0x50d80000);
2802 emitField(0x30, 2, insn
->subOp
);
2804 emitGPR (0x00, insn
->def(r
));
2808 emitPRED (0x2d, insn
->def(p
));
2811 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2812 emitPRED (0x27, insn
->src(0));
2815 /*******************************************************************************
2816 * assembler front-end
2817 ******************************************************************************/
2820 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2822 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2827 if (insn
->encSize
!= 8) {
2828 ERROR("skipping undecodable instruction: "); insn
->print();
2831 if (codeSize
+ size
> codeSizeLimit
) {
2832 ERROR("code emitter output buffer too small\n");
2836 if (writeIssueDelays
) {
2837 int n
= ((codeSize
& 0x1f) / 8) - 1;
2840 data
[0] = 0x00000000;
2841 data
[1] = 0x00000000;
2847 emitField(data
, n
* 21, 21, insn
->sched
);
2903 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
2904 insn
->src(0).getFile() == FILE_PREDICATE
)) {
2906 } else if (isFloatType(insn
->dType
)) {
2907 if (isFloatType(insn
->sType
))
2912 if (isFloatType(insn
->sType
))
2923 if (isFloatType(insn
->dType
)) {
2924 if (insn
->dType
== TYPE_F64
)
2933 if (isFloatType(insn
->dType
)) {
2934 if (insn
->dType
== TYPE_F64
)
2944 if (isFloatType(insn
->dType
)) {
2945 if (insn
->dType
== TYPE_F64
)
2955 if (isFloatType(insn
->dType
)) {
2956 if (insn
->dType
== TYPE_F64
)
2983 if (isFloatType(insn
->dType
))
2992 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2993 if (isFloatType(insn
->sType
))
2994 if (insn
->sType
== TYPE_F64
)
3001 if (isFloatType(insn
->sType
))
3002 if (insn
->sType
== TYPE_F64
)
3034 switch (insn
->src(0).getFile()) {
3035 case FILE_MEMORY_CONST
: emitLDC(); break;
3036 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3037 case FILE_MEMORY_SHARED
: emitLDS(); break;
3038 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3040 assert(!"invalid load");
3046 switch (insn
->src(0).getFile()) {
3047 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3048 case FILE_MEMORY_SHARED
: emitSTS(); break;
3049 case FILE_MEMORY_GLOBAL
: emitST(); break;
3051 assert(!"invalid store");
3057 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3130 assert(!"invalid opcode");
3146 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3151 /*******************************************************************************
3152 * sched data calculator
3153 ******************************************************************************/
3155 class SchedDataCalculatorGM107
: public Pass
3158 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3161 bool visit(BasicBlock
*bb
);
3165 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3167 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3169 insn
->sched
= 0x7e0;
3175 /*******************************************************************************
3177 ******************************************************************************/
3180 CodeEmitterGM107::prepareEmission(Function
*func
)
3182 SchedDataCalculatorGM107
sched(targ
);
3183 CodeEmitter::prepareEmission(func
);
3184 sched
.run(func
, true, true);
3187 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3189 return (size
+ 23) / 24;
3193 CodeEmitterGM107::prepareEmission(Program
*prog
)
3195 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3196 !fi
.end(); fi
.next()) {
3197 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3198 func
->binPos
= prog
->binSize
;
3199 prepareEmission(func
);
3201 // adjust sizes & positions for schedulding info:
3202 if (prog
->getTarget()->hasSWSched
) {
3203 uint32_t adjPos
= func
->binPos
;
3204 BasicBlock
*bb
= NULL
;
3205 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3206 bb
= func
->bbArray
[i
];
3207 int32_t adjSize
= bb
->binSize
;
3209 adjSize
-= 32 - adjPos
% 32;
3213 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3214 bb
->binPos
= adjPos
;
3215 bb
->binSize
= adjSize
;
3219 func
->binSize
= adjPos
- func
->binPos
;
3222 prog
->binSize
+= func
->binSize
;
3226 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3227 : CodeEmitter(target
),
3229 writeIssueDelays(target
->hasSWSched
)
3232 codeSize
= codeSizeLimit
= 0;
3237 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3239 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3240 emit
->setProgramType(type
);
3244 } // namespace nv50_ir