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
->flagsDef
>= 0);
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 switch (insn
->src(0).getFile()) {
684 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
685 emitInsn(0x5b6a0000);
688 emitInsn(0x5c980000);
690 emitGPR (0x14, insn
->src(0));
692 case FILE_MEMORY_CONST
:
693 emitInsn(0x4c980000);
694 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
697 emitInsn(0x38980000);
698 emitIMMD(0x14, 19, insn
->src(0));
701 emitInsn(0x50880000);
702 emitPRED(0x0c, insn
->src(0));
707 assert(!"bad src file");
710 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
711 insn
->src(0).getFile() != FILE_PREDICATE
)
712 emitField(0x27, 4, insn
->lanes
);
714 emitInsn (0x01000000);
715 emitIMMD (0x14, 32, insn
->src(0));
716 emitField(0x0c, 4, insn
->lanes
);
719 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
721 emitPRED(0x03, insn
->def(0));
724 emitGPR(0x00, insn
->def(0));
729 CodeEmitterGM107::emitS2R()
731 emitInsn(0xf0c80000);
732 emitSYS (0x14, insn
->src(0));
733 emitGPR (0x00, insn
->def(0));
737 CodeEmitterGM107::emitF2F()
739 RoundMode rnd
= insn
->rnd
;
742 case OP_FLOOR
: rnd
= ROUND_MI
; break;
743 case OP_CEIL
: rnd
= ROUND_PI
; break;
744 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
749 switch (insn
->src(0).getFile()) {
751 emitInsn(0x5ca80000);
752 emitGPR (0x14, insn
->src(0));
754 case FILE_MEMORY_CONST
:
755 emitInsn(0x4ca80000);
756 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
759 emitInsn(0x38a80000);
760 emitIMMD(0x14, 19, insn
->src(0));
763 assert(!"bad src0 file");
767 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
768 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
770 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
772 emitField(0x29, 1, insn
->subOp
);
773 emitRND (0x27, rnd
, 0x2a);
774 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
775 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
776 emitGPR (0x00, insn
->def(0));
780 CodeEmitterGM107::emitF2I()
782 RoundMode rnd
= insn
->rnd
;
785 case OP_FLOOR
: rnd
= ROUND_M
; break;
786 case OP_CEIL
: rnd
= ROUND_P
; break;
787 case OP_TRUNC
: rnd
= ROUND_Z
; break;
792 switch (insn
->src(0).getFile()) {
794 emitInsn(0x5cb00000);
795 emitGPR (0x14, insn
->src(0));
797 case FILE_MEMORY_CONST
:
798 emitInsn(0x4cb00000);
799 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
802 emitInsn(0x38b00000);
803 emitIMMD(0x14, 19, insn
->src(0));
806 assert(!"bad src0 file");
810 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
812 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
814 emitRND (0x27, rnd
, 0x2a);
815 emitField(0x0c, 1, isSignedType(insn
->dType
));
816 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
817 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
818 emitGPR (0x00, insn
->def(0));
822 CodeEmitterGM107::emitI2F()
824 RoundMode rnd
= insn
->rnd
;
827 case OP_FLOOR
: rnd
= ROUND_M
; break;
828 case OP_CEIL
: rnd
= ROUND_P
; break;
829 case OP_TRUNC
: rnd
= ROUND_Z
; break;
834 switch (insn
->src(0).getFile()) {
836 emitInsn(0x5cb80000);
837 emitGPR (0x14, insn
->src(0));
839 case FILE_MEMORY_CONST
:
840 emitInsn(0x4cb80000);
841 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
844 emitInsn(0x38b80000);
845 emitIMMD(0x14, 19, insn
->src(0));
848 assert(!"bad src0 file");
852 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
854 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
855 emitField(0x29, 2, insn
->subOp
);
856 emitRND (0x27, rnd
, -1);
857 emitField(0x0d, 1, isSignedType(insn
->sType
));
858 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
859 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
860 emitGPR (0x00, insn
->def(0));
864 CodeEmitterGM107::emitI2I()
866 switch (insn
->src(0).getFile()) {
868 emitInsn(0x5ce00000);
869 emitGPR (0x14, insn
->src(0));
871 case FILE_MEMORY_CONST
:
872 emitInsn(0x4ce00000);
873 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
876 emitInsn(0x38e00000);
877 emitIMMD(0x14, 19, insn
->src(0));
880 assert(!"bad src0 file");
885 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
887 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
888 emitField(0x29, 2, insn
->subOp
);
889 emitField(0x0d, 1, isSignedType(insn
->sType
));
890 emitField(0x0c, 1, isSignedType(insn
->dType
));
891 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
892 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
893 emitGPR (0x00, insn
->def(0));
897 selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
899 int loc
= entry
->loc
;
900 if (data
.force_persample_interp
)
901 code
[loc
+ 1] |= 1 << 10;
903 code
[loc
+ 1] &= ~(1 << 10);
907 CodeEmitterGM107::emitSEL()
909 switch (insn
->src(1).getFile()) {
911 emitInsn(0x5ca00000);
912 emitGPR (0x14, insn
->src(1));
914 case FILE_MEMORY_CONST
:
915 emitInsn(0x4ca00000);
916 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
919 emitInsn(0x38a00000);
920 emitIMMD(0x14, 19, insn
->src(1));
923 assert(!"bad src1 file");
927 emitINV (0x2a, insn
->src(2));
928 emitPRED(0x27, insn
->src(2));
929 emitGPR (0x08, insn
->src(0));
930 emitGPR (0x00, insn
->def(0));
932 if (insn
->subOp
== 1) {
933 addInterp(0, 0, selpFlip
);
938 CodeEmitterGM107::emitSHFL()
942 emitInsn (0xef100000);
944 switch (insn
->src(1).getFile()) {
946 emitGPR(0x14, insn
->src(1));
949 emitIMMD(0x14, 5, insn
->src(1));
953 assert(!"invalid src1 file");
957 /*XXX: what is this arg? hardcode immediate for now */
958 emitField(0x22, 13, 0x1c03);
962 emitField(0x1e, 2, insn
->subOp
);
963 emitField(0x1c, 2, type
);
964 emitGPR (0x08, insn
->src(0));
965 emitGPR (0x00, insn
->def(0));
968 /*******************************************************************************
970 ******************************************************************************/
973 CodeEmitterGM107::emitDADD()
975 switch (insn
->src(1).getFile()) {
977 emitInsn(0x5c700000);
978 emitGPR (0x14, insn
->src(1));
980 case FILE_MEMORY_CONST
:
981 emitInsn(0x4c700000);
982 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
985 emitInsn(0x38700000);
986 emitIMMD(0x14, 19, insn
->src(1));
989 assert(!"bad src1 file");
992 emitABS(0x31, insn
->src(1));
993 emitNEG(0x30, insn
->src(0));
995 emitABS(0x2e, insn
->src(0));
996 emitNEG(0x2d, insn
->src(1));
998 if (insn
->op
== OP_SUB
)
999 code
[1] ^= 0x00002000;
1001 emitGPR(0x08, insn
->src(0));
1002 emitGPR(0x00, insn
->def(0));
1006 CodeEmitterGM107::emitDMUL()
1008 switch (insn
->src(1).getFile()) {
1010 emitInsn(0x5c800000);
1011 emitGPR (0x14, insn
->src(1));
1013 case FILE_MEMORY_CONST
:
1014 emitInsn(0x4c800000);
1015 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1017 case FILE_IMMEDIATE
:
1018 emitInsn(0x38800000);
1019 emitIMMD(0x14, 19, insn
->src(1));
1022 assert(!"bad src1 file");
1026 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1029 emitGPR (0x08, insn
->src(0));
1030 emitGPR (0x00, insn
->def(0));
1034 CodeEmitterGM107::emitDFMA()
1036 switch(insn
->src(2).getFile()) {
1038 switch (insn
->src(1).getFile()) {
1040 emitInsn(0x5b700000);
1041 emitGPR (0x14, insn
->src(1));
1043 case FILE_MEMORY_CONST
:
1044 emitInsn(0x4b700000);
1045 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1047 case FILE_IMMEDIATE
:
1048 emitInsn(0x36700000);
1049 emitIMMD(0x14, 19, insn
->src(1));
1052 assert(!"bad src1 file");
1055 emitGPR (0x27, insn
->src(2));
1057 case FILE_MEMORY_CONST
:
1058 emitInsn(0x53700000);
1059 emitGPR (0x27, insn
->src(1));
1060 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1063 assert(!"bad src2 file");
1068 emitNEG (0x31, insn
->src(2));
1069 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1071 emitGPR (0x08, insn
->src(0));
1072 emitGPR (0x00, insn
->def(0));
1076 CodeEmitterGM107::emitDMNMX()
1078 switch (insn
->src(1).getFile()) {
1080 emitInsn(0x5c500000);
1081 emitGPR (0x14, insn
->src(1));
1083 case FILE_MEMORY_CONST
:
1084 emitInsn(0x4c500000);
1085 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1087 case FILE_IMMEDIATE
:
1088 emitInsn(0x38500000);
1089 emitIMMD(0x14, 19, insn
->src(1));
1092 assert(!"bad src1 file");
1096 emitABS (0x31, insn
->src(1));
1097 emitNEG (0x30, insn
->src(0));
1099 emitABS (0x2e, insn
->src(0));
1100 emitNEG (0x2d, insn
->src(1));
1101 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1103 emitGPR (0x08, insn
->src(0));
1104 emitGPR (0x00, insn
->def(0));
1108 CodeEmitterGM107::emitDSET()
1110 const CmpInstruction
*insn
= this->insn
->asCmp();
1112 switch (insn
->src(1).getFile()) {
1114 emitInsn(0x59000000);
1115 emitGPR (0x14, insn
->src(1));
1117 case FILE_MEMORY_CONST
:
1118 emitInsn(0x49000000);
1119 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1121 case FILE_IMMEDIATE
:
1122 emitInsn(0x32000000);
1123 emitIMMD(0x14, 19, insn
->src(1));
1126 assert(!"bad src1 file");
1130 if (insn
->op
!= OP_SET
) {
1132 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1133 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1134 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1136 assert(!"invalid set op");
1139 emitPRED(0x27, insn
->src(2));
1144 emitABS (0x36, insn
->src(0));
1145 emitNEG (0x35, insn
->src(1));
1146 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1147 emitCond4(0x30, insn
->setCond
);
1149 emitABS (0x2c, insn
->src(1));
1150 emitNEG (0x2b, insn
->src(0));
1151 emitGPR (0x08, insn
->src(0));
1152 emitGPR (0x00, insn
->def(0));
1156 CodeEmitterGM107::emitDSETP()
1158 const CmpInstruction
*insn
= this->insn
->asCmp();
1160 switch (insn
->src(1).getFile()) {
1162 emitInsn(0x5b800000);
1163 emitGPR (0x14, insn
->src(1));
1165 case FILE_MEMORY_CONST
:
1166 emitInsn(0x4b800000);
1167 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1169 case FILE_IMMEDIATE
:
1170 emitInsn(0x36800000);
1171 emitIMMD(0x14, 19, insn
->src(1));
1174 assert(!"bad src1 file");
1178 if (insn
->op
!= OP_SET
) {
1180 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1181 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1182 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1184 assert(!"invalid set op");
1187 emitPRED(0x27, insn
->src(2));
1192 emitCond4(0x30, insn
->setCond
);
1193 emitABS (0x2c, insn
->src(1));
1194 emitNEG (0x2b, insn
->src(0));
1195 emitGPR (0x08, insn
->src(0));
1196 emitABS (0x07, insn
->src(0));
1197 emitNEG (0x06, insn
->src(1));
1198 emitPRED (0x03, insn
->def(0));
1199 if (insn
->defExists(1))
1200 emitPRED(0x00, insn
->def(1));
1205 /*******************************************************************************
1207 ******************************************************************************/
1210 CodeEmitterGM107::emitFADD()
1212 if (!longIMMD(insn
->src(1))) {
1213 switch (insn
->src(1).getFile()) {
1215 emitInsn(0x5c580000);
1216 emitGPR (0x14, insn
->src(1));
1218 case FILE_MEMORY_CONST
:
1219 emitInsn(0x4c580000);
1220 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1222 case FILE_IMMEDIATE
:
1223 emitInsn(0x38580000);
1224 emitIMMD(0x14, 19, insn
->src(1));
1227 assert(!"bad src1 file");
1231 emitABS(0x31, insn
->src(1));
1232 emitNEG(0x30, insn
->src(0));
1234 emitABS(0x2e, insn
->src(0));
1235 emitNEG(0x2d, insn
->src(1));
1238 emitInsn(0x08000000);
1239 emitABS(0x39, insn
->src(1));
1240 emitNEG(0x38, insn
->src(0));
1242 emitABS(0x36, insn
->src(0));
1243 emitNEG(0x35, insn
->src(1));
1245 emitIMMD(0x14, 32, insn
->src(1));
1248 if (insn
->op
== OP_SUB
)
1249 code
[1] ^= 0x00002000;
1251 emitGPR(0x08, insn
->src(0));
1252 emitGPR(0x00, insn
->def(0));
1256 CodeEmitterGM107::emitFMUL()
1258 if (!longIMMD(insn
->src(1))) {
1259 switch (insn
->src(1).getFile()) {
1261 emitInsn(0x5c680000);
1262 emitGPR (0x14, insn
->src(1));
1264 case FILE_MEMORY_CONST
:
1265 emitInsn(0x4c680000);
1266 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1268 case FILE_IMMEDIATE
:
1269 emitInsn(0x38680000);
1270 emitIMMD(0x14, 19, insn
->src(1));
1273 assert(!"bad src1 file");
1277 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1283 emitInsn(0x1e000000);
1287 emitIMMD(0x14, 32, insn
->src(1));
1288 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1289 code
[1] ^= 0x00080000; /* flip immd sign bit */
1292 emitGPR(0x08, insn
->src(0));
1293 emitGPR(0x00, insn
->def(0));
1297 CodeEmitterGM107::emitFFMA()
1299 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1300 switch(insn
->src(2).getFile()) {
1302 switch (insn
->src(1).getFile()) {
1304 emitInsn(0x59800000);
1305 emitGPR (0x14, insn
->src(1));
1307 case FILE_MEMORY_CONST
:
1308 emitInsn(0x49800000);
1309 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1311 case FILE_IMMEDIATE
:
1312 emitInsn(0x32800000);
1313 emitIMMD(0x14, 19, insn
->src(1));
1316 assert(!"bad src1 file");
1319 emitGPR (0x27, insn
->src(2));
1321 case FILE_MEMORY_CONST
:
1322 emitInsn(0x51800000);
1323 emitGPR (0x27, insn
->src(1));
1324 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1327 assert(!"bad src2 file");
1332 emitNEG (0x31, insn
->src(2));
1333 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1337 emitGPR(0x08, insn
->src(0));
1338 emitGPR(0x00, insn
->def(0));
1342 CodeEmitterGM107::emitMUFU()
1347 case OP_COS
: mufu
= 0; break;
1348 case OP_SIN
: mufu
= 1; break;
1349 case OP_EX2
: mufu
= 2; break;
1350 case OP_LG2
: mufu
= 3; break;
1351 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1352 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1354 assert(!"invalid mufu");
1358 emitInsn (0x50800000);
1360 emitNEG (0x30, insn
->src(0));
1361 emitABS (0x2e, insn
->src(0));
1362 emitField(0x14, 3, mufu
);
1363 emitGPR (0x08, insn
->src(0));
1364 emitGPR (0x00, insn
->def(0));
1368 CodeEmitterGM107::emitFMNMX()
1370 switch (insn
->src(1).getFile()) {
1372 emitInsn(0x5c600000);
1373 emitGPR (0x14, insn
->src(1));
1375 case FILE_MEMORY_CONST
:
1376 emitInsn(0x4c600000);
1377 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1379 case FILE_IMMEDIATE
:
1380 emitInsn(0x38600000);
1381 emitIMMD(0x14, 19, insn
->src(1));
1384 assert(!"bad src1 file");
1388 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1391 emitABS(0x31, insn
->src(1));
1392 emitNEG(0x30, insn
->src(0));
1394 emitABS(0x2e, insn
->src(0));
1395 emitNEG(0x2d, insn
->src(1));
1397 emitGPR(0x08, insn
->src(0));
1398 emitGPR(0x00, insn
->def(0));
1402 CodeEmitterGM107::emitRRO()
1404 switch (insn
->src(0).getFile()) {
1406 emitInsn(0x5c900000);
1407 emitGPR (0x14, insn
->src(0));
1409 case FILE_MEMORY_CONST
:
1410 emitInsn(0x4c900000);
1411 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1413 case FILE_IMMEDIATE
:
1414 emitInsn(0x38900000);
1415 emitIMMD(0x14, 19, insn
->src(0));
1418 assert(!"bad src file");
1422 emitABS (0x31, insn
->src(0));
1423 emitNEG (0x2d, insn
->src(0));
1424 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1425 emitGPR (0x00, insn
->def(0));
1429 CodeEmitterGM107::emitFCMP()
1431 const CmpInstruction
*insn
= this->insn
->asCmp();
1432 CondCode cc
= insn
->setCond
;
1434 if (insn
->src(2).mod
.neg())
1435 cc
= reverseCondCode(cc
);
1437 switch(insn
->src(2).getFile()) {
1439 switch (insn
->src(1).getFile()) {
1441 emitInsn(0x5ba00000);
1442 emitGPR (0x14, insn
->src(1));
1444 case FILE_MEMORY_CONST
:
1445 emitInsn(0x4ba00000);
1446 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1448 case FILE_IMMEDIATE
:
1449 emitInsn(0x36a00000);
1450 emitIMMD(0x14, 19, insn
->src(1));
1453 assert(!"bad src1 file");
1456 emitGPR (0x27, insn
->src(2));
1458 case FILE_MEMORY_CONST
:
1459 emitInsn(0x53a00000);
1460 emitGPR (0x27, insn
->src(1));
1461 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1464 assert(!"bad src2 file");
1468 emitCond4(0x30, cc
);
1470 emitGPR (0x08, insn
->src(0));
1471 emitGPR (0x00, insn
->def(0));
1475 CodeEmitterGM107::emitFSET()
1477 const CmpInstruction
*insn
= this->insn
->asCmp();
1479 switch (insn
->src(1).getFile()) {
1481 emitInsn(0x58000000);
1482 emitGPR (0x14, insn
->src(1));
1484 case FILE_MEMORY_CONST
:
1485 emitInsn(0x48000000);
1486 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1488 case FILE_IMMEDIATE
:
1489 emitInsn(0x30000000);
1490 emitIMMD(0x14, 19, insn
->src(1));
1493 assert(!"bad src1 file");
1497 if (insn
->op
!= OP_SET
) {
1499 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1500 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1501 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1503 assert(!"invalid set op");
1506 emitPRED(0x27, insn
->src(2));
1512 emitABS (0x36, insn
->src(0));
1513 emitNEG (0x35, insn
->src(1));
1514 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1515 emitCond4(0x30, insn
->setCond
);
1517 emitABS (0x2c, insn
->src(1));
1518 emitNEG (0x2b, insn
->src(0));
1519 emitGPR (0x08, insn
->src(0));
1520 emitGPR (0x00, insn
->def(0));
1524 CodeEmitterGM107::emitFSETP()
1526 const CmpInstruction
*insn
= this->insn
->asCmp();
1528 switch (insn
->src(1).getFile()) {
1530 emitInsn(0x5bb00000);
1531 emitGPR (0x14, insn
->src(1));
1533 case FILE_MEMORY_CONST
:
1534 emitInsn(0x4bb00000);
1535 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1537 case FILE_IMMEDIATE
:
1538 emitInsn(0x36b00000);
1539 emitIMMD(0x14, 19, insn
->src(1));
1542 assert(!"bad src1 file");
1546 if (insn
->op
!= OP_SET
) {
1548 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1549 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1550 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1552 assert(!"invalid set op");
1555 emitPRED(0x27, insn
->src(2));
1560 emitCond4(0x30, insn
->setCond
);
1562 emitABS (0x2c, insn
->src(1));
1563 emitNEG (0x2b, insn
->src(0));
1564 emitGPR (0x08, insn
->src(0));
1565 emitABS (0x07, insn
->src(0));
1566 emitNEG (0x06, insn
->src(1));
1567 emitPRED (0x03, insn
->def(0));
1568 if (insn
->defExists(1))
1569 emitPRED(0x00, insn
->def(1));
1575 CodeEmitterGM107::emitFSWZADD()
1577 emitInsn (0x50f80000);
1581 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1582 emitField(0x1c, 8, insn
->subOp
);
1583 if (insn
->predSrc
!= 1)
1584 emitGPR (0x14, insn
->src(1));
1587 emitGPR (0x08, insn
->src(0));
1588 emitGPR (0x00, insn
->def(0));
1591 /*******************************************************************************
1593 ******************************************************************************/
1596 CodeEmitterGM107::emitLOP()
1601 case OP_AND
: lop
= 0; break;
1602 case OP_OR
: lop
= 1; break;
1603 case OP_XOR
: lop
= 2; break;
1605 assert(!"invalid lop");
1609 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1610 switch (insn
->src(1).getFile()) {
1612 emitInsn(0x5c400000);
1613 emitGPR (0x14, insn
->src(1));
1615 case FILE_MEMORY_CONST
:
1616 emitInsn(0x4c400000);
1617 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1619 case FILE_IMMEDIATE
:
1620 emitInsn(0x38400000);
1621 emitIMMD(0x14, 19, insn
->src(1));
1624 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
);
1640 emitIMMD (0x14, 32, insn
->src(1));
1643 emitGPR (0x08, insn
->src(0));
1644 emitGPR (0x00, insn
->def(0));
1647 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1649 CodeEmitterGM107::emitNOT()
1651 if (!longIMMD(insn
->src(0))) {
1652 switch (insn
->src(0).getFile()) {
1654 emitInsn(0x5c400700);
1655 emitGPR (0x14, insn
->src(0));
1657 case FILE_MEMORY_CONST
:
1658 emitInsn(0x4c400700);
1659 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1661 case FILE_IMMEDIATE
:
1662 emitInsn(0x38400700);
1663 emitIMMD(0x14, 19, insn
->src(0));
1666 assert(!"bad src1 file");
1671 emitInsn (0x05600000);
1672 emitIMMD (0x14, 32, insn
->src(1));
1676 emitGPR(0x00, insn
->def(0));
1680 CodeEmitterGM107::emitIADD()
1682 if (!longIMMD(insn
->src(1))) {
1683 switch (insn
->src(1).getFile()) {
1685 emitInsn(0x5c100000);
1686 emitGPR (0x14, insn
->src(1));
1688 case FILE_MEMORY_CONST
:
1689 emitInsn(0x4c100000);
1690 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1692 case FILE_IMMEDIATE
:
1693 emitInsn(0x38100000);
1694 emitIMMD(0x14, 19, insn
->src(1));
1697 assert(!"bad src1 file");
1701 emitNEG(0x31, insn
->src(0));
1702 emitNEG(0x30, insn
->src(1));
1706 emitInsn(0x1c000000);
1710 emitIMMD(0x14, 32, insn
->src(1));
1713 if (insn
->op
== OP_SUB
)
1714 code
[1] ^= 0x00010000;
1716 emitGPR(0x08, insn
->src(0));
1717 emitGPR(0x00, insn
->def(0));
1721 CodeEmitterGM107::emitIMUL()
1723 if (insn
->src(1).getFile() != FILE_IMMEDIATE
) {
1724 switch (insn
->src(1).getFile()) {
1726 emitInsn(0x5c380000);
1727 emitGPR (0x14, insn
->src(1));
1729 case FILE_MEMORY_CONST
:
1730 emitInsn(0x4c380000);
1731 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1733 case FILE_IMMEDIATE
:
1734 emitInsn(0x38380000);
1735 emitIMMD(0x14, 19, insn
->src(1));
1738 assert(!"bad src1 file");
1742 emitField(0x29, 1, isSignedType(insn
->sType
));
1743 emitField(0x28, 1, isSignedType(insn
->dType
));
1744 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1746 emitInsn (0x1f000000);
1747 emitField(0x37, 1, isSignedType(insn
->sType
));
1748 emitField(0x36, 1, isSignedType(insn
->dType
));
1749 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1751 emitIMMD (0x14, 32, insn
->src(1));
1754 emitGPR(0x08, insn
->src(0));
1755 emitGPR(0x00, insn
->def(0));
1759 CodeEmitterGM107::emitIMAD()
1761 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1762 switch(insn
->src(2).getFile()) {
1764 switch (insn
->src(1).getFile()) {
1766 emitInsn(0x5a000000);
1767 emitGPR (0x14, insn
->src(1));
1769 case FILE_MEMORY_CONST
:
1770 emitInsn(0x4a000000);
1771 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1773 case FILE_IMMEDIATE
:
1774 emitInsn(0x34000000);
1775 emitIMMD(0x14, 19, insn
->src(1));
1778 assert(!"bad src1 file");
1781 emitGPR (0x27, insn
->src(2));
1783 case FILE_MEMORY_CONST
:
1784 emitInsn(0x52000000);
1785 emitGPR (0x27, insn
->src(1));
1786 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1789 assert(!"bad src2 file");
1793 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1794 emitField(0x35, 1, isSignedType(insn
->sType
));
1795 emitNEG (0x34, insn
->src(2));
1796 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1799 emitField(0x30, 1, isSignedType(insn
->dType
));
1801 emitGPR (0x08, insn
->src(0));
1802 emitGPR (0x00, insn
->def(0));
1806 CodeEmitterGM107::emitIMNMX()
1808 switch (insn
->src(1).getFile()) {
1810 emitInsn(0x5c200000);
1811 emitGPR (0x14, insn
->src(1));
1813 case FILE_MEMORY_CONST
:
1814 emitInsn(0x4c200000);
1815 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1817 case FILE_IMMEDIATE
:
1818 emitInsn(0x38200000);
1819 emitIMMD(0x14, 19, insn
->src(1));
1822 assert(!"bad src1 file");
1826 emitField(0x30, 1, isSignedType(insn
->dType
));
1828 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1830 emitGPR (0x08, insn
->src(0));
1831 emitGPR (0x00, insn
->def(0));
1835 CodeEmitterGM107::emitICMP()
1837 const CmpInstruction
*insn
= this->insn
->asCmp();
1838 CondCode cc
= insn
->setCond
;
1840 if (insn
->src(2).mod
.neg())
1841 cc
= reverseCondCode(cc
);
1843 switch(insn
->src(2).getFile()) {
1845 switch (insn
->src(1).getFile()) {
1847 emitInsn(0x5b400000);
1848 emitGPR (0x14, insn
->src(1));
1850 case FILE_MEMORY_CONST
:
1851 emitInsn(0x4b400000);
1852 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1854 case FILE_IMMEDIATE
:
1855 emitInsn(0x36400000);
1856 emitIMMD(0x14, 19, insn
->src(1));
1859 assert(!"bad src1 file");
1862 emitGPR (0x27, insn
->src(2));
1864 case FILE_MEMORY_CONST
:
1865 emitInsn(0x53400000);
1866 emitGPR (0x27, insn
->src(1));
1867 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1870 assert(!"bad src2 file");
1874 emitCond3(0x31, cc
);
1875 emitField(0x30, 1, isSignedType(insn
->sType
));
1876 emitGPR (0x08, insn
->src(0));
1877 emitGPR (0x00, insn
->def(0));
1881 CodeEmitterGM107::emitISET()
1883 const CmpInstruction
*insn
= this->insn
->asCmp();
1885 switch (insn
->src(1).getFile()) {
1887 emitInsn(0x5b500000);
1888 emitGPR (0x14, insn
->src(1));
1890 case FILE_MEMORY_CONST
:
1891 emitInsn(0x4b500000);
1892 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1894 case FILE_IMMEDIATE
:
1895 emitInsn(0x36500000);
1896 emitIMMD(0x14, 19, insn
->src(1));
1899 assert(!"bad src1 file");
1903 if (insn
->op
!= OP_SET
) {
1905 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1906 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1907 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1909 assert(!"invalid set op");
1912 emitPRED(0x27, insn
->src(2));
1917 emitCond3(0x31, insn
->setCond
);
1918 emitField(0x30, 1, isSignedType(insn
->sType
));
1920 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1922 emitGPR (0x08, insn
->src(0));
1923 emitGPR (0x00, insn
->def(0));
1927 CodeEmitterGM107::emitISETP()
1929 const CmpInstruction
*insn
= this->insn
->asCmp();
1931 switch (insn
->src(1).getFile()) {
1933 emitInsn(0x5b600000);
1934 emitGPR (0x14, insn
->src(1));
1936 case FILE_MEMORY_CONST
:
1937 emitInsn(0x4b600000);
1938 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1940 case FILE_IMMEDIATE
:
1941 emitInsn(0x36600000);
1942 emitIMMD(0x14, 19, insn
->src(1));
1945 assert(!"bad src1 file");
1949 if (insn
->op
!= OP_SET
) {
1951 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1952 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1953 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1955 assert(!"invalid set op");
1958 emitPRED(0x27, insn
->src(2));
1963 emitCond3(0x31, insn
->setCond
);
1964 emitField(0x30, 1, isSignedType(insn
->sType
));
1966 emitGPR (0x08, insn
->src(0));
1967 emitPRED (0x03, insn
->def(0));
1968 if (insn
->defExists(1))
1969 emitPRED(0x00, insn
->def(1));
1975 CodeEmitterGM107::emitSHL()
1977 switch (insn
->src(1).getFile()) {
1979 emitInsn(0x5c480000);
1980 emitGPR (0x14, insn
->src(1));
1982 case FILE_MEMORY_CONST
:
1983 emitInsn(0x4c480000);
1984 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1986 case FILE_IMMEDIATE
:
1987 emitInsn(0x38480000);
1988 emitIMMD(0x14, 19, insn
->src(1));
1991 assert(!"bad src1 file");
1997 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1998 emitGPR (0x08, insn
->src(0));
1999 emitGPR (0x00, insn
->def(0));
2003 CodeEmitterGM107::emitSHR()
2005 switch (insn
->src(1).getFile()) {
2007 emitInsn(0x5c280000);
2008 emitGPR (0x14, insn
->src(1));
2010 case FILE_MEMORY_CONST
:
2011 emitInsn(0x4c280000);
2012 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2014 case FILE_IMMEDIATE
:
2015 emitInsn(0x38280000);
2016 emitIMMD(0x14, 19, insn
->src(1));
2019 assert(!"bad src1 file");
2023 emitField(0x30, 1, isSignedType(insn
->dType
));
2026 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2027 emitGPR (0x08, insn
->src(0));
2028 emitGPR (0x00, insn
->def(0));
2032 CodeEmitterGM107::emitPOPC()
2034 switch (insn
->src(0).getFile()) {
2036 emitInsn(0x5c080000);
2037 emitGPR (0x14, insn
->src(0));
2039 case FILE_MEMORY_CONST
:
2040 emitInsn(0x4c080000);
2041 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2043 case FILE_IMMEDIATE
:
2044 emitInsn(0x38080000);
2045 emitIMMD(0x14, 19, insn
->src(0));
2048 assert(!"bad src1 file");
2052 emitINV(0x28, insn
->src(0));
2053 emitGPR(0x00, insn
->def(0));
2057 CodeEmitterGM107::emitBFI()
2059 switch(insn
->src(2).getFile()) {
2061 switch (insn
->src(1).getFile()) {
2063 emitInsn(0x5bf00000);
2064 emitGPR (0x14, insn
->src(1));
2066 case FILE_MEMORY_CONST
:
2067 emitInsn(0x4bf00000);
2068 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2070 case FILE_IMMEDIATE
:
2071 emitInsn(0x36f00000);
2072 emitIMMD(0x14, 19, insn
->src(1));
2075 assert(!"bad src1 file");
2078 emitGPR (0x27, insn
->src(2));
2080 case FILE_MEMORY_CONST
:
2081 emitInsn(0x53f00000);
2082 emitGPR (0x27, insn
->src(1));
2083 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2086 assert(!"bad src2 file");
2091 emitGPR (0x08, insn
->src(0));
2092 emitGPR (0x00, insn
->def(0));
2096 CodeEmitterGM107::emitBFE()
2098 switch (insn
->src(1).getFile()) {
2100 emitInsn(0x5c000000);
2101 emitGPR (0x14, insn
->src(1));
2103 case FILE_MEMORY_CONST
:
2104 emitInsn(0x4c000000);
2105 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2107 case FILE_IMMEDIATE
:
2108 emitInsn(0x38000000);
2109 emitIMMD(0x14, 19, insn
->src(1));
2112 assert(!"bad src1 file");
2116 emitField(0x30, 1, isSignedType(insn
->dType
));
2118 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2119 emitGPR (0x08, insn
->src(0));
2120 emitGPR (0x00, insn
->def(0));
2124 CodeEmitterGM107::emitFLO()
2126 switch (insn
->src(0).getFile()) {
2128 emitInsn(0x5c300000);
2129 emitGPR (0x14, insn
->src(0));
2131 case FILE_MEMORY_CONST
:
2132 emitInsn(0x4c300000);
2133 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2135 case FILE_IMMEDIATE
:
2136 emitInsn(0x38300000);
2137 emitIMMD(0x14, 19, insn
->src(0));
2140 assert(!"bad src1 file");
2144 emitField(0x30, 1, isSignedType(insn
->dType
));
2146 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2147 emitINV (0x28, insn
->src(0));
2148 emitGPR (0x00, insn
->def(0));
2151 /*******************************************************************************
2153 ******************************************************************************/
2156 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2160 switch (typeSizeof(type
)) {
2161 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2162 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2163 case 4: data
= 4; break;
2164 case 8: data
= 5; break;
2165 case 16: data
= 6; break;
2167 assert(!"bad type");
2171 emitField(pos
, 3, data
);
2175 CodeEmitterGM107::emitLDSTc(int pos
)
2179 switch (insn
->cache
) {
2180 case CACHE_CA
: mode
= 0; break;
2181 case CACHE_CG
: mode
= 1; break;
2182 case CACHE_CS
: mode
= 2; break;
2183 case CACHE_CV
: mode
= 3; break;
2185 assert(!"invalid caching mode");
2189 emitField(pos
, 2, mode
);
2193 CodeEmitterGM107::emitLDC()
2195 emitInsn (0xef900000);
2196 emitLDSTs(0x30, insn
->dType
);
2197 emitField(0x2c, 2, insn
->subOp
);
2198 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2199 emitGPR (0x00, insn
->def(0));
2203 CodeEmitterGM107::emitLDL()
2205 emitInsn (0xef400000);
2206 emitLDSTs(0x30, insn
->dType
);
2208 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2209 emitGPR (0x00, insn
->def(0));
2213 CodeEmitterGM107::emitLDS()
2215 emitInsn (0xef480000);
2216 emitLDSTs(0x30, insn
->dType
);
2217 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2218 emitGPR (0x00, insn
->def(0));
2222 CodeEmitterGM107::emitLD()
2224 emitInsn (0x80000000);
2227 emitLDSTs(0x35, insn
->dType
);
2228 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2229 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2230 emitGPR (0x00, insn
->def(0));
2234 CodeEmitterGM107::emitSTL()
2236 emitInsn (0xef500000);
2237 emitLDSTs(0x30, insn
->dType
);
2239 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2240 emitGPR (0x00, insn
->src(1));
2244 CodeEmitterGM107::emitSTS()
2246 emitInsn (0xef580000);
2247 emitLDSTs(0x30, insn
->dType
);
2248 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2249 emitGPR (0x00, insn
->src(1));
2253 CodeEmitterGM107::emitST()
2255 emitInsn (0xa0000000);
2258 emitLDSTs(0x35, insn
->dType
);
2259 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2260 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2261 emitGPR (0x00, insn
->src(1));
2265 CodeEmitterGM107::emitALD()
2267 emitInsn (0xefd80000);
2268 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2269 emitGPR (0x27, insn
->src(0).getIndirect(1));
2272 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2273 emitGPR (0x00, insn
->def(0));
2277 CodeEmitterGM107::emitAST()
2279 emitInsn (0xeff00000);
2280 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2281 emitGPR (0x27, insn
->src(0).getIndirect(1));
2283 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2284 emitGPR (0x00, insn
->src(1));
2288 CodeEmitterGM107::emitISBERD()
2290 emitInsn(0xefd00000);
2291 emitGPR (0x08, insn
->src(0));
2292 emitGPR (0x00, insn
->def(0));
2296 CodeEmitterGM107::emitAL2P()
2298 emitInsn (0xefa00000);
2299 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2301 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2302 emitGPR (0x08, insn
->src(0).getIndirect(0));
2303 emitGPR (0x00, insn
->def(0));
2307 interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2309 int ipa
= entry
->ipa
;
2310 int reg
= entry
->reg
;
2311 int loc
= entry
->loc
;
2313 if (data
.flatshade
&&
2314 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2315 ipa
= NV50_IR_INTERP_FLAT
;
2317 } else if (data
.force_persample_interp
&&
2318 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2319 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2320 ipa
|= NV50_IR_INTERP_CENTROID
;
2322 code
[loc
+ 1] &= ~(0xf << 0x14);
2323 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2324 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2325 code
[loc
+ 0] &= ~(0xff << 0x14);
2326 code
[loc
+ 0] |= reg
<< 0x14;
2330 CodeEmitterGM107::emitIPA()
2332 int ipam
= 0, ipas
= 0;
2334 switch (insn
->getInterpMode()) {
2335 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2336 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2337 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2338 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2340 assert(!"invalid ipa mode");
2344 switch (insn
->getSampleMode()) {
2345 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2346 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2347 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2349 assert(!"invalid ipa sample mode");
2353 emitInsn (0xe0000000);
2354 emitField(0x36, 2, ipam
);
2355 emitField(0x34, 2, ipas
);
2357 emitField(0x2f, 3, 7);
2358 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2359 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2360 code
[1] |= 0x00000040; /* .idx */
2361 emitGPR(0x00, insn
->def(0));
2363 if (insn
->op
== OP_PINTERP
) {
2364 emitGPR(0x14, insn
->src(1));
2365 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2366 emitGPR(0x27, insn
->src(2));
2367 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2369 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2370 emitGPR(0x27, insn
->src(1));
2372 addInterp(insn
->ipa
, 0xff, interpApply
);
2375 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2380 CodeEmitterGM107::emitATOM()
2382 unsigned dType
, subOp
;
2384 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2385 switch (insn
->dType
) {
2386 case TYPE_U32
: dType
= 0; break;
2387 case TYPE_U64
: dType
= 1; break;
2388 default: assert(!"unexpected dType"); dType
= 0; break;
2392 emitInsn (0xee000000);
2394 switch (insn
->dType
) {
2395 case TYPE_U32
: dType
= 0; break;
2396 case TYPE_S32
: dType
= 1; break;
2397 case TYPE_U64
: dType
= 2; break;
2398 case TYPE_F32
: dType
= 3; break;
2399 case TYPE_B128
: dType
= 4; break;
2400 case TYPE_S64
: dType
= 5; break;
2401 default: assert(!"unexpected dType"); dType
= 0; break;
2403 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2406 subOp
= insn
->subOp
;
2408 emitInsn (0xed000000);
2411 emitField(0x34, 4, subOp
);
2412 emitField(0x31, 3, dType
);
2413 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2414 emitGPR (0x14, insn
->src(1));
2415 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2416 emitGPR (0x00, insn
->def(0));
2420 CodeEmitterGM107::emitATOMS()
2422 unsigned dType
, subOp
;
2424 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2425 switch (insn
->dType
) {
2426 case TYPE_U32
: dType
= 0; break;
2427 case TYPE_U64
: dType
= 1; break;
2428 default: assert(!"unexpected dType"); dType
= 0; break;
2432 emitInsn (0xee000000);
2433 emitField(0x34, 1, dType
);
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_S64
: dType
= 3; break;
2440 default: assert(!"unexpected dType"); dType
= 0; break;
2443 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2446 subOp
= insn
->subOp
;
2448 emitInsn (0xec000000);
2449 emitField(0x1c, 3, dType
);
2452 emitField(0x34, 4, subOp
);
2453 emitGPR (0x14, insn
->src(1));
2454 emitADDR (0x08, 0x12, 22, 0, insn
->src(0));
2455 emitGPR (0x00, insn
->def(0));
2459 CodeEmitterGM107::emitCCTL()
2462 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2463 emitInsn(0xef600000);
2466 emitInsn(0xef800000);
2469 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2470 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2471 emitField(0x00, 4, insn
->subOp
);
2474 /*******************************************************************************
2476 ******************************************************************************/
2479 CodeEmitterGM107::emitPIXLD()
2481 emitInsn (0xefe80000);
2483 emitField(0x1f, 3, insn
->subOp
);
2484 emitGPR (0x08, insn
->src(0));
2485 emitGPR (0x00, insn
->def(0));
2488 /*******************************************************************************
2490 ******************************************************************************/
2493 CodeEmitterGM107::emitTEXs(int pos
)
2495 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2496 if (insn
->srcExists(src1
))
2497 emitGPR(pos
, insn
->src(src1
));
2503 CodeEmitterGM107::emitTEX()
2505 const TexInstruction
*insn
= this->insn
->asTex();
2508 if (!insn
->tex
.levelZero
) {
2510 case OP_TEX
: lodm
= 0; break;
2511 case OP_TXB
: lodm
= 2; break;
2512 case OP_TXL
: lodm
= 3; break;
2514 assert(!"invalid tex op");
2521 if (insn
->tex
.rIndirectSrc
>= 0) {
2522 emitInsn (0xdeb80000);
2523 emitField(0x35, 2, lodm
);
2524 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2526 emitInsn (0xc0380000);
2527 emitField(0x37, 2, lodm
);
2528 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2529 emitField(0x24, 13, insn
->tex
.r
);
2532 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2533 emitField(0x31, 1, insn
->tex
.liveOnly
);
2534 emitField(0x23, 1, insn
->tex
.derivAll
);
2535 emitField(0x1f, 4, insn
->tex
.mask
);
2536 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2537 insn
->tex
.target
.getDim() - 1);
2538 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2540 emitGPR (0x08, insn
->src(0));
2541 emitGPR (0x00, insn
->def(0));
2545 CodeEmitterGM107::emitTLD()
2547 const TexInstruction
*insn
= this->insn
->asTex();
2549 if (insn
->tex
.rIndirectSrc
>= 0) {
2550 emitInsn (0xdd380000);
2552 emitInsn (0xdc380000);
2553 emitField(0x24, 13, insn
->tex
.r
);
2556 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2557 emitField(0x32, 1, insn
->tex
.target
.isMS());
2558 emitField(0x31, 1, insn
->tex
.liveOnly
);
2559 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2560 emitField(0x1f, 4, insn
->tex
.mask
);
2561 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2562 insn
->tex
.target
.getDim() - 1);
2563 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2565 emitGPR (0x08, insn
->src(0));
2566 emitGPR (0x00, insn
->def(0));
2570 CodeEmitterGM107::emitTLD4()
2572 const TexInstruction
*insn
= this->insn
->asTex();
2574 if (insn
->tex
.rIndirectSrc
>= 0) {
2575 emitInsn (0xdef80000);
2576 emitField(0x26, 2, insn
->tex
.gatherComp
);
2577 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2578 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2580 emitInsn (0xc8380000);
2581 emitField(0x38, 2, insn
->tex
.gatherComp
);
2582 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2583 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2584 emitField(0x24, 13, insn
->tex
.r
);
2587 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2588 emitField(0x31, 1, insn
->tex
.liveOnly
);
2589 emitField(0x23, 1, insn
->tex
.derivAll
);
2590 emitField(0x1f, 4, insn
->tex
.mask
);
2591 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2592 insn
->tex
.target
.getDim() - 1);
2593 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2595 emitGPR (0x08, insn
->src(0));
2596 emitGPR (0x00, insn
->def(0));
2600 CodeEmitterGM107::emitTXD()
2602 const TexInstruction
*insn
= this->insn
->asTex();
2604 if (insn
->tex
.rIndirectSrc
>= 0) {
2605 emitInsn (0xde780000);
2607 emitInsn (0xde380000);
2608 emitField(0x24, 13, insn
->tex
.r
);
2611 emitField(0x31, 1, insn
->tex
.liveOnly
);
2612 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2613 emitField(0x1f, 4, insn
->tex
.mask
);
2614 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2615 insn
->tex
.target
.getDim() - 1);
2616 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2618 emitGPR (0x08, insn
->src(0));
2619 emitGPR (0x00, insn
->def(0));
2623 CodeEmitterGM107::emitTMML()
2625 const TexInstruction
*insn
= this->insn
->asTex();
2627 if (insn
->tex
.rIndirectSrc
>= 0) {
2628 emitInsn (0xdf600000);
2630 emitInsn (0xdf580000);
2631 emitField(0x24, 13, insn
->tex
.r
);
2634 emitField(0x31, 1, insn
->tex
.liveOnly
);
2635 emitField(0x23, 1, insn
->tex
.derivAll
);
2636 emitField(0x1f, 4, insn
->tex
.mask
);
2637 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2638 insn
->tex
.target
.getDim() - 1);
2639 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2641 emitGPR (0x08, insn
->src(0));
2642 emitGPR (0x00, insn
->def(0));
2646 CodeEmitterGM107::emitTXQ()
2648 const TexInstruction
*insn
= this->insn
->asTex();
2651 switch (insn
->tex
.query
) {
2652 case TXQ_DIMS
: type
= 0x01; break;
2653 case TXQ_TYPE
: type
= 0x02; break;
2654 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2655 case TXQ_FILTER
: type
= 0x10; break;
2656 case TXQ_LOD
: type
= 0x12; break;
2657 case TXQ_WRAP
: type
= 0x14; break;
2658 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2660 assert(!"invalid txq query");
2664 if (insn
->tex
.rIndirectSrc
>= 0) {
2665 emitInsn (0xdf500000);
2667 emitInsn (0xdf480000);
2668 emitField(0x24, 13, insn
->tex
.r
);
2671 emitField(0x31, 1, insn
->tex
.liveOnly
);
2672 emitField(0x1f, 4, insn
->tex
.mask
);
2673 emitField(0x16, 6, type
);
2674 emitGPR (0x08, insn
->src(0));
2675 emitGPR (0x00, insn
->def(0));
2679 CodeEmitterGM107::emitDEPBAR()
2681 emitInsn (0xf0f00000);
2682 emitField(0x1d, 1, 1); /* le */
2683 emitField(0x1a, 3, 5);
2684 emitField(0x14, 6, insn
->subOp
);
2685 emitField(0x00, 6, insn
->subOp
);
2688 /*******************************************************************************
2690 ******************************************************************************/
2693 CodeEmitterGM107::emitNOP()
2695 emitInsn(0x50b00000);
2699 CodeEmitterGM107::emitKIL()
2701 emitInsn (0xe3300000);
2702 emitCond5(0x00, CC_TR
);
2706 CodeEmitterGM107::emitOUT()
2708 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2709 const int emit
= insn
->op
== OP_EMIT
;
2711 switch (insn
->src(1).getFile()) {
2713 emitInsn(0xfbe00000);
2714 emitGPR (0x14, insn
->src(1));
2716 case FILE_IMMEDIATE
:
2717 emitInsn(0xf6e00000);
2718 emitIMMD(0x14, 19, insn
->src(1));
2720 case FILE_MEMORY_CONST
:
2721 emitInsn(0xebe00000);
2722 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2725 assert(!"bad src1 file");
2729 emitField(0x27, 2, (cut
<< 1) | emit
);
2730 emitGPR (0x08, insn
->src(0));
2731 emitGPR (0x00, insn
->def(0));
2735 CodeEmitterGM107::emitBAR()
2739 emitInsn (0xf0a80000);
2741 switch (insn
->subOp
) {
2742 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
2743 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
2744 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
2745 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
2748 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
2752 emitField(0x20, 8, subop
);
2755 if (insn
->src(0).getFile() == FILE_GPR
) {
2756 emitGPR(0x08, insn
->src(0));
2758 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2760 emitField(0x08, 8, imm
->reg
.data
.u32
);
2761 emitField(0x2b, 1, 1);
2765 if (insn
->src(1).getFile() == FILE_GPR
) {
2766 emitGPR(0x14, insn
->src(1));
2768 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
2770 emitField(0x14, 12, imm
->reg
.data
.u32
);
2771 emitField(0x2c, 1, 1);
2774 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
2775 emitPRED (0x27, insn
->src(2));
2776 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
2778 emitField(0x27, 3, 7);
2783 CodeEmitterGM107::emitMEMBAR()
2785 emitInsn (0xef980000);
2786 emitField(0x08, 2, insn
->subOp
>> 2);
2790 CodeEmitterGM107::emitVOTE()
2792 assert(insn
->src(0).getFile() == FILE_PREDICATE
);
2795 for (int i
= 0; insn
->defExists(i
); i
++) {
2796 if (insn
->def(i
).getFile() == FILE_GPR
)
2798 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
2802 emitInsn (0x50d80000);
2803 emitField(0x30, 2, insn
->subOp
);
2805 emitGPR (0x00, insn
->def(r
));
2809 emitPRED (0x2d, insn
->def(p
));
2812 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
2813 emitPRED (0x27, insn
->src(0));
2816 /*******************************************************************************
2817 * assembler front-end
2818 ******************************************************************************/
2821 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2823 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2828 if (insn
->encSize
!= 8) {
2829 ERROR("skipping undecodable instruction: "); insn
->print();
2832 if (codeSize
+ size
> codeSizeLimit
) {
2833 ERROR("code emitter output buffer too small\n");
2837 if (writeIssueDelays
) {
2838 int n
= ((codeSize
& 0x1f) / 8) - 1;
2841 data
[0] = 0x00000000;
2842 data
[1] = 0x00000000;
2848 emitField(data
, n
* 21, 21, insn
->sched
);
2904 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
2905 insn
->src(0).getFile() == FILE_PREDICATE
)) {
2907 } else if (isFloatType(insn
->dType
)) {
2908 if (isFloatType(insn
->sType
))
2913 if (isFloatType(insn
->sType
))
2924 if (isFloatType(insn
->dType
)) {
2925 if (insn
->dType
== TYPE_F64
)
2934 if (isFloatType(insn
->dType
)) {
2935 if (insn
->dType
== TYPE_F64
)
2945 if (isFloatType(insn
->dType
)) {
2946 if (insn
->dType
== TYPE_F64
)
2956 if (isFloatType(insn
->dType
)) {
2957 if (insn
->dType
== TYPE_F64
)
2984 if (isFloatType(insn
->dType
))
2993 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2994 if (isFloatType(insn
->sType
))
2995 if (insn
->sType
== TYPE_F64
)
3002 if (isFloatType(insn
->sType
))
3003 if (insn
->sType
== TYPE_F64
)
3035 switch (insn
->src(0).getFile()) {
3036 case FILE_MEMORY_CONST
: emitLDC(); break;
3037 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3038 case FILE_MEMORY_SHARED
: emitLDS(); break;
3039 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3041 assert(!"invalid load");
3047 switch (insn
->src(0).getFile()) {
3048 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3049 case FILE_MEMORY_SHARED
: emitSTS(); break;
3050 case FILE_MEMORY_GLOBAL
: emitST(); break;
3052 assert(!"invalid store");
3058 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3131 assert(!"invalid opcode");
3147 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3152 /*******************************************************************************
3153 * sched data calculator
3154 ******************************************************************************/
3156 class SchedDataCalculatorGM107
: public Pass
3159 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
3162 bool visit(BasicBlock
*bb
);
3166 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
3168 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
3170 insn
->sched
= 0x7e0;
3176 /*******************************************************************************
3178 ******************************************************************************/
3181 CodeEmitterGM107::prepareEmission(Function
*func
)
3183 SchedDataCalculatorGM107
sched(targ
);
3184 CodeEmitter::prepareEmission(func
);
3185 sched
.run(func
, true, true);
3188 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3190 return (size
+ 23) / 24;
3194 CodeEmitterGM107::prepareEmission(Program
*prog
)
3196 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3197 !fi
.end(); fi
.next()) {
3198 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3199 func
->binPos
= prog
->binSize
;
3200 prepareEmission(func
);
3202 // adjust sizes & positions for schedulding info:
3203 if (prog
->getTarget()->hasSWSched
) {
3204 uint32_t adjPos
= func
->binPos
;
3205 BasicBlock
*bb
= NULL
;
3206 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3207 bb
= func
->bbArray
[i
];
3208 int32_t adjSize
= bb
->binSize
;
3210 adjSize
-= 32 - adjPos
% 32;
3214 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3215 bb
->binPos
= adjPos
;
3216 bb
->binSize
= adjSize
;
3220 func
->binSize
= adjPos
- func
->binPos
;
3223 prog
->binSize
+= func
->binSize
;
3227 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3228 : CodeEmitter(target
),
3230 writeIssueDelays(target
->hasSWSched
)
3233 codeSize
= codeSizeLimit
= 0;
3238 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3240 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3241 emit
->setProgramType(type
);
3245 } // namespace nv50_ir