2 * Copyright 2014 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 #include "codegen/nv50_ir_target_gm107.h"
29 class CodeEmitterGM107
: public CodeEmitter
32 CodeEmitterGM107(const TargetGM107
*);
34 virtual bool emitInstruction(Instruction
*);
35 virtual uint32_t getMinEncodingSize(const Instruction
*) const;
37 virtual void prepareEmission(Program
*);
38 virtual void prepareEmission(Function
*);
40 inline void setProgramType(Program::Type pType
) { progType
= pType
; }
43 const TargetGM107
*targGM107
;
45 Program::Type progType
;
47 const Instruction
*insn
;
48 const bool writeIssueDelays
;
52 inline void emitField(uint32_t *, int, int, uint32_t);
53 inline void emitField(int b
, int s
, uint32_t v
) { emitField(code
, b
, s
, v
); }
55 inline void emitInsn(uint32_t, bool);
56 inline void emitInsn(uint32_t o
) { emitInsn(o
, true); }
57 inline void emitPred();
58 inline void emitGPR(int, const Value
*);
59 inline void emitGPR(int pos
) {
60 emitGPR(pos
, (const Value
*)NULL
);
62 inline void emitGPR(int pos
, const ValueRef
&ref
) {
63 emitGPR(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
65 inline void emitGPR(int pos
, const ValueRef
*ref
) {
66 emitGPR(pos
, ref
? ref
->rep() : (const Value
*)NULL
);
68 inline void emitGPR(int pos
, const ValueDef
&def
) {
69 emitGPR(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
71 inline void emitSYS(int, const Value
*);
72 inline void emitSYS(int pos
, const ValueRef
&ref
) {
73 emitSYS(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
75 inline void emitPRED(int, const Value
*);
76 inline void emitPRED(int pos
) {
77 emitPRED(pos
, (const Value
*)NULL
);
79 inline void emitPRED(int pos
, const ValueRef
&ref
) {
80 emitPRED(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
82 inline void emitPRED(int pos
, const ValueDef
&def
) {
83 emitPRED(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
85 inline void emitADDR(int, int, int, int, const ValueRef
&);
86 inline void emitCBUF(int, int, int, int, int, const ValueRef
&);
87 inline bool longIMMD(const ValueRef
&);
88 inline void emitIMMD(int, int, const ValueRef
&);
90 void emitCond3(int, CondCode
);
91 void emitCond4(int, CondCode
);
92 void emitCond5(int pos
, CondCode cc
) { emitCond4(pos
, cc
); }
93 inline void emitO(int);
94 inline void emitP(int);
95 inline void emitSAT(int);
96 inline void emitCC(int);
97 inline void emitX(int);
98 inline void emitABS(int, const ValueRef
&);
99 inline void emitNEG(int, const ValueRef
&);
100 inline void emitNEG2(int, const ValueRef
&, const ValueRef
&);
101 inline void emitFMZ(int, int);
102 inline void emitRND(int, RoundMode
, int);
103 inline void emitRND(int pos
) {
104 emitRND(pos
, insn
->rnd
, -1);
106 inline void emitPDIV(int);
107 inline void emitINV(int, const ValueRef
&);
165 void emitLDSTs(int, DataType
);
198 /*******************************************************************************
199 * general instruction layout/fields
200 ******************************************************************************/
203 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
206 uint32_t m
= ((1ULL << s
) - 1);
207 uint64_t d
= (uint64_t)(v
& m
) << b
;
208 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
215 CodeEmitterGM107::emitPred()
217 if (insn
->predSrc
>= 0) {
218 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
219 emitField(19, 1, insn
->cc
== CC_NOT_P
);
226 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
228 code
[0] = 0x00000000;
235 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
237 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
241 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
243 int id
= val
? val
->reg
.data
.id
: -1;
246 case SV_LANEID
: id
= 0x00; break;
247 case SV_VERTEX_COUNT
: id
= 0x10; break;
248 case SV_INVOCATION_ID
: id
= 0x11; break;
249 case SV_THREAD_KILL
: id
= 0x13; break;
250 case SV_INVOCATION_INFO
: id
= 0x1d; break;
252 assert(!"invalid system value");
257 emitField(pos
, 8, id
);
261 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
263 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
267 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
270 const Value
*v
= ref
.get();
271 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
273 emitGPR(gpr
, ref
.getIndirect(0));
274 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
278 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
281 const Value
*v
= ref
.get();
282 const Symbol
*s
= v
->asSym();
284 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
286 emitField(buf
, 5, v
->reg
.fileIndex
);
288 emitGPR(gpr
, ref
.getIndirect(0));
289 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
293 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
295 if (ref
.getFile() == FILE_IMMEDIATE
) {
296 const ImmediateValue
*imm
= ref
.get()->asImm();
297 if (isFloatType(insn
->sType
)) {
298 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
301 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
302 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
310 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
312 const ImmediateValue
*imm
= ref
.get()->asImm();
313 uint32_t val
= imm
->reg
.data
.u32
;
316 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
317 assert(!(val
& 0x00000fff));
319 } else if (insn
->sType
== TYPE_F64
) {
320 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
321 val
= imm
->reg
.data
.u64
>> 44;
323 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
324 emitField( 56, 1, (val
& 0x80000) >> 19);
325 emitField(pos
, len
, (val
& 0x7ffff));
327 emitField(pos
, len
, val
);
331 /*******************************************************************************
333 ******************************************************************************/
336 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
341 case CC_FL
: data
= 0x00; break;
343 case CC_LT
: data
= 0x01; break;
345 case CC_EQ
: data
= 0x02; break;
347 case CC_LE
: data
= 0x03; break;
349 case CC_GT
: data
= 0x04; break;
351 case CC_NE
: data
= 0x05; break;
353 case CC_GE
: data
= 0x06; break;
354 case CC_TR
: data
= 0x07; break;
356 assert(!"invalid cond3");
360 emitField(pos
, 3, data
);
364 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
369 case CC_FL
: data
= 0x00; break;
370 case CC_LT
: data
= 0x01; break;
371 case CC_EQ
: data
= 0x02; break;
372 case CC_LE
: data
= 0x03; break;
373 case CC_GT
: data
= 0x04; break;
374 case CC_NE
: data
= 0x05; break;
375 case CC_GE
: data
= 0x06; break;
376 // case CC_NUM: data = 0x07; break;
377 // case CC_NAN: data = 0x08; break;
378 case CC_LTU
: data
= 0x09; break;
379 case CC_EQU
: data
= 0x0a; break;
380 case CC_LEU
: data
= 0x0b; break;
381 case CC_GTU
: data
= 0x0c; break;
382 case CC_NEU
: data
= 0x0d; break;
383 case CC_GEU
: data
= 0x0e; break;
384 case CC_TR
: data
= 0x0f; break;
386 assert(!"invalid cond4");
390 emitField(pos
, 4, data
);
394 CodeEmitterGM107::emitO(int pos
)
396 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
400 CodeEmitterGM107::emitP(int pos
)
402 emitField(pos
, 1, insn
->perPatch
);
406 CodeEmitterGM107::emitSAT(int pos
)
408 emitField(pos
, 1, insn
->saturate
);
412 CodeEmitterGM107::emitCC(int pos
)
414 emitField(pos
, 1, insn
->defExists(1));
418 CodeEmitterGM107::emitX(int pos
)
420 emitField(pos
, 1, insn
->flagsSrc
>= 0);
424 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
426 emitField(pos
, 1, ref
.mod
.abs());
430 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
432 emitField(pos
, 1, ref
.mod
.neg());
436 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
438 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
442 CodeEmitterGM107::emitFMZ(int pos
, int len
)
444 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
448 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
452 case ROUND_NI
: ri
= 1;
453 case ROUND_N
: rm
= 0; break;
454 case ROUND_MI
: ri
= 1;
455 case ROUND_M
: rm
= 1; break;
456 case ROUND_PI
: ri
= 1;
457 case ROUND_P
: rm
= 2; break;
458 case ROUND_ZI
: ri
= 1;
459 case ROUND_Z
: rm
= 3; break;
461 assert(!"invalid round mode");
464 emitField(rip
, 1, ri
);
465 emitField(rmp
, 2, rm
);
469 CodeEmitterGM107::emitPDIV(int pos
)
471 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
472 if (insn
->postFactor
> 0)
473 emitField(pos
, 3, 7 - insn
->postFactor
);
475 emitField(pos
, 3, 0 - insn
->postFactor
);
479 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
481 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
484 /*******************************************************************************
486 ******************************************************************************/
489 CodeEmitterGM107::emitEXIT()
491 emitInsn (0xe3000000);
492 emitCond5(0x00, CC_TR
);
496 CodeEmitterGM107::emitBRA()
498 const FlowInstruction
*insn
= this->insn
->asFlow();
501 if (insn
->indirect
) {
503 emitInsn(0xe2000000); // JMX
505 emitInsn(0xe2500000); // BRX
509 emitInsn(0xe2100000); // JMP
511 emitInsn(0xe2400000); // BRA
512 emitField(0x07, 1, insn
->allWarp
);
515 emitField(0x06, 1, insn
->limit
);
516 emitCond5(0x00, CC_TR
);
518 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
519 int32_t pos
= insn
->target
.bb
->binPos
;
520 if (writeIssueDelays
&& !(pos
& 0x1f))
523 emitField(0x14, 24, pos
- (codeSize
+ 8));
525 emitField(0x14, 32, pos
);
527 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
528 emitField(0x05, 1, 1);
533 CodeEmitterGM107::emitCAL()
535 const FlowInstruction
*insn
= this->insn
->asFlow();
537 if (insn
->absolute
) {
538 emitInsn(0xe2200000, 0); // JCAL
540 emitInsn(0xe2600000, 0); // CAL
543 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
545 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
548 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
549 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
550 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
552 emitField(0x14, 32, insn
->target
.bb
->binPos
);
556 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
557 emitField(0x05, 1, 1);
562 CodeEmitterGM107::emitPCNT()
564 const FlowInstruction
*insn
= this->insn
->asFlow();
566 emitInsn(0xe2b00000, 0);
568 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
569 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
571 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
572 emitField(0x05, 1, 1);
577 CodeEmitterGM107::emitCONT()
579 emitInsn (0xe3500000);
580 emitCond5(0x00, CC_TR
);
584 CodeEmitterGM107::emitPBK()
586 const FlowInstruction
*insn
= this->insn
->asFlow();
588 emitInsn(0xe2a00000, 0);
590 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
591 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
593 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
594 emitField(0x05, 1, 1);
599 CodeEmitterGM107::emitBRK()
601 emitInsn (0xe3400000);
602 emitCond5(0x00, CC_TR
);
606 CodeEmitterGM107::emitPRET()
608 const FlowInstruction
*insn
= this->insn
->asFlow();
610 emitInsn(0xe2700000, 0);
612 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
613 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
615 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
616 emitField(0x05, 1, 1);
621 CodeEmitterGM107::emitRET()
623 emitInsn (0xe3200000);
624 emitCond5(0x00, CC_TR
);
628 CodeEmitterGM107::emitSSY()
630 const FlowInstruction
*insn
= this->insn
->asFlow();
632 emitInsn(0xe2900000, 0);
634 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
635 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
637 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
638 emitField(0x05, 1, 1);
643 CodeEmitterGM107::emitSYNC()
645 emitInsn (0xf0f80000);
646 emitCond5(0x00, CC_TR
);
650 CodeEmitterGM107::emitSAM()
652 emitInsn(0xe3700000, 0);
656 CodeEmitterGM107::emitRAM()
658 emitInsn(0xe3800000, 0);
661 /*******************************************************************************
663 ******************************************************************************/
665 /*******************************************************************************
666 * movement / conversion
667 ******************************************************************************/
670 CodeEmitterGM107::emitMOV()
672 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
673 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
674 switch (insn
->src(0).getFile()) {
676 emitInsn(0x5c980000);
677 emitGPR (0x14, insn
->src(0));
679 case FILE_MEMORY_CONST
:
680 emitInsn(0x4c980000);
681 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
684 emitInsn(0x38980000);
685 emitIMMD(0x14, 19, insn
->src(0));
688 assert(!"bad src file");
691 emitField(0x27, 4, insn
->lanes
);
693 emitInsn (0x01000000);
694 emitIMMD (0x14, 32, insn
->src(0));
695 emitField(0x0c, 4, insn
->lanes
);
698 emitGPR(0x00, insn
->def(0));
702 CodeEmitterGM107::emitS2R()
704 emitInsn(0xf0c80000);
705 emitSYS (0x14, insn
->src(0));
706 emitGPR (0x00, insn
->def(0));
710 CodeEmitterGM107::emitF2F()
712 RoundMode rnd
= insn
->rnd
;
715 case OP_FLOOR
: rnd
= ROUND_MI
; break;
716 case OP_CEIL
: rnd
= ROUND_PI
; break;
717 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
722 switch (insn
->src(0).getFile()) {
724 emitInsn(0x5ca80000);
725 emitGPR (0x14, insn
->src(0));
727 case FILE_MEMORY_CONST
:
728 emitInsn(0x4ca80000);
729 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
732 emitInsn(0x38a80000);
733 emitIMMD(0x14, 19, insn
->src(0));
736 assert(!"bad src0 file");
740 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
741 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
743 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
745 emitField(0x29, 1, insn
->subOp
);
746 emitRND (0x27, rnd
, 0x2a);
747 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
748 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
749 emitGPR (0x00, insn
->def(0));
753 CodeEmitterGM107::emitF2I()
755 RoundMode rnd
= insn
->rnd
;
758 case OP_FLOOR
: rnd
= ROUND_M
; break;
759 case OP_CEIL
: rnd
= ROUND_P
; break;
760 case OP_TRUNC
: rnd
= ROUND_Z
; break;
765 switch (insn
->src(0).getFile()) {
767 emitInsn(0x5cb00000);
768 emitGPR (0x14, insn
->src(0));
770 case FILE_MEMORY_CONST
:
771 emitInsn(0x4cb00000);
772 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
775 emitInsn(0x38b00000);
776 emitIMMD(0x14, 19, insn
->src(0));
779 assert(!"bad src0 file");
783 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
785 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
787 emitRND (0x27, rnd
, 0x2a);
788 emitField(0x0c, 1, isSignedType(insn
->dType
));
789 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
790 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
791 emitGPR (0x00, insn
->def(0));
795 CodeEmitterGM107::emitI2F()
797 RoundMode rnd
= insn
->rnd
;
800 case OP_FLOOR
: rnd
= ROUND_M
; break;
801 case OP_CEIL
: rnd
= ROUND_P
; break;
802 case OP_TRUNC
: rnd
= ROUND_Z
; break;
807 switch (insn
->src(0).getFile()) {
809 emitInsn(0x5cb80000);
810 emitGPR (0x14, insn
->src(0));
812 case FILE_MEMORY_CONST
:
813 emitInsn(0x4cb80000);
814 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
817 emitInsn(0x38b80000);
818 emitIMMD(0x14, 19, insn
->src(0));
821 assert(!"bad src0 file");
825 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
827 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
828 emitField(0x29, 2, insn
->subOp
);
829 emitRND (0x27, rnd
, -1);
830 emitField(0x0d, 1, isSignedType(insn
->sType
));
831 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
832 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
833 emitGPR (0x00, insn
->def(0));
837 CodeEmitterGM107::emitI2I()
839 switch (insn
->src(0).getFile()) {
841 emitInsn(0x5ce00000);
842 emitGPR (0x14, insn
->src(0));
844 case FILE_MEMORY_CONST
:
845 emitInsn(0x4ce00000);
846 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
849 emitInsn(0x38e00000);
850 emitIMMD(0x14, 19, insn
->src(0));
853 assert(!"bad src0 file");
858 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
860 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
861 emitField(0x29, 2, insn
->subOp
);
862 emitField(0x0d, 1, isSignedType(insn
->sType
));
863 emitField(0x0c, 1, isSignedType(insn
->dType
));
864 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
865 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
866 emitGPR (0x00, insn
->def(0));
870 CodeEmitterGM107::emitSHFL()
874 emitInsn (0xef100000);
876 switch (insn
->src(1).getFile()) {
878 emitGPR(0x14, insn
->src(1));
881 emitIMMD(0x14, 5, insn
->src(1));
885 assert(!"invalid src1 file");
889 /*XXX: what is this arg? hardcode immediate for now */
890 emitField(0x22, 13, 0x1c03);
894 emitField(0x1e, 2, insn
->subOp
);
895 emitField(0x1c, 2, type
);
896 emitGPR (0x08, insn
->src(0));
897 emitGPR (0x00, insn
->def(0));
900 /*******************************************************************************
902 ******************************************************************************/
905 CodeEmitterGM107::emitDADD()
907 switch (insn
->src(1).getFile()) {
909 emitInsn(0x5c700000);
910 emitGPR (0x14, insn
->src(1));
912 case FILE_MEMORY_CONST
:
913 emitInsn(0x4c700000);
914 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
917 emitInsn(0x38700000);
918 emitIMMD(0x14, 19, insn
->src(1));
921 assert(!"bad src1 file");
924 emitABS(0x31, insn
->src(1));
925 emitNEG(0x30, insn
->src(0));
927 emitABS(0x2e, insn
->src(0));
928 emitNEG(0x2d, insn
->src(1));
930 if (insn
->op
== OP_SUB
)
931 code
[1] ^= 0x00002000;
933 emitGPR(0x08, insn
->src(0));
934 emitGPR(0x00, insn
->def(0));
938 CodeEmitterGM107::emitDMUL()
940 switch (insn
->src(1).getFile()) {
942 emitInsn(0x5c800000);
943 emitGPR (0x14, insn
->src(1));
945 case FILE_MEMORY_CONST
:
946 emitInsn(0x4c800000);
947 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
950 emitInsn(0x38800000);
951 emitIMMD(0x14, 19, insn
->src(1));
954 assert(!"bad src1 file");
958 emitNEG2(0x30, insn
->src(0), insn
->src(1));
961 emitGPR (0x08, insn
->src(0));
962 emitGPR (0x00, insn
->def(0));
966 CodeEmitterGM107::emitDFMA()
968 switch(insn
->src(2).getFile()) {
970 switch (insn
->src(1).getFile()) {
972 emitInsn(0x5b700000);
973 emitGPR (0x14, insn
->src(1));
975 case FILE_MEMORY_CONST
:
976 emitInsn(0x4b700000);
977 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
980 emitInsn(0x36700000);
981 emitIMMD(0x14, 19, insn
->src(1));
984 assert(!"bad src1 file");
987 emitGPR (0x27, insn
->src(2));
989 case FILE_MEMORY_CONST
:
990 emitInsn(0x53700000);
991 emitGPR (0x27, insn
->src(1));
992 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
995 assert(!"bad src2 file");
1000 emitNEG (0x31, insn
->src(2));
1001 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1003 emitGPR (0x08, insn
->src(0));
1004 emitGPR (0x00, insn
->def(0));
1008 CodeEmitterGM107::emitDMNMX()
1010 switch (insn
->src(1).getFile()) {
1012 emitInsn(0x5c500000);
1013 emitGPR (0x14, insn
->src(1));
1015 case FILE_MEMORY_CONST
:
1016 emitInsn(0x4c500000);
1017 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1019 case FILE_IMMEDIATE
:
1020 emitInsn(0x38500000);
1021 emitIMMD(0x14, 19, insn
->src(1));
1024 assert(!"bad src1 file");
1028 emitABS (0x31, insn
->src(1));
1029 emitNEG (0x30, insn
->src(0));
1031 emitABS (0x2e, insn
->src(0));
1032 emitNEG (0x2d, insn
->src(1));
1033 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1035 emitGPR (0x08, insn
->src(0));
1036 emitGPR (0x00, insn
->def(0));
1040 CodeEmitterGM107::emitDSET()
1042 const CmpInstruction
*insn
= this->insn
->asCmp();
1044 switch (insn
->src(1).getFile()) {
1046 emitInsn(0x59000000);
1047 emitGPR (0x14, insn
->src(1));
1049 case FILE_MEMORY_CONST
:
1050 emitInsn(0x49000000);
1051 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1053 case FILE_IMMEDIATE
:
1054 emitInsn(0x32000000);
1055 emitIMMD(0x14, 19, insn
->src(1));
1058 assert(!"bad src1 file");
1062 if (insn
->op
!= OP_SET
) {
1064 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1065 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1066 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1068 assert(!"invalid set op");
1071 emitPRED(0x27, insn
->src(2));
1076 emitABS (0x36, insn
->src(0));
1077 emitNEG (0x35, insn
->src(1));
1078 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1079 emitCond4(0x30, insn
->setCond
);
1081 emitABS (0x2c, insn
->src(1));
1082 emitNEG (0x2b, insn
->src(0));
1083 emitGPR (0x08, insn
->src(0));
1084 emitGPR (0x00, insn
->def(0));
1088 CodeEmitterGM107::emitDSETP()
1090 const CmpInstruction
*insn
= this->insn
->asCmp();
1092 switch (insn
->src(1).getFile()) {
1094 emitInsn(0x5b800000);
1095 emitGPR (0x14, insn
->src(1));
1097 case FILE_MEMORY_CONST
:
1098 emitInsn(0x4b800000);
1099 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1101 case FILE_IMMEDIATE
:
1102 emitInsn(0x36800000);
1103 emitIMMD(0x14, 19, insn
->src(1));
1106 assert(!"bad src1 file");
1110 if (insn
->op
!= OP_SET
) {
1112 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1113 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1114 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1116 assert(!"invalid set op");
1119 emitPRED(0x27, insn
->src(2));
1124 emitCond4(0x30, insn
->setCond
);
1125 emitABS (0x2c, insn
->src(1));
1126 emitNEG (0x2b, insn
->src(0));
1127 emitGPR (0x08, insn
->src(0));
1128 emitABS (0x07, insn
->src(0));
1129 emitNEG (0x06, insn
->src(1));
1130 emitPRED (0x03, insn
->def(0));
1131 if (insn
->defExists(1))
1132 emitPRED(0x00, insn
->def(1));
1137 /*******************************************************************************
1139 ******************************************************************************/
1142 CodeEmitterGM107::emitFADD()
1144 if (!longIMMD(insn
->src(1))) {
1145 switch (insn
->src(1).getFile()) {
1147 emitInsn(0x5c580000);
1148 emitGPR (0x14, insn
->src(1));
1150 case FILE_MEMORY_CONST
:
1151 emitInsn(0x4c580000);
1152 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1154 case FILE_IMMEDIATE
:
1155 emitInsn(0x38580000);
1156 emitIMMD(0x14, 19, insn
->src(1));
1159 assert(!"bad src1 file");
1163 emitABS(0x31, insn
->src(1));
1164 emitNEG(0x30, insn
->src(0));
1166 emitABS(0x2e, insn
->src(0));
1167 emitNEG(0x2d, insn
->src(1));
1170 emitInsn(0x08000000);
1171 emitABS(0x39, insn
->src(1));
1172 emitNEG(0x38, insn
->src(0));
1174 emitABS(0x36, insn
->src(0));
1175 emitNEG(0x35, insn
->src(1));
1177 emitIMMD(0x14, 32, insn
->src(1));
1180 if (insn
->op
== OP_SUB
)
1181 code
[1] ^= 0x00002000;
1183 emitGPR(0x08, insn
->src(0));
1184 emitGPR(0x00, insn
->def(0));
1188 CodeEmitterGM107::emitFMUL()
1190 if (!longIMMD(insn
->src(1))) {
1191 switch (insn
->src(1).getFile()) {
1193 emitInsn(0x5c680000);
1194 emitGPR (0x14, insn
->src(1));
1196 case FILE_MEMORY_CONST
:
1197 emitInsn(0x4c680000);
1198 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1200 case FILE_IMMEDIATE
:
1201 emitInsn(0x38680000);
1202 emitIMMD(0x14, 19, insn
->src(1));
1205 assert(!"bad src1 file");
1209 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1215 emitInsn(0x1e000000);
1219 emitIMMD(0x14, 32, insn
->src(1));
1220 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1221 code
[1] ^= 0x00080000; /* flip immd sign bit */
1224 emitGPR(0x08, insn
->src(0));
1225 emitGPR(0x00, insn
->def(0));
1229 CodeEmitterGM107::emitFFMA()
1231 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1232 switch(insn
->src(2).getFile()) {
1234 switch (insn
->src(1).getFile()) {
1236 emitInsn(0x59800000);
1237 emitGPR (0x14, insn
->src(1));
1239 case FILE_MEMORY_CONST
:
1240 emitInsn(0x49800000);
1241 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1243 case FILE_IMMEDIATE
:
1244 emitInsn(0x32800000);
1245 emitIMMD(0x14, 19, insn
->src(1));
1248 assert(!"bad src1 file");
1251 emitGPR (0x27, insn
->src(2));
1253 case FILE_MEMORY_CONST
:
1254 emitInsn(0x51800000);
1255 emitGPR (0x27, insn
->src(1));
1256 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1259 assert(!"bad src2 file");
1264 emitNEG (0x31, insn
->src(2));
1265 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1269 emitGPR(0x08, insn
->src(0));
1270 emitGPR(0x00, insn
->def(0));
1274 CodeEmitterGM107::emitMUFU()
1279 case OP_COS
: mufu
= 0; break;
1280 case OP_SIN
: mufu
= 1; break;
1281 case OP_EX2
: mufu
= 2; break;
1282 case OP_LG2
: mufu
= 3; break;
1283 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1284 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1286 assert(!"invalid mufu");
1290 emitInsn (0x50800000);
1292 emitNEG (0x30, insn
->src(0));
1293 emitABS (0x2e, insn
->src(0));
1294 emitField(0x14, 3, mufu
);
1295 emitGPR (0x08, insn
->src(0));
1296 emitGPR (0x00, insn
->def(0));
1300 CodeEmitterGM107::emitFMNMX()
1302 switch (insn
->src(1).getFile()) {
1304 emitInsn(0x5c600000);
1305 emitGPR (0x14, insn
->src(1));
1307 case FILE_MEMORY_CONST
:
1308 emitInsn(0x4c600000);
1309 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1311 case FILE_IMMEDIATE
:
1312 emitInsn(0x38600000);
1313 emitIMMD(0x14, 19, insn
->src(1));
1316 assert(!"bad src1 file");
1320 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1323 emitABS(0x31, insn
->src(1));
1324 emitNEG(0x30, insn
->src(0));
1326 emitABS(0x2e, insn
->src(0));
1327 emitNEG(0x2d, insn
->src(1));
1329 emitGPR(0x08, insn
->src(0));
1330 emitGPR(0x00, insn
->def(0));
1334 CodeEmitterGM107::emitRRO()
1336 switch (insn
->src(0).getFile()) {
1338 emitInsn(0x5c900000);
1339 emitGPR (0x14, insn
->src(0));
1341 case FILE_MEMORY_CONST
:
1342 emitInsn(0x4c900000);
1343 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1345 case FILE_IMMEDIATE
:
1346 emitInsn(0x38900000);
1347 emitIMMD(0x14, 19, insn
->src(0));
1350 assert(!"bad src file");
1354 emitABS (0x31, insn
->src(0));
1355 emitNEG (0x2d, insn
->src(0));
1356 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1357 emitGPR (0x00, insn
->def(0));
1361 CodeEmitterGM107::emitFCMP()
1363 const CmpInstruction
*insn
= this->insn
->asCmp();
1364 CondCode cc
= insn
->setCond
;
1366 if (insn
->src(2).mod
.neg())
1367 cc
= reverseCondCode(cc
);
1369 switch(insn
->src(2).getFile()) {
1371 switch (insn
->src(1).getFile()) {
1373 emitInsn(0x5ba00000);
1374 emitGPR (0x14, insn
->src(1));
1376 case FILE_MEMORY_CONST
:
1377 emitInsn(0x4ba00000);
1378 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1380 case FILE_IMMEDIATE
:
1381 emitInsn(0x36a00000);
1382 emitIMMD(0x14, 19, insn
->src(1));
1385 assert(!"bad src1 file");
1388 emitGPR (0x27, insn
->src(2));
1390 case FILE_MEMORY_CONST
:
1391 emitInsn(0x53a00000);
1392 emitGPR (0x27, insn
->src(1));
1393 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1396 assert(!"bad src2 file");
1400 emitCond4(0x30, cc
);
1402 emitGPR (0x08, insn
->src(0));
1403 emitGPR (0x00, insn
->def(0));
1407 CodeEmitterGM107::emitFSET()
1409 const CmpInstruction
*insn
= this->insn
->asCmp();
1411 switch (insn
->src(1).getFile()) {
1413 emitInsn(0x58000000);
1414 emitGPR (0x14, insn
->src(1));
1416 case FILE_MEMORY_CONST
:
1417 emitInsn(0x48000000);
1418 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1420 case FILE_IMMEDIATE
:
1421 emitInsn(0x30000000);
1422 emitIMMD(0x14, 19, insn
->src(1));
1425 assert(!"bad src1 file");
1429 if (insn
->op
!= OP_SET
) {
1431 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1432 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1433 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1435 assert(!"invalid set op");
1438 emitPRED(0x27, insn
->src(2));
1444 emitABS (0x36, insn
->src(0));
1445 emitNEG (0x35, insn
->src(1));
1446 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1447 emitCond4(0x30, insn
->setCond
);
1449 emitABS (0x2c, insn
->src(1));
1450 emitNEG (0x2b, insn
->src(0));
1451 emitGPR (0x08, insn
->src(0));
1452 emitGPR (0x00, insn
->def(0));
1456 CodeEmitterGM107::emitFSETP()
1458 const CmpInstruction
*insn
= this->insn
->asCmp();
1460 switch (insn
->src(1).getFile()) {
1462 emitInsn(0x5bb00000);
1463 emitGPR (0x14, insn
->src(1));
1465 case FILE_MEMORY_CONST
:
1466 emitInsn(0x4bb00000);
1467 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1469 case FILE_IMMEDIATE
:
1470 emitInsn(0x36b00000);
1471 emitIMMD(0x14, 19, insn
->src(1));
1474 assert(!"bad src1 file");
1478 if (insn
->op
!= OP_SET
) {
1480 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1481 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1482 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1484 assert(!"invalid set op");
1487 emitPRED(0x27, insn
->src(2));
1492 emitCond4(0x30, insn
->setCond
);
1494 emitABS (0x2c, insn
->src(1));
1495 emitNEG (0x2b, insn
->src(0));
1496 emitGPR (0x08, insn
->src(0));
1497 emitABS (0x07, insn
->src(0));
1498 emitNEG (0x06, insn
->src(1));
1499 emitPRED (0x03, insn
->def(0));
1500 if (insn
->defExists(1))
1501 emitPRED(0x00, insn
->def(1));
1507 CodeEmitterGM107::emitFSWZADD()
1509 emitInsn (0x50f80000);
1513 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1514 emitField(0x1c, 8, insn
->subOp
);
1515 emitGPR (0x14, insn
->src(1));
1516 emitGPR (0x08, insn
->src(0));
1517 emitGPR (0x00, insn
->def(0));
1520 /*******************************************************************************
1522 ******************************************************************************/
1525 CodeEmitterGM107::emitLOP()
1530 case OP_AND
: lop
= 0; break;
1531 case OP_OR
: lop
= 1; break;
1532 case OP_XOR
: lop
= 2; break;
1534 assert(!"invalid lop");
1538 if (!longIMMD(insn
->src(1))) {
1539 switch (insn
->src(1).getFile()) {
1541 emitInsn(0x5c400000);
1542 emitGPR (0x14, insn
->src(1));
1544 case FILE_MEMORY_CONST
:
1545 emitInsn(0x4c400000);
1546 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1548 case FILE_IMMEDIATE
:
1549 emitInsn(0x38400000);
1550 emitIMMD(0x14, 19, insn
->src(1));
1553 assert(!"bad src1 file");
1557 emitField(0x29, 2, lop
);
1558 emitINV (0x28, insn
->src(1));
1559 emitINV (0x27, insn
->src(0));
1561 emitInsn (0x04000000);
1562 emitINV (0x38, insn
->src(1));
1563 emitINV (0x37, insn
->src(0));
1564 emitField(0x35, 2, lop
);
1565 emitIMMD (0x14, 32, insn
->src(1));
1568 emitGPR (0x08, insn
->src(0));
1569 emitGPR (0x00, insn
->def(0));
1572 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1574 CodeEmitterGM107::emitNOT()
1576 if (!longIMMD(insn
->src(0))) {
1577 switch (insn
->src(0).getFile()) {
1579 emitInsn(0x5c400700);
1580 emitGPR (0x14, insn
->src(0));
1582 case FILE_MEMORY_CONST
:
1583 emitInsn(0x4c400700);
1584 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1586 case FILE_IMMEDIATE
:
1587 emitInsn(0x38400700);
1588 emitIMMD(0x14, 19, insn
->src(0));
1591 assert(!"bad src1 file");
1596 emitInsn (0x05600000);
1597 emitIMMD (0x14, 32, insn
->src(1));
1601 emitGPR(0x00, insn
->def(0));
1605 CodeEmitterGM107::emitIADD()
1607 if (!longIMMD(insn
->src(1))) {
1608 switch (insn
->src(1).getFile()) {
1610 emitInsn(0x5c100000);
1611 emitGPR (0x14, insn
->src(1));
1613 case FILE_MEMORY_CONST
:
1614 emitInsn(0x4c100000);
1615 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1617 case FILE_IMMEDIATE
:
1618 emitInsn(0x38100000);
1619 emitIMMD(0x14, 19, insn
->src(1));
1622 assert(!"bad src1 file");
1626 emitNEG(0x31, insn
->src(0));
1627 emitNEG(0x30, insn
->src(1));
1630 emitInsn(0x1c000000);
1633 emitIMMD(0x14, 32, insn
->src(1));
1636 if (insn
->op
== OP_SUB
)
1637 code
[1] ^= 0x00010000;
1639 emitGPR(0x08, insn
->src(0));
1640 emitGPR(0x00, insn
->def(0));
1644 CodeEmitterGM107::emitIMUL()
1646 if (!longIMMD(insn
->src(1))) {
1647 switch (insn
->src(1).getFile()) {
1649 emitInsn(0x5c380000);
1650 emitGPR (0x14, insn
->src(1));
1652 case FILE_MEMORY_CONST
:
1653 emitInsn(0x4c380000);
1654 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1656 case FILE_IMMEDIATE
:
1657 emitInsn(0x38380000);
1658 emitIMMD(0x14, 19, insn
->src(1));
1661 assert(!"bad src1 file");
1665 emitField(0x29, 1, isSignedType(insn
->sType
));
1666 emitField(0x28, 1, isSignedType(insn
->dType
));
1667 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1669 emitInsn (0x1f000000);
1670 emitField(0x37, 1, isSignedType(insn
->sType
));
1671 emitField(0x36, 1, isSignedType(insn
->dType
));
1672 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1674 emitIMMD (0x14, 32, insn
->src(1));
1677 emitGPR(0x08, insn
->src(0));
1678 emitGPR(0x00, insn
->def(0));
1682 CodeEmitterGM107::emitIMAD()
1684 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1685 switch(insn
->src(2).getFile()) {
1687 switch (insn
->src(1).getFile()) {
1689 emitInsn(0x5a000000);
1690 emitGPR (0x14, insn
->src(1));
1692 case FILE_MEMORY_CONST
:
1693 emitInsn(0x4a000000);
1694 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1696 case FILE_IMMEDIATE
:
1697 emitInsn(0x34000000);
1698 emitIMMD(0x14, 19, insn
->src(1));
1701 assert(!"bad src1 file");
1704 emitGPR (0x27, insn
->src(2));
1706 case FILE_MEMORY_CONST
:
1707 emitInsn(0x52000000);
1708 emitGPR (0x27, insn
->src(1));
1709 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1712 assert(!"bad src2 file");
1716 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1717 emitField(0x35, 1, isSignedType(insn
->sType
));
1718 emitNEG (0x34, insn
->src(2));
1719 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1722 emitField(0x30, 1, isSignedType(insn
->dType
));
1724 emitGPR (0x08, insn
->src(0));
1725 emitGPR (0x00, insn
->def(0));
1729 CodeEmitterGM107::emitIMNMX()
1731 switch (insn
->src(1).getFile()) {
1733 emitInsn(0x5c200000);
1734 emitGPR (0x14, insn
->src(1));
1736 case FILE_MEMORY_CONST
:
1737 emitInsn(0x4c200000);
1738 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1740 case FILE_IMMEDIATE
:
1741 emitInsn(0x38200000);
1742 emitIMMD(0x14, 19, insn
->src(1));
1745 assert(!"bad src1 file");
1749 emitField(0x30, 1, isSignedType(insn
->dType
));
1751 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1753 emitGPR (0x08, insn
->src(0));
1754 emitGPR (0x00, insn
->def(0));
1758 CodeEmitterGM107::emitICMP()
1760 const CmpInstruction
*insn
= this->insn
->asCmp();
1761 CondCode cc
= insn
->setCond
;
1763 if (insn
->src(2).mod
.neg())
1764 cc
= reverseCondCode(cc
);
1766 switch(insn
->src(2).getFile()) {
1768 switch (insn
->src(1).getFile()) {
1770 emitInsn(0x5b400000);
1771 emitGPR (0x14, insn
->src(1));
1773 case FILE_MEMORY_CONST
:
1774 emitInsn(0x4b400000);
1775 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1777 case FILE_IMMEDIATE
:
1778 emitInsn(0x36400000);
1779 emitIMMD(0x14, 19, insn
->src(1));
1782 assert(!"bad src1 file");
1785 emitGPR (0x27, insn
->src(2));
1787 case FILE_MEMORY_CONST
:
1788 emitInsn(0x53400000);
1789 emitGPR (0x27, insn
->src(1));
1790 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1793 assert(!"bad src2 file");
1797 emitCond3(0x31, cc
);
1798 emitField(0x30, 1, isSignedType(insn
->sType
));
1799 emitGPR (0x08, insn
->src(0));
1800 emitGPR (0x00, insn
->def(0));
1804 CodeEmitterGM107::emitISET()
1806 const CmpInstruction
*insn
= this->insn
->asCmp();
1808 switch (insn
->src(1).getFile()) {
1810 emitInsn(0x5b500000);
1811 emitGPR (0x14, insn
->src(1));
1813 case FILE_MEMORY_CONST
:
1814 emitInsn(0x4b500000);
1815 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1817 case FILE_IMMEDIATE
:
1818 emitInsn(0x36500000);
1819 emitIMMD(0x14, 19, insn
->src(1));
1822 assert(!"bad src1 file");
1826 if (insn
->op
!= OP_SET
) {
1828 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1829 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1830 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1832 assert(!"invalid set op");
1835 emitPRED(0x27, insn
->src(2));
1840 emitCond3(0x31, insn
->setCond
);
1841 emitField(0x30, 1, isSignedType(insn
->sType
));
1843 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1845 emitGPR (0x08, insn
->src(0));
1846 emitGPR (0x00, insn
->def(0));
1850 CodeEmitterGM107::emitISETP()
1852 const CmpInstruction
*insn
= this->insn
->asCmp();
1854 switch (insn
->src(1).getFile()) {
1856 emitInsn(0x5b600000);
1857 emitGPR (0x14, insn
->src(1));
1859 case FILE_MEMORY_CONST
:
1860 emitInsn(0x4b600000);
1861 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1863 case FILE_IMMEDIATE
:
1864 emitInsn(0x36600000);
1865 emitIMMD(0x14, 19, insn
->src(1));
1868 assert(!"bad src1 file");
1872 if (insn
->op
!= OP_SET
) {
1874 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1875 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1876 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1878 assert(!"invalid set op");
1881 emitPRED(0x27, insn
->src(2));
1886 emitCond3(0x31, insn
->setCond
);
1887 emitField(0x30, 1, isSignedType(insn
->sType
));
1889 emitGPR (0x08, insn
->src(0));
1890 emitPRED (0x03, insn
->def(0));
1891 if (insn
->defExists(1))
1892 emitPRED(0x00, insn
->def(1));
1898 CodeEmitterGM107::emitSHL()
1900 switch (insn
->src(1).getFile()) {
1902 emitInsn(0x5c480000);
1903 emitGPR (0x14, insn
->src(1));
1905 case FILE_MEMORY_CONST
:
1906 emitInsn(0x4c480000);
1907 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1909 case FILE_IMMEDIATE
:
1910 emitInsn(0x38480000);
1911 emitIMMD(0x14, 19, insn
->src(1));
1914 assert(!"bad src1 file");
1920 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1921 emitGPR (0x08, insn
->src(0));
1922 emitGPR (0x00, insn
->def(0));
1926 CodeEmitterGM107::emitSHR()
1928 switch (insn
->src(1).getFile()) {
1930 emitInsn(0x5c280000);
1931 emitGPR (0x14, insn
->src(1));
1933 case FILE_MEMORY_CONST
:
1934 emitInsn(0x4c280000);
1935 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1937 case FILE_IMMEDIATE
:
1938 emitInsn(0x38280000);
1939 emitIMMD(0x14, 19, insn
->src(1));
1942 assert(!"bad src1 file");
1946 emitField(0x30, 1, isSignedType(insn
->dType
));
1949 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1950 emitGPR (0x08, insn
->src(0));
1951 emitGPR (0x00, insn
->def(0));
1955 CodeEmitterGM107::emitPOPC()
1957 switch (insn
->src(0).getFile()) {
1959 emitInsn(0x5c080000);
1960 emitGPR (0x14, insn
->src(0));
1962 case FILE_MEMORY_CONST
:
1963 emitInsn(0x4c080000);
1964 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1966 case FILE_IMMEDIATE
:
1967 emitInsn(0x38080000);
1968 emitIMMD(0x14, 19, insn
->src(0));
1971 assert(!"bad src1 file");
1975 emitINV(0x28, insn
->src(0));
1976 emitGPR(0x00, insn
->def(0));
1980 CodeEmitterGM107::emitBFI()
1982 switch(insn
->src(2).getFile()) {
1984 switch (insn
->src(1).getFile()) {
1986 emitInsn(0x5bf00000);
1987 emitGPR (0x14, insn
->src(1));
1989 case FILE_MEMORY_CONST
:
1990 emitInsn(0x4bf00000);
1991 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1993 case FILE_IMMEDIATE
:
1994 emitInsn(0x36f00000);
1995 emitIMMD(0x14, 19, insn
->src(1));
1998 assert(!"bad src1 file");
2001 emitGPR (0x27, insn
->src(2));
2003 case FILE_MEMORY_CONST
:
2004 emitInsn(0x53f00000);
2005 emitGPR (0x27, insn
->src(1));
2006 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2009 assert(!"bad src2 file");
2014 emitGPR (0x08, insn
->src(0));
2015 emitGPR (0x00, insn
->def(0));
2019 CodeEmitterGM107::emitBFE()
2021 switch (insn
->src(1).getFile()) {
2023 emitInsn(0x5c000000);
2024 emitGPR (0x14, insn
->src(1));
2026 case FILE_MEMORY_CONST
:
2027 emitInsn(0x4c000000);
2028 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2030 case FILE_IMMEDIATE
:
2031 emitInsn(0x38000000);
2032 emitIMMD(0x14, 19, insn
->src(1));
2035 assert(!"bad src1 file");
2039 emitField(0x30, 1, isSignedType(insn
->dType
));
2041 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2042 emitGPR (0x08, insn
->src(0));
2043 emitGPR (0x00, insn
->def(0));
2047 CodeEmitterGM107::emitFLO()
2049 switch (insn
->src(0).getFile()) {
2051 emitInsn(0x5c300000);
2052 emitGPR (0x14, insn
->src(0));
2054 case FILE_MEMORY_CONST
:
2055 emitInsn(0x4c300000);
2056 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2058 case FILE_IMMEDIATE
:
2059 emitInsn(0x38300000);
2060 emitIMMD(0x14, 19, insn
->src(0));
2063 assert(!"bad src1 file");
2067 emitField(0x30, 1, isSignedType(insn
->dType
));
2069 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2070 emitINV (0x28, insn
->src(0));
2071 emitGPR (0x00, insn
->def(0));
2074 /*******************************************************************************
2076 ******************************************************************************/
2079 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2083 switch (typeSizeof(type
)) {
2084 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2085 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2086 case 4: data
= 4; break;
2087 case 8: data
= 5; break;
2088 case 16: data
= 6; break;
2090 assert(!"bad type");
2094 emitField(pos
, 3, data
);
2098 CodeEmitterGM107::emitLDSTc(int pos
)
2102 switch (insn
->cache
) {
2103 case CACHE_CA
: mode
= 0; break;
2104 case CACHE_CG
: mode
= 1; break;
2105 case CACHE_CS
: mode
= 2; break;
2106 case CACHE_CV
: mode
= 3; break;
2108 assert(!"invalid caching mode");
2112 emitField(pos
, 2, mode
);
2116 CodeEmitterGM107::emitLDC()
2118 emitInsn (0xef900000);
2119 emitLDSTs(0x30, insn
->dType
);
2120 emitField(0x2c, 2, insn
->subOp
);
2121 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2122 emitGPR (0x00, insn
->def(0));
2126 CodeEmitterGM107::emitLDL()
2128 emitInsn (0xef400000);
2129 emitLDSTs(0x30, insn
->dType
);
2131 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2132 emitGPR (0x00, insn
->def(0));
2136 CodeEmitterGM107::emitLDS()
2138 emitInsn (0xef480000);
2139 emitLDSTs(0x30, insn
->dType
);
2140 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2141 emitGPR (0x00, insn
->def(0));
2145 CodeEmitterGM107::emitLD()
2147 emitInsn (0x80000000);
2150 emitLDSTs(0x35, insn
->dType
);
2151 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2152 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2153 emitGPR (0x00, insn
->def(0));
2157 CodeEmitterGM107::emitSTL()
2159 emitInsn (0xef500000);
2160 emitLDSTs(0x30, insn
->dType
);
2162 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2163 emitGPR (0x00, insn
->src(1));
2167 CodeEmitterGM107::emitSTS()
2169 emitInsn (0xef580000);
2170 emitLDSTs(0x30, insn
->dType
);
2171 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2172 emitGPR (0x00, insn
->src(1));
2176 CodeEmitterGM107::emitST()
2178 emitInsn (0xa0000000);
2181 emitLDSTs(0x35, insn
->dType
);
2182 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2183 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2184 emitGPR (0x00, insn
->src(1));
2188 CodeEmitterGM107::emitALD()
2190 emitInsn (0xefd80000);
2191 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2192 emitGPR (0x27, insn
->src(0).getIndirect(1));
2195 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2196 emitGPR (0x00, insn
->def(0));
2200 CodeEmitterGM107::emitAST()
2202 emitInsn (0xeff00000);
2203 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2204 emitGPR (0x27, insn
->src(0).getIndirect(1));
2206 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2207 emitGPR (0x00, insn
->src(1));
2211 CodeEmitterGM107::emitISBERD()
2213 emitInsn(0xefd00000);
2214 emitGPR (0x08, insn
->src(0));
2215 emitGPR (0x00, insn
->def(0));
2219 CodeEmitterGM107::emitAL2P()
2221 emitInsn (0xefa00000);
2222 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2224 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2225 emitGPR (0x08, insn
->src(0).getIndirect(0));
2226 emitGPR (0x00, insn
->def(0));
2230 interpApply(const InterpEntry
*entry
, uint32_t *code
,
2231 bool force_persample_interp
, bool flatshade
)
2233 int ipa
= entry
->ipa
;
2234 int reg
= entry
->reg
;
2235 int loc
= entry
->loc
;
2238 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2239 ipa
= NV50_IR_INTERP_FLAT
;
2241 } else if (force_persample_interp
&&
2242 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2243 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2244 ipa
|= NV50_IR_INTERP_CENTROID
;
2246 code
[loc
+ 1] &= ~(0xf << 0x14);
2247 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2248 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2249 code
[loc
+ 0] &= ~(0xff << 0x14);
2250 code
[loc
+ 0] |= reg
<< 0x14;
2254 CodeEmitterGM107::emitIPA()
2256 int ipam
= 0, ipas
= 0;
2258 switch (insn
->getInterpMode()) {
2259 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2260 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2261 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2262 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2264 assert(!"invalid ipa mode");
2268 switch (insn
->getSampleMode()) {
2269 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2270 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2271 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2273 assert(!"invalid ipa sample mode");
2277 emitInsn (0xe0000000);
2278 emitField(0x36, 2, ipam
);
2279 emitField(0x34, 2, ipas
);
2281 emitField(0x2f, 3, 7);
2282 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2283 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2284 code
[1] |= 0x00000040; /* .idx */
2285 emitGPR(0x00, insn
->def(0));
2287 if (insn
->op
== OP_PINTERP
) {
2288 emitGPR(0x14, insn
->src(1));
2289 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2290 emitGPR(0x27, insn
->src(2));
2291 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2293 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2294 emitGPR(0x27, insn
->src(1));
2296 addInterp(insn
->ipa
, 0xff, interpApply
);
2299 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2304 CodeEmitterGM107::emitATOM()
2306 unsigned dType
, subOp
;
2307 switch (insn
->dType
) {
2308 case TYPE_U32
: dType
= 0; break;
2309 case TYPE_S32
: dType
= 1; break;
2310 case TYPE_U64
: dType
= 2; break;
2311 case TYPE_F32
: dType
= 3; break;
2312 case TYPE_B128
: dType
= 4; break;
2313 case TYPE_S64
: dType
= 5; break;
2314 default: assert(!"unexpected dType"); dType
= 0; break;
2316 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2319 subOp
= insn
->subOp
;
2320 assert(insn
->subOp
!= NV50_IR_SUBOP_ATOM_CAS
); /* XXX */
2322 emitInsn (0xed000000);
2323 emitField(0x34, 4, subOp
);
2324 emitField(0x31, 3, dType
);
2325 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2326 emitGPR (0x14, insn
->src(1));
2327 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2328 emitGPR (0x00, insn
->def(0));
2332 CodeEmitterGM107::emitCCTL()
2335 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2336 emitInsn(0xef600000);
2339 emitInsn(0xef800000);
2342 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2343 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2344 emitField(0x00, 4, insn
->subOp
);
2347 /*******************************************************************************
2349 ******************************************************************************/
2352 CodeEmitterGM107::emitPIXLD()
2354 emitInsn (0xefe80000);
2356 emitField(0x1f, 3, insn
->subOp
);
2357 emitGPR (0x08, insn
->src(0));
2358 emitGPR (0x00, insn
->def(0));
2361 /*******************************************************************************
2363 ******************************************************************************/
2366 CodeEmitterGM107::emitTEXs(int pos
)
2368 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2369 if (insn
->srcExists(src1
))
2370 emitGPR(pos
, insn
->src(src1
));
2376 CodeEmitterGM107::emitTEX()
2378 const TexInstruction
*insn
= this->insn
->asTex();
2381 if (!insn
->tex
.levelZero
) {
2383 case OP_TEX
: lodm
= 0; break;
2384 case OP_TXB
: lodm
= 2; break;
2385 case OP_TXL
: lodm
= 3; break;
2387 assert(!"invalid tex op");
2394 if (insn
->tex
.rIndirectSrc
>= 0) {
2395 emitInsn (0xdeb80000);
2396 emitField(0x35, 2, lodm
);
2397 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2399 emitInsn (0xc0380000);
2400 emitField(0x37, 2, lodm
);
2401 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2402 emitField(0x24, 13, insn
->tex
.r
);
2405 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2406 emitField(0x31, 1, insn
->tex
.liveOnly
);
2407 emitField(0x23, 1, insn
->tex
.derivAll
);
2408 emitField(0x1f, 4, insn
->tex
.mask
);
2409 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2410 insn
->tex
.target
.getDim() - 1);
2411 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2413 emitGPR (0x08, insn
->src(0));
2414 emitGPR (0x00, insn
->def(0));
2418 CodeEmitterGM107::emitTLD()
2420 const TexInstruction
*insn
= this->insn
->asTex();
2422 if (insn
->tex
.rIndirectSrc
>= 0) {
2423 emitInsn (0xdd380000);
2425 emitInsn (0xdc380000);
2426 emitField(0x24, 13, insn
->tex
.r
);
2429 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2430 emitField(0x32, 1, insn
->tex
.target
.isMS());
2431 emitField(0x31, 1, insn
->tex
.liveOnly
);
2432 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2433 emitField(0x1f, 4, insn
->tex
.mask
);
2434 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2435 insn
->tex
.target
.getDim() - 1);
2436 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2438 emitGPR (0x08, insn
->src(0));
2439 emitGPR (0x00, insn
->def(0));
2443 CodeEmitterGM107::emitTLD4()
2445 const TexInstruction
*insn
= this->insn
->asTex();
2447 if (insn
->tex
.rIndirectSrc
>= 0) {
2448 emitInsn (0xdef80000);
2449 emitField(0x26, 2, insn
->tex
.gatherComp
);
2450 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2451 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2453 emitInsn (0xc8380000);
2454 emitField(0x38, 2, insn
->tex
.gatherComp
);
2455 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2456 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2457 emitField(0x24, 13, insn
->tex
.r
);
2460 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2461 emitField(0x31, 1, insn
->tex
.liveOnly
);
2462 emitField(0x23, 1, insn
->tex
.derivAll
);
2463 emitField(0x1f, 4, insn
->tex
.mask
);
2464 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2465 insn
->tex
.target
.getDim() - 1);
2466 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2468 emitGPR (0x08, insn
->src(0));
2469 emitGPR (0x00, insn
->def(0));
2473 CodeEmitterGM107::emitTXD()
2475 const TexInstruction
*insn
= this->insn
->asTex();
2477 if (insn
->tex
.rIndirectSrc
>= 0) {
2478 emitInsn (0xde780000);
2480 emitInsn (0xde380000);
2481 emitField(0x24, 13, insn
->tex
.r
);
2484 emitField(0x31, 1, insn
->tex
.liveOnly
);
2485 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2486 emitField(0x1f, 4, insn
->tex
.mask
);
2487 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2488 insn
->tex
.target
.getDim() - 1);
2489 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2491 emitGPR (0x08, insn
->src(0));
2492 emitGPR (0x00, insn
->def(0));
2496 CodeEmitterGM107::emitTMML()
2498 const TexInstruction
*insn
= this->insn
->asTex();
2500 if (insn
->tex
.rIndirectSrc
>= 0) {
2501 emitInsn (0xdf600000);
2503 emitInsn (0xdf580000);
2504 emitField(0x24, 13, insn
->tex
.r
);
2507 emitField(0x31, 1, insn
->tex
.liveOnly
);
2508 emitField(0x23, 1, insn
->tex
.derivAll
);
2509 emitField(0x1f, 4, insn
->tex
.mask
);
2510 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2511 insn
->tex
.target
.getDim() - 1);
2512 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2514 emitGPR (0x08, insn
->src(0));
2515 emitGPR (0x00, insn
->def(0));
2519 CodeEmitterGM107::emitTXQ()
2521 const TexInstruction
*insn
= this->insn
->asTex();
2524 switch (insn
->tex
.query
) {
2525 case TXQ_DIMS
: type
= 0x01; break;
2526 case TXQ_TYPE
: type
= 0x02; break;
2527 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2528 case TXQ_FILTER
: type
= 0x10; break;
2529 case TXQ_LOD
: type
= 0x12; break;
2530 case TXQ_WRAP
: type
= 0x14; break;
2531 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2533 assert(!"invalid txq query");
2537 if (insn
->tex
.rIndirectSrc
>= 0) {
2538 emitInsn (0xdf500000);
2540 emitInsn (0xdf480000);
2541 emitField(0x24, 13, insn
->tex
.r
);
2544 emitField(0x31, 1, insn
->tex
.liveOnly
);
2545 emitField(0x1f, 4, insn
->tex
.mask
);
2546 emitField(0x16, 6, type
);
2547 emitGPR (0x08, insn
->src(0));
2548 emitGPR (0x00, insn
->def(0));
2552 CodeEmitterGM107::emitDEPBAR()
2554 emitInsn (0xf0f00000);
2555 emitField(0x1d, 1, 1); /* le */
2556 emitField(0x1a, 3, 5);
2557 emitField(0x14, 6, insn
->subOp
);
2558 emitField(0x00, 6, insn
->subOp
);
2561 /*******************************************************************************
2563 ******************************************************************************/
2566 CodeEmitterGM107::emitNOP()
2568 emitInsn(0x50b00000);
2572 CodeEmitterGM107::emitKIL()
2574 emitInsn (0xe3300000);
2575 emitCond5(0x00, CC_TR
);
2579 CodeEmitterGM107::emitOUT()
2581 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2582 const int emit
= insn
->op
== OP_EMIT
;
2584 switch (insn
->src(1).getFile()) {
2586 emitInsn(0xfbe00000);
2587 emitGPR (0x14, insn
->src(1));
2589 case FILE_IMMEDIATE
:
2590 emitInsn(0xf6e00000);
2591 emitIMMD(0x14, 19, insn
->src(1));
2593 case FILE_MEMORY_CONST
:
2594 emitInsn(0xebe00000);
2595 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2598 assert(!"bad src1 file");
2602 emitField(0x27, 2, (cut
<< 1) | emit
);
2603 emitGPR (0x08, insn
->src(0));
2604 emitGPR (0x00, insn
->def(0));
2607 /*******************************************************************************
2608 * assembler front-end
2609 ******************************************************************************/
2612 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2614 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2619 if (insn
->encSize
!= 8) {
2620 ERROR("skipping undecodable instruction: "); insn
->print();
2623 if (codeSize
+ size
> codeSizeLimit
) {
2624 ERROR("code emitter output buffer too small\n");
2628 if (writeIssueDelays
) {
2629 int n
= ((codeSize
& 0x1f) / 8) - 1;
2632 data
[0] = 0x00000000;
2633 data
[1] = 0x00000000;
2639 emitField(data
, n
* 21, 21, insn
->sched
);
2683 if (insn
->def(0).getFile() == FILE_GPR
&&
2684 insn
->src(0).getFile() != FILE_PREDICATE
)
2699 if (isFloatType(insn
->dType
)) {
2700 if (isFloatType(insn
->sType
))
2705 if (isFloatType(insn
->sType
))
2716 if (isFloatType(insn
->dType
)) {
2717 if (insn
->dType
== TYPE_F64
)
2726 if (isFloatType(insn
->dType
)) {
2727 if (insn
->dType
== TYPE_F64
)
2737 if (isFloatType(insn
->dType
)) {
2738 if (insn
->dType
== TYPE_F64
)
2748 if (isFloatType(insn
->dType
)) {
2749 if (insn
->dType
== TYPE_F64
)
2776 if (isFloatType(insn
->dType
))
2785 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2786 if (isFloatType(insn
->sType
))
2787 if (insn
->sType
== TYPE_F64
)
2794 if (isFloatType(insn
->sType
))
2795 if (insn
->sType
== TYPE_F64
)
2824 switch (insn
->src(0).getFile()) {
2825 case FILE_MEMORY_CONST
: emitLDC(); break;
2826 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2827 case FILE_MEMORY_SHARED
: emitLDS(); break;
2828 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2830 assert(!"invalid load");
2836 switch (insn
->src(0).getFile()) {
2837 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2838 case FILE_MEMORY_SHARED
: emitSTS(); break;
2839 case FILE_MEMORY_GLOBAL
: emitST(); break;
2841 assert(!"invalid load");
2908 assert(!"invalid opcode");
2924 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2929 /*******************************************************************************
2930 * sched data calculator
2931 ******************************************************************************/
2933 class SchedDataCalculatorGM107
: public Pass
2936 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2939 bool visit(BasicBlock
*bb
);
2943 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2945 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2947 insn
->sched
= 0x7e0;
2953 /*******************************************************************************
2955 ******************************************************************************/
2958 CodeEmitterGM107::prepareEmission(Function
*func
)
2960 SchedDataCalculatorGM107
sched(targ
);
2961 CodeEmitter::prepareEmission(func
);
2962 sched
.run(func
, true, true);
2965 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
2967 return (size
+ 23) / 24;
2971 CodeEmitterGM107::prepareEmission(Program
*prog
)
2973 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
2974 !fi
.end(); fi
.next()) {
2975 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
2976 func
->binPos
= prog
->binSize
;
2977 prepareEmission(func
);
2979 // adjust sizes & positions for schedulding info:
2980 if (prog
->getTarget()->hasSWSched
) {
2981 uint32_t adjPos
= func
->binPos
;
2982 BasicBlock
*bb
= NULL
;
2983 for (int i
= 0; i
< func
->bbCount
; ++i
) {
2984 bb
= func
->bbArray
[i
];
2985 int32_t adjSize
= bb
->binSize
;
2987 adjSize
-= 32 - adjPos
% 32;
2991 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
2992 bb
->binPos
= adjPos
;
2993 bb
->binSize
= adjSize
;
2997 func
->binSize
= adjPos
- func
->binPos
;
3000 prog
->binSize
+= func
->binSize
;
3004 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3005 : CodeEmitter(target
),
3007 writeIssueDelays(target
->hasSWSched
)
3010 codeSize
= codeSizeLimit
= 0;
3015 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3017 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3018 emit
->setProgramType(type
);
3022 } // namespace nv50_ir