Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gv100.cpp
4574 views
1
/*
2
* Copyright 2020 Red Hat Inc.
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 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.
21
*/
22
#include "codegen/nv50_ir_emit_gv100.h"
23
#include "codegen/nv50_ir_sched_gm107.h"
24
25
namespace nv50_ir {
26
27
/*******************************************************************************
28
* instruction format helpers
29
******************************************************************************/
30
31
#define FA_NODEF (1 << 0)
32
#define FA_RRR (1 << 1)
33
#define FA_RRI (1 << 2)
34
#define FA_RRC (1 << 3)
35
#define FA_RIR (1 << 4)
36
#define FA_RCR (1 << 5)
37
38
#define FA_SRC_MASK 0x0ff
39
#define FA_SRC_NEG 0x100
40
#define FA_SRC_ABS 0x200
41
42
#define EMPTY -1
43
#define __(a) (a) // no source modifiers
44
#define _A(a) ((a) | FA_SRC_ABS)
45
#define N_(a) ((a) | FA_SRC_NEG)
46
#define NA(a) ((a) | FA_SRC_NEG | FA_SRC_ABS)
47
48
void
49
CodeEmitterGV100::emitFormA_I32(int src)
50
{
51
emitIMMD(32, 32, insn->src(src));
52
if (insn->src(src).mod.abs())
53
code[1] &= 0x7fffffff;
54
if (insn->src(src).mod.neg())
55
code[1] ^= 0x80000000;
56
}
57
58
void
59
CodeEmitterGV100::emitFormA_RRC(uint16_t op, int src1, int src2)
60
{
61
emitInsn(op);
62
if (src1 >= 0) {
63
emitNEG (75, (src1 & FA_SRC_MASK), (src1 & FA_SRC_NEG));
64
emitABS (74, (src1 & FA_SRC_MASK), (src1 & FA_SRC_ABS));
65
emitGPR (64, insn->src(src1 & FA_SRC_MASK));
66
}
67
if (src2 >= 0) {
68
emitNEG (63, (src2 & FA_SRC_MASK), (src2 & FA_SRC_NEG));
69
emitABS (62, (src2 & FA_SRC_MASK), (src2 & FA_SRC_ABS));
70
emitCBUF(54, -1, 38, 0, 2, insn->src(src2 & FA_SRC_MASK));
71
}
72
}
73
74
void
75
CodeEmitterGV100::emitFormA_RRI(uint16_t op, int src1, int src2)
76
{
77
emitInsn(op);
78
if (src1 >= 0) {
79
emitNEG (75, (src1 & FA_SRC_MASK), (src1 & FA_SRC_NEG));
80
emitABS (74, (src1 & FA_SRC_MASK), (src1 & FA_SRC_ABS));
81
emitGPR (64, insn->src(src1 & FA_SRC_MASK));
82
}
83
if (src2 >= 0)
84
emitFormA_I32(src2 & FA_SRC_MASK);
85
}
86
87
void
88
CodeEmitterGV100::emitFormA_RRR(uint16_t op, int src1, int src2)
89
{
90
emitInsn(op);
91
if (src2 >= 0) {
92
emitNEG (75, (src2 & FA_SRC_MASK), (src2 & FA_SRC_NEG));
93
emitABS (74, (src2 & FA_SRC_MASK), (src2 & FA_SRC_ABS));
94
emitGPR (64, insn->src(src2 & FA_SRC_MASK));
95
}
96
97
if (src1 >= 0) {
98
emitNEG (63, (src1 & FA_SRC_MASK), (src1 & FA_SRC_NEG));
99
emitABS (62, (src1 & FA_SRC_MASK), (src1 & FA_SRC_ABS));
100
emitGPR (32, insn->src(src1 & FA_SRC_MASK));
101
}
102
}
103
104
void
105
CodeEmitterGV100::emitFormA(uint16_t op, uint8_t forms,
106
int src0, int src1, int src2)
107
{
108
switch ((src1 < 0) ? FILE_GPR : insn->src(src1 & FA_SRC_MASK).getFile()) {
109
case FILE_GPR:
110
switch ((src2 < 0) ? FILE_GPR : insn->src(src2 & FA_SRC_MASK).getFile()) {
111
case FILE_GPR:
112
assert(forms & FA_RRR);
113
emitFormA_RRR((1 << 9) | op, src1, src2);
114
break;
115
case FILE_IMMEDIATE:
116
assert(forms & FA_RRI);
117
emitFormA_RRI((2 << 9) | op, src1, src2);
118
break;
119
case FILE_MEMORY_CONST:
120
assert(forms & FA_RRC);
121
emitFormA_RRC((3 << 9) | op, src1, src2);
122
break;
123
default:
124
assert(!"bad src2 file");
125
break;
126
}
127
break;
128
case FILE_IMMEDIATE:
129
assert((src2 < 0) || insn->src(src2 & FA_SRC_MASK).getFile() == FILE_GPR);
130
assert(forms & FA_RIR);
131
emitFormA_RRI((4 << 9) | op, src2, src1);
132
break;
133
case FILE_MEMORY_CONST:
134
assert((src2 < 0) || insn->src(src2 & FA_SRC_MASK).getFile() == FILE_GPR);
135
assert(forms & FA_RCR);
136
emitFormA_RRC((5 << 9) | op, src2, src1);
137
break;
138
default:
139
assert(!"bad src1 file");
140
break;
141
}
142
143
if (src0 >= 0) {
144
assert(insn->src(src0 & FA_SRC_MASK).getFile() == FILE_GPR);
145
emitABS(73, (src0 & FA_SRC_MASK), (src0 & FA_SRC_ABS));
146
emitNEG(72, (src0 & FA_SRC_MASK), (src0 & FA_SRC_NEG));
147
emitGPR(24, insn->src(src0 & FA_SRC_MASK));
148
}
149
150
if (!(forms & FA_NODEF))
151
emitGPR(16, insn->def(0));
152
}
153
154
/*******************************************************************************
155
* control
156
******************************************************************************/
157
158
void
159
CodeEmitterGV100::emitBRA()
160
{
161
const FlowInstruction *insn = this->insn->asFlow();
162
int64_t target = ((int64_t)insn->target.bb->binPos - (codeSize + 0x10)) / 4;
163
164
assert(!insn->indirect && !insn->absolute);
165
166
emitInsn (0x947);
167
emitField(34, 48, target);
168
emitPRED (87);
169
emitField(86, 2, 0); // ./.INC/.DEC
170
}
171
172
void
173
CodeEmitterGV100::emitEXIT()
174
{
175
emitInsn (0x94d);
176
emitNOT (90);
177
emitPRED (87);
178
emitField(85, 1, 0); // .NO_ATEXIT
179
emitField(84, 2, 0); // ./.KEEPREFCOUNT/.PREEMPTED/.INVALID3
180
}
181
182
void
183
CodeEmitterGV100::emitKILL()
184
{
185
emitInsn(0x95b);
186
emitPRED(87);
187
}
188
189
void
190
CodeEmitterGV100::emitNOP()
191
{
192
emitInsn(0x918);
193
}
194
195
void
196
CodeEmitterGV100::emitWARPSYNC()
197
{
198
emitFormA(0x148, FA_NODEF | FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
199
emitNOT (90);
200
emitPRED (87);
201
}
202
203
/*******************************************************************************
204
* movement / conversion
205
******************************************************************************/
206
207
void
208
CodeEmitterGV100::emitCS2R()
209
{
210
emitInsn(0x805);
211
emitSYS (72, insn->src(0));
212
emitGPR (16, insn->def(0));
213
}
214
215
void
216
CodeEmitterGV100::emitF2F()
217
{
218
if (typeSizeof(insn->sType) != 8 && typeSizeof(insn->dType) != 8)
219
emitFormA(0x104, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
220
else
221
emitFormA(0x110, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
222
emitField(84, 2, util_logbase2(typeSizeof(insn->sType)));
223
emitFMZ (80, 1);
224
emitRND (78);
225
emitField(75, 2, util_logbase2(typeSizeof(insn->dType)));
226
emitField(60, 2, insn->subOp); // ./.H1/.INVALID2/.INVALID3
227
}
228
229
void
230
CodeEmitterGV100::emitF2I()
231
{
232
if (typeSizeof(insn->sType) != 8 && typeSizeof(insn->dType) != 8)
233
emitFormA(0x105, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
234
else
235
emitFormA(0x111, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
236
emitField(84, 2, util_logbase2(typeSizeof(insn->sType)));
237
emitFMZ (80, 1);
238
emitRND (78);
239
emitField(77, 1, 0); // .NTZ
240
emitField(75, 2, util_logbase2(typeSizeof(insn->dType)));
241
emitField(72, 1, isSignedType(insn->dType));
242
}
243
244
void
245
CodeEmitterGV100::emitFRND()
246
{
247
int subop = 0;
248
249
switch (insn->op) {
250
case OP_CVT:
251
switch (insn->rnd) {
252
case ROUND_NI: subop = 0; break;
253
case ROUND_MI: subop = 1; break;
254
case ROUND_PI: subop = 2; break;
255
case ROUND_ZI: subop = 3; break;
256
default:
257
assert(!"invalid FRND mode");
258
break;
259
}
260
break;
261
case OP_FLOOR: subop = 1; break;
262
case OP_CEIL : subop = 2; break;
263
case OP_TRUNC: subop = 3; break;
264
default:
265
assert(!"invalid FRND opcode");
266
break;
267
}
268
269
if (typeSizeof(insn->sType) != 8 && typeSizeof(insn->dType) != 8)
270
emitFormA(0x107, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
271
else
272
emitFormA(0x113, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
273
emitField(84, 2, util_logbase2(typeSizeof(insn->sType)));
274
emitFMZ (80, 1);
275
emitField(78, 2, subop);
276
emitField(75, 2, util_logbase2(typeSizeof(insn->dType)));
277
}
278
279
void
280
CodeEmitterGV100::emitI2F()
281
{
282
if (typeSizeof(insn->sType) != 8 && typeSizeof(insn->dType) != 8)
283
emitFormA(0x106, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
284
else
285
emitFormA(0x112, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
286
emitField(84, 2, util_logbase2(typeSizeof(insn->sType)));
287
emitRND (78);
288
emitField(75, 2, util_logbase2(typeSizeof(insn->dType)));
289
emitField(74, 1, isSignedType(insn->sType));
290
if (typeSizeof(insn->sType) == 2)
291
emitField(60, 2, insn->subOp >> 1);
292
else
293
emitField(60, 2, insn->subOp); // ./.B1/.B2/.B3
294
}
295
296
void
297
CodeEmitterGV100::emitMOV()
298
{
299
switch (insn->def(0).getFile()) {
300
case FILE_GPR:
301
switch (insn->src(0).getFile()) {
302
case FILE_GPR:
303
case FILE_MEMORY_CONST:
304
case FILE_IMMEDIATE:
305
emitFormA(0x002, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
306
emitField(72, 4, insn->lanes);
307
break;
308
case FILE_PREDICATE:
309
emitInsn (0x807);
310
emitGPR (16, insn->def(0));
311
emitGPR (24);
312
emitField(32, 32, 0xffffffff);
313
emitField(90, 1, 1);
314
emitPRED (87, insn->src(0));
315
break;
316
case FILE_BARRIER:
317
case FILE_THREAD_STATE:
318
emitInsn (0x355);
319
emitBTS (24, insn->src(0));
320
emitGPR (16, insn->def(0));
321
break;
322
default:
323
assert(!"bad src file");
324
break;
325
}
326
break;
327
case FILE_PREDICATE:
328
emitInsn (0x20c);
329
emitPRED (87);
330
emitPRED (84);
331
emitNOT (71);
332
emitPRED (68);
333
emitPRED (81, insn->def(0));
334
emitCond3(76, CC_NE);
335
emitGPR (24, insn->src(0));
336
emitGPR (32);
337
break;
338
case FILE_BARRIER:
339
case FILE_THREAD_STATE:
340
switch (insn->src(0).getFile()) {
341
case FILE_GPR:
342
emitInsn (0x356);
343
emitGPR (32, insn->src(0));
344
emitBTS (24, insn->def(0));
345
break;
346
case FILE_BARRIER:
347
emitInsn (0xf56);
348
emitBTS (24, insn->def(0));
349
emitBTS (16, insn->src(0));
350
break;
351
case FILE_THREAD_STATE:
352
assert(insn->def(0).getFile() == FILE_BARRIER);
353
emitInsn (0xf55);
354
emitBTS (24, insn->src(0));
355
emitBTS (16, insn->def(0));
356
break;
357
default:
358
assert(!"bad src file");
359
break;
360
}
361
emitField(84, 1, insn->getDef(0)->reg.data.ts == TS_PQUAD_MACTIVE ? 1 : 0);
362
break;
363
default:
364
assert(!"bad dst file");
365
break;
366
}
367
}
368
369
void
370
CodeEmitterGV100::emitPRMT()
371
{
372
emitFormA(0x016, FA_RRR | FA_RRI | FA_RRC | FA_RIR | FA_RCR, __(0), __(1), __(2));
373
emitField(72, 3, insn->subOp);
374
}
375
376
void
377
CodeEmitterGV100::emitS2R()
378
{
379
emitInsn(0x919);
380
emitSYS (72, insn->src(0));
381
emitGPR (16, insn->def(0));
382
}
383
384
void
385
gv100_selpFlip(const FixupEntry *entry, uint32_t *code, const FixupData& data)
386
{
387
int loc = entry->loc;
388
bool val = false;
389
switch (entry->ipa) {
390
case 0:
391
val = data.force_persample_interp;
392
break;
393
case 1:
394
val = data.msaa;
395
break;
396
}
397
if (val)
398
code[loc + 2] |= 1 << 26;
399
else
400
code[loc + 2] &= ~(1 << 26);
401
}
402
403
void
404
CodeEmitterGV100::emitSEL()
405
{
406
emitFormA(0x007, FA_RRR | FA_RIR | FA_RCR, __(0), __(1), EMPTY);
407
emitNOT (90, insn->src(2));
408
emitPRED (87, insn->src(2));
409
if (insn->subOp >= 1)
410
addInterp(insn->subOp - 1, 0, gv100_selpFlip);
411
}
412
413
void
414
CodeEmitterGV100::emitSHFL()
415
{
416
switch (insn->src(1).getFile()) {
417
case FILE_GPR:
418
switch (insn->src(2).getFile()) {
419
case FILE_GPR:
420
emitInsn(0x389);
421
emitGPR (64, insn->src(2));
422
break;
423
case FILE_IMMEDIATE:
424
emitInsn(0x589);
425
emitIMMD(40, 13, insn->src(2));
426
break;
427
default:
428
assert(!"bad src2 file");
429
break;
430
}
431
emitGPR(32, insn->src(1));
432
break;
433
case FILE_IMMEDIATE:
434
switch (insn->src(2).getFile()) {
435
case FILE_GPR:
436
emitInsn(0x989);
437
emitGPR (64, insn->src(2));
438
break;
439
case FILE_IMMEDIATE:
440
emitInsn(0xf89);
441
emitIMMD(40, 13, insn->src(2));
442
break;
443
default:
444
assert(!"bad src2 file");
445
break;
446
}
447
emitIMMD(53, 5, insn->src(1));
448
break;
449
default:
450
assert(!"bad src1 file");
451
break;
452
}
453
454
if (insn->defExists(1))
455
emitPRED(81, insn->def(1));
456
else
457
emitPRED(81);
458
459
emitField(58, 2, insn->subOp);
460
emitGPR (24, insn->src(0));
461
emitGPR (16, insn->def(0));
462
}
463
464
/*******************************************************************************
465
* fp32
466
******************************************************************************/
467
468
void
469
CodeEmitterGV100::emitFADD()
470
{
471
if (insn->src(1).getFile() == FILE_GPR)
472
emitFormA(0x021, FA_RRR , NA(0), NA(1), EMPTY);
473
else
474
emitFormA(0x021, FA_RRI | FA_RRC, NA(0), EMPTY, NA(1));
475
emitFMZ (80, 1);
476
emitRND (78);
477
emitSAT (77);
478
}
479
480
void
481
CodeEmitterGV100::emitFFMA()
482
{
483
emitFormA(0x023, FA_RRR | FA_RRI | FA_RRC | FA_RIR | FA_RCR, NA(0), NA(1), NA(2));
484
emitField(80, 1, insn->ftz);
485
emitRND (78);
486
emitSAT (77);
487
emitField(76, 1, insn->dnz);
488
}
489
490
void
491
CodeEmitterGV100::emitFMNMX()
492
{
493
emitFormA(0x009, FA_RRR | FA_RIR | FA_RCR, NA(0), NA(1), EMPTY);
494
emitField(90, 1, insn->op == OP_MAX);
495
emitPRED (87);
496
emitFMZ (80, 1);
497
}
498
499
void
500
CodeEmitterGV100::emitFMUL()
501
{
502
emitFormA(0x020, FA_RRR | FA_RIR | FA_RCR, NA(0), NA(1), EMPTY);
503
emitField(80, 1, insn->ftz);
504
emitPDIV (84);
505
emitRND (78);
506
emitSAT (77);
507
emitField(76, 1, insn->dnz);
508
}
509
510
void
511
CodeEmitterGV100::emitFSET_BF()
512
{
513
const CmpInstruction *insn = this->insn->asCmp();
514
515
emitFormA(0x00a, FA_RRR | FA_RIR | FA_RCR, NA(0), NA(1), EMPTY);
516
emitFMZ (80, 1);
517
emitCond4(76, insn->setCond);
518
519
if (insn->op != OP_SET) {
520
switch (insn->op) {
521
case OP_SET_AND: emitField(74, 2, 0); break;
522
case OP_SET_OR : emitField(74, 2, 1); break;
523
case OP_SET_XOR: emitField(74, 2, 2); break;
524
default:
525
assert(!"invalid set op");
526
break;
527
}
528
emitNOT (90, insn->src(2));
529
emitPRED(87, insn->src(2));
530
} else {
531
emitPRED(87);
532
}
533
}
534
535
void
536
CodeEmitterGV100::emitFSETP()
537
{
538
const CmpInstruction *insn = this->insn->asCmp();
539
540
emitFormA(0x00b, FA_NODEF | FA_RRR | FA_RIR | FA_RCR, NA(0), NA(1), EMPTY);
541
emitFMZ (80, 1);
542
emitCond4(76, insn->setCond);
543
544
if (insn->op != OP_SET) {
545
switch (insn->op) {
546
case OP_SET_AND: emitField(74, 2, 0); break;
547
case OP_SET_OR : emitField(74, 2, 1); break;
548
case OP_SET_XOR: emitField(74, 2, 2); break;
549
default:
550
assert(!"invalid set op");
551
break;
552
}
553
emitNOT (90, insn->src(2));
554
emitPRED(87, insn->src(2));
555
} else {
556
emitPRED(87);
557
}
558
559
if (insn->defExists(1))
560
emitPRED(84, insn->def(1));
561
else
562
emitPRED(84);
563
emitPRED(81, insn->def(0));
564
}
565
566
void
567
CodeEmitterGV100::emitFSWZADD()
568
{
569
uint8_t subOp = 0;
570
571
// NP/PN swapped vs SM60
572
for (int i = 0; i < 4; i++) {
573
uint8_t p = ((insn->subOp >> (i * 2)) & 3);
574
if (p == 1 || p == 2)
575
p ^= 3;
576
subOp |= p << (i * 2);
577
}
578
579
emitInsn (0x822);
580
emitFMZ (80, 1);
581
emitRND (78);
582
emitField(77, 1, insn->lanes); /* abused for .ndv */
583
emitGPR (64, insn->src(1));
584
emitField(32, 8, subOp);
585
emitGPR (24, insn->src(0));
586
emitGPR (16, insn->def(0));
587
}
588
589
void
590
CodeEmitterGV100::emitMUFU()
591
{
592
int mufu = 0;
593
594
switch (insn->op) {
595
case OP_COS : mufu = 0; break;
596
case OP_SIN : mufu = 1; break;
597
case OP_EX2 : mufu = 2; break;
598
case OP_LG2 : mufu = 3; break;
599
case OP_RCP : mufu = 4 + 2 * insn->subOp; break;
600
case OP_RSQ : mufu = 5 + 2 * insn->subOp; break;
601
case OP_SQRT: mufu = 8; break;
602
default:
603
assert(!"invalid mufu");
604
break;
605
}
606
607
emitFormA(0x108, FA_RRR | FA_RIR | FA_RCR, EMPTY, NA(0), EMPTY);
608
emitField(74, 4, mufu);
609
}
610
611
/*******************************************************************************
612
* fp64
613
******************************************************************************/
614
615
void
616
CodeEmitterGV100::emitDADD()
617
{
618
emitFormA(0x029, FA_RRR | FA_RRI | FA_RRC, NA(0), EMPTY, NA(1));
619
emitRND(78);
620
}
621
622
void
623
CodeEmitterGV100::emitDFMA()
624
{
625
emitFormA(0x02b, FA_RRR | FA_RRI | FA_RRC | FA_RIR | FA_RCR, NA(0), NA(1), NA(2));
626
emitRND(78);
627
}
628
629
void
630
CodeEmitterGV100::emitDMUL()
631
{
632
emitFormA(0x028, FA_RRR | FA_RIR | FA_RCR, NA(0), NA(1), EMPTY);
633
emitRND(78);
634
}
635
636
void
637
CodeEmitterGV100::emitDSETP()
638
{
639
const CmpInstruction *insn = this->insn->asCmp();
640
641
if (insn->src(1).getFile() == FILE_GPR)
642
emitFormA(0x02a, FA_NODEF | FA_RRR , NA(0), NA(1), EMPTY);
643
else
644
emitFormA(0x02a, FA_NODEF | FA_RRI | FA_RRC, NA(0), EMPTY, NA(1));
645
646
if (insn->op != OP_SET) {
647
switch (insn->op) {
648
case OP_SET_AND: emitField(74, 2, 0); break;
649
case OP_SET_OR : emitField(74, 2, 1); break;
650
case OP_SET_XOR: emitField(74, 2, 2); break;
651
default:
652
assert(!"invalid set op");
653
break;
654
}
655
emitNOT (90, insn->src(2));
656
emitPRED(87, insn->src(2));
657
} else {
658
emitPRED(87);
659
}
660
661
if (insn->defExists(1))
662
emitPRED(84, insn->def(1));
663
else
664
emitPRED(84);
665
emitPRED (81, insn->def(0));
666
emitCond4(76, insn->setCond);
667
}
668
669
/*******************************************************************************
670
* integer
671
******************************************************************************/
672
673
void
674
CodeEmitterGV100::emitBMSK()
675
{
676
emitFormA(0x01b, FA_RRR | FA_RIR | FA_RCR, __(0), __(1), EMPTY);
677
emitField(75, 1, insn->subOp); // .C/.W
678
}
679
680
void
681
CodeEmitterGV100::emitBREV()
682
{
683
emitFormA(0x101, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
684
}
685
686
void
687
CodeEmitterGV100::emitFLO()
688
{
689
emitFormA(0x100, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
690
emitPRED (81);
691
emitField(74, 1, insn->subOp == NV50_IR_SUBOP_BFIND_SAMT);
692
emitField(73, 1, isSignedType(insn->dType));
693
emitNOT (63, insn->src(0));
694
}
695
696
void
697
CodeEmitterGV100::emitIABS()
698
{
699
emitFormA(0x013, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
700
}
701
702
void
703
CodeEmitterGV100::emitIADD3()
704
{
705
// emitFormA(0x010, FA_RRR | FA_RIR | FA_RCR, N_(0), N_(1), N_(2));
706
emitFormA(0x010, FA_RRR | FA_RIR | FA_RCR, N_(0), N_(1), EMPTY);
707
emitGPR (64); //XXX: fix when switching back to N_(2)
708
emitPRED (84, NULL); // .CC1
709
emitPRED (81, insn->flagsDef >= 0 ? insn->getDef(insn->flagsDef) : NULL);
710
if (insn->flagsSrc >= 0) {
711
emitField(74, 1, 1); // .X
712
emitPRED (87, insn->getSrc(insn->flagsSrc));
713
emitField(77, 4, 0xf); // .X1
714
}
715
}
716
717
void
718
CodeEmitterGV100::emitIMAD()
719
{
720
emitFormA(0x024, FA_RRR | FA_RRI | FA_RRC | FA_RIR | FA_RCR, __(0), __(1), N_(2));
721
emitField(73, 1, isSignedType(insn->sType));
722
}
723
724
void
725
CodeEmitterGV100::emitIMAD_WIDE()
726
{
727
emitFormA(0x025, FA_RRR | FA_RRC | FA_RIR | FA_RCR, __(0), __(1), N_(2));
728
emitPRED (81);
729
emitField(73, 1, isSignedType(insn->sType));
730
}
731
732
void
733
CodeEmitterGV100::emitISETP()
734
{
735
const CmpInstruction *insn = this->insn->asCmp();
736
737
emitFormA(0x00c, FA_NODEF | FA_RRR | FA_RIR | FA_RCR, __(0), __(1), EMPTY);
738
739
if (insn->op != OP_SET) {
740
switch (insn->op) {
741
case OP_SET_AND: emitField(74, 2, 0); break;
742
case OP_SET_OR : emitField(74, 2, 1); break;
743
case OP_SET_XOR: emitField(74, 2, 2); break;
744
default:
745
assert(!"invalid set op");
746
break;
747
}
748
emitNOT (90, insn->src(2));
749
emitPRED(87, insn->src(2));
750
} else {
751
emitPRED(87);
752
}
753
754
//XXX: CC->pred
755
if (insn->flagsSrc >= 0) {
756
assert(0);
757
emitField(68, 4, 6);
758
} else {
759
emitNOT (71);
760
if (!insn->subOp)
761
emitPRED(68);
762
}
763
764
if (insn->defExists(1))
765
emitPRED(84, insn->def(1));
766
else
767
emitPRED(84);
768
emitPRED (81, insn->def(0));
769
emitCond3(76, insn->setCond);
770
emitField(73, 1, isSignedType(insn->sType));
771
772
if (insn->subOp) { // .EX
773
assert(0);
774
emitField(72, 1, 1);
775
emitPRED (68, insn->srcExists(3) ? insn->src(3) : insn->src(2));
776
}
777
}
778
779
void
780
CodeEmitterGV100::emitLEA()
781
{
782
assert(insn->src(1).get()->asImm());
783
784
emitFormA(0x011, FA_RRR | FA_RIR | FA_RCR, N_(0), N_(2), EMPTY);
785
emitPRED (81);
786
emitIMMD (75, 5, insn->src(1));
787
emitGPR (64);
788
}
789
790
void
791
CodeEmitterGV100::emitLOP3_LUT()
792
{
793
emitFormA(0x012, FA_RRR | FA_RIR | FA_RCR, __(0), __(1), __(2));
794
emitField(90, 1, 1);
795
emitPRED (87);
796
emitPRED (81);
797
emitField(80, 1, 0); // .PAND
798
emitField(72, 8, insn->subOp);
799
}
800
801
void
802
CodeEmitterGV100::emitPOPC()
803
{
804
emitFormA(0x109, FA_RRR | FA_RIR | FA_RCR, EMPTY, __(0), EMPTY);
805
emitNOT (63, insn->src(0));
806
}
807
808
void
809
CodeEmitterGV100::emitSGXT()
810
{
811
emitFormA(0x01a, FA_RRR | FA_RIR | FA_RCR, __(0), __(1), EMPTY);
812
emitField(75, 1, 0); // .W
813
emitField(73, 1, 1); // /.U32
814
}
815
816
void
817
CodeEmitterGV100::emitSHF()
818
{
819
emitFormA(0x019, FA_RRR | FA_RRI | FA_RRC | FA_RIR | FA_RCR, __(0), __(1), __(2));
820
emitField(80, 1, !!(insn->subOp & NV50_IR_SUBOP_SHF_HI));
821
emitField(76, 1, !!(insn->subOp & NV50_IR_SUBOP_SHF_R));
822
emitField(75, 1, !!(insn->subOp & NV50_IR_SUBOP_SHF_W));
823
824
switch (insn->sType) {
825
case TYPE_S64: emitField(73, 2, 0); break;
826
case TYPE_U64: emitField(73, 2, 1); break;
827
case TYPE_S32: emitField(73, 2, 2); break;
828
case TYPE_U32:
829
default:
830
emitField(73, 2, 3);
831
break;
832
}
833
}
834
835
/*******************************************************************************
836
* load/stores
837
******************************************************************************/
838
839
void
840
CodeEmitterGV100::emitALD()
841
{
842
emitInsn (0x321);
843
emitField(74, 2, (insn->getDef(0)->reg.size / 4) - 1);
844
emitGPR (32, insn->src(0).getIndirect(1));
845
emitO (79);
846
emitP (76);
847
emitADDR (24, 40, 10, 0, insn->src(0));
848
emitGPR (16, insn->def(0));
849
}
850
851
void
852
CodeEmitterGV100::emitAST()
853
{
854
emitInsn (0x322);
855
emitField(74, 2, (typeSizeof(insn->dType) / 4) - 1);
856
emitGPR (64, insn->src(0).getIndirect(1));
857
emitP (76);
858
emitADDR (24, 40, 10, 0, insn->src(0));
859
emitGPR (32, insn->src(1));
860
}
861
862
void
863
CodeEmitterGV100::emitATOM()
864
{
865
unsigned subOp, dType;
866
867
if (insn->subOp != NV50_IR_SUBOP_ATOM_CAS) {
868
emitInsn(0x38a);
869
870
if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
871
subOp = 8;
872
else
873
subOp = insn->subOp;
874
emitField(87, 4, subOp);
875
876
switch (insn->dType) {
877
case TYPE_U32 : dType = 0; break;
878
case TYPE_S32 : dType = 1; break;
879
case TYPE_U64 : dType = 2; break;
880
case TYPE_F32 : dType = 3; break;
881
case TYPE_B128: dType = 4; break;
882
case TYPE_S64 : dType = 5; break;
883
default:
884
assert(!"unexpected dType");
885
dType = 0;
886
break;
887
}
888
emitField(73, 3, dType);
889
} else {
890
emitInsn(0x38b);
891
892
switch (insn->dType) {
893
case TYPE_U32: dType = 0; break;
894
case TYPE_U64: dType = 2; break;
895
default:
896
assert(!"unexpected dType");
897
dType = 0;
898
break;
899
}
900
emitField(73, 3, dType);
901
emitGPR (64, insn->src(2));
902
}
903
904
emitPRED (81);
905
emitField(79, 2, 2); // .INVALID0/./.STRONG/.INVALID3
906
emitField(77, 2, 3); // .CTA/.SM/.GPU/.SYS
907
emitField(72, 1, insn->src(0).getIndirect(0)->getSize() == 8);
908
emitGPR (32, insn->src(1));
909
emitADDR (24, 40, 24, 0, insn->src(0));
910
emitGPR (16, insn->def(0));
911
}
912
913
void
914
CodeEmitterGV100::emitATOMS()
915
{
916
unsigned dType, subOp;
917
918
if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
919
switch (insn->dType) {
920
case TYPE_U32: dType = 0; break;
921
case TYPE_S32: dType = 1; break;
922
case TYPE_U64: dType = 2; break;
923
default: assert(!"unexpected dType"); dType = 0; break;
924
}
925
926
emitInsn (0x38d);
927
emitField(87, 1, 0); // ATOMS.CAS/ATOMS.CAST
928
emitField(73, 2, dType);
929
emitGPR (64, insn->src(2));
930
} else {
931
emitInsn(0x38c);
932
933
if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH)
934
subOp = 8;
935
else
936
subOp = insn->subOp;
937
emitField(87, 4, subOp);
938
939
switch (insn->dType) {
940
case TYPE_U32: dType = 0; break;
941
case TYPE_S32: dType = 1; break;
942
case TYPE_U64: dType = 2; break;
943
default: assert(!"unexpected dType"); dType = 0; break;
944
}
945
946
emitField(73, 2, dType);
947
}
948
949
emitGPR (32, insn->src(1));
950
emitADDR (24, 40, 24, 0, insn->src(0));
951
emitGPR (16, insn->def(0));
952
}
953
954
void
955
gv100_interpApply(const FixupEntry *entry, uint32_t *code, const FixupData& data)
956
{
957
int ipa = entry->ipa;
958
int loc = entry->loc;
959
960
if (data.force_persample_interp &&
961
(ipa & NV50_IR_INTERP_SAMPLE_MASK) == NV50_IR_INTERP_DEFAULT &&
962
(ipa & NV50_IR_INTERP_MODE_MASK) != NV50_IR_INTERP_FLAT) {
963
ipa |= NV50_IR_INTERP_CENTROID;
964
}
965
966
int sample;
967
switch (ipa & NV50_IR_INTERP_SAMPLE_MASK) {
968
case NV50_IR_INTERP_DEFAULT : sample = 0; break;
969
case NV50_IR_INTERP_CENTROID: sample = 1; break;
970
case NV50_IR_INTERP_OFFSET : sample = 2; break;
971
default: unreachable("invalid sample mode");
972
}
973
974
int interp;
975
switch (ipa & NV50_IR_INTERP_MODE_MASK) {
976
case NV50_IR_INTERP_LINEAR :
977
case NV50_IR_INTERP_PERSPECTIVE: interp = 0; break;
978
case NV50_IR_INTERP_FLAT : interp = 1; break;
979
case NV50_IR_INTERP_SC : interp = 2; break;
980
default: unreachable("invalid ipa mode");
981
}
982
983
code[loc + 2] &= ~(0xf << 12);
984
code[loc + 2] |= sample << 12;
985
code[loc + 2] |= interp << 14;
986
}
987
988
void
989
CodeEmitterGV100::emitIPA()
990
{
991
emitInsn (0x326);
992
emitPRED (81, insn->defExists(1) ? insn->def(1) : NULL);
993
994
switch (insn->getInterpMode()) {
995
case NV50_IR_INTERP_LINEAR :
996
case NV50_IR_INTERP_PERSPECTIVE: emitField(78, 2, 0); break;
997
case NV50_IR_INTERP_FLAT : emitField(78, 2, 1); break;
998
case NV50_IR_INTERP_SC : emitField(78, 2, 2); break;
999
default:
1000
assert(!"invalid ipa mode");
1001
break;
1002
}
1003
1004
switch (insn->getSampleMode()) {
1005
case NV50_IR_INTERP_DEFAULT : emitField(76, 2, 0); break;
1006
case NV50_IR_INTERP_CENTROID: emitField(76, 2, 1); break;
1007
case NV50_IR_INTERP_OFFSET : emitField(76, 2, 2); break;
1008
default:
1009
assert(!"invalid sample mode");
1010
break;
1011
}
1012
1013
if (insn->getSampleMode() != NV50_IR_INTERP_OFFSET) {
1014
emitGPR (32);
1015
addInterp(insn->ipa, 0xff, gv100_interpApply);
1016
} else {
1017
emitGPR (32, insn->src(1));
1018
addInterp(insn->ipa, insn->getSrc(1)->reg.data.id, gv100_interpApply);
1019
}
1020
1021
assert(!insn->src(0).isIndirect(0));
1022
emitADDR (-1, 64, 8, 2, insn->src(0));
1023
emitGPR (16, insn->def(0));
1024
}
1025
1026
void
1027
CodeEmitterGV100::emitISBERD()
1028
{
1029
emitInsn(0x923);
1030
emitGPR (24, insn->src(0));
1031
emitGPR (16, insn->def(0));
1032
}
1033
1034
void
1035
CodeEmitterGV100::emitLDSTc(int posm, int poso)
1036
{
1037
int mode = 0;
1038
int order = 1;
1039
1040
switch (insn->cache) {
1041
case CACHE_CA: mode = 0; order = 1; break;
1042
case CACHE_CG: mode = 2; order = 2; break;
1043
case CACHE_CV: mode = 3; order = 2; break;
1044
default:
1045
assert(!"invalid caching mode");
1046
break;
1047
}
1048
1049
emitField(poso, 2, order);
1050
emitField(posm, 2, mode);
1051
}
1052
1053
void
1054
CodeEmitterGV100::emitLDSTs(int pos, DataType type)
1055
{
1056
int data = 0;
1057
1058
switch (typeSizeof(type)) {
1059
case 1: data = isSignedType(type) ? 1 : 0; break;
1060
case 2: data = isSignedType(type) ? 3 : 2; break;
1061
case 4: data = 4; break;
1062
case 8: data = 5; break;
1063
case 16: data = 6; break;
1064
default:
1065
assert(!"bad type");
1066
break;
1067
}
1068
1069
emitField(pos, 3, data);
1070
}
1071
1072
void
1073
CodeEmitterGV100::emitLD()
1074
{
1075
emitInsn (0x980);
1076
emitField(79, 2, 2); // .CONSTANT/./.STRONG/.MMIO
1077
emitField(77, 2, 2); // .CTA/.SM/.GPU/.SYS
1078
emitLDSTs(73, insn->dType);
1079
emitField(72, 1, insn->src(0).getIndirect(0)->getSize() == 8);
1080
emitADDR (24, 32, 32, 0, insn->src(0));
1081
emitGPR (16, insn->def(0));
1082
}
1083
1084
void
1085
CodeEmitterGV100::emitLDC()
1086
{
1087
emitFormA(0x182, FA_RCR, EMPTY, __(0), EMPTY);
1088
emitField(78, 2, insn->subOp);
1089
emitLDSTs(73, insn->dType);
1090
emitGPR (24, insn->src(0).getIndirect(0));
1091
}
1092
1093
void
1094
CodeEmitterGV100::emitLDL()
1095
{
1096
emitInsn (0x983);
1097
emitField(84, 3, 1); // .EF/./.EL/.LU/.EU/.NA/.INVALID6/.INVALID7
1098
emitLDSTs(73, insn->dType);
1099
emitADDR (24, 40, 24, 0, insn->src(0));
1100
emitGPR (16, insn->def(0));
1101
}
1102
1103
void
1104
CodeEmitterGV100::emitLDS()
1105
{
1106
emitInsn (0x984);
1107
emitLDSTs(73, insn->dType);
1108
emitADDR (24, 40, 24, 0, insn->src(0));
1109
emitGPR (16, insn->def(0));
1110
}
1111
1112
void
1113
CodeEmitterGV100::emitOUT()
1114
{
1115
const int cut = insn->op == OP_RESTART || insn->subOp;
1116
const int emit = insn->op == OP_EMIT;
1117
1118
if (insn->op != OP_FINAL)
1119
emitFormA(0x124, FA_RRR | FA_RIR, __(0), __(1), EMPTY);
1120
else
1121
emitFormA(0x124, FA_RRR | FA_RIR, __(0), EMPTY, EMPTY);
1122
emitField(78, 2, (cut << 1) | emit);
1123
}
1124
1125
void
1126
CodeEmitterGV100::emitRED()
1127
{
1128
unsigned dType;
1129
1130
switch (insn->dType) {
1131
case TYPE_U32: dType = 0; break;
1132
case TYPE_S32: dType = 1; break;
1133
case TYPE_U64: dType = 2; break;
1134
case TYPE_F32: dType = 3; break;
1135
case TYPE_B128: dType = 4; break;
1136
case TYPE_S64: dType = 5; break;
1137
default: assert(!"unexpected dType"); dType = 0; break;
1138
}
1139
1140
emitInsn (0x98e);
1141
emitField(87, 3, insn->subOp);
1142
emitField(84, 3, 1); // 0=.EF, 1=, 2=.EL, 3=.LU, 4=.EU, 5=.NA
1143
emitField(79, 2, 2); // .INVALID0/./.STRONG/.INVALID3
1144
emitField(77, 2, 3); // .CTA/.SM/.GPU/.SYS
1145
emitField(73, 3, dType);
1146
emitField(72, 1, insn->src(0).getIndirect(0)->getSize() == 8);
1147
emitGPR (32, insn->src(1));
1148
emitADDR (24, 40, 24, 0, insn->src(0));
1149
}
1150
1151
void
1152
CodeEmitterGV100::emitST()
1153
{
1154
emitInsn (0x385);
1155
emitField(79, 2, 2); // .INVALID0/./.STRONG/.MMIO
1156
emitField(77, 2, 2); // .CTA/.SM/.GPU/.SYS
1157
emitLDSTs(73, insn->dType);
1158
emitField(72, 1, insn->src(0).getIndirect(0)->getSize() == 8);
1159
emitGPR (64, insn->src(1));
1160
emitADDR (24, 32, 32, 0, insn->src(0));
1161
}
1162
1163
void
1164
CodeEmitterGV100::emitSTL()
1165
{
1166
emitInsn (0x387);
1167
emitField(84, 3, 1); // .EF/./.EL/.LU/.EU/.NA/.INVALID6/.INVALID7
1168
emitLDSTs(73, insn->dType);
1169
emitADDR (24, 40, 24, 0, insn->src(0));
1170
emitGPR (32, insn->src(1));
1171
}
1172
1173
void
1174
CodeEmitterGV100::emitSTS()
1175
{
1176
emitInsn (0x388);
1177
emitLDSTs(73, insn->dType);
1178
emitADDR (24, 40, 24, 0, insn->src(0));
1179
emitGPR (32, insn->src(1));
1180
}
1181
1182
/*******************************************************************************
1183
* texture
1184
******************************************************************************/
1185
1186
void
1187
CodeEmitterGV100::emitTEXs(int pos)
1188
{
1189
int src1 = insn->predSrc == 1 ? 2 : 1;
1190
if (insn->srcExists(src1))
1191
emitGPR(pos, insn->src(src1));
1192
else
1193
emitGPR(pos);
1194
}
1195
1196
void
1197
CodeEmitterGV100::emitTEX()
1198
{
1199
const TexInstruction *insn = this->insn->asTex();
1200
int lodm = 0;
1201
1202
if (!insn->tex.levelZero) {
1203
switch (insn->op) {
1204
case OP_TEX: lodm = 0; break;
1205
case OP_TXB: lodm = 2; break;
1206
case OP_TXL: lodm = 3; break;
1207
default:
1208
assert(!"invalid tex op");
1209
break;
1210
}
1211
} else {
1212
lodm = 1;
1213
}
1214
1215
if (insn->tex.rIndirectSrc < 0) {
1216
emitInsn (0xb60);
1217
emitField(54, 5, prog->driver->io.auxCBSlot);
1218
emitField(40, 14, insn->tex.r);
1219
} else {
1220
emitInsn (0x361);
1221
emitField(59, 1, 1); // .B
1222
}
1223
emitField(90, 1, insn->tex.liveOnly); // .NODEP
1224
emitField(87, 3, lodm);
1225
emitField(84, 3, 1); // 0=.EF, 1=, 2=.EL, 3=.LU, 4=.EU, 5=.NA
1226
emitField(78, 1, insn->tex.target.isShadow()); // .DC
1227
emitField(77, 1, insn->tex.derivAll); // .NDV
1228
emitField(76, 1, insn->tex.useOffsets == 1); // .AOFFI
1229
emitPRED (81);
1230
emitGPR (64, insn->def(1));
1231
emitGPR (16, insn->def(0));
1232
emitGPR (24, insn->src(0));
1233
emitTEXs (32);
1234
emitField(63, 1, insn->tex.target.isArray());
1235
emitField(61, 2, insn->tex.target.isCube() ? 3 :
1236
insn->tex.target.getDim() - 1);
1237
emitField(72, 4, insn->tex.mask);
1238
}
1239
1240
void
1241
CodeEmitterGV100::emitTLD()
1242
{
1243
const TexInstruction *insn = this->insn->asTex();
1244
1245
if (insn->tex.rIndirectSrc < 0) {
1246
emitInsn (0xb66);
1247
emitField(54, 5, prog->driver->io.auxCBSlot);
1248
emitField(40, 14, insn->tex.r);
1249
} else {
1250
emitInsn (0x367);
1251
emitField(59, 1, 1); // .B
1252
}
1253
emitField(90, 1, insn->tex.liveOnly);
1254
emitField(87, 3, insn->tex.levelZero ? 1 /* .LZ */ : 3 /* .LL */);
1255
emitPRED (81);
1256
emitField(78, 1, insn->tex.target.isMS());
1257
emitField(76, 1, insn->tex.useOffsets == 1);
1258
emitField(72, 4, insn->tex.mask);
1259
emitGPR (64, insn->def(1));
1260
emitField(63, 1, insn->tex.target.isArray());
1261
emitField(61, 2, insn->tex.target.isCube() ? 3 :
1262
insn->tex.target.getDim() - 1);
1263
emitTEXs (32);
1264
emitGPR (24, insn->src(0));
1265
emitGPR (16, insn->def(0));
1266
}
1267
1268
void
1269
CodeEmitterGV100::emitTLD4()
1270
{
1271
const TexInstruction *insn = this->insn->asTex();
1272
1273
int offsets = 0;
1274
switch (insn->tex.useOffsets) {
1275
case 4: offsets = 2; break;
1276
case 1: offsets = 1; break;
1277
case 0: offsets = 0; break;
1278
default: assert(!"invalid offsets count"); break;
1279
}
1280
1281
if (insn->tex.rIndirectSrc < 0) {
1282
emitInsn (0xb63);
1283
emitField(54, 5, prog->driver->io.auxCBSlot);
1284
emitField(40, 14, insn->tex.r);
1285
} else {
1286
emitInsn (0x364);
1287
emitField(59, 1, 1); // .B
1288
}
1289
emitField(90, 1, insn->tex.liveOnly);
1290
emitField(87, 2, insn->tex.gatherComp);
1291
emitField(84, 1, 1); // !.EF
1292
emitPRED (81);
1293
emitField(78, 1, insn->tex.target.isShadow());
1294
emitField(76, 2, offsets);
1295
emitField(72, 4, insn->tex.mask);
1296
emitGPR (64, insn->def(1));
1297
emitField(63, 1, insn->tex.target.isArray());
1298
emitField(61, 2, insn->tex.target.isCube() ? 3 :
1299
insn->tex.target.getDim() - 1);
1300
emitTEXs (32);
1301
emitGPR (24, insn->src(0));
1302
emitGPR (16, insn->def(0));
1303
}
1304
1305
void
1306
CodeEmitterGV100::emitTMML()
1307
{
1308
const TexInstruction *insn = this->insn->asTex();
1309
1310
if (insn->tex.rIndirectSrc < 0) {
1311
emitInsn (0xb69);
1312
emitField(54, 5, prog->driver->io.auxCBSlot);
1313
emitField(40, 14, insn->tex.r);
1314
} else {
1315
emitInsn (0x36a);
1316
emitField(59, 1, 1); // .B
1317
}
1318
emitField(90, 1, insn->tex.liveOnly);
1319
emitField(77, 1, insn->tex.derivAll);
1320
emitField(72, 4, insn->tex.mask);
1321
emitGPR (64, insn->def(1));
1322
emitField(63, 1, insn->tex.target.isArray());
1323
emitField(61, 2, insn->tex.target.isCube() ? 3 :
1324
insn->tex.target.getDim() - 1);
1325
emitTEXs (32);
1326
emitGPR (24, insn->src(0));
1327
emitGPR (16, insn->def(0));
1328
}
1329
1330
void
1331
CodeEmitterGV100::emitTXD()
1332
{
1333
const TexInstruction *insn = this->insn->asTex();
1334
1335
if (insn->tex.rIndirectSrc < 0) {
1336
emitInsn (0xb6c);
1337
emitField(54, 5, prog->driver->io.auxCBSlot);
1338
emitField(40, 14, insn->tex.r);
1339
} else {
1340
emitInsn (0x36d);
1341
emitField(59, 1, 1); // .B
1342
}
1343
emitField(90, 1, insn->tex.liveOnly);
1344
emitPRED (81);
1345
emitField(76, 1, insn->tex.useOffsets == 1);
1346
emitField(72, 4, insn->tex.mask);
1347
emitGPR (64, insn->def(1));
1348
emitField(63, 1, insn->tex.target.isArray());
1349
emitField(61, 2, insn->tex.target.isCube() ? 3 :
1350
insn->tex.target.getDim() - 1);
1351
emitTEXs (32);
1352
emitGPR (24, insn->src(0));
1353
emitGPR (16, insn->def(0));
1354
}
1355
1356
void
1357
CodeEmitterGV100::emitTXQ()
1358
{
1359
const TexInstruction *insn = this->insn->asTex();
1360
int type = 0;
1361
1362
switch (insn->tex.query) {
1363
case TXQ_DIMS : type = 0x00; break;
1364
case TXQ_TYPE : type = 0x01; break;
1365
case TXQ_SAMPLE_POSITION: type = 0x02; break;
1366
default:
1367
assert(!"invalid txq query");
1368
break;
1369
}
1370
1371
if (insn->tex.rIndirectSrc < 0) {
1372
emitInsn (0xb6f);
1373
emitField(54, 5, prog->driver->io.auxCBSlot);
1374
emitField(40, 14, insn->tex.r);
1375
} else {
1376
emitInsn (0x370);
1377
emitField(59, 1, 1); // .B
1378
}
1379
emitField(90, 1, insn->tex.liveOnly);
1380
emitField(72, 4, insn->tex.mask);
1381
emitGPR (64, insn->def(1));
1382
emitField(62, 2, type);
1383
emitGPR (24, insn->src(0));
1384
emitGPR (16, insn->def(0));
1385
}
1386
1387
/*******************************************************************************
1388
* surface
1389
******************************************************************************/
1390
1391
void
1392
CodeEmitterGV100::emitSUHandle(const int s)
1393
{
1394
const TexInstruction *insn = this->insn->asTex();
1395
1396
assert(insn->op >= OP_SULDB && insn->op <= OP_SUREDP);
1397
1398
if (insn->src(s).getFile() == FILE_GPR) {
1399
emitGPR(64, insn->src(s));
1400
} else {
1401
assert(0);
1402
//XXX: not done
1403
ImmediateValue *imm = insn->getSrc(s)->asImm();
1404
assert(imm);
1405
emitField(0x33, 1, 1);
1406
emitField(0x24, 13, imm->reg.data.u32);
1407
}
1408
}
1409
1410
void
1411
CodeEmitterGV100::emitSUTarget()
1412
{
1413
const TexInstruction *insn = this->insn->asTex();
1414
int target = 0;
1415
1416
assert(insn->op >= OP_SULDB && insn->op <= OP_SUREDP);
1417
1418
if (insn->tex.target == TEX_TARGET_BUFFER) {
1419
target = 1;
1420
} else if (insn->tex.target == TEX_TARGET_1D_ARRAY) {
1421
target = 2;
1422
} else if (insn->tex.target == TEX_TARGET_2D ||
1423
insn->tex.target == TEX_TARGET_RECT) {
1424
target = 3;
1425
} else if (insn->tex.target == TEX_TARGET_2D_ARRAY ||
1426
insn->tex.target == TEX_TARGET_CUBE ||
1427
insn->tex.target == TEX_TARGET_CUBE_ARRAY) {
1428
target = 4;
1429
} else if (insn->tex.target == TEX_TARGET_3D) {
1430
target = 5;
1431
} else {
1432
assert(insn->tex.target == TEX_TARGET_1D);
1433
}
1434
emitField(61, 3, target);
1435
}
1436
1437
void
1438
CodeEmitterGV100::emitSUATOM()
1439
{
1440
const TexInstruction *insn = this->insn->asTex();
1441
uint8_t type = 0, subOp;
1442
1443
if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS)
1444
emitInsn(0x396); // SUATOM.D.CAS
1445
else
1446
emitInsn(0x394); // SUATOM.D
1447
1448
emitSUTarget();
1449
1450
// destination type
1451
switch (insn->dType) {
1452
case TYPE_S32: type = 1; break;
1453
case TYPE_U64: type = 2; break;
1454
case TYPE_F32: type = 3; break;
1455
case TYPE_S64: type = 5; break;
1456
default:
1457
assert(insn->dType == TYPE_U32);
1458
break;
1459
}
1460
1461
// atomic operation
1462
if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
1463
subOp = 0;
1464
} else if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
1465
subOp = 8;
1466
} else {
1467
subOp = insn->subOp;
1468
}
1469
1470
emitField(87, 4, subOp);
1471
emitPRED (81);
1472
emitField(79, 2, 1);
1473
emitField(73, 3, type);
1474
emitField(72, 1, 0); // .BA
1475
emitGPR (32, insn->src(1));
1476
emitGPR (24, insn->src(0));
1477
emitGPR (16, insn->def(0));
1478
1479
emitSUHandle(2);
1480
}
1481
1482
void
1483
CodeEmitterGV100::emitSULD()
1484
{
1485
const TexInstruction *insn = this->insn->asTex();
1486
int type = 0;
1487
1488
if (insn->op == OP_SULDB) {
1489
emitInsn(0x99a);
1490
emitSUTarget();
1491
1492
switch (insn->dType) {
1493
case TYPE_U8: type = 0; break;
1494
case TYPE_S8: type = 1; break;
1495
case TYPE_U16: type = 2; break;
1496
case TYPE_S16: type = 3; break;
1497
case TYPE_U32: type = 4; break;
1498
case TYPE_U64: type = 5; break;
1499
case TYPE_B128: type = 6; break;
1500
default:
1501
assert(0);
1502
break;
1503
}
1504
emitField(73, 3, type);
1505
} else {
1506
emitInsn(0x998);
1507
emitSUTarget();
1508
emitField(72, 4, 0xf); // rgba
1509
}
1510
1511
emitPRED (81);
1512
emitLDSTc(77, 79);
1513
1514
emitGPR (16, insn->def(0));
1515
emitGPR (24, insn->src(0));
1516
1517
emitSUHandle(1);
1518
}
1519
1520
void
1521
CodeEmitterGV100::emitSUST()
1522
{
1523
const TexInstruction *insn = this->insn->asTex();
1524
1525
emitInsn(0x99c); // SUST.P
1526
#if 0
1527
if (insn->op == OP_SUSTB)
1528
emitField(0x34, 1, 1);
1529
#endif
1530
emitSUTarget();
1531
1532
emitLDSTc(77, 79);
1533
emitField(72, 4, 0xf); // rgba
1534
emitGPR(32, insn->src(1));
1535
emitGPR(24, insn->src(0));
1536
emitSUHandle(2);
1537
}
1538
1539
/*******************************************************************************
1540
* misc
1541
******************************************************************************/
1542
1543
void
1544
CodeEmitterGV100::emitAL2P()
1545
{
1546
emitInsn (0x920);
1547
emitO (79);
1548
emitField(74, 2, (insn->getDef(0)->reg.size / 4) - 1);
1549
emitField(40, 11, insn->src(0).get()->reg.data.offset);
1550
emitGPR (24, insn->src(0).getIndirect(0));
1551
emitGPR (16, insn->def(0));
1552
}
1553
1554
void
1555
CodeEmitterGV100::emitBAR()
1556
{
1557
uint8_t subop, redop = 0x00;
1558
1559
// 80
1560
// 01: DEFER_BLOCKING
1561
// 78:77
1562
// 00: SYNC
1563
// 01: ARV
1564
// 02: RED
1565
// 03: SCAN
1566
// 75:74
1567
// 00: RED.POPC
1568
// 01: RED.AND
1569
// 02: RED.OR
1570
1571
switch (insn->subOp) {
1572
case NV50_IR_SUBOP_BAR_RED_POPC: subop = 0x02; redop = 0x00; break;
1573
case NV50_IR_SUBOP_BAR_RED_AND : subop = 0x02; redop = 0x01; break;
1574
case NV50_IR_SUBOP_BAR_RED_OR : subop = 0x02; redop = 0x02; break;
1575
case NV50_IR_SUBOP_BAR_ARRIVE : subop = 0x01; break;
1576
default:
1577
subop = 0x00;
1578
assert(insn->subOp == NV50_IR_SUBOP_BAR_SYNC);
1579
break;
1580
}
1581
1582
if (insn->src(0).getFile() == FILE_GPR) {
1583
emitInsn ((1 << 9) | 0x11d);
1584
emitGPR (32, insn->src(0)); //XXX: nvdisasm shows src0==src1
1585
} else {
1586
ImmediateValue *imm = insn->getSrc(0)->asImm();
1587
assert(imm);
1588
if (insn->src(1).getFile() == FILE_GPR) {
1589
emitInsn ((4 << 9) | 0x11d);
1590
emitGPR (32, insn->src(1));
1591
} else {
1592
emitInsn ((5 << 9) | 0x11d);
1593
}
1594
emitField(54, 4, imm->reg.data.u32);
1595
}
1596
1597
emitField(77, 2, subop);
1598
emitField(74, 2, redop);
1599
1600
if (insn->srcExists(2) && (insn->predSrc != 2)) {
1601
emitField(90, 1, insn->src(2).mod == Modifier(NV50_IR_MOD_NOT));
1602
emitPRED (87, insn->src(2));
1603
} else {
1604
emitField(87, 3, 7);
1605
}
1606
}
1607
1608
void
1609
CodeEmitterGV100::emitCCTL()
1610
{
1611
if (insn->src(0).getFile() == FILE_MEMORY_GLOBAL)
1612
emitInsn(0x98f);
1613
else
1614
emitInsn(0x990);
1615
emitField(87, 4, insn->subOp);
1616
emitField(72, 1, insn->src(0).getIndirect(0)->getSize() == 8);
1617
emitADDR (24, 32, 32, 0, insn->src(0));
1618
}
1619
1620
void
1621
CodeEmitterGV100::emitMEMBAR()
1622
{
1623
emitInsn (0x992);
1624
switch (NV50_IR_SUBOP_MEMBAR_SCOPE(insn->subOp)) {
1625
case NV50_IR_SUBOP_MEMBAR_CTA: emitField(76, 3, 0); break;
1626
case NV50_IR_SUBOP_MEMBAR_GL : emitField(76, 3, 2); break;
1627
case NV50_IR_SUBOP_MEMBAR_SYS: emitField(76, 3, 3); break;
1628
default:
1629
assert(!"invalid scope");
1630
break;
1631
}
1632
}
1633
1634
void
1635
CodeEmitterGV100::emitPIXLD()
1636
{
1637
emitInsn (0x925);
1638
switch (insn->subOp) {
1639
case NV50_IR_SUBOP_PIXLD_COVMASK : emitField(78, 3, 1); break; // .COVMASK
1640
case NV50_IR_SUBOP_PIXLD_SAMPLEID: emitField(78, 3, 3); break; // .MY_INDEX
1641
default:
1642
assert(0);
1643
break;
1644
}
1645
emitPRED (71);
1646
emitGPR (16, insn->def(0));
1647
}
1648
1649
void
1650
CodeEmitterGV100::emitPLOP3_LUT()
1651
{
1652
uint8_t op[2] = {};
1653
1654
switch (insn->op) {
1655
case OP_AND: op[0] = 0xf0 & 0xcc; break;
1656
case OP_OR : op[0] = 0xf0 | 0xcc; break;
1657
case OP_XOR: op[0] = 0xf0 ^ 0xcc; break;
1658
default:
1659
assert(!"invalid PLOP3");
1660
break;
1661
}
1662
1663
emitInsn(0x81c);
1664
emitNOT (90, insn->src(0));
1665
emitPRED(87, insn->src(0));
1666
emitPRED(84); // def(1)
1667
emitPRED(81, insn->def(0));
1668
emitNOT (80, insn->src(1));
1669
emitPRED(77, insn->src(1));
1670
emitField(72, 5, op[0] >> 3);
1671
emitNOT (71); // src(2)
1672
emitPRED(68); // src(2)
1673
emitField(64, 3, op[0] & 7);
1674
emitField(16, 8, op[1]);
1675
}
1676
1677
void
1678
CodeEmitterGV100::emitVOTE()
1679
{
1680
const ImmediateValue *imm;
1681
uint32_t u32;
1682
1683
int r = -1, p = -1;
1684
for (int i = 0; insn->defExists(i); i++) {
1685
if (insn->def(i).getFile() == FILE_GPR)
1686
r = i;
1687
else if (insn->def(i).getFile() == FILE_PREDICATE)
1688
p = i;
1689
}
1690
1691
emitInsn (0x806);
1692
emitField(72, 2, insn->subOp);
1693
if (r >= 0)
1694
emitGPR (16, insn->def(r));
1695
else
1696
emitGPR (16);
1697
if (p >= 0)
1698
emitPRED (81, insn->def(p));
1699
else
1700
emitPRED (81);
1701
1702
switch (insn->src(0).getFile()) {
1703
case FILE_PREDICATE:
1704
emitField(90, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT));
1705
emitPRED (87, insn->src(0));
1706
break;
1707
case FILE_IMMEDIATE:
1708
imm = insn->getSrc(0)->asImm();
1709
assert(imm);
1710
u32 = imm->reg.data.u32;
1711
assert(u32 == 0 || u32 == 1);
1712
emitField(90, 1, u32 == 0);
1713
emitPRED (87);
1714
break;
1715
default:
1716
assert(!"Unhandled src");
1717
break;
1718
}
1719
}
1720
1721
bool
1722
CodeEmitterGV100::emitInstruction(Instruction *i)
1723
{
1724
insn = i;
1725
1726
switch (insn->op) {
1727
case OP_ABS:
1728
assert(!isFloatType(insn->dType));
1729
emitIABS();
1730
break;
1731
case OP_ADD:
1732
if (isFloatType(insn->dType)) {
1733
if (insn->dType == TYPE_F32)
1734
emitFADD();
1735
else
1736
emitDADD();
1737
} else {
1738
emitIADD3();
1739
}
1740
break;
1741
case OP_AFETCH:
1742
emitAL2P();
1743
break;
1744
case OP_AND:
1745
case OP_OR:
1746
case OP_XOR:
1747
if (insn->def(0).getFile() == FILE_PREDICATE) {
1748
emitPLOP3_LUT();
1749
} else {
1750
assert(!"invalid logop");
1751
emitNOP();
1752
}
1753
break;
1754
case OP_ATOM:
1755
if (insn->src(0).getFile() == FILE_MEMORY_SHARED)
1756
emitATOMS();
1757
else
1758
if (!insn->defExists(0) && insn->subOp < NV50_IR_SUBOP_ATOM_CAS)
1759
emitRED();
1760
else
1761
emitATOM();
1762
break;
1763
case OP_BAR:
1764
emitBAR();
1765
break;
1766
case OP_BFIND:
1767
emitFLO();
1768
break;
1769
case OP_BMSK:
1770
emitBMSK();
1771
break;
1772
case OP_BREV:
1773
emitBREV();
1774
break;
1775
case OP_BRA:
1776
case OP_JOIN: //XXX
1777
emitBRA();
1778
break;
1779
case OP_CCTL:
1780
emitCCTL();
1781
break;
1782
case OP_CEIL:
1783
case OP_CVT:
1784
case OP_FLOOR:
1785
case OP_TRUNC:
1786
if (insn->op == OP_CVT && (insn->def(0).getFile() == FILE_PREDICATE ||
1787
insn->def(0).getFile() == FILE_BARRIER ||
1788
insn->def(0).getFile() == FILE_THREAD_STATE ||
1789
insn->src(0).getFile() == FILE_PREDICATE ||
1790
insn->src(0).getFile() == FILE_BARRIER ||
1791
insn->src(0).getFile() == FILE_THREAD_STATE)) {
1792
emitMOV();
1793
} else if (isFloatType(insn->dType)) {
1794
if (isFloatType(insn->sType)) {
1795
if (insn->sType == insn->dType)
1796
emitFRND();
1797
else
1798
emitF2F();
1799
} else {
1800
emitI2F();
1801
}
1802
} else {
1803
if (isFloatType(insn->sType)) {
1804
emitF2I();
1805
} else {
1806
assert(!"I2I");
1807
emitNOP();
1808
}
1809
}
1810
break;
1811
case OP_COS:
1812
case OP_EX2:
1813
case OP_LG2:
1814
case OP_RCP:
1815
case OP_RSQ:
1816
case OP_SIN:
1817
case OP_SQRT:
1818
emitMUFU();
1819
break;
1820
case OP_DISCARD:
1821
emitKILL();
1822
break;
1823
case OP_EMIT:
1824
case OP_FINAL:
1825
case OP_RESTART:
1826
emitOUT();
1827
break;
1828
case OP_EXIT:
1829
emitEXIT();
1830
break;
1831
case OP_EXPORT:
1832
emitAST();
1833
break;
1834
case OP_FMA:
1835
case OP_MAD:
1836
if (isFloatType(insn->dType)) {
1837
if (insn->dType == TYPE_F32)
1838
emitFFMA();
1839
else
1840
emitDFMA();
1841
} else {
1842
if (typeSizeof(insn->dType) != 8)
1843
emitIMAD();
1844
else
1845
emitIMAD_WIDE();
1846
}
1847
break;
1848
case OP_JOINAT: //XXX
1849
emitNOP();
1850
break;
1851
case OP_LINTERP:
1852
emitIPA();
1853
break;
1854
case OP_LOAD:
1855
switch (insn->src(0).getFile()) {
1856
case FILE_MEMORY_CONST : emitLDC(); break;
1857
case FILE_MEMORY_LOCAL : emitLDL(); break;
1858
case FILE_MEMORY_SHARED: emitLDS(); break;
1859
case FILE_MEMORY_GLOBAL: emitLD(); break;
1860
default:
1861
assert(!"invalid load");
1862
emitNOP();
1863
break;
1864
}
1865
break;
1866
case OP_LOP3_LUT:
1867
emitLOP3_LUT();
1868
break;
1869
case OP_MAX:
1870
case OP_MIN:
1871
if (isFloatType(insn->dType)) {
1872
if (insn->dType == TYPE_F32) {
1873
emitFMNMX();
1874
} else {
1875
assert(!"invalid FMNMX");
1876
emitNOP();
1877
}
1878
} else {
1879
assert(!"invalid MNMX");
1880
emitNOP();
1881
}
1882
break;
1883
case OP_MEMBAR:
1884
emitMEMBAR();
1885
break;
1886
case OP_MOV:
1887
emitMOV();
1888
break;
1889
case OP_MUL:
1890
if (isFloatType(insn->dType)) {
1891
if (insn->dType == TYPE_F32)
1892
emitFMUL();
1893
else
1894
emitDMUL();
1895
} else {
1896
assert(!"invalid IMUL");
1897
emitNOP();
1898
}
1899
break;
1900
case OP_PERMT:
1901
emitPRMT();
1902
break;
1903
case OP_PFETCH:
1904
emitISBERD();
1905
break;
1906
case OP_PIXLD:
1907
emitPIXLD();
1908
break;
1909
case OP_POPCNT:
1910
emitPOPC();
1911
break;
1912
case OP_QUADOP:
1913
emitFSWZADD();
1914
break;
1915
case OP_RDSV:
1916
if (targ->isCS2RSV(insn->getSrc(0)->reg.data.sv.sv))
1917
emitCS2R();
1918
else
1919
emitS2R();
1920
break;
1921
case OP_SELP:
1922
emitSEL();
1923
break;
1924
case OP_SET:
1925
case OP_SET_AND:
1926
case OP_SET_OR:
1927
case OP_SET_XOR:
1928
if (insn->def(0).getFile() != FILE_PREDICATE) {
1929
if (isFloatType(insn->dType)) {
1930
if (insn->dType == TYPE_F32) {
1931
emitFSET_BF();
1932
} else {
1933
assert(!"invalid FSET");
1934
emitNOP();
1935
}
1936
} else {
1937
assert(!"invalid SET");
1938
emitNOP();
1939
}
1940
} else {
1941
if (isFloatType(insn->sType))
1942
if (insn->sType == TYPE_F64)
1943
emitDSETP();
1944
else
1945
emitFSETP();
1946
else
1947
emitISETP();
1948
}
1949
break;
1950
case OP_SGXT:
1951
emitSGXT();
1952
break;
1953
case OP_SHF:
1954
emitSHF();
1955
break;
1956
case OP_SHFL:
1957
emitSHFL();
1958
break;
1959
case OP_SHLADD:
1960
emitLEA();
1961
break;
1962
case OP_STORE:
1963
switch (insn->src(0).getFile()) {
1964
case FILE_MEMORY_LOCAL : emitSTL(); break;
1965
case FILE_MEMORY_SHARED: emitSTS(); break;
1966
case FILE_MEMORY_GLOBAL: emitST(); break;
1967
default:
1968
assert(!"invalid store");
1969
emitNOP();
1970
break;
1971
}
1972
break;
1973
case OP_SULDB:
1974
case OP_SULDP:
1975
emitSULD();
1976
break;
1977
case OP_SUREDB:
1978
case OP_SUREDP:
1979
emitSUATOM();
1980
break;
1981
case OP_SUSTB:
1982
case OP_SUSTP:
1983
emitSUST();
1984
break;
1985
case OP_TEX:
1986
case OP_TXB:
1987
case OP_TXL:
1988
emitTEX();
1989
break;
1990
case OP_TXD:
1991
emitTXD();
1992
break;
1993
case OP_TXF:
1994
emitTLD();
1995
break;
1996
case OP_TXG:
1997
emitTLD4();
1998
break;
1999
case OP_TXLQ:
2000
emitTMML();
2001
break;
2002
case OP_TXQ:
2003
emitTXQ();
2004
break;
2005
case OP_VFETCH:
2006
emitALD();
2007
break;
2008
case OP_VOTE:
2009
emitVOTE();
2010
break;
2011
case OP_WARPSYNC:
2012
emitWARPSYNC();
2013
break;
2014
default:
2015
assert(!"invalid opcode");
2016
emitNOP();
2017
break;
2018
}
2019
2020
code[3] &= 0x000001ff;
2021
code[3] |= insn->sched << 9;
2022
code += 4;
2023
codeSize += 16;
2024
return true;
2025
}
2026
2027
void
2028
CodeEmitterGV100::prepareEmission(BasicBlock *bb)
2029
{
2030
Function *func = bb->getFunction();
2031
Instruction *i;
2032
int j;
2033
2034
for (j = func->bbCount - 1; j >= 0 && !func->bbArray[j]->binSize; --j);
2035
2036
for (; j >= 0; --j) {
2037
BasicBlock *in = func->bbArray[j];
2038
Instruction *exit = in->getExit();
2039
2040
if (exit && exit->op == OP_BRA && exit->asFlow()->target.bb == bb) {
2041
in->binSize -= 16;
2042
func->binSize -= 16;
2043
2044
for (++j; j < func->bbCount; ++j)
2045
func->bbArray[j]->binPos -= 16;
2046
2047
in->remove(exit);
2048
}
2049
bb->binPos = in->binPos + in->binSize;
2050
if (in->binSize) // no more no-op branches to bb
2051
break;
2052
}
2053
func->bbArray[func->bbCount++] = bb;
2054
2055
if (!bb->getExit())
2056
return;
2057
2058
for (i = bb->getEntry(); i; i = i->next) {
2059
i->encSize = getMinEncodingSize(i);
2060
bb->binSize += i->encSize;
2061
}
2062
2063
assert(!bb->getEntry() || (bb->getExit() && bb->getExit()->encSize == 16));
2064
2065
func->binSize += bb->binSize;
2066
}
2067
2068
void
2069
CodeEmitterGV100::prepareEmission(Function *func)
2070
{
2071
SchedDataCalculatorGM107 sched(targ);
2072
CodeEmitter::prepareEmission(func);
2073
sched.run(func, true, true);
2074
}
2075
2076
void
2077
CodeEmitterGV100::prepareEmission(Program *prog)
2078
{
2079
for (ArrayList::Iterator fi = prog->allFuncs.iterator();
2080
!fi.end(); fi.next()) {
2081
Function *func = reinterpret_cast<Function *>(fi.get());
2082
func->binPos = prog->binSize;
2083
prepareEmission(func);
2084
prog->binSize += func->binSize;
2085
}
2086
2087
this->prog = prog;
2088
}
2089
2090
CodeEmitterGV100::CodeEmitterGV100(TargetGV100 *target)
2091
: CodeEmitter(target), prog(NULL), targ(target), insn(NULL)
2092
{
2093
code = NULL;
2094
codeSize = codeSizeLimit = 0;
2095
relocInfo = NULL;
2096
}
2097
};
2098
2099