nv50/ir: change texture offsets to ValueRefs, allow nonconst
[mesa.git] / src / gallium / drivers / nouveau / codegen / nv50_ir_emit_nv50.cpp
1 /*
2 * Copyright 2011 Christoph Bumiller
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
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 AUTHORS OR COPYRIGHT HOLDERS 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.
21 */
22
23 #include "codegen/nv50_ir.h"
24 #include "codegen/nv50_ir_target_nv50.h"
25
26 namespace nv50_ir {
27
28 #define NV50_OP_ENC_LONG 0
29 #define NV50_OP_ENC_SHORT 1
30 #define NV50_OP_ENC_IMM 2
31 #define NV50_OP_ENC_LONG_ALT 3
32
33 class CodeEmitterNV50 : public CodeEmitter
34 {
35 public:
36 CodeEmitterNV50(const TargetNV50 *);
37
38 virtual bool emitInstruction(Instruction *);
39
40 virtual uint32_t getMinEncodingSize(const Instruction *) const;
41
42 inline void setProgramType(Program::Type pType) { progType = pType; }
43
44 virtual void prepareEmission(Function *);
45
46 private:
47 Program::Type progType;
48
49 const TargetNV50 *targNV50;
50
51 private:
52 inline void defId(const ValueDef&, const int pos);
53 inline void srcId(const ValueRef&, const int pos);
54 inline void srcId(const ValueRef *, const int pos);
55
56 inline void srcAddr16(const ValueRef&, bool adj, const int pos);
57 inline void srcAddr8(const ValueRef&, const int pos);
58
59 void emitFlagsRd(const Instruction *);
60 void emitFlagsWr(const Instruction *);
61
62 void emitCondCode(CondCode cc, DataType ty, int pos);
63
64 inline void setARegBits(unsigned int);
65
66 void setAReg16(const Instruction *, int s);
67 void setImmediate(const Instruction *, int s);
68
69 void setDst(const Value *);
70 void setDst(const Instruction *, int d);
71 void setSrcFileBits(const Instruction *, int enc);
72 void setSrc(const Instruction *, unsigned int s, int slot);
73
74 void emitForm_MAD(const Instruction *);
75 void emitForm_ADD(const Instruction *);
76 void emitForm_MUL(const Instruction *);
77 void emitForm_IMM(const Instruction *);
78
79 void emitLoadStoreSizeLG(DataType ty, int pos);
80 void emitLoadStoreSizeCS(DataType ty);
81
82 void roundMode_MAD(const Instruction *);
83 void roundMode_CVT(RoundMode);
84
85 void emitMNeg12(const Instruction *);
86
87 void emitLOAD(const Instruction *);
88 void emitSTORE(const Instruction *);
89 void emitMOV(const Instruction *);
90 void emitRDSV(const Instruction *);
91 void emitNOP();
92 void emitINTERP(const Instruction *);
93 void emitPFETCH(const Instruction *);
94 void emitOUT(const Instruction *);
95
96 void emitUADD(const Instruction *);
97 void emitAADD(const Instruction *);
98 void emitFADD(const Instruction *);
99 void emitIMUL(const Instruction *);
100 void emitFMUL(const Instruction *);
101 void emitFMAD(const Instruction *);
102 void emitIMAD(const Instruction *);
103 void emitISAD(const Instruction *);
104
105 void emitMINMAX(const Instruction *);
106
107 void emitPreOp(const Instruction *);
108 void emitSFnOp(const Instruction *, uint8_t subOp);
109
110 void emitShift(const Instruction *);
111 void emitARL(const Instruction *, unsigned int shl);
112 void emitLogicOp(const Instruction *);
113 void emitNOT(const Instruction *);
114
115 void emitCVT(const Instruction *);
116 void emitSET(const Instruction *);
117
118 void emitTEX(const TexInstruction *);
119 void emitTXQ(const TexInstruction *);
120 void emitTEXPREP(const TexInstruction *);
121
122 void emitQUADOP(const Instruction *, uint8_t lane, uint8_t quOp);
123
124 void emitFlow(const Instruction *, uint8_t flowOp);
125 void emitPRERETEmu(const FlowInstruction *);
126 void emitBAR(const Instruction *);
127
128 void emitATOM(const Instruction *);
129 };
130
131 #define SDATA(a) ((a).rep()->reg.data)
132 #define DDATA(a) ((a).rep()->reg.data)
133
134 void CodeEmitterNV50::srcId(const ValueRef& src, const int pos)
135 {
136 assert(src.get());
137 code[pos / 32] |= SDATA(src).id << (pos % 32);
138 }
139
140 void CodeEmitterNV50::srcId(const ValueRef *src, const int pos)
141 {
142 assert(src->get());
143 code[pos / 32] |= SDATA(*src).id << (pos % 32);
144 }
145
146 void CodeEmitterNV50::srcAddr16(const ValueRef& src, bool adj, const int pos)
147 {
148 assert(src.get());
149
150 int32_t offset = SDATA(src).offset;
151
152 assert(!adj || src.get()->reg.size <= 4);
153 if (adj)
154 offset /= src.get()->reg.size;
155
156 assert(offset <= 0x7fff && offset >= (int32_t)-0x8000 && (pos % 32) <= 16);
157
158 if (offset < 0)
159 offset &= adj ? (0xffff >> (src.get()->reg.size >> 1)) : 0xffff;
160
161 code[pos / 32] |= offset << (pos % 32);
162 }
163
164 void CodeEmitterNV50::srcAddr8(const ValueRef& src, const int pos)
165 {
166 assert(src.get());
167
168 uint32_t offset = SDATA(src).offset;
169
170 assert((offset <= 0x1fc || offset == 0x3fc) && !(offset & 0x3));
171
172 code[pos / 32] |= (offset >> 2) << (pos % 32);
173 }
174
175 void CodeEmitterNV50::defId(const ValueDef& def, const int pos)
176 {
177 assert(def.get() && def.getFile() != FILE_SHADER_OUTPUT);
178
179 code[pos / 32] |= DDATA(def).id << (pos % 32);
180 }
181
182 void
183 CodeEmitterNV50::roundMode_MAD(const Instruction *insn)
184 {
185 switch (insn->rnd) {
186 case ROUND_M: code[1] |= 1 << 22; break;
187 case ROUND_P: code[1] |= 2 << 22; break;
188 case ROUND_Z: code[1] |= 3 << 22; break;
189 default:
190 assert(insn->rnd == ROUND_N);
191 break;
192 }
193 }
194
195 void
196 CodeEmitterNV50::emitMNeg12(const Instruction *i)
197 {
198 code[1] |= i->src(0).mod.neg() << 26;
199 code[1] |= i->src(1).mod.neg() << 27;
200 }
201
202 void CodeEmitterNV50::emitCondCode(CondCode cc, DataType ty, int pos)
203 {
204 uint8_t enc;
205
206 assert(pos >= 32 || pos <= 27);
207
208 switch (cc) {
209 case CC_LT: enc = 0x1; break;
210 case CC_LTU: enc = 0x9; break;
211 case CC_EQ: enc = 0x2; break;
212 case CC_EQU: enc = 0xa; break;
213 case CC_LE: enc = 0x3; break;
214 case CC_LEU: enc = 0xb; break;
215 case CC_GT: enc = 0x4; break;
216 case CC_GTU: enc = 0xc; break;
217 case CC_NE: enc = 0x5; break;
218 case CC_NEU: enc = 0xd; break;
219 case CC_GE: enc = 0x6; break;
220 case CC_GEU: enc = 0xe; break;
221 case CC_TR: enc = 0xf; break;
222 case CC_FL: enc = 0x0; break;
223
224 case CC_O: enc = 0x10; break;
225 case CC_C: enc = 0x11; break;
226 case CC_A: enc = 0x12; break;
227 case CC_S: enc = 0x13; break;
228 case CC_NS: enc = 0x1c; break;
229 case CC_NA: enc = 0x1d; break;
230 case CC_NC: enc = 0x1e; break;
231 case CC_NO: enc = 0x1f; break;
232
233 default:
234 enc = 0;
235 assert(!"invalid condition code");
236 break;
237 }
238 if (ty != TYPE_NONE && !isFloatType(ty))
239 enc &= ~0x8; // unordered only exists for float types
240
241 code[pos / 32] |= enc << (pos % 32);
242 }
243
244 void
245 CodeEmitterNV50::emitFlagsRd(const Instruction *i)
246 {
247 int s = (i->flagsSrc >= 0) ? i->flagsSrc : i->predSrc;
248
249 assert(!(code[1] & 0x00003f80));
250
251 if (s >= 0) {
252 assert(i->getSrc(s)->reg.file == FILE_FLAGS);
253 emitCondCode(i->cc, TYPE_NONE, 32 + 7);
254 srcId(i->src(s), 32 + 12);
255 } else {
256 code[1] |= 0x0780;
257 }
258 }
259
260 void
261 CodeEmitterNV50::emitFlagsWr(const Instruction *i)
262 {
263 assert(!(code[1] & 0x70));
264
265 int flagsDef = i->flagsDef;
266
267 // find flags definition and check that it is the last def
268 if (flagsDef < 0) {
269 for (int d = 0; i->defExists(d); ++d)
270 if (i->def(d).getFile() == FILE_FLAGS)
271 flagsDef = d;
272 if (flagsDef >= 0 && 0) // TODO: enforce use of flagsDef at some point
273 WARN("Instruction::flagsDef was not set properly\n");
274 }
275 if (flagsDef == 0 && i->defExists(1))
276 WARN("flags def should not be the primary definition\n");
277
278 if (flagsDef >= 0)
279 code[1] |= (DDATA(i->def(flagsDef)).id << 4) | 0x40;
280
281 }
282
283 void
284 CodeEmitterNV50::setARegBits(unsigned int u)
285 {
286 code[0] |= (u & 3) << 26;
287 code[1] |= (u & 4);
288 }
289
290 void
291 CodeEmitterNV50::setAReg16(const Instruction *i, int s)
292 {
293 if (i->srcExists(s)) {
294 s = i->src(s).indirect[0];
295 if (s >= 0)
296 setARegBits(SDATA(i->src(s)).id + 1);
297 }
298 }
299
300 void
301 CodeEmitterNV50::setImmediate(const Instruction *i, int s)
302 {
303 const ImmediateValue *imm = i->src(s).get()->asImm();
304 assert(imm);
305
306 uint32_t u = imm->reg.data.u32;
307
308 if (i->src(s).mod & Modifier(NV50_IR_MOD_NOT))
309 u = ~u;
310
311 code[1] |= 3;
312 code[0] |= (u & 0x3f) << 16;
313 code[1] |= (u >> 6) << 2;
314 }
315
316 void
317 CodeEmitterNV50::setDst(const Value *dst)
318 {
319 const Storage *reg = &dst->join->reg;
320
321 assert(reg->file != FILE_ADDRESS);
322
323 if (reg->data.id < 0 || reg->file == FILE_FLAGS) {
324 code[0] |= (127 << 2) | 1;
325 code[1] |= 8;
326 } else {
327 int id;
328 if (reg->file == FILE_SHADER_OUTPUT) {
329 code[1] |= 8;
330 id = reg->data.offset / 4;
331 } else {
332 id = reg->data.id;
333 }
334 code[0] |= id << 2;
335 }
336 }
337
338 void
339 CodeEmitterNV50::setDst(const Instruction *i, int d)
340 {
341 if (i->defExists(d)) {
342 setDst(i->getDef(d));
343 } else
344 if (!d) {
345 code[0] |= 0x01fc; // bit bucket
346 code[1] |= 0x0008;
347 }
348 }
349
350 // 3 * 2 bits:
351 // 0: r
352 // 1: a/s
353 // 2: c
354 // 3: i
355 void
356 CodeEmitterNV50::setSrcFileBits(const Instruction *i, int enc)
357 {
358 uint8_t mode = 0;
359
360 for (unsigned int s = 0; s < Target::operationSrcNr[i->op]; ++s) {
361 switch (i->src(s).getFile()) {
362 case FILE_GPR:
363 break;
364 case FILE_MEMORY_SHARED:
365 case FILE_SHADER_INPUT:
366 mode |= 1 << (s * 2);
367 break;
368 case FILE_MEMORY_CONST:
369 mode |= 2 << (s * 2);
370 break;
371 case FILE_IMMEDIATE:
372 mode |= 3 << (s * 2);
373 break;
374 default:
375 ERROR("invalid file on source %i: %u\n", s, i->src(s).getFile());
376 assert(0);
377 break;
378 }
379 }
380 switch (mode) {
381 case 0x00: // rrr
382 break;
383 case 0x01: // arr/grr
384 if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0)) {
385 code[0] |= 0x01800000;
386 if (enc == NV50_OP_ENC_LONG || enc == NV50_OP_ENC_LONG_ALT)
387 code[1] |= 0x00200000;
388 } else {
389 if (enc == NV50_OP_ENC_SHORT)
390 code[0] |= 0x01000000;
391 else
392 code[1] |= 0x00200000;
393 }
394 break;
395 case 0x03: // irr
396 assert(i->op == OP_MOV);
397 return;
398 case 0x0c: // rir
399 break;
400 case 0x0d: // gir
401 assert(progType == Program::TYPE_GEOMETRY ||
402 progType == Program::TYPE_COMPUTE);
403 code[0] |= 0x01000000;
404 if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0)) {
405 int reg = i->src(0).getIndirect(0)->rep()->reg.data.id;
406 assert(reg < 3);
407 code[0] |= (reg + 1) << 26;
408 }
409 break;
410 case 0x08: // rcr
411 code[0] |= (enc == NV50_OP_ENC_LONG_ALT) ? 0x01000000 : 0x00800000;
412 code[1] |= (i->getSrc(1)->reg.fileIndex << 22);
413 break;
414 case 0x09: // acr/gcr
415 if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0)) {
416 code[0] |= 0x01800000;
417 } else {
418 code[0] |= (enc == NV50_OP_ENC_LONG_ALT) ? 0x01000000 : 0x00800000;
419 code[1] |= 0x00200000;
420 }
421 code[1] |= (i->getSrc(1)->reg.fileIndex << 22);
422 break;
423 case 0x20: // rrc
424 code[0] |= 0x01000000;
425 code[1] |= (i->getSrc(2)->reg.fileIndex << 22);
426 break;
427 case 0x21: // arc
428 code[0] |= 0x01000000;
429 code[1] |= 0x00200000 | (i->getSrc(2)->reg.fileIndex << 22);
430 assert(progType != Program::TYPE_GEOMETRY);
431 break;
432 default:
433 ERROR("not encodable: %x\n", mode);
434 assert(0);
435 break;
436 }
437 if (progType != Program::TYPE_COMPUTE)
438 return;
439
440 if ((mode & 3) == 1) {
441 const int pos = i->src(1).getFile() == FILE_IMMEDIATE ? 13 : 14;
442
443 switch (i->getSrc(0)->reg.type) {
444 case TYPE_U8:
445 break;
446 case TYPE_U16:
447 code[0] |= 1 << pos;
448 break;
449 case TYPE_S16:
450 code[0] |= 2 << pos;
451 break;
452 default:
453 code[0] |= 3 << pos;
454 assert(i->getSrc(0)->reg.size == 4);
455 break;
456 }
457 }
458 }
459
460 void
461 CodeEmitterNV50::setSrc(const Instruction *i, unsigned int s, int slot)
462 {
463 if (Target::operationSrcNr[i->op] <= s)
464 return;
465 const Storage *reg = &i->src(s).rep()->reg;
466
467 unsigned int id = (reg->file == FILE_GPR) ?
468 reg->data.id :
469 reg->data.offset >> (reg->size >> 1); // no > 4 byte sources here
470
471 switch (slot) {
472 case 0: code[0] |= id << 9; break;
473 case 1: code[0] |= id << 16; break;
474 case 2: code[1] |= id << 14; break;
475 default:
476 assert(0);
477 break;
478 }
479 }
480
481 // the default form:
482 // - long instruction
483 // - 1 to 3 sources in slots 0, 1, 2 (rrr, arr, rcr, acr, rrc, arc, gcr, grr)
484 // - address & flags
485 void
486 CodeEmitterNV50::emitForm_MAD(const Instruction *i)
487 {
488 assert(i->encSize == 8);
489 code[0] |= 1;
490
491 emitFlagsRd(i);
492 emitFlagsWr(i);
493
494 setDst(i, 0);
495
496 setSrcFileBits(i, NV50_OP_ENC_LONG);
497 setSrc(i, 0, 0);
498 setSrc(i, 1, 1);
499 setSrc(i, 2, 2);
500
501 if (i->getIndirect(0, 0)) {
502 assert(!i->getIndirect(1, 0));
503 setAReg16(i, 0);
504 } else {
505 setAReg16(i, 1);
506 }
507 }
508
509 // like default form, but 2nd source in slot 2, and no 3rd source
510 void
511 CodeEmitterNV50::emitForm_ADD(const Instruction *i)
512 {
513 assert(i->encSize == 8);
514 code[0] |= 1;
515
516 emitFlagsRd(i);
517 emitFlagsWr(i);
518
519 setDst(i, 0);
520
521 setSrcFileBits(i, NV50_OP_ENC_LONG_ALT);
522 setSrc(i, 0, 0);
523 setSrc(i, 1, 2);
524
525 if (i->getIndirect(0, 0)) {
526 assert(!i->getIndirect(1, 0));
527 setAReg16(i, 0);
528 } else {
529 setAReg16(i, 1);
530 }
531 }
532
533 // default short form (rr, ar, rc, gr)
534 void
535 CodeEmitterNV50::emitForm_MUL(const Instruction *i)
536 {
537 assert(i->encSize == 4 && !(code[0] & 1));
538 assert(i->defExists(0));
539 assert(!i->getPredicate());
540
541 setDst(i, 0);
542
543 setSrcFileBits(i, NV50_OP_ENC_SHORT);
544 setSrc(i, 0, 0);
545 setSrc(i, 1, 1);
546 }
547
548 // usual immediate form
549 // - 1 to 3 sources where last is immediate (rir, gir)
550 // - no address or predicate possible
551 void
552 CodeEmitterNV50::emitForm_IMM(const Instruction *i)
553 {
554 assert(i->encSize == 8);
555 code[0] |= 1;
556
557 assert(i->defExists(0) && i->srcExists(0));
558
559 setDst(i, 0);
560
561 setSrcFileBits(i, NV50_OP_ENC_IMM);
562 if (Target::operationSrcNr[i->op] > 1) {
563 setSrc(i, 0, 0);
564 setImmediate(i, 1);
565 setSrc(i, 2, 1);
566 } else {
567 setImmediate(i, 0);
568 }
569 }
570
571 void
572 CodeEmitterNV50::emitLoadStoreSizeLG(DataType ty, int pos)
573 {
574 uint8_t enc;
575
576 switch (ty) {
577 case TYPE_F32: // fall through
578 case TYPE_S32: // fall through
579 case TYPE_U32: enc = 0x6; break;
580 case TYPE_B128: enc = 0x5; break;
581 case TYPE_F64: // fall through
582 case TYPE_S64: // fall through
583 case TYPE_U64: enc = 0x4; break;
584 case TYPE_S16: enc = 0x3; break;
585 case TYPE_U16: enc = 0x2; break;
586 case TYPE_S8: enc = 0x1; break;
587 case TYPE_U8: enc = 0x0; break;
588 default:
589 enc = 0;
590 assert(!"invalid load/store type");
591 break;
592 }
593 code[pos / 32] |= enc << (pos % 32);
594 }
595
596 void
597 CodeEmitterNV50::emitLoadStoreSizeCS(DataType ty)
598 {
599 switch (ty) {
600 case TYPE_U8: break;
601 case TYPE_U16: code[1] |= 0x4000; break;
602 case TYPE_S16: code[1] |= 0x8000; break;
603 case TYPE_F32:
604 case TYPE_S32:
605 case TYPE_U32: code[1] |= 0xc000; break;
606 default:
607 assert(0);
608 break;
609 }
610 }
611
612 void
613 CodeEmitterNV50::emitLOAD(const Instruction *i)
614 {
615 DataFile sf = i->src(0).getFile();
616 int32_t offset = i->getSrc(0)->reg.data.offset;
617
618 switch (sf) {
619 case FILE_SHADER_INPUT:
620 if (progType == Program::TYPE_GEOMETRY && i->src(0).isIndirect(0))
621 code[0] = 0x11800001;
622 else
623 // use 'mov' where we can
624 code[0] = i->src(0).isIndirect(0) ? 0x00000001 : 0x10000001;
625 code[1] = 0x00200000 | (i->lanes << 14);
626 if (typeSizeof(i->dType) == 4)
627 code[1] |= 0x04000000;
628 break;
629 case FILE_MEMORY_SHARED:
630 if (targ->getChipset() >= 0x84) {
631 assert(offset <= (int32_t)(0x3fff * typeSizeof(i->sType)));
632 code[0] = 0x10000001;
633 code[1] = 0x40000000;
634
635 if (typeSizeof(i->dType) == 4)
636 code[1] |= 0x04000000;
637
638 emitLoadStoreSizeCS(i->sType);
639 } else {
640 assert(offset <= (int32_t)(0x1f * typeSizeof(i->sType)));
641 code[0] = 0x10000001;
642 code[1] = 0x00200000 | (i->lanes << 14);
643 emitLoadStoreSizeCS(i->sType);
644 }
645 break;
646 case FILE_MEMORY_CONST:
647 code[0] = 0x10000001;
648 code[1] = 0x20000000 | (i->getSrc(0)->reg.fileIndex << 22);
649 if (typeSizeof(i->dType) == 4)
650 code[1] |= 0x04000000;
651 emitLoadStoreSizeCS(i->sType);
652 break;
653 case FILE_MEMORY_LOCAL:
654 code[0] = 0xd0000001;
655 code[1] = 0x40000000;
656 break;
657 case FILE_MEMORY_GLOBAL:
658 code[0] = 0xd0000001 | (i->getSrc(0)->reg.fileIndex << 16);
659 code[1] = 0x80000000;
660 break;
661 default:
662 assert(!"invalid load source file");
663 break;
664 }
665 if (sf == FILE_MEMORY_LOCAL ||
666 sf == FILE_MEMORY_GLOBAL)
667 emitLoadStoreSizeLG(i->sType, 21 + 32);
668
669 setDst(i, 0);
670
671 emitFlagsRd(i);
672 emitFlagsWr(i);
673
674 if (i->src(0).getFile() == FILE_MEMORY_GLOBAL) {
675 srcId(*i->src(0).getIndirect(0), 9);
676 } else {
677 setAReg16(i, 0);
678 srcAddr16(i->src(0), i->src(0).getFile() != FILE_MEMORY_LOCAL, 9);
679 }
680 }
681
682 void
683 CodeEmitterNV50::emitSTORE(const Instruction *i)
684 {
685 DataFile f = i->getSrc(0)->reg.file;
686 int32_t offset = i->getSrc(0)->reg.data.offset;
687
688 switch (f) {
689 case FILE_SHADER_OUTPUT:
690 code[0] = 0x00000001 | ((offset >> 2) << 9);
691 code[1] = 0x80c00000;
692 srcId(i->src(1), 32 + 14);
693 break;
694 case FILE_MEMORY_GLOBAL:
695 code[0] = 0xd0000001 | (i->getSrc(0)->reg.fileIndex << 16);
696 code[1] = 0xa0000000;
697 emitLoadStoreSizeLG(i->dType, 21 + 32);
698 srcId(i->src(1), 2);
699 break;
700 case FILE_MEMORY_LOCAL:
701 code[0] = 0xd0000001;
702 code[1] = 0x60000000;
703 emitLoadStoreSizeLG(i->dType, 21 + 32);
704 srcId(i->src(1), 2);
705 break;
706 case FILE_MEMORY_SHARED:
707 code[0] = 0x00000001;
708 code[1] = 0xe0000000;
709 switch (typeSizeof(i->dType)) {
710 case 1:
711 code[0] |= offset << 9;
712 code[1] |= 0x00400000;
713 break;
714 case 2:
715 code[0] |= (offset >> 1) << 9;
716 break;
717 case 4:
718 code[0] |= (offset >> 2) << 9;
719 code[1] |= 0x04200000;
720 break;
721 default:
722 assert(0);
723 break;
724 }
725 srcId(i->src(1), 32 + 14);
726 break;
727 default:
728 assert(!"invalid store destination file");
729 break;
730 }
731
732 if (f == FILE_MEMORY_GLOBAL)
733 srcId(*i->src(0).getIndirect(0), 9);
734 else
735 setAReg16(i, 0);
736
737 if (f == FILE_MEMORY_LOCAL)
738 srcAddr16(i->src(0), false, 9);
739
740 emitFlagsRd(i);
741 }
742
743 void
744 CodeEmitterNV50::emitMOV(const Instruction *i)
745 {
746 DataFile sf = i->getSrc(0)->reg.file;
747 DataFile df = i->getDef(0)->reg.file;
748
749 assert(sf == FILE_GPR || df == FILE_GPR);
750
751 if (sf == FILE_FLAGS) {
752 code[0] = 0x00000001;
753 code[1] = 0x20000000;
754 defId(i->def(0), 2);
755 srcId(i->src(0), 12);
756 emitFlagsRd(i);
757 } else
758 if (sf == FILE_ADDRESS) {
759 code[0] = 0x00000001;
760 code[1] = 0x40000000;
761 defId(i->def(0), 2);
762 setARegBits(SDATA(i->src(0)).id + 1);
763 emitFlagsRd(i);
764 } else
765 if (df == FILE_FLAGS) {
766 code[0] = 0x00000001;
767 code[1] = 0xa0000000;
768 defId(i->def(0), 4);
769 srcId(i->src(0), 9);
770 emitFlagsRd(i);
771 } else
772 if (sf == FILE_IMMEDIATE) {
773 code[0] = 0x10008001;
774 code[1] = 0x00000003;
775 emitForm_IMM(i);
776 } else {
777 if (i->encSize == 4) {
778 code[0] = 0x10008000;
779 } else {
780 code[0] = 0x10000001;
781 code[1] = (typeSizeof(i->dType) == 2) ? 0 : 0x04000000;
782 code[1] |= (i->lanes << 14);
783 emitFlagsRd(i);
784 }
785 defId(i->def(0), 2);
786 srcId(i->src(0), 9);
787 }
788 if (df == FILE_SHADER_OUTPUT) {
789 assert(i->encSize == 8);
790 code[1] |= 0x8;
791 }
792 }
793
794 static inline uint8_t getSRegEncoding(const ValueRef &ref)
795 {
796 switch (SDATA(ref).sv.sv) {
797 case SV_PHYSID: return 0;
798 case SV_CLOCK: return 1;
799 case SV_VERTEX_STRIDE: return 3;
800 // case SV_PM_COUNTER: return 4 + SDATA(ref).sv.index;
801 case SV_SAMPLE_INDEX: return 8;
802 default:
803 assert(!"no sreg for system value");
804 return 0;
805 }
806 }
807
808 void
809 CodeEmitterNV50::emitRDSV(const Instruction *i)
810 {
811 code[0] = 0x00000001;
812 code[1] = 0x60000000 | (getSRegEncoding(i->src(0)) << 14);
813 defId(i->def(0), 2);
814 emitFlagsRd(i);
815 }
816
817 void
818 CodeEmitterNV50::emitNOP()
819 {
820 code[0] = 0xf0000001;
821 code[1] = 0xe0000000;
822 }
823
824 void
825 CodeEmitterNV50::emitQUADOP(const Instruction *i, uint8_t lane, uint8_t quOp)
826 {
827 code[0] = 0xc0000000 | (lane << 16);
828 code[1] = 0x80000000;
829
830 code[0] |= (quOp & 0x03) << 20;
831 code[1] |= (quOp & 0xfc) << 20;
832
833 emitForm_ADD(i);
834
835 if (!i->srcExists(1))
836 srcId(i->src(0), 32 + 14);
837 }
838
839 /* NOTE: This returns the base address of a vertex inside the primitive.
840 * src0 is an immediate, the index (not offset) of the vertex
841 * inside the primitive. XXX: signed or unsigned ?
842 * src1 (may be NULL) should use whatever units the hardware requires
843 * (on nv50 this is bytes, so, relative index * 4; signed 16 bit value).
844 */
845 void
846 CodeEmitterNV50::emitPFETCH(const Instruction *i)
847 {
848 const uint32_t prim = i->src(0).get()->reg.data.u32;
849 assert(prim <= 127);
850
851 if (i->def(0).getFile() == FILE_ADDRESS) {
852 // shl $aX a[] 0
853 code[0] = 0x00000001 | ((DDATA(i->def(0)).id + 1) << 2);
854 code[1] = 0xc0200000;
855 code[0] |= prim << 9;
856 assert(!i->srcExists(1));
857 } else
858 if (i->srcExists(1)) {
859 // ld b32 $rX a[$aX+base]
860 code[0] = 0x00000001;
861 code[1] = 0x04200000 | (0xf << 14);
862 defId(i->def(0), 2);
863 code[0] |= prim << 9;
864 setARegBits(SDATA(i->src(1)).id + 1);
865 } else {
866 // mov b32 $rX a[]
867 code[0] = 0x10000001;
868 code[1] = 0x04200000 | (0xf << 14);
869 defId(i->def(0), 2);
870 code[0] |= prim << 9;
871 }
872 emitFlagsRd(i);
873 }
874
875 void
876 CodeEmitterNV50::emitINTERP(const Instruction *i)
877 {
878 code[0] = 0x80000000;
879
880 defId(i->def(0), 2);
881 srcAddr8(i->src(0), 16);
882
883 if (i->getInterpMode() == NV50_IR_INTERP_FLAT) {
884 code[0] |= 1 << 8;
885 } else {
886 if (i->op == OP_PINTERP) {
887 code[0] |= 1 << 25;
888 srcId(i->src(1), 9);
889 }
890 if (i->getSampleMode() == NV50_IR_INTERP_CENTROID)
891 code[0] |= 1 << 24;
892 }
893
894 if (i->encSize == 8) {
895 code[1] =
896 (code[0] & (3 << 24)) >> (24 - 16) |
897 (code[0] & (1 << 8)) << (18 - 8);
898 code[0] &= ~0x03000100;
899 code[0] |= 1;
900 emitFlagsRd(i);
901 }
902 }
903
904 void
905 CodeEmitterNV50::emitMINMAX(const Instruction *i)
906 {
907 if (i->dType == TYPE_F64) {
908 code[0] = 0xe0000000;
909 code[1] = (i->op == OP_MIN) ? 0xa0000000 : 0xc0000000;
910 } else {
911 code[0] = 0x30000000;
912 code[1] = 0x80000000;
913 if (i->op == OP_MIN)
914 code[1] |= 0x20000000;
915
916 switch (i->dType) {
917 case TYPE_F32: code[0] |= 0x80000000; break;
918 case TYPE_S32: code[1] |= 0x8c000000; break;
919 case TYPE_U32: code[1] |= 0x84000000; break;
920 case TYPE_S16: code[1] |= 0x80000000; break;
921 case TYPE_U16: break;
922 default:
923 assert(0);
924 break;
925 }
926 code[1] |= i->src(0).mod.abs() << 20;
927 code[1] |= i->src(1).mod.abs() << 19;
928 }
929 emitForm_MAD(i);
930 }
931
932 void
933 CodeEmitterNV50::emitFMAD(const Instruction *i)
934 {
935 const int neg_mul = i->src(0).mod.neg() ^ i->src(1).mod.neg();
936 const int neg_add = i->src(2).mod.neg();
937
938 code[0] = 0xe0000000;
939
940 if (i->encSize == 4) {
941 emitForm_MUL(i);
942 assert(!neg_mul && !neg_add);
943 } else {
944 code[1] = neg_mul << 26;
945 code[1] |= neg_add << 27;
946 if (i->saturate)
947 code[1] |= 1 << 29;
948 emitForm_MAD(i);
949 }
950 }
951
952 void
953 CodeEmitterNV50::emitFADD(const Instruction *i)
954 {
955 const int neg0 = i->src(0).mod.neg();
956 const int neg1 = i->src(1).mod.neg() ^ ((i->op == OP_SUB) ? 1 : 0);
957
958 code[0] = 0xb0000000;
959
960 assert(!(i->src(0).mod | i->src(1).mod).abs());
961
962 if (i->src(1).getFile() == FILE_IMMEDIATE) {
963 code[1] = 0;
964 emitForm_IMM(i);
965 code[0] |= neg0 << 15;
966 code[0] |= neg1 << 22;
967 if (i->saturate)
968 code[0] |= 1 << 8;
969 } else
970 if (i->encSize == 8) {
971 code[1] = 0;
972 emitForm_ADD(i);
973 code[1] |= neg0 << 26;
974 code[1] |= neg1 << 27;
975 if (i->saturate)
976 code[1] |= 1 << 29;
977 } else {
978 emitForm_MUL(i);
979 code[0] |= neg0 << 15;
980 code[0] |= neg1 << 22;
981 if (i->saturate)
982 code[0] |= 1 << 8;
983 }
984 }
985
986 void
987 CodeEmitterNV50::emitUADD(const Instruction *i)
988 {
989 const int neg0 = i->src(0).mod.neg();
990 const int neg1 = i->src(1).mod.neg() ^ ((i->op == OP_SUB) ? 1 : 0);
991
992 code[0] = 0x20008000;
993
994 if (i->src(1).getFile() == FILE_IMMEDIATE) {
995 code[1] = 0;
996 emitForm_IMM(i);
997 } else
998 if (i->encSize == 8) {
999 code[0] = 0x20000000;
1000 code[1] = (typeSizeof(i->dType) == 2) ? 0 : 0x04000000;
1001 emitForm_ADD(i);
1002 } else {
1003 emitForm_MUL(i);
1004 }
1005 assert(!(neg0 && neg1));
1006 code[0] |= neg0 << 28;
1007 code[0] |= neg1 << 22;
1008
1009 if (i->flagsSrc >= 0) {
1010 // addc == sub | subr
1011 assert(!(code[0] & 0x10400000) && !i->getPredicate());
1012 code[0] |= 0x10400000;
1013 srcId(i->src(i->flagsSrc), 32 + 12);
1014 }
1015 }
1016
1017 void
1018 CodeEmitterNV50::emitAADD(const Instruction *i)
1019 {
1020 const int s = (i->op == OP_MOV) ? 0 : 1;
1021
1022 code[0] = 0xd0000001 | (i->getSrc(s)->reg.data.u16 << 9);
1023 code[1] = 0x20000000;
1024
1025 code[0] |= (DDATA(i->def(0)).id + 1) << 2;
1026
1027 emitFlagsRd(i);
1028
1029 if (s && i->srcExists(0))
1030 setARegBits(SDATA(i->src(0)).id + 1);
1031 }
1032
1033 void
1034 CodeEmitterNV50::emitIMUL(const Instruction *i)
1035 {
1036 code[0] = 0x40000000;
1037
1038 if (i->encSize == 8) {
1039 code[1] = (i->sType == TYPE_S16) ? (0x8000 | 0x4000) : 0x0000;
1040 emitForm_MAD(i);
1041 } else {
1042 if (i->sType == TYPE_S16)
1043 code[0] |= 0x8100;
1044 emitForm_MUL(i);
1045 }
1046 }
1047
1048 void
1049 CodeEmitterNV50::emitFMUL(const Instruction *i)
1050 {
1051 const int neg = (i->src(0).mod ^ i->src(1).mod).neg();
1052
1053 code[0] = 0xc0000000;
1054
1055 if (i->src(1).getFile() == FILE_IMMEDIATE) {
1056 code[1] = 0;
1057 emitForm_IMM(i);
1058 if (neg)
1059 code[0] |= 0x8000;
1060 } else
1061 if (i->encSize == 8) {
1062 code[1] = i->rnd == ROUND_Z ? 0x0000c000 : 0;
1063 if (neg)
1064 code[1] |= 0x08000000;
1065 emitForm_MAD(i);
1066 } else {
1067 emitForm_MUL(i);
1068 if (neg)
1069 code[0] |= 0x8000;
1070 }
1071 }
1072
1073 void
1074 CodeEmitterNV50::emitIMAD(const Instruction *i)
1075 {
1076 code[0] = 0x60000000;
1077 if (isSignedType(i->sType))
1078 code[1] = i->saturate ? 0x40000000 : 0x20000000;
1079 else
1080 code[1] = 0x00000000;
1081
1082 int neg1 = i->src(0).mod.neg() ^ i->src(1).mod.neg();
1083 int neg2 = i->src(2).mod.neg();
1084
1085 assert(!(neg1 & neg2));
1086 code[1] |= neg1 << 27;
1087 code[1] |= neg2 << 26;
1088
1089 emitForm_MAD(i);
1090
1091 if (i->flagsSrc >= 0) {
1092 // add with carry from $cX
1093 assert(!(code[1] & 0x0c000000) && !i->getPredicate());
1094 code[1] |= 0xc << 24;
1095 srcId(i->src(i->flagsSrc), 32 + 12);
1096 }
1097 }
1098
1099 void
1100 CodeEmitterNV50::emitISAD(const Instruction *i)
1101 {
1102 if (i->encSize == 8) {
1103 code[0] = 0x50000000;
1104 switch (i->sType) {
1105 case TYPE_U32: code[1] = 0x04000000; break;
1106 case TYPE_S32: code[1] = 0x0c000000; break;
1107 case TYPE_U16: code[1] = 0x00000000; break;
1108 case TYPE_S16: code[1] = 0x08000000; break;
1109 default:
1110 assert(0);
1111 break;
1112 }
1113 emitForm_MAD(i);
1114 } else {
1115 switch (i->sType) {
1116 case TYPE_U32: code[0] = 0x50008000; break;
1117 case TYPE_S32: code[0] = 0x50008100; break;
1118 case TYPE_U16: code[0] = 0x50000000; break;
1119 case TYPE_S16: code[0] = 0x50000100; break;
1120 default:
1121 assert(0);
1122 break;
1123 }
1124 emitForm_MUL(i);
1125 }
1126 }
1127
1128 void
1129 CodeEmitterNV50::emitSET(const Instruction *i)
1130 {
1131 code[0] = 0x30000000;
1132 code[1] = 0x60000000;
1133
1134 emitCondCode(i->asCmp()->setCond, i->sType, 32 + 14);
1135
1136 switch (i->sType) {
1137 case TYPE_F32: code[0] |= 0x80000000; break;
1138 case TYPE_S32: code[1] |= 0x0c000000; break;
1139 case TYPE_U32: code[1] |= 0x04000000; break;
1140 case TYPE_S16: code[1] |= 0x08000000; break;
1141 case TYPE_U16: break;
1142 default:
1143 assert(0);
1144 break;
1145 }
1146 if (i->src(0).mod.neg()) code[1] |= 0x04000000;
1147 if (i->src(1).mod.neg()) code[1] |= 0x08000000;
1148 if (i->src(0).mod.abs()) code[1] |= 0x00100000;
1149 if (i->src(1).mod.abs()) code[1] |= 0x00080000;
1150
1151 emitForm_MAD(i);
1152 }
1153
1154 void
1155 CodeEmitterNV50::roundMode_CVT(RoundMode rnd)
1156 {
1157 switch (rnd) {
1158 case ROUND_NI: code[1] |= 0x08000000; break;
1159 case ROUND_M: code[1] |= 0x00020000; break;
1160 case ROUND_MI: code[1] |= 0x08020000; break;
1161 case ROUND_P: code[1] |= 0x00040000; break;
1162 case ROUND_PI: code[1] |= 0x08040000; break;
1163 case ROUND_Z: code[1] |= 0x00060000; break;
1164 case ROUND_ZI: code[1] |= 0x08060000; break;
1165 default:
1166 assert(rnd == ROUND_N);
1167 break;
1168 }
1169 }
1170
1171 void
1172 CodeEmitterNV50::emitCVT(const Instruction *i)
1173 {
1174 const bool f2f = isFloatType(i->dType) && isFloatType(i->sType);
1175 RoundMode rnd;
1176 DataType dType;
1177
1178 switch (i->op) {
1179 case OP_CEIL: rnd = f2f ? ROUND_PI : ROUND_P; break;
1180 case OP_FLOOR: rnd = f2f ? ROUND_MI : ROUND_M; break;
1181 case OP_TRUNC: rnd = f2f ? ROUND_ZI : ROUND_Z; break;
1182 default:
1183 rnd = i->rnd;
1184 break;
1185 }
1186
1187 if (i->op == OP_NEG && i->dType == TYPE_U32)
1188 dType = TYPE_S32;
1189 else
1190 dType = i->dType;
1191
1192 code[0] = 0xa0000000;
1193
1194 switch (dType) {
1195 case TYPE_F64:
1196 switch (i->sType) {
1197 case TYPE_F64: code[1] = 0xc4404000; break;
1198 case TYPE_S64: code[1] = 0x44414000; break;
1199 case TYPE_U64: code[1] = 0x44404000; break;
1200 case TYPE_F32: code[1] = 0xc4400000; break;
1201 case TYPE_S32: code[1] = 0x44410000; break;
1202 case TYPE_U32: code[1] = 0x44400000; break;
1203 default:
1204 assert(0);
1205 break;
1206 }
1207 break;
1208 case TYPE_S64:
1209 switch (i->sType) {
1210 case TYPE_F64: code[1] = 0x8c404000; break;
1211 case TYPE_F32: code[1] = 0x8c400000; break;
1212 default:
1213 assert(0);
1214 break;
1215 }
1216 break;
1217 case TYPE_U64:
1218 switch (i->sType) {
1219 case TYPE_F64: code[1] = 0x84404000; break;
1220 case TYPE_F32: code[1] = 0x84400000; break;
1221 default:
1222 assert(0);
1223 break;
1224 }
1225 break;
1226 case TYPE_F32:
1227 switch (i->sType) {
1228 case TYPE_F64: code[1] = 0xc0404000; break;
1229 case TYPE_S64: code[1] = 0x40414000; break;
1230 case TYPE_U64: code[1] = 0x40404000; break;
1231 case TYPE_F32: code[1] = 0xc4004000; break;
1232 case TYPE_S32: code[1] = 0x44014000; break;
1233 case TYPE_U32: code[1] = 0x44004000; break;
1234 case TYPE_F16: code[1] = 0xc4000000; break;
1235 case TYPE_U16: code[1] = 0x44000000; break;
1236 default:
1237 assert(0);
1238 break;
1239 }
1240 break;
1241 case TYPE_S32:
1242 switch (i->sType) {
1243 case TYPE_F64: code[1] = 0x88404000; break;
1244 case TYPE_F32: code[1] = 0x8c004000; break;
1245 case TYPE_S32: code[1] = 0x0c014000; break;
1246 case TYPE_U32: code[1] = 0x0c004000; break;
1247 case TYPE_F16: code[1] = 0x8c000000; break;
1248 case TYPE_S16: code[1] = 0x0c010000; break;
1249 case TYPE_U16: code[1] = 0x0c000000; break;
1250 case TYPE_S8: code[1] = 0x0c018000; break;
1251 case TYPE_U8: code[1] = 0x0c008000; break;
1252 default:
1253 assert(0);
1254 break;
1255 }
1256 break;
1257 case TYPE_U32:
1258 switch (i->sType) {
1259 case TYPE_F64: code[1] = 0x80404000; break;
1260 case TYPE_F32: code[1] = 0x84004000; break;
1261 case TYPE_S32: code[1] = 0x04014000; break;
1262 case TYPE_U32: code[1] = 0x04004000; break;
1263 case TYPE_F16: code[1] = 0x84000000; break;
1264 case TYPE_S16: code[1] = 0x04010000; break;
1265 case TYPE_U16: code[1] = 0x04000000; break;
1266 case TYPE_S8: code[1] = 0x04018000; break;
1267 case TYPE_U8: code[1] = 0x04008000; break;
1268 default:
1269 assert(0);
1270 break;
1271 }
1272 break;
1273 case TYPE_S16:
1274 case TYPE_U16:
1275 case TYPE_S8:
1276 case TYPE_U8:
1277 default:
1278 assert(0);
1279 break;
1280 }
1281 if (typeSizeof(i->sType) == 1 && i->getSrc(0)->reg.size == 4)
1282 code[1] |= 0x00004000;
1283
1284 roundMode_CVT(rnd);
1285
1286 switch (i->op) {
1287 case OP_ABS: code[1] |= 1 << 20; break;
1288 case OP_SAT: code[1] |= 1 << 19; break;
1289 case OP_NEG: code[1] |= 1 << 29; break;
1290 default:
1291 break;
1292 }
1293 code[1] ^= i->src(0).mod.neg() << 29;
1294 code[1] |= i->src(0).mod.abs() << 20;
1295 if (i->saturate)
1296 code[1] |= 1 << 19;
1297
1298 assert(i->op != OP_ABS || !i->src(0).mod.neg());
1299
1300 emitForm_MAD(i);
1301 }
1302
1303 void
1304 CodeEmitterNV50::emitPreOp(const Instruction *i)
1305 {
1306 code[0] = 0xb0000000;
1307 code[1] = (i->op == OP_PREEX2) ? 0xc0004000 : 0xc0000000;
1308
1309 code[1] |= i->src(0).mod.abs() << 20;
1310 code[1] |= i->src(0).mod.neg() << 26;
1311
1312 emitForm_MAD(i);
1313 }
1314
1315 void
1316 CodeEmitterNV50::emitSFnOp(const Instruction *i, uint8_t subOp)
1317 {
1318 code[0] = 0x90000000;
1319
1320 if (i->encSize == 4) {
1321 assert(i->op == OP_RCP);
1322 code[0] |= i->src(0).mod.abs() << 15;
1323 code[0] |= i->src(0).mod.neg() << 22;
1324 emitForm_MUL(i);
1325 } else {
1326 code[1] = subOp << 29;
1327 code[1] |= i->src(0).mod.abs() << 20;
1328 code[1] |= i->src(0).mod.neg() << 26;
1329 emitForm_MAD(i);
1330 }
1331 }
1332
1333 void
1334 CodeEmitterNV50::emitNOT(const Instruction *i)
1335 {
1336 code[0] = 0xd0000000;
1337 code[1] = 0x0002c000;
1338
1339 switch (i->sType) {
1340 case TYPE_U32:
1341 case TYPE_S32:
1342 code[1] |= 0x04000000;
1343 break;
1344 default:
1345 break;
1346 }
1347 emitForm_MAD(i);
1348 setSrc(i, 0, 1);
1349 }
1350
1351 void
1352 CodeEmitterNV50::emitLogicOp(const Instruction *i)
1353 {
1354 code[0] = 0xd0000000;
1355 code[1] = 0;
1356
1357 if (i->src(1).getFile() == FILE_IMMEDIATE) {
1358 switch (i->op) {
1359 case OP_OR: code[0] |= 0x0100; break;
1360 case OP_XOR: code[0] |= 0x8000; break;
1361 default:
1362 assert(i->op == OP_AND);
1363 break;
1364 }
1365 if (i->src(0).mod & Modifier(NV50_IR_MOD_NOT))
1366 code[0] |= 1 << 22;
1367
1368 emitForm_IMM(i);
1369 } else {
1370 switch (i->op) {
1371 case OP_AND: code[1] = 0x04000000; break;
1372 case OP_OR: code[1] = 0x04004000; break;
1373 case OP_XOR: code[1] = 0x04008000; break;
1374 default:
1375 assert(0);
1376 break;
1377 }
1378 if (i->src(0).mod & Modifier(NV50_IR_MOD_NOT))
1379 code[1] |= 1 << 16;
1380 if (i->src(1).mod & Modifier(NV50_IR_MOD_NOT))
1381 code[1] |= 1 << 17;
1382
1383 emitForm_MAD(i);
1384 }
1385 }
1386
1387 void
1388 CodeEmitterNV50::emitARL(const Instruction *i, unsigned int shl)
1389 {
1390 code[0] = 0x00000001 | (shl << 16);
1391 code[1] = 0xc0000000;
1392
1393 code[0] |= (DDATA(i->def(0)).id + 1) << 2;
1394
1395 setSrcFileBits(i, NV50_OP_ENC_IMM);
1396 setSrc(i, 0, 0);
1397 emitFlagsRd(i);
1398 }
1399
1400 void
1401 CodeEmitterNV50::emitShift(const Instruction *i)
1402 {
1403 if (i->def(0).getFile() == FILE_ADDRESS) {
1404 assert(i->srcExists(1) && i->src(1).getFile() == FILE_IMMEDIATE);
1405 emitARL(i, i->getSrc(1)->reg.data.u32 & 0x3f);
1406 } else {
1407 code[0] = 0x30000001;
1408 code[1] = (i->op == OP_SHR) ? 0xe4000000 : 0xc4000000;
1409 if (i->op == OP_SHR && isSignedType(i->sType))
1410 code[1] |= 1 << 27;
1411
1412 if (i->src(1).getFile() == FILE_IMMEDIATE) {
1413 code[1] |= 1 << 20;
1414 code[0] |= (i->getSrc(1)->reg.data.u32 & 0x7f) << 16;
1415 defId(i->def(0), 2);
1416 srcId(i->src(0), 9);
1417 emitFlagsRd(i);
1418 } else {
1419 emitForm_MAD(i);
1420 }
1421 }
1422 }
1423
1424 void
1425 CodeEmitterNV50::emitOUT(const Instruction *i)
1426 {
1427 code[0] = (i->op == OP_EMIT) ? 0xf0000201 : 0xf0000401;
1428 code[1] = 0xc0000000;
1429
1430 emitFlagsRd(i);
1431 }
1432
1433 void
1434 CodeEmitterNV50::emitTEX(const TexInstruction *i)
1435 {
1436 code[0] = 0xf0000001;
1437 code[1] = 0x00000000;
1438
1439 switch (i->op) {
1440 case OP_TXB:
1441 code[1] = 0x20000000;
1442 break;
1443 case OP_TXL:
1444 code[1] = 0x40000000;
1445 break;
1446 case OP_TXF:
1447 code[0] |= 0x01000000;
1448 break;
1449 case OP_TXG:
1450 code[0] |= 0x01000000;
1451 code[1] = 0x80000000;
1452 break;
1453 case OP_TXLQ:
1454 code[1] = 0x60020000;
1455 break;
1456 default:
1457 assert(i->op == OP_TEX);
1458 break;
1459 }
1460
1461 code[0] |= i->tex.r << 9;
1462 code[0] |= i->tex.s << 17;
1463
1464 int argc = i->tex.target.getArgCount();
1465
1466 if (i->op == OP_TXB || i->op == OP_TXL || i->op == OP_TXF)
1467 argc += 1;
1468 if (i->tex.target.isShadow())
1469 argc += 1;
1470 assert(argc <= 4);
1471
1472 code[0] |= (argc - 1) << 22;
1473
1474 if (i->tex.target.isCube()) {
1475 code[0] |= 0x08000000;
1476 } else
1477 if (i->tex.useOffsets) {
1478 code[1] |= (i->tex.offset[0] & 0xf) << 24;
1479 code[1] |= (i->tex.offset[1] & 0xf) << 20;
1480 code[1] |= (i->tex.offset[2] & 0xf) << 16;
1481 }
1482
1483 code[0] |= (i->tex.mask & 0x3) << 25;
1484 code[1] |= (i->tex.mask & 0xc) << 12;
1485
1486 if (i->tex.liveOnly)
1487 code[1] |= 4;
1488
1489 defId(i->def(0), 2);
1490
1491 emitFlagsRd(i);
1492 }
1493
1494 void
1495 CodeEmitterNV50::emitTXQ(const TexInstruction *i)
1496 {
1497 assert(i->tex.query == TXQ_DIMS);
1498
1499 code[0] = 0xf0000001;
1500 code[1] = 0x60000000;
1501
1502 code[0] |= i->tex.r << 9;
1503 code[0] |= i->tex.s << 17;
1504
1505 code[0] |= (i->tex.mask & 0x3) << 25;
1506 code[1] |= (i->tex.mask & 0xc) << 12;
1507
1508 defId(i->def(0), 2);
1509
1510 emitFlagsRd(i);
1511 }
1512
1513 void
1514 CodeEmitterNV50::emitTEXPREP(const TexInstruction *i)
1515 {
1516 code[0] = 0xf8000001 | (3 << 22) | (i->tex.s << 17) | (i->tex.r << 9);
1517 code[1] = 0x60010000;
1518
1519 code[0] |= (i->tex.mask & 0x3) << 25;
1520 code[1] |= (i->tex.mask & 0xc) << 12;
1521 defId(i->def(0), 2);
1522
1523 emitFlagsRd(i);
1524 }
1525
1526 void
1527 CodeEmitterNV50::emitPRERETEmu(const FlowInstruction *i)
1528 {
1529 uint32_t pos = i->target.bb->binPos + 8; // +8 to skip an op */
1530
1531 code[0] = 0x10000003; // bra
1532 code[1] = 0x00000780; // always
1533
1534 switch (i->subOp) {
1535 case NV50_IR_SUBOP_EMU_PRERET + 0: // bra to the call
1536 break;
1537 case NV50_IR_SUBOP_EMU_PRERET + 1: // bra to skip the call
1538 pos += 8;
1539 break;
1540 default:
1541 assert(i->subOp == (NV50_IR_SUBOP_EMU_PRERET + 2));
1542 code[0] = 0x20000003; // call
1543 code[1] = 0x00000000; // no predicate
1544 break;
1545 }
1546 addReloc(RelocEntry::TYPE_CODE, 0, pos, 0x07fff800, 9);
1547 addReloc(RelocEntry::TYPE_CODE, 1, pos, 0x000fc000, -4);
1548 }
1549
1550 void
1551 CodeEmitterNV50::emitFlow(const Instruction *i, uint8_t flowOp)
1552 {
1553 const FlowInstruction *f = i->asFlow();
1554 bool hasPred = false;
1555 bool hasTarg = false;
1556
1557 code[0] = 0x00000003 | (flowOp << 28);
1558 code[1] = 0x00000000;
1559
1560 switch (i->op) {
1561 case OP_BRA:
1562 hasPred = true;
1563 hasTarg = true;
1564 break;
1565 case OP_BREAK:
1566 case OP_BRKPT:
1567 case OP_DISCARD:
1568 case OP_RET:
1569 hasPred = true;
1570 break;
1571 case OP_CALL:
1572 case OP_PREBREAK:
1573 case OP_JOINAT:
1574 hasTarg = true;
1575 break;
1576 case OP_PRERET:
1577 hasTarg = true;
1578 if (i->subOp >= NV50_IR_SUBOP_EMU_PRERET) {
1579 emitPRERETEmu(f);
1580 return;
1581 }
1582 break;
1583 default:
1584 break;
1585 }
1586
1587 if (hasPred)
1588 emitFlagsRd(i);
1589
1590 if (hasTarg && f) {
1591 uint32_t pos;
1592
1593 if (f->op == OP_CALL) {
1594 if (f->builtin) {
1595 pos = targNV50->getBuiltinOffset(f->target.builtin);
1596 } else {
1597 pos = f->target.fn->binPos;
1598 }
1599 } else {
1600 pos = f->target.bb->binPos;
1601 }
1602
1603 code[0] |= ((pos >> 2) & 0xffff) << 11;
1604 code[1] |= ((pos >> 18) & 0x003f) << 14;
1605
1606 RelocEntry::Type relocTy;
1607
1608 relocTy = f->builtin ? RelocEntry::TYPE_BUILTIN : RelocEntry::TYPE_CODE;
1609
1610 addReloc(relocTy, 0, pos, 0x07fff800, 9);
1611 addReloc(relocTy, 1, pos, 0x000fc000, -4);
1612 }
1613 }
1614
1615 void
1616 CodeEmitterNV50::emitBAR(const Instruction *i)
1617 {
1618 ImmediateValue *barId = i->getSrc(0)->asImm();
1619 assert(barId);
1620
1621 code[0] = 0x82000003 | (barId->reg.data.u32 << 21);
1622 code[1] = 0x00004000;
1623
1624 if (i->subOp == NV50_IR_SUBOP_BAR_SYNC)
1625 code[0] |= 1 << 26;
1626 }
1627
1628 void
1629 CodeEmitterNV50::emitATOM(const Instruction *i)
1630 {
1631 uint8_t subOp;
1632 switch (i->subOp) {
1633 case NV50_IR_SUBOP_ATOM_ADD: subOp = 0x0; break;
1634 case NV50_IR_SUBOP_ATOM_MIN: subOp = 0x7; break;
1635 case NV50_IR_SUBOP_ATOM_MAX: subOp = 0x6; break;
1636 case NV50_IR_SUBOP_ATOM_INC: subOp = 0x4; break;
1637 case NV50_IR_SUBOP_ATOM_DEC: subOp = 0x5; break;
1638 case NV50_IR_SUBOP_ATOM_AND: subOp = 0xa; break;
1639 case NV50_IR_SUBOP_ATOM_OR: subOp = 0xb; break;
1640 case NV50_IR_SUBOP_ATOM_XOR: subOp = 0xc; break;
1641 case NV50_IR_SUBOP_ATOM_CAS: subOp = 0x2; break;
1642 case NV50_IR_SUBOP_ATOM_EXCH: subOp = 0x1; break;
1643 default:
1644 assert(!"invalid subop");
1645 return;
1646 }
1647 code[0] = 0xd0000001;
1648 code[1] = 0xe0c00000 | (subOp << 2);
1649 if (isSignedType(i->dType))
1650 code[1] |= 1 << 21;
1651
1652 // args
1653 emitFlagsRd(i);
1654 setDst(i, 0);
1655 setSrc(i, 1, 1);
1656 if (i->subOp == NV50_IR_SUBOP_ATOM_CAS)
1657 setSrc(i, 2, 2);
1658
1659 // g[] pointer
1660 code[0] |= i->getSrc(0)->reg.fileIndex << 23;
1661 srcId(i->getIndirect(0, 0), 9);
1662 }
1663
1664 bool
1665 CodeEmitterNV50::emitInstruction(Instruction *insn)
1666 {
1667 if (!insn->encSize) {
1668 ERROR("skipping unencodable instruction: "); insn->print();
1669 return false;
1670 } else
1671 if (codeSize + insn->encSize > codeSizeLimit) {
1672 ERROR("code emitter output buffer too small\n");
1673 return false;
1674 }
1675
1676 if (insn->bb->getProgram()->dbgFlags & NV50_IR_DEBUG_BASIC) {
1677 INFO("EMIT: "); insn->print();
1678 }
1679
1680 switch (insn->op) {
1681 case OP_MOV:
1682 emitMOV(insn);
1683 break;
1684 case OP_EXIT:
1685 case OP_NOP:
1686 case OP_JOIN:
1687 emitNOP();
1688 break;
1689 case OP_VFETCH:
1690 case OP_LOAD:
1691 emitLOAD(insn);
1692 break;
1693 case OP_EXPORT:
1694 case OP_STORE:
1695 emitSTORE(insn);
1696 break;
1697 case OP_PFETCH:
1698 emitPFETCH(insn);
1699 break;
1700 case OP_RDSV:
1701 emitRDSV(insn);
1702 break;
1703 case OP_LINTERP:
1704 case OP_PINTERP:
1705 emitINTERP(insn);
1706 break;
1707 case OP_ADD:
1708 case OP_SUB:
1709 if (isFloatType(insn->dType))
1710 emitFADD(insn);
1711 else if (insn->getDef(0)->reg.file == FILE_ADDRESS)
1712 emitAADD(insn);
1713 else
1714 emitUADD(insn);
1715 break;
1716 case OP_MUL:
1717 if (isFloatType(insn->dType))
1718 emitFMUL(insn);
1719 else
1720 emitIMUL(insn);
1721 break;
1722 case OP_MAD:
1723 case OP_FMA:
1724 if (isFloatType(insn->dType))
1725 emitFMAD(insn);
1726 else
1727 emitIMAD(insn);
1728 break;
1729 case OP_SAD:
1730 emitISAD(insn);
1731 break;
1732 case OP_NOT:
1733 emitNOT(insn);
1734 break;
1735 case OP_AND:
1736 case OP_OR:
1737 case OP_XOR:
1738 emitLogicOp(insn);
1739 break;
1740 case OP_SHL:
1741 case OP_SHR:
1742 emitShift(insn);
1743 break;
1744 case OP_SET:
1745 emitSET(insn);
1746 break;
1747 case OP_MIN:
1748 case OP_MAX:
1749 emitMINMAX(insn);
1750 break;
1751 case OP_CEIL:
1752 case OP_FLOOR:
1753 case OP_TRUNC:
1754 case OP_ABS:
1755 case OP_NEG:
1756 case OP_SAT:
1757 emitCVT(insn);
1758 break;
1759 case OP_CVT:
1760 if (insn->def(0).getFile() == FILE_ADDRESS)
1761 emitARL(insn, 0);
1762 else
1763 if (insn->def(0).getFile() == FILE_FLAGS ||
1764 insn->src(0).getFile() == FILE_FLAGS ||
1765 insn->src(0).getFile() == FILE_ADDRESS)
1766 emitMOV(insn);
1767 else
1768 emitCVT(insn);
1769 break;
1770 case OP_RCP:
1771 emitSFnOp(insn, 0);
1772 break;
1773 case OP_RSQ:
1774 emitSFnOp(insn, 2);
1775 break;
1776 case OP_LG2:
1777 emitSFnOp(insn, 3);
1778 break;
1779 case OP_SIN:
1780 emitSFnOp(insn, 4);
1781 break;
1782 case OP_COS:
1783 emitSFnOp(insn, 5);
1784 break;
1785 case OP_EX2:
1786 emitSFnOp(insn, 6);
1787 break;
1788 case OP_PRESIN:
1789 case OP_PREEX2:
1790 emitPreOp(insn);
1791 break;
1792 case OP_TEX:
1793 case OP_TXB:
1794 case OP_TXL:
1795 case OP_TXF:
1796 case OP_TXG:
1797 case OP_TXLQ:
1798 emitTEX(insn->asTex());
1799 break;
1800 case OP_TXQ:
1801 emitTXQ(insn->asTex());
1802 break;
1803 case OP_TEXPREP:
1804 emitTEXPREP(insn->asTex());
1805 break;
1806 case OP_EMIT:
1807 case OP_RESTART:
1808 emitOUT(insn);
1809 break;
1810 case OP_DISCARD:
1811 emitFlow(insn, 0x0);
1812 break;
1813 case OP_BRA:
1814 emitFlow(insn, 0x1);
1815 break;
1816 case OP_CALL:
1817 emitFlow(insn, 0x2);
1818 break;
1819 case OP_RET:
1820 emitFlow(insn, 0x3);
1821 break;
1822 case OP_PREBREAK:
1823 emitFlow(insn, 0x4);
1824 break;
1825 case OP_BREAK:
1826 emitFlow(insn, 0x5);
1827 break;
1828 case OP_QUADON:
1829 emitFlow(insn, 0x6);
1830 break;
1831 case OP_QUADPOP:
1832 emitFlow(insn, 0x7);
1833 break;
1834 case OP_JOINAT:
1835 emitFlow(insn, 0xa);
1836 break;
1837 case OP_PRERET:
1838 emitFlow(insn, 0xd);
1839 break;
1840 case OP_QUADOP:
1841 emitQUADOP(insn, insn->lanes, insn->subOp);
1842 break;
1843 case OP_DFDX:
1844 emitQUADOP(insn, 4, insn->src(0).mod.neg() ? 0x66 : 0x99);
1845 break;
1846 case OP_DFDY:
1847 emitQUADOP(insn, 5, insn->src(0).mod.neg() ? 0x5a : 0xa5);
1848 break;
1849 case OP_ATOM:
1850 emitATOM(insn);
1851 break;
1852 case OP_BAR:
1853 emitBAR(insn);
1854 break;
1855 case OP_PHI:
1856 case OP_UNION:
1857 case OP_CONSTRAINT:
1858 ERROR("operation should have been eliminated\n");
1859 return false;
1860 case OP_EXP:
1861 case OP_LOG:
1862 case OP_SQRT:
1863 case OP_POW:
1864 case OP_SELP:
1865 case OP_SLCT:
1866 case OP_TXD:
1867 case OP_PRECONT:
1868 case OP_CONT:
1869 case OP_POPCNT:
1870 case OP_INSBF:
1871 case OP_EXTBF:
1872 ERROR("operation should have been lowered\n");
1873 return false;
1874 default:
1875 ERROR("unknown op: %u\n", insn->op);
1876 return false;
1877 }
1878 if (insn->join || insn->op == OP_JOIN)
1879 code[1] |= 0x2;
1880 else
1881 if (insn->exit || insn->op == OP_EXIT)
1882 code[1] |= 0x1;
1883
1884 assert((insn->encSize == 8) == (code[0] & 1));
1885
1886 code += insn->encSize / 4;
1887 codeSize += insn->encSize;
1888 return true;
1889 }
1890
1891 uint32_t
1892 CodeEmitterNV50::getMinEncodingSize(const Instruction *i) const
1893 {
1894 const Target::OpInfo &info = targ->getOpInfo(i);
1895
1896 if (info.minEncSize > 4)
1897 return 8;
1898
1899 // check constraints on dst and src operands
1900 for (int d = 0; i->defExists(d); ++d) {
1901 if (i->def(d).rep()->reg.data.id > 63 ||
1902 i->def(d).rep()->reg.file != FILE_GPR)
1903 return 8;
1904 }
1905
1906 for (int s = 0; i->srcExists(s); ++s) {
1907 DataFile sf = i->src(s).getFile();
1908 if (sf != FILE_GPR)
1909 if (sf != FILE_SHADER_INPUT || progType != Program::TYPE_FRAGMENT)
1910 return 8;
1911 if (i->src(s).rep()->reg.data.id > 63)
1912 return 8;
1913 }
1914
1915 // check modifiers & rounding
1916 if (i->join || i->lanes != 0xf || i->exit)
1917 return 8;
1918 if (i->op == OP_MUL && i->rnd != ROUND_N)
1919 return 8;
1920
1921 if (i->asTex())
1922 return 8; // TODO: short tex encoding
1923
1924 // check constraints on short MAD
1925 if (info.srcNr >= 2 && i->srcExists(2)) {
1926 if (i->saturate || i->src(2).mod)
1927 return 8;
1928 if ((i->src(0).mod ^ i->src(1).mod) ||
1929 (i->src(0).mod | i->src(1).mod).abs())
1930 return 8;
1931 if (!i->defExists(0) ||
1932 i->def(0).rep()->reg.data.id != i->src(2).rep()->reg.data.id)
1933 return 8;
1934 }
1935
1936 return info.minEncSize;
1937 }
1938
1939 // Change the encoding size of an instruction after BBs have been scheduled.
1940 static void
1941 makeInstructionLong(Instruction *insn)
1942 {
1943 if (insn->encSize == 8)
1944 return;
1945 Function *fn = insn->bb->getFunction();
1946 int n = 0;
1947 int adj = 4;
1948
1949 for (Instruction *i = insn->next; i && i->encSize == 4; ++n, i = i->next);
1950
1951 if (n & 1) {
1952 adj = 8;
1953 insn->next->encSize = 8;
1954 } else
1955 if (insn->prev && insn->prev->encSize == 4) {
1956 adj = 8;
1957 insn->prev->encSize = 8;
1958 }
1959 insn->encSize = 8;
1960
1961 for (int i = fn->bbCount - 1; i >= 0 && fn->bbArray[i] != insn->bb; --i) {
1962 fn->bbArray[i]->binPos += 4;
1963 }
1964 fn->binSize += adj;
1965 insn->bb->binSize += adj;
1966 }
1967
1968 static bool
1969 trySetExitModifier(Instruction *insn)
1970 {
1971 if (insn->op == OP_DISCARD ||
1972 insn->op == OP_QUADON ||
1973 insn->op == OP_QUADPOP)
1974 return false;
1975 for (int s = 0; insn->srcExists(s); ++s)
1976 if (insn->src(s).getFile() == FILE_IMMEDIATE)
1977 return false;
1978 if (insn->asFlow()) {
1979 if (insn->op == OP_CALL) // side effects !
1980 return false;
1981 if (insn->getPredicate()) // cannot do conditional exit (or can we ?)
1982 return false;
1983 insn->op = OP_EXIT;
1984 }
1985 insn->exit = 1;
1986 makeInstructionLong(insn);
1987 return true;
1988 }
1989
1990 static void
1991 replaceExitWithModifier(Function *func)
1992 {
1993 BasicBlock *epilogue = BasicBlock::get(func->cfgExit);
1994
1995 if (!epilogue->getExit() ||
1996 epilogue->getExit()->op != OP_EXIT) // only main will use OP_EXIT
1997 return;
1998
1999 if (epilogue->getEntry()->op != OP_EXIT) {
2000 Instruction *insn = epilogue->getExit()->prev;
2001 if (!insn || !trySetExitModifier(insn))
2002 return;
2003 insn->exit = 1;
2004 } else {
2005 for (Graph::EdgeIterator ei = func->cfgExit->incident();
2006 !ei.end(); ei.next()) {
2007 BasicBlock *bb = BasicBlock::get(ei.getNode());
2008 Instruction *i = bb->getExit();
2009
2010 if (!i || !trySetExitModifier(i))
2011 return;
2012 }
2013 }
2014 epilogue->binSize -= 8;
2015 func->binSize -= 8;
2016 delete_Instruction(func->getProgram(), epilogue->getExit());
2017 }
2018
2019 void
2020 CodeEmitterNV50::prepareEmission(Function *func)
2021 {
2022 CodeEmitter::prepareEmission(func);
2023
2024 replaceExitWithModifier(func);
2025 }
2026
2027 CodeEmitterNV50::CodeEmitterNV50(const TargetNV50 *target) :
2028 CodeEmitter(target), targNV50(target)
2029 {
2030 targ = target; // specialized
2031 code = NULL;
2032 codeSize = codeSizeLimit = 0;
2033 relocInfo = NULL;
2034 }
2035
2036 CodeEmitter *
2037 TargetNV50::getCodeEmitter(Program::Type type)
2038 {
2039 CodeEmitterNV50 *emit = new CodeEmitterNV50(this);
2040 emit->setProgramType(type);
2041 return emit;
2042 }
2043
2044 } // namespace nv50_ir