3 #include "nv50_ir_target.h"
7 class CodeEmitterNV50
: public CodeEmitter
10 CodeEmitterNV50(const Target
*);
12 virtual bool emitInstruction(Instruction
*);
14 virtual uint32_t getMinEncodingSize(const Instruction
*) const;
16 inline void setProgramType(Program::Type pType
) { progType
= pType
; }
21 Program::Type progType
;
24 inline void defId(const ValueDef
&, const int pos
);
25 inline void srcId(const ValueRef
&, const int pos
);
26 inline void srcId(const ValueRef
*, const int pos
);
28 inline void srcAddr16(const ValueRef
&, const int pos
);
29 inline void srcAddr8(const ValueRef
&, const int pos
);
31 void emitFlagsRd(const Instruction
*);
32 void emitFlagsWr(const Instruction
*);
34 void emitCondCode(CondCode cc
, int pos
);
36 inline void setARegBits(unsigned int);
38 void setAReg16(const Instruction
*, int s
);
39 void setImmediate(const Instruction
*, int s
);
41 void setDst(const Value
*);
42 void setDst(const Instruction
*, int d
);
43 void emitSrc0(const ValueRef
&);
44 void emitSrc1(const ValueRef
&);
45 void emitSrc2(const ValueRef
&);
47 void emitForm_MAD(const Instruction
*);
48 void emitForm_ADD(const Instruction
*);
49 void emitForm_MUL(const Instruction
*);
50 void emitForm_IMM(const Instruction
*);
52 void emitLoadStoreSize(DataType ty
, int pos
);
54 void roundMode_MAD(const Instruction
*);
55 void roundMode_CVT(RoundMode
);
57 void emitMNeg12(const Instruction
*);
59 void emitLOAD(const Instruction
*);
60 void emitSTORE(const Instruction
*);
61 void emitMOV(const Instruction
*);
63 void emitINTERP(const Instruction
*);
64 void emitPFETCH(const Instruction
*);
65 void emitOUT(const Instruction
*);
67 void emitUADD(const Instruction
*);
68 void emitAADD(const Instruction
*);
69 void emitFADD(const Instruction
*);
70 void emitUMUL(const Instruction
*);
71 void emitFMUL(const Instruction
*);
72 void emitFMAD(const Instruction
*);
74 void emitMINMAX(const Instruction
*);
76 void emitPreOp(const Instruction
*);
77 void emitSFnOp(const Instruction
*, uint8_t subOp
);
79 void emitShift(const Instruction
*);
80 void emitARL(const Instruction
*);
81 void emitLogicOp(const Instruction
*);
83 void emitCVT(const Instruction
*);
84 void emitSET(const Instruction
*);
86 void emitTEX(const TexInstruction
*);
88 void emitQUADOP(const Instruction
*, uint8_t lane
, uint8_t quOp
);
90 void emitFlow(const Instruction
*, uint8_t flowOp
);
93 #define SDATA(a) ((a).rep()->reg.data)
94 #define DDATA(a) ((a).rep()->reg.data)
96 void CodeEmitterNV50::srcId(const ValueRef
& src
, const int pos
)
99 code
[pos
/ 32] |= SDATA(src
).id
<< (pos
% 32);
102 void CodeEmitterNV50::srcId(const ValueRef
*src
, const int pos
)
105 code
[pos
/ 32] |= SDATA(*src
).id
<< (pos
% 32);
108 void CodeEmitterNV50::srcAddr16(const ValueRef
& src
, const int pos
)
112 uint32_t offset
= SDATA(src
).offset
;
114 assert(offset
<= 0xffff && (pos
% 32) <= 16);
116 code
[pos
/ 32] |= offset
<< (pos
% 32);
119 void CodeEmitterNV50::srcAddr8(const ValueRef
& src
, const int pos
)
123 uint32_t offset
= SDATA(src
).offset
;
125 assert(offset
<= 0x1fc && !(offset
& 0x3));
127 code
[pos
/ 32] |= (offset
>> 2) << (pos
% 32);
130 void CodeEmitterNV50::defId(const ValueDef
& def
, const int pos
)
133 code
[pos
/ 32] |= DDATA(def
).id
<< (pos
% 32);
137 CodeEmitterNV50::roundMode_MAD(const Instruction
*insn
)
140 case ROUND_M
: code
[1] |= 1 << 22; break;
141 case ROUND_P
: code
[1] |= 2 << 22; break;
142 case ROUND_Z
: code
[1] |= 3 << 22; break;
144 assert(insn
->rnd
== ROUND_N
);
150 CodeEmitterNV50::emitMNeg12(const Instruction
*i
)
152 code
[1] |= i
->src
[0].mod
.neg() << 26;
153 code
[1] |= i
->src
[1].mod
.neg() << 27;
156 void CodeEmitterNV50::emitCondCode(CondCode cc
, int pos
)
160 assert(pos
>= 32 || pos
<= 27);
163 case CC_LT
: enc
= 0x1; break;
164 case CC_LTU
: enc
= 0x9; break;
165 case CC_EQ
: enc
= 0x2; break;
166 case CC_EQU
: enc
= 0xa; break;
167 case CC_LE
: enc
= 0x3; break;
168 case CC_LEU
: enc
= 0xb; break;
169 case CC_GT
: enc
= 0x4; break;
170 case CC_GTU
: enc
= 0xc; break;
171 case CC_NE
: enc
= 0x5; break;
172 case CC_NEU
: enc
= 0xd; break;
173 case CC_GE
: enc
= 0x6; break;
174 case CC_GEU
: enc
= 0xe; break;
175 case CC_TR
: enc
= 0xf; break;
176 case CC_FL
: enc
= 0x0; break;
178 case CC_O
: enc
= 0x10; break;
179 case CC_C
: enc
= 0x11; break;
180 case CC_A
: enc
= 0x12; break;
181 case CC_S
: enc
= 0x13; break;
182 case CC_NS
: enc
= 0x1c; break;
183 case CC_NA
: enc
= 0x1d; break;
184 case CC_NC
: enc
= 0x1e; break;
185 case CC_NO
: enc
= 0x1f; break;
189 assert(!"invalid condition code");
192 code
[pos
/ 32] |= enc
<< (pos
% 32);
196 CodeEmitterNV50::emitFlagsRd(const Instruction
*i
)
198 int s
= (i
->flagsSrc
>= 0) ? i
->flagsSrc
: i
->predSrc
;
200 assert(!(code
[1] & 0x00003f80));
203 assert(i
->getSrc(s
)->reg
.file
== FILE_FLAGS
);
204 emitCondCode(i
->cc
, 32 + 7);
205 srcId(i
->src
[s
], 32 + 12);
212 CodeEmitterNV50::emitFlagsWr(const Instruction
*i
)
214 assert(!(code
[1] & 0x70));
216 if (i
->flagsDef
>= 0)
217 code
[1] |= (DDATA(i
->def
[i
->flagsDef
]).id
<< 4) | 0x40;
221 CodeEmitterNV50::setARegBits(unsigned int u
)
223 code
[0] |= (u
& 3) << 26;
228 CodeEmitterNV50::setAReg16(const Instruction
*i
, int s
)
230 s
= i
->src
[s
].indirect
[0];
232 setARegBits(SDATA(i
->src
[s
]).id
+ 1);
236 CodeEmitterNV50::setImmediate(const Instruction
*i
, int s
)
238 const ImmediateValue
*imm
= i
->src
[s
].get()->asImm();
242 code
[0] |= (imm
->reg
.data
.u32
& 0x3f) << 16;
243 code
[1] |= (imm
->reg
.data
.u32
>> 6) << 2;
247 CodeEmitterNV50::setDst(const Value
*dst
)
249 const Storage
*reg
= &dst
->join
->reg
;
251 assert(reg
->file
!= FILE_ADDRESS
);
253 if (reg
->data
.id
< 0) {
254 code
[0] |= (127 << 2) | 1;
257 if (reg
->file
== FILE_SHADER_OUTPUT
)
259 code
[0] |= reg
->data
.id
<< 2;
264 CodeEmitterNV50::setDst(const Instruction
*i
, int d
)
266 if (i
->defExists(d
)) {
267 setDst(i
->getDef(d
));
270 code
[0] |= 0x01fc; // bit bucket
276 CodeEmitterNV50::emitSrc0(const ValueRef
& ref
)
278 const Storage
*reg
= &ref
.rep()->reg
;
280 if (reg
->file
== FILE_SHADER_INPUT
)
281 code
[1] |= 0x00200000;
283 if (reg
->file
!= FILE_GPR
)
284 ERROR("invalid src0 register file: %d\n", reg
->file
);
286 assert(reg
->data
.id
< 128);
287 code
[0] |= reg
->data
.id
<< 9;
291 CodeEmitterNV50::emitSrc1(const ValueRef
& ref
)
293 const Storage
*reg
= &ref
.rep()->reg
;
295 if (reg
->file
== FILE_MEMORY_CONST
) {
296 assert(!(code
[1] & 0x01800000));
298 code
[1] |= reg
->fileIndex
<< 22;
300 if (reg
->file
!= FILE_GPR
) {
301 ERROR("invalid src1 register file: %d\n", reg
->file
);
304 assert(reg
->data
.id
< 128);
305 code
[0] |= reg
->data
.id
<< 16;
309 CodeEmitterNV50::emitSrc2(const ValueRef
& ref
)
311 const Storage
*reg
= &ref
.rep()->reg
;
313 if (reg
->file
== FILE_MEMORY_CONST
) {
314 assert(!(code
[1] & 0x01800000));
316 code
[1] |= reg
->fileIndex
<< 22;
318 if (reg
->file
!= FILE_GPR
) {
319 ERROR("invalid src1 register file: %d\n", reg
->file
);
322 assert(reg
->data
.id
< 128);
323 code
[1] |= reg
->data
.id
<< 14;
327 // - long instruction
328 // - 1 to 3 sources in slots 0, 1, 2
331 CodeEmitterNV50::emitForm_MAD(const Instruction
*i
)
333 assert(i
->encSize
== 8);
353 // like default form, but 2nd source in slot 2, and no 3rd source
355 CodeEmitterNV50::emitForm_ADD(const Instruction
*i
)
357 assert(i
->encSize
== 8);
374 // default short form
376 CodeEmitterNV50::emitForm_MUL(const Instruction
*i
)
378 assert(i
->encSize
== 4 && !(code
[0] & 1));
379 assert(i
->defExists(0));
380 assert(!i
->getPredicate());
391 // usual immediate form
392 // - 1 to 3 sources where last is immediate
393 // - no address or predicate possible
395 CodeEmitterNV50::emitForm_IMM(const Instruction
*i
)
397 assert(i
->encSize
== 8);
400 assert(i
->defExists(0) && i
->srcExists(0));
404 if (i
->srcExists(2)) {
409 if (i
->srcExists(1)) {
418 CodeEmitterNV50::emitLoadStoreSize(DataType ty
, int pos
)
423 case TYPE_F32
: // fall through
424 case TYPE_S32
: // fall through
425 case TYPE_U32
: enc
= 0x6; break;
426 case TYPE_B128
: enc
= 0x5; break;
427 case TYPE_F64
: enc
= 0x4; break;
428 case TYPE_S16
: enc
= 0x3; break;
429 case TYPE_U16
: enc
= 0x2; break;
430 case TYPE_S8
: enc
= 0x1; break;
431 case TYPE_U8
: enc
= 0x0; break;
434 assert(!"invalid load/store type");
437 code
[pos
/ 32] |= enc
<< (pos
% 32);
441 CodeEmitterNV50::emitLOAD(const Instruction
*i
)
443 DataFile sf
= i
->src
[0].getFile();
446 case FILE_SHADER_INPUT
:
447 code
[0] = 0x10000001;
448 code
[1] = 0x04200000 | (i
->lanes
<< 14);
450 case FILE_MEMORY_CONST
:
451 code
[0] = 0x10000001;
452 code
[1] = 0x24000000 | (i
->getSrc(0)->reg
.fileIndex
<< 22);
454 case FILE_MEMORY_LOCAL
:
455 code
[0] = 0xd0000001;
456 code
[1] = 0x40000000;
458 case FILE_MEMORY_GLOBAL
:
459 code
[0] = 0xd0000001 | (i
->getSrc(0)->reg
.fileIndex
<< 16);
460 code
[1] = 0x80000000;
463 assert(!"invalid load source file");
466 if (sf
== FILE_MEMORY_LOCAL
||
467 sf
== FILE_MEMORY_GLOBAL
)
468 emitLoadStoreSize(i
->sType
, 21 + 32);
475 if (i
->src
[0].getFile() == FILE_MEMORY_GLOBAL
) {
476 srcId(*i
->src
[0].getIndirect(0), 9);
479 srcAddr16(i
->src
[0], 9);
484 CodeEmitterNV50::emitSTORE(const Instruction
*i
)
486 DataFile f
= i
->getSrc(0)->reg
.file
;
487 int32_t offset
= i
->getSrc(0)->reg
.data
.offset
;
490 case FILE_SHADER_OUTPUT
:
491 code
[0] = 0x00000001 | ((offset
>> 2) << 2);
492 code
[1] = 0x80c00000;
493 srcId(i
->src
[1], 32 + 15);
495 case FILE_MEMORY_GLOBAL
:
496 code
[0] = 0xd0000000;
497 code
[1] = 0xa0000000;
498 emitLoadStoreSize(i
->dType
, 21 + 32);
500 case FILE_MEMORY_LOCAL
:
501 code
[0] = 0xd0000001;
502 code
[1] = 0x60000000;
503 emitLoadStoreSize(i
->dType
, 21 + 32);
505 case FILE_MEMORY_SHARED
:
506 code
[0] = 0x00000001;
507 code
[1] = 0xe0000000;
508 switch (typeSizeof(i
->dType
)) {
510 code
[0] |= offset
<< 9;
511 code
[1] |= 0x00400000;
514 code
[0] |= (offset
>> 1) << 9;
517 code
[0] |= (offset
>> 2) << 9;
518 code
[1] |= 0x04000000;
526 assert(!"invalid store destination file");
530 if (f
!= FILE_SHADER_OUTPUT
) {
532 if (f
== FILE_MEMORY_GLOBAL
)
533 srcId(*i
->src
[0].getIndirect(0), 9);
534 if (f
== FILE_MEMORY_LOCAL
)
535 srcAddr16(i
->src
[0], 9);
537 if (f
!= FILE_MEMORY_GLOBAL
)
544 CodeEmitterNV50::emitMOV(const Instruction
*i
)
546 DataFile sf
= i
->getSrc(0)->reg
.file
;
547 DataFile df
= i
->getDef(0)->reg
.file
;
549 assert(sf
== FILE_GPR
|| df
== FILE_GPR
);
551 if (sf
== FILE_FLAGS
) {
552 code
[0] = 0x00000001;
553 code
[1] = 0x20000000;
555 srcId(i
->src
[0], 12);
558 if (sf
== FILE_ADDRESS
) {
559 code
[0] = 0x00000001;
560 code
[1] = 0x40000000;
562 setARegBits(SDATA(i
->src
[0]).id
+ 1);
564 if (df
== FILE_FLAGS
) {
565 code
[0] = 0x00000001;
566 code
[1] = 0xa0000000;
571 if (sf
== FILE_IMMEDIATE
) {
572 code
[0] = 0x10008001;
573 code
[1] = 0x00000003;
576 if (i
->encSize
== 4) {
577 code
[0] = 0x10008000;
579 code
[0] = 0x10000001;
580 code
[1] = 0x04000000 | (i
->lanes
<< 14);
585 if (df
== FILE_SHADER_OUTPUT
) {
586 assert(i
->encSize
== 8);
592 CodeEmitterNV50::emitNOP()
594 code
[0] = 0xf0000001;
595 code
[1] = 0xe0000000;
599 CodeEmitterNV50::emitQUADOP(const Instruction
*i
, uint8_t lane
, uint8_t quOp
)
601 code
[0] = 0xc0000000 | (lane
<< 16);
602 code
[1] = 0x80000000;
604 code
[0] |= (quOp
& 0x03) << 20;
605 code
[1] |= (quOp
& 0xfc) << 20;
609 if (!i
->srcExists(1))
610 srcId(i
->src
[0], 32 + 14);
614 CodeEmitterNV50::emitPFETCH(const Instruction
*i
)
616 code
[0] = 0x11800001;
617 code
[1] = 0x04200000 | (0xf << 14);
620 srcAddr8(i
->src
[0], 9);
625 CodeEmitterNV50::emitINTERP(const Instruction
*i
)
627 code
[0] = 0x80000000;
630 srcAddr8(i
->src
[0], 16);
632 if (i
->getInterpMode() == NV50_IR_INTERP_FLAT
) {
635 if (i
->op
== OP_PINTERP
) {
639 if (i
->getSampleMode() == NV50_IR_INTERP_CENTROID
)
643 if (i
->encSize
== 8) {
646 (code
[0] & (3 << 24)) >> (24 - 16) |
647 (code
[0] & (1 << 8)) >> (18 - 8);
648 code
[0] &= ~0x03000100;
654 CodeEmitterNV50::emitMINMAX(const Instruction
*i
)
656 if (i
->dType
== TYPE_F64
) {
657 code
[0] = 0xe0000000;
658 code
[1] = (i
->op
== OP_MIN
) ? 0xa0000000 : 0xc0000000;
660 code
[0] = 0x30000000;
661 code
[1] = 0x80000000;
663 code
[1] |= 0x20000000;
666 case TYPE_F32
: code
[0] |= 0x80000000; break;
667 case TYPE_S32
: code
[1] |= 0x8c000000; break;
668 case TYPE_U32
: code
[1] |= 0x84000000; break;
669 case TYPE_S16
: code
[1] |= 0x80000000; break;
670 case TYPE_U16
: break;
675 code
[1] |= i
->src
[0].mod
.abs() << 20;
676 code
[1] |= i
->src
[1].mod
.abs() << 19;
682 CodeEmitterNV50::emitFMAD(const Instruction
*i
)
684 const int neg_mul
= i
->src
[0].mod
.neg() ^ i
->src
[1].mod
.neg();
685 const int neg_add
= i
->src
[2].mod
.neg();
687 code
[0] = 0xe0000000;
689 if (i
->encSize
== 4) {
691 assert(!neg_mul
&& !neg_add
);
694 code
[1] |= neg_mul
<< 26;
695 code
[1] |= neg_add
<< 27;
702 CodeEmitterNV50::emitFADD(const Instruction
*i
)
704 const int neg0
= i
->src
[0].mod
.neg();
705 const int neg1
= i
->src
[1].mod
.neg() ^ ((i
->op
== OP_SUB
) ? 1 : 0);
707 code
[0] = 0xb0000000;
709 assert(!(i
->src
[0].mod
| i
->src
[1].mod
).abs());
711 if (i
->src
[1].getFile() == FILE_IMMEDIATE
) {
713 code
[0] |= neg0
<< 15;
714 code
[0] |= neg1
<< 22;
716 if (i
->encSize
== 8) {
718 code
[1] |= neg0
<< 26;
719 code
[1] |= neg1
<< 27;
724 code
[0] |= neg0
<< 15;
725 code
[0] |= neg1
<< 22;
730 CodeEmitterNV50::emitUADD(const Instruction
*i
)
732 code
[0] = 0x20008000;
734 if (i
->src
[0].getFile() == FILE_IMMEDIATE
) {
737 if (i
->encSize
== 8) {
738 code
[0] = 0x20000000;
739 code
[1] = 0x04000000;
744 assert(!(i
->src
[0].mod
.neg() && i
->src
[1].mod
.neg()));
745 code
[0] |= i
->src
[0].mod
.neg() << 28;
746 code
[0] |= i
->src
[1].mod
.neg() << 22;
750 CodeEmitterNV50::emitAADD(const Instruction
*i
)
752 const int s
= (i
->op
== OP_MOV
) ? 0 : 1;
754 code
[0] = 0xd0000001 | (i
->getSrc(s
)->reg
.data
.u16
<< 9);
755 code
[1] = 0x20000000;
757 code
[0] |= (DDATA(i
->def
[0]).id
+ 1) << 2;
761 if (s
&& i
->srcExists(0))
762 setARegBits(SDATA(i
->src
[0]).id
+ 1);
766 CodeEmitterNV50::emitFMUL(const Instruction
*i
)
768 const int neg
= (i
->src
[0].mod
^ i
->src
[1].mod
).neg();
770 code
[0] = 0xc0000000;
772 if (i
->src
[0].getFile() == FILE_IMMEDIATE
) {
777 if (i
->encSize
== 8) {
780 code
[1] |= 0x08000000;
789 CodeEmitterNV50::emitSET(const Instruction
*i
)
791 code
[0] = 0x30000000;
792 code
[1] = 0x60000000;
794 emitCondCode(i
->asCmp()->setCond
, 32 + 14);
797 case TYPE_F32
: code
[0] |= 0x80000000; break;
798 case TYPE_S32
: code
[1] |= 0x0c000000; break;
799 case TYPE_U32
: code
[1] |= 0x04000000; break;
800 case TYPE_S16
: code
[1] |= 0x08000000; break;
801 case TYPE_U16
: break;
810 CodeEmitterNV50::roundMode_CVT(RoundMode rnd
)
813 case ROUND_NI
: code
[1] |= 0x08000000; break;
814 case ROUND_M
: code
[1] |= 0x00020000; break;
815 case ROUND_MI
: code
[1] |= 0x08020000; break;
816 case ROUND_P
: code
[1] |= 0x00040000; break;
817 case ROUND_PI
: code
[1] |= 0x08040000; break;
818 case ROUND_Z
: code
[1] |= 0x00060000; break;
819 case ROUND_ZI
: code
[1] |= 0x08060000; break;
821 assert(rnd
== ROUND_N
);
827 CodeEmitterNV50::emitCVT(const Instruction
*i
)
829 const bool f2f
= isFloatType(i
->dType
) && isFloatType(i
->sType
);
833 case OP_CEIL
: rnd
= f2f
? ROUND_PI
: ROUND_P
; break;
834 case OP_FLOOR
: rnd
= f2f
? ROUND_MI
: ROUND_M
; break;
835 case OP_TRUNC
: rnd
= f2f
? ROUND_ZI
: ROUND_Z
; break;
841 code
[0] = 0xa0000000;
846 case TYPE_F64
: code
[1] = 0xc4404000; break;
847 case TYPE_S64
: code
[1] = 0x44414000; break;
848 case TYPE_U64
: code
[1] = 0x44404000; break;
849 case TYPE_F32
: code
[1] = 0xc4400000; break;
850 case TYPE_S32
: code
[1] = 0x44410000; break;
851 case TYPE_U32
: code
[1] = 0x44400000; break;
859 case TYPE_F64
: code
[1] = 0x8c404000; break;
860 case TYPE_F32
: code
[1] = 0x8c400000; break;
868 case TYPE_F64
: code
[1] = 0x84404000; break;
869 case TYPE_F32
: code
[1] = 0x84400000; break;
877 case TYPE_F64
: code
[1] = 0xc0404000; break;
878 case TYPE_S64
: code
[1] = 0x40414000; break;
879 case TYPE_U64
: code
[1] = 0x40404000; break;
880 case TYPE_F32
: code
[1] = 0xc4004000; break;
881 case TYPE_S32
: code
[1] = 0x44014000; break;
882 case TYPE_U32
: code
[1] = 0x44004000; break;
883 case TYPE_F16
: code
[1] = 0xc4000000; break;
891 case TYPE_F64
: code
[1] = 0x88404000; break;
892 case TYPE_F32
: code
[1] = 0x8c004000; break;
893 case TYPE_S32
: code
[1] = 0x0c014000; break;
894 case TYPE_U32
: code
[1] = 0x0c004000; break;
895 case TYPE_F16
: code
[1] = 0x8c000000; break;
896 case TYPE_S16
: code
[1] = 0x0c010000; break;
897 case TYPE_U16
: code
[1] = 0x0c000000; break;
898 case TYPE_S8
: code
[1] = 0x0c018000; break;
899 case TYPE_U8
: code
[1] = 0x0c008000; break;
907 case TYPE_F64
: code
[1] = 0x80404000; break;
908 case TYPE_F32
: code
[1] = 0x84004000; break;
909 case TYPE_S32
: code
[1] = 0x04014000; break;
910 case TYPE_U32
: code
[1] = 0x04004000; break;
911 case TYPE_F16
: code
[1] = 0x84000000; break;
912 case TYPE_S16
: code
[1] = 0x04010000; break;
913 case TYPE_U16
: code
[1] = 0x04000000; break;
914 case TYPE_S8
: code
[1] = 0x04018000; break;
915 case TYPE_U8
: code
[1] = 0x04008000; break;
928 if (typeSizeof(i
->sType
) == 1 && i
->getSrc(0)->reg
.size
== 4)
929 code
[1] |= 0x00004000;
934 case OP_ABS
: code
[1] |= 1 << 20; break;
935 case OP_SAT
: code
[1] |= 1 << 19; break;
936 case OP_NEG
: code
[1] |= 1 << 29; break;
940 code
[1] ^= i
->src
[0].mod
.neg() << 29;
941 code
[1] |= i
->src
[0].mod
.abs() << 20;
945 assert(i
->op
!= OP_ABS
|| !i
->src
[0].mod
.neg());
951 CodeEmitterNV50::emitPreOp(const Instruction
*i
)
953 code
[0] = 0xb0000000;
954 code
[1] = (i
->op
== OP_PREEX2
) ? 0xc0004000 : 0xc0000000;
956 code
[1] |= i
->src
[0].mod
.abs() << 20;
957 code
[1] |= i
->src
[0].mod
.neg() << 26;
963 CodeEmitterNV50::emitSFnOp(const Instruction
*i
, uint8_t subOp
)
965 code
[0] = 0x90000000;
967 if (i
->encSize
== 4) {
968 assert(i
->op
== OP_RCP
);
971 code
[1] = subOp
<< 29;
972 code
[1] |= i
->src
[0].mod
.abs() << 20;
973 code
[1] |= i
->src
[0].mod
.neg() << 26;
979 CodeEmitterNV50::emitLogicOp(const Instruction
*i
)
981 code
[0] = 0xd0000000;
983 if (i
->src
[1].getFile() == FILE_IMMEDIATE
) {
985 case OP_OR
: code
[0] |= 0x0100; break;
986 case OP_XOR
: code
[0] |= 0x8000; break;
988 assert(i
->op
== OP_AND
);
994 case OP_AND
: code
[1] = 0x04000000; break;
995 case OP_OR
: code
[1] = 0x04004000; break;
996 case OP_XOR
: code
[1] = 0x04008000; break;
1006 CodeEmitterNV50::emitARL(const Instruction
*i
)
1008 assert(i
->src
[1].getFile() == FILE_IMMEDIATE
);
1010 code
[0] = 0x00000001 | (i
->getSrc(1)->reg
.data
.u32
& 0x3f) << 16;
1011 code
[1] = 0xc0000000;
1013 code
[0] |= (DDATA(i
->def
[0]).id
+ 1) << 2;
1014 emitSrc0(i
->src
[0]);
1019 CodeEmitterNV50::emitShift(const Instruction
*i
)
1021 if (i
->def
[0].getFile() == FILE_ADDRESS
) {
1024 code
[0] = 0x30000001;
1025 code
[1] = (i
->op
== OP_SHR
) ? 0xe4000000 : 0xc4000000;
1026 if (isSignedType(i
->sType
))
1029 if (i
->src
[1].getFile() == FILE_IMMEDIATE
) {
1031 code
[0] |= (i
->getSrc(1)->reg
.data
.u32
& 0x7f) << 16;
1040 CodeEmitterNV50::emitOUT(const Instruction
*i
)
1042 code
[0] = (i
->op
== OP_EMIT
) ? 0xf0000200 : 0xf0000400;
1043 code
[1] = 0xc0000001;
1049 CodeEmitterNV50::emitTEX(const TexInstruction
*i
)
1051 code
[0] = 0xf0000001;
1052 code
[1] = 0x00000000;
1056 code
[1] = 0x20000000;
1059 code
[1] = 0x40000000;
1062 code
[0] = 0x01000000;
1065 code
[0] = 0x01000000;
1066 code
[1] = 0x80000000;
1069 assert(i
->op
== OP_TEX
);
1073 code
[0] |= i
->tex
.r
<< 9;
1074 code
[0] |= i
->tex
.s
<< 17;
1076 int argc
= i
->tex
.target
.getArgCount();
1078 if (i
->op
== OP_TXB
|| i
->op
== OP_TXL
)
1080 if (i
->tex
.target
.isShadow())
1084 code
[0] |= (argc
- 1) << 22;
1086 if (i
->tex
.target
.isCube()) {
1087 code
[0] |= 0x08000000;
1089 if (i
->tex
.useOffsets
) {
1090 code
[1] |= (i
->tex
.offset
[0][0] & 0xf) << 16;
1091 code
[1] |= (i
->tex
.offset
[0][1] & 0xf) << 20;
1092 code
[1] |= (i
->tex
.offset
[0][2] & 0xf) << 24;
1095 code
[0] |= (i
->tex
.mask
& 0x3) << 25;
1096 code
[1] |= (i
->tex
.mask
& 0xc) << 12;
1098 if (i
->tex
.liveOnly
)
1101 defId(i
->def
[0], 2);
1107 CodeEmitterNV50::emitFlow(const Instruction
*i
, uint8_t flowOp
)
1109 const FlowInstruction
*f
= i
->asFlow();
1111 code
[0] = 0x00000003 | (flowOp
<< 28);
1112 code
[1] = 0x00000000;
1116 if (f
&& f
->target
.bb
) {
1119 if (f
->op
== OP_CALL
) {
1121 pos
= 0; // XXX: TODO
1123 pos
= f
->target
.fn
->binPos
;
1126 pos
= f
->target
.bb
->binPos
;
1129 code
[0] |= ((pos
>> 2) & 0xffff) << 11;
1130 code
[1] |= ((pos
>> 18) & 0x003f) << 14;
1135 CodeEmitterNV50::emitInstruction(Instruction
*insn
)
1137 if (!insn
->encSize
) {
1138 ERROR("skipping unencodable instruction: "); insn
->print();
1141 if (codeSize
+ insn
->encSize
> codeSizeLimit
) {
1142 ERROR("code emitter output buffer too small\n");
1171 if (isFloatType(insn
->dType
))
1177 if (isFloatType(insn
->dType
))
1227 emitTEX(insn
->asTex());
1234 emitFlow(insn
, 0x0);
1237 emitFlow(insn
, 0x1);
1240 emitFlow(insn
, 0x2);
1243 emitFlow(insn
, 0x3);
1246 emitFlow(insn
, 0x4);
1249 emitFlow(insn
, 0x5);
1252 emitFlow(insn
, 0x6);
1255 emitFlow(insn
, 0x7);
1258 emitFlow(insn
, 0xa);
1261 emitFlow(insn
, 0xd);
1264 emitQUADOP(insn
, insn
->lanes
, insn
->subOp
);
1267 emitQUADOP(insn
, 4, insn
->src
[0].mod
.neg() ? 0x66 : 0x99);
1270 emitQUADOP(insn
, 5, insn
->src
[0].mod
.neg() ? 0x5a : 0xa5);
1275 ERROR("operation should have been eliminated");
1289 ERROR("operation should have been lowered\n");
1292 ERROR("unknow op\n");
1301 assert((insn
->encSize
== 8) == (code
[1] & 1));
1303 code
+= insn
->encSize
/ 4;
1304 codeSize
+= insn
->encSize
;
1309 CodeEmitterNV50::getMinEncodingSize(const Instruction
*i
) const
1311 const Target::OpInfo
&info
= targ
->getOpInfo(i
);
1313 if (info
.minEncSize
== 8)
1319 CodeEmitterNV50::CodeEmitterNV50(const Target
*target
) : targ(target
)
1322 codeSize
= codeSizeLimit
= 0;
1326 Target::getCodeEmitter(Program::Type type
)
1328 CodeEmitterNV50
*emit
= new CodeEmitterNV50(this);
1329 emit
->setProgramType(type
);
1333 } // namespace nv50_ir