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
);
196 /*******************************************************************************
197 * general instruction layout/fields
198 ******************************************************************************/
201 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
204 uint32_t m
= ((1ULL << s
) - 1);
205 uint64_t d
= (uint64_t)(v
& m
) << b
;
206 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
213 CodeEmitterGM107::emitPred()
215 if (insn
->predSrc
>= 0) {
216 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
217 emitField(19, 1, insn
->cc
== CC_NOT_P
);
224 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
226 code
[0] = 0x00000000;
233 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
235 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
239 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
241 int id
= val
? val
->reg
.data
.id
: -1;
244 case SV_LANEID
: id
= 0x00; break;
245 case SV_VERTEX_COUNT
: id
= 0x10; break;
246 case SV_INVOCATION_ID
: id
= 0x11; break;
247 case SV_INVOCATION_INFO
: id
= 0x1d; break;
249 assert(!"invalid system value");
254 emitField(pos
, 8, id
);
258 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
260 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
264 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
267 const Value
*v
= ref
.get();
268 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
270 emitGPR(gpr
, ref
.getIndirect(0));
271 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
275 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
278 const Value
*v
= ref
.get();
279 const Symbol
*s
= v
->asSym();
281 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
283 emitField(buf
, 5, v
->reg
.fileIndex
);
285 emitGPR(gpr
, ref
.getIndirect(0));
286 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
290 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
292 if (ref
.getFile() == FILE_IMMEDIATE
) {
293 const ImmediateValue
*imm
= ref
.get()->asImm();
294 if (isFloatType(insn
->sType
)) {
295 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
298 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
299 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
307 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
309 const ImmediateValue
*imm
= ref
.get()->asImm();
310 uint32_t val
= imm
->reg
.data
.u32
;
313 if (isFloatType(insn
->sType
)) {
314 assert(!(val
& 0x00000fff));
317 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
318 emitField( 56, 1, (val
& 0x80000) >> 19);
319 emitField(pos
, len
, (val
& 0x7ffff));
321 emitField(pos
, len
, val
);
325 /*******************************************************************************
327 ******************************************************************************/
330 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
335 case CC_FL
: data
= 0x00; break;
337 case CC_LT
: data
= 0x01; break;
339 case CC_EQ
: data
= 0x02; break;
341 case CC_LE
: data
= 0x03; break;
343 case CC_GT
: data
= 0x04; break;
345 case CC_NE
: data
= 0x05; break;
347 case CC_GE
: data
= 0x06; break;
348 case CC_TR
: data
= 0x07; break;
350 assert(!"invalid cond3");
354 emitField(pos
, 3, data
);
358 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
363 case CC_FL
: data
= 0x00; break;
364 case CC_LT
: data
= 0x01; break;
365 case CC_EQ
: data
= 0x02; break;
366 case CC_LE
: data
= 0x03; break;
367 case CC_GT
: data
= 0x04; break;
368 case CC_NE
: data
= 0x05; break;
369 case CC_GE
: data
= 0x06; break;
370 // case CC_NUM: data = 0x07; break;
371 // case CC_NAN: data = 0x08; break;
372 case CC_LTU
: data
= 0x09; break;
373 case CC_EQU
: data
= 0x0a; break;
374 case CC_LEU
: data
= 0x0b; break;
375 case CC_GTU
: data
= 0x0c; break;
376 case CC_NEU
: data
= 0x0d; break;
377 case CC_GEU
: data
= 0x0e; break;
378 case CC_TR
: data
= 0x0f; break;
380 assert(!"invalid cond4");
384 emitField(pos
, 4, data
);
388 CodeEmitterGM107::emitO(int pos
)
390 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
394 CodeEmitterGM107::emitP(int pos
)
396 emitField(pos
, 1, insn
->perPatch
);
400 CodeEmitterGM107::emitSAT(int pos
)
402 emitField(pos
, 1, insn
->saturate
);
406 CodeEmitterGM107::emitCC(int pos
)
408 emitField(pos
, 1, insn
->defExists(1));
412 CodeEmitterGM107::emitX(int pos
)
414 emitField(pos
, 1, insn
->flagsSrc
>= 0);
418 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
420 emitField(pos
, 1, ref
.mod
.abs());
424 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
426 emitField(pos
, 1, ref
.mod
.neg());
430 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
432 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
436 CodeEmitterGM107::emitFMZ(int pos
, int len
)
438 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
442 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
446 case ROUND_NI
: ri
= 1;
447 case ROUND_N
: rm
= 0; break;
448 case ROUND_MI
: ri
= 1;
449 case ROUND_M
: rm
= 1; break;
450 case ROUND_PI
: ri
= 1;
451 case ROUND_P
: rm
= 2; break;
452 case ROUND_ZI
: ri
= 1;
453 case ROUND_Z
: rm
= 3; break;
455 assert(!"invalid round mode");
458 emitField(rip
, 1, ri
);
459 emitField(rmp
, 2, rm
);
463 CodeEmitterGM107::emitPDIV(int pos
)
465 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
466 if (insn
->postFactor
> 0)
467 emitField(pos
, 3, 7 - insn
->postFactor
);
469 emitField(pos
, 3, 0 - insn
->postFactor
);
473 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
475 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
478 /*******************************************************************************
480 ******************************************************************************/
483 CodeEmitterGM107::emitEXIT()
485 emitInsn (0xe3000000);
486 emitCond5(0x00, CC_TR
);
490 CodeEmitterGM107::emitBRA()
492 const FlowInstruction
*insn
= this->insn
->asFlow();
495 if (insn
->indirect
) {
497 emitInsn(0xe2000000); // JMX
499 emitInsn(0xe2500000); // BRX
503 emitInsn(0xe2100000); // JMP
505 emitInsn(0xe2400000); // BRA
506 emitField(0x07, 1, insn
->allWarp
);
509 emitField(0x06, 1, insn
->limit
);
510 emitCond5(0x00, CC_TR
);
512 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
513 int32_t pos
= insn
->target
.bb
->binPos
;
514 if (writeIssueDelays
&& !(pos
& 0x1f))
517 emitField(0x14, 24, pos
- (codeSize
+ 8));
519 emitField(0x14, 32, pos
);
521 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
522 emitField(0x05, 1, 1);
527 CodeEmitterGM107::emitCAL()
529 const FlowInstruction
*insn
= this->insn
->asFlow();
531 if (insn
->absolute
) {
532 emitInsn(0xe2200000, 0); // JCAL
534 emitInsn(0xe2600000, 0); // CAL
537 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
539 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
542 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
543 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
544 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
546 emitField(0x14, 32, insn
->target
.bb
->binPos
);
550 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
551 emitField(0x05, 1, 1);
556 CodeEmitterGM107::emitPCNT()
558 const FlowInstruction
*insn
= this->insn
->asFlow();
560 emitInsn(0xe2b00000, 0);
562 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
563 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
565 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
566 emitField(0x05, 1, 1);
571 CodeEmitterGM107::emitCONT()
573 emitInsn (0xe3500000);
574 emitCond5(0x00, CC_TR
);
578 CodeEmitterGM107::emitPBK()
580 const FlowInstruction
*insn
= this->insn
->asFlow();
582 emitInsn(0xe2a00000, 0);
584 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
585 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
587 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
588 emitField(0x05, 1, 1);
593 CodeEmitterGM107::emitBRK()
595 emitInsn (0xe3400000);
596 emitCond5(0x00, CC_TR
);
600 CodeEmitterGM107::emitPRET()
602 const FlowInstruction
*insn
= this->insn
->asFlow();
604 emitInsn(0xe2700000, 0);
606 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
607 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
609 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
610 emitField(0x05, 1, 1);
615 CodeEmitterGM107::emitRET()
617 emitInsn (0xe3200000);
618 emitCond5(0x00, CC_TR
);
622 CodeEmitterGM107::emitSSY()
624 const FlowInstruction
*insn
= this->insn
->asFlow();
626 emitInsn(0xe2900000, 0);
628 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
629 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
631 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
632 emitField(0x05, 1, 1);
637 CodeEmitterGM107::emitSYNC()
639 emitInsn (0xf0f80000);
640 emitCond5(0x00, CC_TR
);
644 CodeEmitterGM107::emitSAM()
646 emitInsn(0xe3700000, 0);
650 CodeEmitterGM107::emitRAM()
652 emitInsn(0xe3800000, 0);
655 /*******************************************************************************
657 ******************************************************************************/
659 /*******************************************************************************
660 * movement / conversion
661 ******************************************************************************/
664 CodeEmitterGM107::emitMOV()
666 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
667 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
668 switch (insn
->src(0).getFile()) {
670 emitInsn(0x5c980000);
671 emitGPR (0x14, insn
->src(0));
673 case FILE_MEMORY_CONST
:
674 emitInsn(0x4c980000);
675 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
678 emitInsn(0x38980000);
679 emitIMMD(0x14, 19, insn
->src(0));
682 assert(!"bad src file");
685 emitField(0x27, 4, insn
->lanes
);
687 emitInsn (0x01000000);
688 emitIMMD (0x14, 32, insn
->src(0));
689 emitField(0x0c, 4, insn
->lanes
);
692 emitGPR(0x00, insn
->def(0));
696 CodeEmitterGM107::emitS2R()
698 emitInsn(0xf0c80000);
699 emitSYS (0x14, insn
->src(0));
700 emitGPR (0x00, insn
->def(0));
704 CodeEmitterGM107::emitF2F()
706 RoundMode rnd
= insn
->rnd
;
709 case OP_FLOOR
: rnd
= ROUND_MI
; break;
710 case OP_CEIL
: rnd
= ROUND_PI
; break;
711 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
716 switch (insn
->src(0).getFile()) {
718 emitInsn(0x5ca80000);
719 emitGPR (0x14, insn
->src(0));
721 case FILE_MEMORY_CONST
:
722 emitInsn(0x4ca80000);
723 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
726 emitInsn(0x38a80000);
727 emitIMMD(0x14, 19, insn
->src(0));
730 assert(!"bad src0 file");
734 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
735 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
737 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
739 emitRND (0x27, rnd
, 0x2a);
740 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
741 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
742 emitGPR (0x00, insn
->def(0));
746 CodeEmitterGM107::emitF2I()
748 RoundMode rnd
= insn
->rnd
;
751 case OP_FLOOR
: rnd
= ROUND_M
; break;
752 case OP_CEIL
: rnd
= ROUND_P
; break;
753 case OP_TRUNC
: rnd
= ROUND_Z
; break;
758 switch (insn
->src(0).getFile()) {
760 emitInsn(0x5cb00000);
761 emitGPR (0x14, insn
->src(0));
763 case FILE_MEMORY_CONST
:
764 emitInsn(0x4cb00000);
765 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
768 emitInsn(0x38b00000);
769 emitIMMD(0x14, 19, insn
->src(0));
772 assert(!"bad src0 file");
776 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
778 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
780 emitRND (0x27, rnd
, 0x2a);
781 emitField(0x0c, 1, isSignedType(insn
->dType
));
782 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
783 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
784 emitGPR (0x00, insn
->def(0));
788 CodeEmitterGM107::emitI2F()
790 RoundMode rnd
= insn
->rnd
;
793 case OP_FLOOR
: rnd
= ROUND_M
; break;
794 case OP_CEIL
: rnd
= ROUND_P
; break;
795 case OP_TRUNC
: rnd
= ROUND_Z
; break;
800 switch (insn
->src(0).getFile()) {
802 emitInsn(0x5cb80000);
803 emitGPR (0x14, insn
->src(0));
805 case FILE_MEMORY_CONST
:
806 emitInsn(0x4cb80000);
807 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
810 emitInsn(0x38b80000);
811 emitIMMD(0x14, 19, insn
->src(0));
814 assert(!"bad src0 file");
818 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
820 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
821 emitField(0x29, 2, insn
->subOp
);
822 emitRND (0x27, rnd
, -1);
823 emitField(0x0d, 1, isSignedType(insn
->sType
));
824 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
825 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
826 emitGPR (0x00, insn
->def(0));
830 CodeEmitterGM107::emitI2I()
832 switch (insn
->src(0).getFile()) {
834 emitInsn(0x5ce00000);
835 emitGPR (0x14, insn
->src(0));
837 case FILE_MEMORY_CONST
:
838 emitInsn(0x4ce00000);
839 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
842 emitInsn(0x38e00000);
843 emitIMMD(0x14, 19, insn
->src(0));
846 assert(!"bad src0 file");
851 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
853 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
854 emitField(0x29, 2, insn
->subOp
);
855 emitField(0x0d, 1, isSignedType(insn
->sType
));
856 emitField(0x0c, 1, isSignedType(insn
->dType
));
857 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
858 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
859 emitGPR (0x00, insn
->def(0));
863 CodeEmitterGM107::emitSHFL()
867 emitInsn (0xef100000);
869 switch (insn
->src(1).getFile()) {
871 emitGPR(0x14, insn
->src(1));
874 emitIMMD(0x14, 5, insn
->src(1));
878 assert(!"invalid src1 file");
882 /*XXX: what is this arg? hardcode immediate for now */
883 emitField(0x22, 13, 0x1c03);
887 emitField(0x1e, 2, insn
->subOp
);
888 emitField(0x1c, 2, type
);
889 emitGPR (0x08, insn
->src(0));
890 emitGPR (0x00, insn
->def(0));
893 /*******************************************************************************
895 ******************************************************************************/
898 CodeEmitterGM107::emitDADD()
900 switch (insn
->src(1).getFile()) {
902 emitInsn(0x5c700000);
903 emitGPR (0x14, insn
->src(1));
905 case FILE_MEMORY_CONST
:
906 emitInsn(0x4c700000);
907 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
910 emitInsn(0x38700000);
911 emitIMMD(0x14, 19, insn
->src(1));
914 assert(!"bad src1 file");
917 emitABS(0x31, insn
->src(1));
918 emitNEG(0x30, insn
->src(0));
920 emitABS(0x2e, insn
->src(0));
921 emitNEG(0x2d, insn
->src(1));
923 if (insn
->op
== OP_SUB
)
924 code
[1] ^= 0x00002000;
926 emitGPR(0x08, insn
->src(0));
927 emitGPR(0x00, insn
->def(0));
931 CodeEmitterGM107::emitDMUL()
933 switch (insn
->src(1).getFile()) {
935 emitInsn(0x5c800000);
936 emitGPR (0x14, insn
->src(1));
938 case FILE_MEMORY_CONST
:
939 emitInsn(0x4c800000);
940 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
943 emitInsn(0x38800000);
944 emitIMMD(0x14, 19, insn
->src(1));
947 assert(!"bad src1 file");
951 emitNEG2(0x30, insn
->src(0), insn
->src(1));
954 emitGPR (0x08, insn
->src(0));
955 emitGPR (0x00, insn
->def(0));
959 CodeEmitterGM107::emitDFMA()
961 switch(insn
->src(2).getFile()) {
963 switch (insn
->src(1).getFile()) {
965 emitInsn(0x5b700000);
966 emitGPR (0x14, insn
->src(1));
968 case FILE_MEMORY_CONST
:
969 emitInsn(0x4b700000);
970 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
973 emitInsn(0x36700000);
974 emitIMMD(0x14, 19, insn
->src(1));
977 assert(!"bad src1 file");
980 emitGPR (0x27, insn
->src(2));
982 case FILE_MEMORY_CONST
:
983 emitInsn(0x53700000);
984 emitGPR (0x27, insn
->src(1));
985 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
988 assert(!"bad src2 file");
993 emitNEG (0x31, insn
->src(2));
994 emitNEG2(0x30, insn
->src(0), insn
->src(1));
996 emitGPR (0x08, insn
->src(0));
997 emitGPR (0x00, insn
->def(0));
1001 CodeEmitterGM107::emitDMNMX()
1003 switch (insn
->src(1).getFile()) {
1005 emitInsn(0x5c500000);
1006 emitGPR (0x14, insn
->src(1));
1008 case FILE_MEMORY_CONST
:
1009 emitInsn(0x4c500000);
1010 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1012 case FILE_IMMEDIATE
:
1013 emitInsn(0x38500000);
1014 emitIMMD(0x14, 19, insn
->src(1));
1017 assert(!"bad src1 file");
1021 emitABS (0x31, insn
->src(1));
1022 emitNEG (0x30, insn
->src(0));
1024 emitABS (0x2e, insn
->src(0));
1025 emitNEG (0x2d, insn
->src(1));
1026 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1028 emitGPR (0x08, insn
->src(0));
1029 emitGPR (0x00, insn
->def(0));
1033 CodeEmitterGM107::emitDSET()
1035 const CmpInstruction
*insn
= this->insn
->asCmp();
1037 switch (insn
->src(1).getFile()) {
1039 emitInsn(0x59000000);
1040 emitGPR (0x14, insn
->src(1));
1042 case FILE_MEMORY_CONST
:
1043 emitInsn(0x49000000);
1044 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1046 case FILE_IMMEDIATE
:
1047 emitInsn(0x32000000);
1048 emitIMMD(0x14, 19, insn
->src(1));
1051 assert(!"bad src1 file");
1055 if (insn
->op
!= OP_SET
) {
1057 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1058 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1059 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1061 assert(!"invalid set op");
1064 emitPRED(0x27, insn
->src(2));
1069 emitABS (0x36, insn
->src(0));
1070 emitNEG (0x35, insn
->src(1));
1071 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1072 emitCond4(0x30, insn
->setCond
);
1074 emitABS (0x2c, insn
->src(1));
1075 emitNEG (0x2b, insn
->src(0));
1076 emitGPR (0x08, insn
->src(0));
1077 emitGPR (0x00, insn
->def(0));
1081 CodeEmitterGM107::emitDSETP()
1083 const CmpInstruction
*insn
= this->insn
->asCmp();
1085 switch (insn
->src(1).getFile()) {
1087 emitInsn(0x5b800000);
1088 emitGPR (0x14, insn
->src(1));
1090 case FILE_MEMORY_CONST
:
1091 emitInsn(0x4b800000);
1092 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1094 case FILE_IMMEDIATE
:
1095 emitInsn(0x36800000);
1096 emitIMMD(0x14, 19, insn
->src(1));
1099 assert(!"bad src1 file");
1103 if (insn
->op
!= OP_SET
) {
1105 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1106 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1107 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1109 assert(!"invalid set op");
1112 emitPRED(0x27, insn
->src(2));
1117 emitCond4(0x30, insn
->setCond
);
1118 emitABS (0x2c, insn
->src(1));
1119 emitNEG (0x2b, insn
->src(0));
1120 emitGPR (0x08, insn
->src(0));
1121 emitABS (0x07, insn
->src(0));
1122 emitNEG (0x06, insn
->src(1));
1123 emitPRED (0x03, insn
->def(0));
1124 if (insn
->defExists(1))
1125 emitPRED(0x00, insn
->def(1));
1130 /*******************************************************************************
1132 ******************************************************************************/
1135 CodeEmitterGM107::emitFADD()
1137 if (!longIMMD(insn
->src(1))) {
1138 switch (insn
->src(1).getFile()) {
1140 emitInsn(0x5c580000);
1141 emitGPR (0x14, insn
->src(1));
1143 case FILE_MEMORY_CONST
:
1144 emitInsn(0x4c580000);
1145 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1147 case FILE_IMMEDIATE
:
1148 emitInsn(0x38580000);
1149 emitIMMD(0x14, 19, insn
->src(1));
1152 assert(!"bad src1 file");
1156 emitABS(0x31, insn
->src(1));
1157 emitNEG(0x30, insn
->src(0));
1159 emitABS(0x2e, insn
->src(0));
1160 emitNEG(0x2d, insn
->src(1));
1163 emitInsn(0x08000000);
1164 emitABS(0x39, insn
->src(1));
1165 emitNEG(0x38, insn
->src(0));
1167 emitABS(0x36, insn
->src(0));
1168 emitNEG(0x35, insn
->src(1));
1170 emitIMMD(0x14, 32, insn
->src(1));
1173 if (insn
->op
== OP_SUB
)
1174 code
[1] ^= 0x00002000;
1176 emitGPR(0x08, insn
->src(0));
1177 emitGPR(0x00, insn
->def(0));
1181 CodeEmitterGM107::emitFMUL()
1183 if (!longIMMD(insn
->src(1))) {
1184 switch (insn
->src(1).getFile()) {
1186 emitInsn(0x5c680000);
1187 emitGPR (0x14, insn
->src(1));
1189 case FILE_MEMORY_CONST
:
1190 emitInsn(0x4c680000);
1191 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1193 case FILE_IMMEDIATE
:
1194 emitInsn(0x38680000);
1195 emitIMMD(0x14, 19, insn
->src(1));
1198 assert(!"bad src1 file");
1202 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1208 emitInsn(0x1e000000);
1212 emitIMMD(0x14, 32, insn
->src(1));
1213 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1214 code
[1] ^= 0x00080000; /* flip immd sign bit */
1217 emitGPR(0x08, insn
->src(0));
1218 emitGPR(0x00, insn
->def(0));
1222 CodeEmitterGM107::emitFFMA()
1224 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1225 switch(insn
->src(2).getFile()) {
1227 switch (insn
->src(1).getFile()) {
1229 emitInsn(0x59800000);
1230 emitGPR (0x14, insn
->src(1));
1232 case FILE_MEMORY_CONST
:
1233 emitInsn(0x49800000);
1234 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1236 case FILE_IMMEDIATE
:
1237 emitInsn(0x32800000);
1238 emitIMMD(0x14, 19, insn
->src(1));
1241 assert(!"bad src1 file");
1244 emitGPR (0x27, insn
->src(2));
1246 case FILE_MEMORY_CONST
:
1247 emitInsn(0x51800000);
1248 emitGPR (0x27, insn
->src(1));
1249 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1252 assert(!"bad src2 file");
1257 emitNEG (0x31, insn
->src(2));
1258 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1262 emitGPR(0x08, insn
->src(0));
1263 emitGPR(0x00, insn
->def(0));
1267 CodeEmitterGM107::emitMUFU()
1272 case OP_COS
: mufu
= 0; break;
1273 case OP_SIN
: mufu
= 1; break;
1274 case OP_EX2
: mufu
= 2; break;
1275 case OP_LG2
: mufu
= 3; break;
1276 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1277 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1279 assert(!"invalid mufu");
1283 emitInsn (0x50800000);
1285 emitNEG (0x30, insn
->src(0));
1286 emitABS (0x2e, insn
->src(0));
1287 emitField(0x14, 3, mufu
);
1288 emitGPR (0x08, insn
->src(0));
1289 emitGPR (0x00, insn
->def(0));
1293 CodeEmitterGM107::emitFMNMX()
1295 switch (insn
->src(1).getFile()) {
1297 emitInsn(0x5c600000);
1298 emitGPR (0x14, insn
->src(1));
1300 case FILE_MEMORY_CONST
:
1301 emitInsn(0x4c600000);
1302 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1304 case FILE_IMMEDIATE
:
1305 emitInsn(0x38600000);
1306 emitIMMD(0x14, 19, insn
->src(1));
1309 assert(!"bad src1 file");
1313 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1316 emitABS(0x31, insn
->src(1));
1317 emitNEG(0x30, insn
->src(0));
1319 emitABS(0x2e, insn
->src(0));
1320 emitNEG(0x2d, insn
->src(1));
1322 emitGPR(0x08, insn
->src(0));
1323 emitGPR(0x00, insn
->def(0));
1327 CodeEmitterGM107::emitRRO()
1329 switch (insn
->src(0).getFile()) {
1331 emitInsn(0x5c900000);
1332 emitGPR (0x14, insn
->src(0));
1334 case FILE_MEMORY_CONST
:
1335 emitInsn(0x4c900000);
1336 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1338 case FILE_IMMEDIATE
:
1339 emitInsn(0x38900000);
1340 emitIMMD(0x14, 19, insn
->src(0));
1343 assert(!"bad src file");
1347 emitABS (0x31, insn
->src(0));
1348 emitNEG (0x2d, insn
->src(0));
1349 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1350 emitGPR (0x00, insn
->def(0));
1354 CodeEmitterGM107::emitFCMP()
1356 const CmpInstruction
*insn
= this->insn
->asCmp();
1357 CondCode cc
= insn
->setCond
;
1359 if (insn
->src(2).mod
.neg())
1360 cc
= reverseCondCode(cc
);
1362 switch(insn
->src(2).getFile()) {
1364 switch (insn
->src(1).getFile()) {
1366 emitInsn(0x5ba00000);
1367 emitGPR (0x14, insn
->src(1));
1369 case FILE_MEMORY_CONST
:
1370 emitInsn(0x4ba00000);
1371 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1373 case FILE_IMMEDIATE
:
1374 emitInsn(0x36a00000);
1375 emitIMMD(0x14, 19, insn
->src(1));
1378 assert(!"bad src1 file");
1381 emitGPR (0x27, insn
->src(2));
1383 case FILE_MEMORY_CONST
:
1384 emitInsn(0x53a00000);
1385 emitGPR (0x27, insn
->src(1));
1386 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1389 assert(!"bad src2 file");
1393 emitCond4(0x30, cc
);
1395 emitGPR (0x08, insn
->src(0));
1396 emitGPR (0x00, insn
->def(0));
1400 CodeEmitterGM107::emitFSET()
1402 const CmpInstruction
*insn
= this->insn
->asCmp();
1404 switch (insn
->src(1).getFile()) {
1406 emitInsn(0x58000000);
1407 emitGPR (0x14, insn
->src(1));
1409 case FILE_MEMORY_CONST
:
1410 emitInsn(0x48000000);
1411 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1413 case FILE_IMMEDIATE
:
1414 emitInsn(0x30000000);
1415 emitIMMD(0x14, 19, insn
->src(1));
1418 assert(!"bad src1 file");
1422 if (insn
->op
!= OP_SET
) {
1424 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1425 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1426 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1428 assert(!"invalid set op");
1431 emitPRED(0x27, insn
->src(2));
1437 emitABS (0x36, insn
->src(0));
1438 emitNEG (0x35, insn
->src(1));
1439 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1440 emitCond4(0x30, insn
->setCond
);
1442 emitABS (0x2c, insn
->src(1));
1443 emitNEG (0x2b, insn
->src(0));
1444 emitGPR (0x08, insn
->src(0));
1445 emitGPR (0x00, insn
->def(0));
1449 CodeEmitterGM107::emitFSETP()
1451 const CmpInstruction
*insn
= this->insn
->asCmp();
1453 switch (insn
->src(1).getFile()) {
1455 emitInsn(0x5bb00000);
1456 emitGPR (0x14, insn
->src(1));
1458 case FILE_MEMORY_CONST
:
1459 emitInsn(0x4bb00000);
1460 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1462 case FILE_IMMEDIATE
:
1463 emitInsn(0x36b00000);
1464 emitIMMD(0x14, 19, insn
->src(1));
1467 assert(!"bad src1 file");
1471 if (insn
->op
!= OP_SET
) {
1473 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1474 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1475 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1477 assert(!"invalid set op");
1480 emitPRED(0x27, insn
->src(2));
1485 emitCond4(0x30, insn
->setCond
);
1487 emitABS (0x2c, insn
->src(1));
1488 emitNEG (0x2b, insn
->src(0));
1489 emitGPR (0x08, insn
->src(0));
1490 emitABS (0x07, insn
->src(0));
1491 emitNEG (0x06, insn
->src(1));
1492 emitPRED (0x03, insn
->def(0));
1493 if (insn
->defExists(1))
1494 emitPRED(0x00, insn
->def(1));
1500 CodeEmitterGM107::emitFSWZADD()
1502 emitInsn (0x50f80000);
1506 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1507 emitField(0x1c, 8, insn
->subOp
);
1508 emitGPR (0x14, insn
->src(1));
1509 emitGPR (0x08, insn
->src(0));
1510 emitGPR (0x00, insn
->def(0));
1513 /*******************************************************************************
1515 ******************************************************************************/
1518 CodeEmitterGM107::emitLOP()
1523 case OP_AND
: lop
= 0; break;
1524 case OP_OR
: lop
= 1; break;
1525 case OP_XOR
: lop
= 2; break;
1527 assert(!"invalid lop");
1531 if (!longIMMD(insn
->src(1))) {
1532 switch (insn
->src(1).getFile()) {
1534 emitInsn(0x5c400000);
1535 emitGPR (0x14, insn
->src(1));
1537 case FILE_MEMORY_CONST
:
1538 emitInsn(0x4c400000);
1539 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1541 case FILE_IMMEDIATE
:
1542 emitInsn(0x38400000);
1543 emitIMMD(0x14, 19, insn
->src(1));
1546 assert(!"bad src1 file");
1550 emitField(0x29, 2, lop
);
1551 emitINV (0x28, insn
->src(1));
1552 emitINV (0x27, insn
->src(0));
1554 emitInsn (0x04000000);
1555 emitINV (0x38, insn
->src(1));
1556 emitINV (0x37, insn
->src(0));
1557 emitField(0x35, 2, lop
);
1558 emitIMMD (0x14, 32, insn
->src(1));
1561 emitGPR (0x08, insn
->src(0));
1562 emitGPR (0x00, insn
->def(0));
1565 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1567 CodeEmitterGM107::emitNOT()
1569 if (!longIMMD(insn
->src(0))) {
1570 switch (insn
->src(0).getFile()) {
1572 emitInsn(0x5c400700);
1573 emitGPR (0x14, insn
->src(0));
1575 case FILE_MEMORY_CONST
:
1576 emitInsn(0x4c400700);
1577 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1579 case FILE_IMMEDIATE
:
1580 emitInsn(0x38400700);
1581 emitIMMD(0x14, 19, insn
->src(0));
1584 assert(!"bad src1 file");
1589 emitInsn (0x05600000);
1590 emitIMMD (0x14, 32, insn
->src(1));
1594 emitGPR(0x00, insn
->def(0));
1598 CodeEmitterGM107::emitIADD()
1600 if (!longIMMD(insn
->src(1))) {
1601 switch (insn
->src(1).getFile()) {
1603 emitInsn(0x5c100000);
1604 emitGPR (0x14, insn
->src(1));
1606 case FILE_MEMORY_CONST
:
1607 emitInsn(0x4c100000);
1608 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1610 case FILE_IMMEDIATE
:
1611 emitInsn(0x38100000);
1612 emitIMMD(0x14, 19, insn
->src(1));
1615 assert(!"bad src1 file");
1619 emitNEG(0x31, insn
->src(0));
1620 emitNEG(0x30, insn
->src(1));
1623 emitInsn(0x1c000000);
1626 emitIMMD(0x14, 32, insn
->src(1));
1629 if (insn
->op
== OP_SUB
)
1630 code
[1] ^= 0x00010000;
1632 emitGPR(0x08, insn
->src(0));
1633 emitGPR(0x00, insn
->def(0));
1637 CodeEmitterGM107::emitIMUL()
1639 if (!longIMMD(insn
->src(1))) {
1640 switch (insn
->src(1).getFile()) {
1642 emitInsn(0x5c380000);
1643 emitGPR (0x14, insn
->src(1));
1645 case FILE_MEMORY_CONST
:
1646 emitInsn(0x4c380000);
1647 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1649 case FILE_IMMEDIATE
:
1650 emitInsn(0x38380000);
1651 emitIMMD(0x14, 19, insn
->src(1));
1654 assert(!"bad src1 file");
1658 emitField(0x29, 1, isSignedType(insn
->sType
));
1659 emitField(0x28, 1, isSignedType(insn
->dType
));
1660 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1662 emitInsn (0x1f000000);
1663 emitField(0x37, 1, isSignedType(insn
->sType
));
1664 emitField(0x36, 1, isSignedType(insn
->dType
));
1665 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1667 emitIMMD (0x14, 32, insn
->src(1));
1670 emitGPR(0x08, insn
->src(0));
1671 emitGPR(0x00, insn
->def(0));
1675 CodeEmitterGM107::emitIMAD()
1677 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1678 switch(insn
->src(2).getFile()) {
1680 switch (insn
->src(1).getFile()) {
1682 emitInsn(0x5a000000);
1683 emitGPR (0x14, insn
->src(1));
1685 case FILE_MEMORY_CONST
:
1686 emitInsn(0x4a000000);
1687 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1689 case FILE_IMMEDIATE
:
1690 emitInsn(0x34000000);
1691 emitIMMD(0x14, 19, insn
->src(1));
1694 assert(!"bad src1 file");
1697 emitGPR (0x27, insn
->src(2));
1699 case FILE_MEMORY_CONST
:
1700 emitInsn(0x52000000);
1701 emitGPR (0x27, insn
->src(1));
1702 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1705 assert(!"bad src2 file");
1709 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1710 emitField(0x35, 1, isSignedType(insn
->sType
));
1711 emitNEG (0x34, insn
->src(2));
1712 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1715 emitField(0x30, 1, isSignedType(insn
->dType
));
1717 emitGPR (0x08, insn
->src(0));
1718 emitGPR (0x00, insn
->def(0));
1722 CodeEmitterGM107::emitIMNMX()
1724 switch (insn
->src(1).getFile()) {
1726 emitInsn(0x5c200000);
1727 emitGPR (0x14, insn
->src(1));
1729 case FILE_MEMORY_CONST
:
1730 emitInsn(0x4c200000);
1731 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1733 case FILE_IMMEDIATE
:
1734 emitInsn(0x38200000);
1735 emitIMMD(0x14, 19, insn
->src(1));
1738 assert(!"bad src1 file");
1742 emitField(0x30, 1, isSignedType(insn
->dType
));
1744 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1746 emitGPR (0x08, insn
->src(0));
1747 emitGPR (0x00, insn
->def(0));
1751 CodeEmitterGM107::emitICMP()
1753 const CmpInstruction
*insn
= this->insn
->asCmp();
1754 CondCode cc
= insn
->setCond
;
1756 if (insn
->src(2).mod
.neg())
1757 cc
= reverseCondCode(cc
);
1759 switch(insn
->src(2).getFile()) {
1761 switch (insn
->src(1).getFile()) {
1763 emitInsn(0x5b400000);
1764 emitGPR (0x14, insn
->src(1));
1766 case FILE_MEMORY_CONST
:
1767 emitInsn(0x4b400000);
1768 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1770 case FILE_IMMEDIATE
:
1771 emitInsn(0x36400000);
1772 emitIMMD(0x14, 19, insn
->src(1));
1775 assert(!"bad src1 file");
1778 emitGPR (0x27, insn
->src(2));
1780 case FILE_MEMORY_CONST
:
1781 emitInsn(0x53400000);
1782 emitGPR (0x27, insn
->src(1));
1783 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1786 assert(!"bad src2 file");
1790 emitCond3(0x31, cc
);
1791 emitField(0x30, 1, isSignedType(insn
->sType
));
1792 emitGPR (0x08, insn
->src(0));
1793 emitGPR (0x00, insn
->def(0));
1797 CodeEmitterGM107::emitISET()
1799 const CmpInstruction
*insn
= this->insn
->asCmp();
1801 switch (insn
->src(1).getFile()) {
1803 emitInsn(0x5b500000);
1804 emitGPR (0x14, insn
->src(1));
1806 case FILE_MEMORY_CONST
:
1807 emitInsn(0x4b500000);
1808 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1810 case FILE_IMMEDIATE
:
1811 emitInsn(0x36500000);
1812 emitIMMD(0x14, 19, insn
->src(1));
1815 assert(!"bad src1 file");
1819 if (insn
->op
!= OP_SET
) {
1821 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1822 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1823 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1825 assert(!"invalid set op");
1828 emitPRED(0x27, insn
->src(2));
1833 emitCond3(0x31, insn
->setCond
);
1834 emitField(0x30, 1, isSignedType(insn
->sType
));
1836 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1838 emitGPR (0x08, insn
->src(0));
1839 emitGPR (0x00, insn
->def(0));
1843 CodeEmitterGM107::emitISETP()
1845 const CmpInstruction
*insn
= this->insn
->asCmp();
1847 switch (insn
->src(1).getFile()) {
1849 emitInsn(0x5b600000);
1850 emitGPR (0x14, insn
->src(1));
1852 case FILE_MEMORY_CONST
:
1853 emitInsn(0x4b600000);
1854 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1856 case FILE_IMMEDIATE
:
1857 emitInsn(0x36600000);
1858 emitIMMD(0x14, 19, insn
->src(1));
1861 assert(!"bad src1 file");
1865 if (insn
->op
!= OP_SET
) {
1867 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1868 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1869 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1871 assert(!"invalid set op");
1874 emitPRED(0x27, insn
->src(2));
1879 emitCond3(0x31, insn
->setCond
);
1880 emitField(0x30, 1, isSignedType(insn
->sType
));
1882 emitGPR (0x08, insn
->src(0));
1883 emitPRED (0x03, insn
->def(0));
1884 if (insn
->defExists(1))
1885 emitPRED(0x00, insn
->def(1));
1891 CodeEmitterGM107::emitSHL()
1893 switch (insn
->src(1).getFile()) {
1895 emitInsn(0x5c480000);
1896 emitGPR (0x14, insn
->src(1));
1898 case FILE_MEMORY_CONST
:
1899 emitInsn(0x4c480000);
1900 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1902 case FILE_IMMEDIATE
:
1903 emitInsn(0x38480000);
1904 emitIMMD(0x14, 19, insn
->src(1));
1907 assert(!"bad src1 file");
1913 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1914 emitGPR (0x08, insn
->src(0));
1915 emitGPR (0x00, insn
->def(0));
1919 CodeEmitterGM107::emitSHR()
1921 switch (insn
->src(1).getFile()) {
1923 emitInsn(0x5c280000);
1924 emitGPR (0x14, insn
->src(1));
1926 case FILE_MEMORY_CONST
:
1927 emitInsn(0x4c280000);
1928 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1930 case FILE_IMMEDIATE
:
1931 emitInsn(0x38280000);
1932 emitIMMD(0x14, 19, insn
->src(1));
1935 assert(!"bad src1 file");
1939 emitField(0x30, 1, isSignedType(insn
->dType
));
1942 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1943 emitGPR (0x08, insn
->src(0));
1944 emitGPR (0x00, insn
->def(0));
1948 CodeEmitterGM107::emitPOPC()
1950 switch (insn
->src(0).getFile()) {
1952 emitInsn(0x5c080000);
1953 emitGPR (0x14, insn
->src(0));
1955 case FILE_MEMORY_CONST
:
1956 emitInsn(0x4c080000);
1957 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1959 case FILE_IMMEDIATE
:
1960 emitInsn(0x38080000);
1961 emitIMMD(0x14, 19, insn
->src(0));
1964 assert(!"bad src1 file");
1968 emitINV(0x28, insn
->src(0));
1969 emitGPR(0x00, insn
->def(0));
1973 CodeEmitterGM107::emitBFI()
1975 switch(insn
->src(2).getFile()) {
1977 switch (insn
->src(1).getFile()) {
1979 emitInsn(0x5bf00000);
1980 emitGPR (0x14, insn
->src(1));
1982 case FILE_MEMORY_CONST
:
1983 emitInsn(0x4bf00000);
1984 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1986 case FILE_IMMEDIATE
:
1987 emitInsn(0x36f00000);
1988 emitIMMD(0x14, 19, insn
->src(1));
1991 assert(!"bad src1 file");
1994 emitGPR (0x27, insn
->src(2));
1996 case FILE_MEMORY_CONST
:
1997 emitInsn(0x53f00000);
1998 emitGPR (0x27, insn
->src(1));
1999 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2002 assert(!"bad src2 file");
2007 emitGPR (0x08, insn
->src(0));
2008 emitGPR (0x00, insn
->def(0));
2012 CodeEmitterGM107::emitBFE()
2014 switch (insn
->src(1).getFile()) {
2016 emitInsn(0x5c000000);
2017 emitGPR (0x14, insn
->src(1));
2019 case FILE_MEMORY_CONST
:
2020 emitInsn(0x4c000000);
2021 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2023 case FILE_IMMEDIATE
:
2024 emitInsn(0x38000000);
2025 emitIMMD(0x14, 19, insn
->src(1));
2028 assert(!"bad src1 file");
2032 emitField(0x30, 1, isSignedType(insn
->dType
));
2034 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2035 emitGPR (0x08, insn
->src(0));
2036 emitGPR (0x00, insn
->def(0));
2040 CodeEmitterGM107::emitFLO()
2042 switch (insn
->src(0).getFile()) {
2044 emitInsn(0x5c300000);
2045 emitGPR (0x14, insn
->src(0));
2047 case FILE_MEMORY_CONST
:
2048 emitInsn(0x4c300000);
2049 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2051 case FILE_IMMEDIATE
:
2052 emitInsn(0x38300000);
2053 emitIMMD(0x14, 19, insn
->src(0));
2056 assert(!"bad src1 file");
2060 emitField(0x30, 1, isSignedType(insn
->dType
));
2062 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2063 emitINV (0x28, insn
->src(0));
2064 emitGPR (0x00, insn
->def(0));
2067 /*******************************************************************************
2069 ******************************************************************************/
2072 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2076 switch (typeSizeof(type
)) {
2077 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2078 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2079 case 4: data
= 4; break;
2080 case 8: data
= 5; break;
2081 case 16: data
= 6; break;
2083 assert(!"bad type");
2087 emitField(pos
, 3, data
);
2091 CodeEmitterGM107::emitLDSTc(int pos
)
2095 switch (insn
->cache
) {
2096 case CACHE_CA
: mode
= 0; break;
2097 case CACHE_CG
: mode
= 1; break;
2098 case CACHE_CS
: mode
= 2; break;
2099 case CACHE_CV
: mode
= 3; break;
2101 assert(!"invalid caching mode");
2105 emitField(pos
, 2, mode
);
2109 CodeEmitterGM107::emitLDC()
2111 emitInsn (0xef900000);
2112 emitLDSTs(0x30, insn
->dType
);
2113 emitField(0x2c, 2, insn
->subOp
);
2114 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2115 emitGPR (0x00, insn
->def(0));
2119 CodeEmitterGM107::emitLDL()
2121 emitInsn (0xef400000);
2122 emitLDSTs(0x30, insn
->dType
);
2124 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2125 emitGPR (0x00, insn
->def(0));
2129 CodeEmitterGM107::emitLDS()
2131 emitInsn (0xef480000);
2132 emitLDSTs(0x30, insn
->dType
);
2133 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2134 emitGPR (0x00, insn
->def(0));
2138 CodeEmitterGM107::emitLD()
2140 emitInsn (0x80000000);
2143 emitLDSTs(0x35, insn
->dType
);
2144 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2145 emitGPR (0x00, insn
->def(0));
2149 CodeEmitterGM107::emitSTL()
2151 emitInsn (0xef500000);
2152 emitLDSTs(0x30, insn
->dType
);
2154 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2155 emitGPR (0x00, insn
->src(1));
2159 CodeEmitterGM107::emitSTS()
2161 emitInsn (0xef580000);
2162 emitLDSTs(0x30, insn
->dType
);
2163 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2164 emitGPR (0x00, insn
->src(1));
2168 CodeEmitterGM107::emitST()
2170 emitInsn (0xa0000000);
2173 emitLDSTs(0x35, insn
->dType
);
2174 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2175 emitGPR (0x00, insn
->src(1));
2179 CodeEmitterGM107::emitALD()
2181 emitInsn (0xefd80000);
2182 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2183 emitGPR (0x27, insn
->src(0).getIndirect(1));
2186 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2187 emitGPR (0x00, insn
->def(0));
2191 CodeEmitterGM107::emitAST()
2193 emitInsn (0xeff00000);
2194 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2195 emitGPR (0x27, insn
->src(0).getIndirect(1));
2197 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2198 emitGPR (0x00, insn
->src(1));
2202 CodeEmitterGM107::emitISBERD()
2204 emitInsn(0xefd00000);
2205 emitGPR (0x08, insn
->src(0));
2206 emitGPR (0x00, insn
->def(0));
2210 CodeEmitterGM107::emitAL2P()
2212 emitInsn (0xefa00000);
2213 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2215 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2216 emitGPR (0x08, insn
->src(0).getIndirect(0));
2217 emitGPR (0x00, insn
->def(0));
2221 interpApply(const InterpEntry
*entry
, uint32_t *code
,
2222 bool force_persample_interp
, bool flatshade
)
2224 int ipa
= entry
->ipa
;
2225 int reg
= entry
->reg
;
2226 int loc
= entry
->loc
;
2229 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2230 ipa
= NV50_IR_INTERP_FLAT
;
2232 } else if (force_persample_interp
&&
2233 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2234 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2235 ipa
|= NV50_IR_INTERP_CENTROID
;
2237 code
[loc
+ 1] &= ~(0xf << 0x14);
2238 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2239 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2240 code
[loc
+ 0] &= ~(0xff << 0x14);
2241 code
[loc
+ 0] |= reg
<< 0x14;
2245 CodeEmitterGM107::emitIPA()
2247 int ipam
= 0, ipas
= 0;
2249 switch (insn
->getInterpMode()) {
2250 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2251 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2252 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2253 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2255 assert(!"invalid ipa mode");
2259 switch (insn
->getSampleMode()) {
2260 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2261 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2262 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2264 assert(!"invalid ipa sample mode");
2268 emitInsn (0xe0000000);
2269 emitField(0x36, 2, ipam
);
2270 emitField(0x34, 2, ipas
);
2272 emitField(0x2f, 3, 7);
2273 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2274 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2275 code
[1] |= 0x00000040; /* .idx */
2276 emitGPR(0x00, insn
->def(0));
2278 if (insn
->op
== OP_PINTERP
) {
2279 emitGPR(0x14, insn
->src(1));
2280 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2281 emitGPR(0x27, insn
->src(2));
2282 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2284 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2285 emitGPR(0x27, insn
->src(1));
2287 addInterp(insn
->ipa
, 0xff, interpApply
);
2290 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2294 /*******************************************************************************
2296 ******************************************************************************/
2299 CodeEmitterGM107::emitPIXLD()
2301 emitInsn (0xefe80000);
2303 emitField(0x1f, 3, insn
->subOp
);
2304 emitGPR (0x08, insn
->src(0));
2305 emitGPR (0x00, insn
->def(0));
2308 /*******************************************************************************
2310 ******************************************************************************/
2313 CodeEmitterGM107::emitTEXs(int pos
)
2315 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2316 if (insn
->srcExists(src1
))
2317 emitGPR(pos
, insn
->src(src1
));
2323 CodeEmitterGM107::emitTEX()
2325 const TexInstruction
*insn
= this->insn
->asTex();
2328 if (!insn
->tex
.levelZero
) {
2330 case OP_TEX
: lodm
= 0; break;
2331 case OP_TXB
: lodm
= 2; break;
2332 case OP_TXL
: lodm
= 3; break;
2334 assert(!"invalid tex op");
2341 if (insn
->tex
.rIndirectSrc
>= 0) {
2342 emitInsn (0xdeb80000);
2343 emitField(0x35, 2, lodm
);
2344 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2346 emitInsn (0xc0380000);
2347 emitField(0x37, 2, lodm
);
2348 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2349 emitField(0x24, 13, insn
->tex
.r
);
2352 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2353 emitField(0x31, 1, insn
->tex
.liveOnly
);
2354 emitField(0x23, 1, insn
->tex
.derivAll
);
2355 emitField(0x1f, 4, insn
->tex
.mask
);
2356 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2357 insn
->tex
.target
.getDim() - 1);
2358 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2360 emitGPR (0x08, insn
->src(0));
2361 emitGPR (0x00, insn
->def(0));
2365 CodeEmitterGM107::emitTLD()
2367 const TexInstruction
*insn
= this->insn
->asTex();
2369 if (insn
->tex
.rIndirectSrc
>= 0) {
2370 emitInsn (0xdd380000);
2372 emitInsn (0xdc380000);
2373 emitField(0x24, 13, insn
->tex
.r
);
2376 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2377 emitField(0x32, 1, insn
->tex
.target
.isMS());
2378 emitField(0x31, 1, insn
->tex
.liveOnly
);
2379 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2380 emitField(0x1f, 4, insn
->tex
.mask
);
2381 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2382 insn
->tex
.target
.getDim() - 1);
2383 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2385 emitGPR (0x08, insn
->src(0));
2386 emitGPR (0x00, insn
->def(0));
2390 CodeEmitterGM107::emitTLD4()
2392 const TexInstruction
*insn
= this->insn
->asTex();
2394 if (insn
->tex
.rIndirectSrc
>= 0) {
2395 emitInsn (0xdef80000);
2396 emitField(0x26, 2, insn
->tex
.gatherComp
);
2397 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2398 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2400 emitInsn (0xc8380000);
2401 emitField(0x38, 2, insn
->tex
.gatherComp
);
2402 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2403 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2404 emitField(0x24, 13, insn
->tex
.r
);
2407 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2408 emitField(0x31, 1, insn
->tex
.liveOnly
);
2409 emitField(0x23, 1, insn
->tex
.derivAll
);
2410 emitField(0x1f, 4, insn
->tex
.mask
);
2411 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2412 insn
->tex
.target
.getDim() - 1);
2413 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2415 emitGPR (0x08, insn
->src(0));
2416 emitGPR (0x00, insn
->def(0));
2420 CodeEmitterGM107::emitTXD()
2422 const TexInstruction
*insn
= this->insn
->asTex();
2424 if (insn
->tex
.rIndirectSrc
>= 0) {
2425 emitInsn (0xde780000);
2427 emitInsn (0xde380000);
2428 emitField(0x24, 13, insn
->tex
.r
);
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::emitTMML()
2445 const TexInstruction
*insn
= this->insn
->asTex();
2447 if (insn
->tex
.rIndirectSrc
>= 0) {
2448 emitInsn (0xdf600000);
2450 emitInsn (0xdf580000);
2451 emitField(0x24, 13, insn
->tex
.r
);
2454 emitField(0x31, 1, insn
->tex
.liveOnly
);
2455 emitField(0x23, 1, insn
->tex
.derivAll
);
2456 emitField(0x1f, 4, insn
->tex
.mask
);
2457 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2458 insn
->tex
.target
.getDim() - 1);
2459 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2461 emitGPR (0x08, insn
->src(0));
2462 emitGPR (0x00, insn
->def(0));
2466 CodeEmitterGM107::emitTXQ()
2468 const TexInstruction
*insn
= this->insn
->asTex();
2471 switch (insn
->tex
.query
) {
2472 case TXQ_DIMS
: type
= 0x01; break;
2473 case TXQ_TYPE
: type
= 0x02; break;
2474 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2475 case TXQ_FILTER
: type
= 0x10; break;
2476 case TXQ_LOD
: type
= 0x12; break;
2477 case TXQ_WRAP
: type
= 0x14; break;
2478 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2480 assert(!"invalid txq query");
2484 if (insn
->tex
.rIndirectSrc
>= 0) {
2485 emitInsn (0xdf500000);
2487 emitInsn (0xdf480000);
2488 emitField(0x24, 13, insn
->tex
.r
);
2491 emitField(0x31, 1, insn
->tex
.liveOnly
);
2492 emitField(0x1f, 4, insn
->tex
.mask
);
2493 emitField(0x16, 6, type
);
2494 emitGPR (0x08, insn
->src(0));
2495 emitGPR (0x00, insn
->def(0));
2499 CodeEmitterGM107::emitDEPBAR()
2501 emitInsn (0xf0f00000);
2502 emitField(0x1d, 1, 1); /* le */
2503 emitField(0x1a, 3, 5);
2504 emitField(0x14, 6, insn
->subOp
);
2505 emitField(0x00, 6, insn
->subOp
);
2508 /*******************************************************************************
2510 ******************************************************************************/
2513 CodeEmitterGM107::emitNOP()
2515 emitInsn(0x50b00000);
2519 CodeEmitterGM107::emitKIL()
2521 emitInsn (0xe3300000);
2522 emitCond5(0x00, CC_TR
);
2526 CodeEmitterGM107::emitOUT()
2528 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2529 const int emit
= insn
->op
== OP_EMIT
;
2531 switch (insn
->src(1).getFile()) {
2533 emitInsn(0xfbe00000);
2534 emitGPR (0x14, insn
->src(1));
2536 case FILE_IMMEDIATE
:
2537 emitInsn(0xf6e00000);
2538 emitIMMD(0x14, 19, insn
->src(1));
2540 case FILE_MEMORY_CONST
:
2541 emitInsn(0xebe00000);
2542 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2545 assert(!"bad src1 file");
2549 emitField(0x27, 2, (cut
<< 1) | emit
);
2550 emitGPR (0x08, insn
->src(0));
2551 emitGPR (0x00, insn
->def(0));
2554 /*******************************************************************************
2555 * assembler front-end
2556 ******************************************************************************/
2559 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2561 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2566 if (insn
->encSize
!= 8) {
2567 ERROR("skipping undecodable instruction: "); insn
->print();
2570 if (codeSize
+ size
> codeSizeLimit
) {
2571 ERROR("code emitter output buffer too small\n");
2575 if (writeIssueDelays
) {
2576 int n
= ((codeSize
& 0x1f) / 8) - 1;
2579 data
[0] = 0x00000000;
2580 data
[1] = 0x00000000;
2586 emitField(data
, n
* 21, 21, insn
->sched
);
2630 if (insn
->def(0).getFile() == FILE_GPR
&&
2631 insn
->src(0).getFile() != FILE_PREDICATE
)
2646 if (isFloatType(insn
->dType
)) {
2647 if (isFloatType(insn
->sType
))
2652 if (isFloatType(insn
->sType
))
2663 if (isFloatType(insn
->dType
)) {
2664 if (insn
->dType
== TYPE_F64
)
2673 if (isFloatType(insn
->dType
)) {
2674 if (insn
->dType
== TYPE_F64
)
2684 if (isFloatType(insn
->dType
)) {
2685 if (insn
->dType
== TYPE_F64
)
2695 if (isFloatType(insn
->dType
)) {
2696 if (insn
->dType
== TYPE_F64
)
2723 if (isFloatType(insn
->dType
))
2732 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2733 if (isFloatType(insn
->sType
))
2734 if (insn
->sType
== TYPE_F64
)
2741 if (isFloatType(insn
->sType
))
2742 if (insn
->sType
== TYPE_F64
)
2771 switch (insn
->src(0).getFile()) {
2772 case FILE_MEMORY_CONST
: emitLDC(); break;
2773 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2774 case FILE_MEMORY_SHARED
: emitLDS(); break;
2775 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2777 assert(!"invalid load");
2783 switch (insn
->src(0).getFile()) {
2784 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2785 case FILE_MEMORY_SHARED
: emitSTS(); break;
2786 case FILE_MEMORY_GLOBAL
: emitST(); break;
2788 assert(!"invalid load");
2849 assert(!"invalid opcode");
2865 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2870 /*******************************************************************************
2871 * sched data calculator
2872 ******************************************************************************/
2874 class SchedDataCalculatorGM107
: public Pass
2877 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2880 bool visit(BasicBlock
*bb
);
2884 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2886 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2888 insn
->sched
= 0x7e0;
2894 /*******************************************************************************
2896 ******************************************************************************/
2899 CodeEmitterGM107::prepareEmission(Function
*func
)
2901 SchedDataCalculatorGM107
sched(targ
);
2902 CodeEmitter::prepareEmission(func
);
2903 sched
.run(func
, true, true);
2906 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
2908 return (size
+ 23) / 24;
2912 CodeEmitterGM107::prepareEmission(Program
*prog
)
2914 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
2915 !fi
.end(); fi
.next()) {
2916 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
2917 func
->binPos
= prog
->binSize
;
2918 prepareEmission(func
);
2920 // adjust sizes & positions for schedulding info:
2921 if (prog
->getTarget()->hasSWSched
) {
2922 uint32_t adjPos
= func
->binPos
;
2923 BasicBlock
*bb
= NULL
;
2924 for (int i
= 0; i
< func
->bbCount
; ++i
) {
2925 bb
= func
->bbArray
[i
];
2926 int32_t adjSize
= bb
->binSize
;
2928 adjSize
-= 32 - adjPos
% 32;
2932 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
2933 bb
->binPos
= adjPos
;
2934 bb
->binSize
= adjSize
;
2938 func
->binSize
= adjPos
- func
->binPos
;
2941 prog
->binSize
+= func
->binSize
;
2945 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
2946 : CodeEmitter(target
),
2948 writeIssueDelays(target
->hasSWSched
)
2951 codeSize
= codeSizeLimit
= 0;
2956 TargetGM107::createCodeEmitterGM107(Program::Type type
)
2958 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
2959 emit
->setProgramType(type
);
2963 } // namespace nv50_ir