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
);
195 /*******************************************************************************
196 * general instruction layout/fields
197 ******************************************************************************/
200 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
203 uint32_t m
= ((1ULL << s
) - 1);
204 uint64_t d
= (uint64_t)(v
& m
) << b
;
205 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
212 CodeEmitterGM107::emitPred()
214 if (insn
->predSrc
>= 0) {
215 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
216 emitField(19, 1, insn
->cc
== CC_NOT_P
);
223 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
225 code
[0] = 0x00000000;
232 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
234 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
238 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
240 int id
= val
? val
->reg
.data
.id
: -1;
243 case SV_INVOCATION_ID
: id
= 0x11; break;
244 case SV_INVOCATION_INFO
: id
= 0x1d; break;
246 assert(!"invalid system value");
251 emitField(pos
, 8, id
);
255 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
257 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
261 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
264 const Value
*v
= ref
.get();
265 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
267 emitGPR(gpr
, ref
.getIndirect(0));
268 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
272 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
275 const Value
*v
= ref
.get();
276 const Symbol
*s
= v
->asSym();
278 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
280 emitField(buf
, 5, v
->reg
.fileIndex
);
282 emitGPR(gpr
, ref
.getIndirect(0));
283 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
287 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
289 if (ref
.getFile() == FILE_IMMEDIATE
) {
290 const ImmediateValue
*imm
= ref
.get()->asImm();
291 if (isFloatType(insn
->sType
)) {
292 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
295 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
296 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
304 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
306 const ImmediateValue
*imm
= ref
.get()->asImm();
307 uint32_t val
= imm
->reg
.data
.u32
;
310 if (isFloatType(insn
->sType
)) {
311 assert(!(val
& 0x00000fff));
314 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
315 emitField( 56, 1, (val
& 0x80000) >> 19);
316 emitField(pos
, len
, (val
& 0x7ffff));
318 emitField(pos
, len
, val
);
322 /*******************************************************************************
324 ******************************************************************************/
327 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
332 case CC_FL
: data
= 0x00; break;
334 case CC_LT
: data
= 0x01; break;
336 case CC_EQ
: data
= 0x02; break;
338 case CC_LE
: data
= 0x03; break;
340 case CC_GT
: data
= 0x04; break;
342 case CC_NE
: data
= 0x05; break;
344 case CC_GE
: data
= 0x06; break;
345 case CC_TR
: data
= 0x07; break;
347 assert(!"invalid cond3");
351 emitField(pos
, 3, data
);
355 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
360 case CC_FL
: data
= 0x00; break;
361 case CC_LT
: data
= 0x01; break;
362 case CC_EQ
: data
= 0x02; break;
363 case CC_LE
: data
= 0x03; break;
364 case CC_GT
: data
= 0x04; break;
365 case CC_NE
: data
= 0x05; break;
366 case CC_GE
: data
= 0x06; break;
367 // case CC_NUM: data = 0x07; break;
368 // case CC_NAN: data = 0x08; break;
369 case CC_LTU
: data
= 0x09; break;
370 case CC_EQU
: data
= 0x0a; break;
371 case CC_LEU
: data
= 0x0b; break;
372 case CC_GTU
: data
= 0x0c; break;
373 case CC_NEU
: data
= 0x0d; break;
374 case CC_GEU
: data
= 0x0e; break;
375 case CC_TR
: data
= 0x0f; break;
377 assert(!"invalid cond4");
381 emitField(pos
, 4, data
);
385 CodeEmitterGM107::emitO(int pos
)
387 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
391 CodeEmitterGM107::emitP(int pos
)
393 emitField(pos
, 1, insn
->perPatch
);
397 CodeEmitterGM107::emitSAT(int pos
)
399 emitField(pos
, 1, insn
->saturate
);
403 CodeEmitterGM107::emitCC(int pos
)
405 emitField(pos
, 1, insn
->defExists(1));
409 CodeEmitterGM107::emitX(int pos
)
411 emitField(pos
, 1, insn
->flagsSrc
>= 0);
415 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
417 emitField(pos
, 1, ref
.mod
.abs());
421 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
423 emitField(pos
, 1, ref
.mod
.neg());
427 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
429 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
433 CodeEmitterGM107::emitFMZ(int pos
, int len
)
435 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
439 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
443 case ROUND_NI
: ri
= 1;
444 case ROUND_N
: rm
= 0; break;
445 case ROUND_MI
: ri
= 1;
446 case ROUND_M
: rm
= 1; break;
447 case ROUND_PI
: ri
= 1;
448 case ROUND_P
: rm
= 2; break;
449 case ROUND_ZI
: ri
= 1;
450 case ROUND_Z
: rm
= 3; break;
452 assert(!"invalid round mode");
455 emitField(rip
, 1, ri
);
456 emitField(rmp
, 2, rm
);
460 CodeEmitterGM107::emitPDIV(int pos
)
462 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
463 if (insn
->postFactor
> 0)
464 emitField(pos
, 3, 7 - insn
->postFactor
);
466 emitField(pos
, 3, 0 - insn
->postFactor
);
470 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
472 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
475 /*******************************************************************************
477 ******************************************************************************/
480 CodeEmitterGM107::emitEXIT()
482 emitInsn (0xe3000000);
483 emitCond5(0x00, CC_TR
);
487 CodeEmitterGM107::emitBRA()
489 const FlowInstruction
*insn
= this->insn
->asFlow();
492 if (insn
->indirect
) {
494 emitInsn(0xe2000000); // JMX
496 emitInsn(0xe2500000); // BRX
500 emitInsn(0xe2100000); // JMP
502 emitInsn(0xe2400000); // BRA
503 emitField(0x07, 1, insn
->allWarp
);
506 emitField(0x06, 1, insn
->limit
);
507 emitCond5(0x00, CC_TR
);
509 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
511 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
513 emitField(0x14, 32, insn
->target
.bb
->binPos
);
515 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
516 emitField(0x05, 1, 1);
521 CodeEmitterGM107::emitCAL()
523 const FlowInstruction
*insn
= this->insn
->asFlow();
525 if (insn
->absolute
) {
526 emitInsn(0xe2200000, 0); // JCAL
528 emitInsn(0xe2600000, 0); // CAL
531 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
533 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
536 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
537 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
538 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
540 emitField(0x14, 32, insn
->target
.bb
->binPos
);
544 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
545 emitField(0x05, 1, 1);
550 CodeEmitterGM107::emitPCNT()
552 const FlowInstruction
*insn
= this->insn
->asFlow();
554 emitInsn(0xe2b00000, 0);
556 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
557 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
559 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
560 emitField(0x05, 1, 1);
565 CodeEmitterGM107::emitCONT()
567 emitInsn (0xe3500000);
568 emitCond5(0x00, CC_TR
);
572 CodeEmitterGM107::emitPBK()
574 const FlowInstruction
*insn
= this->insn
->asFlow();
576 emitInsn(0xe2a00000, 0);
578 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
579 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
581 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
582 emitField(0x05, 1, 1);
587 CodeEmitterGM107::emitBRK()
589 emitInsn (0xe3400000);
590 emitCond5(0x00, CC_TR
);
594 CodeEmitterGM107::emitPRET()
596 const FlowInstruction
*insn
= this->insn
->asFlow();
598 emitInsn(0xe2700000, 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::emitRET()
611 emitInsn (0xe3200000);
612 emitCond5(0x00, CC_TR
);
616 CodeEmitterGM107::emitSSY()
618 const FlowInstruction
*insn
= this->insn
->asFlow();
620 emitInsn(0xe2900000, 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::emitSYNC()
633 emitInsn (0xf0f80000);
634 emitCond5(0x00, CC_TR
);
638 CodeEmitterGM107::emitSAM()
640 emitInsn(0xe3700000, 0);
644 CodeEmitterGM107::emitRAM()
646 emitInsn(0xe3800000, 0);
649 /*******************************************************************************
651 ******************************************************************************/
653 /*******************************************************************************
654 * movement / conversion
655 ******************************************************************************/
658 CodeEmitterGM107::emitMOV()
660 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
661 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
662 switch (insn
->src(0).getFile()) {
664 emitInsn(0x5c980000);
665 emitGPR (0x14, insn
->src(0));
667 case FILE_MEMORY_CONST
:
668 emitInsn(0x4c980000);
669 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
672 emitInsn(0x38980000);
673 emitIMMD(0x14, 19, insn
->src(0));
676 assert(!"bad src file");
679 emitField(0x27, 4, insn
->lanes
);
681 emitInsn (0x01000000);
682 emitIMMD (0x14, 32, insn
->src(0));
683 emitField(0x0c, 4, insn
->lanes
);
686 emitGPR(0x00, insn
->def(0));
690 CodeEmitterGM107::emitS2R()
692 emitInsn(0xf0c80000);
693 emitSYS (0x14, insn
->src(0));
694 emitGPR (0x00, insn
->def(0));
698 CodeEmitterGM107::emitF2F()
700 RoundMode rnd
= insn
->rnd
;
703 case OP_FLOOR
: rnd
= ROUND_MI
; break;
704 case OP_CEIL
: rnd
= ROUND_PI
; break;
705 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
710 switch (insn
->src(0).getFile()) {
712 emitInsn(0x5ca80000);
713 emitGPR (0x14, insn
->src(0));
715 case FILE_MEMORY_CONST
:
716 emitInsn(0x4ca80000);
717 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
720 emitInsn(0x38a80000);
721 emitIMMD(0x14, 19, insn
->src(0));
724 assert(!"bad src0 file");
728 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
729 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
731 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
733 emitRND (0x27, rnd
, 0x2a);
734 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->dType
)));
735 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->sType
)));
736 emitGPR (0x00, insn
->def(0));
740 CodeEmitterGM107::emitF2I()
742 RoundMode rnd
= insn
->rnd
;
745 case OP_FLOOR
: rnd
= ROUND_M
; break;
746 case OP_CEIL
: rnd
= ROUND_P
; break;
747 case OP_TRUNC
: rnd
= ROUND_Z
; break;
752 switch (insn
->src(0).getFile()) {
754 emitInsn(0x5cb00000);
755 emitGPR (0x14, insn
->src(0));
757 case FILE_MEMORY_CONST
:
758 emitInsn(0x4cb00000);
759 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
762 emitInsn(0x38b00000);
763 emitIMMD(0x14, 19, insn
->src(0));
766 assert(!"bad src0 file");
770 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
772 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
774 emitRND (0x27, rnd
, 0x2a);
775 emitField(0x0c, 1, isSignedType(insn
->dType
));
776 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
777 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
778 emitGPR (0x00, insn
->def(0));
782 CodeEmitterGM107::emitI2F()
784 RoundMode rnd
= insn
->rnd
;
787 case OP_FLOOR
: rnd
= ROUND_M
; break;
788 case OP_CEIL
: rnd
= ROUND_P
; break;
789 case OP_TRUNC
: rnd
= ROUND_Z
; break;
794 switch (insn
->src(0).getFile()) {
796 emitInsn(0x5cb80000);
797 emitGPR (0x14, insn
->src(0));
799 case FILE_MEMORY_CONST
:
800 emitInsn(0x4cb80000);
801 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
804 emitInsn(0x38b80000);
805 emitIMMD(0x14, 19, insn
->src(0));
808 assert(!"bad src0 file");
812 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
814 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
815 emitRND (0x27, rnd
, -1);
816 emitField(0x0d, 1, isSignedType(insn
->sType
));
817 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
818 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
819 emitGPR (0x00, insn
->def(0));
823 CodeEmitterGM107::emitI2I()
825 switch (insn
->src(0).getFile()) {
827 emitInsn(0x5ce00000);
828 emitGPR (0x14, insn
->src(0));
830 case FILE_MEMORY_CONST
:
831 emitInsn(0x4ce00000);
832 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
835 emitInsn(0x38e00000);
836 emitIMMD(0x14, 19, insn
->src(0));
839 assert(!"bad src0 file");
844 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
846 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
847 emitField(0x0d, 1, isSignedType(insn
->sType
));
848 emitField(0x0c, 1, isSignedType(insn
->dType
));
849 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
850 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
851 emitGPR (0x00, insn
->def(0));
855 CodeEmitterGM107::emitSHFL()
859 emitInsn (0xef100000);
861 switch (insn
->src(1).getFile()) {
863 emitGPR(0x14, insn
->src(1));
866 emitIMMD(0x14, 5, insn
->src(1));
870 assert(!"invalid src1 file");
874 /*XXX: what is this arg? hardcode immediate for now */
875 emitField(0x22, 13, 0x1c03);
879 emitField(0x1e, 2, insn
->subOp
);
880 emitField(0x1c, 2, type
);
881 emitGPR (0x08, insn
->src(0));
882 emitGPR (0x00, insn
->def(0));
885 /*******************************************************************************
887 ******************************************************************************/
890 CodeEmitterGM107::emitDADD()
892 switch (insn
->src(1).getFile()) {
894 emitInsn(0x5c700000);
895 emitGPR (0x14, insn
->src(1));
897 case FILE_MEMORY_CONST
:
898 emitInsn(0x4c700000);
899 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
902 emitInsn(0x38700000);
903 emitIMMD(0x14, 19, insn
->src(1));
906 assert(!"bad src1 file");
909 emitABS(0x31, insn
->src(1));
910 emitNEG(0x30, insn
->src(0));
912 emitABS(0x2e, insn
->src(0));
913 emitNEG(0x2d, insn
->src(1));
915 if (insn
->op
== OP_SUB
)
916 code
[1] ^= 0x00002000;
918 emitGPR(0x08, insn
->src(0));
919 emitGPR(0x00, insn
->def(0));
923 CodeEmitterGM107::emitDMUL()
925 switch (insn
->src(1).getFile()) {
927 emitInsn(0x5c680000);
928 emitGPR (0x14, insn
->src(1));
930 case FILE_MEMORY_CONST
:
931 emitInsn(0x4c680000);
932 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
935 emitInsn(0x38680000);
936 emitIMMD(0x14, 19, insn
->src(1));
939 assert(!"bad src1 file");
943 emitNEG2(0x30, insn
->src(0), insn
->src(1));
946 emitGPR (0x08, insn
->src(0));
947 emitGPR (0x00, insn
->def(0));
951 CodeEmitterGM107::emitDFMA()
953 switch(insn
->src(2).getFile()) {
955 switch (insn
->src(1).getFile()) {
957 emitInsn(0x5b700000);
958 emitGPR (0x14, insn
->src(1));
960 case FILE_MEMORY_CONST
:
961 emitInsn(0x4b700000);
962 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
965 emitInsn(0x36700000);
966 emitIMMD(0x14, 19, insn
->src(1));
969 assert(!"bad src1 file");
972 emitGPR (0x27, insn
->src(2));
974 case FILE_MEMORY_CONST
:
975 emitInsn(0x53700000);
976 emitGPR (0x27, insn
->src(1));
977 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
980 assert(!"bad src2 file");
985 emitNEG (0x31, insn
->src(2));
986 emitNEG2(0x30, insn
->src(0), insn
->src(1));
988 emitGPR (0x08, insn
->src(0));
989 emitGPR (0x00, insn
->def(0));
993 CodeEmitterGM107::emitDMNMX()
995 switch (insn
->src(1).getFile()) {
997 emitInsn(0x5c500000);
998 emitGPR (0x14, insn
->src(1));
1000 case FILE_MEMORY_CONST
:
1001 emitInsn(0x4c500000);
1002 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1004 case FILE_IMMEDIATE
:
1005 emitInsn(0x38500000);
1006 emitIMMD(0x14, 19, insn
->src(1));
1009 assert(!"bad src1 file");
1013 emitABS (0x31, insn
->src(1));
1014 emitNEG (0x30, insn
->src(0));
1016 emitABS (0x2e, insn
->src(0));
1017 emitNEG (0x2d, insn
->src(1));
1018 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1020 emitGPR (0x08, insn
->src(0));
1021 emitGPR (0x00, insn
->def(0));
1025 CodeEmitterGM107::emitDSET()
1027 const CmpInstruction
*insn
= this->insn
->asCmp();
1029 switch (insn
->src(1).getFile()) {
1031 emitInsn(0x59000000);
1032 emitGPR (0x14, insn
->src(1));
1034 case FILE_MEMORY_CONST
:
1035 emitInsn(0x49000000);
1036 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1038 case FILE_IMMEDIATE
:
1039 emitInsn(0x32000000);
1040 emitIMMD(0x14, 19, insn
->src(1));
1043 assert(!"bad src1 file");
1047 if (insn
->op
!= OP_SET
) {
1049 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1050 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1051 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1053 assert(!"invalid set op");
1056 emitPRED(0x27, insn
->src(2));
1061 emitABS (0x36, insn
->src(0));
1062 emitNEG (0x35, insn
->src(1));
1063 emitCond4(0x30, insn
->setCond
);
1065 emitABS (0x2c, insn
->src(1));
1066 emitNEG (0x2b, insn
->src(0));
1067 emitGPR (0x08, insn
->src(0));
1068 emitGPR (0x00, insn
->def(0));
1072 CodeEmitterGM107::emitDSETP()
1074 const CmpInstruction
*insn
= this->insn
->asCmp();
1076 switch (insn
->src(1).getFile()) {
1078 emitInsn(0x5b800000);
1079 emitGPR (0x14, insn
->src(1));
1081 case FILE_MEMORY_CONST
:
1082 emitInsn(0x4b800000);
1083 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1085 case FILE_IMMEDIATE
:
1086 emitInsn(0x36800000);
1087 emitIMMD(0x14, 19, insn
->src(1));
1090 assert(!"bad src1 file");
1094 if (insn
->op
!= OP_SET
) {
1096 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1097 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1098 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1100 assert(!"invalid set op");
1103 emitPRED(0x27, insn
->src(2));
1108 emitCond4(0x30, insn
->setCond
);
1109 emitABS (0x2c, insn
->src(1));
1110 emitNEG (0x2b, insn
->src(0));
1111 emitGPR (0x08, insn
->src(0));
1112 emitABS (0x07, insn
->src(0));
1113 emitNEG (0x06, insn
->src(1));
1114 emitPRED (0x03, insn
->def(0));
1115 if (insn
->defExists(1))
1116 emitPRED(0x00, insn
->def(1));
1121 /*******************************************************************************
1123 ******************************************************************************/
1126 CodeEmitterGM107::emitFADD()
1128 if (!longIMMD(insn
->src(1))) {
1129 switch (insn
->src(1).getFile()) {
1131 emitInsn(0x5c580000);
1132 emitGPR (0x14, insn
->src(1));
1134 case FILE_MEMORY_CONST
:
1135 emitInsn(0x4c580000);
1136 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1138 case FILE_IMMEDIATE
:
1139 emitInsn(0x38580000);
1140 emitIMMD(0x14, 19, insn
->src(1));
1143 assert(!"bad src1 file");
1147 emitABS(0x31, insn
->src(1));
1148 emitNEG(0x30, insn
->src(0));
1150 emitABS(0x2e, insn
->src(0));
1151 emitNEG(0x2d, insn
->src(1));
1154 emitInsn(0x08000000);
1155 emitABS(0x39, insn
->src(1));
1156 emitNEG(0x38, insn
->src(0));
1158 emitABS(0x36, insn
->src(0));
1159 emitNEG(0x35, insn
->src(1));
1161 emitIMMD(0x14, 32, insn
->src(1));
1164 if (insn
->op
== OP_SUB
)
1165 code
[1] ^= 0x00002000;
1167 emitGPR(0x08, insn
->src(0));
1168 emitGPR(0x00, insn
->def(0));
1172 CodeEmitterGM107::emitFMUL()
1174 if (!longIMMD(insn
->src(1))) {
1175 switch (insn
->src(1).getFile()) {
1177 emitInsn(0x5c680000);
1178 emitGPR (0x14, insn
->src(1));
1180 case FILE_MEMORY_CONST
:
1181 emitInsn(0x4c680000);
1182 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1184 case FILE_IMMEDIATE
:
1185 emitInsn(0x38680000);
1186 emitIMMD(0x14, 19, insn
->src(1));
1189 assert(!"bad src1 file");
1193 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1199 emitInsn(0x1e000000);
1203 emitIMMD(0x14, 32, insn
->src(1));
1204 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1205 code
[1] ^= 0x00080000; /* flip immd sign bit */
1208 emitGPR(0x08, insn
->src(0));
1209 emitGPR(0x00, insn
->def(0));
1213 CodeEmitterGM107::emitFFMA()
1215 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1216 switch(insn
->src(2).getFile()) {
1218 switch (insn
->src(1).getFile()) {
1220 emitInsn(0x59800000);
1221 emitGPR (0x14, insn
->src(1));
1223 case FILE_MEMORY_CONST
:
1224 emitInsn(0x49800000);
1225 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1227 case FILE_IMMEDIATE
:
1228 emitInsn(0x32800000);
1229 emitIMMD(0x14, 19, insn
->src(1));
1232 assert(!"bad src1 file");
1235 emitGPR (0x27, insn
->src(2));
1237 case FILE_MEMORY_CONST
:
1238 emitInsn(0x51800000);
1239 emitGPR (0x27, insn
->src(1));
1240 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1243 assert(!"bad src2 file");
1248 emitNEG (0x31, insn
->src(2));
1249 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1253 emitGPR(0x08, insn
->src(0));
1254 emitGPR(0x00, insn
->def(0));
1258 CodeEmitterGM107::emitMUFU()
1263 case OP_COS
: mufu
= 0; break;
1264 case OP_SIN
: mufu
= 1; break;
1265 case OP_EX2
: mufu
= 2; break;
1266 case OP_LG2
: mufu
= 3; break;
1267 case OP_RCP
: mufu
= 4; break;
1268 case OP_RSQ
: mufu
= 5; break;
1270 assert(!"invalid mufu");
1274 emitInsn (0x50800000);
1276 emitNEG (0x30, insn
->src(0));
1277 emitABS (0x2e, insn
->src(0));
1278 emitField(0x14, 3, mufu
);
1279 emitGPR (0x08, insn
->src(0));
1280 emitGPR (0x00, insn
->def(0));
1284 CodeEmitterGM107::emitFMNMX()
1286 switch (insn
->src(1).getFile()) {
1288 emitInsn(0x5c600000);
1289 emitGPR (0x14, insn
->src(1));
1291 case FILE_MEMORY_CONST
:
1292 emitInsn(0x4c600000);
1293 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1295 case FILE_IMMEDIATE
:
1296 emitInsn(0x38600000);
1297 emitIMMD(0x14, 19, insn
->src(1));
1300 assert(!"bad src1 file");
1304 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1307 emitABS(0x31, insn
->src(1));
1308 emitNEG(0x30, insn
->src(0));
1310 emitABS(0x2e, insn
->src(0));
1311 emitNEG(0x2d, insn
->src(1));
1313 emitGPR(0x08, insn
->src(0));
1314 emitGPR(0x00, insn
->def(0));
1318 CodeEmitterGM107::emitRRO()
1320 switch (insn
->src(0).getFile()) {
1322 emitInsn(0x5c900000);
1323 emitGPR (0x14, insn
->src(0));
1325 case FILE_MEMORY_CONST
:
1326 emitInsn(0x4c900000);
1327 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1329 case FILE_IMMEDIATE
:
1330 emitInsn(0x38900000);
1331 emitIMMD(0x14, 19, insn
->src(0));
1334 assert(!"bad src file");
1338 emitABS (0x31, insn
->src(0));
1339 emitNEG (0x2d, insn
->src(0));
1340 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1341 emitGPR (0x00, insn
->def(0));
1345 CodeEmitterGM107::emitFCMP()
1347 const CmpInstruction
*insn
= this->insn
->asCmp();
1348 CondCode cc
= insn
->setCond
;
1350 if (insn
->src(2).mod
.neg())
1351 cc
= reverseCondCode(cc
);
1353 switch(insn
->src(2).getFile()) {
1355 switch (insn
->src(1).getFile()) {
1357 emitInsn(0x5ba00000);
1358 emitGPR (0x14, insn
->src(1));
1360 case FILE_MEMORY_CONST
:
1361 emitInsn(0x4ba00000);
1362 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1364 case FILE_IMMEDIATE
:
1365 emitInsn(0x36a00000);
1366 emitIMMD(0x14, 19, insn
->src(1));
1369 assert(!"bad src1 file");
1372 emitGPR (0x27, insn
->src(2));
1374 case FILE_MEMORY_CONST
:
1375 emitInsn(0x53a00000);
1376 emitGPR (0x27, insn
->src(1));
1377 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1380 assert(!"bad src2 file");
1384 emitCond4(0x30, cc
);
1386 emitGPR (0x08, insn
->src(0));
1387 emitGPR (0x00, insn
->def(0));
1391 CodeEmitterGM107::emitFSET()
1393 const CmpInstruction
*insn
= this->insn
->asCmp();
1395 switch (insn
->src(1).getFile()) {
1397 emitInsn(0x58000000);
1398 emitGPR (0x14, insn
->src(1));
1400 case FILE_MEMORY_CONST
:
1401 emitInsn(0x48000000);
1402 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1404 case FILE_IMMEDIATE
:
1405 emitInsn(0x30000000);
1406 emitIMMD(0x14, 19, insn
->src(1));
1409 assert(!"bad src1 file");
1413 if (insn
->op
!= OP_SET
) {
1415 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1416 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1417 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1419 assert(!"invalid set op");
1422 emitPRED(0x27, insn
->src(2));
1428 emitABS (0x36, insn
->src(0));
1429 emitNEG (0x35, insn
->src(1));
1430 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1431 emitCond4(0x30, insn
->setCond
);
1433 emitABS (0x2c, insn
->src(1));
1434 emitNEG (0x2b, insn
->src(0));
1435 emitGPR (0x08, insn
->src(0));
1436 emitGPR (0x00, insn
->def(0));
1440 CodeEmitterGM107::emitFSETP()
1442 const CmpInstruction
*insn
= this->insn
->asCmp();
1444 switch (insn
->src(1).getFile()) {
1446 emitInsn(0x5bb00000);
1447 emitGPR (0x14, insn
->src(1));
1449 case FILE_MEMORY_CONST
:
1450 emitInsn(0x4bb00000);
1451 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1453 case FILE_IMMEDIATE
:
1454 emitInsn(0x36b00000);
1455 emitIMMD(0x14, 19, insn
->src(1));
1458 assert(!"bad src1 file");
1462 if (insn
->op
!= OP_SET
) {
1464 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1465 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1466 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1468 assert(!"invalid set op");
1471 emitPRED(0x27, insn
->src(2));
1476 emitCond4(0x30, insn
->setCond
);
1478 emitABS (0x2c, insn
->src(1));
1479 emitNEG (0x2b, insn
->src(0));
1480 emitGPR (0x08, insn
->src(0));
1481 emitABS (0x07, insn
->src(0));
1482 emitNEG (0x06, insn
->src(1));
1483 emitPRED (0x03, insn
->def(0));
1484 if (insn
->defExists(1))
1485 emitPRED(0x00, insn
->def(1));
1491 CodeEmitterGM107::emitFSWZADD()
1493 emitInsn (0x50f80000);
1497 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1498 emitField(0x1c, 8, insn
->subOp
);
1499 emitGPR (0x14, insn
->src(1));
1500 emitGPR (0x08, insn
->src(0));
1501 emitGPR (0x00, insn
->def(0));
1504 /*******************************************************************************
1506 ******************************************************************************/
1509 CodeEmitterGM107::emitLOP()
1514 case OP_AND
: lop
= 0; break;
1515 case OP_OR
: lop
= 1; break;
1516 case OP_XOR
: lop
= 2; break;
1518 assert(!"invalid lop");
1522 if (!longIMMD(insn
->src(1))) {
1523 switch (insn
->src(1).getFile()) {
1525 emitInsn(0x5c400000);
1526 emitGPR (0x14, insn
->src(1));
1528 case FILE_MEMORY_CONST
:
1529 emitInsn(0x4c400000);
1530 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1532 case FILE_IMMEDIATE
:
1533 emitInsn(0x38400000);
1534 emitIMMD(0x14, 19, insn
->src(1));
1537 assert(!"bad src1 file");
1541 emitField(0x29, 2, lop
);
1542 emitINV (0x28, insn
->src(1));
1543 emitINV (0x27, insn
->src(0));
1545 emitInsn (0x04000000);
1546 emitINV (0x38, insn
->src(1));
1547 emitINV (0x37, insn
->src(0));
1548 emitField(0x35, 2, lop
);
1549 emitIMMD (0x14, 32, insn
->src(1));
1552 emitGPR (0x08, insn
->src(0));
1553 emitGPR (0x00, insn
->def(0));
1556 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1558 CodeEmitterGM107::emitNOT()
1560 if (!longIMMD(insn
->src(0))) {
1561 switch (insn
->src(0).getFile()) {
1563 emitInsn(0x5c400700);
1564 emitGPR (0x14, insn
->src(0));
1566 case FILE_MEMORY_CONST
:
1567 emitInsn(0x4c400700);
1568 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1570 case FILE_IMMEDIATE
:
1571 emitInsn(0x38400700);
1572 emitIMMD(0x14, 19, insn
->src(0));
1575 assert(!"bad src1 file");
1580 emitInsn (0x05600000);
1581 emitIMMD (0x14, 32, insn
->src(1));
1585 emitGPR(0x00, insn
->def(0));
1589 CodeEmitterGM107::emitIADD()
1591 if (!longIMMD(insn
->src(1))) {
1592 switch (insn
->src(1).getFile()) {
1594 emitInsn(0x5c100000);
1595 emitGPR (0x14, insn
->src(1));
1597 case FILE_MEMORY_CONST
:
1598 emitInsn(0x4c100000);
1599 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1601 case FILE_IMMEDIATE
:
1602 emitInsn(0x38100000);
1603 emitIMMD(0x14, 19, insn
->src(1));
1606 assert(!"bad src1 file");
1610 emitNEG(0x31, insn
->src(0));
1611 emitNEG(0x30, insn
->src(1));
1614 emitInsn(0x1c000000);
1617 emitIMMD(0x14, 32, insn
->src(1));
1620 if (insn
->op
== OP_SUB
)
1621 code
[1] ^= 0x00010000;
1623 emitGPR(0x08, insn
->src(0));
1624 emitGPR(0x00, insn
->def(0));
1628 CodeEmitterGM107::emitIMUL()
1630 if (!longIMMD(insn
->src(1))) {
1631 switch (insn
->src(1).getFile()) {
1633 emitInsn(0x5c380000);
1634 emitGPR (0x14, insn
->src(1));
1636 case FILE_MEMORY_CONST
:
1637 emitInsn(0x4c380000);
1638 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1640 case FILE_IMMEDIATE
:
1641 emitInsn(0x38380000);
1642 emitIMMD(0x14, 19, insn
->src(1));
1645 assert(!"bad src1 file");
1649 emitField(0x29, 1, isSignedType(insn
->sType
));
1650 emitField(0x28, 1, isSignedType(insn
->dType
));
1651 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1653 emitInsn (0x1f000000);
1654 emitField(0x37, 1, isSignedType(insn
->sType
));
1655 emitField(0x36, 1, isSignedType(insn
->dType
));
1656 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1658 emitIMMD (0x14, 32, insn
->src(1));
1661 emitGPR(0x08, insn
->src(0));
1662 emitGPR(0x00, insn
->def(0));
1666 CodeEmitterGM107::emitIMAD()
1668 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1669 switch(insn
->src(2).getFile()) {
1671 switch (insn
->src(1).getFile()) {
1673 emitInsn(0x5a000000);
1674 emitGPR (0x14, insn
->src(1));
1676 case FILE_MEMORY_CONST
:
1677 emitInsn(0x4a000000);
1678 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1680 case FILE_IMMEDIATE
:
1681 emitInsn(0x34000000);
1682 emitIMMD(0x14, 19, insn
->src(1));
1685 assert(!"bad src1 file");
1688 emitGPR (0x27, insn
->src(2));
1690 case FILE_MEMORY_CONST
:
1691 emitInsn(0x52000000);
1692 emitGPR (0x27, insn
->src(1));
1693 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1696 assert(!"bad src2 file");
1700 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1701 emitField(0x35, 1, isSignedType(insn
->sType
));
1702 emitNEG (0x34, insn
->src(2));
1703 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1706 emitField(0x30, 1, isSignedType(insn
->dType
));
1708 emitGPR (0x08, insn
->src(0));
1709 emitGPR (0x00, insn
->def(0));
1713 CodeEmitterGM107::emitIMNMX()
1715 switch (insn
->src(1).getFile()) {
1717 emitInsn(0x5c200000);
1718 emitGPR (0x14, insn
->src(1));
1720 case FILE_MEMORY_CONST
:
1721 emitInsn(0x4c200000);
1722 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1724 case FILE_IMMEDIATE
:
1725 emitInsn(0x38200000);
1726 emitIMMD(0x14, 19, insn
->src(1));
1729 assert(!"bad src1 file");
1733 emitField(0x30, 1, isSignedType(insn
->dType
));
1735 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1737 emitGPR (0x08, insn
->src(0));
1738 emitGPR (0x00, insn
->def(0));
1742 CodeEmitterGM107::emitICMP()
1744 const CmpInstruction
*insn
= this->insn
->asCmp();
1745 CondCode cc
= insn
->setCond
;
1747 if (insn
->src(2).mod
.neg())
1748 cc
= reverseCondCode(cc
);
1750 switch(insn
->src(2).getFile()) {
1752 switch (insn
->src(1).getFile()) {
1754 emitInsn(0x5b400000);
1755 emitGPR (0x14, insn
->src(1));
1757 case FILE_MEMORY_CONST
:
1758 emitInsn(0x4b400000);
1759 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1761 case FILE_IMMEDIATE
:
1762 emitInsn(0x36400000);
1763 emitIMMD(0x14, 19, insn
->src(1));
1766 assert(!"bad src1 file");
1769 emitGPR (0x27, insn
->src(2));
1771 case FILE_MEMORY_CONST
:
1772 emitInsn(0x53400000);
1773 emitGPR (0x27, insn
->src(1));
1774 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1777 assert(!"bad src2 file");
1781 emitCond3(0x31, cc
);
1782 emitField(0x30, 1, isSignedType(insn
->sType
));
1783 emitGPR (0x08, insn
->src(0));
1784 emitGPR (0x00, insn
->def(0));
1788 CodeEmitterGM107::emitISET()
1790 const CmpInstruction
*insn
= this->insn
->asCmp();
1792 switch (insn
->src(1).getFile()) {
1794 emitInsn(0x5b500000);
1795 emitGPR (0x14, insn
->src(1));
1797 case FILE_MEMORY_CONST
:
1798 emitInsn(0x4b500000);
1799 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1801 case FILE_IMMEDIATE
:
1802 emitInsn(0x36500000);
1803 emitIMMD(0x14, 19, insn
->src(1));
1806 assert(!"bad src1 file");
1810 if (insn
->op
!= OP_SET
) {
1812 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1813 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1814 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1816 assert(!"invalid set op");
1819 emitPRED(0x27, insn
->src(2));
1824 emitCond3(0x31, insn
->setCond
);
1825 emitField(0x30, 1, isSignedType(insn
->sType
));
1828 emitGPR (0x08, insn
->src(0));
1829 emitGPR (0x00, insn
->def(0));
1833 CodeEmitterGM107::emitISETP()
1835 const CmpInstruction
*insn
= this->insn
->asCmp();
1837 switch (insn
->src(1).getFile()) {
1839 emitInsn(0x5b600000);
1840 emitGPR (0x14, insn
->src(1));
1842 case FILE_MEMORY_CONST
:
1843 emitInsn(0x4b600000);
1844 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1846 case FILE_IMMEDIATE
:
1847 emitInsn(0x36600000);
1848 emitIMMD(0x14, 19, insn
->src(1));
1851 assert(!"bad src1 file");
1855 if (insn
->op
!= OP_SET
) {
1857 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1858 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1859 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1861 assert(!"invalid set op");
1864 emitPRED(0x27, insn
->src(2));
1869 emitCond3(0x31, insn
->setCond
);
1870 emitField(0x30, 1, isSignedType(insn
->sType
));
1872 emitGPR (0x08, insn
->src(0));
1873 emitPRED (0x03, insn
->def(0));
1874 if (insn
->defExists(1))
1875 emitPRED(0x00, insn
->def(1));
1881 CodeEmitterGM107::emitSHL()
1883 switch (insn
->src(1).getFile()) {
1885 emitInsn(0x5c480000);
1886 emitGPR (0x14, insn
->src(1));
1888 case FILE_MEMORY_CONST
:
1889 emitInsn(0x4c480000);
1890 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1892 case FILE_IMMEDIATE
:
1893 emitInsn(0x38480000);
1894 emitIMMD(0x14, 19, insn
->src(1));
1897 assert(!"bad src1 file");
1903 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1904 emitGPR (0x08, insn
->src(0));
1905 emitGPR (0x00, insn
->def(0));
1909 CodeEmitterGM107::emitSHR()
1911 switch (insn
->src(1).getFile()) {
1913 emitInsn(0x5c280000);
1914 emitGPR (0x14, insn
->src(1));
1916 case FILE_MEMORY_CONST
:
1917 emitInsn(0x4c280000);
1918 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1920 case FILE_IMMEDIATE
:
1921 emitInsn(0x38280000);
1922 emitIMMD(0x14, 19, insn
->src(1));
1925 assert(!"bad src1 file");
1929 emitField(0x30, 1, isSignedType(insn
->dType
));
1932 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1933 emitGPR (0x08, insn
->src(0));
1934 emitGPR (0x00, insn
->def(0));
1938 CodeEmitterGM107::emitPOPC()
1940 switch (insn
->src(0).getFile()) {
1942 emitInsn(0x5c080000);
1943 emitGPR (0x14, insn
->src(0));
1945 case FILE_MEMORY_CONST
:
1946 emitInsn(0x4c080000);
1947 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1949 case FILE_IMMEDIATE
:
1950 emitInsn(0x38080000);
1951 emitIMMD(0x14, 19, insn
->src(0));
1954 assert(!"bad src1 file");
1958 emitINV(0x28, insn
->src(0));
1959 emitGPR(0x00, insn
->def(0));
1963 CodeEmitterGM107::emitBFI()
1965 switch(insn
->src(2).getFile()) {
1967 switch (insn
->src(1).getFile()) {
1969 emitInsn(0x5bf00000);
1970 emitGPR (0x14, insn
->src(1));
1972 case FILE_MEMORY_CONST
:
1973 emitInsn(0x4bf00000);
1974 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1976 case FILE_IMMEDIATE
:
1977 emitInsn(0x36f00000);
1978 emitIMMD(0x14, 19, insn
->src(1));
1981 assert(!"bad src1 file");
1984 emitGPR (0x27, insn
->src(2));
1986 case FILE_MEMORY_CONST
:
1987 emitInsn(0x53f00000);
1988 emitGPR (0x27, insn
->src(1));
1989 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1992 assert(!"bad src2 file");
1997 emitGPR (0x08, insn
->src(0));
1998 emitGPR (0x00, insn
->def(0));
2002 CodeEmitterGM107::emitBFE()
2004 switch (insn
->src(1).getFile()) {
2006 emitInsn(0x5c000000);
2007 emitGPR (0x14, insn
->src(1));
2009 case FILE_MEMORY_CONST
:
2010 emitInsn(0x4c000000);
2011 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2013 case FILE_IMMEDIATE
:
2014 emitInsn(0x38000000);
2015 emitIMMD(0x14, 19, insn
->src(1));
2018 assert(!"bad src1 file");
2022 emitField(0x30, 1, isSignedType(insn
->dType
));
2024 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2025 emitGPR (0x08, insn
->src(0));
2026 emitGPR (0x00, insn
->def(0));
2030 CodeEmitterGM107::emitFLO()
2032 switch (insn
->src(0).getFile()) {
2034 emitInsn(0x5c300000);
2035 emitGPR (0x14, insn
->src(0));
2037 case FILE_MEMORY_CONST
:
2038 emitInsn(0x4c300000);
2039 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2041 case FILE_IMMEDIATE
:
2042 emitInsn(0x38300000);
2043 emitIMMD(0x14, 19, insn
->src(0));
2046 assert(!"bad src1 file");
2050 emitField(0x30, 1, isSignedType(insn
->dType
));
2052 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2053 emitINV (0x28, insn
->src(0));
2054 emitGPR (0x00, insn
->def(0));
2057 /*******************************************************************************
2059 ******************************************************************************/
2062 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2066 switch (typeSizeof(type
)) {
2067 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2068 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2069 case 4: data
= 4; break;
2070 case 8: data
= 5; break;
2071 case 16: data
= 6; break;
2073 assert(!"bad type");
2077 emitField(pos
, 3, data
);
2081 CodeEmitterGM107::emitLDSTc(int pos
)
2085 switch (insn
->cache
) {
2086 case CACHE_CA
: mode
= 0; break;
2087 case CACHE_CG
: mode
= 1; break;
2088 case CACHE_CS
: mode
= 2; break;
2089 case CACHE_CV
: mode
= 3; break;
2091 assert(!"invalid caching mode");
2095 emitField(pos
, 2, mode
);
2099 CodeEmitterGM107::emitLDC()
2101 emitInsn (0xef900000);
2102 emitLDSTs(0x30, insn
->dType
);
2103 emitField(0x2c, 2, insn
->subOp
);
2104 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2105 emitGPR (0x00, insn
->def(0));
2109 CodeEmitterGM107::emitLDL()
2111 emitInsn (0xef400000);
2112 emitLDSTs(0x30, insn
->dType
);
2114 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2115 emitGPR (0x00, insn
->def(0));
2119 CodeEmitterGM107::emitLDS()
2121 emitInsn (0xef480000);
2122 emitLDSTs(0x30, insn
->dType
);
2123 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2124 emitGPR (0x00, insn
->def(0));
2128 CodeEmitterGM107::emitLD()
2130 emitInsn (0x80000000);
2133 emitLDSTs(0x35, insn
->dType
);
2134 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2135 emitGPR (0x00, insn
->def(0));
2139 CodeEmitterGM107::emitSTL()
2141 emitInsn (0xef500000);
2142 emitLDSTs(0x30, insn
->dType
);
2144 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2145 emitGPR (0x00, insn
->src(1));
2149 CodeEmitterGM107::emitSTS()
2151 emitInsn (0xef580000);
2152 emitLDSTs(0x30, insn
->dType
);
2153 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2154 emitGPR (0x00, insn
->src(1));
2158 CodeEmitterGM107::emitST()
2160 emitInsn (0xa0000000);
2163 emitLDSTs(0x35, insn
->dType
);
2164 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2165 emitGPR (0x00, insn
->src(1));
2169 CodeEmitterGM107::emitALD()
2171 emitInsn (0xefd80000);
2172 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2173 emitGPR (0x27, insn
->src(0).getIndirect(1));
2176 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2177 emitGPR (0x00, insn
->def(0));
2181 CodeEmitterGM107::emitAST()
2183 emitInsn (0xeff00000);
2184 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2185 emitGPR (0x27, insn
->src(0).getIndirect(1));
2187 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2188 emitGPR (0x00, insn
->src(1));
2192 CodeEmitterGM107::emitISBERD()
2194 emitInsn(0xefd00000);
2195 emitGPR (0x08, insn
->src(0));
2196 emitGPR (0x00, insn
->def(0));
2200 CodeEmitterGM107::emitIPA()
2202 int ipam
= 0, ipas
= 0;
2204 switch (insn
->getInterpMode()) {
2205 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2206 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2207 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2208 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2210 assert(!"invalid ipa mode");
2214 switch (insn
->getSampleMode()) {
2215 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2216 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2217 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2219 assert(!"invalid ipa sample mode");
2223 emitInsn (0xe0000000);
2224 emitField(0x36, 2, ipam
);
2225 emitField(0x34, 2, ipas
);
2227 emitField(0x2f, 3, 7);
2228 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2229 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2230 code
[1] |= 0x00000040; /* .idx */
2231 emitGPR(0x00, insn
->def(0));
2233 if (insn
->op
== OP_PINTERP
) {
2234 emitGPR(0x14, insn
->src(1));
2235 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2236 emitGPR(0x27, insn
->src(2));
2238 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2239 emitGPR(0x27, insn
->src(1));
2243 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2247 /*******************************************************************************
2249 ******************************************************************************/
2252 CodeEmitterGM107::emitPIXLD()
2254 emitInsn (0xefe80000);
2256 emitField(0x1f, 3, insn
->subOp
);
2257 emitGPR (0x08, insn
->src(0));
2258 emitGPR (0x00, insn
->def(0));
2261 /*******************************************************************************
2263 ******************************************************************************/
2266 CodeEmitterGM107::emitTEXs(int pos
)
2268 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2269 if (insn
->srcExists(src1
))
2270 emitGPR(pos
, insn
->src(src1
));
2276 CodeEmitterGM107::emitTEX()
2278 const TexInstruction
*insn
= this->insn
->asTex();
2281 if (!insn
->tex
.levelZero
) {
2283 case OP_TEX
: lodm
= 0; break;
2284 case OP_TXB
: lodm
= 2; break;
2285 case OP_TXL
: lodm
= 3; break;
2287 assert(!"invalid tex op");
2294 if (insn
->tex
.rIndirectSrc
>= 0) {
2295 emitInsn (0xdeb80000);
2296 emitField(0x35, 2, lodm
);
2297 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2299 emitInsn (0xc0380000);
2300 emitField(0x37, 2, lodm
);
2301 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2302 emitField(0x24, 13, insn
->tex
.r
);
2305 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2306 emitField(0x31, 1, insn
->tex
.liveOnly
);
2307 emitField(0x23, 1, insn
->tex
.derivAll
);
2308 emitField(0x1f, 4, insn
->tex
.mask
);
2309 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2310 insn
->tex
.target
.getDim() - 1);
2311 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2313 emitGPR (0x08, insn
->src(0));
2314 emitGPR (0x00, insn
->def(0));
2318 CodeEmitterGM107::emitTLD()
2320 const TexInstruction
*insn
= this->insn
->asTex();
2322 if (insn
->tex
.rIndirectSrc
>= 0) {
2323 emitInsn (0xdd380000);
2325 emitInsn (0xdc380000);
2326 emitField(0x24, 13, insn
->tex
.r
);
2329 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2330 emitField(0x32, 1, insn
->tex
.target
.isMS());
2331 emitField(0x31, 1, insn
->tex
.liveOnly
);
2332 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2333 emitField(0x1f, 4, insn
->tex
.mask
);
2334 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2335 insn
->tex
.target
.getDim() - 1);
2336 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2338 emitGPR (0x08, insn
->src(0));
2339 emitGPR (0x00, insn
->def(0));
2343 CodeEmitterGM107::emitTLD4()
2345 const TexInstruction
*insn
= this->insn
->asTex();
2347 if (insn
->tex
.rIndirectSrc
>= 0) {
2348 emitInsn (0xdef80000);
2349 emitField(0x26, 2, insn
->tex
.gatherComp
);
2350 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2351 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2353 emitInsn (0xc8380000);
2354 emitField(0x38, 2, insn
->tex
.gatherComp
);
2355 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2356 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2357 emitField(0x24, 13, insn
->tex
.r
);
2360 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2361 emitField(0x31, 1, insn
->tex
.liveOnly
);
2362 emitField(0x23, 1, insn
->tex
.derivAll
);
2363 emitField(0x1f, 4, insn
->tex
.mask
);
2364 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2365 insn
->tex
.target
.getDim() - 1);
2366 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2368 emitGPR (0x08, insn
->src(0));
2369 emitGPR (0x00, insn
->def(0));
2373 CodeEmitterGM107::emitTXD()
2375 const TexInstruction
*insn
= this->insn
->asTex();
2377 if (insn
->tex
.rIndirectSrc
>= 0) {
2378 emitInsn (0xde780000);
2380 emitInsn (0xde380000);
2381 emitField(0x24, 13, insn
->tex
.r
);
2384 emitField(0x31, 1, insn
->tex
.liveOnly
);
2385 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2386 emitField(0x1f, 4, insn
->tex
.mask
);
2387 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2388 insn
->tex
.target
.getDim() - 1);
2389 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2391 emitGPR (0x08, insn
->src(0));
2392 emitGPR (0x00, insn
->def(0));
2396 CodeEmitterGM107::emitTMML()
2398 const TexInstruction
*insn
= this->insn
->asTex();
2400 if (insn
->tex
.rIndirectSrc
>= 0) {
2401 emitInsn (0xdf600000);
2403 emitInsn (0xdf580000);
2404 emitField(0x24, 13, insn
->tex
.r
);
2407 emitField(0x31, 1, insn
->tex
.liveOnly
);
2408 emitField(0x23, 1, insn
->tex
.derivAll
);
2409 emitField(0x1f, 4, insn
->tex
.mask
);
2410 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2411 insn
->tex
.target
.getDim() - 1);
2412 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2414 emitGPR (0x08, insn
->src(0));
2415 emitGPR (0x00, insn
->def(0));
2419 CodeEmitterGM107::emitTXQ()
2421 const TexInstruction
*insn
= this->insn
->asTex();
2424 switch (insn
->tex
.query
) {
2425 case TXQ_DIMS
: type
= 0x01; break;
2426 case TXQ_TYPE
: type
= 0x02; break;
2427 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2428 case TXQ_FILTER
: type
= 0x10; break;
2429 case TXQ_LOD
: type
= 0x12; break;
2430 case TXQ_WRAP
: type
= 0x14; break;
2431 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2433 assert(!"invalid txq query");
2437 emitInsn (0xdf4a0000);
2438 emitField(0x24, 13, insn
->tex
.r
);
2439 emitField(0x1f, 4, insn
->tex
.mask
);
2440 emitField(0x16, 6, type
);
2441 emitGPR (0x08, insn
->src(0));
2442 emitGPR (0x00, insn
->def(0));
2446 CodeEmitterGM107::emitDEPBAR()
2448 emitInsn (0xf0f00000);
2449 emitField(0x1d, 1, 1); /* le */
2450 emitField(0x1a, 3, 5);
2451 emitField(0x14, 6, insn
->subOp
);
2452 emitField(0x00, 6, insn
->subOp
);
2455 /*******************************************************************************
2457 ******************************************************************************/
2460 CodeEmitterGM107::emitNOP()
2462 emitInsn(0x50b00000);
2466 CodeEmitterGM107::emitKIL()
2468 emitInsn (0xe3300000);
2469 emitCond5(0x00, CC_TR
);
2473 CodeEmitterGM107::emitOUT()
2475 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2476 const int emit
= insn
->op
== OP_EMIT
;
2478 switch (insn
->src(1).getFile()) {
2480 emitInsn(0xfbe00000);
2481 emitGPR (0x14, insn
->src(1));
2483 case FILE_IMMEDIATE
:
2484 emitInsn(0xf6e00000);
2485 emitIMMD(0x14, 19, insn
->src(1));
2487 case FILE_MEMORY_CONST
:
2488 emitInsn(0xebe00000);
2489 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2492 assert(!"bad src1 file");
2496 emitField(0x27, 2, (cut
<< 1) | emit
);
2497 emitGPR (0x08, insn
->src(0));
2498 emitGPR (0x00, insn
->def(0));
2501 /*******************************************************************************
2502 * assembler front-end
2503 ******************************************************************************/
2506 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2508 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2513 if (insn
->encSize
!= 8) {
2514 ERROR("skipping undecodable instruction: "); insn
->print();
2517 if (codeSize
+ size
> codeSizeLimit
) {
2518 ERROR("code emitter output buffer too small\n");
2522 if (writeIssueDelays
) {
2523 int n
= ((codeSize
& 0x1f) / 8) - 1;
2526 data
[0] = 0x00000000;
2527 data
[1] = 0x00000000;
2533 emitField(data
, n
* 21, 21, insn
->sched
);
2577 if (insn
->def(0).getFile() == FILE_GPR
&&
2578 insn
->src(0).getFile() != FILE_PREDICATE
)
2593 if (isFloatType(insn
->dType
)) {
2594 if (isFloatType(insn
->sType
))
2599 if (isFloatType(insn
->sType
))
2610 if (isFloatType(insn
->dType
)) {
2611 if (insn
->dType
== TYPE_F64
)
2620 if (isFloatType(insn
->dType
)) {
2621 if (insn
->dType
== TYPE_F64
)
2631 if (isFloatType(insn
->dType
)) {
2632 if (insn
->dType
== TYPE_F64
)
2642 if (isFloatType(insn
->dType
)) {
2643 if (insn
->dType
== TYPE_F64
)
2670 if (isFloatType(insn
->dType
))
2679 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2680 if (isFloatType(insn
->sType
))
2681 if (insn
->sType
== TYPE_F64
)
2688 if (isFloatType(insn
->sType
))
2689 if (insn
->sType
== TYPE_F64
)
2718 switch (insn
->src(0).getFile()) {
2719 case FILE_MEMORY_CONST
: emitLDC(); break;
2720 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2721 case FILE_MEMORY_SHARED
: emitLDS(); break;
2722 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2724 assert(!"invalid load");
2730 switch (insn
->src(0).getFile()) {
2731 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2732 case FILE_MEMORY_SHARED
: emitSTS(); break;
2733 case FILE_MEMORY_GLOBAL
: emitST(); break;
2735 assert(!"invalid load");
2793 assert(!"invalid opcode");
2809 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2814 /*******************************************************************************
2815 * sched data calculator
2816 ******************************************************************************/
2818 class SchedDataCalculatorGM107
: public Pass
2821 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2824 bool visit(BasicBlock
*bb
);
2828 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2830 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2832 insn
->sched
= 0x7e0;
2838 /*******************************************************************************
2840 ******************************************************************************/
2843 CodeEmitterGM107::prepareEmission(Function
*func
)
2845 SchedDataCalculatorGM107
sched(targ
);
2846 CodeEmitter::prepareEmission(func
);
2847 sched
.run(func
, true, true);
2850 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
2852 return (size
+ 23) / 24;
2856 CodeEmitterGM107::prepareEmission(Program
*prog
)
2858 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
2859 !fi
.end(); fi
.next()) {
2860 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
2861 func
->binPos
= prog
->binSize
;
2862 prepareEmission(func
);
2864 // adjust sizes & positions for schedulding info:
2865 if (prog
->getTarget()->hasSWSched
) {
2866 uint32_t adjPos
= func
->binPos
;
2867 BasicBlock
*bb
= NULL
;
2868 for (int i
= 0; i
< func
->bbCount
; ++i
) {
2869 bb
= func
->bbArray
[i
];
2870 int32_t adjSize
= bb
->binSize
;
2872 adjSize
-= 32 - adjPos
% 32;
2876 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
2877 bb
->binPos
= adjPos
;
2878 bb
->binSize
= adjSize
;
2882 func
->binSize
= adjPos
- func
->binPos
;
2885 prog
->binSize
+= func
->binSize
;
2889 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
2890 : CodeEmitter(target
),
2892 writeIssueDelays(target
->hasSWSched
)
2895 codeSize
= codeSizeLimit
= 0;
2900 TargetGM107::createCodeEmitterGM107(Program::Type type
)
2902 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
2903 emit
->setProgramType(type
);
2907 } // namespace nv50_ir