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
);
200 /*******************************************************************************
201 * general instruction layout/fields
202 ******************************************************************************/
205 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
208 uint32_t m
= ((1ULL << s
) - 1);
209 uint64_t d
= (uint64_t)(v
& m
) << b
;
210 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
217 CodeEmitterGM107::emitPred()
219 if (insn
->predSrc
>= 0) {
220 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
221 emitField(19, 1, insn
->cc
== CC_NOT_P
);
228 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
230 code
[0] = 0x00000000;
237 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
239 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
243 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
245 int id
= val
? val
->reg
.data
.id
: -1;
248 case SV_LANEID
: id
= 0x00; break;
249 case SV_VERTEX_COUNT
: id
= 0x10; break;
250 case SV_INVOCATION_ID
: id
= 0x11; break;
251 case SV_THREAD_KILL
: id
= 0x13; break;
252 case SV_INVOCATION_INFO
: id
= 0x1d; break;
253 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
254 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
256 assert(!"invalid system value");
261 emitField(pos
, 8, id
);
265 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
267 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
271 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
274 const Value
*v
= ref
.get();
275 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
277 emitGPR(gpr
, ref
.getIndirect(0));
278 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
282 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
285 const Value
*v
= ref
.get();
286 const Symbol
*s
= v
->asSym();
288 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
290 emitField(buf
, 5, v
->reg
.fileIndex
);
292 emitGPR(gpr
, ref
.getIndirect(0));
293 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
297 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
299 if (ref
.getFile() == FILE_IMMEDIATE
) {
300 const ImmediateValue
*imm
= ref
.get()->asImm();
301 if (isFloatType(insn
->sType
)) {
302 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
305 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
306 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
314 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
316 const ImmediateValue
*imm
= ref
.get()->asImm();
317 uint32_t val
= imm
->reg
.data
.u32
;
320 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
321 assert(!(val
& 0x00000fff));
323 } else if (insn
->sType
== TYPE_F64
) {
324 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
325 val
= imm
->reg
.data
.u64
>> 44;
327 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
328 emitField( 56, 1, (val
& 0x80000) >> 19);
329 emitField(pos
, len
, (val
& 0x7ffff));
331 emitField(pos
, len
, val
);
335 /*******************************************************************************
337 ******************************************************************************/
340 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
345 case CC_FL
: data
= 0x00; break;
347 case CC_LT
: data
= 0x01; break;
349 case CC_EQ
: data
= 0x02; break;
351 case CC_LE
: data
= 0x03; break;
353 case CC_GT
: data
= 0x04; break;
355 case CC_NE
: data
= 0x05; break;
357 case CC_GE
: data
= 0x06; break;
358 case CC_TR
: data
= 0x07; break;
360 assert(!"invalid cond3");
364 emitField(pos
, 3, data
);
368 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
373 case CC_FL
: data
= 0x00; break;
374 case CC_LT
: data
= 0x01; break;
375 case CC_EQ
: data
= 0x02; break;
376 case CC_LE
: data
= 0x03; break;
377 case CC_GT
: data
= 0x04; break;
378 case CC_NE
: data
= 0x05; break;
379 case CC_GE
: data
= 0x06; break;
380 // case CC_NUM: data = 0x07; break;
381 // case CC_NAN: data = 0x08; break;
382 case CC_LTU
: data
= 0x09; break;
383 case CC_EQU
: data
= 0x0a; break;
384 case CC_LEU
: data
= 0x0b; break;
385 case CC_GTU
: data
= 0x0c; break;
386 case CC_NEU
: data
= 0x0d; break;
387 case CC_GEU
: data
= 0x0e; break;
388 case CC_TR
: data
= 0x0f; break;
390 assert(!"invalid cond4");
394 emitField(pos
, 4, data
);
398 CodeEmitterGM107::emitO(int pos
)
400 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
404 CodeEmitterGM107::emitP(int pos
)
406 emitField(pos
, 1, insn
->perPatch
);
410 CodeEmitterGM107::emitSAT(int pos
)
412 emitField(pos
, 1, insn
->saturate
);
416 CodeEmitterGM107::emitCC(int pos
)
418 emitField(pos
, 1, insn
->defExists(1));
422 CodeEmitterGM107::emitX(int pos
)
424 emitField(pos
, 1, insn
->flagsSrc
>= 0);
428 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
430 emitField(pos
, 1, ref
.mod
.abs());
434 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
436 emitField(pos
, 1, ref
.mod
.neg());
440 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
442 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
446 CodeEmitterGM107::emitFMZ(int pos
, int len
)
448 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
452 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
456 case ROUND_NI
: ri
= 1;
457 case ROUND_N
: rm
= 0; break;
458 case ROUND_MI
: ri
= 1;
459 case ROUND_M
: rm
= 1; break;
460 case ROUND_PI
: ri
= 1;
461 case ROUND_P
: rm
= 2; break;
462 case ROUND_ZI
: ri
= 1;
463 case ROUND_Z
: rm
= 3; break;
465 assert(!"invalid round mode");
468 emitField(rip
, 1, ri
);
469 emitField(rmp
, 2, rm
);
473 CodeEmitterGM107::emitPDIV(int pos
)
475 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
476 if (insn
->postFactor
> 0)
477 emitField(pos
, 3, 7 - insn
->postFactor
);
479 emitField(pos
, 3, 0 - insn
->postFactor
);
483 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
485 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
488 /*******************************************************************************
490 ******************************************************************************/
493 CodeEmitterGM107::emitEXIT()
495 emitInsn (0xe3000000);
496 emitCond5(0x00, CC_TR
);
500 CodeEmitterGM107::emitBRA()
502 const FlowInstruction
*insn
= this->insn
->asFlow();
505 if (insn
->indirect
) {
507 emitInsn(0xe2000000); // JMX
509 emitInsn(0xe2500000); // BRX
513 emitInsn(0xe2100000); // JMP
515 emitInsn(0xe2400000); // BRA
516 emitField(0x07, 1, insn
->allWarp
);
519 emitField(0x06, 1, insn
->limit
);
520 emitCond5(0x00, CC_TR
);
522 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
523 int32_t pos
= insn
->target
.bb
->binPos
;
524 if (writeIssueDelays
&& !(pos
& 0x1f))
527 emitField(0x14, 24, pos
- (codeSize
+ 8));
529 emitField(0x14, 32, pos
);
531 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
532 emitField(0x05, 1, 1);
537 CodeEmitterGM107::emitCAL()
539 const FlowInstruction
*insn
= this->insn
->asFlow();
541 if (insn
->absolute
) {
542 emitInsn(0xe2200000, 0); // JCAL
544 emitInsn(0xe2600000, 0); // CAL
547 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
549 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
552 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
553 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
554 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
556 emitField(0x14, 32, insn
->target
.bb
->binPos
);
560 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
561 emitField(0x05, 1, 1);
566 CodeEmitterGM107::emitPCNT()
568 const FlowInstruction
*insn
= this->insn
->asFlow();
570 emitInsn(0xe2b00000, 0);
572 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
573 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
575 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
576 emitField(0x05, 1, 1);
581 CodeEmitterGM107::emitCONT()
583 emitInsn (0xe3500000);
584 emitCond5(0x00, CC_TR
);
588 CodeEmitterGM107::emitPBK()
590 const FlowInstruction
*insn
= this->insn
->asFlow();
592 emitInsn(0xe2a00000, 0);
594 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
595 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
597 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
598 emitField(0x05, 1, 1);
603 CodeEmitterGM107::emitBRK()
605 emitInsn (0xe3400000);
606 emitCond5(0x00, CC_TR
);
610 CodeEmitterGM107::emitPRET()
612 const FlowInstruction
*insn
= this->insn
->asFlow();
614 emitInsn(0xe2700000, 0);
616 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
617 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
619 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
620 emitField(0x05, 1, 1);
625 CodeEmitterGM107::emitRET()
627 emitInsn (0xe3200000);
628 emitCond5(0x00, CC_TR
);
632 CodeEmitterGM107::emitSSY()
634 const FlowInstruction
*insn
= this->insn
->asFlow();
636 emitInsn(0xe2900000, 0);
638 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
639 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
641 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
642 emitField(0x05, 1, 1);
647 CodeEmitterGM107::emitSYNC()
649 emitInsn (0xf0f80000);
650 emitCond5(0x00, CC_TR
);
654 CodeEmitterGM107::emitSAM()
656 emitInsn(0xe3700000, 0);
660 CodeEmitterGM107::emitRAM()
662 emitInsn(0xe3800000, 0);
665 /*******************************************************************************
667 ******************************************************************************/
669 /*******************************************************************************
670 * movement / conversion
671 ******************************************************************************/
674 CodeEmitterGM107::emitMOV()
676 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
677 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
678 switch (insn
->src(0).getFile()) {
680 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
681 emitInsn(0x5b6a0000);
684 emitInsn(0x5c980000);
686 emitGPR (0x14, insn
->src(0));
688 case FILE_MEMORY_CONST
:
689 emitInsn(0x4c980000);
690 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
693 emitInsn(0x38980000);
694 emitIMMD(0x14, 19, insn
->src(0));
697 emitInsn(0x50880000);
698 emitPRED(0x0c, insn
->src(0));
703 assert(!"bad src file");
706 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
707 insn
->src(0).getFile() != FILE_PREDICATE
)
708 emitField(0x27, 4, insn
->lanes
);
710 emitInsn (0x01000000);
711 emitIMMD (0x14, 32, insn
->src(0));
712 emitField(0x0c, 4, insn
->lanes
);
715 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
717 emitPRED(0x03, insn
->def(0));
720 emitGPR(0x00, insn
->def(0));
725 CodeEmitterGM107::emitS2R()
727 emitInsn(0xf0c80000);
728 emitSYS (0x14, insn
->src(0));
729 emitGPR (0x00, insn
->def(0));
733 CodeEmitterGM107::emitF2F()
735 RoundMode rnd
= insn
->rnd
;
738 case OP_FLOOR
: rnd
= ROUND_MI
; break;
739 case OP_CEIL
: rnd
= ROUND_PI
; break;
740 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
745 switch (insn
->src(0).getFile()) {
747 emitInsn(0x5ca80000);
748 emitGPR (0x14, insn
->src(0));
750 case FILE_MEMORY_CONST
:
751 emitInsn(0x4ca80000);
752 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
755 emitInsn(0x38a80000);
756 emitIMMD(0x14, 19, insn
->src(0));
759 assert(!"bad src0 file");
763 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
764 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
766 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
768 emitField(0x29, 1, insn
->subOp
);
769 emitRND (0x27, rnd
, 0x2a);
770 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
771 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
772 emitGPR (0x00, insn
->def(0));
776 CodeEmitterGM107::emitF2I()
778 RoundMode rnd
= insn
->rnd
;
781 case OP_FLOOR
: rnd
= ROUND_M
; break;
782 case OP_CEIL
: rnd
= ROUND_P
; break;
783 case OP_TRUNC
: rnd
= ROUND_Z
; break;
788 switch (insn
->src(0).getFile()) {
790 emitInsn(0x5cb00000);
791 emitGPR (0x14, insn
->src(0));
793 case FILE_MEMORY_CONST
:
794 emitInsn(0x4cb00000);
795 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
798 emitInsn(0x38b00000);
799 emitIMMD(0x14, 19, insn
->src(0));
802 assert(!"bad src0 file");
806 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
808 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
810 emitRND (0x27, rnd
, 0x2a);
811 emitField(0x0c, 1, isSignedType(insn
->dType
));
812 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
813 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
814 emitGPR (0x00, insn
->def(0));
818 CodeEmitterGM107::emitI2F()
820 RoundMode rnd
= insn
->rnd
;
823 case OP_FLOOR
: rnd
= ROUND_M
; break;
824 case OP_CEIL
: rnd
= ROUND_P
; break;
825 case OP_TRUNC
: rnd
= ROUND_Z
; break;
830 switch (insn
->src(0).getFile()) {
832 emitInsn(0x5cb80000);
833 emitGPR (0x14, insn
->src(0));
835 case FILE_MEMORY_CONST
:
836 emitInsn(0x4cb80000);
837 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
840 emitInsn(0x38b80000);
841 emitIMMD(0x14, 19, insn
->src(0));
844 assert(!"bad src0 file");
848 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
850 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
851 emitField(0x29, 2, insn
->subOp
);
852 emitRND (0x27, rnd
, -1);
853 emitField(0x0d, 1, isSignedType(insn
->sType
));
854 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
855 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
856 emitGPR (0x00, insn
->def(0));
860 CodeEmitterGM107::emitI2I()
862 switch (insn
->src(0).getFile()) {
864 emitInsn(0x5ce00000);
865 emitGPR (0x14, insn
->src(0));
867 case FILE_MEMORY_CONST
:
868 emitInsn(0x4ce00000);
869 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
872 emitInsn(0x38e00000);
873 emitIMMD(0x14, 19, insn
->src(0));
876 assert(!"bad src0 file");
881 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
883 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
884 emitField(0x29, 2, insn
->subOp
);
885 emitField(0x0d, 1, isSignedType(insn
->sType
));
886 emitField(0x0c, 1, isSignedType(insn
->dType
));
887 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
888 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
889 emitGPR (0x00, insn
->def(0));
893 CodeEmitterGM107::emitSHFL()
897 emitInsn (0xef100000);
899 switch (insn
->src(1).getFile()) {
901 emitGPR(0x14, insn
->src(1));
904 emitIMMD(0x14, 5, insn
->src(1));
908 assert(!"invalid src1 file");
912 /*XXX: what is this arg? hardcode immediate for now */
913 emitField(0x22, 13, 0x1c03);
917 emitField(0x1e, 2, insn
->subOp
);
918 emitField(0x1c, 2, type
);
919 emitGPR (0x08, insn
->src(0));
920 emitGPR (0x00, insn
->def(0));
923 /*******************************************************************************
925 ******************************************************************************/
928 CodeEmitterGM107::emitDADD()
930 switch (insn
->src(1).getFile()) {
932 emitInsn(0x5c700000);
933 emitGPR (0x14, insn
->src(1));
935 case FILE_MEMORY_CONST
:
936 emitInsn(0x4c700000);
937 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
940 emitInsn(0x38700000);
941 emitIMMD(0x14, 19, insn
->src(1));
944 assert(!"bad src1 file");
947 emitABS(0x31, insn
->src(1));
948 emitNEG(0x30, insn
->src(0));
950 emitABS(0x2e, insn
->src(0));
951 emitNEG(0x2d, insn
->src(1));
953 if (insn
->op
== OP_SUB
)
954 code
[1] ^= 0x00002000;
956 emitGPR(0x08, insn
->src(0));
957 emitGPR(0x00, insn
->def(0));
961 CodeEmitterGM107::emitDMUL()
963 switch (insn
->src(1).getFile()) {
965 emitInsn(0x5c800000);
966 emitGPR (0x14, insn
->src(1));
968 case FILE_MEMORY_CONST
:
969 emitInsn(0x4c800000);
970 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
973 emitInsn(0x38800000);
974 emitIMMD(0x14, 19, insn
->src(1));
977 assert(!"bad src1 file");
981 emitNEG2(0x30, insn
->src(0), insn
->src(1));
984 emitGPR (0x08, insn
->src(0));
985 emitGPR (0x00, insn
->def(0));
989 CodeEmitterGM107::emitDFMA()
991 switch(insn
->src(2).getFile()) {
993 switch (insn
->src(1).getFile()) {
995 emitInsn(0x5b700000);
996 emitGPR (0x14, insn
->src(1));
998 case FILE_MEMORY_CONST
:
999 emitInsn(0x4b700000);
1000 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1002 case FILE_IMMEDIATE
:
1003 emitInsn(0x36700000);
1004 emitIMMD(0x14, 19, insn
->src(1));
1007 assert(!"bad src1 file");
1010 emitGPR (0x27, insn
->src(2));
1012 case FILE_MEMORY_CONST
:
1013 emitInsn(0x53700000);
1014 emitGPR (0x27, insn
->src(1));
1015 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1018 assert(!"bad src2 file");
1023 emitNEG (0x31, insn
->src(2));
1024 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1026 emitGPR (0x08, insn
->src(0));
1027 emitGPR (0x00, insn
->def(0));
1031 CodeEmitterGM107::emitDMNMX()
1033 switch (insn
->src(1).getFile()) {
1035 emitInsn(0x5c500000);
1036 emitGPR (0x14, insn
->src(1));
1038 case FILE_MEMORY_CONST
:
1039 emitInsn(0x4c500000);
1040 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1042 case FILE_IMMEDIATE
:
1043 emitInsn(0x38500000);
1044 emitIMMD(0x14, 19, insn
->src(1));
1047 assert(!"bad src1 file");
1051 emitABS (0x31, insn
->src(1));
1052 emitNEG (0x30, insn
->src(0));
1054 emitABS (0x2e, insn
->src(0));
1055 emitNEG (0x2d, insn
->src(1));
1056 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1058 emitGPR (0x08, insn
->src(0));
1059 emitGPR (0x00, insn
->def(0));
1063 CodeEmitterGM107::emitDSET()
1065 const CmpInstruction
*insn
= this->insn
->asCmp();
1067 switch (insn
->src(1).getFile()) {
1069 emitInsn(0x59000000);
1070 emitGPR (0x14, insn
->src(1));
1072 case FILE_MEMORY_CONST
:
1073 emitInsn(0x49000000);
1074 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1076 case FILE_IMMEDIATE
:
1077 emitInsn(0x32000000);
1078 emitIMMD(0x14, 19, insn
->src(1));
1081 assert(!"bad src1 file");
1085 if (insn
->op
!= OP_SET
) {
1087 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1088 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1089 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1091 assert(!"invalid set op");
1094 emitPRED(0x27, insn
->src(2));
1099 emitABS (0x36, insn
->src(0));
1100 emitNEG (0x35, insn
->src(1));
1101 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1102 emitCond4(0x30, insn
->setCond
);
1104 emitABS (0x2c, insn
->src(1));
1105 emitNEG (0x2b, insn
->src(0));
1106 emitGPR (0x08, insn
->src(0));
1107 emitGPR (0x00, insn
->def(0));
1111 CodeEmitterGM107::emitDSETP()
1113 const CmpInstruction
*insn
= this->insn
->asCmp();
1115 switch (insn
->src(1).getFile()) {
1117 emitInsn(0x5b800000);
1118 emitGPR (0x14, insn
->src(1));
1120 case FILE_MEMORY_CONST
:
1121 emitInsn(0x4b800000);
1122 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1124 case FILE_IMMEDIATE
:
1125 emitInsn(0x36800000);
1126 emitIMMD(0x14, 19, insn
->src(1));
1129 assert(!"bad src1 file");
1133 if (insn
->op
!= OP_SET
) {
1135 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1136 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1137 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1139 assert(!"invalid set op");
1142 emitPRED(0x27, insn
->src(2));
1147 emitCond4(0x30, insn
->setCond
);
1148 emitABS (0x2c, insn
->src(1));
1149 emitNEG (0x2b, insn
->src(0));
1150 emitGPR (0x08, insn
->src(0));
1151 emitABS (0x07, insn
->src(0));
1152 emitNEG (0x06, insn
->src(1));
1153 emitPRED (0x03, insn
->def(0));
1154 if (insn
->defExists(1))
1155 emitPRED(0x00, insn
->def(1));
1160 /*******************************************************************************
1162 ******************************************************************************/
1165 CodeEmitterGM107::emitFADD()
1167 if (!longIMMD(insn
->src(1))) {
1168 switch (insn
->src(1).getFile()) {
1170 emitInsn(0x5c580000);
1171 emitGPR (0x14, insn
->src(1));
1173 case FILE_MEMORY_CONST
:
1174 emitInsn(0x4c580000);
1175 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1177 case FILE_IMMEDIATE
:
1178 emitInsn(0x38580000);
1179 emitIMMD(0x14, 19, insn
->src(1));
1182 assert(!"bad src1 file");
1186 emitABS(0x31, insn
->src(1));
1187 emitNEG(0x30, insn
->src(0));
1189 emitABS(0x2e, insn
->src(0));
1190 emitNEG(0x2d, insn
->src(1));
1193 emitInsn(0x08000000);
1194 emitABS(0x39, insn
->src(1));
1195 emitNEG(0x38, insn
->src(0));
1197 emitABS(0x36, insn
->src(0));
1198 emitNEG(0x35, insn
->src(1));
1200 emitIMMD(0x14, 32, insn
->src(1));
1203 if (insn
->op
== OP_SUB
)
1204 code
[1] ^= 0x00002000;
1206 emitGPR(0x08, insn
->src(0));
1207 emitGPR(0x00, insn
->def(0));
1211 CodeEmitterGM107::emitFMUL()
1213 if (!longIMMD(insn
->src(1))) {
1214 switch (insn
->src(1).getFile()) {
1216 emitInsn(0x5c680000);
1217 emitGPR (0x14, insn
->src(1));
1219 case FILE_MEMORY_CONST
:
1220 emitInsn(0x4c680000);
1221 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1223 case FILE_IMMEDIATE
:
1224 emitInsn(0x38680000);
1225 emitIMMD(0x14, 19, insn
->src(1));
1228 assert(!"bad src1 file");
1232 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1238 emitInsn(0x1e000000);
1242 emitIMMD(0x14, 32, insn
->src(1));
1243 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1244 code
[1] ^= 0x00080000; /* flip immd sign bit */
1247 emitGPR(0x08, insn
->src(0));
1248 emitGPR(0x00, insn
->def(0));
1252 CodeEmitterGM107::emitFFMA()
1254 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1255 switch(insn
->src(2).getFile()) {
1257 switch (insn
->src(1).getFile()) {
1259 emitInsn(0x59800000);
1260 emitGPR (0x14, insn
->src(1));
1262 case FILE_MEMORY_CONST
:
1263 emitInsn(0x49800000);
1264 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1266 case FILE_IMMEDIATE
:
1267 emitInsn(0x32800000);
1268 emitIMMD(0x14, 19, insn
->src(1));
1271 assert(!"bad src1 file");
1274 emitGPR (0x27, insn
->src(2));
1276 case FILE_MEMORY_CONST
:
1277 emitInsn(0x51800000);
1278 emitGPR (0x27, insn
->src(1));
1279 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1282 assert(!"bad src2 file");
1287 emitNEG (0x31, insn
->src(2));
1288 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1292 emitGPR(0x08, insn
->src(0));
1293 emitGPR(0x00, insn
->def(0));
1297 CodeEmitterGM107::emitMUFU()
1302 case OP_COS
: mufu
= 0; break;
1303 case OP_SIN
: mufu
= 1; break;
1304 case OP_EX2
: mufu
= 2; break;
1305 case OP_LG2
: mufu
= 3; break;
1306 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1307 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1309 assert(!"invalid mufu");
1313 emitInsn (0x50800000);
1315 emitNEG (0x30, insn
->src(0));
1316 emitABS (0x2e, insn
->src(0));
1317 emitField(0x14, 3, mufu
);
1318 emitGPR (0x08, insn
->src(0));
1319 emitGPR (0x00, insn
->def(0));
1323 CodeEmitterGM107::emitFMNMX()
1325 switch (insn
->src(1).getFile()) {
1327 emitInsn(0x5c600000);
1328 emitGPR (0x14, insn
->src(1));
1330 case FILE_MEMORY_CONST
:
1331 emitInsn(0x4c600000);
1332 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1334 case FILE_IMMEDIATE
:
1335 emitInsn(0x38600000);
1336 emitIMMD(0x14, 19, insn
->src(1));
1339 assert(!"bad src1 file");
1343 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1346 emitABS(0x31, insn
->src(1));
1347 emitNEG(0x30, insn
->src(0));
1349 emitABS(0x2e, insn
->src(0));
1350 emitNEG(0x2d, insn
->src(1));
1352 emitGPR(0x08, insn
->src(0));
1353 emitGPR(0x00, insn
->def(0));
1357 CodeEmitterGM107::emitRRO()
1359 switch (insn
->src(0).getFile()) {
1361 emitInsn(0x5c900000);
1362 emitGPR (0x14, insn
->src(0));
1364 case FILE_MEMORY_CONST
:
1365 emitInsn(0x4c900000);
1366 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1368 case FILE_IMMEDIATE
:
1369 emitInsn(0x38900000);
1370 emitIMMD(0x14, 19, insn
->src(0));
1373 assert(!"bad src file");
1377 emitABS (0x31, insn
->src(0));
1378 emitNEG (0x2d, insn
->src(0));
1379 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1380 emitGPR (0x00, insn
->def(0));
1384 CodeEmitterGM107::emitFCMP()
1386 const CmpInstruction
*insn
= this->insn
->asCmp();
1387 CondCode cc
= insn
->setCond
;
1389 if (insn
->src(2).mod
.neg())
1390 cc
= reverseCondCode(cc
);
1392 switch(insn
->src(2).getFile()) {
1394 switch (insn
->src(1).getFile()) {
1396 emitInsn(0x5ba00000);
1397 emitGPR (0x14, insn
->src(1));
1399 case FILE_MEMORY_CONST
:
1400 emitInsn(0x4ba00000);
1401 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1403 case FILE_IMMEDIATE
:
1404 emitInsn(0x36a00000);
1405 emitIMMD(0x14, 19, insn
->src(1));
1408 assert(!"bad src1 file");
1411 emitGPR (0x27, insn
->src(2));
1413 case FILE_MEMORY_CONST
:
1414 emitInsn(0x53a00000);
1415 emitGPR (0x27, insn
->src(1));
1416 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1419 assert(!"bad src2 file");
1423 emitCond4(0x30, cc
);
1425 emitGPR (0x08, insn
->src(0));
1426 emitGPR (0x00, insn
->def(0));
1430 CodeEmitterGM107::emitFSET()
1432 const CmpInstruction
*insn
= this->insn
->asCmp();
1434 switch (insn
->src(1).getFile()) {
1436 emitInsn(0x58000000);
1437 emitGPR (0x14, insn
->src(1));
1439 case FILE_MEMORY_CONST
:
1440 emitInsn(0x48000000);
1441 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1443 case FILE_IMMEDIATE
:
1444 emitInsn(0x30000000);
1445 emitIMMD(0x14, 19, insn
->src(1));
1448 assert(!"bad src1 file");
1452 if (insn
->op
!= OP_SET
) {
1454 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1455 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1456 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1458 assert(!"invalid set op");
1461 emitPRED(0x27, insn
->src(2));
1467 emitABS (0x36, insn
->src(0));
1468 emitNEG (0x35, insn
->src(1));
1469 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1470 emitCond4(0x30, insn
->setCond
);
1472 emitABS (0x2c, insn
->src(1));
1473 emitNEG (0x2b, insn
->src(0));
1474 emitGPR (0x08, insn
->src(0));
1475 emitGPR (0x00, insn
->def(0));
1479 CodeEmitterGM107::emitFSETP()
1481 const CmpInstruction
*insn
= this->insn
->asCmp();
1483 switch (insn
->src(1).getFile()) {
1485 emitInsn(0x5bb00000);
1486 emitGPR (0x14, insn
->src(1));
1488 case FILE_MEMORY_CONST
:
1489 emitInsn(0x4bb00000);
1490 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1492 case FILE_IMMEDIATE
:
1493 emitInsn(0x36b00000);
1494 emitIMMD(0x14, 19, insn
->src(1));
1497 assert(!"bad src1 file");
1501 if (insn
->op
!= OP_SET
) {
1503 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1504 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1505 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1507 assert(!"invalid set op");
1510 emitPRED(0x27, insn
->src(2));
1515 emitCond4(0x30, insn
->setCond
);
1517 emitABS (0x2c, insn
->src(1));
1518 emitNEG (0x2b, insn
->src(0));
1519 emitGPR (0x08, insn
->src(0));
1520 emitABS (0x07, insn
->src(0));
1521 emitNEG (0x06, insn
->src(1));
1522 emitPRED (0x03, insn
->def(0));
1523 if (insn
->defExists(1))
1524 emitPRED(0x00, insn
->def(1));
1530 CodeEmitterGM107::emitFSWZADD()
1532 emitInsn (0x50f80000);
1536 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1537 emitField(0x1c, 8, insn
->subOp
);
1538 if (insn
->predSrc
!= 1)
1539 emitGPR (0x14, insn
->src(1));
1542 emitGPR (0x08, insn
->src(0));
1543 emitGPR (0x00, insn
->def(0));
1546 /*******************************************************************************
1548 ******************************************************************************/
1551 CodeEmitterGM107::emitLOP()
1556 case OP_AND
: lop
= 0; break;
1557 case OP_OR
: lop
= 1; break;
1558 case OP_XOR
: lop
= 2; break;
1560 assert(!"invalid lop");
1564 if (!longIMMD(insn
->src(1))) {
1565 switch (insn
->src(1).getFile()) {
1567 emitInsn(0x5c400000);
1568 emitGPR (0x14, insn
->src(1));
1570 case FILE_MEMORY_CONST
:
1571 emitInsn(0x4c400000);
1572 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1574 case FILE_IMMEDIATE
:
1575 emitInsn(0x38400000);
1576 emitIMMD(0x14, 19, insn
->src(1));
1579 assert(!"bad src1 file");
1584 emitField(0x29, 2, lop
);
1585 emitINV (0x28, insn
->src(1));
1586 emitINV (0x27, insn
->src(0));
1588 emitInsn (0x04000000);
1590 emitINV (0x38, insn
->src(1));
1591 emitINV (0x37, insn
->src(0));
1592 emitField(0x35, 2, lop
);
1593 emitIMMD (0x14, 32, insn
->src(1));
1596 emitGPR (0x08, insn
->src(0));
1597 emitGPR (0x00, insn
->def(0));
1600 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1602 CodeEmitterGM107::emitNOT()
1604 if (!longIMMD(insn
->src(0))) {
1605 switch (insn
->src(0).getFile()) {
1607 emitInsn(0x5c400700);
1608 emitGPR (0x14, insn
->src(0));
1610 case FILE_MEMORY_CONST
:
1611 emitInsn(0x4c400700);
1612 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1614 case FILE_IMMEDIATE
:
1615 emitInsn(0x38400700);
1616 emitIMMD(0x14, 19, insn
->src(0));
1619 assert(!"bad src1 file");
1624 emitInsn (0x05600000);
1625 emitIMMD (0x14, 32, insn
->src(1));
1629 emitGPR(0x00, insn
->def(0));
1633 CodeEmitterGM107::emitIADD()
1635 if (!longIMMD(insn
->src(1))) {
1636 switch (insn
->src(1).getFile()) {
1638 emitInsn(0x5c100000);
1639 emitGPR (0x14, insn
->src(1));
1641 case FILE_MEMORY_CONST
:
1642 emitInsn(0x4c100000);
1643 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1645 case FILE_IMMEDIATE
:
1646 emitInsn(0x38100000);
1647 emitIMMD(0x14, 19, insn
->src(1));
1650 assert(!"bad src1 file");
1654 emitNEG(0x31, insn
->src(0));
1655 emitNEG(0x30, insn
->src(1));
1659 emitInsn(0x1c000000);
1663 emitIMMD(0x14, 32, insn
->src(1));
1666 if (insn
->op
== OP_SUB
)
1667 code
[1] ^= 0x00010000;
1669 emitGPR(0x08, insn
->src(0));
1670 emitGPR(0x00, insn
->def(0));
1674 CodeEmitterGM107::emitIMUL()
1676 if (!longIMMD(insn
->src(1))) {
1677 switch (insn
->src(1).getFile()) {
1679 emitInsn(0x5c380000);
1680 emitGPR (0x14, insn
->src(1));
1682 case FILE_MEMORY_CONST
:
1683 emitInsn(0x4c380000);
1684 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1686 case FILE_IMMEDIATE
:
1687 emitInsn(0x38380000);
1688 emitIMMD(0x14, 19, insn
->src(1));
1691 assert(!"bad src1 file");
1695 emitField(0x29, 1, isSignedType(insn
->sType
));
1696 emitField(0x28, 1, isSignedType(insn
->dType
));
1697 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1699 emitInsn (0x1f000000);
1700 emitField(0x37, 1, isSignedType(insn
->sType
));
1701 emitField(0x36, 1, isSignedType(insn
->dType
));
1702 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1704 emitIMMD (0x14, 32, insn
->src(1));
1707 emitGPR(0x08, insn
->src(0));
1708 emitGPR(0x00, insn
->def(0));
1712 CodeEmitterGM107::emitIMAD()
1714 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1715 switch(insn
->src(2).getFile()) {
1717 switch (insn
->src(1).getFile()) {
1719 emitInsn(0x5a000000);
1720 emitGPR (0x14, insn
->src(1));
1722 case FILE_MEMORY_CONST
:
1723 emitInsn(0x4a000000);
1724 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1726 case FILE_IMMEDIATE
:
1727 emitInsn(0x34000000);
1728 emitIMMD(0x14, 19, insn
->src(1));
1731 assert(!"bad src1 file");
1734 emitGPR (0x27, insn
->src(2));
1736 case FILE_MEMORY_CONST
:
1737 emitInsn(0x52000000);
1738 emitGPR (0x27, insn
->src(1));
1739 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1742 assert(!"bad src2 file");
1746 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1747 emitField(0x35, 1, isSignedType(insn
->sType
));
1748 emitNEG (0x34, insn
->src(2));
1749 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1752 emitField(0x30, 1, isSignedType(insn
->dType
));
1754 emitGPR (0x08, insn
->src(0));
1755 emitGPR (0x00, insn
->def(0));
1759 CodeEmitterGM107::emitIMNMX()
1761 switch (insn
->src(1).getFile()) {
1763 emitInsn(0x5c200000);
1764 emitGPR (0x14, insn
->src(1));
1766 case FILE_MEMORY_CONST
:
1767 emitInsn(0x4c200000);
1768 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1770 case FILE_IMMEDIATE
:
1771 emitInsn(0x38200000);
1772 emitIMMD(0x14, 19, insn
->src(1));
1775 assert(!"bad src1 file");
1779 emitField(0x30, 1, isSignedType(insn
->dType
));
1781 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1783 emitGPR (0x08, insn
->src(0));
1784 emitGPR (0x00, insn
->def(0));
1788 CodeEmitterGM107::emitICMP()
1790 const CmpInstruction
*insn
= this->insn
->asCmp();
1791 CondCode cc
= insn
->setCond
;
1793 if (insn
->src(2).mod
.neg())
1794 cc
= reverseCondCode(cc
);
1796 switch(insn
->src(2).getFile()) {
1798 switch (insn
->src(1).getFile()) {
1800 emitInsn(0x5b400000);
1801 emitGPR (0x14, insn
->src(1));
1803 case FILE_MEMORY_CONST
:
1804 emitInsn(0x4b400000);
1805 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1807 case FILE_IMMEDIATE
:
1808 emitInsn(0x36400000);
1809 emitIMMD(0x14, 19, insn
->src(1));
1812 assert(!"bad src1 file");
1815 emitGPR (0x27, insn
->src(2));
1817 case FILE_MEMORY_CONST
:
1818 emitInsn(0x53400000);
1819 emitGPR (0x27, insn
->src(1));
1820 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1823 assert(!"bad src2 file");
1827 emitCond3(0x31, cc
);
1828 emitField(0x30, 1, isSignedType(insn
->sType
));
1829 emitGPR (0x08, insn
->src(0));
1830 emitGPR (0x00, insn
->def(0));
1834 CodeEmitterGM107::emitISET()
1836 const CmpInstruction
*insn
= this->insn
->asCmp();
1838 switch (insn
->src(1).getFile()) {
1840 emitInsn(0x5b500000);
1841 emitGPR (0x14, insn
->src(1));
1843 case FILE_MEMORY_CONST
:
1844 emitInsn(0x4b500000);
1845 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1847 case FILE_IMMEDIATE
:
1848 emitInsn(0x36500000);
1849 emitIMMD(0x14, 19, insn
->src(1));
1852 assert(!"bad src1 file");
1856 if (insn
->op
!= OP_SET
) {
1858 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1859 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1860 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1862 assert(!"invalid set op");
1865 emitPRED(0x27, insn
->src(2));
1870 emitCond3(0x31, insn
->setCond
);
1871 emitField(0x30, 1, isSignedType(insn
->sType
));
1873 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1875 emitGPR (0x08, insn
->src(0));
1876 emitGPR (0x00, insn
->def(0));
1880 CodeEmitterGM107::emitISETP()
1882 const CmpInstruction
*insn
= this->insn
->asCmp();
1884 switch (insn
->src(1).getFile()) {
1886 emitInsn(0x5b600000);
1887 emitGPR (0x14, insn
->src(1));
1889 case FILE_MEMORY_CONST
:
1890 emitInsn(0x4b600000);
1891 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1893 case FILE_IMMEDIATE
:
1894 emitInsn(0x36600000);
1895 emitIMMD(0x14, 19, insn
->src(1));
1898 assert(!"bad src1 file");
1902 if (insn
->op
!= OP_SET
) {
1904 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1905 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1906 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1908 assert(!"invalid set op");
1911 emitPRED(0x27, insn
->src(2));
1916 emitCond3(0x31, insn
->setCond
);
1917 emitField(0x30, 1, isSignedType(insn
->sType
));
1919 emitGPR (0x08, insn
->src(0));
1920 emitPRED (0x03, insn
->def(0));
1921 if (insn
->defExists(1))
1922 emitPRED(0x00, insn
->def(1));
1928 CodeEmitterGM107::emitSHL()
1930 switch (insn
->src(1).getFile()) {
1932 emitInsn(0x5c480000);
1933 emitGPR (0x14, insn
->src(1));
1935 case FILE_MEMORY_CONST
:
1936 emitInsn(0x4c480000);
1937 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1939 case FILE_IMMEDIATE
:
1940 emitInsn(0x38480000);
1941 emitIMMD(0x14, 19, insn
->src(1));
1944 assert(!"bad src1 file");
1950 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1951 emitGPR (0x08, insn
->src(0));
1952 emitGPR (0x00, insn
->def(0));
1956 CodeEmitterGM107::emitSHR()
1958 switch (insn
->src(1).getFile()) {
1960 emitInsn(0x5c280000);
1961 emitGPR (0x14, insn
->src(1));
1963 case FILE_MEMORY_CONST
:
1964 emitInsn(0x4c280000);
1965 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1967 case FILE_IMMEDIATE
:
1968 emitInsn(0x38280000);
1969 emitIMMD(0x14, 19, insn
->src(1));
1972 assert(!"bad src1 file");
1976 emitField(0x30, 1, isSignedType(insn
->dType
));
1979 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1980 emitGPR (0x08, insn
->src(0));
1981 emitGPR (0x00, insn
->def(0));
1985 CodeEmitterGM107::emitPOPC()
1987 switch (insn
->src(0).getFile()) {
1989 emitInsn(0x5c080000);
1990 emitGPR (0x14, insn
->src(0));
1992 case FILE_MEMORY_CONST
:
1993 emitInsn(0x4c080000);
1994 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1996 case FILE_IMMEDIATE
:
1997 emitInsn(0x38080000);
1998 emitIMMD(0x14, 19, insn
->src(0));
2001 assert(!"bad src1 file");
2005 emitINV(0x28, insn
->src(0));
2006 emitGPR(0x00, insn
->def(0));
2010 CodeEmitterGM107::emitBFI()
2012 switch(insn
->src(2).getFile()) {
2014 switch (insn
->src(1).getFile()) {
2016 emitInsn(0x5bf00000);
2017 emitGPR (0x14, insn
->src(1));
2019 case FILE_MEMORY_CONST
:
2020 emitInsn(0x4bf00000);
2021 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2023 case FILE_IMMEDIATE
:
2024 emitInsn(0x36f00000);
2025 emitIMMD(0x14, 19, insn
->src(1));
2028 assert(!"bad src1 file");
2031 emitGPR (0x27, insn
->src(2));
2033 case FILE_MEMORY_CONST
:
2034 emitInsn(0x53f00000);
2035 emitGPR (0x27, insn
->src(1));
2036 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2039 assert(!"bad src2 file");
2044 emitGPR (0x08, insn
->src(0));
2045 emitGPR (0x00, insn
->def(0));
2049 CodeEmitterGM107::emitBFE()
2051 switch (insn
->src(1).getFile()) {
2053 emitInsn(0x5c000000);
2054 emitGPR (0x14, insn
->src(1));
2056 case FILE_MEMORY_CONST
:
2057 emitInsn(0x4c000000);
2058 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2060 case FILE_IMMEDIATE
:
2061 emitInsn(0x38000000);
2062 emitIMMD(0x14, 19, insn
->src(1));
2065 assert(!"bad src1 file");
2069 emitField(0x30, 1, isSignedType(insn
->dType
));
2071 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2072 emitGPR (0x08, insn
->src(0));
2073 emitGPR (0x00, insn
->def(0));
2077 CodeEmitterGM107::emitFLO()
2079 switch (insn
->src(0).getFile()) {
2081 emitInsn(0x5c300000);
2082 emitGPR (0x14, insn
->src(0));
2084 case FILE_MEMORY_CONST
:
2085 emitInsn(0x4c300000);
2086 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2088 case FILE_IMMEDIATE
:
2089 emitInsn(0x38300000);
2090 emitIMMD(0x14, 19, insn
->src(0));
2093 assert(!"bad src1 file");
2097 emitField(0x30, 1, isSignedType(insn
->dType
));
2099 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2100 emitINV (0x28, insn
->src(0));
2101 emitGPR (0x00, insn
->def(0));
2104 /*******************************************************************************
2106 ******************************************************************************/
2109 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2113 switch (typeSizeof(type
)) {
2114 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2115 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2116 case 4: data
= 4; break;
2117 case 8: data
= 5; break;
2118 case 16: data
= 6; break;
2120 assert(!"bad type");
2124 emitField(pos
, 3, data
);
2128 CodeEmitterGM107::emitLDSTc(int pos
)
2132 switch (insn
->cache
) {
2133 case CACHE_CA
: mode
= 0; break;
2134 case CACHE_CG
: mode
= 1; break;
2135 case CACHE_CS
: mode
= 2; break;
2136 case CACHE_CV
: mode
= 3; break;
2138 assert(!"invalid caching mode");
2142 emitField(pos
, 2, mode
);
2146 CodeEmitterGM107::emitLDC()
2148 emitInsn (0xef900000);
2149 emitLDSTs(0x30, insn
->dType
);
2150 emitField(0x2c, 2, insn
->subOp
);
2151 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2152 emitGPR (0x00, insn
->def(0));
2156 CodeEmitterGM107::emitLDL()
2158 emitInsn (0xef400000);
2159 emitLDSTs(0x30, insn
->dType
);
2161 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2162 emitGPR (0x00, insn
->def(0));
2166 CodeEmitterGM107::emitLDS()
2168 emitInsn (0xef480000);
2169 emitLDSTs(0x30, insn
->dType
);
2170 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2171 emitGPR (0x00, insn
->def(0));
2175 CodeEmitterGM107::emitLD()
2177 emitInsn (0x80000000);
2180 emitLDSTs(0x35, insn
->dType
);
2181 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2182 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2183 emitGPR (0x00, insn
->def(0));
2187 CodeEmitterGM107::emitSTL()
2189 emitInsn (0xef500000);
2190 emitLDSTs(0x30, insn
->dType
);
2192 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2193 emitGPR (0x00, insn
->src(1));
2197 CodeEmitterGM107::emitSTS()
2199 emitInsn (0xef580000);
2200 emitLDSTs(0x30, insn
->dType
);
2201 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2202 emitGPR (0x00, insn
->src(1));
2206 CodeEmitterGM107::emitST()
2208 emitInsn (0xa0000000);
2211 emitLDSTs(0x35, insn
->dType
);
2212 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2213 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2214 emitGPR (0x00, insn
->src(1));
2218 CodeEmitterGM107::emitALD()
2220 emitInsn (0xefd80000);
2221 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2222 emitGPR (0x27, insn
->src(0).getIndirect(1));
2225 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2226 emitGPR (0x00, insn
->def(0));
2230 CodeEmitterGM107::emitAST()
2232 emitInsn (0xeff00000);
2233 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2234 emitGPR (0x27, insn
->src(0).getIndirect(1));
2236 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2237 emitGPR (0x00, insn
->src(1));
2241 CodeEmitterGM107::emitISBERD()
2243 emitInsn(0xefd00000);
2244 emitGPR (0x08, insn
->src(0));
2245 emitGPR (0x00, insn
->def(0));
2249 CodeEmitterGM107::emitAL2P()
2251 emitInsn (0xefa00000);
2252 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2254 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2255 emitGPR (0x08, insn
->src(0).getIndirect(0));
2256 emitGPR (0x00, insn
->def(0));
2260 interpApply(const InterpEntry
*entry
, uint32_t *code
,
2261 bool force_persample_interp
, bool flatshade
)
2263 int ipa
= entry
->ipa
;
2264 int reg
= entry
->reg
;
2265 int loc
= entry
->loc
;
2268 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2269 ipa
= NV50_IR_INTERP_FLAT
;
2271 } else if (force_persample_interp
&&
2272 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2273 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2274 ipa
|= NV50_IR_INTERP_CENTROID
;
2276 code
[loc
+ 1] &= ~(0xf << 0x14);
2277 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2278 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2279 code
[loc
+ 0] &= ~(0xff << 0x14);
2280 code
[loc
+ 0] |= reg
<< 0x14;
2284 CodeEmitterGM107::emitIPA()
2286 int ipam
= 0, ipas
= 0;
2288 switch (insn
->getInterpMode()) {
2289 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2290 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2291 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2292 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2294 assert(!"invalid ipa mode");
2298 switch (insn
->getSampleMode()) {
2299 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2300 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2301 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2303 assert(!"invalid ipa sample mode");
2307 emitInsn (0xe0000000);
2308 emitField(0x36, 2, ipam
);
2309 emitField(0x34, 2, ipas
);
2311 emitField(0x2f, 3, 7);
2312 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2313 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2314 code
[1] |= 0x00000040; /* .idx */
2315 emitGPR(0x00, insn
->def(0));
2317 if (insn
->op
== OP_PINTERP
) {
2318 emitGPR(0x14, insn
->src(1));
2319 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2320 emitGPR(0x27, insn
->src(2));
2321 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2323 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2324 emitGPR(0x27, insn
->src(1));
2326 addInterp(insn
->ipa
, 0xff, interpApply
);
2329 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2334 CodeEmitterGM107::emitATOM()
2336 unsigned dType
, subOp
;
2338 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2339 switch (insn
->dType
) {
2340 case TYPE_U32
: dType
= 0; break;
2341 case TYPE_U64
: dType
= 1; break;
2342 default: assert(!"unexpected dType"); dType
= 0; break;
2346 emitInsn (0xee000000);
2348 switch (insn
->dType
) {
2349 case TYPE_U32
: dType
= 0; break;
2350 case TYPE_S32
: dType
= 1; break;
2351 case TYPE_U64
: dType
= 2; break;
2352 case TYPE_F32
: dType
= 3; break;
2353 case TYPE_B128
: dType
= 4; break;
2354 case TYPE_S64
: dType
= 5; break;
2355 default: assert(!"unexpected dType"); dType
= 0; break;
2357 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2360 subOp
= insn
->subOp
;
2362 emitInsn (0xed000000);
2365 emitField(0x34, 4, subOp
);
2366 emitField(0x31, 3, dType
);
2367 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2368 emitGPR (0x14, insn
->src(1));
2369 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2370 emitGPR (0x00, insn
->def(0));
2374 CodeEmitterGM107::emitCCTL()
2377 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2378 emitInsn(0xef600000);
2381 emitInsn(0xef800000);
2384 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2385 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2386 emitField(0x00, 4, insn
->subOp
);
2389 /*******************************************************************************
2391 ******************************************************************************/
2394 CodeEmitterGM107::emitPIXLD()
2396 emitInsn (0xefe80000);
2398 emitField(0x1f, 3, insn
->subOp
);
2399 emitGPR (0x08, insn
->src(0));
2400 emitGPR (0x00, insn
->def(0));
2403 /*******************************************************************************
2405 ******************************************************************************/
2408 CodeEmitterGM107::emitTEXs(int pos
)
2410 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2411 if (insn
->srcExists(src1
))
2412 emitGPR(pos
, insn
->src(src1
));
2418 CodeEmitterGM107::emitTEX()
2420 const TexInstruction
*insn
= this->insn
->asTex();
2423 if (!insn
->tex
.levelZero
) {
2425 case OP_TEX
: lodm
= 0; break;
2426 case OP_TXB
: lodm
= 2; break;
2427 case OP_TXL
: lodm
= 3; break;
2429 assert(!"invalid tex op");
2436 if (insn
->tex
.rIndirectSrc
>= 0) {
2437 emitInsn (0xdeb80000);
2438 emitField(0x35, 2, lodm
);
2439 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2441 emitInsn (0xc0380000);
2442 emitField(0x37, 2, lodm
);
2443 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2444 emitField(0x24, 13, insn
->tex
.r
);
2447 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2448 emitField(0x31, 1, insn
->tex
.liveOnly
);
2449 emitField(0x23, 1, insn
->tex
.derivAll
);
2450 emitField(0x1f, 4, insn
->tex
.mask
);
2451 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2452 insn
->tex
.target
.getDim() - 1);
2453 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2455 emitGPR (0x08, insn
->src(0));
2456 emitGPR (0x00, insn
->def(0));
2460 CodeEmitterGM107::emitTLD()
2462 const TexInstruction
*insn
= this->insn
->asTex();
2464 if (insn
->tex
.rIndirectSrc
>= 0) {
2465 emitInsn (0xdd380000);
2467 emitInsn (0xdc380000);
2468 emitField(0x24, 13, insn
->tex
.r
);
2471 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2472 emitField(0x32, 1, insn
->tex
.target
.isMS());
2473 emitField(0x31, 1, insn
->tex
.liveOnly
);
2474 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2475 emitField(0x1f, 4, insn
->tex
.mask
);
2476 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2477 insn
->tex
.target
.getDim() - 1);
2478 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2480 emitGPR (0x08, insn
->src(0));
2481 emitGPR (0x00, insn
->def(0));
2485 CodeEmitterGM107::emitTLD4()
2487 const TexInstruction
*insn
= this->insn
->asTex();
2489 if (insn
->tex
.rIndirectSrc
>= 0) {
2490 emitInsn (0xdef80000);
2491 emitField(0x26, 2, insn
->tex
.gatherComp
);
2492 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2493 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2495 emitInsn (0xc8380000);
2496 emitField(0x38, 2, insn
->tex
.gatherComp
);
2497 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2498 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2499 emitField(0x24, 13, insn
->tex
.r
);
2502 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2503 emitField(0x31, 1, insn
->tex
.liveOnly
);
2504 emitField(0x23, 1, insn
->tex
.derivAll
);
2505 emitField(0x1f, 4, insn
->tex
.mask
);
2506 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2507 insn
->tex
.target
.getDim() - 1);
2508 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2510 emitGPR (0x08, insn
->src(0));
2511 emitGPR (0x00, insn
->def(0));
2515 CodeEmitterGM107::emitTXD()
2517 const TexInstruction
*insn
= this->insn
->asTex();
2519 if (insn
->tex
.rIndirectSrc
>= 0) {
2520 emitInsn (0xde780000);
2522 emitInsn (0xde380000);
2523 emitField(0x24, 13, insn
->tex
.r
);
2526 emitField(0x31, 1, insn
->tex
.liveOnly
);
2527 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2528 emitField(0x1f, 4, insn
->tex
.mask
);
2529 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2530 insn
->tex
.target
.getDim() - 1);
2531 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2533 emitGPR (0x08, insn
->src(0));
2534 emitGPR (0x00, insn
->def(0));
2538 CodeEmitterGM107::emitTMML()
2540 const TexInstruction
*insn
= this->insn
->asTex();
2542 if (insn
->tex
.rIndirectSrc
>= 0) {
2543 emitInsn (0xdf600000);
2545 emitInsn (0xdf580000);
2546 emitField(0x24, 13, insn
->tex
.r
);
2549 emitField(0x31, 1, insn
->tex
.liveOnly
);
2550 emitField(0x23, 1, insn
->tex
.derivAll
);
2551 emitField(0x1f, 4, insn
->tex
.mask
);
2552 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2553 insn
->tex
.target
.getDim() - 1);
2554 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2556 emitGPR (0x08, insn
->src(0));
2557 emitGPR (0x00, insn
->def(0));
2561 CodeEmitterGM107::emitTXQ()
2563 const TexInstruction
*insn
= this->insn
->asTex();
2566 switch (insn
->tex
.query
) {
2567 case TXQ_DIMS
: type
= 0x01; break;
2568 case TXQ_TYPE
: type
= 0x02; break;
2569 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2570 case TXQ_FILTER
: type
= 0x10; break;
2571 case TXQ_LOD
: type
= 0x12; break;
2572 case TXQ_WRAP
: type
= 0x14; break;
2573 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2575 assert(!"invalid txq query");
2579 if (insn
->tex
.rIndirectSrc
>= 0) {
2580 emitInsn (0xdf500000);
2582 emitInsn (0xdf480000);
2583 emitField(0x24, 13, insn
->tex
.r
);
2586 emitField(0x31, 1, insn
->tex
.liveOnly
);
2587 emitField(0x1f, 4, insn
->tex
.mask
);
2588 emitField(0x16, 6, type
);
2589 emitGPR (0x08, insn
->src(0));
2590 emitGPR (0x00, insn
->def(0));
2594 CodeEmitterGM107::emitDEPBAR()
2596 emitInsn (0xf0f00000);
2597 emitField(0x1d, 1, 1); /* le */
2598 emitField(0x1a, 3, 5);
2599 emitField(0x14, 6, insn
->subOp
);
2600 emitField(0x00, 6, insn
->subOp
);
2603 /*******************************************************************************
2605 ******************************************************************************/
2608 CodeEmitterGM107::emitNOP()
2610 emitInsn(0x50b00000);
2614 CodeEmitterGM107::emitKIL()
2616 emitInsn (0xe3300000);
2617 emitCond5(0x00, CC_TR
);
2621 CodeEmitterGM107::emitOUT()
2623 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2624 const int emit
= insn
->op
== OP_EMIT
;
2626 switch (insn
->src(1).getFile()) {
2628 emitInsn(0xfbe00000);
2629 emitGPR (0x14, insn
->src(1));
2631 case FILE_IMMEDIATE
:
2632 emitInsn(0xf6e00000);
2633 emitIMMD(0x14, 19, insn
->src(1));
2635 case FILE_MEMORY_CONST
:
2636 emitInsn(0xebe00000);
2637 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2640 assert(!"bad src1 file");
2644 emitField(0x27, 2, (cut
<< 1) | emit
);
2645 emitGPR (0x08, insn
->src(0));
2646 emitGPR (0x00, insn
->def(0));
2650 CodeEmitterGM107::emitMEMBAR()
2652 emitInsn (0xef980000);
2653 emitField(0x08, 2, insn
->subOp
>> 2);
2656 /*******************************************************************************
2657 * assembler front-end
2658 ******************************************************************************/
2661 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2663 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2668 if (insn
->encSize
!= 8) {
2669 ERROR("skipping undecodable instruction: "); insn
->print();
2672 if (codeSize
+ size
> codeSizeLimit
) {
2673 ERROR("code emitter output buffer too small\n");
2677 if (writeIssueDelays
) {
2678 int n
= ((codeSize
& 0x1f) / 8) - 1;
2681 data
[0] = 0x00000000;
2682 data
[1] = 0x00000000;
2688 emitField(data
, n
* 21, 21, insn
->sched
);
2744 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
2745 insn
->src(0).getFile() == FILE_PREDICATE
)) {
2747 } else if (isFloatType(insn
->dType
)) {
2748 if (isFloatType(insn
->sType
))
2753 if (isFloatType(insn
->sType
))
2764 if (isFloatType(insn
->dType
)) {
2765 if (insn
->dType
== TYPE_F64
)
2774 if (isFloatType(insn
->dType
)) {
2775 if (insn
->dType
== TYPE_F64
)
2785 if (isFloatType(insn
->dType
)) {
2786 if (insn
->dType
== TYPE_F64
)
2796 if (isFloatType(insn
->dType
)) {
2797 if (insn
->dType
== TYPE_F64
)
2824 if (isFloatType(insn
->dType
))
2833 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2834 if (isFloatType(insn
->sType
))
2835 if (insn
->sType
== TYPE_F64
)
2842 if (isFloatType(insn
->sType
))
2843 if (insn
->sType
== TYPE_F64
)
2872 switch (insn
->src(0).getFile()) {
2873 case FILE_MEMORY_CONST
: emitLDC(); break;
2874 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2875 case FILE_MEMORY_SHARED
: emitLDS(); break;
2876 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2878 assert(!"invalid load");
2884 switch (insn
->src(0).getFile()) {
2885 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2886 case FILE_MEMORY_SHARED
: emitSTS(); break;
2887 case FILE_MEMORY_GLOBAL
: emitST(); break;
2889 assert(!"invalid load");
2959 assert(!"invalid opcode");
2975 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2980 /*******************************************************************************
2981 * sched data calculator
2982 ******************************************************************************/
2984 class SchedDataCalculatorGM107
: public Pass
2987 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2990 bool visit(BasicBlock
*bb
);
2994 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2996 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2998 insn
->sched
= 0x7e0;
3004 /*******************************************************************************
3006 ******************************************************************************/
3009 CodeEmitterGM107::prepareEmission(Function
*func
)
3011 SchedDataCalculatorGM107
sched(targ
);
3012 CodeEmitter::prepareEmission(func
);
3013 sched
.run(func
, true, true);
3016 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3018 return (size
+ 23) / 24;
3022 CodeEmitterGM107::prepareEmission(Program
*prog
)
3024 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3025 !fi
.end(); fi
.next()) {
3026 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3027 func
->binPos
= prog
->binSize
;
3028 prepareEmission(func
);
3030 // adjust sizes & positions for schedulding info:
3031 if (prog
->getTarget()->hasSWSched
) {
3032 uint32_t adjPos
= func
->binPos
;
3033 BasicBlock
*bb
= NULL
;
3034 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3035 bb
= func
->bbArray
[i
];
3036 int32_t adjSize
= bb
->binSize
;
3038 adjSize
-= 32 - adjPos
% 32;
3042 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3043 bb
->binPos
= adjPos
;
3044 bb
->binSize
= adjSize
;
3048 func
->binSize
= adjPos
- func
->binPos
;
3051 prog
->binSize
+= func
->binSize
;
3055 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3056 : CodeEmitter(target
),
3058 writeIssueDelays(target
->hasSWSched
)
3061 codeSize
= codeSizeLimit
= 0;
3066 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3068 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3069 emit
->setProgramType(type
);
3073 } // namespace nv50_ir