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_LANEID
: id
= 0x00; break;
244 case SV_VERTEX_COUNT
: id
= 0x10; break;
245 case SV_INVOCATION_ID
: id
= 0x11; break;
246 case SV_INVOCATION_INFO
: id
= 0x1d; break;
248 assert(!"invalid system value");
253 emitField(pos
, 8, id
);
257 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
259 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
263 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
266 const Value
*v
= ref
.get();
267 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
269 emitGPR(gpr
, ref
.getIndirect(0));
270 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
274 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
277 const Value
*v
= ref
.get();
278 const Symbol
*s
= v
->asSym();
280 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
282 emitField(buf
, 5, v
->reg
.fileIndex
);
284 emitGPR(gpr
, ref
.getIndirect(0));
285 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
289 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
291 if (ref
.getFile() == FILE_IMMEDIATE
) {
292 const ImmediateValue
*imm
= ref
.get()->asImm();
293 if (isFloatType(insn
->sType
)) {
294 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
297 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
298 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
306 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
308 const ImmediateValue
*imm
= ref
.get()->asImm();
309 uint32_t val
= imm
->reg
.data
.u32
;
312 if (isFloatType(insn
->sType
)) {
313 assert(!(val
& 0x00000fff));
316 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
317 emitField( 56, 1, (val
& 0x80000) >> 19);
318 emitField(pos
, len
, (val
& 0x7ffff));
320 emitField(pos
, len
, val
);
324 /*******************************************************************************
326 ******************************************************************************/
329 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
334 case CC_FL
: data
= 0x00; break;
336 case CC_LT
: data
= 0x01; break;
338 case CC_EQ
: data
= 0x02; break;
340 case CC_LE
: data
= 0x03; break;
342 case CC_GT
: data
= 0x04; break;
344 case CC_NE
: data
= 0x05; break;
346 case CC_GE
: data
= 0x06; break;
347 case CC_TR
: data
= 0x07; break;
349 assert(!"invalid cond3");
353 emitField(pos
, 3, data
);
357 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
362 case CC_FL
: data
= 0x00; break;
363 case CC_LT
: data
= 0x01; break;
364 case CC_EQ
: data
= 0x02; break;
365 case CC_LE
: data
= 0x03; break;
366 case CC_GT
: data
= 0x04; break;
367 case CC_NE
: data
= 0x05; break;
368 case CC_GE
: data
= 0x06; break;
369 // case CC_NUM: data = 0x07; break;
370 // case CC_NAN: data = 0x08; break;
371 case CC_LTU
: data
= 0x09; break;
372 case CC_EQU
: data
= 0x0a; break;
373 case CC_LEU
: data
= 0x0b; break;
374 case CC_GTU
: data
= 0x0c; break;
375 case CC_NEU
: data
= 0x0d; break;
376 case CC_GEU
: data
= 0x0e; break;
377 case CC_TR
: data
= 0x0f; break;
379 assert(!"invalid cond4");
383 emitField(pos
, 4, data
);
387 CodeEmitterGM107::emitO(int pos
)
389 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
393 CodeEmitterGM107::emitP(int pos
)
395 emitField(pos
, 1, insn
->perPatch
);
399 CodeEmitterGM107::emitSAT(int pos
)
401 emitField(pos
, 1, insn
->saturate
);
405 CodeEmitterGM107::emitCC(int pos
)
407 emitField(pos
, 1, insn
->defExists(1));
411 CodeEmitterGM107::emitX(int pos
)
413 emitField(pos
, 1, insn
->flagsSrc
>= 0);
417 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
419 emitField(pos
, 1, ref
.mod
.abs());
423 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
425 emitField(pos
, 1, ref
.mod
.neg());
429 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
431 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
435 CodeEmitterGM107::emitFMZ(int pos
, int len
)
437 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
441 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
445 case ROUND_NI
: ri
= 1;
446 case ROUND_N
: rm
= 0; break;
447 case ROUND_MI
: ri
= 1;
448 case ROUND_M
: rm
= 1; break;
449 case ROUND_PI
: ri
= 1;
450 case ROUND_P
: rm
= 2; break;
451 case ROUND_ZI
: ri
= 1;
452 case ROUND_Z
: rm
= 3; break;
454 assert(!"invalid round mode");
457 emitField(rip
, 1, ri
);
458 emitField(rmp
, 2, rm
);
462 CodeEmitterGM107::emitPDIV(int pos
)
464 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
465 if (insn
->postFactor
> 0)
466 emitField(pos
, 3, 7 - insn
->postFactor
);
468 emitField(pos
, 3, 0 - insn
->postFactor
);
472 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
474 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
477 /*******************************************************************************
479 ******************************************************************************/
482 CodeEmitterGM107::emitEXIT()
484 emitInsn (0xe3000000);
485 emitCond5(0x00, CC_TR
);
489 CodeEmitterGM107::emitBRA()
491 const FlowInstruction
*insn
= this->insn
->asFlow();
494 if (insn
->indirect
) {
496 emitInsn(0xe2000000); // JMX
498 emitInsn(0xe2500000); // BRX
502 emitInsn(0xe2100000); // JMP
504 emitInsn(0xe2400000); // BRA
505 emitField(0x07, 1, insn
->allWarp
);
508 emitField(0x06, 1, insn
->limit
);
509 emitCond5(0x00, CC_TR
);
511 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
512 int32_t pos
= insn
->target
.bb
->binPos
;
513 if (writeIssueDelays
&& !(pos
& 0x1f))
516 emitField(0x14, 24, pos
- (codeSize
+ 8));
518 emitField(0x14, 32, pos
);
520 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
521 emitField(0x05, 1, 1);
526 CodeEmitterGM107::emitCAL()
528 const FlowInstruction
*insn
= this->insn
->asFlow();
530 if (insn
->absolute
) {
531 emitInsn(0xe2200000, 0); // JCAL
533 emitInsn(0xe2600000, 0); // CAL
536 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
538 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
541 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
542 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
543 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
545 emitField(0x14, 32, insn
->target
.bb
->binPos
);
549 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
550 emitField(0x05, 1, 1);
555 CodeEmitterGM107::emitPCNT()
557 const FlowInstruction
*insn
= this->insn
->asFlow();
559 emitInsn(0xe2b00000, 0);
561 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
562 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
564 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
565 emitField(0x05, 1, 1);
570 CodeEmitterGM107::emitCONT()
572 emitInsn (0xe3500000);
573 emitCond5(0x00, CC_TR
);
577 CodeEmitterGM107::emitPBK()
579 const FlowInstruction
*insn
= this->insn
->asFlow();
581 emitInsn(0xe2a00000, 0);
583 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
584 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
586 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
587 emitField(0x05, 1, 1);
592 CodeEmitterGM107::emitBRK()
594 emitInsn (0xe3400000);
595 emitCond5(0x00, CC_TR
);
599 CodeEmitterGM107::emitPRET()
601 const FlowInstruction
*insn
= this->insn
->asFlow();
603 emitInsn(0xe2700000, 0);
605 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
606 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
608 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
609 emitField(0x05, 1, 1);
614 CodeEmitterGM107::emitRET()
616 emitInsn (0xe3200000);
617 emitCond5(0x00, CC_TR
);
621 CodeEmitterGM107::emitSSY()
623 const FlowInstruction
*insn
= this->insn
->asFlow();
625 emitInsn(0xe2900000, 0);
627 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
628 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
630 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
631 emitField(0x05, 1, 1);
636 CodeEmitterGM107::emitSYNC()
638 emitInsn (0xf0f80000);
639 emitCond5(0x00, CC_TR
);
643 CodeEmitterGM107::emitSAM()
645 emitInsn(0xe3700000, 0);
649 CodeEmitterGM107::emitRAM()
651 emitInsn(0xe3800000, 0);
654 /*******************************************************************************
656 ******************************************************************************/
658 /*******************************************************************************
659 * movement / conversion
660 ******************************************************************************/
663 CodeEmitterGM107::emitMOV()
665 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
666 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
667 switch (insn
->src(0).getFile()) {
669 emitInsn(0x5c980000);
670 emitGPR (0x14, insn
->src(0));
672 case FILE_MEMORY_CONST
:
673 emitInsn(0x4c980000);
674 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
677 emitInsn(0x38980000);
678 emitIMMD(0x14, 19, insn
->src(0));
681 assert(!"bad src file");
684 emitField(0x27, 4, insn
->lanes
);
686 emitInsn (0x01000000);
687 emitIMMD (0x14, 32, insn
->src(0));
688 emitField(0x0c, 4, insn
->lanes
);
691 emitGPR(0x00, insn
->def(0));
695 CodeEmitterGM107::emitS2R()
697 emitInsn(0xf0c80000);
698 emitSYS (0x14, insn
->src(0));
699 emitGPR (0x00, insn
->def(0));
703 CodeEmitterGM107::emitF2F()
705 RoundMode rnd
= insn
->rnd
;
708 case OP_FLOOR
: rnd
= ROUND_MI
; break;
709 case OP_CEIL
: rnd
= ROUND_PI
; break;
710 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
715 switch (insn
->src(0).getFile()) {
717 emitInsn(0x5ca80000);
718 emitGPR (0x14, insn
->src(0));
720 case FILE_MEMORY_CONST
:
721 emitInsn(0x4ca80000);
722 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
725 emitInsn(0x38a80000);
726 emitIMMD(0x14, 19, insn
->src(0));
729 assert(!"bad src0 file");
733 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
734 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
736 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
738 emitRND (0x27, rnd
, 0x2a);
739 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
740 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
741 emitGPR (0x00, insn
->def(0));
745 CodeEmitterGM107::emitF2I()
747 RoundMode rnd
= insn
->rnd
;
750 case OP_FLOOR
: rnd
= ROUND_M
; break;
751 case OP_CEIL
: rnd
= ROUND_P
; break;
752 case OP_TRUNC
: rnd
= ROUND_Z
; break;
757 switch (insn
->src(0).getFile()) {
759 emitInsn(0x5cb00000);
760 emitGPR (0x14, insn
->src(0));
762 case FILE_MEMORY_CONST
:
763 emitInsn(0x4cb00000);
764 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
767 emitInsn(0x38b00000);
768 emitIMMD(0x14, 19, insn
->src(0));
771 assert(!"bad src0 file");
775 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
777 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
779 emitRND (0x27, rnd
, 0x2a);
780 emitField(0x0c, 1, isSignedType(insn
->dType
));
781 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
782 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
783 emitGPR (0x00, insn
->def(0));
787 CodeEmitterGM107::emitI2F()
789 RoundMode rnd
= insn
->rnd
;
792 case OP_FLOOR
: rnd
= ROUND_M
; break;
793 case OP_CEIL
: rnd
= ROUND_P
; break;
794 case OP_TRUNC
: rnd
= ROUND_Z
; break;
799 switch (insn
->src(0).getFile()) {
801 emitInsn(0x5cb80000);
802 emitGPR (0x14, insn
->src(0));
804 case FILE_MEMORY_CONST
:
805 emitInsn(0x4cb80000);
806 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
809 emitInsn(0x38b80000);
810 emitIMMD(0x14, 19, insn
->src(0));
813 assert(!"bad src0 file");
817 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
819 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
820 emitRND (0x27, rnd
, -1);
821 emitField(0x0d, 1, isSignedType(insn
->sType
));
822 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
823 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
824 emitGPR (0x00, insn
->def(0));
828 CodeEmitterGM107::emitI2I()
830 switch (insn
->src(0).getFile()) {
832 emitInsn(0x5ce00000);
833 emitGPR (0x14, insn
->src(0));
835 case FILE_MEMORY_CONST
:
836 emitInsn(0x4ce00000);
837 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
840 emitInsn(0x38e00000);
841 emitIMMD(0x14, 19, insn
->src(0));
844 assert(!"bad src0 file");
849 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
851 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
852 emitField(0x0d, 1, isSignedType(insn
->sType
));
853 emitField(0x0c, 1, isSignedType(insn
->dType
));
854 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
855 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
856 emitGPR (0x00, insn
->def(0));
860 CodeEmitterGM107::emitSHFL()
864 emitInsn (0xef100000);
866 switch (insn
->src(1).getFile()) {
868 emitGPR(0x14, insn
->src(1));
871 emitIMMD(0x14, 5, insn
->src(1));
875 assert(!"invalid src1 file");
879 /*XXX: what is this arg? hardcode immediate for now */
880 emitField(0x22, 13, 0x1c03);
884 emitField(0x1e, 2, insn
->subOp
);
885 emitField(0x1c, 2, type
);
886 emitGPR (0x08, insn
->src(0));
887 emitGPR (0x00, insn
->def(0));
890 /*******************************************************************************
892 ******************************************************************************/
895 CodeEmitterGM107::emitDADD()
897 switch (insn
->src(1).getFile()) {
899 emitInsn(0x5c700000);
900 emitGPR (0x14, insn
->src(1));
902 case FILE_MEMORY_CONST
:
903 emitInsn(0x4c700000);
904 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
907 emitInsn(0x38700000);
908 emitIMMD(0x14, 19, insn
->src(1));
911 assert(!"bad src1 file");
914 emitABS(0x31, insn
->src(1));
915 emitNEG(0x30, insn
->src(0));
917 emitABS(0x2e, insn
->src(0));
918 emitNEG(0x2d, insn
->src(1));
920 if (insn
->op
== OP_SUB
)
921 code
[1] ^= 0x00002000;
923 emitGPR(0x08, insn
->src(0));
924 emitGPR(0x00, insn
->def(0));
928 CodeEmitterGM107::emitDMUL()
930 switch (insn
->src(1).getFile()) {
932 emitInsn(0x5c800000);
933 emitGPR (0x14, insn
->src(1));
935 case FILE_MEMORY_CONST
:
936 emitInsn(0x4c800000);
937 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
940 emitInsn(0x38800000);
941 emitIMMD(0x14, 19, insn
->src(1));
944 assert(!"bad src1 file");
948 emitNEG2(0x30, insn
->src(0), insn
->src(1));
951 emitGPR (0x08, insn
->src(0));
952 emitGPR (0x00, insn
->def(0));
956 CodeEmitterGM107::emitDFMA()
958 switch(insn
->src(2).getFile()) {
960 switch (insn
->src(1).getFile()) {
962 emitInsn(0x5b700000);
963 emitGPR (0x14, insn
->src(1));
965 case FILE_MEMORY_CONST
:
966 emitInsn(0x4b700000);
967 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
970 emitInsn(0x36700000);
971 emitIMMD(0x14, 19, insn
->src(1));
974 assert(!"bad src1 file");
977 emitGPR (0x27, insn
->src(2));
979 case FILE_MEMORY_CONST
:
980 emitInsn(0x53700000);
981 emitGPR (0x27, insn
->src(1));
982 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
985 assert(!"bad src2 file");
990 emitNEG (0x31, insn
->src(2));
991 emitNEG2(0x30, insn
->src(0), insn
->src(1));
993 emitGPR (0x08, insn
->src(0));
994 emitGPR (0x00, insn
->def(0));
998 CodeEmitterGM107::emitDMNMX()
1000 switch (insn
->src(1).getFile()) {
1002 emitInsn(0x5c500000);
1003 emitGPR (0x14, insn
->src(1));
1005 case FILE_MEMORY_CONST
:
1006 emitInsn(0x4c500000);
1007 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1009 case FILE_IMMEDIATE
:
1010 emitInsn(0x38500000);
1011 emitIMMD(0x14, 19, insn
->src(1));
1014 assert(!"bad src1 file");
1018 emitABS (0x31, insn
->src(1));
1019 emitNEG (0x30, insn
->src(0));
1021 emitABS (0x2e, insn
->src(0));
1022 emitNEG (0x2d, insn
->src(1));
1023 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1025 emitGPR (0x08, insn
->src(0));
1026 emitGPR (0x00, insn
->def(0));
1030 CodeEmitterGM107::emitDSET()
1032 const CmpInstruction
*insn
= this->insn
->asCmp();
1034 switch (insn
->src(1).getFile()) {
1036 emitInsn(0x59000000);
1037 emitGPR (0x14, insn
->src(1));
1039 case FILE_MEMORY_CONST
:
1040 emitInsn(0x49000000);
1041 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1043 case FILE_IMMEDIATE
:
1044 emitInsn(0x32000000);
1045 emitIMMD(0x14, 19, insn
->src(1));
1048 assert(!"bad src1 file");
1052 if (insn
->op
!= OP_SET
) {
1054 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1055 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1056 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1058 assert(!"invalid set op");
1061 emitPRED(0x27, insn
->src(2));
1066 emitABS (0x36, insn
->src(0));
1067 emitNEG (0x35, insn
->src(1));
1068 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1069 emitCond4(0x30, insn
->setCond
);
1071 emitABS (0x2c, insn
->src(1));
1072 emitNEG (0x2b, insn
->src(0));
1073 emitGPR (0x08, insn
->src(0));
1074 emitGPR (0x00, insn
->def(0));
1078 CodeEmitterGM107::emitDSETP()
1080 const CmpInstruction
*insn
= this->insn
->asCmp();
1082 switch (insn
->src(1).getFile()) {
1084 emitInsn(0x5b800000);
1085 emitGPR (0x14, insn
->src(1));
1087 case FILE_MEMORY_CONST
:
1088 emitInsn(0x4b800000);
1089 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1091 case FILE_IMMEDIATE
:
1092 emitInsn(0x36800000);
1093 emitIMMD(0x14, 19, insn
->src(1));
1096 assert(!"bad src1 file");
1100 if (insn
->op
!= OP_SET
) {
1102 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1103 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1104 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1106 assert(!"invalid set op");
1109 emitPRED(0x27, insn
->src(2));
1114 emitCond4(0x30, insn
->setCond
);
1115 emitABS (0x2c, insn
->src(1));
1116 emitNEG (0x2b, insn
->src(0));
1117 emitGPR (0x08, insn
->src(0));
1118 emitABS (0x07, insn
->src(0));
1119 emitNEG (0x06, insn
->src(1));
1120 emitPRED (0x03, insn
->def(0));
1121 if (insn
->defExists(1))
1122 emitPRED(0x00, insn
->def(1));
1127 /*******************************************************************************
1129 ******************************************************************************/
1132 CodeEmitterGM107::emitFADD()
1134 if (!longIMMD(insn
->src(1))) {
1135 switch (insn
->src(1).getFile()) {
1137 emitInsn(0x5c580000);
1138 emitGPR (0x14, insn
->src(1));
1140 case FILE_MEMORY_CONST
:
1141 emitInsn(0x4c580000);
1142 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1144 case FILE_IMMEDIATE
:
1145 emitInsn(0x38580000);
1146 emitIMMD(0x14, 19, insn
->src(1));
1149 assert(!"bad src1 file");
1153 emitABS(0x31, insn
->src(1));
1154 emitNEG(0x30, insn
->src(0));
1156 emitABS(0x2e, insn
->src(0));
1157 emitNEG(0x2d, insn
->src(1));
1160 emitInsn(0x08000000);
1161 emitABS(0x39, insn
->src(1));
1162 emitNEG(0x38, insn
->src(0));
1164 emitABS(0x36, insn
->src(0));
1165 emitNEG(0x35, insn
->src(1));
1167 emitIMMD(0x14, 32, insn
->src(1));
1170 if (insn
->op
== OP_SUB
)
1171 code
[1] ^= 0x00002000;
1173 emitGPR(0x08, insn
->src(0));
1174 emitGPR(0x00, insn
->def(0));
1178 CodeEmitterGM107::emitFMUL()
1180 if (!longIMMD(insn
->src(1))) {
1181 switch (insn
->src(1).getFile()) {
1183 emitInsn(0x5c680000);
1184 emitGPR (0x14, insn
->src(1));
1186 case FILE_MEMORY_CONST
:
1187 emitInsn(0x4c680000);
1188 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1190 case FILE_IMMEDIATE
:
1191 emitInsn(0x38680000);
1192 emitIMMD(0x14, 19, insn
->src(1));
1195 assert(!"bad src1 file");
1199 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1205 emitInsn(0x1e000000);
1209 emitIMMD(0x14, 32, insn
->src(1));
1210 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1211 code
[1] ^= 0x00080000; /* flip immd sign bit */
1214 emitGPR(0x08, insn
->src(0));
1215 emitGPR(0x00, insn
->def(0));
1219 CodeEmitterGM107::emitFFMA()
1221 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1222 switch(insn
->src(2).getFile()) {
1224 switch (insn
->src(1).getFile()) {
1226 emitInsn(0x59800000);
1227 emitGPR (0x14, insn
->src(1));
1229 case FILE_MEMORY_CONST
:
1230 emitInsn(0x49800000);
1231 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1233 case FILE_IMMEDIATE
:
1234 emitInsn(0x32800000);
1235 emitIMMD(0x14, 19, insn
->src(1));
1238 assert(!"bad src1 file");
1241 emitGPR (0x27, insn
->src(2));
1243 case FILE_MEMORY_CONST
:
1244 emitInsn(0x51800000);
1245 emitGPR (0x27, insn
->src(1));
1246 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1249 assert(!"bad src2 file");
1254 emitNEG (0x31, insn
->src(2));
1255 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1259 emitGPR(0x08, insn
->src(0));
1260 emitGPR(0x00, insn
->def(0));
1264 CodeEmitterGM107::emitMUFU()
1269 case OP_COS
: mufu
= 0; break;
1270 case OP_SIN
: mufu
= 1; break;
1271 case OP_EX2
: mufu
= 2; break;
1272 case OP_LG2
: mufu
= 3; break;
1273 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1274 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1276 assert(!"invalid mufu");
1280 emitInsn (0x50800000);
1282 emitNEG (0x30, insn
->src(0));
1283 emitABS (0x2e, insn
->src(0));
1284 emitField(0x14, 3, mufu
);
1285 emitGPR (0x08, insn
->src(0));
1286 emitGPR (0x00, insn
->def(0));
1290 CodeEmitterGM107::emitFMNMX()
1292 switch (insn
->src(1).getFile()) {
1294 emitInsn(0x5c600000);
1295 emitGPR (0x14, insn
->src(1));
1297 case FILE_MEMORY_CONST
:
1298 emitInsn(0x4c600000);
1299 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1301 case FILE_IMMEDIATE
:
1302 emitInsn(0x38600000);
1303 emitIMMD(0x14, 19, insn
->src(1));
1306 assert(!"bad src1 file");
1310 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1313 emitABS(0x31, insn
->src(1));
1314 emitNEG(0x30, insn
->src(0));
1316 emitABS(0x2e, insn
->src(0));
1317 emitNEG(0x2d, insn
->src(1));
1319 emitGPR(0x08, insn
->src(0));
1320 emitGPR(0x00, insn
->def(0));
1324 CodeEmitterGM107::emitRRO()
1326 switch (insn
->src(0).getFile()) {
1328 emitInsn(0x5c900000);
1329 emitGPR (0x14, insn
->src(0));
1331 case FILE_MEMORY_CONST
:
1332 emitInsn(0x4c900000);
1333 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1335 case FILE_IMMEDIATE
:
1336 emitInsn(0x38900000);
1337 emitIMMD(0x14, 19, insn
->src(0));
1340 assert(!"bad src file");
1344 emitABS (0x31, insn
->src(0));
1345 emitNEG (0x2d, insn
->src(0));
1346 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1347 emitGPR (0x00, insn
->def(0));
1351 CodeEmitterGM107::emitFCMP()
1353 const CmpInstruction
*insn
= this->insn
->asCmp();
1354 CondCode cc
= insn
->setCond
;
1356 if (insn
->src(2).mod
.neg())
1357 cc
= reverseCondCode(cc
);
1359 switch(insn
->src(2).getFile()) {
1361 switch (insn
->src(1).getFile()) {
1363 emitInsn(0x5ba00000);
1364 emitGPR (0x14, insn
->src(1));
1366 case FILE_MEMORY_CONST
:
1367 emitInsn(0x4ba00000);
1368 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1370 case FILE_IMMEDIATE
:
1371 emitInsn(0x36a00000);
1372 emitIMMD(0x14, 19, insn
->src(1));
1375 assert(!"bad src1 file");
1378 emitGPR (0x27, insn
->src(2));
1380 case FILE_MEMORY_CONST
:
1381 emitInsn(0x53a00000);
1382 emitGPR (0x27, insn
->src(1));
1383 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1386 assert(!"bad src2 file");
1390 emitCond4(0x30, cc
);
1392 emitGPR (0x08, insn
->src(0));
1393 emitGPR (0x00, insn
->def(0));
1397 CodeEmitterGM107::emitFSET()
1399 const CmpInstruction
*insn
= this->insn
->asCmp();
1401 switch (insn
->src(1).getFile()) {
1403 emitInsn(0x58000000);
1404 emitGPR (0x14, insn
->src(1));
1406 case FILE_MEMORY_CONST
:
1407 emitInsn(0x48000000);
1408 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1410 case FILE_IMMEDIATE
:
1411 emitInsn(0x30000000);
1412 emitIMMD(0x14, 19, insn
->src(1));
1415 assert(!"bad src1 file");
1419 if (insn
->op
!= OP_SET
) {
1421 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1422 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1423 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1425 assert(!"invalid set op");
1428 emitPRED(0x27, insn
->src(2));
1434 emitABS (0x36, insn
->src(0));
1435 emitNEG (0x35, insn
->src(1));
1436 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1437 emitCond4(0x30, insn
->setCond
);
1439 emitABS (0x2c, insn
->src(1));
1440 emitNEG (0x2b, insn
->src(0));
1441 emitGPR (0x08, insn
->src(0));
1442 emitGPR (0x00, insn
->def(0));
1446 CodeEmitterGM107::emitFSETP()
1448 const CmpInstruction
*insn
= this->insn
->asCmp();
1450 switch (insn
->src(1).getFile()) {
1452 emitInsn(0x5bb00000);
1453 emitGPR (0x14, insn
->src(1));
1455 case FILE_MEMORY_CONST
:
1456 emitInsn(0x4bb00000);
1457 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1459 case FILE_IMMEDIATE
:
1460 emitInsn(0x36b00000);
1461 emitIMMD(0x14, 19, insn
->src(1));
1464 assert(!"bad src1 file");
1468 if (insn
->op
!= OP_SET
) {
1470 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1471 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1472 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1474 assert(!"invalid set op");
1477 emitPRED(0x27, insn
->src(2));
1482 emitCond4(0x30, insn
->setCond
);
1484 emitABS (0x2c, insn
->src(1));
1485 emitNEG (0x2b, insn
->src(0));
1486 emitGPR (0x08, insn
->src(0));
1487 emitABS (0x07, insn
->src(0));
1488 emitNEG (0x06, insn
->src(1));
1489 emitPRED (0x03, insn
->def(0));
1490 if (insn
->defExists(1))
1491 emitPRED(0x00, insn
->def(1));
1497 CodeEmitterGM107::emitFSWZADD()
1499 emitInsn (0x50f80000);
1503 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1504 emitField(0x1c, 8, insn
->subOp
);
1505 emitGPR (0x14, insn
->src(1));
1506 emitGPR (0x08, insn
->src(0));
1507 emitGPR (0x00, insn
->def(0));
1510 /*******************************************************************************
1512 ******************************************************************************/
1515 CodeEmitterGM107::emitLOP()
1520 case OP_AND
: lop
= 0; break;
1521 case OP_OR
: lop
= 1; break;
1522 case OP_XOR
: lop
= 2; break;
1524 assert(!"invalid lop");
1528 if (!longIMMD(insn
->src(1))) {
1529 switch (insn
->src(1).getFile()) {
1531 emitInsn(0x5c400000);
1532 emitGPR (0x14, insn
->src(1));
1534 case FILE_MEMORY_CONST
:
1535 emitInsn(0x4c400000);
1536 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1538 case FILE_IMMEDIATE
:
1539 emitInsn(0x38400000);
1540 emitIMMD(0x14, 19, insn
->src(1));
1543 assert(!"bad src1 file");
1547 emitField(0x29, 2, lop
);
1548 emitINV (0x28, insn
->src(1));
1549 emitINV (0x27, insn
->src(0));
1551 emitInsn (0x04000000);
1552 emitINV (0x38, insn
->src(1));
1553 emitINV (0x37, insn
->src(0));
1554 emitField(0x35, 2, lop
);
1555 emitIMMD (0x14, 32, insn
->src(1));
1558 emitGPR (0x08, insn
->src(0));
1559 emitGPR (0x00, insn
->def(0));
1562 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1564 CodeEmitterGM107::emitNOT()
1566 if (!longIMMD(insn
->src(0))) {
1567 switch (insn
->src(0).getFile()) {
1569 emitInsn(0x5c400700);
1570 emitGPR (0x14, insn
->src(0));
1572 case FILE_MEMORY_CONST
:
1573 emitInsn(0x4c400700);
1574 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1576 case FILE_IMMEDIATE
:
1577 emitInsn(0x38400700);
1578 emitIMMD(0x14, 19, insn
->src(0));
1581 assert(!"bad src1 file");
1586 emitInsn (0x05600000);
1587 emitIMMD (0x14, 32, insn
->src(1));
1591 emitGPR(0x00, insn
->def(0));
1595 CodeEmitterGM107::emitIADD()
1597 if (!longIMMD(insn
->src(1))) {
1598 switch (insn
->src(1).getFile()) {
1600 emitInsn(0x5c100000);
1601 emitGPR (0x14, insn
->src(1));
1603 case FILE_MEMORY_CONST
:
1604 emitInsn(0x4c100000);
1605 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1607 case FILE_IMMEDIATE
:
1608 emitInsn(0x38100000);
1609 emitIMMD(0x14, 19, insn
->src(1));
1612 assert(!"bad src1 file");
1616 emitNEG(0x31, insn
->src(0));
1617 emitNEG(0x30, insn
->src(1));
1620 emitInsn(0x1c000000);
1623 emitIMMD(0x14, 32, insn
->src(1));
1626 if (insn
->op
== OP_SUB
)
1627 code
[1] ^= 0x00010000;
1629 emitGPR(0x08, insn
->src(0));
1630 emitGPR(0x00, insn
->def(0));
1634 CodeEmitterGM107::emitIMUL()
1636 if (!longIMMD(insn
->src(1))) {
1637 switch (insn
->src(1).getFile()) {
1639 emitInsn(0x5c380000);
1640 emitGPR (0x14, insn
->src(1));
1642 case FILE_MEMORY_CONST
:
1643 emitInsn(0x4c380000);
1644 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1646 case FILE_IMMEDIATE
:
1647 emitInsn(0x38380000);
1648 emitIMMD(0x14, 19, insn
->src(1));
1651 assert(!"bad src1 file");
1655 emitField(0x29, 1, isSignedType(insn
->sType
));
1656 emitField(0x28, 1, isSignedType(insn
->dType
));
1657 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1659 emitInsn (0x1f000000);
1660 emitField(0x37, 1, isSignedType(insn
->sType
));
1661 emitField(0x36, 1, isSignedType(insn
->dType
));
1662 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1664 emitIMMD (0x14, 32, insn
->src(1));
1667 emitGPR(0x08, insn
->src(0));
1668 emitGPR(0x00, insn
->def(0));
1672 CodeEmitterGM107::emitIMAD()
1674 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1675 switch(insn
->src(2).getFile()) {
1677 switch (insn
->src(1).getFile()) {
1679 emitInsn(0x5a000000);
1680 emitGPR (0x14, insn
->src(1));
1682 case FILE_MEMORY_CONST
:
1683 emitInsn(0x4a000000);
1684 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1686 case FILE_IMMEDIATE
:
1687 emitInsn(0x34000000);
1688 emitIMMD(0x14, 19, insn
->src(1));
1691 assert(!"bad src1 file");
1694 emitGPR (0x27, insn
->src(2));
1696 case FILE_MEMORY_CONST
:
1697 emitInsn(0x52000000);
1698 emitGPR (0x27, insn
->src(1));
1699 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1702 assert(!"bad src2 file");
1706 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1707 emitField(0x35, 1, isSignedType(insn
->sType
));
1708 emitNEG (0x34, insn
->src(2));
1709 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1712 emitField(0x30, 1, isSignedType(insn
->dType
));
1714 emitGPR (0x08, insn
->src(0));
1715 emitGPR (0x00, insn
->def(0));
1719 CodeEmitterGM107::emitIMNMX()
1721 switch (insn
->src(1).getFile()) {
1723 emitInsn(0x5c200000);
1724 emitGPR (0x14, insn
->src(1));
1726 case FILE_MEMORY_CONST
:
1727 emitInsn(0x4c200000);
1728 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1730 case FILE_IMMEDIATE
:
1731 emitInsn(0x38200000);
1732 emitIMMD(0x14, 19, insn
->src(1));
1735 assert(!"bad src1 file");
1739 emitField(0x30, 1, isSignedType(insn
->dType
));
1741 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1743 emitGPR (0x08, insn
->src(0));
1744 emitGPR (0x00, insn
->def(0));
1748 CodeEmitterGM107::emitICMP()
1750 const CmpInstruction
*insn
= this->insn
->asCmp();
1751 CondCode cc
= insn
->setCond
;
1753 if (insn
->src(2).mod
.neg())
1754 cc
= reverseCondCode(cc
);
1756 switch(insn
->src(2).getFile()) {
1758 switch (insn
->src(1).getFile()) {
1760 emitInsn(0x5b400000);
1761 emitGPR (0x14, insn
->src(1));
1763 case FILE_MEMORY_CONST
:
1764 emitInsn(0x4b400000);
1765 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1767 case FILE_IMMEDIATE
:
1768 emitInsn(0x36400000);
1769 emitIMMD(0x14, 19, insn
->src(1));
1772 assert(!"bad src1 file");
1775 emitGPR (0x27, insn
->src(2));
1777 case FILE_MEMORY_CONST
:
1778 emitInsn(0x53400000);
1779 emitGPR (0x27, insn
->src(1));
1780 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1783 assert(!"bad src2 file");
1787 emitCond3(0x31, cc
);
1788 emitField(0x30, 1, isSignedType(insn
->sType
));
1789 emitGPR (0x08, insn
->src(0));
1790 emitGPR (0x00, insn
->def(0));
1794 CodeEmitterGM107::emitISET()
1796 const CmpInstruction
*insn
= this->insn
->asCmp();
1798 switch (insn
->src(1).getFile()) {
1800 emitInsn(0x5b500000);
1801 emitGPR (0x14, insn
->src(1));
1803 case FILE_MEMORY_CONST
:
1804 emitInsn(0x4b500000);
1805 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1807 case FILE_IMMEDIATE
:
1808 emitInsn(0x36500000);
1809 emitIMMD(0x14, 19, insn
->src(1));
1812 assert(!"bad src1 file");
1816 if (insn
->op
!= OP_SET
) {
1818 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1819 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1820 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1822 assert(!"invalid set op");
1825 emitPRED(0x27, insn
->src(2));
1830 emitCond3(0x31, insn
->setCond
);
1831 emitField(0x30, 1, isSignedType(insn
->sType
));
1833 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1835 emitGPR (0x08, insn
->src(0));
1836 emitGPR (0x00, insn
->def(0));
1840 CodeEmitterGM107::emitISETP()
1842 const CmpInstruction
*insn
= this->insn
->asCmp();
1844 switch (insn
->src(1).getFile()) {
1846 emitInsn(0x5b600000);
1847 emitGPR (0x14, insn
->src(1));
1849 case FILE_MEMORY_CONST
:
1850 emitInsn(0x4b600000);
1851 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1853 case FILE_IMMEDIATE
:
1854 emitInsn(0x36600000);
1855 emitIMMD(0x14, 19, insn
->src(1));
1858 assert(!"bad src1 file");
1862 if (insn
->op
!= OP_SET
) {
1864 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1865 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1866 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1868 assert(!"invalid set op");
1871 emitPRED(0x27, insn
->src(2));
1876 emitCond3(0x31, insn
->setCond
);
1877 emitField(0x30, 1, isSignedType(insn
->sType
));
1879 emitGPR (0x08, insn
->src(0));
1880 emitPRED (0x03, insn
->def(0));
1881 if (insn
->defExists(1))
1882 emitPRED(0x00, insn
->def(1));
1888 CodeEmitterGM107::emitSHL()
1890 switch (insn
->src(1).getFile()) {
1892 emitInsn(0x5c480000);
1893 emitGPR (0x14, insn
->src(1));
1895 case FILE_MEMORY_CONST
:
1896 emitInsn(0x4c480000);
1897 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1899 case FILE_IMMEDIATE
:
1900 emitInsn(0x38480000);
1901 emitIMMD(0x14, 19, insn
->src(1));
1904 assert(!"bad src1 file");
1910 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1911 emitGPR (0x08, insn
->src(0));
1912 emitGPR (0x00, insn
->def(0));
1916 CodeEmitterGM107::emitSHR()
1918 switch (insn
->src(1).getFile()) {
1920 emitInsn(0x5c280000);
1921 emitGPR (0x14, insn
->src(1));
1923 case FILE_MEMORY_CONST
:
1924 emitInsn(0x4c280000);
1925 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1927 case FILE_IMMEDIATE
:
1928 emitInsn(0x38280000);
1929 emitIMMD(0x14, 19, insn
->src(1));
1932 assert(!"bad src1 file");
1936 emitField(0x30, 1, isSignedType(insn
->dType
));
1939 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1940 emitGPR (0x08, insn
->src(0));
1941 emitGPR (0x00, insn
->def(0));
1945 CodeEmitterGM107::emitPOPC()
1947 switch (insn
->src(0).getFile()) {
1949 emitInsn(0x5c080000);
1950 emitGPR (0x14, insn
->src(0));
1952 case FILE_MEMORY_CONST
:
1953 emitInsn(0x4c080000);
1954 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1956 case FILE_IMMEDIATE
:
1957 emitInsn(0x38080000);
1958 emitIMMD(0x14, 19, insn
->src(0));
1961 assert(!"bad src1 file");
1965 emitINV(0x28, insn
->src(0));
1966 emitGPR(0x00, insn
->def(0));
1970 CodeEmitterGM107::emitBFI()
1972 switch(insn
->src(2).getFile()) {
1974 switch (insn
->src(1).getFile()) {
1976 emitInsn(0x5bf00000);
1977 emitGPR (0x14, insn
->src(1));
1979 case FILE_MEMORY_CONST
:
1980 emitInsn(0x4bf00000);
1981 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1983 case FILE_IMMEDIATE
:
1984 emitInsn(0x36f00000);
1985 emitIMMD(0x14, 19, insn
->src(1));
1988 assert(!"bad src1 file");
1991 emitGPR (0x27, insn
->src(2));
1993 case FILE_MEMORY_CONST
:
1994 emitInsn(0x53f00000);
1995 emitGPR (0x27, insn
->src(1));
1996 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1999 assert(!"bad src2 file");
2004 emitGPR (0x08, insn
->src(0));
2005 emitGPR (0x00, insn
->def(0));
2009 CodeEmitterGM107::emitBFE()
2011 switch (insn
->src(1).getFile()) {
2013 emitInsn(0x5c000000);
2014 emitGPR (0x14, insn
->src(1));
2016 case FILE_MEMORY_CONST
:
2017 emitInsn(0x4c000000);
2018 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2020 case FILE_IMMEDIATE
:
2021 emitInsn(0x38000000);
2022 emitIMMD(0x14, 19, insn
->src(1));
2025 assert(!"bad src1 file");
2029 emitField(0x30, 1, isSignedType(insn
->dType
));
2031 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2032 emitGPR (0x08, insn
->src(0));
2033 emitGPR (0x00, insn
->def(0));
2037 CodeEmitterGM107::emitFLO()
2039 switch (insn
->src(0).getFile()) {
2041 emitInsn(0x5c300000);
2042 emitGPR (0x14, insn
->src(0));
2044 case FILE_MEMORY_CONST
:
2045 emitInsn(0x4c300000);
2046 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2048 case FILE_IMMEDIATE
:
2049 emitInsn(0x38300000);
2050 emitIMMD(0x14, 19, insn
->src(0));
2053 assert(!"bad src1 file");
2057 emitField(0x30, 1, isSignedType(insn
->dType
));
2059 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2060 emitINV (0x28, insn
->src(0));
2061 emitGPR (0x00, insn
->def(0));
2064 /*******************************************************************************
2066 ******************************************************************************/
2069 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2073 switch (typeSizeof(type
)) {
2074 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2075 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2076 case 4: data
= 4; break;
2077 case 8: data
= 5; break;
2078 case 16: data
= 6; break;
2080 assert(!"bad type");
2084 emitField(pos
, 3, data
);
2088 CodeEmitterGM107::emitLDSTc(int pos
)
2092 switch (insn
->cache
) {
2093 case CACHE_CA
: mode
= 0; break;
2094 case CACHE_CG
: mode
= 1; break;
2095 case CACHE_CS
: mode
= 2; break;
2096 case CACHE_CV
: mode
= 3; break;
2098 assert(!"invalid caching mode");
2102 emitField(pos
, 2, mode
);
2106 CodeEmitterGM107::emitLDC()
2108 emitInsn (0xef900000);
2109 emitLDSTs(0x30, insn
->dType
);
2110 emitField(0x2c, 2, insn
->subOp
);
2111 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2112 emitGPR (0x00, insn
->def(0));
2116 CodeEmitterGM107::emitLDL()
2118 emitInsn (0xef400000);
2119 emitLDSTs(0x30, insn
->dType
);
2121 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2122 emitGPR (0x00, insn
->def(0));
2126 CodeEmitterGM107::emitLDS()
2128 emitInsn (0xef480000);
2129 emitLDSTs(0x30, insn
->dType
);
2130 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2131 emitGPR (0x00, insn
->def(0));
2135 CodeEmitterGM107::emitLD()
2137 emitInsn (0x80000000);
2140 emitLDSTs(0x35, insn
->dType
);
2141 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2142 emitGPR (0x00, insn
->def(0));
2146 CodeEmitterGM107::emitSTL()
2148 emitInsn (0xef500000);
2149 emitLDSTs(0x30, insn
->dType
);
2151 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2152 emitGPR (0x00, insn
->src(1));
2156 CodeEmitterGM107::emitSTS()
2158 emitInsn (0xef580000);
2159 emitLDSTs(0x30, insn
->dType
);
2160 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2161 emitGPR (0x00, insn
->src(1));
2165 CodeEmitterGM107::emitST()
2167 emitInsn (0xa0000000);
2170 emitLDSTs(0x35, insn
->dType
);
2171 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2172 emitGPR (0x00, insn
->src(1));
2176 CodeEmitterGM107::emitALD()
2178 emitInsn (0xefd80000);
2179 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2180 emitGPR (0x27, insn
->src(0).getIndirect(1));
2183 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2184 emitGPR (0x00, insn
->def(0));
2188 CodeEmitterGM107::emitAST()
2190 emitInsn (0xeff00000);
2191 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2192 emitGPR (0x27, insn
->src(0).getIndirect(1));
2194 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2195 emitGPR (0x00, insn
->src(1));
2199 CodeEmitterGM107::emitISBERD()
2201 emitInsn(0xefd00000);
2202 emitGPR (0x08, insn
->src(0));
2203 emitGPR (0x00, insn
->def(0));
2207 CodeEmitterGM107::emitIPA()
2209 int ipam
= 0, ipas
= 0;
2211 switch (insn
->getInterpMode()) {
2212 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2213 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2214 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2215 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2217 assert(!"invalid ipa mode");
2221 switch (insn
->getSampleMode()) {
2222 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2223 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2224 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2226 assert(!"invalid ipa sample mode");
2230 emitInsn (0xe0000000);
2231 emitField(0x36, 2, ipam
);
2232 emitField(0x34, 2, ipas
);
2234 emitField(0x2f, 3, 7);
2235 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2236 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2237 code
[1] |= 0x00000040; /* .idx */
2238 emitGPR(0x00, insn
->def(0));
2240 if (insn
->op
== OP_PINTERP
) {
2241 emitGPR(0x14, insn
->src(1));
2242 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2243 emitGPR(0x27, insn
->src(2));
2245 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2246 emitGPR(0x27, insn
->src(1));
2250 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2254 /*******************************************************************************
2256 ******************************************************************************/
2259 CodeEmitterGM107::emitPIXLD()
2261 emitInsn (0xefe80000);
2263 emitField(0x1f, 3, insn
->subOp
);
2264 emitGPR (0x08, insn
->src(0));
2265 emitGPR (0x00, insn
->def(0));
2268 /*******************************************************************************
2270 ******************************************************************************/
2273 CodeEmitterGM107::emitTEXs(int pos
)
2275 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2276 if (insn
->srcExists(src1
))
2277 emitGPR(pos
, insn
->src(src1
));
2283 CodeEmitterGM107::emitTEX()
2285 const TexInstruction
*insn
= this->insn
->asTex();
2288 if (!insn
->tex
.levelZero
) {
2290 case OP_TEX
: lodm
= 0; break;
2291 case OP_TXB
: lodm
= 2; break;
2292 case OP_TXL
: lodm
= 3; break;
2294 assert(!"invalid tex op");
2301 if (insn
->tex
.rIndirectSrc
>= 0) {
2302 emitInsn (0xdeb80000);
2303 emitField(0x35, 2, lodm
);
2304 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2306 emitInsn (0xc0380000);
2307 emitField(0x37, 2, lodm
);
2308 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2309 emitField(0x24, 13, insn
->tex
.r
);
2312 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2313 emitField(0x31, 1, insn
->tex
.liveOnly
);
2314 emitField(0x23, 1, insn
->tex
.derivAll
);
2315 emitField(0x1f, 4, insn
->tex
.mask
);
2316 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2317 insn
->tex
.target
.getDim() - 1);
2318 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2320 emitGPR (0x08, insn
->src(0));
2321 emitGPR (0x00, insn
->def(0));
2325 CodeEmitterGM107::emitTLD()
2327 const TexInstruction
*insn
= this->insn
->asTex();
2329 if (insn
->tex
.rIndirectSrc
>= 0) {
2330 emitInsn (0xdd380000);
2332 emitInsn (0xdc380000);
2333 emitField(0x24, 13, insn
->tex
.r
);
2336 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2337 emitField(0x32, 1, insn
->tex
.target
.isMS());
2338 emitField(0x31, 1, insn
->tex
.liveOnly
);
2339 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2340 emitField(0x1f, 4, insn
->tex
.mask
);
2341 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2342 insn
->tex
.target
.getDim() - 1);
2343 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2345 emitGPR (0x08, insn
->src(0));
2346 emitGPR (0x00, insn
->def(0));
2350 CodeEmitterGM107::emitTLD4()
2352 const TexInstruction
*insn
= this->insn
->asTex();
2354 if (insn
->tex
.rIndirectSrc
>= 0) {
2355 emitInsn (0xdef80000);
2356 emitField(0x26, 2, insn
->tex
.gatherComp
);
2357 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2358 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2360 emitInsn (0xc8380000);
2361 emitField(0x38, 2, insn
->tex
.gatherComp
);
2362 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2363 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2364 emitField(0x24, 13, insn
->tex
.r
);
2367 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2368 emitField(0x31, 1, insn
->tex
.liveOnly
);
2369 emitField(0x23, 1, insn
->tex
.derivAll
);
2370 emitField(0x1f, 4, insn
->tex
.mask
);
2371 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2372 insn
->tex
.target
.getDim() - 1);
2373 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2375 emitGPR (0x08, insn
->src(0));
2376 emitGPR (0x00, insn
->def(0));
2380 CodeEmitterGM107::emitTXD()
2382 const TexInstruction
*insn
= this->insn
->asTex();
2384 if (insn
->tex
.rIndirectSrc
>= 0) {
2385 emitInsn (0xde780000);
2387 emitInsn (0xde380000);
2388 emitField(0x24, 13, insn
->tex
.r
);
2391 emitField(0x31, 1, insn
->tex
.liveOnly
);
2392 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2393 emitField(0x1f, 4, insn
->tex
.mask
);
2394 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2395 insn
->tex
.target
.getDim() - 1);
2396 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2398 emitGPR (0x08, insn
->src(0));
2399 emitGPR (0x00, insn
->def(0));
2403 CodeEmitterGM107::emitTMML()
2405 const TexInstruction
*insn
= this->insn
->asTex();
2407 if (insn
->tex
.rIndirectSrc
>= 0) {
2408 emitInsn (0xdf600000);
2410 emitInsn (0xdf580000);
2411 emitField(0x24, 13, insn
->tex
.r
);
2414 emitField(0x31, 1, insn
->tex
.liveOnly
);
2415 emitField(0x23, 1, insn
->tex
.derivAll
);
2416 emitField(0x1f, 4, insn
->tex
.mask
);
2417 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2418 insn
->tex
.target
.getDim() - 1);
2419 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2421 emitGPR (0x08, insn
->src(0));
2422 emitGPR (0x00, insn
->def(0));
2426 CodeEmitterGM107::emitTXQ()
2428 const TexInstruction
*insn
= this->insn
->asTex();
2431 switch (insn
->tex
.query
) {
2432 case TXQ_DIMS
: type
= 0x01; break;
2433 case TXQ_TYPE
: type
= 0x02; break;
2434 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2435 case TXQ_FILTER
: type
= 0x10; break;
2436 case TXQ_LOD
: type
= 0x12; break;
2437 case TXQ_WRAP
: type
= 0x14; break;
2438 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2440 assert(!"invalid txq query");
2444 if (insn
->tex
.rIndirectSrc
>= 0) {
2445 emitInsn (0xdf500000);
2447 emitInsn (0xdf480000);
2448 emitField(0x24, 13, insn
->tex
.r
);
2451 emitField(0x31, 1, insn
->tex
.liveOnly
);
2452 emitField(0x1f, 4, insn
->tex
.mask
);
2453 emitField(0x16, 6, type
);
2454 emitGPR (0x08, insn
->src(0));
2455 emitGPR (0x00, insn
->def(0));
2459 CodeEmitterGM107::emitDEPBAR()
2461 emitInsn (0xf0f00000);
2462 emitField(0x1d, 1, 1); /* le */
2463 emitField(0x1a, 3, 5);
2464 emitField(0x14, 6, insn
->subOp
);
2465 emitField(0x00, 6, insn
->subOp
);
2468 /*******************************************************************************
2470 ******************************************************************************/
2473 CodeEmitterGM107::emitNOP()
2475 emitInsn(0x50b00000);
2479 CodeEmitterGM107::emitKIL()
2481 emitInsn (0xe3300000);
2482 emitCond5(0x00, CC_TR
);
2486 CodeEmitterGM107::emitOUT()
2488 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2489 const int emit
= insn
->op
== OP_EMIT
;
2491 switch (insn
->src(1).getFile()) {
2493 emitInsn(0xfbe00000);
2494 emitGPR (0x14, insn
->src(1));
2496 case FILE_IMMEDIATE
:
2497 emitInsn(0xf6e00000);
2498 emitIMMD(0x14, 19, insn
->src(1));
2500 case FILE_MEMORY_CONST
:
2501 emitInsn(0xebe00000);
2502 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2505 assert(!"bad src1 file");
2509 emitField(0x27, 2, (cut
<< 1) | emit
);
2510 emitGPR (0x08, insn
->src(0));
2511 emitGPR (0x00, insn
->def(0));
2514 /*******************************************************************************
2515 * assembler front-end
2516 ******************************************************************************/
2519 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2521 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2526 if (insn
->encSize
!= 8) {
2527 ERROR("skipping undecodable instruction: "); insn
->print();
2530 if (codeSize
+ size
> codeSizeLimit
) {
2531 ERROR("code emitter output buffer too small\n");
2535 if (writeIssueDelays
) {
2536 int n
= ((codeSize
& 0x1f) / 8) - 1;
2539 data
[0] = 0x00000000;
2540 data
[1] = 0x00000000;
2546 emitField(data
, n
* 21, 21, insn
->sched
);
2590 if (insn
->def(0).getFile() == FILE_GPR
&&
2591 insn
->src(0).getFile() != FILE_PREDICATE
)
2606 if (isFloatType(insn
->dType
)) {
2607 if (isFloatType(insn
->sType
))
2612 if (isFloatType(insn
->sType
))
2623 if (isFloatType(insn
->dType
)) {
2624 if (insn
->dType
== TYPE_F64
)
2633 if (isFloatType(insn
->dType
)) {
2634 if (insn
->dType
== TYPE_F64
)
2644 if (isFloatType(insn
->dType
)) {
2645 if (insn
->dType
== TYPE_F64
)
2655 if (isFloatType(insn
->dType
)) {
2656 if (insn
->dType
== TYPE_F64
)
2683 if (isFloatType(insn
->dType
))
2692 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2693 if (isFloatType(insn
->sType
))
2694 if (insn
->sType
== TYPE_F64
)
2701 if (isFloatType(insn
->sType
))
2702 if (insn
->sType
== TYPE_F64
)
2731 switch (insn
->src(0).getFile()) {
2732 case FILE_MEMORY_CONST
: emitLDC(); break;
2733 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2734 case FILE_MEMORY_SHARED
: emitLDS(); break;
2735 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2737 assert(!"invalid load");
2743 switch (insn
->src(0).getFile()) {
2744 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2745 case FILE_MEMORY_SHARED
: emitSTS(); break;
2746 case FILE_MEMORY_GLOBAL
: emitST(); break;
2748 assert(!"invalid load");
2806 assert(!"invalid opcode");
2822 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2827 /*******************************************************************************
2828 * sched data calculator
2829 ******************************************************************************/
2831 class SchedDataCalculatorGM107
: public Pass
2834 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2837 bool visit(BasicBlock
*bb
);
2841 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2843 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2845 insn
->sched
= 0x7e0;
2851 /*******************************************************************************
2853 ******************************************************************************/
2856 CodeEmitterGM107::prepareEmission(Function
*func
)
2858 SchedDataCalculatorGM107
sched(targ
);
2859 CodeEmitter::prepareEmission(func
);
2860 sched
.run(func
, true, true);
2863 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
2865 return (size
+ 23) / 24;
2869 CodeEmitterGM107::prepareEmission(Program
*prog
)
2871 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
2872 !fi
.end(); fi
.next()) {
2873 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
2874 func
->binPos
= prog
->binSize
;
2875 prepareEmission(func
);
2877 // adjust sizes & positions for schedulding info:
2878 if (prog
->getTarget()->hasSWSched
) {
2879 uint32_t adjPos
= func
->binPos
;
2880 BasicBlock
*bb
= NULL
;
2881 for (int i
= 0; i
< func
->bbCount
; ++i
) {
2882 bb
= func
->bbArray
[i
];
2883 int32_t adjSize
= bb
->binSize
;
2885 adjSize
-= 32 - adjPos
% 32;
2889 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
2890 bb
->binPos
= adjPos
;
2891 bb
->binSize
= adjSize
;
2895 func
->binSize
= adjPos
- func
->binPos
;
2898 prog
->binSize
+= func
->binSize
;
2902 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
2903 : CodeEmitter(target
),
2905 writeIssueDelays(target
->hasSWSched
)
2908 codeSize
= codeSizeLimit
= 0;
2913 TargetGM107::createCodeEmitterGM107(Program::Type type
)
2915 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
2916 emit
->setProgramType(type
);
2920 } // namespace nv50_ir