2 * Copyright 2014 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
25 #include "codegen/nv50_ir_target_gm107.h"
29 class CodeEmitterGM107
: public CodeEmitter
32 CodeEmitterGM107(const TargetGM107
*);
34 virtual bool emitInstruction(Instruction
*);
35 virtual uint32_t getMinEncodingSize(const Instruction
*) const;
37 virtual void prepareEmission(Program
*);
38 virtual void prepareEmission(Function
*);
40 inline void setProgramType(Program::Type pType
) { progType
= pType
; }
43 const TargetGM107
*targGM107
;
45 Program::Type progType
;
47 const Instruction
*insn
;
48 const bool writeIssueDelays
;
52 inline void emitField(uint32_t *, int, int, uint32_t);
53 inline void emitField(int b
, int s
, uint32_t v
) { emitField(code
, b
, s
, v
); }
55 inline void emitInsn(uint32_t, bool);
56 inline void emitInsn(uint32_t o
) { emitInsn(o
, true); }
57 inline void emitPred();
58 inline void emitGPR(int, const Value
*);
59 inline void emitGPR(int pos
) {
60 emitGPR(pos
, (const Value
*)NULL
);
62 inline void emitGPR(int pos
, const ValueRef
&ref
) {
63 emitGPR(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
65 inline void emitGPR(int pos
, const ValueRef
*ref
) {
66 emitGPR(pos
, ref
? ref
->rep() : (const Value
*)NULL
);
68 inline void emitGPR(int pos
, const ValueDef
&def
) {
69 emitGPR(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
71 inline void emitSYS(int, const Value
*);
72 inline void emitSYS(int pos
, const ValueRef
&ref
) {
73 emitSYS(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
75 inline void emitPRED(int, const Value
*);
76 inline void emitPRED(int pos
) {
77 emitPRED(pos
, (const Value
*)NULL
);
79 inline void emitPRED(int pos
, const ValueRef
&ref
) {
80 emitPRED(pos
, ref
.get() ? ref
.rep() : (const Value
*)NULL
);
82 inline void emitPRED(int pos
, const ValueDef
&def
) {
83 emitPRED(pos
, def
.get() ? def
.rep() : (const Value
*)NULL
);
85 inline void emitADDR(int, int, int, int, const ValueRef
&);
86 inline void emitCBUF(int, int, int, int, int, const ValueRef
&);
87 inline bool longIMMD(const ValueRef
&);
88 inline void emitIMMD(int, int, const ValueRef
&);
90 void emitCond3(int, CondCode
);
91 void emitCond4(int, CondCode
);
92 void emitCond5(int pos
, CondCode cc
) { emitCond4(pos
, cc
); }
93 inline void emitO(int);
94 inline void emitP(int);
95 inline void emitSAT(int);
96 inline void emitCC(int);
97 inline void emitX(int);
98 inline void emitABS(int, const ValueRef
&);
99 inline void emitNEG(int, const ValueRef
&);
100 inline void emitNEG2(int, const ValueRef
&, const ValueRef
&);
101 inline void emitFMZ(int, int);
102 inline void emitRND(int, RoundMode
, int);
103 inline void emitRND(int pos
) {
104 emitRND(pos
, insn
->rnd
, -1);
106 inline void emitPDIV(int);
107 inline void emitINV(int, const ValueRef
&);
165 void emitLDSTs(int, DataType
);
196 /*******************************************************************************
197 * general instruction layout/fields
198 ******************************************************************************/
201 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
204 uint32_t m
= ((1ULL << s
) - 1);
205 uint64_t d
= (uint64_t)(v
& m
) << b
;
206 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
213 CodeEmitterGM107::emitPred()
215 if (insn
->predSrc
>= 0) {
216 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
217 emitField(19, 1, insn
->cc
== CC_NOT_P
);
224 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
226 code
[0] = 0x00000000;
233 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
235 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
239 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
241 int id
= val
? val
->reg
.data
.id
: -1;
244 case SV_LANEID
: id
= 0x00; break;
245 case SV_VERTEX_COUNT
: id
= 0x10; break;
246 case SV_INVOCATION_ID
: id
= 0x11; break;
247 case SV_THREAD_KILL
: id
= 0x13; break;
248 case SV_INVOCATION_INFO
: id
= 0x1d; break;
250 assert(!"invalid system value");
255 emitField(pos
, 8, id
);
259 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
261 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
265 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
268 const Value
*v
= ref
.get();
269 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
271 emitGPR(gpr
, ref
.getIndirect(0));
272 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
276 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
279 const Value
*v
= ref
.get();
280 const Symbol
*s
= v
->asSym();
282 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
284 emitField(buf
, 5, v
->reg
.fileIndex
);
286 emitGPR(gpr
, ref
.getIndirect(0));
287 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
291 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
293 if (ref
.getFile() == FILE_IMMEDIATE
) {
294 const ImmediateValue
*imm
= ref
.get()->asImm();
295 if (isFloatType(insn
->sType
)) {
296 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
299 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
300 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
308 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
310 const ImmediateValue
*imm
= ref
.get()->asImm();
311 uint32_t val
= imm
->reg
.data
.u32
;
314 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
315 assert(!(val
& 0x00000fff));
317 } else if (insn
->sType
== TYPE_F64
) {
318 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
319 val
= imm
->reg
.data
.u64
>> 44;
321 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
322 emitField( 56, 1, (val
& 0x80000) >> 19);
323 emitField(pos
, len
, (val
& 0x7ffff));
325 emitField(pos
, len
, val
);
329 /*******************************************************************************
331 ******************************************************************************/
334 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
339 case CC_FL
: data
= 0x00; break;
341 case CC_LT
: data
= 0x01; break;
343 case CC_EQ
: data
= 0x02; break;
345 case CC_LE
: data
= 0x03; break;
347 case CC_GT
: data
= 0x04; break;
349 case CC_NE
: data
= 0x05; break;
351 case CC_GE
: data
= 0x06; break;
352 case CC_TR
: data
= 0x07; break;
354 assert(!"invalid cond3");
358 emitField(pos
, 3, data
);
362 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
367 case CC_FL
: data
= 0x00; break;
368 case CC_LT
: data
= 0x01; break;
369 case CC_EQ
: data
= 0x02; break;
370 case CC_LE
: data
= 0x03; break;
371 case CC_GT
: data
= 0x04; break;
372 case CC_NE
: data
= 0x05; break;
373 case CC_GE
: data
= 0x06; break;
374 // case CC_NUM: data = 0x07; break;
375 // case CC_NAN: data = 0x08; break;
376 case CC_LTU
: data
= 0x09; break;
377 case CC_EQU
: data
= 0x0a; break;
378 case CC_LEU
: data
= 0x0b; break;
379 case CC_GTU
: data
= 0x0c; break;
380 case CC_NEU
: data
= 0x0d; break;
381 case CC_GEU
: data
= 0x0e; break;
382 case CC_TR
: data
= 0x0f; break;
384 assert(!"invalid cond4");
388 emitField(pos
, 4, data
);
392 CodeEmitterGM107::emitO(int pos
)
394 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
398 CodeEmitterGM107::emitP(int pos
)
400 emitField(pos
, 1, insn
->perPatch
);
404 CodeEmitterGM107::emitSAT(int pos
)
406 emitField(pos
, 1, insn
->saturate
);
410 CodeEmitterGM107::emitCC(int pos
)
412 emitField(pos
, 1, insn
->defExists(1));
416 CodeEmitterGM107::emitX(int pos
)
418 emitField(pos
, 1, insn
->flagsSrc
>= 0);
422 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
424 emitField(pos
, 1, ref
.mod
.abs());
428 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
430 emitField(pos
, 1, ref
.mod
.neg());
434 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
436 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
440 CodeEmitterGM107::emitFMZ(int pos
, int len
)
442 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
446 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
450 case ROUND_NI
: ri
= 1;
451 case ROUND_N
: rm
= 0; break;
452 case ROUND_MI
: ri
= 1;
453 case ROUND_M
: rm
= 1; break;
454 case ROUND_PI
: ri
= 1;
455 case ROUND_P
: rm
= 2; break;
456 case ROUND_ZI
: ri
= 1;
457 case ROUND_Z
: rm
= 3; break;
459 assert(!"invalid round mode");
462 emitField(rip
, 1, ri
);
463 emitField(rmp
, 2, rm
);
467 CodeEmitterGM107::emitPDIV(int pos
)
469 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
470 if (insn
->postFactor
> 0)
471 emitField(pos
, 3, 7 - insn
->postFactor
);
473 emitField(pos
, 3, 0 - insn
->postFactor
);
477 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
479 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
482 /*******************************************************************************
484 ******************************************************************************/
487 CodeEmitterGM107::emitEXIT()
489 emitInsn (0xe3000000);
490 emitCond5(0x00, CC_TR
);
494 CodeEmitterGM107::emitBRA()
496 const FlowInstruction
*insn
= this->insn
->asFlow();
499 if (insn
->indirect
) {
501 emitInsn(0xe2000000); // JMX
503 emitInsn(0xe2500000); // BRX
507 emitInsn(0xe2100000); // JMP
509 emitInsn(0xe2400000); // BRA
510 emitField(0x07, 1, insn
->allWarp
);
513 emitField(0x06, 1, insn
->limit
);
514 emitCond5(0x00, CC_TR
);
516 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
517 int32_t pos
= insn
->target
.bb
->binPos
;
518 if (writeIssueDelays
&& !(pos
& 0x1f))
521 emitField(0x14, 24, pos
- (codeSize
+ 8));
523 emitField(0x14, 32, pos
);
525 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
526 emitField(0x05, 1, 1);
531 CodeEmitterGM107::emitCAL()
533 const FlowInstruction
*insn
= this->insn
->asFlow();
535 if (insn
->absolute
) {
536 emitInsn(0xe2200000, 0); // JCAL
538 emitInsn(0xe2600000, 0); // CAL
541 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
543 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
546 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
547 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
548 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
550 emitField(0x14, 32, insn
->target
.bb
->binPos
);
554 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
555 emitField(0x05, 1, 1);
560 CodeEmitterGM107::emitPCNT()
562 const FlowInstruction
*insn
= this->insn
->asFlow();
564 emitInsn(0xe2b00000, 0);
566 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
567 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
569 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
570 emitField(0x05, 1, 1);
575 CodeEmitterGM107::emitCONT()
577 emitInsn (0xe3500000);
578 emitCond5(0x00, CC_TR
);
582 CodeEmitterGM107::emitPBK()
584 const FlowInstruction
*insn
= this->insn
->asFlow();
586 emitInsn(0xe2a00000, 0);
588 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
589 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
591 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
592 emitField(0x05, 1, 1);
597 CodeEmitterGM107::emitBRK()
599 emitInsn (0xe3400000);
600 emitCond5(0x00, CC_TR
);
604 CodeEmitterGM107::emitPRET()
606 const FlowInstruction
*insn
= this->insn
->asFlow();
608 emitInsn(0xe2700000, 0);
610 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
611 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
613 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
614 emitField(0x05, 1, 1);
619 CodeEmitterGM107::emitRET()
621 emitInsn (0xe3200000);
622 emitCond5(0x00, CC_TR
);
626 CodeEmitterGM107::emitSSY()
628 const FlowInstruction
*insn
= this->insn
->asFlow();
630 emitInsn(0xe2900000, 0);
632 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
633 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
635 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
636 emitField(0x05, 1, 1);
641 CodeEmitterGM107::emitSYNC()
643 emitInsn (0xf0f80000);
644 emitCond5(0x00, CC_TR
);
648 CodeEmitterGM107::emitSAM()
650 emitInsn(0xe3700000, 0);
654 CodeEmitterGM107::emitRAM()
656 emitInsn(0xe3800000, 0);
659 /*******************************************************************************
661 ******************************************************************************/
663 /*******************************************************************************
664 * movement / conversion
665 ******************************************************************************/
668 CodeEmitterGM107::emitMOV()
670 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
671 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
672 switch (insn
->src(0).getFile()) {
674 emitInsn(0x5c980000);
675 emitGPR (0x14, insn
->src(0));
677 case FILE_MEMORY_CONST
:
678 emitInsn(0x4c980000);
679 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
682 emitInsn(0x38980000);
683 emitIMMD(0x14, 19, insn
->src(0));
686 assert(!"bad src file");
689 emitField(0x27, 4, insn
->lanes
);
691 emitInsn (0x01000000);
692 emitIMMD (0x14, 32, insn
->src(0));
693 emitField(0x0c, 4, insn
->lanes
);
696 emitGPR(0x00, insn
->def(0));
700 CodeEmitterGM107::emitS2R()
702 emitInsn(0xf0c80000);
703 emitSYS (0x14, insn
->src(0));
704 emitGPR (0x00, insn
->def(0));
708 CodeEmitterGM107::emitF2F()
710 RoundMode rnd
= insn
->rnd
;
713 case OP_FLOOR
: rnd
= ROUND_MI
; break;
714 case OP_CEIL
: rnd
= ROUND_PI
; break;
715 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
720 switch (insn
->src(0).getFile()) {
722 emitInsn(0x5ca80000);
723 emitGPR (0x14, insn
->src(0));
725 case FILE_MEMORY_CONST
:
726 emitInsn(0x4ca80000);
727 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
730 emitInsn(0x38a80000);
731 emitIMMD(0x14, 19, insn
->src(0));
734 assert(!"bad src0 file");
738 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
739 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
741 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
743 emitField(0x29, 1, insn
->subOp
);
744 emitRND (0x27, rnd
, 0x2a);
745 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
746 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
747 emitGPR (0x00, insn
->def(0));
751 CodeEmitterGM107::emitF2I()
753 RoundMode rnd
= insn
->rnd
;
756 case OP_FLOOR
: rnd
= ROUND_M
; break;
757 case OP_CEIL
: rnd
= ROUND_P
; break;
758 case OP_TRUNC
: rnd
= ROUND_Z
; break;
763 switch (insn
->src(0).getFile()) {
765 emitInsn(0x5cb00000);
766 emitGPR (0x14, insn
->src(0));
768 case FILE_MEMORY_CONST
:
769 emitInsn(0x4cb00000);
770 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
773 emitInsn(0x38b00000);
774 emitIMMD(0x14, 19, insn
->src(0));
777 assert(!"bad src0 file");
781 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
783 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
785 emitRND (0x27, rnd
, 0x2a);
786 emitField(0x0c, 1, isSignedType(insn
->dType
));
787 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
788 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
789 emitGPR (0x00, insn
->def(0));
793 CodeEmitterGM107::emitI2F()
795 RoundMode rnd
= insn
->rnd
;
798 case OP_FLOOR
: rnd
= ROUND_M
; break;
799 case OP_CEIL
: rnd
= ROUND_P
; break;
800 case OP_TRUNC
: rnd
= ROUND_Z
; break;
805 switch (insn
->src(0).getFile()) {
807 emitInsn(0x5cb80000);
808 emitGPR (0x14, insn
->src(0));
810 case FILE_MEMORY_CONST
:
811 emitInsn(0x4cb80000);
812 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
815 emitInsn(0x38b80000);
816 emitIMMD(0x14, 19, insn
->src(0));
819 assert(!"bad src0 file");
823 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
825 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
826 emitField(0x29, 2, insn
->subOp
);
827 emitRND (0x27, rnd
, -1);
828 emitField(0x0d, 1, isSignedType(insn
->sType
));
829 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
830 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
831 emitGPR (0x00, insn
->def(0));
835 CodeEmitterGM107::emitI2I()
837 switch (insn
->src(0).getFile()) {
839 emitInsn(0x5ce00000);
840 emitGPR (0x14, insn
->src(0));
842 case FILE_MEMORY_CONST
:
843 emitInsn(0x4ce00000);
844 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
847 emitInsn(0x38e00000);
848 emitIMMD(0x14, 19, insn
->src(0));
851 assert(!"bad src0 file");
856 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
858 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
859 emitField(0x29, 2, insn
->subOp
);
860 emitField(0x0d, 1, isSignedType(insn
->sType
));
861 emitField(0x0c, 1, isSignedType(insn
->dType
));
862 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
863 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
864 emitGPR (0x00, insn
->def(0));
868 CodeEmitterGM107::emitSHFL()
872 emitInsn (0xef100000);
874 switch (insn
->src(1).getFile()) {
876 emitGPR(0x14, insn
->src(1));
879 emitIMMD(0x14, 5, insn
->src(1));
883 assert(!"invalid src1 file");
887 /*XXX: what is this arg? hardcode immediate for now */
888 emitField(0x22, 13, 0x1c03);
892 emitField(0x1e, 2, insn
->subOp
);
893 emitField(0x1c, 2, type
);
894 emitGPR (0x08, insn
->src(0));
895 emitGPR (0x00, insn
->def(0));
898 /*******************************************************************************
900 ******************************************************************************/
903 CodeEmitterGM107::emitDADD()
905 switch (insn
->src(1).getFile()) {
907 emitInsn(0x5c700000);
908 emitGPR (0x14, insn
->src(1));
910 case FILE_MEMORY_CONST
:
911 emitInsn(0x4c700000);
912 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
915 emitInsn(0x38700000);
916 emitIMMD(0x14, 19, insn
->src(1));
919 assert(!"bad src1 file");
922 emitABS(0x31, insn
->src(1));
923 emitNEG(0x30, insn
->src(0));
925 emitABS(0x2e, insn
->src(0));
926 emitNEG(0x2d, insn
->src(1));
928 if (insn
->op
== OP_SUB
)
929 code
[1] ^= 0x00002000;
931 emitGPR(0x08, insn
->src(0));
932 emitGPR(0x00, insn
->def(0));
936 CodeEmitterGM107::emitDMUL()
938 switch (insn
->src(1).getFile()) {
940 emitInsn(0x5c800000);
941 emitGPR (0x14, insn
->src(1));
943 case FILE_MEMORY_CONST
:
944 emitInsn(0x4c800000);
945 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
948 emitInsn(0x38800000);
949 emitIMMD(0x14, 19, insn
->src(1));
952 assert(!"bad src1 file");
956 emitNEG2(0x30, insn
->src(0), insn
->src(1));
959 emitGPR (0x08, insn
->src(0));
960 emitGPR (0x00, insn
->def(0));
964 CodeEmitterGM107::emitDFMA()
966 switch(insn
->src(2).getFile()) {
968 switch (insn
->src(1).getFile()) {
970 emitInsn(0x5b700000);
971 emitGPR (0x14, insn
->src(1));
973 case FILE_MEMORY_CONST
:
974 emitInsn(0x4b700000);
975 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
978 emitInsn(0x36700000);
979 emitIMMD(0x14, 19, insn
->src(1));
982 assert(!"bad src1 file");
985 emitGPR (0x27, insn
->src(2));
987 case FILE_MEMORY_CONST
:
988 emitInsn(0x53700000);
989 emitGPR (0x27, insn
->src(1));
990 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
993 assert(!"bad src2 file");
998 emitNEG (0x31, insn
->src(2));
999 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1001 emitGPR (0x08, insn
->src(0));
1002 emitGPR (0x00, insn
->def(0));
1006 CodeEmitterGM107::emitDMNMX()
1008 switch (insn
->src(1).getFile()) {
1010 emitInsn(0x5c500000);
1011 emitGPR (0x14, insn
->src(1));
1013 case FILE_MEMORY_CONST
:
1014 emitInsn(0x4c500000);
1015 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1017 case FILE_IMMEDIATE
:
1018 emitInsn(0x38500000);
1019 emitIMMD(0x14, 19, insn
->src(1));
1022 assert(!"bad src1 file");
1026 emitABS (0x31, insn
->src(1));
1027 emitNEG (0x30, insn
->src(0));
1029 emitABS (0x2e, insn
->src(0));
1030 emitNEG (0x2d, insn
->src(1));
1031 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1033 emitGPR (0x08, insn
->src(0));
1034 emitGPR (0x00, insn
->def(0));
1038 CodeEmitterGM107::emitDSET()
1040 const CmpInstruction
*insn
= this->insn
->asCmp();
1042 switch (insn
->src(1).getFile()) {
1044 emitInsn(0x59000000);
1045 emitGPR (0x14, insn
->src(1));
1047 case FILE_MEMORY_CONST
:
1048 emitInsn(0x49000000);
1049 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1051 case FILE_IMMEDIATE
:
1052 emitInsn(0x32000000);
1053 emitIMMD(0x14, 19, insn
->src(1));
1056 assert(!"bad src1 file");
1060 if (insn
->op
!= OP_SET
) {
1062 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1063 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1064 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1066 assert(!"invalid set op");
1069 emitPRED(0x27, insn
->src(2));
1074 emitABS (0x36, insn
->src(0));
1075 emitNEG (0x35, insn
->src(1));
1076 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1077 emitCond4(0x30, insn
->setCond
);
1079 emitABS (0x2c, insn
->src(1));
1080 emitNEG (0x2b, insn
->src(0));
1081 emitGPR (0x08, insn
->src(0));
1082 emitGPR (0x00, insn
->def(0));
1086 CodeEmitterGM107::emitDSETP()
1088 const CmpInstruction
*insn
= this->insn
->asCmp();
1090 switch (insn
->src(1).getFile()) {
1092 emitInsn(0x5b800000);
1093 emitGPR (0x14, insn
->src(1));
1095 case FILE_MEMORY_CONST
:
1096 emitInsn(0x4b800000);
1097 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1099 case FILE_IMMEDIATE
:
1100 emitInsn(0x36800000);
1101 emitIMMD(0x14, 19, insn
->src(1));
1104 assert(!"bad src1 file");
1108 if (insn
->op
!= OP_SET
) {
1110 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1111 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1112 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1114 assert(!"invalid set op");
1117 emitPRED(0x27, insn
->src(2));
1122 emitCond4(0x30, insn
->setCond
);
1123 emitABS (0x2c, insn
->src(1));
1124 emitNEG (0x2b, insn
->src(0));
1125 emitGPR (0x08, insn
->src(0));
1126 emitABS (0x07, insn
->src(0));
1127 emitNEG (0x06, insn
->src(1));
1128 emitPRED (0x03, insn
->def(0));
1129 if (insn
->defExists(1))
1130 emitPRED(0x00, insn
->def(1));
1135 /*******************************************************************************
1137 ******************************************************************************/
1140 CodeEmitterGM107::emitFADD()
1142 if (!longIMMD(insn
->src(1))) {
1143 switch (insn
->src(1).getFile()) {
1145 emitInsn(0x5c580000);
1146 emitGPR (0x14, insn
->src(1));
1148 case FILE_MEMORY_CONST
:
1149 emitInsn(0x4c580000);
1150 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1152 case FILE_IMMEDIATE
:
1153 emitInsn(0x38580000);
1154 emitIMMD(0x14, 19, insn
->src(1));
1157 assert(!"bad src1 file");
1161 emitABS(0x31, insn
->src(1));
1162 emitNEG(0x30, insn
->src(0));
1164 emitABS(0x2e, insn
->src(0));
1165 emitNEG(0x2d, insn
->src(1));
1168 emitInsn(0x08000000);
1169 emitABS(0x39, insn
->src(1));
1170 emitNEG(0x38, insn
->src(0));
1172 emitABS(0x36, insn
->src(0));
1173 emitNEG(0x35, insn
->src(1));
1175 emitIMMD(0x14, 32, insn
->src(1));
1178 if (insn
->op
== OP_SUB
)
1179 code
[1] ^= 0x00002000;
1181 emitGPR(0x08, insn
->src(0));
1182 emitGPR(0x00, insn
->def(0));
1186 CodeEmitterGM107::emitFMUL()
1188 if (!longIMMD(insn
->src(1))) {
1189 switch (insn
->src(1).getFile()) {
1191 emitInsn(0x5c680000);
1192 emitGPR (0x14, insn
->src(1));
1194 case FILE_MEMORY_CONST
:
1195 emitInsn(0x4c680000);
1196 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1198 case FILE_IMMEDIATE
:
1199 emitInsn(0x38680000);
1200 emitIMMD(0x14, 19, insn
->src(1));
1203 assert(!"bad src1 file");
1207 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1213 emitInsn(0x1e000000);
1217 emitIMMD(0x14, 32, insn
->src(1));
1218 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1219 code
[1] ^= 0x00080000; /* flip immd sign bit */
1222 emitGPR(0x08, insn
->src(0));
1223 emitGPR(0x00, insn
->def(0));
1227 CodeEmitterGM107::emitFFMA()
1229 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1230 switch(insn
->src(2).getFile()) {
1232 switch (insn
->src(1).getFile()) {
1234 emitInsn(0x59800000);
1235 emitGPR (0x14, insn
->src(1));
1237 case FILE_MEMORY_CONST
:
1238 emitInsn(0x49800000);
1239 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1241 case FILE_IMMEDIATE
:
1242 emitInsn(0x32800000);
1243 emitIMMD(0x14, 19, insn
->src(1));
1246 assert(!"bad src1 file");
1249 emitGPR (0x27, insn
->src(2));
1251 case FILE_MEMORY_CONST
:
1252 emitInsn(0x51800000);
1253 emitGPR (0x27, insn
->src(1));
1254 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1257 assert(!"bad src2 file");
1262 emitNEG (0x31, insn
->src(2));
1263 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1267 emitGPR(0x08, insn
->src(0));
1268 emitGPR(0x00, insn
->def(0));
1272 CodeEmitterGM107::emitMUFU()
1277 case OP_COS
: mufu
= 0; break;
1278 case OP_SIN
: mufu
= 1; break;
1279 case OP_EX2
: mufu
= 2; break;
1280 case OP_LG2
: mufu
= 3; break;
1281 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1282 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1284 assert(!"invalid mufu");
1288 emitInsn (0x50800000);
1290 emitNEG (0x30, insn
->src(0));
1291 emitABS (0x2e, insn
->src(0));
1292 emitField(0x14, 3, mufu
);
1293 emitGPR (0x08, insn
->src(0));
1294 emitGPR (0x00, insn
->def(0));
1298 CodeEmitterGM107::emitFMNMX()
1300 switch (insn
->src(1).getFile()) {
1302 emitInsn(0x5c600000);
1303 emitGPR (0x14, insn
->src(1));
1305 case FILE_MEMORY_CONST
:
1306 emitInsn(0x4c600000);
1307 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1309 case FILE_IMMEDIATE
:
1310 emitInsn(0x38600000);
1311 emitIMMD(0x14, 19, insn
->src(1));
1314 assert(!"bad src1 file");
1318 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1321 emitABS(0x31, insn
->src(1));
1322 emitNEG(0x30, insn
->src(0));
1324 emitABS(0x2e, insn
->src(0));
1325 emitNEG(0x2d, insn
->src(1));
1327 emitGPR(0x08, insn
->src(0));
1328 emitGPR(0x00, insn
->def(0));
1332 CodeEmitterGM107::emitRRO()
1334 switch (insn
->src(0).getFile()) {
1336 emitInsn(0x5c900000);
1337 emitGPR (0x14, insn
->src(0));
1339 case FILE_MEMORY_CONST
:
1340 emitInsn(0x4c900000);
1341 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1343 case FILE_IMMEDIATE
:
1344 emitInsn(0x38900000);
1345 emitIMMD(0x14, 19, insn
->src(0));
1348 assert(!"bad src file");
1352 emitABS (0x31, insn
->src(0));
1353 emitNEG (0x2d, insn
->src(0));
1354 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1355 emitGPR (0x00, insn
->def(0));
1359 CodeEmitterGM107::emitFCMP()
1361 const CmpInstruction
*insn
= this->insn
->asCmp();
1362 CondCode cc
= insn
->setCond
;
1364 if (insn
->src(2).mod
.neg())
1365 cc
= reverseCondCode(cc
);
1367 switch(insn
->src(2).getFile()) {
1369 switch (insn
->src(1).getFile()) {
1371 emitInsn(0x5ba00000);
1372 emitGPR (0x14, insn
->src(1));
1374 case FILE_MEMORY_CONST
:
1375 emitInsn(0x4ba00000);
1376 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1378 case FILE_IMMEDIATE
:
1379 emitInsn(0x36a00000);
1380 emitIMMD(0x14, 19, insn
->src(1));
1383 assert(!"bad src1 file");
1386 emitGPR (0x27, insn
->src(2));
1388 case FILE_MEMORY_CONST
:
1389 emitInsn(0x53a00000);
1390 emitGPR (0x27, insn
->src(1));
1391 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1394 assert(!"bad src2 file");
1398 emitCond4(0x30, cc
);
1400 emitGPR (0x08, insn
->src(0));
1401 emitGPR (0x00, insn
->def(0));
1405 CodeEmitterGM107::emitFSET()
1407 const CmpInstruction
*insn
= this->insn
->asCmp();
1409 switch (insn
->src(1).getFile()) {
1411 emitInsn(0x58000000);
1412 emitGPR (0x14, insn
->src(1));
1414 case FILE_MEMORY_CONST
:
1415 emitInsn(0x48000000);
1416 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1418 case FILE_IMMEDIATE
:
1419 emitInsn(0x30000000);
1420 emitIMMD(0x14, 19, insn
->src(1));
1423 assert(!"bad src1 file");
1427 if (insn
->op
!= OP_SET
) {
1429 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1430 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1431 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1433 assert(!"invalid set op");
1436 emitPRED(0x27, insn
->src(2));
1442 emitABS (0x36, insn
->src(0));
1443 emitNEG (0x35, insn
->src(1));
1444 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1445 emitCond4(0x30, insn
->setCond
);
1447 emitABS (0x2c, insn
->src(1));
1448 emitNEG (0x2b, insn
->src(0));
1449 emitGPR (0x08, insn
->src(0));
1450 emitGPR (0x00, insn
->def(0));
1454 CodeEmitterGM107::emitFSETP()
1456 const CmpInstruction
*insn
= this->insn
->asCmp();
1458 switch (insn
->src(1).getFile()) {
1460 emitInsn(0x5bb00000);
1461 emitGPR (0x14, insn
->src(1));
1463 case FILE_MEMORY_CONST
:
1464 emitInsn(0x4bb00000);
1465 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1467 case FILE_IMMEDIATE
:
1468 emitInsn(0x36b00000);
1469 emitIMMD(0x14, 19, insn
->src(1));
1472 assert(!"bad src1 file");
1476 if (insn
->op
!= OP_SET
) {
1478 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1479 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1480 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1482 assert(!"invalid set op");
1485 emitPRED(0x27, insn
->src(2));
1490 emitCond4(0x30, insn
->setCond
);
1492 emitABS (0x2c, insn
->src(1));
1493 emitNEG (0x2b, insn
->src(0));
1494 emitGPR (0x08, insn
->src(0));
1495 emitABS (0x07, insn
->src(0));
1496 emitNEG (0x06, insn
->src(1));
1497 emitPRED (0x03, insn
->def(0));
1498 if (insn
->defExists(1))
1499 emitPRED(0x00, insn
->def(1));
1505 CodeEmitterGM107::emitFSWZADD()
1507 emitInsn (0x50f80000);
1511 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1512 emitField(0x1c, 8, insn
->subOp
);
1513 emitGPR (0x14, insn
->src(1));
1514 emitGPR (0x08, insn
->src(0));
1515 emitGPR (0x00, insn
->def(0));
1518 /*******************************************************************************
1520 ******************************************************************************/
1523 CodeEmitterGM107::emitLOP()
1528 case OP_AND
: lop
= 0; break;
1529 case OP_OR
: lop
= 1; break;
1530 case OP_XOR
: lop
= 2; break;
1532 assert(!"invalid lop");
1536 if (!longIMMD(insn
->src(1))) {
1537 switch (insn
->src(1).getFile()) {
1539 emitInsn(0x5c400000);
1540 emitGPR (0x14, insn
->src(1));
1542 case FILE_MEMORY_CONST
:
1543 emitInsn(0x4c400000);
1544 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1546 case FILE_IMMEDIATE
:
1547 emitInsn(0x38400000);
1548 emitIMMD(0x14, 19, insn
->src(1));
1551 assert(!"bad src1 file");
1555 emitField(0x29, 2, lop
);
1556 emitINV (0x28, insn
->src(1));
1557 emitINV (0x27, insn
->src(0));
1559 emitInsn (0x04000000);
1560 emitINV (0x38, insn
->src(1));
1561 emitINV (0x37, insn
->src(0));
1562 emitField(0x35, 2, lop
);
1563 emitIMMD (0x14, 32, insn
->src(1));
1566 emitGPR (0x08, insn
->src(0));
1567 emitGPR (0x00, insn
->def(0));
1570 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1572 CodeEmitterGM107::emitNOT()
1574 if (!longIMMD(insn
->src(0))) {
1575 switch (insn
->src(0).getFile()) {
1577 emitInsn(0x5c400700);
1578 emitGPR (0x14, insn
->src(0));
1580 case FILE_MEMORY_CONST
:
1581 emitInsn(0x4c400700);
1582 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1584 case FILE_IMMEDIATE
:
1585 emitInsn(0x38400700);
1586 emitIMMD(0x14, 19, insn
->src(0));
1589 assert(!"bad src1 file");
1594 emitInsn (0x05600000);
1595 emitIMMD (0x14, 32, insn
->src(1));
1599 emitGPR(0x00, insn
->def(0));
1603 CodeEmitterGM107::emitIADD()
1605 if (!longIMMD(insn
->src(1))) {
1606 switch (insn
->src(1).getFile()) {
1608 emitInsn(0x5c100000);
1609 emitGPR (0x14, insn
->src(1));
1611 case FILE_MEMORY_CONST
:
1612 emitInsn(0x4c100000);
1613 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1615 case FILE_IMMEDIATE
:
1616 emitInsn(0x38100000);
1617 emitIMMD(0x14, 19, insn
->src(1));
1620 assert(!"bad src1 file");
1624 emitNEG(0x31, insn
->src(0));
1625 emitNEG(0x30, insn
->src(1));
1628 emitInsn(0x1c000000);
1631 emitIMMD(0x14, 32, insn
->src(1));
1634 if (insn
->op
== OP_SUB
)
1635 code
[1] ^= 0x00010000;
1637 emitGPR(0x08, insn
->src(0));
1638 emitGPR(0x00, insn
->def(0));
1642 CodeEmitterGM107::emitIMUL()
1644 if (!longIMMD(insn
->src(1))) {
1645 switch (insn
->src(1).getFile()) {
1647 emitInsn(0x5c380000);
1648 emitGPR (0x14, insn
->src(1));
1650 case FILE_MEMORY_CONST
:
1651 emitInsn(0x4c380000);
1652 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1654 case FILE_IMMEDIATE
:
1655 emitInsn(0x38380000);
1656 emitIMMD(0x14, 19, insn
->src(1));
1659 assert(!"bad src1 file");
1663 emitField(0x29, 1, isSignedType(insn
->sType
));
1664 emitField(0x28, 1, isSignedType(insn
->dType
));
1665 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1667 emitInsn (0x1f000000);
1668 emitField(0x37, 1, isSignedType(insn
->sType
));
1669 emitField(0x36, 1, isSignedType(insn
->dType
));
1670 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1672 emitIMMD (0x14, 32, insn
->src(1));
1675 emitGPR(0x08, insn
->src(0));
1676 emitGPR(0x00, insn
->def(0));
1680 CodeEmitterGM107::emitIMAD()
1682 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1683 switch(insn
->src(2).getFile()) {
1685 switch (insn
->src(1).getFile()) {
1687 emitInsn(0x5a000000);
1688 emitGPR (0x14, insn
->src(1));
1690 case FILE_MEMORY_CONST
:
1691 emitInsn(0x4a000000);
1692 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1694 case FILE_IMMEDIATE
:
1695 emitInsn(0x34000000);
1696 emitIMMD(0x14, 19, insn
->src(1));
1699 assert(!"bad src1 file");
1702 emitGPR (0x27, insn
->src(2));
1704 case FILE_MEMORY_CONST
:
1705 emitInsn(0x52000000);
1706 emitGPR (0x27, insn
->src(1));
1707 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1710 assert(!"bad src2 file");
1714 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1715 emitField(0x35, 1, isSignedType(insn
->sType
));
1716 emitNEG (0x34, insn
->src(2));
1717 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1720 emitField(0x30, 1, isSignedType(insn
->dType
));
1722 emitGPR (0x08, insn
->src(0));
1723 emitGPR (0x00, insn
->def(0));
1727 CodeEmitterGM107::emitIMNMX()
1729 switch (insn
->src(1).getFile()) {
1731 emitInsn(0x5c200000);
1732 emitGPR (0x14, insn
->src(1));
1734 case FILE_MEMORY_CONST
:
1735 emitInsn(0x4c200000);
1736 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1738 case FILE_IMMEDIATE
:
1739 emitInsn(0x38200000);
1740 emitIMMD(0x14, 19, insn
->src(1));
1743 assert(!"bad src1 file");
1747 emitField(0x30, 1, isSignedType(insn
->dType
));
1749 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1751 emitGPR (0x08, insn
->src(0));
1752 emitGPR (0x00, insn
->def(0));
1756 CodeEmitterGM107::emitICMP()
1758 const CmpInstruction
*insn
= this->insn
->asCmp();
1759 CondCode cc
= insn
->setCond
;
1761 if (insn
->src(2).mod
.neg())
1762 cc
= reverseCondCode(cc
);
1764 switch(insn
->src(2).getFile()) {
1766 switch (insn
->src(1).getFile()) {
1768 emitInsn(0x5b400000);
1769 emitGPR (0x14, insn
->src(1));
1771 case FILE_MEMORY_CONST
:
1772 emitInsn(0x4b400000);
1773 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1775 case FILE_IMMEDIATE
:
1776 emitInsn(0x36400000);
1777 emitIMMD(0x14, 19, insn
->src(1));
1780 assert(!"bad src1 file");
1783 emitGPR (0x27, insn
->src(2));
1785 case FILE_MEMORY_CONST
:
1786 emitInsn(0x53400000);
1787 emitGPR (0x27, insn
->src(1));
1788 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1791 assert(!"bad src2 file");
1795 emitCond3(0x31, cc
);
1796 emitField(0x30, 1, isSignedType(insn
->sType
));
1797 emitGPR (0x08, insn
->src(0));
1798 emitGPR (0x00, insn
->def(0));
1802 CodeEmitterGM107::emitISET()
1804 const CmpInstruction
*insn
= this->insn
->asCmp();
1806 switch (insn
->src(1).getFile()) {
1808 emitInsn(0x5b500000);
1809 emitGPR (0x14, insn
->src(1));
1811 case FILE_MEMORY_CONST
:
1812 emitInsn(0x4b500000);
1813 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1815 case FILE_IMMEDIATE
:
1816 emitInsn(0x36500000);
1817 emitIMMD(0x14, 19, insn
->src(1));
1820 assert(!"bad src1 file");
1824 if (insn
->op
!= OP_SET
) {
1826 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1827 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1828 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1830 assert(!"invalid set op");
1833 emitPRED(0x27, insn
->src(2));
1838 emitCond3(0x31, insn
->setCond
);
1839 emitField(0x30, 1, isSignedType(insn
->sType
));
1841 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1843 emitGPR (0x08, insn
->src(0));
1844 emitGPR (0x00, insn
->def(0));
1848 CodeEmitterGM107::emitISETP()
1850 const CmpInstruction
*insn
= this->insn
->asCmp();
1852 switch (insn
->src(1).getFile()) {
1854 emitInsn(0x5b600000);
1855 emitGPR (0x14, insn
->src(1));
1857 case FILE_MEMORY_CONST
:
1858 emitInsn(0x4b600000);
1859 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1861 case FILE_IMMEDIATE
:
1862 emitInsn(0x36600000);
1863 emitIMMD(0x14, 19, insn
->src(1));
1866 assert(!"bad src1 file");
1870 if (insn
->op
!= OP_SET
) {
1872 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1873 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1874 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1876 assert(!"invalid set op");
1879 emitPRED(0x27, insn
->src(2));
1884 emitCond3(0x31, insn
->setCond
);
1885 emitField(0x30, 1, isSignedType(insn
->sType
));
1887 emitGPR (0x08, insn
->src(0));
1888 emitPRED (0x03, insn
->def(0));
1889 if (insn
->defExists(1))
1890 emitPRED(0x00, insn
->def(1));
1896 CodeEmitterGM107::emitSHL()
1898 switch (insn
->src(1).getFile()) {
1900 emitInsn(0x5c480000);
1901 emitGPR (0x14, insn
->src(1));
1903 case FILE_MEMORY_CONST
:
1904 emitInsn(0x4c480000);
1905 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1907 case FILE_IMMEDIATE
:
1908 emitInsn(0x38480000);
1909 emitIMMD(0x14, 19, insn
->src(1));
1912 assert(!"bad src1 file");
1918 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1919 emitGPR (0x08, insn
->src(0));
1920 emitGPR (0x00, insn
->def(0));
1924 CodeEmitterGM107::emitSHR()
1926 switch (insn
->src(1).getFile()) {
1928 emitInsn(0x5c280000);
1929 emitGPR (0x14, insn
->src(1));
1931 case FILE_MEMORY_CONST
:
1932 emitInsn(0x4c280000);
1933 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1935 case FILE_IMMEDIATE
:
1936 emitInsn(0x38280000);
1937 emitIMMD(0x14, 19, insn
->src(1));
1940 assert(!"bad src1 file");
1944 emitField(0x30, 1, isSignedType(insn
->dType
));
1947 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1948 emitGPR (0x08, insn
->src(0));
1949 emitGPR (0x00, insn
->def(0));
1953 CodeEmitterGM107::emitPOPC()
1955 switch (insn
->src(0).getFile()) {
1957 emitInsn(0x5c080000);
1958 emitGPR (0x14, insn
->src(0));
1960 case FILE_MEMORY_CONST
:
1961 emitInsn(0x4c080000);
1962 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1964 case FILE_IMMEDIATE
:
1965 emitInsn(0x38080000);
1966 emitIMMD(0x14, 19, insn
->src(0));
1969 assert(!"bad src1 file");
1973 emitINV(0x28, insn
->src(0));
1974 emitGPR(0x00, insn
->def(0));
1978 CodeEmitterGM107::emitBFI()
1980 switch(insn
->src(2).getFile()) {
1982 switch (insn
->src(1).getFile()) {
1984 emitInsn(0x5bf00000);
1985 emitGPR (0x14, insn
->src(1));
1987 case FILE_MEMORY_CONST
:
1988 emitInsn(0x4bf00000);
1989 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1991 case FILE_IMMEDIATE
:
1992 emitInsn(0x36f00000);
1993 emitIMMD(0x14, 19, insn
->src(1));
1996 assert(!"bad src1 file");
1999 emitGPR (0x27, insn
->src(2));
2001 case FILE_MEMORY_CONST
:
2002 emitInsn(0x53f00000);
2003 emitGPR (0x27, insn
->src(1));
2004 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2007 assert(!"bad src2 file");
2012 emitGPR (0x08, insn
->src(0));
2013 emitGPR (0x00, insn
->def(0));
2017 CodeEmitterGM107::emitBFE()
2019 switch (insn
->src(1).getFile()) {
2021 emitInsn(0x5c000000);
2022 emitGPR (0x14, insn
->src(1));
2024 case FILE_MEMORY_CONST
:
2025 emitInsn(0x4c000000);
2026 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2028 case FILE_IMMEDIATE
:
2029 emitInsn(0x38000000);
2030 emitIMMD(0x14, 19, insn
->src(1));
2033 assert(!"bad src1 file");
2037 emitField(0x30, 1, isSignedType(insn
->dType
));
2039 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2040 emitGPR (0x08, insn
->src(0));
2041 emitGPR (0x00, insn
->def(0));
2045 CodeEmitterGM107::emitFLO()
2047 switch (insn
->src(0).getFile()) {
2049 emitInsn(0x5c300000);
2050 emitGPR (0x14, insn
->src(0));
2052 case FILE_MEMORY_CONST
:
2053 emitInsn(0x4c300000);
2054 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2056 case FILE_IMMEDIATE
:
2057 emitInsn(0x38300000);
2058 emitIMMD(0x14, 19, insn
->src(0));
2061 assert(!"bad src1 file");
2065 emitField(0x30, 1, isSignedType(insn
->dType
));
2067 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2068 emitINV (0x28, insn
->src(0));
2069 emitGPR (0x00, insn
->def(0));
2072 /*******************************************************************************
2074 ******************************************************************************/
2077 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2081 switch (typeSizeof(type
)) {
2082 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2083 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2084 case 4: data
= 4; break;
2085 case 8: data
= 5; break;
2086 case 16: data
= 6; break;
2088 assert(!"bad type");
2092 emitField(pos
, 3, data
);
2096 CodeEmitterGM107::emitLDSTc(int pos
)
2100 switch (insn
->cache
) {
2101 case CACHE_CA
: mode
= 0; break;
2102 case CACHE_CG
: mode
= 1; break;
2103 case CACHE_CS
: mode
= 2; break;
2104 case CACHE_CV
: mode
= 3; break;
2106 assert(!"invalid caching mode");
2110 emitField(pos
, 2, mode
);
2114 CodeEmitterGM107::emitLDC()
2116 emitInsn (0xef900000);
2117 emitLDSTs(0x30, insn
->dType
);
2118 emitField(0x2c, 2, insn
->subOp
);
2119 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2120 emitGPR (0x00, insn
->def(0));
2124 CodeEmitterGM107::emitLDL()
2126 emitInsn (0xef400000);
2127 emitLDSTs(0x30, insn
->dType
);
2129 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2130 emitGPR (0x00, insn
->def(0));
2134 CodeEmitterGM107::emitLDS()
2136 emitInsn (0xef480000);
2137 emitLDSTs(0x30, insn
->dType
);
2138 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2139 emitGPR (0x00, insn
->def(0));
2143 CodeEmitterGM107::emitLD()
2145 emitInsn (0x80000000);
2148 emitLDSTs(0x35, insn
->dType
);
2149 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2150 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2151 emitGPR (0x00, insn
->def(0));
2155 CodeEmitterGM107::emitSTL()
2157 emitInsn (0xef500000);
2158 emitLDSTs(0x30, insn
->dType
);
2160 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2161 emitGPR (0x00, insn
->src(1));
2165 CodeEmitterGM107::emitSTS()
2167 emitInsn (0xef580000);
2168 emitLDSTs(0x30, insn
->dType
);
2169 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2170 emitGPR (0x00, insn
->src(1));
2174 CodeEmitterGM107::emitST()
2176 emitInsn (0xa0000000);
2179 emitLDSTs(0x35, insn
->dType
);
2180 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2181 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2182 emitGPR (0x00, insn
->src(1));
2186 CodeEmitterGM107::emitALD()
2188 emitInsn (0xefd80000);
2189 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2190 emitGPR (0x27, insn
->src(0).getIndirect(1));
2193 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2194 emitGPR (0x00, insn
->def(0));
2198 CodeEmitterGM107::emitAST()
2200 emitInsn (0xeff00000);
2201 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2202 emitGPR (0x27, insn
->src(0).getIndirect(1));
2204 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2205 emitGPR (0x00, insn
->src(1));
2209 CodeEmitterGM107::emitISBERD()
2211 emitInsn(0xefd00000);
2212 emitGPR (0x08, insn
->src(0));
2213 emitGPR (0x00, insn
->def(0));
2217 CodeEmitterGM107::emitAL2P()
2219 emitInsn (0xefa00000);
2220 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2222 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2223 emitGPR (0x08, insn
->src(0).getIndirect(0));
2224 emitGPR (0x00, insn
->def(0));
2228 interpApply(const InterpEntry
*entry
, uint32_t *code
,
2229 bool force_persample_interp
, bool flatshade
)
2231 int ipa
= entry
->ipa
;
2232 int reg
= entry
->reg
;
2233 int loc
= entry
->loc
;
2236 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2237 ipa
= NV50_IR_INTERP_FLAT
;
2239 } else if (force_persample_interp
&&
2240 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2241 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2242 ipa
|= NV50_IR_INTERP_CENTROID
;
2244 code
[loc
+ 1] &= ~(0xf << 0x14);
2245 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2246 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2247 code
[loc
+ 0] &= ~(0xff << 0x14);
2248 code
[loc
+ 0] |= reg
<< 0x14;
2252 CodeEmitterGM107::emitIPA()
2254 int ipam
= 0, ipas
= 0;
2256 switch (insn
->getInterpMode()) {
2257 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2258 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2259 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2260 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2262 assert(!"invalid ipa mode");
2266 switch (insn
->getSampleMode()) {
2267 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2268 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2269 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2271 assert(!"invalid ipa sample mode");
2275 emitInsn (0xe0000000);
2276 emitField(0x36, 2, ipam
);
2277 emitField(0x34, 2, ipas
);
2279 emitField(0x2f, 3, 7);
2280 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2281 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2282 code
[1] |= 0x00000040; /* .idx */
2283 emitGPR(0x00, insn
->def(0));
2285 if (insn
->op
== OP_PINTERP
) {
2286 emitGPR(0x14, insn
->src(1));
2287 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2288 emitGPR(0x27, insn
->src(2));
2289 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2291 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2292 emitGPR(0x27, insn
->src(1));
2294 addInterp(insn
->ipa
, 0xff, interpApply
);
2297 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2301 /*******************************************************************************
2303 ******************************************************************************/
2306 CodeEmitterGM107::emitPIXLD()
2308 emitInsn (0xefe80000);
2310 emitField(0x1f, 3, insn
->subOp
);
2311 emitGPR (0x08, insn
->src(0));
2312 emitGPR (0x00, insn
->def(0));
2315 /*******************************************************************************
2317 ******************************************************************************/
2320 CodeEmitterGM107::emitTEXs(int pos
)
2322 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2323 if (insn
->srcExists(src1
))
2324 emitGPR(pos
, insn
->src(src1
));
2330 CodeEmitterGM107::emitTEX()
2332 const TexInstruction
*insn
= this->insn
->asTex();
2335 if (!insn
->tex
.levelZero
) {
2337 case OP_TEX
: lodm
= 0; break;
2338 case OP_TXB
: lodm
= 2; break;
2339 case OP_TXL
: lodm
= 3; break;
2341 assert(!"invalid tex op");
2348 if (insn
->tex
.rIndirectSrc
>= 0) {
2349 emitInsn (0xdeb80000);
2350 emitField(0x35, 2, lodm
);
2351 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2353 emitInsn (0xc0380000);
2354 emitField(0x37, 2, lodm
);
2355 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2356 emitField(0x24, 13, insn
->tex
.r
);
2359 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2360 emitField(0x31, 1, insn
->tex
.liveOnly
);
2361 emitField(0x23, 1, insn
->tex
.derivAll
);
2362 emitField(0x1f, 4, insn
->tex
.mask
);
2363 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2364 insn
->tex
.target
.getDim() - 1);
2365 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2367 emitGPR (0x08, insn
->src(0));
2368 emitGPR (0x00, insn
->def(0));
2372 CodeEmitterGM107::emitTLD()
2374 const TexInstruction
*insn
= this->insn
->asTex();
2376 if (insn
->tex
.rIndirectSrc
>= 0) {
2377 emitInsn (0xdd380000);
2379 emitInsn (0xdc380000);
2380 emitField(0x24, 13, insn
->tex
.r
);
2383 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2384 emitField(0x32, 1, insn
->tex
.target
.isMS());
2385 emitField(0x31, 1, insn
->tex
.liveOnly
);
2386 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2387 emitField(0x1f, 4, insn
->tex
.mask
);
2388 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2389 insn
->tex
.target
.getDim() - 1);
2390 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2392 emitGPR (0x08, insn
->src(0));
2393 emitGPR (0x00, insn
->def(0));
2397 CodeEmitterGM107::emitTLD4()
2399 const TexInstruction
*insn
= this->insn
->asTex();
2401 if (insn
->tex
.rIndirectSrc
>= 0) {
2402 emitInsn (0xdef80000);
2403 emitField(0x26, 2, insn
->tex
.gatherComp
);
2404 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2405 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2407 emitInsn (0xc8380000);
2408 emitField(0x38, 2, insn
->tex
.gatherComp
);
2409 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2410 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2411 emitField(0x24, 13, insn
->tex
.r
);
2414 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2415 emitField(0x31, 1, insn
->tex
.liveOnly
);
2416 emitField(0x23, 1, insn
->tex
.derivAll
);
2417 emitField(0x1f, 4, insn
->tex
.mask
);
2418 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2419 insn
->tex
.target
.getDim() - 1);
2420 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2422 emitGPR (0x08, insn
->src(0));
2423 emitGPR (0x00, insn
->def(0));
2427 CodeEmitterGM107::emitTXD()
2429 const TexInstruction
*insn
= this->insn
->asTex();
2431 if (insn
->tex
.rIndirectSrc
>= 0) {
2432 emitInsn (0xde780000);
2434 emitInsn (0xde380000);
2435 emitField(0x24, 13, insn
->tex
.r
);
2438 emitField(0x31, 1, insn
->tex
.liveOnly
);
2439 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2440 emitField(0x1f, 4, insn
->tex
.mask
);
2441 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2442 insn
->tex
.target
.getDim() - 1);
2443 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2445 emitGPR (0x08, insn
->src(0));
2446 emitGPR (0x00, insn
->def(0));
2450 CodeEmitterGM107::emitTMML()
2452 const TexInstruction
*insn
= this->insn
->asTex();
2454 if (insn
->tex
.rIndirectSrc
>= 0) {
2455 emitInsn (0xdf600000);
2457 emitInsn (0xdf580000);
2458 emitField(0x24, 13, insn
->tex
.r
);
2461 emitField(0x31, 1, insn
->tex
.liveOnly
);
2462 emitField(0x23, 1, insn
->tex
.derivAll
);
2463 emitField(0x1f, 4, insn
->tex
.mask
);
2464 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2465 insn
->tex
.target
.getDim() - 1);
2466 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2468 emitGPR (0x08, insn
->src(0));
2469 emitGPR (0x00, insn
->def(0));
2473 CodeEmitterGM107::emitTXQ()
2475 const TexInstruction
*insn
= this->insn
->asTex();
2478 switch (insn
->tex
.query
) {
2479 case TXQ_DIMS
: type
= 0x01; break;
2480 case TXQ_TYPE
: type
= 0x02; break;
2481 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2482 case TXQ_FILTER
: type
= 0x10; break;
2483 case TXQ_LOD
: type
= 0x12; break;
2484 case TXQ_WRAP
: type
= 0x14; break;
2485 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2487 assert(!"invalid txq query");
2491 if (insn
->tex
.rIndirectSrc
>= 0) {
2492 emitInsn (0xdf500000);
2494 emitInsn (0xdf480000);
2495 emitField(0x24, 13, insn
->tex
.r
);
2498 emitField(0x31, 1, insn
->tex
.liveOnly
);
2499 emitField(0x1f, 4, insn
->tex
.mask
);
2500 emitField(0x16, 6, type
);
2501 emitGPR (0x08, insn
->src(0));
2502 emitGPR (0x00, insn
->def(0));
2506 CodeEmitterGM107::emitDEPBAR()
2508 emitInsn (0xf0f00000);
2509 emitField(0x1d, 1, 1); /* le */
2510 emitField(0x1a, 3, 5);
2511 emitField(0x14, 6, insn
->subOp
);
2512 emitField(0x00, 6, insn
->subOp
);
2515 /*******************************************************************************
2517 ******************************************************************************/
2520 CodeEmitterGM107::emitNOP()
2522 emitInsn(0x50b00000);
2526 CodeEmitterGM107::emitKIL()
2528 emitInsn (0xe3300000);
2529 emitCond5(0x00, CC_TR
);
2533 CodeEmitterGM107::emitOUT()
2535 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2536 const int emit
= insn
->op
== OP_EMIT
;
2538 switch (insn
->src(1).getFile()) {
2540 emitInsn(0xfbe00000);
2541 emitGPR (0x14, insn
->src(1));
2543 case FILE_IMMEDIATE
:
2544 emitInsn(0xf6e00000);
2545 emitIMMD(0x14, 19, insn
->src(1));
2547 case FILE_MEMORY_CONST
:
2548 emitInsn(0xebe00000);
2549 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2552 assert(!"bad src1 file");
2556 emitField(0x27, 2, (cut
<< 1) | emit
);
2557 emitGPR (0x08, insn
->src(0));
2558 emitGPR (0x00, insn
->def(0));
2561 /*******************************************************************************
2562 * assembler front-end
2563 ******************************************************************************/
2566 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2568 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2573 if (insn
->encSize
!= 8) {
2574 ERROR("skipping undecodable instruction: "); insn
->print();
2577 if (codeSize
+ size
> codeSizeLimit
) {
2578 ERROR("code emitter output buffer too small\n");
2582 if (writeIssueDelays
) {
2583 int n
= ((codeSize
& 0x1f) / 8) - 1;
2586 data
[0] = 0x00000000;
2587 data
[1] = 0x00000000;
2593 emitField(data
, n
* 21, 21, insn
->sched
);
2637 if (insn
->def(0).getFile() == FILE_GPR
&&
2638 insn
->src(0).getFile() != FILE_PREDICATE
)
2653 if (isFloatType(insn
->dType
)) {
2654 if (isFloatType(insn
->sType
))
2659 if (isFloatType(insn
->sType
))
2670 if (isFloatType(insn
->dType
)) {
2671 if (insn
->dType
== TYPE_F64
)
2680 if (isFloatType(insn
->dType
)) {
2681 if (insn
->dType
== TYPE_F64
)
2691 if (isFloatType(insn
->dType
)) {
2692 if (insn
->dType
== TYPE_F64
)
2702 if (isFloatType(insn
->dType
)) {
2703 if (insn
->dType
== TYPE_F64
)
2730 if (isFloatType(insn
->dType
))
2739 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2740 if (isFloatType(insn
->sType
))
2741 if (insn
->sType
== TYPE_F64
)
2748 if (isFloatType(insn
->sType
))
2749 if (insn
->sType
== TYPE_F64
)
2778 switch (insn
->src(0).getFile()) {
2779 case FILE_MEMORY_CONST
: emitLDC(); break;
2780 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2781 case FILE_MEMORY_SHARED
: emitLDS(); break;
2782 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2784 assert(!"invalid load");
2790 switch (insn
->src(0).getFile()) {
2791 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2792 case FILE_MEMORY_SHARED
: emitSTS(); break;
2793 case FILE_MEMORY_GLOBAL
: emitST(); break;
2795 assert(!"invalid load");
2856 assert(!"invalid opcode");
2872 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2877 /*******************************************************************************
2878 * sched data calculator
2879 ******************************************************************************/
2881 class SchedDataCalculatorGM107
: public Pass
2884 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2887 bool visit(BasicBlock
*bb
);
2891 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2893 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2895 insn
->sched
= 0x7e0;
2901 /*******************************************************************************
2903 ******************************************************************************/
2906 CodeEmitterGM107::prepareEmission(Function
*func
)
2908 SchedDataCalculatorGM107
sched(targ
);
2909 CodeEmitter::prepareEmission(func
);
2910 sched
.run(func
, true, true);
2913 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
2915 return (size
+ 23) / 24;
2919 CodeEmitterGM107::prepareEmission(Program
*prog
)
2921 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
2922 !fi
.end(); fi
.next()) {
2923 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
2924 func
->binPos
= prog
->binSize
;
2925 prepareEmission(func
);
2927 // adjust sizes & positions for schedulding info:
2928 if (prog
->getTarget()->hasSWSched
) {
2929 uint32_t adjPos
= func
->binPos
;
2930 BasicBlock
*bb
= NULL
;
2931 for (int i
= 0; i
< func
->bbCount
; ++i
) {
2932 bb
= func
->bbArray
[i
];
2933 int32_t adjSize
= bb
->binSize
;
2935 adjSize
-= 32 - adjPos
% 32;
2939 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
2940 bb
->binPos
= adjPos
;
2941 bb
->binSize
= adjSize
;
2945 func
->binSize
= adjPos
- func
->binPos
;
2948 prog
->binSize
+= func
->binSize
;
2952 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
2953 : CodeEmitter(target
),
2955 writeIssueDelays(target
->hasSWSched
)
2958 codeSize
= codeSizeLimit
= 0;
2963 TargetGM107::createCodeEmitterGM107(Program::Type type
)
2965 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
2966 emit
->setProgramType(type
);
2970 } // namespace nv50_ir