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
);
200 /*******************************************************************************
201 * general instruction layout/fields
202 ******************************************************************************/
205 CodeEmitterGM107::emitField(uint32_t *data
, int b
, int s
, uint32_t v
)
208 uint32_t m
= ((1ULL << s
) - 1);
209 uint64_t d
= (uint64_t)(v
& m
) << b
;
210 assert(!(v
& ~m
) || (v
& ~m
) == ~m
);
217 CodeEmitterGM107::emitPred()
219 if (insn
->predSrc
>= 0) {
220 emitField(16, 3, insn
->getSrc(insn
->predSrc
)->rep()->reg
.data
.id
);
221 emitField(19, 1, insn
->cc
== CC_NOT_P
);
228 CodeEmitterGM107::emitInsn(uint32_t hi
, bool pred
)
230 code
[0] = 0x00000000;
237 CodeEmitterGM107::emitGPR(int pos
, const Value
*val
)
239 emitField(pos
, 8, val
? val
->reg
.data
.id
: 255);
243 CodeEmitterGM107::emitSYS(int pos
, const Value
*val
)
245 int id
= val
? val
->reg
.data
.id
: -1;
248 case SV_LANEID
: id
= 0x00; break;
249 case SV_VERTEX_COUNT
: id
= 0x10; break;
250 case SV_INVOCATION_ID
: id
= 0x11; break;
251 case SV_THREAD_KILL
: id
= 0x13; break;
252 case SV_INVOCATION_INFO
: id
= 0x1d; break;
254 assert(!"invalid system value");
259 emitField(pos
, 8, id
);
263 CodeEmitterGM107::emitPRED(int pos
, const Value
*val
)
265 emitField(pos
, 3, val
? val
->reg
.data
.id
: 7);
269 CodeEmitterGM107::emitADDR(int gpr
, int off
, int len
, int shr
,
272 const Value
*v
= ref
.get();
273 assert(!(v
->reg
.data
.offset
& ((1 << shr
) - 1)));
275 emitGPR(gpr
, ref
.getIndirect(0));
276 emitField(off
, len
, v
->reg
.data
.offset
>> shr
);
280 CodeEmitterGM107::emitCBUF(int buf
, int gpr
, int off
, int len
, int shr
,
283 const Value
*v
= ref
.get();
284 const Symbol
*s
= v
->asSym();
286 assert(!(s
->reg
.data
.offset
& ((1 << shr
) - 1)));
288 emitField(buf
, 5, v
->reg
.fileIndex
);
290 emitGPR(gpr
, ref
.getIndirect(0));
291 emitField(off
, 16, s
->reg
.data
.offset
>> shr
);
295 CodeEmitterGM107::longIMMD(const ValueRef
&ref
)
297 if (ref
.getFile() == FILE_IMMEDIATE
) {
298 const ImmediateValue
*imm
= ref
.get()->asImm();
299 if (isFloatType(insn
->sType
)) {
300 if ((imm
->reg
.data
.u32
& 0x00000fff) != 0x00000000)
303 if ((imm
->reg
.data
.u32
& 0xfff00000) != 0x00000000 &&
304 (imm
->reg
.data
.u32
& 0xfff00000) != 0xfff00000)
312 CodeEmitterGM107::emitIMMD(int pos
, int len
, const ValueRef
&ref
)
314 const ImmediateValue
*imm
= ref
.get()->asImm();
315 uint32_t val
= imm
->reg
.data
.u32
;
318 if (insn
->sType
== TYPE_F32
|| insn
->sType
== TYPE_F16
) {
319 assert(!(val
& 0x00000fff));
321 } else if (insn
->sType
== TYPE_F64
) {
322 assert(!(imm
->reg
.data
.u64
& 0x00000fffffffffffULL
));
323 val
= imm
->reg
.data
.u64
>> 44;
325 assert(!(val
& 0xfff00000) || (val
& 0xfff00000) == 0xfff00000);
326 emitField( 56, 1, (val
& 0x80000) >> 19);
327 emitField(pos
, len
, (val
& 0x7ffff));
329 emitField(pos
, len
, val
);
333 /*******************************************************************************
335 ******************************************************************************/
338 CodeEmitterGM107::emitCond3(int pos
, CondCode code
)
343 case CC_FL
: data
= 0x00; break;
345 case CC_LT
: data
= 0x01; break;
347 case CC_EQ
: data
= 0x02; break;
349 case CC_LE
: data
= 0x03; break;
351 case CC_GT
: data
= 0x04; break;
353 case CC_NE
: data
= 0x05; break;
355 case CC_GE
: data
= 0x06; break;
356 case CC_TR
: data
= 0x07; break;
358 assert(!"invalid cond3");
362 emitField(pos
, 3, data
);
366 CodeEmitterGM107::emitCond4(int pos
, CondCode code
)
371 case CC_FL
: data
= 0x00; break;
372 case CC_LT
: data
= 0x01; break;
373 case CC_EQ
: data
= 0x02; break;
374 case CC_LE
: data
= 0x03; break;
375 case CC_GT
: data
= 0x04; break;
376 case CC_NE
: data
= 0x05; break;
377 case CC_GE
: data
= 0x06; break;
378 // case CC_NUM: data = 0x07; break;
379 // case CC_NAN: data = 0x08; break;
380 case CC_LTU
: data
= 0x09; break;
381 case CC_EQU
: data
= 0x0a; break;
382 case CC_LEU
: data
= 0x0b; break;
383 case CC_GTU
: data
= 0x0c; break;
384 case CC_NEU
: data
= 0x0d; break;
385 case CC_GEU
: data
= 0x0e; break;
386 case CC_TR
: data
= 0x0f; break;
388 assert(!"invalid cond4");
392 emitField(pos
, 4, data
);
396 CodeEmitterGM107::emitO(int pos
)
398 emitField(pos
, 1, insn
->getSrc(0)->reg
.file
== FILE_SHADER_OUTPUT
);
402 CodeEmitterGM107::emitP(int pos
)
404 emitField(pos
, 1, insn
->perPatch
);
408 CodeEmitterGM107::emitSAT(int pos
)
410 emitField(pos
, 1, insn
->saturate
);
414 CodeEmitterGM107::emitCC(int pos
)
416 emitField(pos
, 1, insn
->defExists(1));
420 CodeEmitterGM107::emitX(int pos
)
422 emitField(pos
, 1, insn
->flagsSrc
>= 0);
426 CodeEmitterGM107::emitABS(int pos
, const ValueRef
&ref
)
428 emitField(pos
, 1, ref
.mod
.abs());
432 CodeEmitterGM107::emitNEG(int pos
, const ValueRef
&ref
)
434 emitField(pos
, 1, ref
.mod
.neg());
438 CodeEmitterGM107::emitNEG2(int pos
, const ValueRef
&a
, const ValueRef
&b
)
440 emitField(pos
, 1, a
.mod
.neg() ^ b
.mod
.neg());
444 CodeEmitterGM107::emitFMZ(int pos
, int len
)
446 emitField(pos
, len
, insn
->dnz
<< 1 | insn
->ftz
);
450 CodeEmitterGM107::emitRND(int rmp
, RoundMode rnd
, int rip
)
454 case ROUND_NI
: ri
= 1;
455 case ROUND_N
: rm
= 0; break;
456 case ROUND_MI
: ri
= 1;
457 case ROUND_M
: rm
= 1; break;
458 case ROUND_PI
: ri
= 1;
459 case ROUND_P
: rm
= 2; break;
460 case ROUND_ZI
: ri
= 1;
461 case ROUND_Z
: rm
= 3; break;
463 assert(!"invalid round mode");
466 emitField(rip
, 1, ri
);
467 emitField(rmp
, 2, rm
);
471 CodeEmitterGM107::emitPDIV(int pos
)
473 assert(insn
->postFactor
>= -3 && insn
->postFactor
<= 3);
474 if (insn
->postFactor
> 0)
475 emitField(pos
, 3, 7 - insn
->postFactor
);
477 emitField(pos
, 3, 0 - insn
->postFactor
);
481 CodeEmitterGM107::emitINV(int pos
, const ValueRef
&ref
)
483 emitField(pos
, 1, !!(ref
.mod
& Modifier(NV50_IR_MOD_NOT
)));
486 /*******************************************************************************
488 ******************************************************************************/
491 CodeEmitterGM107::emitEXIT()
493 emitInsn (0xe3000000);
494 emitCond5(0x00, CC_TR
);
498 CodeEmitterGM107::emitBRA()
500 const FlowInstruction
*insn
= this->insn
->asFlow();
503 if (insn
->indirect
) {
505 emitInsn(0xe2000000); // JMX
507 emitInsn(0xe2500000); // BRX
511 emitInsn(0xe2100000); // JMP
513 emitInsn(0xe2400000); // BRA
514 emitField(0x07, 1, insn
->allWarp
);
517 emitField(0x06, 1, insn
->limit
);
518 emitCond5(0x00, CC_TR
);
520 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
521 int32_t pos
= insn
->target
.bb
->binPos
;
522 if (writeIssueDelays
&& !(pos
& 0x1f))
525 emitField(0x14, 24, pos
- (codeSize
+ 8));
527 emitField(0x14, 32, pos
);
529 emitCBUF (0x24, gpr
, 20, 16, 0, insn
->src(0));
530 emitField(0x05, 1, 1);
535 CodeEmitterGM107::emitCAL()
537 const FlowInstruction
*insn
= this->insn
->asFlow();
539 if (insn
->absolute
) {
540 emitInsn(0xe2200000, 0); // JCAL
542 emitInsn(0xe2600000, 0); // CAL
545 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
547 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
550 int pcAbs
= targGM107
->getBuiltinOffset(insn
->target
.builtin
);
551 addReloc(RelocEntry::TYPE_BUILTIN
, 0, pcAbs
, 0xfff00000, 20);
552 addReloc(RelocEntry::TYPE_BUILTIN
, 1, pcAbs
, 0x000fffff, -12);
554 emitField(0x14, 32, insn
->target
.bb
->binPos
);
558 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
559 emitField(0x05, 1, 1);
564 CodeEmitterGM107::emitPCNT()
566 const FlowInstruction
*insn
= this->insn
->asFlow();
568 emitInsn(0xe2b00000, 0);
570 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
571 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
573 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
574 emitField(0x05, 1, 1);
579 CodeEmitterGM107::emitCONT()
581 emitInsn (0xe3500000);
582 emitCond5(0x00, CC_TR
);
586 CodeEmitterGM107::emitPBK()
588 const FlowInstruction
*insn
= this->insn
->asFlow();
590 emitInsn(0xe2a00000, 0);
592 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
593 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
595 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
596 emitField(0x05, 1, 1);
601 CodeEmitterGM107::emitBRK()
603 emitInsn (0xe3400000);
604 emitCond5(0x00, CC_TR
);
608 CodeEmitterGM107::emitPRET()
610 const FlowInstruction
*insn
= this->insn
->asFlow();
612 emitInsn(0xe2700000, 0);
614 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
615 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
617 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
618 emitField(0x05, 1, 1);
623 CodeEmitterGM107::emitRET()
625 emitInsn (0xe3200000);
626 emitCond5(0x00, CC_TR
);
630 CodeEmitterGM107::emitSSY()
632 const FlowInstruction
*insn
= this->insn
->asFlow();
634 emitInsn(0xe2900000, 0);
636 if (!insn
->srcExists(0) || insn
->src(0).getFile() != FILE_MEMORY_CONST
) {
637 emitField(0x14, 24, insn
->target
.bb
->binPos
- (codeSize
+ 8));
639 emitCBUF (0x24, -1, 20, 16, 0, insn
->src(0));
640 emitField(0x05, 1, 1);
645 CodeEmitterGM107::emitSYNC()
647 emitInsn (0xf0f80000);
648 emitCond5(0x00, CC_TR
);
652 CodeEmitterGM107::emitSAM()
654 emitInsn(0xe3700000, 0);
658 CodeEmitterGM107::emitRAM()
660 emitInsn(0xe3800000, 0);
663 /*******************************************************************************
665 ******************************************************************************/
667 /*******************************************************************************
668 * movement / conversion
669 ******************************************************************************/
672 CodeEmitterGM107::emitMOV()
674 if ( insn
->src(0).getFile() != FILE_IMMEDIATE
||
675 (insn
->sType
!= TYPE_F32
&& !longIMMD(insn
->src(0)))) {
676 switch (insn
->src(0).getFile()) {
678 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
679 emitInsn(0x5b6a0000);
682 emitInsn(0x5c980000);
684 emitGPR (0x14, insn
->src(0));
686 case FILE_MEMORY_CONST
:
687 emitInsn(0x4c980000);
688 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
691 emitInsn(0x38980000);
692 emitIMMD(0x14, 19, insn
->src(0));
695 emitInsn(0x50880000);
696 emitPRED(0x0c, insn
->src(0));
701 assert(!"bad src file");
704 if (insn
->def(0).getFile() != FILE_PREDICATE
&&
705 insn
->src(0).getFile() != FILE_PREDICATE
)
706 emitField(0x27, 4, insn
->lanes
);
708 emitInsn (0x01000000);
709 emitIMMD (0x14, 32, insn
->src(0));
710 emitField(0x0c, 4, insn
->lanes
);
713 if (insn
->def(0).getFile() == FILE_PREDICATE
) {
715 emitPRED(0x03, insn
->def(0));
718 emitGPR(0x00, insn
->def(0));
723 CodeEmitterGM107::emitS2R()
725 emitInsn(0xf0c80000);
726 emitSYS (0x14, insn
->src(0));
727 emitGPR (0x00, insn
->def(0));
731 CodeEmitterGM107::emitF2F()
733 RoundMode rnd
= insn
->rnd
;
736 case OP_FLOOR
: rnd
= ROUND_MI
; break;
737 case OP_CEIL
: rnd
= ROUND_PI
; break;
738 case OP_TRUNC
: rnd
= ROUND_ZI
; break;
743 switch (insn
->src(0).getFile()) {
745 emitInsn(0x5ca80000);
746 emitGPR (0x14, insn
->src(0));
748 case FILE_MEMORY_CONST
:
749 emitInsn(0x4ca80000);
750 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
753 emitInsn(0x38a80000);
754 emitIMMD(0x14, 19, insn
->src(0));
757 assert(!"bad src0 file");
761 emitField(0x32, 1, (insn
->op
== OP_SAT
) || insn
->saturate
);
762 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
764 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
766 emitField(0x29, 1, insn
->subOp
);
767 emitRND (0x27, rnd
, 0x2a);
768 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
769 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
770 emitGPR (0x00, insn
->def(0));
774 CodeEmitterGM107::emitF2I()
776 RoundMode rnd
= insn
->rnd
;
779 case OP_FLOOR
: rnd
= ROUND_M
; break;
780 case OP_CEIL
: rnd
= ROUND_P
; break;
781 case OP_TRUNC
: rnd
= ROUND_Z
; break;
786 switch (insn
->src(0).getFile()) {
788 emitInsn(0x5cb00000);
789 emitGPR (0x14, insn
->src(0));
791 case FILE_MEMORY_CONST
:
792 emitInsn(0x4cb00000);
793 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
796 emitInsn(0x38b00000);
797 emitIMMD(0x14, 19, insn
->src(0));
800 assert(!"bad src0 file");
804 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
806 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
808 emitRND (0x27, rnd
, 0x2a);
809 emitField(0x0c, 1, isSignedType(insn
->dType
));
810 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
811 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
812 emitGPR (0x00, insn
->def(0));
816 CodeEmitterGM107::emitI2F()
818 RoundMode rnd
= insn
->rnd
;
821 case OP_FLOOR
: rnd
= ROUND_M
; break;
822 case OP_CEIL
: rnd
= ROUND_P
; break;
823 case OP_TRUNC
: rnd
= ROUND_Z
; break;
828 switch (insn
->src(0).getFile()) {
830 emitInsn(0x5cb80000);
831 emitGPR (0x14, insn
->src(0));
833 case FILE_MEMORY_CONST
:
834 emitInsn(0x4cb80000);
835 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
838 emitInsn(0x38b80000);
839 emitIMMD(0x14, 19, insn
->src(0));
842 assert(!"bad src0 file");
846 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
848 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
849 emitField(0x29, 2, insn
->subOp
);
850 emitRND (0x27, rnd
, -1);
851 emitField(0x0d, 1, isSignedType(insn
->sType
));
852 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
853 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
854 emitGPR (0x00, insn
->def(0));
858 CodeEmitterGM107::emitI2I()
860 switch (insn
->src(0).getFile()) {
862 emitInsn(0x5ce00000);
863 emitGPR (0x14, insn
->src(0));
865 case FILE_MEMORY_CONST
:
866 emitInsn(0x4ce00000);
867 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
870 emitInsn(0x38e00000);
871 emitIMMD(0x14, 19, insn
->src(0));
874 assert(!"bad src0 file");
879 emitField(0x31, 1, (insn
->op
== OP_ABS
) || insn
->src(0).mod
.abs());
881 emitField(0x2d, 1, (insn
->op
== OP_NEG
) || insn
->src(0).mod
.neg());
882 emitField(0x29, 2, insn
->subOp
);
883 emitField(0x0d, 1, isSignedType(insn
->sType
));
884 emitField(0x0c, 1, isSignedType(insn
->dType
));
885 emitField(0x0a, 2, util_logbase2(typeSizeof(insn
->sType
)));
886 emitField(0x08, 2, util_logbase2(typeSizeof(insn
->dType
)));
887 emitGPR (0x00, insn
->def(0));
891 CodeEmitterGM107::emitSHFL()
895 emitInsn (0xef100000);
897 switch (insn
->src(1).getFile()) {
899 emitGPR(0x14, insn
->src(1));
902 emitIMMD(0x14, 5, insn
->src(1));
906 assert(!"invalid src1 file");
910 /*XXX: what is this arg? hardcode immediate for now */
911 emitField(0x22, 13, 0x1c03);
915 emitField(0x1e, 2, insn
->subOp
);
916 emitField(0x1c, 2, type
);
917 emitGPR (0x08, insn
->src(0));
918 emitGPR (0x00, insn
->def(0));
921 /*******************************************************************************
923 ******************************************************************************/
926 CodeEmitterGM107::emitDADD()
928 switch (insn
->src(1).getFile()) {
930 emitInsn(0x5c700000);
931 emitGPR (0x14, insn
->src(1));
933 case FILE_MEMORY_CONST
:
934 emitInsn(0x4c700000);
935 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
938 emitInsn(0x38700000);
939 emitIMMD(0x14, 19, insn
->src(1));
942 assert(!"bad src1 file");
945 emitABS(0x31, insn
->src(1));
946 emitNEG(0x30, insn
->src(0));
948 emitABS(0x2e, insn
->src(0));
949 emitNEG(0x2d, insn
->src(1));
951 if (insn
->op
== OP_SUB
)
952 code
[1] ^= 0x00002000;
954 emitGPR(0x08, insn
->src(0));
955 emitGPR(0x00, insn
->def(0));
959 CodeEmitterGM107::emitDMUL()
961 switch (insn
->src(1).getFile()) {
963 emitInsn(0x5c800000);
964 emitGPR (0x14, insn
->src(1));
966 case FILE_MEMORY_CONST
:
967 emitInsn(0x4c800000);
968 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
971 emitInsn(0x38800000);
972 emitIMMD(0x14, 19, insn
->src(1));
975 assert(!"bad src1 file");
979 emitNEG2(0x30, insn
->src(0), insn
->src(1));
982 emitGPR (0x08, insn
->src(0));
983 emitGPR (0x00, insn
->def(0));
987 CodeEmitterGM107::emitDFMA()
989 switch(insn
->src(2).getFile()) {
991 switch (insn
->src(1).getFile()) {
993 emitInsn(0x5b700000);
994 emitGPR (0x14, insn
->src(1));
996 case FILE_MEMORY_CONST
:
997 emitInsn(0x4b700000);
998 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1000 case FILE_IMMEDIATE
:
1001 emitInsn(0x36700000);
1002 emitIMMD(0x14, 19, insn
->src(1));
1005 assert(!"bad src1 file");
1008 emitGPR (0x27, insn
->src(2));
1010 case FILE_MEMORY_CONST
:
1011 emitInsn(0x53700000);
1012 emitGPR (0x27, insn
->src(1));
1013 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1016 assert(!"bad src2 file");
1021 emitNEG (0x31, insn
->src(2));
1022 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1024 emitGPR (0x08, insn
->src(0));
1025 emitGPR (0x00, insn
->def(0));
1029 CodeEmitterGM107::emitDMNMX()
1031 switch (insn
->src(1).getFile()) {
1033 emitInsn(0x5c500000);
1034 emitGPR (0x14, insn
->src(1));
1036 case FILE_MEMORY_CONST
:
1037 emitInsn(0x4c500000);
1038 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1040 case FILE_IMMEDIATE
:
1041 emitInsn(0x38500000);
1042 emitIMMD(0x14, 19, insn
->src(1));
1045 assert(!"bad src1 file");
1049 emitABS (0x31, insn
->src(1));
1050 emitNEG (0x30, insn
->src(0));
1052 emitABS (0x2e, insn
->src(0));
1053 emitNEG (0x2d, insn
->src(1));
1054 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1056 emitGPR (0x08, insn
->src(0));
1057 emitGPR (0x00, insn
->def(0));
1061 CodeEmitterGM107::emitDSET()
1063 const CmpInstruction
*insn
= this->insn
->asCmp();
1065 switch (insn
->src(1).getFile()) {
1067 emitInsn(0x59000000);
1068 emitGPR (0x14, insn
->src(1));
1070 case FILE_MEMORY_CONST
:
1071 emitInsn(0x49000000);
1072 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1074 case FILE_IMMEDIATE
:
1075 emitInsn(0x32000000);
1076 emitIMMD(0x14, 19, insn
->src(1));
1079 assert(!"bad src1 file");
1083 if (insn
->op
!= OP_SET
) {
1085 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1086 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1087 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1089 assert(!"invalid set op");
1092 emitPRED(0x27, insn
->src(2));
1097 emitABS (0x36, insn
->src(0));
1098 emitNEG (0x35, insn
->src(1));
1099 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1100 emitCond4(0x30, insn
->setCond
);
1102 emitABS (0x2c, insn
->src(1));
1103 emitNEG (0x2b, insn
->src(0));
1104 emitGPR (0x08, insn
->src(0));
1105 emitGPR (0x00, insn
->def(0));
1109 CodeEmitterGM107::emitDSETP()
1111 const CmpInstruction
*insn
= this->insn
->asCmp();
1113 switch (insn
->src(1).getFile()) {
1115 emitInsn(0x5b800000);
1116 emitGPR (0x14, insn
->src(1));
1118 case FILE_MEMORY_CONST
:
1119 emitInsn(0x4b800000);
1120 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1122 case FILE_IMMEDIATE
:
1123 emitInsn(0x36800000);
1124 emitIMMD(0x14, 19, insn
->src(1));
1127 assert(!"bad src1 file");
1131 if (insn
->op
!= OP_SET
) {
1133 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1134 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1135 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1137 assert(!"invalid set op");
1140 emitPRED(0x27, insn
->src(2));
1145 emitCond4(0x30, insn
->setCond
);
1146 emitABS (0x2c, insn
->src(1));
1147 emitNEG (0x2b, insn
->src(0));
1148 emitGPR (0x08, insn
->src(0));
1149 emitABS (0x07, insn
->src(0));
1150 emitNEG (0x06, insn
->src(1));
1151 emitPRED (0x03, insn
->def(0));
1152 if (insn
->defExists(1))
1153 emitPRED(0x00, insn
->def(1));
1158 /*******************************************************************************
1160 ******************************************************************************/
1163 CodeEmitterGM107::emitFADD()
1165 if (!longIMMD(insn
->src(1))) {
1166 switch (insn
->src(1).getFile()) {
1168 emitInsn(0x5c580000);
1169 emitGPR (0x14, insn
->src(1));
1171 case FILE_MEMORY_CONST
:
1172 emitInsn(0x4c580000);
1173 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1175 case FILE_IMMEDIATE
:
1176 emitInsn(0x38580000);
1177 emitIMMD(0x14, 19, insn
->src(1));
1180 assert(!"bad src1 file");
1184 emitABS(0x31, insn
->src(1));
1185 emitNEG(0x30, insn
->src(0));
1187 emitABS(0x2e, insn
->src(0));
1188 emitNEG(0x2d, insn
->src(1));
1191 emitInsn(0x08000000);
1192 emitABS(0x39, insn
->src(1));
1193 emitNEG(0x38, insn
->src(0));
1195 emitABS(0x36, insn
->src(0));
1196 emitNEG(0x35, insn
->src(1));
1198 emitIMMD(0x14, 32, insn
->src(1));
1201 if (insn
->op
== OP_SUB
)
1202 code
[1] ^= 0x00002000;
1204 emitGPR(0x08, insn
->src(0));
1205 emitGPR(0x00, insn
->def(0));
1209 CodeEmitterGM107::emitFMUL()
1211 if (!longIMMD(insn
->src(1))) {
1212 switch (insn
->src(1).getFile()) {
1214 emitInsn(0x5c680000);
1215 emitGPR (0x14, insn
->src(1));
1217 case FILE_MEMORY_CONST
:
1218 emitInsn(0x4c680000);
1219 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1221 case FILE_IMMEDIATE
:
1222 emitInsn(0x38680000);
1223 emitIMMD(0x14, 19, insn
->src(1));
1226 assert(!"bad src1 file");
1230 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1236 emitInsn(0x1e000000);
1240 emitIMMD(0x14, 32, insn
->src(1));
1241 if (insn
->src(0).mod
.neg() ^ insn
->src(1).mod
.neg())
1242 code
[1] ^= 0x00080000; /* flip immd sign bit */
1245 emitGPR(0x08, insn
->src(0));
1246 emitGPR(0x00, insn
->def(0));
1250 CodeEmitterGM107::emitFFMA()
1252 /*XXX: ffma32i exists, but not using it as third src overlaps dst */
1253 switch(insn
->src(2).getFile()) {
1255 switch (insn
->src(1).getFile()) {
1257 emitInsn(0x59800000);
1258 emitGPR (0x14, insn
->src(1));
1260 case FILE_MEMORY_CONST
:
1261 emitInsn(0x49800000);
1262 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1264 case FILE_IMMEDIATE
:
1265 emitInsn(0x32800000);
1266 emitIMMD(0x14, 19, insn
->src(1));
1269 assert(!"bad src1 file");
1272 emitGPR (0x27, insn
->src(2));
1274 case FILE_MEMORY_CONST
:
1275 emitInsn(0x51800000);
1276 emitGPR (0x27, insn
->src(1));
1277 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1280 assert(!"bad src2 file");
1285 emitNEG (0x31, insn
->src(2));
1286 emitNEG2(0x30, insn
->src(0), insn
->src(1));
1290 emitGPR(0x08, insn
->src(0));
1291 emitGPR(0x00, insn
->def(0));
1295 CodeEmitterGM107::emitMUFU()
1300 case OP_COS
: mufu
= 0; break;
1301 case OP_SIN
: mufu
= 1; break;
1302 case OP_EX2
: mufu
= 2; break;
1303 case OP_LG2
: mufu
= 3; break;
1304 case OP_RCP
: mufu
= 4 + 2 * insn
->subOp
; break;
1305 case OP_RSQ
: mufu
= 5 + 2 * insn
->subOp
; break;
1307 assert(!"invalid mufu");
1311 emitInsn (0x50800000);
1313 emitNEG (0x30, insn
->src(0));
1314 emitABS (0x2e, insn
->src(0));
1315 emitField(0x14, 3, mufu
);
1316 emitGPR (0x08, insn
->src(0));
1317 emitGPR (0x00, insn
->def(0));
1321 CodeEmitterGM107::emitFMNMX()
1323 switch (insn
->src(1).getFile()) {
1325 emitInsn(0x5c600000);
1326 emitGPR (0x14, insn
->src(1));
1328 case FILE_MEMORY_CONST
:
1329 emitInsn(0x4c600000);
1330 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1332 case FILE_IMMEDIATE
:
1333 emitInsn(0x38600000);
1334 emitIMMD(0x14, 19, insn
->src(1));
1337 assert(!"bad src1 file");
1341 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1344 emitABS(0x31, insn
->src(1));
1345 emitNEG(0x30, insn
->src(0));
1347 emitABS(0x2e, insn
->src(0));
1348 emitNEG(0x2d, insn
->src(1));
1350 emitGPR(0x08, insn
->src(0));
1351 emitGPR(0x00, insn
->def(0));
1355 CodeEmitterGM107::emitRRO()
1357 switch (insn
->src(0).getFile()) {
1359 emitInsn(0x5c900000);
1360 emitGPR (0x14, insn
->src(0));
1362 case FILE_MEMORY_CONST
:
1363 emitInsn(0x4c900000);
1364 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1366 case FILE_IMMEDIATE
:
1367 emitInsn(0x38900000);
1368 emitIMMD(0x14, 19, insn
->src(0));
1371 assert(!"bad src file");
1375 emitABS (0x31, insn
->src(0));
1376 emitNEG (0x2d, insn
->src(0));
1377 emitField(0x27, 1, insn
->op
== OP_PREEX2
);
1378 emitGPR (0x00, insn
->def(0));
1382 CodeEmitterGM107::emitFCMP()
1384 const CmpInstruction
*insn
= this->insn
->asCmp();
1385 CondCode cc
= insn
->setCond
;
1387 if (insn
->src(2).mod
.neg())
1388 cc
= reverseCondCode(cc
);
1390 switch(insn
->src(2).getFile()) {
1392 switch (insn
->src(1).getFile()) {
1394 emitInsn(0x5ba00000);
1395 emitGPR (0x14, insn
->src(1));
1397 case FILE_MEMORY_CONST
:
1398 emitInsn(0x4ba00000);
1399 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1401 case FILE_IMMEDIATE
:
1402 emitInsn(0x36a00000);
1403 emitIMMD(0x14, 19, insn
->src(1));
1406 assert(!"bad src1 file");
1409 emitGPR (0x27, insn
->src(2));
1411 case FILE_MEMORY_CONST
:
1412 emitInsn(0x53a00000);
1413 emitGPR (0x27, insn
->src(1));
1414 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1417 assert(!"bad src2 file");
1421 emitCond4(0x30, cc
);
1423 emitGPR (0x08, insn
->src(0));
1424 emitGPR (0x00, insn
->def(0));
1428 CodeEmitterGM107::emitFSET()
1430 const CmpInstruction
*insn
= this->insn
->asCmp();
1432 switch (insn
->src(1).getFile()) {
1434 emitInsn(0x58000000);
1435 emitGPR (0x14, insn
->src(1));
1437 case FILE_MEMORY_CONST
:
1438 emitInsn(0x48000000);
1439 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1441 case FILE_IMMEDIATE
:
1442 emitInsn(0x30000000);
1443 emitIMMD(0x14, 19, insn
->src(1));
1446 assert(!"bad src1 file");
1450 if (insn
->op
!= OP_SET
) {
1452 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1453 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1454 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1456 assert(!"invalid set op");
1459 emitPRED(0x27, insn
->src(2));
1465 emitABS (0x36, insn
->src(0));
1466 emitNEG (0x35, insn
->src(1));
1467 emitField(0x34, 1, insn
->dType
== TYPE_F32
);
1468 emitCond4(0x30, insn
->setCond
);
1470 emitABS (0x2c, insn
->src(1));
1471 emitNEG (0x2b, insn
->src(0));
1472 emitGPR (0x08, insn
->src(0));
1473 emitGPR (0x00, insn
->def(0));
1477 CodeEmitterGM107::emitFSETP()
1479 const CmpInstruction
*insn
= this->insn
->asCmp();
1481 switch (insn
->src(1).getFile()) {
1483 emitInsn(0x5bb00000);
1484 emitGPR (0x14, insn
->src(1));
1486 case FILE_MEMORY_CONST
:
1487 emitInsn(0x4bb00000);
1488 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1490 case FILE_IMMEDIATE
:
1491 emitInsn(0x36b00000);
1492 emitIMMD(0x14, 19, insn
->src(1));
1495 assert(!"bad src1 file");
1499 if (insn
->op
!= OP_SET
) {
1501 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1502 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1503 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1505 assert(!"invalid set op");
1508 emitPRED(0x27, insn
->src(2));
1513 emitCond4(0x30, insn
->setCond
);
1515 emitABS (0x2c, insn
->src(1));
1516 emitNEG (0x2b, insn
->src(0));
1517 emitGPR (0x08, insn
->src(0));
1518 emitABS (0x07, insn
->src(0));
1519 emitNEG (0x06, insn
->src(1));
1520 emitPRED (0x03, insn
->def(0));
1521 if (insn
->defExists(1))
1522 emitPRED(0x00, insn
->def(1));
1528 CodeEmitterGM107::emitFSWZADD()
1530 emitInsn (0x50f80000);
1534 emitField(0x26, 1, insn
->lanes
); /* abused for .ndv */
1535 emitField(0x1c, 8, insn
->subOp
);
1536 emitGPR (0x14, insn
->src(1));
1537 emitGPR (0x08, insn
->src(0));
1538 emitGPR (0x00, insn
->def(0));
1541 /*******************************************************************************
1543 ******************************************************************************/
1546 CodeEmitterGM107::emitLOP()
1551 case OP_AND
: lop
= 0; break;
1552 case OP_OR
: lop
= 1; break;
1553 case OP_XOR
: lop
= 2; break;
1555 assert(!"invalid lop");
1559 if (!longIMMD(insn
->src(1))) {
1560 switch (insn
->src(1).getFile()) {
1562 emitInsn(0x5c400000);
1563 emitGPR (0x14, insn
->src(1));
1565 case FILE_MEMORY_CONST
:
1566 emitInsn(0x4c400000);
1567 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1569 case FILE_IMMEDIATE
:
1570 emitInsn(0x38400000);
1571 emitIMMD(0x14, 19, insn
->src(1));
1574 assert(!"bad src1 file");
1579 emitField(0x29, 2, lop
);
1580 emitINV (0x28, insn
->src(1));
1581 emitINV (0x27, insn
->src(0));
1583 emitInsn (0x04000000);
1585 emitINV (0x38, insn
->src(1));
1586 emitINV (0x37, insn
->src(0));
1587 emitField(0x35, 2, lop
);
1588 emitIMMD (0x14, 32, insn
->src(1));
1591 emitGPR (0x08, insn
->src(0));
1592 emitGPR (0x00, insn
->def(0));
1595 /* special-case of emitLOP(): lop pass_b dst 0 ~src */
1597 CodeEmitterGM107::emitNOT()
1599 if (!longIMMD(insn
->src(0))) {
1600 switch (insn
->src(0).getFile()) {
1602 emitInsn(0x5c400700);
1603 emitGPR (0x14, insn
->src(0));
1605 case FILE_MEMORY_CONST
:
1606 emitInsn(0x4c400700);
1607 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1609 case FILE_IMMEDIATE
:
1610 emitInsn(0x38400700);
1611 emitIMMD(0x14, 19, insn
->src(0));
1614 assert(!"bad src1 file");
1619 emitInsn (0x05600000);
1620 emitIMMD (0x14, 32, insn
->src(1));
1624 emitGPR(0x00, insn
->def(0));
1628 CodeEmitterGM107::emitIADD()
1630 if (!longIMMD(insn
->src(1))) {
1631 switch (insn
->src(1).getFile()) {
1633 emitInsn(0x5c100000);
1634 emitGPR (0x14, insn
->src(1));
1636 case FILE_MEMORY_CONST
:
1637 emitInsn(0x4c100000);
1638 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1640 case FILE_IMMEDIATE
:
1641 emitInsn(0x38100000);
1642 emitIMMD(0x14, 19, insn
->src(1));
1645 assert(!"bad src1 file");
1649 emitNEG(0x31, insn
->src(0));
1650 emitNEG(0x30, insn
->src(1));
1654 emitInsn(0x1c000000);
1658 emitIMMD(0x14, 32, insn
->src(1));
1661 if (insn
->op
== OP_SUB
)
1662 code
[1] ^= 0x00010000;
1664 emitGPR(0x08, insn
->src(0));
1665 emitGPR(0x00, insn
->def(0));
1669 CodeEmitterGM107::emitIMUL()
1671 if (!longIMMD(insn
->src(1))) {
1672 switch (insn
->src(1).getFile()) {
1674 emitInsn(0x5c380000);
1675 emitGPR (0x14, insn
->src(1));
1677 case FILE_MEMORY_CONST
:
1678 emitInsn(0x4c380000);
1679 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1681 case FILE_IMMEDIATE
:
1682 emitInsn(0x38380000);
1683 emitIMMD(0x14, 19, insn
->src(1));
1686 assert(!"bad src1 file");
1690 emitField(0x29, 1, isSignedType(insn
->sType
));
1691 emitField(0x28, 1, isSignedType(insn
->dType
));
1692 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1694 emitInsn (0x1f000000);
1695 emitField(0x37, 1, isSignedType(insn
->sType
));
1696 emitField(0x36, 1, isSignedType(insn
->dType
));
1697 emitField(0x35, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1699 emitIMMD (0x14, 32, insn
->src(1));
1702 emitGPR(0x08, insn
->src(0));
1703 emitGPR(0x00, insn
->def(0));
1707 CodeEmitterGM107::emitIMAD()
1709 /*XXX: imad32i exists, but not using it as third src overlaps dst */
1710 switch(insn
->src(2).getFile()) {
1712 switch (insn
->src(1).getFile()) {
1714 emitInsn(0x5a000000);
1715 emitGPR (0x14, insn
->src(1));
1717 case FILE_MEMORY_CONST
:
1718 emitInsn(0x4a000000);
1719 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1721 case FILE_IMMEDIATE
:
1722 emitInsn(0x34000000);
1723 emitIMMD(0x14, 19, insn
->src(1));
1726 assert(!"bad src1 file");
1729 emitGPR (0x27, insn
->src(2));
1731 case FILE_MEMORY_CONST
:
1732 emitInsn(0x52000000);
1733 emitGPR (0x27, insn
->src(1));
1734 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1737 assert(!"bad src2 file");
1741 emitField(0x36, 1, insn
->subOp
== NV50_IR_SUBOP_MUL_HIGH
);
1742 emitField(0x35, 1, isSignedType(insn
->sType
));
1743 emitNEG (0x34, insn
->src(2));
1744 emitNEG2 (0x33, insn
->src(0), insn
->src(1));
1747 emitField(0x30, 1, isSignedType(insn
->dType
));
1749 emitGPR (0x08, insn
->src(0));
1750 emitGPR (0x00, insn
->def(0));
1754 CodeEmitterGM107::emitIMNMX()
1756 switch (insn
->src(1).getFile()) {
1758 emitInsn(0x5c200000);
1759 emitGPR (0x14, insn
->src(1));
1761 case FILE_MEMORY_CONST
:
1762 emitInsn(0x4c200000);
1763 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1765 case FILE_IMMEDIATE
:
1766 emitInsn(0x38200000);
1767 emitIMMD(0x14, 19, insn
->src(1));
1770 assert(!"bad src1 file");
1774 emitField(0x30, 1, isSignedType(insn
->dType
));
1776 emitField(0x2a, 1, insn
->op
== OP_MAX
);
1778 emitGPR (0x08, insn
->src(0));
1779 emitGPR (0x00, insn
->def(0));
1783 CodeEmitterGM107::emitICMP()
1785 const CmpInstruction
*insn
= this->insn
->asCmp();
1786 CondCode cc
= insn
->setCond
;
1788 if (insn
->src(2).mod
.neg())
1789 cc
= reverseCondCode(cc
);
1791 switch(insn
->src(2).getFile()) {
1793 switch (insn
->src(1).getFile()) {
1795 emitInsn(0x5b400000);
1796 emitGPR (0x14, insn
->src(1));
1798 case FILE_MEMORY_CONST
:
1799 emitInsn(0x4b400000);
1800 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1802 case FILE_IMMEDIATE
:
1803 emitInsn(0x36400000);
1804 emitIMMD(0x14, 19, insn
->src(1));
1807 assert(!"bad src1 file");
1810 emitGPR (0x27, insn
->src(2));
1812 case FILE_MEMORY_CONST
:
1813 emitInsn(0x53400000);
1814 emitGPR (0x27, insn
->src(1));
1815 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
1818 assert(!"bad src2 file");
1822 emitCond3(0x31, cc
);
1823 emitField(0x30, 1, isSignedType(insn
->sType
));
1824 emitGPR (0x08, insn
->src(0));
1825 emitGPR (0x00, insn
->def(0));
1829 CodeEmitterGM107::emitISET()
1831 const CmpInstruction
*insn
= this->insn
->asCmp();
1833 switch (insn
->src(1).getFile()) {
1835 emitInsn(0x5b500000);
1836 emitGPR (0x14, insn
->src(1));
1838 case FILE_MEMORY_CONST
:
1839 emitInsn(0x4b500000);
1840 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1842 case FILE_IMMEDIATE
:
1843 emitInsn(0x36500000);
1844 emitIMMD(0x14, 19, insn
->src(1));
1847 assert(!"bad src1 file");
1851 if (insn
->op
!= OP_SET
) {
1853 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1854 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1855 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1857 assert(!"invalid set op");
1860 emitPRED(0x27, insn
->src(2));
1865 emitCond3(0x31, insn
->setCond
);
1866 emitField(0x30, 1, isSignedType(insn
->sType
));
1868 emitField(0x2c, 1, insn
->dType
== TYPE_F32
);
1870 emitGPR (0x08, insn
->src(0));
1871 emitGPR (0x00, insn
->def(0));
1875 CodeEmitterGM107::emitISETP()
1877 const CmpInstruction
*insn
= this->insn
->asCmp();
1879 switch (insn
->src(1).getFile()) {
1881 emitInsn(0x5b600000);
1882 emitGPR (0x14, insn
->src(1));
1884 case FILE_MEMORY_CONST
:
1885 emitInsn(0x4b600000);
1886 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1888 case FILE_IMMEDIATE
:
1889 emitInsn(0x36600000);
1890 emitIMMD(0x14, 19, insn
->src(1));
1893 assert(!"bad src1 file");
1897 if (insn
->op
!= OP_SET
) {
1899 case OP_SET_AND
: emitField(0x2d, 2, 0); break;
1900 case OP_SET_OR
: emitField(0x2d, 2, 1); break;
1901 case OP_SET_XOR
: emitField(0x2d, 2, 2); break;
1903 assert(!"invalid set op");
1906 emitPRED(0x27, insn
->src(2));
1911 emitCond3(0x31, insn
->setCond
);
1912 emitField(0x30, 1, isSignedType(insn
->sType
));
1914 emitGPR (0x08, insn
->src(0));
1915 emitPRED (0x03, insn
->def(0));
1916 if (insn
->defExists(1))
1917 emitPRED(0x00, insn
->def(1));
1923 CodeEmitterGM107::emitSHL()
1925 switch (insn
->src(1).getFile()) {
1927 emitInsn(0x5c480000);
1928 emitGPR (0x14, insn
->src(1));
1930 case FILE_MEMORY_CONST
:
1931 emitInsn(0x4c480000);
1932 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1934 case FILE_IMMEDIATE
:
1935 emitInsn(0x38480000);
1936 emitIMMD(0x14, 19, insn
->src(1));
1939 assert(!"bad src1 file");
1945 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1946 emitGPR (0x08, insn
->src(0));
1947 emitGPR (0x00, insn
->def(0));
1951 CodeEmitterGM107::emitSHR()
1953 switch (insn
->src(1).getFile()) {
1955 emitInsn(0x5c280000);
1956 emitGPR (0x14, insn
->src(1));
1958 case FILE_MEMORY_CONST
:
1959 emitInsn(0x4c280000);
1960 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
1962 case FILE_IMMEDIATE
:
1963 emitInsn(0x38280000);
1964 emitIMMD(0x14, 19, insn
->src(1));
1967 assert(!"bad src1 file");
1971 emitField(0x30, 1, isSignedType(insn
->dType
));
1974 emitField(0x27, 1, insn
->subOp
== NV50_IR_SUBOP_SHIFT_WRAP
);
1975 emitGPR (0x08, insn
->src(0));
1976 emitGPR (0x00, insn
->def(0));
1980 CodeEmitterGM107::emitPOPC()
1982 switch (insn
->src(0).getFile()) {
1984 emitInsn(0x5c080000);
1985 emitGPR (0x14, insn
->src(0));
1987 case FILE_MEMORY_CONST
:
1988 emitInsn(0x4c080000);
1989 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
1991 case FILE_IMMEDIATE
:
1992 emitInsn(0x38080000);
1993 emitIMMD(0x14, 19, insn
->src(0));
1996 assert(!"bad src1 file");
2000 emitINV(0x28, insn
->src(0));
2001 emitGPR(0x00, insn
->def(0));
2005 CodeEmitterGM107::emitBFI()
2007 switch(insn
->src(2).getFile()) {
2009 switch (insn
->src(1).getFile()) {
2011 emitInsn(0x5bf00000);
2012 emitGPR (0x14, insn
->src(1));
2014 case FILE_MEMORY_CONST
:
2015 emitInsn(0x4bf00000);
2016 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2018 case FILE_IMMEDIATE
:
2019 emitInsn(0x36f00000);
2020 emitIMMD(0x14, 19, insn
->src(1));
2023 assert(!"bad src1 file");
2026 emitGPR (0x27, insn
->src(2));
2028 case FILE_MEMORY_CONST
:
2029 emitInsn(0x53f00000);
2030 emitGPR (0x27, insn
->src(1));
2031 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(2));
2034 assert(!"bad src2 file");
2039 emitGPR (0x08, insn
->src(0));
2040 emitGPR (0x00, insn
->def(0));
2044 CodeEmitterGM107::emitBFE()
2046 switch (insn
->src(1).getFile()) {
2048 emitInsn(0x5c000000);
2049 emitGPR (0x14, insn
->src(1));
2051 case FILE_MEMORY_CONST
:
2052 emitInsn(0x4c000000);
2053 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2055 case FILE_IMMEDIATE
:
2056 emitInsn(0x38000000);
2057 emitIMMD(0x14, 19, insn
->src(1));
2060 assert(!"bad src1 file");
2064 emitField(0x30, 1, isSignedType(insn
->dType
));
2066 emitField(0x28, 1, insn
->subOp
== NV50_IR_SUBOP_EXTBF_REV
);
2067 emitGPR (0x08, insn
->src(0));
2068 emitGPR (0x00, insn
->def(0));
2072 CodeEmitterGM107::emitFLO()
2074 switch (insn
->src(0).getFile()) {
2076 emitInsn(0x5c300000);
2077 emitGPR (0x14, insn
->src(0));
2079 case FILE_MEMORY_CONST
:
2080 emitInsn(0x4c300000);
2081 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(0));
2083 case FILE_IMMEDIATE
:
2084 emitInsn(0x38300000);
2085 emitIMMD(0x14, 19, insn
->src(0));
2088 assert(!"bad src1 file");
2092 emitField(0x30, 1, isSignedType(insn
->dType
));
2094 emitField(0x29, 1, insn
->subOp
== NV50_IR_SUBOP_BFIND_SAMT
);
2095 emitINV (0x28, insn
->src(0));
2096 emitGPR (0x00, insn
->def(0));
2099 /*******************************************************************************
2101 ******************************************************************************/
2104 CodeEmitterGM107::emitLDSTs(int pos
, DataType type
)
2108 switch (typeSizeof(type
)) {
2109 case 1: data
= isSignedType(type
) ? 1 : 0; break;
2110 case 2: data
= isSignedType(type
) ? 3 : 2; break;
2111 case 4: data
= 4; break;
2112 case 8: data
= 5; break;
2113 case 16: data
= 6; break;
2115 assert(!"bad type");
2119 emitField(pos
, 3, data
);
2123 CodeEmitterGM107::emitLDSTc(int pos
)
2127 switch (insn
->cache
) {
2128 case CACHE_CA
: mode
= 0; break;
2129 case CACHE_CG
: mode
= 1; break;
2130 case CACHE_CS
: mode
= 2; break;
2131 case CACHE_CV
: mode
= 3; break;
2133 assert(!"invalid caching mode");
2137 emitField(pos
, 2, mode
);
2141 CodeEmitterGM107::emitLDC()
2143 emitInsn (0xef900000);
2144 emitLDSTs(0x30, insn
->dType
);
2145 emitField(0x2c, 2, insn
->subOp
);
2146 emitCBUF (0x24, 0x08, 0x14, 16, 0, insn
->src(0));
2147 emitGPR (0x00, insn
->def(0));
2151 CodeEmitterGM107::emitLDL()
2153 emitInsn (0xef400000);
2154 emitLDSTs(0x30, insn
->dType
);
2156 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2157 emitGPR (0x00, insn
->def(0));
2161 CodeEmitterGM107::emitLDS()
2163 emitInsn (0xef480000);
2164 emitLDSTs(0x30, insn
->dType
);
2165 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2166 emitGPR (0x00, insn
->def(0));
2170 CodeEmitterGM107::emitLD()
2172 emitInsn (0x80000000);
2175 emitLDSTs(0x35, insn
->dType
);
2176 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2177 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2178 emitGPR (0x00, insn
->def(0));
2182 CodeEmitterGM107::emitSTL()
2184 emitInsn (0xef500000);
2185 emitLDSTs(0x30, insn
->dType
);
2187 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2188 emitGPR (0x00, insn
->src(1));
2192 CodeEmitterGM107::emitSTS()
2194 emitInsn (0xef580000);
2195 emitLDSTs(0x30, insn
->dType
);
2196 emitADDR (0x08, 0x14, 24, 0, insn
->src(0));
2197 emitGPR (0x00, insn
->src(1));
2201 CodeEmitterGM107::emitST()
2203 emitInsn (0xa0000000);
2206 emitLDSTs(0x35, insn
->dType
);
2207 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2208 emitADDR (0x08, 0x14, 32, 0, insn
->src(0));
2209 emitGPR (0x00, insn
->src(1));
2213 CodeEmitterGM107::emitALD()
2215 emitInsn (0xefd80000);
2216 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2217 emitGPR (0x27, insn
->src(0).getIndirect(1));
2220 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2221 emitGPR (0x00, insn
->def(0));
2225 CodeEmitterGM107::emitAST()
2227 emitInsn (0xeff00000);
2228 emitField(0x2f, 2, (typeSizeof(insn
->dType
) / 4) - 1);
2229 emitGPR (0x27, insn
->src(0).getIndirect(1));
2231 emitADDR (0x08, 20, 10, 0, insn
->src(0));
2232 emitGPR (0x00, insn
->src(1));
2236 CodeEmitterGM107::emitISBERD()
2238 emitInsn(0xefd00000);
2239 emitGPR (0x08, insn
->src(0));
2240 emitGPR (0x00, insn
->def(0));
2244 CodeEmitterGM107::emitAL2P()
2246 emitInsn (0xefa00000);
2247 emitField(0x2f, 2, (insn
->getDef(0)->reg
.size
/ 4) - 1);
2249 emitField(0x14, 11, insn
->src(0).get()->reg
.data
.offset
);
2250 emitGPR (0x08, insn
->src(0).getIndirect(0));
2251 emitGPR (0x00, insn
->def(0));
2255 interpApply(const InterpEntry
*entry
, uint32_t *code
,
2256 bool force_persample_interp
, bool flatshade
)
2258 int ipa
= entry
->ipa
;
2259 int reg
= entry
->reg
;
2260 int loc
= entry
->loc
;
2263 (ipa
& NV50_IR_INTERP_MODE_MASK
) == NV50_IR_INTERP_SC
) {
2264 ipa
= NV50_IR_INTERP_FLAT
;
2266 } else if (force_persample_interp
&&
2267 (ipa
& NV50_IR_INTERP_SAMPLE_MASK
) == NV50_IR_INTERP_DEFAULT
&&
2268 (ipa
& NV50_IR_INTERP_MODE_MASK
) != NV50_IR_INTERP_FLAT
) {
2269 ipa
|= NV50_IR_INTERP_CENTROID
;
2271 code
[loc
+ 1] &= ~(0xf << 0x14);
2272 code
[loc
+ 1] |= (ipa
& 0x3) << 0x16;
2273 code
[loc
+ 1] |= (ipa
& 0xc) << (0x14 - 2);
2274 code
[loc
+ 0] &= ~(0xff << 0x14);
2275 code
[loc
+ 0] |= reg
<< 0x14;
2279 CodeEmitterGM107::emitIPA()
2281 int ipam
= 0, ipas
= 0;
2283 switch (insn
->getInterpMode()) {
2284 case NV50_IR_INTERP_LINEAR
: ipam
= 0; break;
2285 case NV50_IR_INTERP_PERSPECTIVE
: ipam
= 1; break;
2286 case NV50_IR_INTERP_FLAT
: ipam
= 2; break;
2287 case NV50_IR_INTERP_SC
: ipam
= 3; break;
2289 assert(!"invalid ipa mode");
2293 switch (insn
->getSampleMode()) {
2294 case NV50_IR_INTERP_DEFAULT
: ipas
= 0; break;
2295 case NV50_IR_INTERP_CENTROID
: ipas
= 1; break;
2296 case NV50_IR_INTERP_OFFSET
: ipas
= 2; break;
2298 assert(!"invalid ipa sample mode");
2302 emitInsn (0xe0000000);
2303 emitField(0x36, 2, ipam
);
2304 emitField(0x34, 2, ipas
);
2306 emitField(0x2f, 3, 7);
2307 emitADDR (0x08, 0x1c, 10, 0, insn
->src(0));
2308 if ((code
[0] & 0x0000ff00) != 0x0000ff00)
2309 code
[1] |= 0x00000040; /* .idx */
2310 emitGPR(0x00, insn
->def(0));
2312 if (insn
->op
== OP_PINTERP
) {
2313 emitGPR(0x14, insn
->src(1));
2314 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2315 emitGPR(0x27, insn
->src(2));
2316 addInterp(insn
->ipa
, insn
->getSrc(1)->reg
.data
.id
, interpApply
);
2318 if (insn
->getSampleMode() == NV50_IR_INTERP_OFFSET
)
2319 emitGPR(0x27, insn
->src(1));
2321 addInterp(insn
->ipa
, 0xff, interpApply
);
2324 if (insn
->getSampleMode() != NV50_IR_INTERP_OFFSET
)
2329 CodeEmitterGM107::emitATOM()
2331 unsigned dType
, subOp
;
2332 switch (insn
->dType
) {
2333 case TYPE_U32
: dType
= 0; break;
2334 case TYPE_S32
: dType
= 1; break;
2335 case TYPE_U64
: dType
= 2; break;
2336 case TYPE_F32
: dType
= 3; break;
2337 case TYPE_B128
: dType
= 4; break;
2338 case TYPE_S64
: dType
= 5; break;
2339 default: assert(!"unexpected dType"); dType
= 0; break;
2341 if (insn
->subOp
== NV50_IR_SUBOP_ATOM_EXCH
)
2344 subOp
= insn
->subOp
;
2345 assert(insn
->subOp
!= NV50_IR_SUBOP_ATOM_CAS
); /* XXX */
2347 emitInsn (0xed000000);
2348 emitField(0x34, 4, subOp
);
2349 emitField(0x31, 3, dType
);
2350 emitField(0x30, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2351 emitGPR (0x14, insn
->src(1));
2352 emitADDR (0x08, 0x1c, 20, 0, insn
->src(0));
2353 emitGPR (0x00, insn
->def(0));
2357 CodeEmitterGM107::emitCCTL()
2360 if (insn
->src(0).getFile() == FILE_MEMORY_GLOBAL
) {
2361 emitInsn(0xef600000);
2364 emitInsn(0xef800000);
2367 emitField(0x34, 1, insn
->src(0).getIndirect(0)->getSize() == 8);
2368 emitADDR (0x08, 0x16, width
, 2, insn
->src(0));
2369 emitField(0x00, 4, insn
->subOp
);
2372 /*******************************************************************************
2374 ******************************************************************************/
2377 CodeEmitterGM107::emitPIXLD()
2379 emitInsn (0xefe80000);
2381 emitField(0x1f, 3, insn
->subOp
);
2382 emitGPR (0x08, insn
->src(0));
2383 emitGPR (0x00, insn
->def(0));
2386 /*******************************************************************************
2388 ******************************************************************************/
2391 CodeEmitterGM107::emitTEXs(int pos
)
2393 int src1
= insn
->predSrc
== 1 ? 2 : 1;
2394 if (insn
->srcExists(src1
))
2395 emitGPR(pos
, insn
->src(src1
));
2401 CodeEmitterGM107::emitTEX()
2403 const TexInstruction
*insn
= this->insn
->asTex();
2406 if (!insn
->tex
.levelZero
) {
2408 case OP_TEX
: lodm
= 0; break;
2409 case OP_TXB
: lodm
= 2; break;
2410 case OP_TXL
: lodm
= 3; break;
2412 assert(!"invalid tex op");
2419 if (insn
->tex
.rIndirectSrc
>= 0) {
2420 emitInsn (0xdeb80000);
2421 emitField(0x35, 2, lodm
);
2422 emitField(0x24, 1, insn
->tex
.useOffsets
== 1);
2424 emitInsn (0xc0380000);
2425 emitField(0x37, 2, lodm
);
2426 emitField(0x36, 1, insn
->tex
.useOffsets
== 1);
2427 emitField(0x24, 13, insn
->tex
.r
);
2430 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2431 emitField(0x31, 1, insn
->tex
.liveOnly
);
2432 emitField(0x23, 1, insn
->tex
.derivAll
);
2433 emitField(0x1f, 4, insn
->tex
.mask
);
2434 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2435 insn
->tex
.target
.getDim() - 1);
2436 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2438 emitGPR (0x08, insn
->src(0));
2439 emitGPR (0x00, insn
->def(0));
2443 CodeEmitterGM107::emitTLD()
2445 const TexInstruction
*insn
= this->insn
->asTex();
2447 if (insn
->tex
.rIndirectSrc
>= 0) {
2448 emitInsn (0xdd380000);
2450 emitInsn (0xdc380000);
2451 emitField(0x24, 13, insn
->tex
.r
);
2454 emitField(0x37, 1, insn
->tex
.levelZero
== 0);
2455 emitField(0x32, 1, insn
->tex
.target
.isMS());
2456 emitField(0x31, 1, insn
->tex
.liveOnly
);
2457 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2458 emitField(0x1f, 4, insn
->tex
.mask
);
2459 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2460 insn
->tex
.target
.getDim() - 1);
2461 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2463 emitGPR (0x08, insn
->src(0));
2464 emitGPR (0x00, insn
->def(0));
2468 CodeEmitterGM107::emitTLD4()
2470 const TexInstruction
*insn
= this->insn
->asTex();
2472 if (insn
->tex
.rIndirectSrc
>= 0) {
2473 emitInsn (0xdef80000);
2474 emitField(0x26, 2, insn
->tex
.gatherComp
);
2475 emitField(0x25, 2, insn
->tex
.useOffsets
== 4);
2476 emitField(0x24, 2, insn
->tex
.useOffsets
== 1);
2478 emitInsn (0xc8380000);
2479 emitField(0x38, 2, insn
->tex
.gatherComp
);
2480 emitField(0x37, 2, insn
->tex
.useOffsets
== 4);
2481 emitField(0x36, 2, insn
->tex
.useOffsets
== 1);
2482 emitField(0x24, 13, insn
->tex
.r
);
2485 emitField(0x32, 1, insn
->tex
.target
.isShadow());
2486 emitField(0x31, 1, insn
->tex
.liveOnly
);
2487 emitField(0x23, 1, insn
->tex
.derivAll
);
2488 emitField(0x1f, 4, insn
->tex
.mask
);
2489 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2490 insn
->tex
.target
.getDim() - 1);
2491 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2493 emitGPR (0x08, insn
->src(0));
2494 emitGPR (0x00, insn
->def(0));
2498 CodeEmitterGM107::emitTXD()
2500 const TexInstruction
*insn
= this->insn
->asTex();
2502 if (insn
->tex
.rIndirectSrc
>= 0) {
2503 emitInsn (0xde780000);
2505 emitInsn (0xde380000);
2506 emitField(0x24, 13, insn
->tex
.r
);
2509 emitField(0x31, 1, insn
->tex
.liveOnly
);
2510 emitField(0x23, 1, insn
->tex
.useOffsets
== 1);
2511 emitField(0x1f, 4, insn
->tex
.mask
);
2512 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2513 insn
->tex
.target
.getDim() - 1);
2514 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2516 emitGPR (0x08, insn
->src(0));
2517 emitGPR (0x00, insn
->def(0));
2521 CodeEmitterGM107::emitTMML()
2523 const TexInstruction
*insn
= this->insn
->asTex();
2525 if (insn
->tex
.rIndirectSrc
>= 0) {
2526 emitInsn (0xdf600000);
2528 emitInsn (0xdf580000);
2529 emitField(0x24, 13, insn
->tex
.r
);
2532 emitField(0x31, 1, insn
->tex
.liveOnly
);
2533 emitField(0x23, 1, insn
->tex
.derivAll
);
2534 emitField(0x1f, 4, insn
->tex
.mask
);
2535 emitField(0x1d, 2, insn
->tex
.target
.isCube() ? 3 :
2536 insn
->tex
.target
.getDim() - 1);
2537 emitField(0x1c, 1, insn
->tex
.target
.isArray());
2539 emitGPR (0x08, insn
->src(0));
2540 emitGPR (0x00, insn
->def(0));
2544 CodeEmitterGM107::emitTXQ()
2546 const TexInstruction
*insn
= this->insn
->asTex();
2549 switch (insn
->tex
.query
) {
2550 case TXQ_DIMS
: type
= 0x01; break;
2551 case TXQ_TYPE
: type
= 0x02; break;
2552 case TXQ_SAMPLE_POSITION
: type
= 0x05; break;
2553 case TXQ_FILTER
: type
= 0x10; break;
2554 case TXQ_LOD
: type
= 0x12; break;
2555 case TXQ_WRAP
: type
= 0x14; break;
2556 case TXQ_BORDER_COLOUR
: type
= 0x16; break;
2558 assert(!"invalid txq query");
2562 if (insn
->tex
.rIndirectSrc
>= 0) {
2563 emitInsn (0xdf500000);
2565 emitInsn (0xdf480000);
2566 emitField(0x24, 13, insn
->tex
.r
);
2569 emitField(0x31, 1, insn
->tex
.liveOnly
);
2570 emitField(0x1f, 4, insn
->tex
.mask
);
2571 emitField(0x16, 6, type
);
2572 emitGPR (0x08, insn
->src(0));
2573 emitGPR (0x00, insn
->def(0));
2577 CodeEmitterGM107::emitDEPBAR()
2579 emitInsn (0xf0f00000);
2580 emitField(0x1d, 1, 1); /* le */
2581 emitField(0x1a, 3, 5);
2582 emitField(0x14, 6, insn
->subOp
);
2583 emitField(0x00, 6, insn
->subOp
);
2586 /*******************************************************************************
2588 ******************************************************************************/
2591 CodeEmitterGM107::emitNOP()
2593 emitInsn(0x50b00000);
2597 CodeEmitterGM107::emitKIL()
2599 emitInsn (0xe3300000);
2600 emitCond5(0x00, CC_TR
);
2604 CodeEmitterGM107::emitOUT()
2606 const int cut
= insn
->op
== OP_RESTART
|| insn
->subOp
;
2607 const int emit
= insn
->op
== OP_EMIT
;
2609 switch (insn
->src(1).getFile()) {
2611 emitInsn(0xfbe00000);
2612 emitGPR (0x14, insn
->src(1));
2614 case FILE_IMMEDIATE
:
2615 emitInsn(0xf6e00000);
2616 emitIMMD(0x14, 19, insn
->src(1));
2618 case FILE_MEMORY_CONST
:
2619 emitInsn(0xebe00000);
2620 emitCBUF(0x22, -1, 0x14, 16, 2, insn
->src(1));
2623 assert(!"bad src1 file");
2627 emitField(0x27, 2, (cut
<< 1) | emit
);
2628 emitGPR (0x08, insn
->src(0));
2629 emitGPR (0x00, insn
->def(0));
2633 CodeEmitterGM107::emitMEMBAR()
2635 emitInsn (0xef980000);
2636 emitField(0x08, 2, insn
->subOp
>> 2);
2639 /*******************************************************************************
2640 * assembler front-end
2641 ******************************************************************************/
2644 CodeEmitterGM107::emitInstruction(Instruction
*i
)
2646 const unsigned int size
= (writeIssueDelays
&& !(codeSize
& 0x1f)) ? 16 : 8;
2651 if (insn
->encSize
!= 8) {
2652 ERROR("skipping undecodable instruction: "); insn
->print();
2655 if (codeSize
+ size
> codeSizeLimit
) {
2656 ERROR("code emitter output buffer too small\n");
2660 if (writeIssueDelays
) {
2661 int n
= ((codeSize
& 0x1f) / 8) - 1;
2664 data
[0] = 0x00000000;
2665 data
[1] = 0x00000000;
2671 emitField(data
, n
* 21, 21, insn
->sched
);
2727 if (insn
->op
== OP_CVT
&& (insn
->def(0).getFile() == FILE_PREDICATE
||
2728 insn
->src(0).getFile() == FILE_PREDICATE
)) {
2730 } else if (isFloatType(insn
->dType
)) {
2731 if (isFloatType(insn
->sType
))
2736 if (isFloatType(insn
->sType
))
2747 if (isFloatType(insn
->dType
)) {
2748 if (insn
->dType
== TYPE_F64
)
2757 if (isFloatType(insn
->dType
)) {
2758 if (insn
->dType
== TYPE_F64
)
2768 if (isFloatType(insn
->dType
)) {
2769 if (insn
->dType
== TYPE_F64
)
2779 if (isFloatType(insn
->dType
)) {
2780 if (insn
->dType
== TYPE_F64
)
2807 if (isFloatType(insn
->dType
))
2816 if (insn
->def(0).getFile() != FILE_PREDICATE
) {
2817 if (isFloatType(insn
->sType
))
2818 if (insn
->sType
== TYPE_F64
)
2825 if (isFloatType(insn
->sType
))
2826 if (insn
->sType
== TYPE_F64
)
2855 switch (insn
->src(0).getFile()) {
2856 case FILE_MEMORY_CONST
: emitLDC(); break;
2857 case FILE_MEMORY_LOCAL
: emitLDL(); break;
2858 case FILE_MEMORY_SHARED
: emitLDS(); break;
2859 case FILE_MEMORY_GLOBAL
: emitLD(); break;
2861 assert(!"invalid load");
2867 switch (insn
->src(0).getFile()) {
2868 case FILE_MEMORY_LOCAL
: emitSTL(); break;
2869 case FILE_MEMORY_SHARED
: emitSTS(); break;
2870 case FILE_MEMORY_GLOBAL
: emitST(); break;
2872 assert(!"invalid load");
2942 assert(!"invalid opcode");
2958 CodeEmitterGM107::getMinEncodingSize(const Instruction
*i
) const
2963 /*******************************************************************************
2964 * sched data calculator
2965 ******************************************************************************/
2967 class SchedDataCalculatorGM107
: public Pass
2970 SchedDataCalculatorGM107(const Target
*targ
) : targ(targ
) {}
2973 bool visit(BasicBlock
*bb
);
2977 SchedDataCalculatorGM107::visit(BasicBlock
*bb
)
2979 for (Instruction
*insn
= bb
->getEntry(); insn
; insn
= insn
->next
) {
2981 insn
->sched
= 0x7e0;
2987 /*******************************************************************************
2989 ******************************************************************************/
2992 CodeEmitterGM107::prepareEmission(Function
*func
)
2994 SchedDataCalculatorGM107
sched(targ
);
2995 CodeEmitter::prepareEmission(func
);
2996 sched
.run(func
, true, true);
2999 static inline uint32_t sizeToBundlesGM107(uint32_t size
)
3001 return (size
+ 23) / 24;
3005 CodeEmitterGM107::prepareEmission(Program
*prog
)
3007 for (ArrayList::Iterator fi
= prog
->allFuncs
.iterator();
3008 !fi
.end(); fi
.next()) {
3009 Function
*func
= reinterpret_cast<Function
*>(fi
.get());
3010 func
->binPos
= prog
->binSize
;
3011 prepareEmission(func
);
3013 // adjust sizes & positions for schedulding info:
3014 if (prog
->getTarget()->hasSWSched
) {
3015 uint32_t adjPos
= func
->binPos
;
3016 BasicBlock
*bb
= NULL
;
3017 for (int i
= 0; i
< func
->bbCount
; ++i
) {
3018 bb
= func
->bbArray
[i
];
3019 int32_t adjSize
= bb
->binSize
;
3021 adjSize
-= 32 - adjPos
% 32;
3025 adjSize
= bb
->binSize
+ sizeToBundlesGM107(adjSize
) * 8;
3026 bb
->binPos
= adjPos
;
3027 bb
->binSize
= adjSize
;
3031 func
->binSize
= adjPos
- func
->binPos
;
3034 prog
->binSize
+= func
->binSize
;
3038 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107
*target
)
3039 : CodeEmitter(target
),
3041 writeIssueDelays(target
->hasSWSched
)
3044 codeSize
= codeSizeLimit
= 0;
3049 TargetGM107::createCodeEmitterGM107(Program::Type type
)
3051 CodeEmitterGM107
*emit
= new CodeEmitterGM107(this);
3052 emit
->setProgramType(type
);
3056 } // namespace nv50_ir