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"
26 #include "codegen/nv50_ir_sched_gm107.h"
28 //#define GM107_DEBUG_SCHED_DATA
32 class CodeEmitterGM107
: public CodeEmitter
35 CodeEmitterGM107(const TargetGM107
*);
37 virtual bool emitInstruction(Instruction
*);
38 virtual uint32_t getMinEncodingSize(const Instruction
*) const;
40 virtual void prepareEmission(Program
*);
41 virtual void prepareEmission(Function
*);
43 inline void setProgramType(Program::Type pType
) { progType
= pType
; }
46 const TargetGM107
*targGM107
;
48 Program::Type progType
;
50 const Instruction
*insn
;
51 const bool writeIssueDelays
;
55 inline void emitField(uint32_t *, int, int, uint32_t);
56 inline void emitField(int b
, int s
, uint32_t v
) { emitField(code
, b
, s
, v
); }
58 inline void emitInsn(uint32_t, bool);
59 inline void emitInsn(uint32_t o
) { emitInsn(o
, true); }
60 inline void emitPred();
61 inline void emitGPR(int, const Value
*);
62 inline void emitGPR(int pos
) {
63 emitGPR(pos
, (const Value
*)NULL
);
65 inline void emitGPR(int pos
, const ValueRef
&ref
) {
66 emitGPR(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
68 inline void emitGPR(int pos
, const ValueRef
*ref
) {
69 emitGPR(pos
, ref
? ref
->rep() : (const Value
*)NULL
);
71 inline void emitGPR(int pos
, const ValueDef
&def
) {
72 emitGPR(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
74 inline void emitSYS(int, const Value
*);
75 inline void emitSYS(int pos
, const ValueRef
&ref
) {
76 emitSYS(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
78 inline void emitPRED(int, const Value
*);
79 inline void emitPRED(int pos
) {
80 emitPRED(pos
, (const Value
*)NULL
);
82 inline void emitPRED(int pos
, const ValueRef
&ref
) {
83 emitPRED(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
85 inline void emitPRED(int pos
, const ValueDef
&def
) {
86 emitPRED(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
88 inline void emitADDR(int, int, int, int, const ValueRef
&);
89 inline void emitCBUF(int, int, int, int, int, const ValueRef
&);
90 inline bool longIMMD(const ValueRef
&);
91 inline void emitIMMD(int, int, const ValueRef
&);
93 void emitCond3(int, CondCode
);
94 void emitCond4(int, CondCode
);
95 void emitCond5(int pos
, CondCode cc
) { emitCond4(pos
, cc
); }
96 inline void emitO(int);
97 inline void emitP(int);
98 inline void emitSAT(int);
99 inline void emitCC(int);
100 inline void emitX(int);
101 inline void emitABS(int, const ValueRef
&);
102 inline void emitNEG(int, const ValueRef
&);
103 inline void emitNEG2(int, const ValueRef
&, const ValueRef
&);
104 inline void emitFMZ(int, int);
105 inline void emitRND(int, RoundMode
, int);
106 inline void emitRND(int pos
) {
107 emitRND(pos
, insn
->rnd
, -1);
109 inline void emitPDIV(int);
110 inline void emitINV(int, const ValueRef
&);
176 void emitLDSTs(int, DataType
);
217 void emitSUHandle(const int s
);
223 /*******************************************************************************
224 * general instruction layout/fields
225 ******************************************************************************/
228 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
231 uint32_t m
= ((1ULL << s
) - 1);
232 uint64_t d
= (uint64_t)(v
& m
) << b
;
233 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
240 CodeEmitterGM107::emitPred()
242 if (insn
->predSrc
>= 0) {
243 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
244 emitField(19, 1, insn
->cc
== CC_NOT_P
);
251 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
253 code
[0] = 0x00000000;
260 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
262 emitField(pos
, 8, val
&& !val
->inFile(FILE_FLAGS
) ?
263 val
->reg
.data
.id
: 255);
267 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
269 int id
= val
? val
->reg
.data
.id
: -1;
272 case SV_LANEID
: id
= 0x00; break;
273 case SV_VERTEX_COUNT
: id
= 0x10; break;
274 case SV_INVOCATION_ID
: id
= 0x11; break;
275 case SV_THREAD_KILL
: id
= 0x13; break;
276 case SV_INVOCATION_INFO
: id
= 0x1d; break;
277 case SV_COMBINED_TID
: id
= 0x20; break;
278 case SV_TID
: id
= 0x21 + val
->reg
.data
.sv
.index
; break;
279 case SV_CTAID
: id
= 0x25 + val
->reg
.data
.sv
.index
; break;
280 case SV_LANEMASK_EQ
: id
= 0x38; break;
281 case SV_LANEMASK_LT
: id
= 0x39; break;
282 case SV_LANEMASK_LE
: id
= 0x3a; break;
283 case SV_LANEMASK_GT
: id
= 0x3b; break;
284 case SV_LANEMASK_GE
: id
= 0x3c; break;
285 case SV_CLOCK
: id
= 0x50 + val
->reg
.data
.sv
.index
; break;
287 assert(!"invalid system value");
292 emitField(pos
, 8, id
);
296 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
298 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
302 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
305 const Value
*v
= ref
.get();
306 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
308 emitGPR(gpr
, ref
.getIndirect(0));
309 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
313 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
316 const Value
*v
= ref
.get();
317 const Symbol
*s
= v
->asSym();
319 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
321 emitField(buf
, 5, v
->reg
.fileIndex
);
323 emitGPR(gpr
, ref
.getIndirect(0));
324 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
328 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
330 if (ref
.getFile() == FILE_IMMEDIATE
) {
331 const ImmediateValue
*imm
= ref
.get()->asImm();
332 if (isFloatType(insn
->sType
))
333 return imm
->reg
.data
.u32
& 0xfff;
335 return imm
->reg
.data
.s32
> 0x7ffff || imm
->reg
.data
.s32
< -0x80000;
341 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
343 const ImmediateValue
*imm
= ref
.get()->asImm();
344 uint32_t val
= imm
->reg
.data
.u32
;
347 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
348 assert(!(val
& 0x00000fff));
350 } else if (insn
->sType
== TYPE_F64
) {
351 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
352 val
= imm
->reg
.data
.u64
>> 44;
354 assert(!(val
& 0xfff80000) || (val
& 0xfff80000) == 0xfff80000);
356 emitField( 56, 1, (val
& 0x80000) >> 19);
357 emitField(pos
, len
, (val
& 0x7ffff));
359 emitField(pos
, len
, val
);
363 /*******************************************************************************
365 ******************************************************************************/
368 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
373 case CC_FL
: data
= 0x00; break;
375 case CC_LT
: data
= 0x01; break;
377 case CC_EQ
: data
= 0x02; break;
379 case CC_LE
: data
= 0x03; break;
381 case CC_GT
: data
= 0x04; break;
383 case CC_NE
: data
= 0x05; break;
385 case CC_GE
: data
= 0x06; break;
386 case CC_TR
: data
= 0x07; break;
388 assert(!"invalid cond3");
392 emitField(pos
, 3, data
);
396 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
401 case CC_FL
: data
= 0x00; break;
402 case CC_LT
: data
= 0x01; break;
403 case CC_EQ
: data
= 0x02; break;
404 case CC_LE
: data
= 0x03; break;
405 case CC_GT
: data
= 0x04; break;
406 case CC_NE
: data
= 0x05; break;
407 case CC_GE
: data
= 0x06; break;
408 // case CC_NUM: data = 0x07; break;
409 // case CC_NAN: data = 0x08; break;
410 case CC_LTU
: data
= 0x09; break;
411 case CC_EQU
: data
= 0x0a; break;
412 case CC_LEU
: data
= 0x0b; break;
413 case CC_GTU
: data
= 0x0c; break;
414 case CC_NEU
: data
= 0x0d; break;
415 case CC_GEU
: data
= 0x0e; break;
416 case CC_TR
: data
= 0x0f; break;
418 assert(!"invalid cond4");
422 emitField(pos
, 4, data
);
426 CodeEmitterGM107::emitO(int pos
)
428 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
432 CodeEmitterGM107::emitP(int pos
)
434 emitField(pos
, 1, insn
->perPatch
);
438 CodeEmitterGM107::emitSAT(int pos
)
440 emitField(pos
, 1, insn
->saturate
);
444 CodeEmitterGM107::emitCC(int pos
)
446 emitField(pos
, 1, insn
->flagsDef
>= 0);
450 CodeEmitterGM107::emitX(int pos
)
452 emitField(pos
, 1, insn
->flagsSrc
>= 0);
456 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
458 emitField(pos
, 1, ref
.mod
.abs());
462 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
464 emitField(pos
, 1, ref
.mod
.neg());
468 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
470 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
474 CodeEmitterGM107::emitFMZ(int pos
, int len
)
476 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
480 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
484 case ROUND_NI
: ri
= 1;
485 case ROUND_N
: rm
= 0; break;
486 case ROUND_MI
: ri
= 1;
487 case ROUND_M
: rm
= 1; break;
488 case ROUND_PI
: ri
= 1;
489 case ROUND_P
: rm
= 2; break;
490 case ROUND_ZI
: ri
= 1;
491 case ROUND_Z
: rm
= 3; break;
493 assert(!"invalid round mode");
496 emitField(rip
, 1, ri
);
497 emitField(rmp
, 2, rm
);
501 CodeEmitterGM107::emitPDIV(int pos
)
503 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
504 if (insn
->postFactor
> 0)
505 emitField(pos
, 3, 7 - insn
->postFactor
);
507 emitField(pos
, 3, 0 - insn
->postFactor
);
511 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
513 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
516 /*******************************************************************************
518 ******************************************************************************/
521 CodeEmitterGM107::emitEXIT()
523 emitInsn (0xe3000000);
524 emitCond5(0x00, CC_TR
);
528 CodeEmitterGM107::emitBRA()
530 const FlowInstruction
*insn
= this->insn
->asFlow();
533 if (insn
->indirect
) {
535 emitInsn(0xe2000000); // JMX
537 emitInsn(0xe2500000); // BRX
541 emitInsn(0xe2100000); // JMP
543 emitInsn(0xe2400000); // BRA
544 emitField(0x07, 1, insn
->allWarp
);
547 emitField(0x06, 1, insn
->limit
);
548 emitCond5(0x00, CC_TR
);
550 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
551 int32_t pos
= insn
->target
.bb
->binPos
;
552 if (writeIssueDelays
&& !(pos
& 0x1f))
555 emitField(0x14, 24, pos
- (codeSize
+ 8));
557 emitField(0x14, 32, pos
);
559 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
560 emitField(0x05, 1, 1);
565 CodeEmitterGM107::emitCAL()
567 const FlowInstruction
*insn
= this->insn
->asFlow();
569 if (insn
->absolute
) {
570 emitInsn(0xe2200000, 0); // JCAL
572 emitInsn(0xe2600000, 0); // CAL
575 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
577 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
580 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
581 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
582 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
584 emitField(0x14, 32, insn
->target
.bb
->binPos
);
588 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
589 emitField(0x05, 1, 1);
594 CodeEmitterGM107::emitPCNT()
596 const FlowInstruction
*insn
= this->insn
->asFlow();
598 emitInsn(0xe2b00000, 0);
600 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
601 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
603 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
604 emitField(0x05, 1, 1);
609 CodeEmitterGM107::emitCONT()
611 emitInsn (0xe3500000);
612 emitCond5(0x00, CC_TR
);
616 CodeEmitterGM107::emitPBK()
618 const FlowInstruction
*insn
= this->insn
->asFlow();
620 emitInsn(0xe2a00000, 0);
622 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
623 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
625 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
626 emitField(0x05, 1, 1);
631 CodeEmitterGM107::emitBRK()
633 emitInsn (0xe3400000);
634 emitCond5(0x00, CC_TR
);
638 CodeEmitterGM107::emitPRET()
640 const FlowInstruction
*insn
= this->insn
->asFlow();
642 emitInsn(0xe2700000, 0);
644 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
645 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
647 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
648 emitField(0x05, 1, 1);
653 CodeEmitterGM107::emitRET()
655 emitInsn (0xe3200000);
656 emitCond5(0x00, CC_TR
);
660 CodeEmitterGM107::emitSSY()
662 const FlowInstruction
*insn
= this->insn
->asFlow();
664 emitInsn(0xe2900000, 0);
666 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
667 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
669 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
670 emitField(0x05, 1, 1);
675 CodeEmitterGM107::emitSYNC()
677 emitInsn (0xf0f80000);
678 emitCond5(0x00, CC_TR
);
682 CodeEmitterGM107::emitSAM()
684 emitInsn(0xe3700000, 0);
688 CodeEmitterGM107::emitRAM()
690 emitInsn(0xe3800000, 0);
693 /*******************************************************************************
695 ******************************************************************************/
698 CodeEmitterGM107::emitPSETP()
701 emitInsn(0x50900000);
704 case OP_AND
: emitField(0x18, 3, 0); break;
705 case OP_OR
: emitField(0x18, 3, 1); break;
706 case OP_XOR
: emitField(0x18, 3, 2); break;
708 assert(!"unexpected operation");
713 emitPRED(0x27); // TODO: support 3-arg
714 emitINV (0x20, insn
->src(1));
715 emitPRED(0x1d, insn
->src(1));
716 emitINV (0x0f, insn
->src(0));
717 emitPRED(0x0c, insn
->src(0));
718 emitPRED(0x03, insn
->def(0));
722 /*******************************************************************************
723 * movement / conversion
724 ******************************************************************************/
727 CodeEmitterGM107::emitMOV()
729 if (insn
->src(0).getFile() != FILE_IMMEDIATE
) {
730 switch (insn
->src(0).getFile()) {
732 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
733 emitInsn(0x5b6a0000);
736 emitInsn(0x5c980000);
738 emitGPR (0x14, insn
->src(0));
740 case FILE_MEMORY_CONST
:
741 emitInsn(0x4c980000);
742 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
745 emitInsn(0x38980000);
746 emitIMMD(0x14, 19, insn
->src(0));
749 emitInsn(0x50880000);
750 emitPRED(0x0c, insn
->src(0));
755 assert(!"bad src file");
758 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
759 insn
->src(0).getFile() != FILE_PREDICATE
)
760 emitField(0x27, 4, insn
->lanes
);
762 emitInsn (0x01000000);
763 emitIMMD (0x14, 32, insn
->src(0));
764 emitField(0x0c, 4, insn
->lanes
);
767 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
769 emitPRED(0x03, insn
->def(0));
772 emitGPR(0x00, insn
->def(0));
777 CodeEmitterGM107::emitS2R()
779 emitInsn(0xf0c80000);
780 emitSYS (0x14, insn
->src(0));
781 emitGPR (0x00, insn
->def(0));
785 CodeEmitterGM107::emitCS2R()
787 emitInsn(0x50c80000);
788 emitSYS (0x14, insn
->src(0));
789 emitGPR (0x00, insn
->def(0));
793 CodeEmitterGM107::emitF2F()
795 RoundMode rnd
= insn
->rnd
;
798 case OP_FLOOR
: rnd
= ROUND_MI
; break;
799 case OP_CEIL
: rnd
= ROUND_PI
; break;
800 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
805 switch (insn
->src(0).getFile()) {
807 emitInsn(0x5ca80000);
808 emitGPR (0x14, insn
->src(0));
810 case FILE_MEMORY_CONST
:
811 emitInsn(0x4ca80000);
812 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
815 emitInsn(0x38a80000);
816 emitIMMD(0x14, 19, insn
->src(0));
819 assert(!"bad src0 file");
823 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
824 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
826 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
828 emitField(0x29, 1, insn
->subOp
);
829 emitRND (0x27, rnd
, 0x2a);
830 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
831 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
832 emitGPR (0x00, insn
->def(0));
836 CodeEmitterGM107::emitF2I()
838 RoundMode rnd
= insn
->rnd
;
841 case OP_FLOOR
: rnd
= ROUND_M
; break;
842 case OP_CEIL
: rnd
= ROUND_P
; break;
843 case OP_TRUNC
: rnd
= ROUND_Z
; break;
848 switch (insn
->src(0).getFile()) {
850 emitInsn(0x5cb00000);
851 emitGPR (0x14, insn
->src(0));
853 case FILE_MEMORY_CONST
:
854 emitInsn(0x4cb00000);
855 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
858 emitInsn(0x38b00000);
859 emitIMMD(0x14, 19, insn
->src(0));
862 assert(!"bad src0 file");
866 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
868 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
870 emitRND (0x27, rnd
, 0x2a);
871 emitField(0x0c, 1, isSignedType(insn
->dType
));
872 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
873 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
874 emitGPR (0x00, insn
->def(0));
878 CodeEmitterGM107::emitI2F()
880 RoundMode rnd
= insn
->rnd
;
883 case OP_FLOOR
: rnd
= ROUND_M
; break;
884 case OP_CEIL
: rnd
= ROUND_P
; break;
885 case OP_TRUNC
: rnd
= ROUND_Z
; break;
890 switch (insn
->src(0).getFile()) {
892 emitInsn(0x5cb80000);
893 emitGPR (0x14, insn
->src(0));
895 case FILE_MEMORY_CONST
:
896 emitInsn(0x4cb80000);
897 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
900 emitInsn(0x38b80000);
901 emitIMMD(0x14, 19, insn
->src(0));
904 assert(!"bad src0 file");
908 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
910 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
911 emitField(0x29, 2, insn
->subOp
);
912 emitRND (0x27, rnd
, -1);
913 emitField(0x0d, 1, isSignedType(insn
->sType
));
914 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
915 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
916 emitGPR (0x00, insn
->def(0));
920 CodeEmitterGM107::emitI2I()
922 switch (insn
->src(0).getFile()) {
924 emitInsn(0x5ce00000);
925 emitGPR (0x14, insn
->src(0));
927 case FILE_MEMORY_CONST
:
928 emitInsn(0x4ce00000);
929 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
932 emitInsn(0x38e00000);
933 emitIMMD(0x14, 19, insn
->src(0));
936 assert(!"bad src0 file");
941 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
943 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
944 emitField(0x29, 2, insn
->subOp
);
945 emitField(0x0d, 1, isSignedType(insn
->sType
));
946 emitField(0x0c, 1, isSignedType(insn
->dType
));
947 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
948 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
949 emitGPR (0x00, insn
->def(0));
953 gm107_selpFlip(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
955 int loc
= entry
->loc
;
956 if (data
.force_persample_interp
)
957 code
[loc
+ 1] |= 1 << 10;
959 code
[loc
+ 1] &= ~(1 << 10);
963 CodeEmitterGM107::emitSEL()
965 switch (insn
->src(1).getFile()) {
967 emitInsn(0x5ca00000);
968 emitGPR (0x14, insn
->src(1));
970 case FILE_MEMORY_CONST
:
971 emitInsn(0x4ca00000);
972 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
975 emitInsn(0x38a00000);
976 emitIMMD(0x14, 19, insn
->src(1));
979 assert(!"bad src1 file");
983 emitINV (0x2a, insn
->src(2));
984 emitPRED(0x27, insn
->src(2));
985 emitGPR (0x08, insn
->src(0));
986 emitGPR (0x00, insn
->def(0));
988 if (insn
->subOp
== 1) {
989 addInterp(0, 0, gm107_selpFlip
);
994 CodeEmitterGM107::emitSHFL()
998 emitInsn (0xef100000);
1000 switch (insn
->src(1).getFile()) {
1002 emitGPR(0x14, insn
->src(1));
1004 case FILE_IMMEDIATE
:
1005 emitIMMD(0x14, 5, insn
->src(1));
1009 assert(!"invalid src1 file");
1013 switch (insn
->src(2).getFile()) {
1015 emitGPR(0x27, insn
->src(2));
1017 case FILE_IMMEDIATE
:
1018 emitIMMD(0x22, 13, insn
->src(2));
1022 assert(!"invalid src2 file");
1026 if (!insn
->defExists(1))
1029 assert(insn
->def(1).getFile() == FILE_PREDICATE
);
1030 emitPRED(0x30, insn
->def(1));
1033 emitField(0x1e, 2, insn
->subOp
);
1034 emitField(0x1c, 2, type
);
1035 emitGPR (0x08, insn
->src(0));
1036 emitGPR (0x00, insn
->def(0));
1039 /*******************************************************************************
1041 ******************************************************************************/
1044 CodeEmitterGM107::emitDADD()
1046 switch (insn
->src(1).getFile()) {
1048 emitInsn(0x5c700000);
1049 emitGPR (0x14, insn
->src(1));
1051 case FILE_MEMORY_CONST
:
1052 emitInsn(0x4c700000);
1053 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1055 case FILE_IMMEDIATE
:
1056 emitInsn(0x38700000);
1057 emitIMMD(0x14, 19, insn
->src(1));
1060 assert(!"bad src1 file");
1063 emitABS(0x31, insn
->src(1));
1064 emitNEG(0x30, insn
->src(0));
1066 emitABS(0x2e, insn
->src(0));
1067 emitNEG(0x2d, insn
->src(1));
1069 if (insn
->op
== OP_SUB
)
1070 code
[1] ^= 0x00002000;
1072 emitGPR(0x08, insn
->src(0));
1073 emitGPR(0x00, insn
->def(0));
1077 CodeEmitterGM107::emitDMUL()
1079 switch (insn
->src(1).getFile()) {
1081 emitInsn(0x5c800000);
1082 emitGPR (0x14, insn
->src(1));
1084 case FILE_MEMORY_CONST
:
1085 emitInsn(0x4c800000);
1086 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1088 case FILE_IMMEDIATE
:
1089 emitInsn(0x38800000);
1090 emitIMMD(0x14, 19, insn
->src(1));
1093 assert(!"bad src1 file");
1097 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1100 emitGPR (0x08, insn
->src(0));
1101 emitGPR (0x00, insn
->def(0));
1105 CodeEmitterGM107::emitDFMA()
1107 switch(insn
->src(2).getFile()) {
1109 switch (insn
->src(1).getFile()) {
1111 emitInsn(0x5b700000);
1112 emitGPR (0x14, insn
->src(1));
1114 case FILE_MEMORY_CONST
:
1115 emitInsn(0x4b700000);
1116 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1118 case FILE_IMMEDIATE
:
1119 emitInsn(0x36700000);
1120 emitIMMD(0x14, 19, insn
->src(1));
1123 assert(!"bad src1 file");
1126 emitGPR (0x27, insn
->src(2));
1128 case FILE_MEMORY_CONST
:
1129 emitInsn(0x53700000);
1130 emitGPR (0x27, insn
->src(1));
1131 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1134 assert(!"bad src2 file");
1139 emitNEG (0x31, insn
->src(2));
1140 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1142 emitGPR (0x08, insn
->src(0));
1143 emitGPR (0x00, insn
->def(0));
1147 CodeEmitterGM107::emitDMNMX()
1149 switch (insn
->src(1).getFile()) {
1151 emitInsn(0x5c500000);
1152 emitGPR (0x14, insn
->src(1));
1154 case FILE_MEMORY_CONST
:
1155 emitInsn(0x4c500000);
1156 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1158 case FILE_IMMEDIATE
:
1159 emitInsn(0x38500000);
1160 emitIMMD(0x14, 19, insn
->src(1));
1163 assert(!"bad src1 file");
1167 emitABS (0x31, insn
->src(1));
1168 emitNEG (0x30, insn
->src(0));
1170 emitABS (0x2e, insn
->src(0));
1171 emitNEG (0x2d, insn
->src(1));
1172 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1174 emitGPR (0x08, insn
->src(0));
1175 emitGPR (0x00, insn
->def(0));
1179 CodeEmitterGM107::emitDSET()
1181 const CmpInstruction
*insn
= this->insn
->asCmp();
1183 switch (insn
->src(1).getFile()) {
1185 emitInsn(0x59000000);
1186 emitGPR (0x14, insn
->src(1));
1188 case FILE_MEMORY_CONST
:
1189 emitInsn(0x49000000);
1190 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1192 case FILE_IMMEDIATE
:
1193 emitInsn(0x32000000);
1194 emitIMMD(0x14, 19, insn
->src(1));
1197 assert(!"bad src1 file");
1201 if (insn
->op
!= OP_SET
) {
1203 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1204 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1205 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1207 assert(!"invalid set op");
1210 emitPRED(0x27, insn
->src(2));
1215 emitABS (0x36, insn
->src(0));
1216 emitNEG (0x35, insn
->src(1));
1217 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1218 emitCond4(0x30, insn
->setCond
);
1220 emitABS (0x2c, insn
->src(1));
1221 emitNEG (0x2b, insn
->src(0));
1222 emitGPR (0x08, insn
->src(0));
1223 emitGPR (0x00, insn
->def(0));
1227 CodeEmitterGM107::emitDSETP()
1229 const CmpInstruction
*insn
= this->insn
->asCmp();
1231 switch (insn
->src(1).getFile()) {
1233 emitInsn(0x5b800000);
1234 emitGPR (0x14, insn
->src(1));
1236 case FILE_MEMORY_CONST
:
1237 emitInsn(0x4b800000);
1238 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1240 case FILE_IMMEDIATE
:
1241 emitInsn(0x36800000);
1242 emitIMMD(0x14, 19, insn
->src(1));
1245 assert(!"bad src1 file");
1249 if (insn
->op
!= OP_SET
) {
1251 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1252 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1253 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1255 assert(!"invalid set op");
1258 emitPRED(0x27, insn
->src(2));
1263 emitCond4(0x30, insn
->setCond
);
1264 emitABS (0x2c, insn
->src(1));
1265 emitNEG (0x2b, insn
->src(0));
1266 emitGPR (0x08, insn
->src(0));
1267 emitABS (0x07, insn
->src(0));
1268 emitNEG (0x06, insn
->src(1));
1269 emitPRED (0x03, insn
->def(0));
1270 if (insn
->defExists(1))
1271 emitPRED(0x00, insn
->def(1));
1276 /*******************************************************************************
1278 ******************************************************************************/
1281 CodeEmitterGM107::emitFADD()
1283 if (!longIMMD(insn
->src(1))) {
1284 switch (insn
->src(1).getFile()) {
1286 emitInsn(0x5c580000);
1287 emitGPR (0x14, insn
->src(1));
1289 case FILE_MEMORY_CONST
:
1290 emitInsn(0x4c580000);
1291 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1293 case FILE_IMMEDIATE
:
1294 emitInsn(0x38580000);
1295 emitIMMD(0x14, 19, insn
->src(1));
1298 assert(!"bad src1 file");
1302 emitABS(0x31, insn
->src(1));
1303 emitNEG(0x30, insn
->src(0));
1305 emitABS(0x2e, insn
->src(0));
1306 emitNEG(0x2d, insn
->src(1));
1309 if (insn
->op
== OP_SUB
)
1310 code
[1] ^= 0x00002000;
1312 emitInsn(0x08000000);
1313 emitABS(0x39, insn
->src(1));
1314 emitNEG(0x38, insn
->src(0));
1316 emitABS(0x36, insn
->src(0));
1317 emitNEG(0x35, insn
->src(1));
1319 emitIMMD(0x14, 32, insn
->src(1));
1321 if (insn
->op
== OP_SUB
)
1322 code
[1] ^= 0x00080000;
1325 emitGPR(0x08, insn
->src(0));
1326 emitGPR(0x00, insn
->def(0));
1330 CodeEmitterGM107::emitFMUL()
1332 if (!longIMMD(insn
->src(1))) {
1333 switch (insn
->src(1).getFile()) {
1335 emitInsn(0x5c680000);
1336 emitGPR (0x14, insn
->src(1));
1338 case FILE_MEMORY_CONST
:
1339 emitInsn(0x4c680000);
1340 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1342 case FILE_IMMEDIATE
:
1343 emitInsn(0x38680000);
1344 emitIMMD(0x14, 19, insn
->src(1));
1347 assert(!"bad src1 file");
1351 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1357 emitInsn(0x1e000000);
1361 emitIMMD(0x14, 32, insn
->src(1));
1362 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1363 code
[1] ^= 0x00080000; /* flip immd sign bit */
1366 emitGPR(0x08, insn
->src(0));
1367 emitGPR(0x00, insn
->def(0));
1371 CodeEmitterGM107::emitFFMA()
1373 bool isLongIMMD
= false;
1374 switch(insn
->src(2).getFile()) {
1376 switch (insn
->src(1).getFile()) {
1378 emitInsn(0x59800000);
1379 emitGPR (0x14, insn
->src(1));
1381 case FILE_MEMORY_CONST
:
1382 emitInsn(0x49800000);
1383 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1385 case FILE_IMMEDIATE
:
1386 if (longIMMD(insn
->getSrc(1))) {
1387 assert(insn
->getDef(0)->reg
.data
.id
== insn
->getSrc(2)->reg
.data
.id
);
1389 emitInsn(0x0c000000);
1390 emitIMMD(0x14, 32, insn
->src(1));
1392 emitInsn(0x32800000);
1393 emitIMMD(0x14, 19, insn
->src(1));
1397 assert(!"bad src1 file");
1401 emitGPR (0x27, insn
->src(2));
1403 case FILE_MEMORY_CONST
:
1404 emitInsn(0x51800000);
1405 emitGPR (0x27, insn
->src(1));
1406 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1409 assert(!"bad src2 file");
1414 emitNEG (0x39, insn
->src(2));
1415 emitNEG2(0x38, insn
->src(0), insn
->src(1));
1421 emitNEG (0x31, insn
->src(2));
1422 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1427 emitGPR(0x08, insn
->src(0));
1428 emitGPR(0x00, insn
->def(0));
1432 CodeEmitterGM107::emitMUFU()
1437 case OP_COS
: mufu
= 0; break;
1438 case OP_SIN
: mufu
= 1; break;
1439 case OP_EX2
: mufu
= 2; break;
1440 case OP_LG2
: mufu
= 3; break;
1441 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1442 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1443 case OP_SQRT
: mufu
= 8; break;
1445 assert(!"invalid mufu");
1449 emitInsn (0x50800000);
1451 emitNEG (0x30, insn
->src(0));
1452 emitABS (0x2e, insn
->src(0));
1453 emitField(0x14, 4, mufu
);
1454 emitGPR (0x08, insn
->src(0));
1455 emitGPR (0x00, insn
->def(0));
1459 CodeEmitterGM107::emitFMNMX()
1461 switch (insn
->src(1).getFile()) {
1463 emitInsn(0x5c600000);
1464 emitGPR (0x14, insn
->src(1));
1466 case FILE_MEMORY_CONST
:
1467 emitInsn(0x4c600000);
1468 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1470 case FILE_IMMEDIATE
:
1471 emitInsn(0x38600000);
1472 emitIMMD(0x14, 19, insn
->src(1));
1475 assert(!"bad src1 file");
1479 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1482 emitABS(0x31, insn
->src(1));
1483 emitNEG(0x30, insn
->src(0));
1485 emitABS(0x2e, insn
->src(0));
1486 emitNEG(0x2d, insn
->src(1));
1488 emitGPR(0x08, insn
->src(0));
1489 emitGPR(0x00, insn
->def(0));
1493 CodeEmitterGM107::emitRRO()
1495 switch (insn
->src(0).getFile()) {
1497 emitInsn(0x5c900000);
1498 emitGPR (0x14, insn
->src(0));
1500 case FILE_MEMORY_CONST
:
1501 emitInsn(0x4c900000);
1502 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1504 case FILE_IMMEDIATE
:
1505 emitInsn(0x38900000);
1506 emitIMMD(0x14, 19, insn
->src(0));
1509 assert(!"bad src file");
1513 emitABS (0x31, insn
->src(0));
1514 emitNEG (0x2d, insn
->src(0));
1515 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1516 emitGPR (0x00, insn
->def(0));
1520 CodeEmitterGM107::emitFCMP()
1522 const CmpInstruction
*insn
= this->insn
->asCmp();
1523 CondCode cc
= insn
->setCond
;
1525 if (insn
->src(2).mod
.neg())
1526 cc
= reverseCondCode(cc
);
1528 switch(insn
->src(2).getFile()) {
1530 switch (insn
->src(1).getFile()) {
1532 emitInsn(0x5ba00000);
1533 emitGPR (0x14, insn
->src(1));
1535 case FILE_MEMORY_CONST
:
1536 emitInsn(0x4ba00000);
1537 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1539 case FILE_IMMEDIATE
:
1540 emitInsn(0x36a00000);
1541 emitIMMD(0x14, 19, insn
->src(1));
1544 assert(!"bad src1 file");
1547 emitGPR (0x27, insn
->src(2));
1549 case FILE_MEMORY_CONST
:
1550 emitInsn(0x53a00000);
1551 emitGPR (0x27, insn
->src(1));
1552 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1555 assert(!"bad src2 file");
1559 emitCond4(0x30, cc
);
1561 emitGPR (0x08, insn
->src(0));
1562 emitGPR (0x00, insn
->def(0));
1566 CodeEmitterGM107::emitFSET()
1568 const CmpInstruction
*insn
= this->insn
->asCmp();
1570 switch (insn
->src(1).getFile()) {
1572 emitInsn(0x58000000);
1573 emitGPR (0x14, insn
->src(1));
1575 case FILE_MEMORY_CONST
:
1576 emitInsn(0x48000000);
1577 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1579 case FILE_IMMEDIATE
:
1580 emitInsn(0x30000000);
1581 emitIMMD(0x14, 19, insn
->src(1));
1584 assert(!"bad src1 file");
1588 if (insn
->op
!= OP_SET
) {
1590 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1591 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1592 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1594 assert(!"invalid set op");
1597 emitPRED(0x27, insn
->src(2));
1603 emitABS (0x36, insn
->src(0));
1604 emitNEG (0x35, insn
->src(1));
1605 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1606 emitCond4(0x30, insn
->setCond
);
1608 emitABS (0x2c, insn
->src(1));
1609 emitNEG (0x2b, insn
->src(0));
1610 emitGPR (0x08, insn
->src(0));
1611 emitGPR (0x00, insn
->def(0));
1615 CodeEmitterGM107::emitFSETP()
1617 const CmpInstruction
*insn
= this->insn
->asCmp();
1619 switch (insn
->src(1).getFile()) {
1621 emitInsn(0x5bb00000);
1622 emitGPR (0x14, insn
->src(1));
1624 case FILE_MEMORY_CONST
:
1625 emitInsn(0x4bb00000);
1626 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1628 case FILE_IMMEDIATE
:
1629 emitInsn(0x36b00000);
1630 emitIMMD(0x14, 19, insn
->src(1));
1633 assert(!"bad src1 file");
1637 if (insn
->op
!= OP_SET
) {
1639 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1640 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1641 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1643 assert(!"invalid set op");
1646 emitPRED(0x27, insn
->src(2));
1651 emitCond4(0x30, insn
->setCond
);
1653 emitABS (0x2c, insn
->src(1));
1654 emitNEG (0x2b, insn
->src(0));
1655 emitGPR (0x08, insn
->src(0));
1656 emitABS (0x07, insn
->src(0));
1657 emitNEG (0x06, insn
->src(1));
1658 emitPRED (0x03, insn
->def(0));
1659 if (insn
->defExists(1))
1660 emitPRED(0x00, insn
->def(1));
1666 CodeEmitterGM107::emitFSWZADD()
1668 emitInsn (0x50f80000);
1672 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1673 emitField(0x1c, 8, insn
->subOp
);
1674 if (insn
->predSrc
!= 1)
1675 emitGPR (0x14, insn
->src(1));
1678 emitGPR (0x08, insn
->src(0));
1679 emitGPR (0x00, insn
->def(0));
1682 /*******************************************************************************
1684 ******************************************************************************/
1687 CodeEmitterGM107::emitLOP()
1692 case OP_AND
: lop
= 0; break;
1693 case OP_OR
: lop
= 1; break;
1694 case OP_XOR
: lop
= 2; break;
1696 assert(!"invalid lop");
1700 if (!longIMMD(insn
->src(1))) {
1701 switch (insn
->src(1).getFile()) {
1703 emitInsn(0x5c400000);
1704 emitGPR (0x14, insn
->src(1));
1706 case FILE_MEMORY_CONST
:
1707 emitInsn(0x4c400000);
1708 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1710 case FILE_IMMEDIATE
:
1711 emitInsn(0x38400000);
1712 emitIMMD(0x14, 19, insn
->src(1));
1715 assert(!"bad src1 file");
1721 emitField(0x29, 2, lop
);
1722 emitINV (0x28, insn
->src(1));
1723 emitINV (0x27, insn
->src(0));
1725 emitInsn (0x04000000);
1727 emitINV (0x38, insn
->src(1));
1728 emitINV (0x37, insn
->src(0));
1729 emitField(0x35, 2, lop
);
1731 emitIMMD (0x14, 32, insn
->src(1));
1734 emitGPR (0x08, insn
->src(0));
1735 emitGPR (0x00, insn
->def(0));
1738 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1740 CodeEmitterGM107::emitNOT()
1742 if (!longIMMD(insn
->src(0))) {
1743 switch (insn
->src(0).getFile()) {
1745 emitInsn(0x5c400700);
1746 emitGPR (0x14, insn
->src(0));
1748 case FILE_MEMORY_CONST
:
1749 emitInsn(0x4c400700);
1750 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1752 case FILE_IMMEDIATE
:
1753 emitInsn(0x38400700);
1754 emitIMMD(0x14, 19, insn
->src(0));
1757 assert(!"bad src1 file");
1762 emitInsn (0x05600000);
1763 emitIMMD (0x14, 32, insn
->src(1));
1767 emitGPR(0x00, insn
->def(0));
1771 CodeEmitterGM107::emitIADD()
1773 if (!longIMMD(insn
->src(1))) {
1774 switch (insn
->src(1).getFile()) {
1776 emitInsn(0x5c100000);
1777 emitGPR (0x14, insn
->src(1));
1779 case FILE_MEMORY_CONST
:
1780 emitInsn(0x4c100000);
1781 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1783 case FILE_IMMEDIATE
:
1784 emitInsn(0x38100000);
1785 emitIMMD(0x14, 19, insn
->src(1));
1788 assert(!"bad src1 file");
1792 emitNEG(0x31, insn
->src(0));
1793 emitNEG(0x30, insn
->src(1));
1797 emitInsn(0x1c000000);
1798 emitNEG (0x38, insn
->src(0));
1802 emitIMMD(0x14, 32, insn
->src(1));
1805 if (insn
->op
== OP_SUB
)
1806 code
[1] ^= 0x00010000;
1808 emitGPR(0x08, insn
->src(0));
1809 emitGPR(0x00, insn
->def(0));
1813 CodeEmitterGM107::emitIMUL()
1815 if (!longIMMD(insn
->src(1))) {
1816 switch (insn
->src(1).getFile()) {
1818 emitInsn(0x5c380000);
1819 emitGPR (0x14, insn
->src(1));
1821 case FILE_MEMORY_CONST
:
1822 emitInsn(0x4c380000);
1823 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1825 case FILE_IMMEDIATE
:
1826 emitInsn(0x38380000);
1827 emitIMMD(0x14, 19, insn
->src(1));
1830 assert(!"bad src1 file");
1834 emitField(0x29, 1, isSignedType(insn
->sType
));
1835 emitField(0x28, 1, isSignedType(insn
->dType
));
1836 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1838 emitInsn (0x1f000000);
1839 emitField(0x37, 1, isSignedType(insn
->sType
));
1840 emitField(0x36, 1, isSignedType(insn
->dType
));
1841 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1843 emitIMMD (0x14, 32, insn
->src(1));
1846 emitGPR(0x08, insn
->src(0));
1847 emitGPR(0x00, insn
->def(0));
1851 CodeEmitterGM107::emitIMAD()
1853 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1854 switch(insn
->src(2).getFile()) {
1856 switch (insn
->src(1).getFile()) {
1858 emitInsn(0x5a000000);
1859 emitGPR (0x14, insn
->src(1));
1861 case FILE_MEMORY_CONST
:
1862 emitInsn(0x4a000000);
1863 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1865 case FILE_IMMEDIATE
:
1866 emitInsn(0x34000000);
1867 emitIMMD(0x14, 19, insn
->src(1));
1870 assert(!"bad src1 file");
1873 emitGPR (0x27, insn
->src(2));
1875 case FILE_MEMORY_CONST
:
1876 emitInsn(0x52000000);
1877 emitGPR (0x27, insn
->src(1));
1878 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1881 assert(!"bad src2 file");
1885 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1886 emitField(0x35, 1, isSignedType(insn
->sType
));
1887 emitNEG (0x34, insn
->src(2));
1888 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1891 emitField(0x30, 1, isSignedType(insn
->dType
));
1893 emitGPR (0x08, insn
->src(0));
1894 emitGPR (0x00, insn
->def(0));
1898 CodeEmitterGM107::emitISCADD()
1900 assert(insn
->src(1).get()->asImm());
1902 switch (insn
->src(2).getFile()) {
1904 emitInsn(0x5c180000);
1905 emitGPR (0x14, insn
->src(2));
1907 case FILE_MEMORY_CONST
:
1908 emitInsn(0x4c180000);
1909 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1911 case FILE_IMMEDIATE
:
1912 emitInsn(0x38180000);
1913 emitIMMD(0x14, 19, insn
->src(2));
1916 assert(!"bad src1 file");
1919 emitNEG (0x31, insn
->src(0));
1920 emitNEG (0x30, insn
->src(2));
1922 emitIMMD(0x27, 5, insn
->src(1));
1923 emitGPR (0x08, insn
->src(0));
1924 emitGPR (0x00, insn
->def(0));
1928 CodeEmitterGM107::emitXMAD()
1930 assert(insn
->src(0).getFile() == FILE_GPR
);
1932 bool constbuf
= false;
1933 bool psl_mrg
= true;
1934 bool immediate
= false;
1935 if (insn
->src(2).getFile() == FILE_MEMORY_CONST
) {
1936 assert(insn
->src(1).getFile() == FILE_GPR
);
1939 emitInsn(0x51000000);
1940 emitGPR(0x27, insn
->src(1));
1941 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1942 } else if (insn
->src(1).getFile() == FILE_MEMORY_CONST
) {
1943 assert(insn
->src(2).getFile() == FILE_GPR
);
1945 emitInsn(0x4e000000);
1946 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1947 emitGPR(0x27, insn
->src(2));
1948 } else if (insn
->src(1).getFile() == FILE_IMMEDIATE
) {
1949 assert(insn
->src(2).getFile() == FILE_GPR
);
1950 assert(!(insn
->subOp
& NV50_IR_SUBOP_XMAD_H1(1)));
1952 emitInsn(0x36000000);
1953 emitIMMD(0x14, 16, insn
->src(1));
1954 emitGPR(0x27, insn
->src(2));
1956 assert(insn
->src(1).getFile() == FILE_GPR
);
1957 assert(insn
->src(2).getFile() == FILE_GPR
);
1958 emitInsn(0x5b000000);
1959 emitGPR(0x14, insn
->src(1));
1960 emitGPR(0x27, insn
->src(2));
1964 emitField(constbuf
? 0x37 : 0x24, 2, insn
->subOp
& 0x3);
1966 unsigned cmode
= (insn
->subOp
& NV50_IR_SUBOP_XMAD_CMODE_MASK
);
1967 cmode
>>= NV50_IR_SUBOP_XMAD_CMODE_SHIFT
;
1968 emitField(0x32, constbuf
? 2 : 3, cmode
);
1970 emitX(constbuf
? 0x36 : 0x26);
1973 emitGPR(0x0, insn
->def(0));
1974 emitGPR(0x8, insn
->src(0));
1977 if (isSignedType(insn
->sType
)) {
1978 uint16_t h1s
= insn
->subOp
& NV50_IR_SUBOP_XMAD_H1_MASK
;
1979 emitField(0x30, 2, h1s
>> NV50_IR_SUBOP_XMAD_H1_SHIFT
);
1981 emitField(0x35, 1, insn
->subOp
& NV50_IR_SUBOP_XMAD_H1(0) ? 1 : 0);
1983 bool h1
= insn
->subOp
& NV50_IR_SUBOP_XMAD_H1(1);
1984 emitField(constbuf
? 0x34 : 0x23, 1, h1
);
1989 CodeEmitterGM107::emitIMNMX()
1991 switch (insn
->src(1).getFile()) {
1993 emitInsn(0x5c200000);
1994 emitGPR (0x14, insn
->src(1));
1996 case FILE_MEMORY_CONST
:
1997 emitInsn(0x4c200000);
1998 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2000 case FILE_IMMEDIATE
:
2001 emitInsn(0x38200000);
2002 emitIMMD(0x14, 19, insn
->src(1));
2005 assert(!"bad src1 file");
2009 emitField(0x30, 1, isSignedType(insn
->dType
));
2011 emitField(0x2b, 2, insn
->subOp
);
2012 emitField(0x2a, 1, insn
->op
== OP_MAX
);
2014 emitGPR (0x08, insn
->src(0));
2015 emitGPR (0x00, insn
->def(0));
2019 CodeEmitterGM107::emitICMP()
2021 const CmpInstruction
*insn
= this->insn
->asCmp();
2022 CondCode cc
= insn
->setCond
;
2024 if (insn
->src(2).mod
.neg())
2025 cc
= reverseCondCode(cc
);
2027 switch(insn
->src(2).getFile()) {
2029 switch (insn
->src(1).getFile()) {
2031 emitInsn(0x5b400000);
2032 emitGPR (0x14, insn
->src(1));
2034 case FILE_MEMORY_CONST
:
2035 emitInsn(0x4b400000);
2036 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2038 case FILE_IMMEDIATE
:
2039 emitInsn(0x36400000);
2040 emitIMMD(0x14, 19, insn
->src(1));
2043 assert(!"bad src1 file");
2046 emitGPR (0x27, insn
->src(2));
2048 case FILE_MEMORY_CONST
:
2049 emitInsn(0x53400000);
2050 emitGPR (0x27, insn
->src(1));
2051 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2054 assert(!"bad src2 file");
2058 emitCond3(0x31, cc
);
2059 emitField(0x30, 1, isSignedType(insn
->sType
));
2060 emitGPR (0x08, insn
->src(0));
2061 emitGPR (0x00, insn
->def(0));
2065 CodeEmitterGM107::emitISET()
2067 const CmpInstruction
*insn
= this->insn
->asCmp();
2069 switch (insn
->src(1).getFile()) {
2071 emitInsn(0x5b500000);
2072 emitGPR (0x14, insn
->src(1));
2074 case FILE_MEMORY_CONST
:
2075 emitInsn(0x4b500000);
2076 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2078 case FILE_IMMEDIATE
:
2079 emitInsn(0x36500000);
2080 emitIMMD(0x14, 19, insn
->src(1));
2083 assert(!"bad src1 file");
2087 if (insn
->op
!= OP_SET
) {
2089 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
2090 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
2091 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
2093 assert(!"invalid set op");
2096 emitPRED(0x27, insn
->src(2));
2101 emitCond3(0x31, insn
->setCond
);
2102 emitField(0x30, 1, isSignedType(insn
->sType
));
2104 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
2106 emitGPR (0x08, insn
->src(0));
2107 emitGPR (0x00, insn
->def(0));
2111 CodeEmitterGM107::emitISETP()
2113 const CmpInstruction
*insn
= this->insn
->asCmp();
2115 switch (insn
->src(1).getFile()) {
2117 emitInsn(0x5b600000);
2118 emitGPR (0x14, insn
->src(1));
2120 case FILE_MEMORY_CONST
:
2121 emitInsn(0x4b600000);
2122 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2124 case FILE_IMMEDIATE
:
2125 emitInsn(0x36600000);
2126 emitIMMD(0x14, 19, insn
->src(1));
2129 assert(!"bad src1 file");
2133 if (insn
->op
!= OP_SET
) {
2135 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
2136 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
2137 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
2139 assert(!"invalid set op");
2142 emitPRED(0x27, insn
->src(2));
2147 emitCond3(0x31, insn
->setCond
);
2148 emitField(0x30, 1, isSignedType(insn
->sType
));
2150 emitGPR (0x08, insn
->src(0));
2151 emitPRED (0x03, insn
->def(0));
2152 if (insn
->defExists(1))
2153 emitPRED(0x00, insn
->def(1));
2159 CodeEmitterGM107::emitSHL()
2161 switch (insn
->src(1).getFile()) {
2163 emitInsn(0x5c480000);
2164 emitGPR (0x14, insn
->src(1));
2166 case FILE_MEMORY_CONST
:
2167 emitInsn(0x4c480000);
2168 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2170 case FILE_IMMEDIATE
:
2171 emitInsn(0x38480000);
2172 emitIMMD(0x14, 19, insn
->src(1));
2175 assert(!"bad src1 file");
2181 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2182 emitGPR (0x08, insn
->src(0));
2183 emitGPR (0x00, insn
->def(0));
2187 CodeEmitterGM107::emitSHR()
2189 switch (insn
->src(1).getFile()) {
2191 emitInsn(0x5c280000);
2192 emitGPR (0x14, insn
->src(1));
2194 case FILE_MEMORY_CONST
:
2195 emitInsn(0x4c280000);
2196 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2198 case FILE_IMMEDIATE
:
2199 emitInsn(0x38280000);
2200 emitIMMD(0x14, 19, insn
->src(1));
2203 assert(!"bad src1 file");
2207 emitField(0x30, 1, isSignedType(insn
->dType
));
2210 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
2211 emitGPR (0x08, insn
->src(0));
2212 emitGPR (0x00, insn
->def(0));
2216 CodeEmitterGM107::emitSHF()
2220 switch (insn
->src(1).getFile()) {
2222 emitInsn(insn
->op
== OP_SHL
? 0x5bf80000 : 0x5cf80000);
2223 emitGPR(0x14, insn
->src(1));
2225 case FILE_IMMEDIATE
:
2226 emitInsn(insn
->op
== OP_SHL
? 0x36f80000 : 0x38f80000);
2227 emitIMMD(0x14, 19, insn
->src(1));
2230 assert(!"bad src1 file");
2234 switch (insn
->sType
) {
2246 emitField(0x32, 1, !!(insn
->subOp
& NV50_IR_SUBOP_SHIFT_WRAP
));
2248 emitField(0x30, 1, !!(insn
->subOp
& NV50_IR_SUBOP_SHIFT_HIGH
));
2250 emitGPR (0x27, insn
->src(2));
2251 emitField(0x25, 2, type
);
2252 emitGPR (0x08, insn
->src(0));
2253 emitGPR (0x00, insn
->def(0));
2257 CodeEmitterGM107::emitPOPC()
2259 switch (insn
->src(0).getFile()) {
2261 emitInsn(0x5c080000);
2262 emitGPR (0x14, insn
->src(0));
2264 case FILE_MEMORY_CONST
:
2265 emitInsn(0x4c080000);
2266 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2268 case FILE_IMMEDIATE
:
2269 emitInsn(0x38080000);
2270 emitIMMD(0x14, 19, insn
->src(0));
2273 assert(!"bad src1 file");
2277 emitINV(0x28, insn
->src(0));
2278 emitGPR(0x00, insn
->def(0));
2282 CodeEmitterGM107::emitBFI()
2284 switch(insn
->src(2).getFile()) {
2286 switch (insn
->src(1).getFile()) {
2288 emitInsn(0x5bf00000);
2289 emitGPR (0x14, insn
->src(1));
2291 case FILE_MEMORY_CONST
:
2292 emitInsn(0x4bf00000);
2293 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2295 case FILE_IMMEDIATE
:
2296 emitInsn(0x36f00000);
2297 emitIMMD(0x14, 19, insn
->src(1));
2300 assert(!"bad src1 file");
2303 emitGPR (0x27, insn
->src(2));
2305 case FILE_MEMORY_CONST
:
2306 emitInsn(0x53f00000);
2307 emitGPR (0x27, insn
->src(1));
2308 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2311 assert(!"bad src2 file");
2316 emitGPR (0x08, insn
->src(0));
2317 emitGPR (0x00, insn
->def(0));
2321 CodeEmitterGM107::emitBFE()
2323 switch (insn
->src(1).getFile()) {
2325 emitInsn(0x5c000000);
2326 emitGPR (0x14, insn
->src(1));
2328 case FILE_MEMORY_CONST
:
2329 emitInsn(0x4c000000);
2330 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2332 case FILE_IMMEDIATE
:
2333 emitInsn(0x38000000);
2334 emitIMMD(0x14, 19, insn
->src(1));
2337 assert(!"bad src1 file");
2341 emitField(0x30, 1, isSignedType(insn
->dType
));
2343 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2344 emitGPR (0x08, insn
->src(0));
2345 emitGPR (0x00, insn
->def(0));
2349 CodeEmitterGM107::emitFLO()
2351 switch (insn
->src(0).getFile()) {
2353 emitInsn(0x5c300000);
2354 emitGPR (0x14, insn
->src(0));
2356 case FILE_MEMORY_CONST
:
2357 emitInsn(0x4c300000);
2358 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2360 case FILE_IMMEDIATE
:
2361 emitInsn(0x38300000);
2362 emitIMMD(0x14, 19, insn
->src(0));
2365 assert(!"bad src1 file");
2369 emitField(0x30, 1, isSignedType(insn
->dType
));
2371 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2372 emitINV (0x28, insn
->src(0));
2373 emitGPR (0x00, insn
->def(0));
2377 CodeEmitterGM107::emitPRMT()
2379 switch (insn
->src(1).getFile()) {
2381 emitInsn(0x5bc00000);
2382 emitGPR (0x14, insn
->src(1));
2384 case FILE_MEMORY_CONST
:
2385 emitInsn(0x4bc00000);
2386 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2388 case FILE_IMMEDIATE
:
2389 emitInsn(0x36c00000);
2390 emitIMMD(0x14, 19, insn
->src(1));
2393 assert(!"bad src1 file");
2397 emitField(0x30, 3, insn
->subOp
);
2398 emitGPR (0x27, insn
->src(2));
2399 emitGPR (0x08, insn
->src(0));
2400 emitGPR (0x00, insn
->def(0));
2403 /*******************************************************************************
2405 ******************************************************************************/
2408 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2412 switch (typeSizeof(type
)) {
2413 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2414 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2415 case 4: data
= 4; break;
2416 case 8: data
= 5; break;
2417 case 16: data
= 6; break;
2419 assert(!"bad type");
2423 emitField(pos
, 3, data
);
2427 CodeEmitterGM107::emitLDSTc(int pos
)
2431 switch (insn
->cache
) {
2432 case CACHE_CA
: mode
= 0; break;
2433 case CACHE_CG
: mode
= 1; break;
2434 case CACHE_CS
: mode
= 2; break;
2435 case CACHE_CV
: mode
= 3; break;
2437 assert(!"invalid caching mode");
2441 emitField(pos
, 2, mode
);
2445 CodeEmitterGM107::emitLDC()
2447 emitInsn (0xef900000);
2448 emitLDSTs(0x30, insn
->dType
);
2449 emitField(0x2c, 2, insn
->subOp
);
2450 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2451 emitGPR (0x00, insn
->def(0));
2455 CodeEmitterGM107::emitLDL()
2457 emitInsn (0xef400000);
2458 emitLDSTs(0x30, insn
->dType
);
2460 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2461 emitGPR (0x00, insn
->def(0));
2465 CodeEmitterGM107::emitLDS()
2467 emitInsn (0xef480000);
2468 emitLDSTs(0x30, insn
->dType
);
2469 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2470 emitGPR (0x00, insn
->def(0));
2474 CodeEmitterGM107::emitLD()
2476 emitInsn (0x80000000);
2479 emitLDSTs(0x35, insn
->dType
);
2480 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2481 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2482 emitGPR (0x00, insn
->def(0));
2486 CodeEmitterGM107::emitSTL()
2488 emitInsn (0xef500000);
2489 emitLDSTs(0x30, insn
->dType
);
2491 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2492 emitGPR (0x00, insn
->src(1));
2496 CodeEmitterGM107::emitSTS()
2498 emitInsn (0xef580000);
2499 emitLDSTs(0x30, insn
->dType
);
2500 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2501 emitGPR (0x00, insn
->src(1));
2505 CodeEmitterGM107::emitST()
2507 emitInsn (0xa0000000);
2510 emitLDSTs(0x35, insn
->dType
);
2511 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2512 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2513 emitGPR (0x00, insn
->src(1));
2517 CodeEmitterGM107::emitALD()
2519 emitInsn (0xefd80000);
2520 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2521 emitGPR (0x27, insn
->src(0).getIndirect(1));
2524 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2525 emitGPR (0x00, insn
->def(0));
2529 CodeEmitterGM107::emitAST()
2531 emitInsn (0xeff00000);
2532 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2533 emitGPR (0x27, insn
->src(0).getIndirect(1));
2535 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2536 emitGPR (0x00, insn
->src(1));
2540 CodeEmitterGM107::emitISBERD()
2542 emitInsn(0xefd00000);
2543 emitGPR (0x08, insn
->src(0));
2544 emitGPR (0x00, insn
->def(0));
2548 CodeEmitterGM107::emitAL2P()
2550 emitInsn (0xefa00000);
2551 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2554 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2555 emitGPR (0x08, insn
->src(0).getIndirect(0));
2556 emitGPR (0x00, insn
->def(0));
2560 gm107_interpApply(const FixupEntry
*entry
, uint32_t *code
, const FixupData
& data
)
2562 int ipa
= entry
->ipa
;
2563 int reg
= entry
->reg
;
2564 int loc
= entry
->loc
;
2566 if (data
.flatshade
&&
2567 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2568 ipa
= NV50_IR_INTERP_FLAT
;
2570 } else if (data
.force_persample_interp
&&
2571 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2572 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2573 ipa
|= NV50_IR_INTERP_CENTROID
;
2575 code
[loc
+ 1] &= ~(0xf << 0x14);
2576 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2577 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2578 code
[loc
+ 0] &= ~(0xff << 0x14);
2579 code
[loc
+ 0] |= reg
<< 0x14;
2583 CodeEmitterGM107::emitIPA()
2585 int ipam
= 0, ipas
= 0;
2587 switch (insn
->getInterpMode()) {
2588 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2589 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2590 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2591 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2593 assert(!"invalid ipa mode");
2597 switch (insn
->getSampleMode()) {
2598 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2599 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2600 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2602 assert(!"invalid ipa sample mode");
2606 emitInsn (0xe0000000);
2607 emitField(0x36, 2, ipam
);
2608 emitField(0x34, 2, ipas
);
2610 emitField(0x2f, 3, 7);
2611 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2612 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2613 code
[1] |= 0x00000040; /* .idx */
2614 emitGPR(0x00, insn
->def(0));
2616 if (insn
->op
== OP_PINTERP
) {
2617 emitGPR(0x14, insn
->src(1));
2618 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2619 emitGPR(0x27, insn
->src(2));
2620 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, gm107_interpApply
);
2622 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2623 emitGPR(0x27, insn
->src(1));
2625 addInterp(insn
->ipa
, 0xff, gm107_interpApply
);
2628 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2633 CodeEmitterGM107::emitATOM()
2635 unsigned dType
, subOp
;
2637 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2638 switch (insn
->dType
) {
2639 case TYPE_U32
: dType
= 0; break;
2640 case TYPE_U64
: dType
= 1; break;
2641 default: assert(!"unexpected dType"); dType
= 0; break;
2645 emitInsn (0xee000000);
2647 switch (insn
->dType
) {
2648 case TYPE_U32
: dType
= 0; break;
2649 case TYPE_S32
: dType
= 1; break;
2650 case TYPE_U64
: dType
= 2; break;
2651 case TYPE_F32
: dType
= 3; break;
2652 case TYPE_B128
: dType
= 4; break;
2653 case TYPE_S64
: dType
= 5; break;
2654 default: assert(!"unexpected dType"); dType
= 0; break;
2656 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2659 subOp
= insn
->subOp
;
2661 emitInsn (0xed000000);
2664 emitField(0x34, 4, subOp
);
2665 emitField(0x31, 3, dType
);
2666 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2667 emitGPR (0x14, insn
->src(1));
2668 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2669 emitGPR (0x00, insn
->def(0));
2673 CodeEmitterGM107::emitATOMS()
2675 unsigned dType
, subOp
;
2677 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
2678 switch (insn
->dType
) {
2679 case TYPE_U32
: dType
= 0; break;
2680 case TYPE_U64
: dType
= 1; break;
2681 default: assert(!"unexpected dType"); dType
= 0; break;
2685 emitInsn (0xee000000);
2686 emitField(0x34, 1, dType
);
2688 switch (insn
->dType
) {
2689 case TYPE_U32
: dType
= 0; break;
2690 case TYPE_S32
: dType
= 1; break;
2691 case TYPE_U64
: dType
= 2; break;
2692 case TYPE_S64
: dType
= 3; break;
2693 default: assert(!"unexpected dType"); dType
= 0; break;
2696 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2699 subOp
= insn
->subOp
;
2701 emitInsn (0xec000000);
2702 emitField(0x1c, 3, dType
);
2705 emitField(0x34, 4, subOp
);
2706 emitGPR (0x14, insn
->src(1));
2707 emitADDR (0x08, 0x1e, 22, 2, insn
->src(0));
2708 emitGPR (0x00, insn
->def(0));
2712 CodeEmitterGM107::emitRED()
2716 switch (insn
->dType
) {
2717 case TYPE_U32
: dType
= 0; break;
2718 case TYPE_S32
: dType
= 1; break;
2719 case TYPE_U64
: dType
= 2; break;
2720 case TYPE_F32
: dType
= 3; break;
2721 case TYPE_B128
: dType
= 4; break;
2722 case TYPE_S64
: dType
= 5; break;
2723 default: assert(!"unexpected dType"); dType
= 0; break;
2726 emitInsn (0xebf80000);
2727 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2728 emitField(0x17, 3, insn
->subOp
);
2729 emitField(0x14, 3, dType
);
2730 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2731 emitGPR (0x00, insn
->src(1));
2735 CodeEmitterGM107::emitCCTL()
2738 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2739 emitInsn(0xef600000);
2742 emitInsn(0xef800000);
2745 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2746 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2747 emitField(0x00, 4, insn
->subOp
);
2750 /*******************************************************************************
2752 ******************************************************************************/
2755 CodeEmitterGM107::emitPIXLD()
2757 emitInsn (0xefe80000);
2759 emitField(0x1f, 3, insn
->subOp
);
2760 emitGPR (0x08, insn
->src(0));
2761 emitGPR (0x00, insn
->def(0));
2764 /*******************************************************************************
2766 ******************************************************************************/
2769 CodeEmitterGM107::emitTEXs(int pos
)
2771 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2772 if (insn
->srcExists(src1
))
2773 emitGPR(pos
, insn
->src(src1
));
2779 getTEXSMask(uint8_t mask
)
2782 case 0x1: return 0x0;
2783 case 0x2: return 0x1;
2784 case 0x3: return 0x4;
2785 case 0x4: return 0x2;
2786 case 0x7: return 0x0;
2787 case 0x8: return 0x3;
2788 case 0x9: return 0x5;
2789 case 0xa: return 0x6;
2790 case 0xb: return 0x1;
2791 case 0xc: return 0x7;
2792 case 0xd: return 0x2;
2793 case 0xe: return 0x3;
2794 case 0xf: return 0x4;
2796 assert(!"invalid mask");
2802 getTEXSTarget(const TexInstruction
*tex
)
2804 assert(tex
->op
== OP_TEX
|| tex
->op
== OP_TXL
);
2806 switch (tex
->tex
.target
.getEnum()) {
2808 assert(tex
->tex
.levelZero
);
2811 case TEX_TARGET_RECT
:
2812 if (tex
->tex
.levelZero
)
2814 if (tex
->op
== OP_TXL
)
2817 case TEX_TARGET_2D_SHADOW
:
2818 case TEX_TARGET_RECT_SHADOW
:
2819 if (tex
->tex
.levelZero
)
2821 if (tex
->op
== OP_TXL
)
2824 case TEX_TARGET_2D_ARRAY
:
2825 if (tex
->tex
.levelZero
)
2828 case TEX_TARGET_2D_ARRAY_SHADOW
:
2829 assert(tex
->tex
.levelZero
);
2832 if (tex
->tex
.levelZero
)
2834 assert(tex
->op
!= OP_TXL
);
2836 case TEX_TARGET_CUBE
:
2837 assert(!tex
->tex
.levelZero
);
2838 if (tex
->op
== OP_TXL
)
2848 getTLDSTarget(const TexInstruction
*tex
)
2850 switch (tex
->tex
.target
.getEnum()) {
2852 if (tex
->tex
.levelZero
)
2856 case TEX_TARGET_RECT
:
2857 if (tex
->tex
.levelZero
)
2858 return tex
->tex
.useOffsets
? 0x4 : 0x2;
2859 return tex
->tex
.useOffsets
? 0xc : 0x5;
2860 case TEX_TARGET_2D_MS
:
2861 assert(tex
->tex
.levelZero
);
2864 assert(tex
->tex
.levelZero
);
2866 case TEX_TARGET_2D_ARRAY
:
2867 assert(tex
->tex
.levelZero
);
2877 CodeEmitterGM107::emitTEX()
2879 const TexInstruction
*insn
= this->insn
->asTex();
2882 if (!insn
->tex
.levelZero
) {
2884 case OP_TEX
: lodm
= 0; break;
2885 case OP_TXB
: lodm
= 2; break;
2886 case OP_TXL
: lodm
= 3; break;
2888 assert(!"invalid tex op");
2895 if (insn
->tex
.rIndirectSrc
>= 0) {
2896 emitInsn (0xdeb80000);
2897 emitField(0x25, 2, lodm
);
2898 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2900 emitInsn (0xc0380000);
2901 emitField(0x37, 2, lodm
);
2902 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2903 emitField(0x24, 13, insn
->tex
.r
);
2906 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2907 emitField(0x31, 1, insn
->tex
.liveOnly
);
2908 emitField(0x23, 1, insn
->tex
.derivAll
);
2909 emitField(0x1f, 4, insn
->tex
.mask
);
2910 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2911 insn
->tex
.target
.getDim() - 1);
2912 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2914 emitGPR (0x08, insn
->src(0));
2915 emitGPR (0x00, insn
->def(0));
2919 CodeEmitterGM107::emitTEXS()
2921 const TexInstruction
*insn
= this->insn
->asTex();
2922 assert(!insn
->tex
.derivAll
);
2927 emitInsn (0xd8000000);
2928 emitField(0x35, 4, getTEXSTarget(insn
));
2929 emitField(0x32, 3, getTEXSMask(insn
->tex
.mask
));
2932 emitInsn (0xda000000);
2933 emitField(0x35, 4, getTLDSTarget(insn
));
2934 emitField(0x32, 3, getTEXSMask(insn
->tex
.mask
));
2937 assert(insn
->tex
.useOffsets
!= 4);
2938 emitInsn (0xdf000000);
2939 emitField(0x34, 2, insn
->tex
.gatherComp
);
2940 emitField(0x33, 1, insn
->tex
.useOffsets
== 1);
2941 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2944 unreachable("unknown op in emitTEXS()");
2948 emitField(0x31, 1, insn
->tex
.liveOnly
);
2949 emitField(0x24, 13, insn
->tex
.r
);
2950 if (insn
->defExists(1))
2951 emitGPR(0x1c, insn
->def(1));
2954 if (insn
->srcExists(1))
2955 emitGPR(0x14, insn
->getSrc(1));
2958 emitGPR (0x08, insn
->src(0));
2959 emitGPR (0x00, insn
->def(0));
2963 CodeEmitterGM107::emitTLD()
2965 const TexInstruction
*insn
= this->insn
->asTex();
2967 if (insn
->tex
.rIndirectSrc
>= 0) {
2968 emitInsn (0xdd380000);
2970 emitInsn (0xdc380000);
2971 emitField(0x24, 13, insn
->tex
.r
);
2974 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2975 emitField(0x32, 1, insn
->tex
.target
.isMS());
2976 emitField(0x31, 1, insn
->tex
.liveOnly
);
2977 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2978 emitField(0x1f, 4, insn
->tex
.mask
);
2979 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2980 insn
->tex
.target
.getDim() - 1);
2981 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2983 emitGPR (0x08, insn
->src(0));
2984 emitGPR (0x00, insn
->def(0));
2988 CodeEmitterGM107::emitTLD4()
2990 const TexInstruction
*insn
= this->insn
->asTex();
2992 if (insn
->tex
.rIndirectSrc
>= 0) {
2993 emitInsn (0xdef80000);
2994 emitField(0x26, 2, insn
->tex
.gatherComp
);
2995 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2996 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2998 emitInsn (0xc8380000);
2999 emitField(0x38, 2, insn
->tex
.gatherComp
);
3000 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
3001 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
3002 emitField(0x24, 13, insn
->tex
.r
);
3005 emitField(0x32, 1, insn
->tex
.target
.isShadow());
3006 emitField(0x31, 1, insn
->tex
.liveOnly
);
3007 emitField(0x23, 1, insn
->tex
.derivAll
);
3008 emitField(0x1f, 4, insn
->tex
.mask
);
3009 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
3010 insn
->tex
.target
.getDim() - 1);
3011 emitField(0x1c, 1, insn
->tex
.target
.isArray());
3013 emitGPR (0x08, insn
->src(0));
3014 emitGPR (0x00, insn
->def(0));
3018 CodeEmitterGM107::emitTXD()
3020 const TexInstruction
*insn
= this->insn
->asTex();
3022 if (insn
->tex
.rIndirectSrc
>= 0) {
3023 emitInsn (0xde780000);
3025 emitInsn (0xde380000);
3026 emitField(0x24, 13, insn
->tex
.r
);
3029 emitField(0x31, 1, insn
->tex
.liveOnly
);
3030 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
3031 emitField(0x1f, 4, insn
->tex
.mask
);
3032 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
3033 insn
->tex
.target
.getDim() - 1);
3034 emitField(0x1c, 1, insn
->tex
.target
.isArray());
3036 emitGPR (0x08, insn
->src(0));
3037 emitGPR (0x00, insn
->def(0));
3041 CodeEmitterGM107::emitTMML()
3043 const TexInstruction
*insn
= this->insn
->asTex();
3045 if (insn
->tex
.rIndirectSrc
>= 0) {
3046 emitInsn (0xdf600000);
3048 emitInsn (0xdf580000);
3049 emitField(0x24, 13, insn
->tex
.r
);
3052 emitField(0x31, 1, insn
->tex
.liveOnly
);
3053 emitField(0x23, 1, insn
->tex
.derivAll
);
3054 emitField(0x1f, 4, insn
->tex
.mask
);
3055 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
3056 insn
->tex
.target
.getDim() - 1);
3057 emitField(0x1c, 1, insn
->tex
.target
.isArray());
3059 emitGPR (0x08, insn
->src(0));
3060 emitGPR (0x00, insn
->def(0));
3064 CodeEmitterGM107::emitTXQ()
3066 const TexInstruction
*insn
= this->insn
->asTex();
3069 switch (insn
->tex
.query
) {
3070 case TXQ_DIMS
: type
= 0x01; break;
3071 case TXQ_TYPE
: type
= 0x02; break;
3072 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
3073 case TXQ_FILTER
: type
= 0x10; break;
3074 case TXQ_LOD
: type
= 0x12; break;
3075 case TXQ_WRAP
: type
= 0x14; break;
3076 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
3078 assert(!"invalid txq query");
3082 if (insn
->tex
.rIndirectSrc
>= 0) {
3083 emitInsn (0xdf500000);
3085 emitInsn (0xdf480000);
3086 emitField(0x24, 13, insn
->tex
.r
);
3089 emitField(0x31, 1, insn
->tex
.liveOnly
);
3090 emitField(0x1f, 4, insn
->tex
.mask
);
3091 emitField(0x16, 6, type
);
3092 emitGPR (0x08, insn
->src(0));
3093 emitGPR (0x00, insn
->def(0));
3097 CodeEmitterGM107::emitDEPBAR()
3099 emitInsn (0xf0f00000);
3100 emitField(0x1d, 1, 1); /* le */
3101 emitField(0x1a, 3, 5);
3102 emitField(0x14, 6, insn
->subOp
);
3103 emitField(0x00, 6, insn
->subOp
);
3106 /*******************************************************************************
3108 ******************************************************************************/
3111 CodeEmitterGM107::emitNOP()
3113 emitInsn(0x50b00000);
3117 CodeEmitterGM107::emitKIL()
3119 emitInsn (0xe3300000);
3120 emitCond5(0x00, CC_TR
);
3124 CodeEmitterGM107::emitOUT()
3126 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
3127 const int emit
= insn
->op
== OP_EMIT
;
3129 switch (insn
->src(1).getFile()) {
3131 emitInsn(0xfbe00000);
3132 emitGPR (0x14, insn
->src(1));
3134 case FILE_IMMEDIATE
:
3135 emitInsn(0xf6e00000);
3136 emitIMMD(0x14, 19, insn
->src(1));
3138 case FILE_MEMORY_CONST
:
3139 emitInsn(0xebe00000);
3140 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
3143 assert(!"bad src1 file");
3147 emitField(0x27, 2, (cut
<< 1) | emit
);
3148 emitGPR (0x08, insn
->src(0));
3149 emitGPR (0x00, insn
->def(0));
3153 CodeEmitterGM107::emitBAR()
3157 emitInsn (0xf0a80000);
3159 switch (insn
->subOp
) {
3160 case NV50_IR_SUBOP_BAR_RED_POPC
: subop
= 0x02; break;
3161 case NV50_IR_SUBOP_BAR_RED_AND
: subop
= 0x0a; break;
3162 case NV50_IR_SUBOP_BAR_RED_OR
: subop
= 0x12; break;
3163 case NV50_IR_SUBOP_BAR_ARRIVE
: subop
= 0x81; break;
3166 assert(insn
->subOp
== NV50_IR_SUBOP_BAR_SYNC
);
3170 emitField(0x20, 8, subop
);
3173 if (insn
->src(0).getFile() == FILE_GPR
) {
3174 emitGPR(0x08, insn
->src(0));
3176 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
3178 emitField(0x08, 8, imm
->reg
.data
.u32
);
3179 emitField(0x2b, 1, 1);
3183 if (insn
->src(1).getFile() == FILE_GPR
) {
3184 emitGPR(0x14, insn
->src(1));
3186 ImmediateValue
*imm
= insn
->getSrc(0)->asImm();
3188 emitField(0x14, 12, imm
->reg
.data
.u32
);
3189 emitField(0x2c, 1, 1);
3192 if (insn
->srcExists(2) && (insn
->predSrc
!= 2)) {
3193 emitPRED (0x27, insn
->src(2));
3194 emitField(0x2a, 1, insn
->src(2).mod
== Modifier(NV50_IR_MOD_NOT
));
3196 emitField(0x27, 3, 7);
3201 CodeEmitterGM107::emitMEMBAR()
3203 emitInsn (0xef980000);
3204 emitField(0x08, 2, insn
->subOp
>> 2);
3208 CodeEmitterGM107::emitVOTE()
3210 const ImmediateValue
*imm
;
3214 for (int i
= 0; insn
->defExists(i
); i
++) {
3215 if (insn
->def(i
).getFile() == FILE_GPR
)
3217 else if (insn
->def(i
).getFile() == FILE_PREDICATE
)
3221 emitInsn (0x50d80000);
3222 emitField(0x30, 2, insn
->subOp
);
3224 emitGPR (0x00, insn
->def(r
));
3228 emitPRED (0x2d, insn
->def(p
));
3232 switch (insn
->src(0).getFile()) {
3233 case FILE_PREDICATE
:
3234 emitField(0x2a, 1, insn
->src(0).mod
== Modifier(NV50_IR_MOD_NOT
));
3235 emitPRED (0x27, insn
->src(0));
3237 case FILE_IMMEDIATE
:
3238 imm
= insn
->getSrc(0)->asImm();
3240 u32
= imm
->reg
.data
.u32
;
3241 assert(u32
== 0 || u32
== 1);
3243 emitField(0x2a, 1, u32
== 0);
3246 assert(!"Unhandled src");
3252 CodeEmitterGM107::emitSUTarget()
3254 const TexInstruction
*insn
= this->insn
->asTex();
3257 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
3259 if (insn
->tex
.target
== TEX_TARGET_BUFFER
) {
3261 } else if (insn
->tex
.target
== TEX_TARGET_1D_ARRAY
) {
3263 } else if (insn
->tex
.target
== TEX_TARGET_2D
||
3264 insn
->tex
.target
== TEX_TARGET_RECT
) {
3266 } else if (insn
->tex
.target
== TEX_TARGET_2D_ARRAY
||
3267 insn
->tex
.target
== TEX_TARGET_CUBE
||
3268 insn
->tex
.target
== TEX_TARGET_CUBE_ARRAY
) {
3270 } else if (insn
->tex
.target
== TEX_TARGET_3D
) {
3273 assert(insn
->tex
.target
== TEX_TARGET_1D
);
3275 emitField(0x20, 4, target
);
3279 CodeEmitterGM107::emitSUHandle(const int s
)
3281 const TexInstruction
*insn
= this->insn
->asTex();
3283 assert(insn
->op
>= OP_SULDB
&& insn
->op
<= OP_SUREDP
);
3285 if (insn
->src(s
).getFile() == FILE_GPR
) {
3286 emitGPR(0x27, insn
->src(s
));
3288 ImmediateValue
*imm
= insn
->getSrc(s
)->asImm();
3290 emitField(0x33, 1, 1);
3291 emitField(0x24, 13, imm
->reg
.data
.u32
);
3296 CodeEmitterGM107::emitSUSTx()
3298 const TexInstruction
*insn
= this->insn
->asTex();
3300 emitInsn(0xeb200000);
3301 if (insn
->op
== OP_SUSTB
)
3302 emitField(0x34, 1, 1);
3306 emitField(0x14, 4, 0xf); // rgba
3307 emitGPR (0x08, insn
->src(0));
3308 emitGPR (0x00, insn
->src(1));
3314 CodeEmitterGM107::emitSULDx()
3316 const TexInstruction
*insn
= this->insn
->asTex();
3319 emitInsn(0xeb000000);
3320 if (insn
->op
== OP_SULDB
)
3321 emitField(0x34, 1, 1);
3324 switch (insn
->dType
) {
3325 case TYPE_S8
: type
= 1; break;
3326 case TYPE_U16
: type
= 2; break;
3327 case TYPE_S16
: type
= 3; break;
3328 case TYPE_U32
: type
= 4; break;
3329 case TYPE_U64
: type
= 5; break;
3330 case TYPE_B128
: type
= 6; break;
3332 assert(insn
->dType
== TYPE_U8
);
3336 emitField(0x14, 3, type
);
3337 emitGPR (0x00, insn
->def(0));
3338 emitGPR (0x08, insn
->src(0));
3344 CodeEmitterGM107::emitSUREDx()
3346 const TexInstruction
*insn
= this->insn
->asTex();
3347 uint8_t type
= 0, subOp
;
3349 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
)
3350 emitInsn(0xeac00000);
3352 emitInsn(0xea600000);
3354 if (insn
->op
== OP_SUREDB
)
3355 emitField(0x34, 1, 1);
3359 switch (insn
->dType
) {
3360 case TYPE_S32
: type
= 1; break;
3361 case TYPE_U64
: type
= 2; break;
3362 case TYPE_F32
: type
= 3; break;
3363 case TYPE_S64
: type
= 5; break;
3365 assert(insn
->dType
== TYPE_U32
);
3370 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_CAS
) {
3372 } else if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
) {
3375 subOp
= insn
->subOp
;
3378 emitField(0x24, 3, type
);
3379 emitField(0x1d, 4, subOp
);
3380 emitGPR (0x14, insn
->src(1));
3381 emitGPR (0x08, insn
->src(0));
3382 emitGPR (0x00, insn
->def(0));
3387 /*******************************************************************************
3388 * assembler front-end
3389 ******************************************************************************/
3392 CodeEmitterGM107::emitInstruction(Instruction
*i
)
3394 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
3399 if (insn
->encSize
!= 8) {
3400 ERROR("skipping undecodable instruction: "); insn
->print();
3403 if (codeSize
+ size
> codeSizeLimit
) {
3404 ERROR("code emitter output buffer too small\n");
3408 if (writeIssueDelays
) {
3409 int n
= ((codeSize
& 0x1f) / 8) - 1;
3412 data
[0] = 0x00000000;
3413 data
[1] = 0x00000000;
3419 emitField(data
, n
* 21, 21, insn
->sched
);
3466 if (targGM107
->isCS2RSV(insn
->getSrc(0)->reg
.data
.sv
.sv
))
3478 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
3479 insn
->src(0).getFile() == FILE_PREDICATE
)) {
3481 } else if (isFloatType(insn
->dType
)) {
3482 if (isFloatType(insn
->sType
))
3487 if (isFloatType(insn
->sType
))
3498 if (isFloatType(insn
->dType
)) {
3499 if (insn
->dType
== TYPE_F64
)
3508 if (isFloatType(insn
->dType
)) {
3509 if (insn
->dType
== TYPE_F64
)
3519 if (isFloatType(insn
->dType
)) {
3520 if (insn
->dType
== TYPE_F64
)
3536 if (isFloatType(insn
->dType
)) {
3537 if (insn
->dType
== TYPE_F64
)
3546 if (typeSizeof(insn
->sType
) == 8)
3552 if (typeSizeof(insn
->sType
) == 8)
3573 if (isFloatType(insn
->dType
))
3582 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
3583 if (isFloatType(insn
->sType
))
3584 if (insn
->sType
== TYPE_F64
)
3591 if (isFloatType(insn
->sType
))
3592 if (insn
->sType
== TYPE_F64
)
3619 switch (insn
->def(0).getFile()) {
3620 case FILE_GPR
: emitLOP(); break;
3621 case FILE_PREDICATE
: emitPSETP(); break;
3623 assert(!"invalid bool op");
3630 switch (insn
->src(0).getFile()) {
3631 case FILE_MEMORY_CONST
: emitLDC(); break;
3632 case FILE_MEMORY_LOCAL
: emitLDL(); break;
3633 case FILE_MEMORY_SHARED
: emitLDS(); break;
3634 case FILE_MEMORY_GLOBAL
: emitLD(); break;
3636 assert(!"invalid load");
3642 switch (insn
->src(0).getFile()) {
3643 case FILE_MEMORY_LOCAL
: emitSTL(); break;
3644 case FILE_MEMORY_SHARED
: emitSTS(); break;
3645 case FILE_MEMORY_GLOBAL
: emitST(); break;
3647 assert(!"invalid store");
3653 if (insn
->src(0).getFile() == FILE_MEMORY_SHARED
)
3656 if (!insn
->defExists(0) && insn
->subOp
< NV50_IR_SUBOP_ATOM_CAS
)
3685 if (insn
->asTex()->tex
.scalar
)
3694 if (insn
->asTex()->tex
.scalar
)
3700 if (insn
->asTex()->tex
.scalar
)
3752 assert(!"invalid opcode");
3768 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
3773 /*******************************************************************************
3774 * sched data calculator
3775 ******************************************************************************/
3778 SchedDataCalculatorGM107::emitStall(Instruction
*insn
, uint8_t cnt
)
3785 SchedDataCalculatorGM107::emitYield(Instruction
*insn
)
3787 insn
->sched
|= 1 << 4;
3791 SchedDataCalculatorGM107::emitWrDepBar(Instruction
*insn
, uint8_t id
)
3794 if ((insn
->sched
& 0xe0) == 0xe0)
3795 insn
->sched
^= 0xe0;
3796 insn
->sched
|= id
<< 5;
3800 SchedDataCalculatorGM107::emitRdDepBar(Instruction
*insn
, uint8_t id
)
3803 if ((insn
->sched
& 0x700) == 0x700)
3804 insn
->sched
^= 0x700;
3805 insn
->sched
|= id
<< 8;
3809 SchedDataCalculatorGM107::emitWtDepBar(Instruction
*insn
, uint8_t id
)
3812 insn
->sched
|= 1 << (11 + id
);
3816 SchedDataCalculatorGM107::emitReuse(Instruction
*insn
, uint8_t id
)
3819 insn
->sched
|= 1 << (17 + id
);
3823 SchedDataCalculatorGM107::printSchedInfo(int cycle
,
3824 const Instruction
*insn
) const
3826 uint8_t st
, yl
, wr
, rd
, wt
, ru
;
3828 st
= (insn
->sched
& 0x00000f) >> 0;
3829 yl
= (insn
->sched
& 0x000010) >> 4;
3830 wr
= (insn
->sched
& 0x0000e0) >> 5;
3831 rd
= (insn
->sched
& 0x000700) >> 8;
3832 wt
= (insn
->sched
& 0x01f800) >> 11;
3833 ru
= (insn
->sched
& 0x1e0000) >> 17;
3835 INFO("cycle %i, (st 0x%x, yl 0x%x, wr 0x%x, rd 0x%x, wt 0x%x, ru 0x%x)\n",
3836 cycle
, st
, yl
, wr
, rd
, wt
, ru
);
3840 SchedDataCalculatorGM107::getStall(const Instruction
*insn
) const
3842 return insn
->sched
& 0xf;
3846 SchedDataCalculatorGM107::getWrDepBar(const Instruction
*insn
) const
3848 return (insn
->sched
& 0x0000e0) >> 5;
3852 SchedDataCalculatorGM107::getRdDepBar(const Instruction
*insn
) const
3854 return (insn
->sched
& 0x000700) >> 8;
3858 SchedDataCalculatorGM107::getWtDepBar(const Instruction
*insn
) const
3860 return (insn
->sched
& 0x01f800) >> 11;
3863 // Emit the reuse flag which allows to make use of the new memory hierarchy
3864 // introduced since Maxwell, the operand reuse cache.
3866 // It allows to reduce bank conflicts by caching operands. Each time you issue
3867 // an instruction, that flag can tell the hw which operands are going to be
3868 // re-used by the next instruction. Note that the next instruction has to use
3869 // the same GPR id in the same operand slot.
3871 SchedDataCalculatorGM107::setReuseFlag(Instruction
*insn
)
3873 Instruction
*next
= insn
->next
;
3874 BitSet
defs(255, 1);
3876 if (!targ
->isReuseSupported(insn
))
3879 for (int d
= 0; insn
->defExists(d
); ++d
) {
3880 const Value
*def
= insn
->def(d
).rep();
3881 if (insn
->def(d
).getFile() != FILE_GPR
)
3883 if (typeSizeof(insn
->dType
) != 4 || def
->reg
.data
.id
== 255)
3885 defs
.set(def
->reg
.data
.id
);
3888 for (int s
= 0; insn
->srcExists(s
); s
++) {
3889 const Value
*src
= insn
->src(s
).rep();
3890 if (insn
->src(s
).getFile() != FILE_GPR
)
3892 if (typeSizeof(insn
->sType
) != 4 || src
->reg
.data
.id
== 255)
3894 if (defs
.test(src
->reg
.data
.id
))
3896 if (!next
->srcExists(s
) || next
->src(s
).getFile() != FILE_GPR
)
3898 if (src
->reg
.data
.id
!= next
->getSrc(s
)->reg
.data
.id
)
3906 SchedDataCalculatorGM107::recordWr(const Value
*v
, int cycle
, int ready
)
3908 int a
= v
->reg
.data
.id
, b
;
3910 switch (v
->reg
.file
) {
3912 b
= a
+ v
->reg
.size
/ 4;
3913 for (int r
= a
; r
< b
; ++r
)
3914 score
->rd
.r
[r
] = ready
;
3916 case FILE_PREDICATE
:
3917 // To immediately use a predicate set by any instructions, the minimum
3918 // number of stall counts is 13.
3919 score
->rd
.p
[a
] = cycle
+ 13;
3922 score
->rd
.c
= ready
;
3930 SchedDataCalculatorGM107::checkRd(const Value
*v
, int cycle
, int &delay
) const
3932 int a
= v
->reg
.data
.id
, b
;
3935 switch (v
->reg
.file
) {
3937 b
= a
+ v
->reg
.size
/ 4;
3938 for (int r
= a
; r
< b
; ++r
)
3939 ready
= MAX2(ready
, score
->rd
.r
[r
]);
3941 case FILE_PREDICATE
:
3942 ready
= MAX2(ready
, score
->rd
.p
[a
]);
3945 ready
= MAX2(ready
, score
->rd
.c
);
3951 delay
= MAX2(delay
, ready
- cycle
);
3955 SchedDataCalculatorGM107::commitInsn(const Instruction
*insn
, int cycle
)
3957 const int ready
= cycle
+ targ
->getLatency(insn
);
3959 for (int d
= 0; insn
->defExists(d
); ++d
)
3960 recordWr(insn
->getDef(d
), cycle
, ready
);
3962 #ifdef GM107_DEBUG_SCHED_DATA
3963 score
->print(cycle
);
3967 #define GM107_MIN_ISSUE_DELAY 0x1
3968 #define GM107_MAX_ISSUE_DELAY 0xf
3971 SchedDataCalculatorGM107::calcDelay(const Instruction
*insn
, int cycle
) const
3973 int delay
= 0, ready
= cycle
;
3975 for (int s
= 0; insn
->srcExists(s
); ++s
)
3976 checkRd(insn
->getSrc(s
), cycle
, delay
);
3978 // TODO: make use of getReadLatency()!
3980 return MAX2(delay
, ready
- cycle
);
3984 SchedDataCalculatorGM107::setDelay(Instruction
*insn
, int delay
,
3985 const Instruction
*next
)
3987 const OpClass cl
= targ
->getOpClass(insn
->op
);
3990 if (insn
->op
== OP_EXIT
||
3991 insn
->op
== OP_BAR
||
3992 insn
->op
== OP_MEMBAR
) {
3993 delay
= GM107_MAX_ISSUE_DELAY
;
3995 if (insn
->op
== OP_QUADON
||
3996 insn
->op
== OP_QUADPOP
) {
3999 if (cl
== OPCLASS_FLOW
|| insn
->join
) {
4003 if (!next
|| !targ
->canDualIssue(insn
, next
)) {
4004 delay
= CLAMP(delay
, GM107_MIN_ISSUE_DELAY
, GM107_MAX_ISSUE_DELAY
);
4006 delay
= 0x0; // dual-issue
4009 wr
= getWrDepBar(insn
);
4010 rd
= getRdDepBar(insn
);
4012 if (delay
== GM107_MIN_ISSUE_DELAY
&& (wr
& rd
) != 7) {
4013 // Barriers take one additional clock cycle to become active on top of
4014 // the clock consumed by the instruction producing it.
4015 if (!next
|| insn
->bb
!= next
->bb
) {
4018 int wt
= getWtDepBar(next
);
4019 if ((wt
& (1 << wr
)) | (wt
& (1 << rd
)))
4024 emitStall(insn
, delay
);
4028 // Return true when the given instruction needs to emit a read dependency
4029 // barrier (for WaR hazards) because it doesn't operate at a fixed latency, and
4030 // setting the maximum number of stall counts is not enough.
4032 SchedDataCalculatorGM107::needRdDepBar(const Instruction
*insn
) const
4034 BitSet
srcs(255, 1), defs(255, 1);
4037 if (!targ
->isBarrierRequired(insn
))
4040 // Do not emit a read dependency barrier when the instruction doesn't use
4041 // any GPR (like st s[0x4] 0x0) as input because it's unnecessary.
4042 for (int s
= 0; insn
->srcExists(s
); ++s
) {
4043 const Value
*src
= insn
->src(s
).rep();
4044 if (insn
->src(s
).getFile() != FILE_GPR
)
4046 if (src
->reg
.data
.id
== 255)
4049 a
= src
->reg
.data
.id
;
4050 b
= a
+ src
->reg
.size
/ 4;
4051 for (int r
= a
; r
< b
; ++r
)
4055 if (!srcs
.popCount())
4058 // Do not emit a read dependency barrier when the output GPRs are equal to
4059 // the input GPRs (like rcp $r0 $r0) because a write dependency barrier will
4060 // be produced and WaR hazards are prevented.
4061 for (int d
= 0; insn
->defExists(d
); ++d
) {
4062 const Value
*def
= insn
->def(d
).rep();
4063 if (insn
->def(d
).getFile() != FILE_GPR
)
4065 if (def
->reg
.data
.id
== 255)
4068 a
= def
->reg
.data
.id
;
4069 b
= a
+ def
->reg
.size
/ 4;
4070 for (int r
= a
; r
< b
; ++r
)
4075 if (!srcs
.popCount())
4081 // Return true when the given instruction needs to emit a write dependency
4082 // barrier (for RaW hazards) because it doesn't operate at a fixed latency, and
4083 // setting the maximum number of stall counts is not enough. This is only legal
4084 // if the instruction output something.
4086 SchedDataCalculatorGM107::needWrDepBar(const Instruction
*insn
) const
4088 if (!targ
->isBarrierRequired(insn
))
4091 for (int d
= 0; insn
->defExists(d
); ++d
) {
4092 if (insn
->def(d
).getFile() == FILE_GPR
||
4093 insn
->def(d
).getFile() == FILE_FLAGS
||
4094 insn
->def(d
).getFile() == FILE_PREDICATE
)
4100 // Helper function for findFirstUse() and findFirstDef()
4102 SchedDataCalculatorGM107::doesInsnWriteTo(const Instruction
*insn
,
4103 const Value
*val
) const
4105 if (val
->reg
.file
!= FILE_GPR
&&
4106 val
->reg
.file
!= FILE_PREDICATE
&&
4107 val
->reg
.file
!= FILE_FLAGS
)
4110 for (int d
= 0; insn
->defExists(d
); ++d
) {
4111 const Value
* def
= insn
->getDef(d
);
4112 int minGPR
= def
->reg
.data
.id
;
4113 int maxGPR
= minGPR
+ def
->reg
.size
/ 4 - 1;
4115 if (def
->reg
.file
!= val
->reg
.file
)
4118 if (def
->reg
.file
== FILE_GPR
) {
4119 if (val
->reg
.data
.id
+ val
->reg
.size
/ 4 - 1 < minGPR
||
4120 val
->reg
.data
.id
> maxGPR
)
4124 if (def
->reg
.file
== FILE_PREDICATE
) {
4125 if (val
->reg
.data
.id
!= minGPR
)
4129 if (def
->reg
.file
== FILE_FLAGS
) {
4130 if (val
->reg
.data
.id
!= minGPR
)
4139 // Find the next instruction inside the same basic block which uses (reads or
4140 // writes from) the output of the given instruction in order to avoid RaW and
4143 SchedDataCalculatorGM107::findFirstUse(const Instruction
*bari
) const
4145 Instruction
*insn
, *next
;
4147 if (!bari
->defExists(0))
4150 for (insn
= bari
->next
; insn
!= NULL
; insn
= next
) {
4153 for (int s
= 0; insn
->srcExists(s
); ++s
)
4154 if (doesInsnWriteTo(bari
, insn
->getSrc(s
)))
4157 for (int d
= 0; insn
->defExists(d
); ++d
)
4158 if (doesInsnWriteTo(bari
, insn
->getDef(d
)))
4164 // Find the next instruction inside the same basic block which overwrites, at
4165 // least, one source of the given instruction in order to avoid WaR hazards.
4167 SchedDataCalculatorGM107::findFirstDef(const Instruction
*bari
) const
4169 Instruction
*insn
, *next
;
4171 if (!bari
->srcExists(0))
4174 for (insn
= bari
->next
; insn
!= NULL
; insn
= next
) {
4177 for (int s
= 0; bari
->srcExists(s
); ++s
)
4178 if (doesInsnWriteTo(insn
, bari
->getSrc(s
)))
4184 // Dependency barriers:
4185 // This pass is a bit ugly and could probably be improved by performing a
4186 // better allocation.
4188 // The main idea is to avoid WaR and RaW hazards by emitting read/write
4189 // dependency barriers using the control codes.
4191 SchedDataCalculatorGM107::insertBarriers(BasicBlock
*bb
)
4193 std::list
<LiveBarUse
> live_uses
;
4194 std::list
<LiveBarDef
> live_defs
;
4195 Instruction
*insn
, *next
;
4199 for (insn
= bb
->getEntry(); insn
!= NULL
; insn
= next
) {
4200 Instruction
*usei
= NULL
, *defi
= NULL
;
4201 bool need_wr_bar
, need_rd_bar
;
4205 // Expire old barrier uses.
4206 for (std::list
<LiveBarUse
>::iterator it
= live_uses
.begin();
4207 it
!= live_uses
.end();) {
4208 if (insn
->serial
>= it
->usei
->serial
) {
4209 int wr
= getWrDepBar(it
->insn
);
4210 emitWtDepBar(insn
, wr
);
4211 bars
.clr(wr
); // free barrier
4212 it
= live_uses
.erase(it
);
4218 // Expire old barrier defs.
4219 for (std::list
<LiveBarDef
>::iterator it
= live_defs
.begin();
4220 it
!= live_defs
.end();) {
4221 if (insn
->serial
>= it
->defi
->serial
) {
4222 int rd
= getRdDepBar(it
->insn
);
4223 emitWtDepBar(insn
, rd
);
4224 bars
.clr(rd
); // free barrier
4225 it
= live_defs
.erase(it
);
4231 need_wr_bar
= needWrDepBar(insn
);
4232 need_rd_bar
= needRdDepBar(insn
);
4235 // When the instruction requires to emit a write dependency barrier
4236 // (all which write something at a variable latency), find the next
4237 // instruction which reads the outputs (or writes to them, potentially
4238 // completing before this insn.
4239 usei
= findFirstUse(insn
);
4241 // Allocate and emit a new barrier.
4242 bar_id
= bars
.findFreeRange(1);
4246 emitWrDepBar(insn
, bar_id
);
4248 live_uses
.push_back(LiveBarUse(insn
, usei
));
4252 // When the instruction requires to emit a read dependency barrier
4253 // (all which read something at a variable latency), find the next
4254 // instruction which will write the inputs.
4255 defi
= findFirstDef(insn
);
4257 if (usei
&& defi
&& usei
->serial
<= defi
->serial
)
4260 // Allocate and emit a new barrier.
4261 bar_id
= bars
.findFreeRange(1);
4265 emitRdDepBar(insn
, bar_id
);
4267 live_defs
.push_back(LiveBarDef(insn
, defi
));
4271 // Remove unnecessary barrier waits.
4272 BitSet
alive_bars(6, 1);
4273 for (insn
= bb
->getEntry(); insn
!= NULL
; insn
= next
) {
4278 wr
= getWrDepBar(insn
);
4279 rd
= getRdDepBar(insn
);
4280 wt
= getWtDepBar(insn
);
4282 for (int idx
= 0; idx
< 6; ++idx
) {
4283 if (!(wt
& (1 << idx
)))
4285 if (!alive_bars
.test(idx
)) {
4286 insn
->sched
&= ~(1 << (11 + idx
));
4288 alive_bars
.clr(idx
);
4302 SchedDataCalculatorGM107::visit(Function
*func
)
4306 func
->orderInstructions(insns
);
4308 scoreBoards
.resize(func
->cfg
.getSize());
4309 for (size_t i
= 0; i
< scoreBoards
.size(); ++i
)
4310 scoreBoards
[i
].wipe();
4315 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
4317 Instruction
*insn
, *next
= NULL
;
4320 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
4322 insn
->sched
= 0x7e0;
4325 if (!debug_get_bool_option("NV50_PROG_SCHED", true))
4328 // Insert read/write dependency barriers for instructions which don't
4329 // operate at a fixed latency.
4332 score
= &scoreBoards
.at(bb
->getId());
4334 for (Graph::EdgeIterator ei
= bb
->cfg
.incident(); !ei
.end(); ei
.next()) {
4335 // back branches will wait until all target dependencies are satisfied
4336 if (ei
.getType() == Graph::Edge::BACK
) // sched would be uninitialized
4338 BasicBlock
*in
= BasicBlock::get(ei
.getNode());
4339 score
->setMax(&scoreBoards
.at(in
->getId()));
4342 #ifdef GM107_DEBUG_SCHED_DATA
4343 INFO("=== BB:%i initial scores\n", bb
->getId());
4344 score
->print(cycle
);
4347 // Because barriers are allocated locally (intra-BB), we have to make sure
4348 // that all produced barriers have been consumed before entering inside a
4349 // new basic block. The best way is to do a global allocation pre RA but
4350 // it's really more difficult, especially because of the phi nodes. Anyways,
4351 // it seems like that waiting on a barrier which has already been consumed
4352 // doesn't add any additional cost, it's just not elegant!
4353 Instruction
*start
= bb
->getEntry();
4354 if (start
&& bb
->cfg
.incidentCount() > 0) {
4355 for (int b
= 0; b
< 6; b
++)
4356 emitWtDepBar(start
, b
);
4359 for (insn
= bb
->getEntry(); insn
&& insn
->next
; insn
= insn
->next
) {
4362 commitInsn(insn
, cycle
);
4363 int delay
= calcDelay(next
, cycle
);
4364 setDelay(insn
, delay
, next
);
4365 cycle
+= getStall(insn
);
4369 // XXX: The yield flag seems to destroy a bunch of things when it is
4370 // set on every instruction, need investigation.
4373 #ifdef GM107_DEBUG_SCHED_DATA
4374 printSchedInfo(cycle
, insn
);
4382 commitInsn(insn
, cycle
);
4386 #ifdef GM107_DEBUG_SCHED_DATA
4387 fprintf(stderr
, "last instruction is : ");
4389 fprintf(stderr
, "cycle=%d\n", cycle
);
4392 for (Graph::EdgeIterator ei
= bb
->cfg
.outgoing(); !ei
.end(); ei
.next()) {
4393 BasicBlock
*out
= BasicBlock::get(ei
.getNode());
4395 if (ei
.getType() != Graph::Edge::BACK
) {
4396 // Only test the first instruction of the outgoing block.
4397 next
= out
->getEntry();
4399 bbDelay
= MAX2(bbDelay
, calcDelay(next
, cycle
));
4401 // When the outgoing BB is empty, make sure to set the number of
4402 // stall counts needed by the instruction because we don't know the
4403 // next instruction.
4404 bbDelay
= MAX2(bbDelay
, targ
->getLatency(insn
));
4407 // Wait until all dependencies are satisfied.
4408 const int regsFree
= score
->getLatest();
4409 next
= out
->getFirst();
4410 for (int c
= cycle
; next
&& c
< regsFree
; next
= next
->next
) {
4411 bbDelay
= MAX2(bbDelay
, calcDelay(next
, c
));
4412 c
+= getStall(next
);
4417 if (bb
->cfg
.outgoingCount() != 1)
4419 setDelay(insn
, bbDelay
, next
);
4420 cycle
+= getStall(insn
);
4422 score
->rebase(cycle
); // common base for initializing out blocks' scores
4426 /*******************************************************************************
4428 ******************************************************************************/
4431 CodeEmitterGM107::prepareEmission(Function
*func
)
4433 SchedDataCalculatorGM107
sched(targGM107
);
4434 CodeEmitter::prepareEmission(func
);
4435 sched
.run(func
, true, true);
4438 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
4440 return (size
+ 23) / 24;
4444 CodeEmitterGM107::prepareEmission(Program
*prog
)
4446 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
4447 !fi
.end(); fi
.next()) {
4448 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
4449 func
->binPos
= prog
->binSize
;
4450 prepareEmission(func
);
4452 // adjust sizes & positions for schedulding info:
4453 if (prog
->getTarget()->hasSWSched
) {
4454 uint32_t adjPos
= func
->binPos
;
4455 BasicBlock
*bb
= NULL
;
4456 for (int i
= 0; i
< func
->bbCount
; ++i
) {
4457 bb
= func
->bbArray
[i
];
4458 int32_t adjSize
= bb
->binSize
;
4460 adjSize
-= 32 - adjPos
% 32;
4464 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
4465 bb
->binPos
= adjPos
;
4466 bb
->binSize
= adjSize
;
4470 func
->binSize
= adjPos
- func
->binPos
;
4473 prog
->binSize
+= func
->binSize
;
4477 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
4478 : CodeEmitter(target
),
4480 writeIssueDelays(target
->hasSWSched
)
4483 codeSize
= codeSizeLimit
= 0;
4488 TargetGM107::createCodeEmitterGM107(Program::Type type
)
4490 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
4491 emit
->setProgramType(type
);
4495 } // namespace nv50_ir